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