• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2/* eslint-disable camelcase */
3var fs = require('graceful-fs')
4var path = require('path')
5
6var mkdirp = require('mkdirp')
7var test = require('tap').test
8
9var common = require('../common-tap.js')
10
11var pkg = common.pkg
12var deps = path.resolve(pkg, 'deps')
13var opdep = path.resolve(pkg, 'node_modules', 'opdep')
14var cache = common.cache
15var createServer = require('http').createServer
16var mr = require('npm-registry-mock')
17var serverPort = 27991
18
19var json = {
20  name: 'optional-metadep-rollback-collision',
21  version: '1.0.0',
22  description: 'let\'s just see about that race condition',
23  optionalDependencies: {
24    opdep: 'file:./deps/opdep'
25  }
26}
27
28var d1 = {
29  name: 'd1',
30  version: '1.0.0',
31  description: 'I FAIL CONSTANTLY',
32  scripts: {
33    preinstall: 'sleep 1'
34  },
35  dependencies: {
36    foo: 'http://localhost:' + serverPort + '/'
37  }
38}
39
40var d2 = {
41  name: 'd2',
42  version: '1.0.0',
43  description: 'how do you *really* know you exist?',
44  scripts: {
45    postinstall: 'node blart.js'
46  },
47  dependencies: {
48    'request': '^0.9.0',
49    mkdirp: '^0.3.5',
50    wordwrap: '^0.0.2'
51  }
52}
53
54var opdep_json = {
55  name: 'opdep',
56  version: '1.0.0',
57  description: 'To explode, of course!',
58  main: 'index.js',
59  dependencies: {
60    d1: 'file:../d1',
61    d2: 'file:../d2'
62  }
63}
64
65var blart = `
66var rando = require('crypto').randomBytes
67var resolve = require('path').resolve
68
69var mkdirp = require('mkdirp')
70var rimraf = require('rimraf')
71var writeFile = require('graceful-fs').writeFile
72
73var BASEDIR = resolve(__dirname, 'arena')
74
75var keepItGoingLouder = {}
76var writers = 0
77var errors = 0
78
79function gensym () { return rando(16).toString('hex') }
80
81function writeAlmostForever (filename) {
82  if (!keepItGoingLouder[filename]) {
83    writers--
84    if (writers < 1) return done()
85  } else {
86    writeFile(filename, keepItGoingLouder[filename], function (err) {
87      if (err) errors++
88
89      writeAlmostForever(filename)
90    })
91  }
92}
93
94function done () {
95  rimraf(BASEDIR, function () {
96    if (errors > 0) console.log('not ok - %d errors', errors)
97    else console.log('ok')
98  })
99}
100
101mkdirp(BASEDIR, function go () {
102  for (var i = 0; i < 16; i++) {
103    var filename = resolve(BASEDIR, gensym() + '.txt')
104
105    keepItGoingLouder[filename] = ''
106    for (var j = 0; j < 512; j++) keepItGoingLouder[filename] += filename
107
108    writers++
109    writeAlmostForever(filename)
110  }
111
112  setTimeout(function viktor () {
113    // kill all the writers
114    keepItGoingLouder = {}
115  }, 3 * 1000)
116})
117`
118
119test('setup', function (t) {
120  const badServer = createServer(function (req, res) {
121    setTimeout(function () {
122      res.writeHead(404)
123      res.end()
124    }, 1000)
125  }).listen(serverPort, () => t.parent.teardown(() => badServer.close()))
126
127  mkdirp.sync(pkg)
128  fs.writeFileSync(
129    path.join(pkg, 'package.json'),
130    JSON.stringify(json, null, 2)
131  )
132
133  mkdirp.sync(path.join(deps, 'd1'))
134  fs.writeFileSync(
135    path.join(deps, 'd1', 'package.json'),
136    JSON.stringify(d1, null, 2)
137  )
138
139  mkdirp.sync(path.join(deps, 'd2'))
140  fs.writeFileSync(
141    path.join(deps, 'd2', 'package.json'),
142    JSON.stringify(d2, null, 2)
143  )
144  fs.writeFileSync(path.join(deps, 'd2', 'blart.js'), blart)
145
146  mkdirp.sync(path.join(deps, 'opdep'))
147  fs.writeFileSync(
148    path.join(deps, 'opdep', 'package.json'),
149    JSON.stringify(opdep_json, null, 2)
150  )
151  mr({ port: common.port }, function (er, server) {
152    t.parent.teardown(() => server.close())
153    t.end()
154  })
155})
156
157test('go go test racer', t => common.npm(
158  [
159    '--prefix', pkg,
160    '--fetch-retries', '0',
161    '--loglevel', 'error',
162    '--no-progress',
163    '--registry', common.registry,
164    '--parseable',
165    '--cache', cache,
166    'install'
167  ],
168  {
169    cwd: pkg,
170    env: {
171      PATH: process.env.PATH,
172      Path: process.env.Path
173    },
174    stdio: 'pipe'
175  }
176).spread((code, stdout, stderr) => {
177  t.comment(stdout.trim())
178  t.comment(stderr.trim())
179  t.is(code, 0, 'npm install exited with code 0')
180  t.notOk(/not ok/.test(stdout), 'should not contain the string \'not ok\'')
181}))
182
183test('verify results', function (t) {
184  t.throws(function () {
185    fs.statSync(opdep)
186  })
187  t.end()
188})
189