2 var lockFile = require('../')
3 var test = require('tap').test
4 var path = require('path')
5 var lock = path.resolve(__dirname, 'stale.lock')
6 var touch = require('touch')
7 var spawn = require('child_process').spawn
8 var node = process.execPath
10 // We're using a lockfile with an artificially old date,
11 // so make it use that instead of ctime.
12 // Probably you should never do this in production!
13 lockFile.filetime = 'mtime'
15 if (process.argv[2] === 'child') {
20 // Make fs.stat take 100ms to return its data
21 // This is important because, in a test scenario where
22 // we're statting the same exact file rapid-fire like this,
23 // it'll end up being cached by the FS, and never trigger
24 // the race condition we're trying to expose.
25 fs.stat = function (stat) { return function () {
26 var args = [].slice.call(arguments)
28 stat.apply(fs, args.concat(function(er, st) {
29 setTimeout(function () {
35 lockFile.lock(lock, { stale: 100000 }, function (er) {
36 if (er && er.code !== 'EEXIST')
41 setTimeout(function(){}, 500)
45 test('create stale file', function (t) {
46 try { fs.unlinkSync(lock) } catch (er) {}
47 touch.sync(lock, { time: '1979-07-01T19:10:00.000Z' })
51 test('contenders', function (t) {
55 var args = [ __filename, 'child' ]
56 var opt = { stdio: [0, "pipe", 2] }
57 for (var i = 0; i < n; i++) {
58 spawn(node, args, opt).on('close', then)
61 function then (code) {
65 t.fail("unexpected failure", code)
70 if (fails + wins === n) {
76 t.equal(wins, 1, "should have 1 lock winner")
77 t.equal(fails, n - 1, "all others should lose")
82 test('remove stale file', function (t) {
83 try { fs.unlinkSync(lock) } catch (er) {}