-
Notifications
You must be signed in to change notification settings - Fork 30.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: fix flaky test-fs-watch-encoding on OS X
PR-URL: #7356 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
- Loading branch information
Showing
1 changed file
with
43 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,75 @@ | ||
'use strict'; | ||
|
||
// This test is a bit more complicated than it ideally needs to be to work | ||
// around issues on OS X and SmartOS. | ||
// | ||
// On OS X, watch events are subject to peculiar timing oddities such that an | ||
// event might fire out of order. The synchronous refreshing of the tmp | ||
// directory might trigger an event on the watchers that are instantiated after | ||
// it! | ||
// | ||
// On SmartOS, the watch events fire but the filename is null. | ||
|
||
const common = require('../common'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const assert = require('assert'); | ||
|
||
if (common.isFreeBSD) { | ||
common.skip('Test currently not working on FreeBSD'); | ||
return; | ||
} | ||
|
||
common.refreshTmpDir(); | ||
|
||
const fn = '新建文夹件.txt'; | ||
const a = path.join(common.tmpDir, fn); | ||
|
||
const watchers = new Set(); | ||
|
||
function registerWatcher(watcher) { | ||
watchers.add(watcher); | ||
} | ||
|
||
function unregisterWatcher(watcher) { | ||
watcher.close(); | ||
watchers.delete(watcher); | ||
if (watchers.size === 0) { | ||
clearInterval(interval); | ||
} | ||
} | ||
|
||
const watcher1 = fs.watch( | ||
common.tmpDir, | ||
{encoding: 'hex'}, | ||
(event, filename) => { | ||
if (filename) | ||
assert.equal(filename, 'e696b0e5bbbae69687e5a4b9e4bbb62e747874'); | ||
watcher1.close(); | ||
if (['e696b0e5bbbae69687e5a4b9e4bbb62e747874', null].includes(filename)) | ||
done(watcher1); | ||
} | ||
); | ||
registerWatcher(watcher1); | ||
|
||
const watcher2 = fs.watch( | ||
common.tmpDir, | ||
(event, filename) => { | ||
if (filename) | ||
assert.equal(filename, fn); | ||
watcher2.close(); | ||
if ([fn, null].includes(filename)) | ||
done(watcher2); | ||
} | ||
); | ||
registerWatcher(watcher2); | ||
|
||
const watcher3 = fs.watch( | ||
common.tmpDir, | ||
{encoding: 'buffer'}, | ||
(event, filename) => { | ||
if (filename) { | ||
assert(filename instanceof Buffer); | ||
assert.equal(filename.toString('utf8'), fn); | ||
} | ||
watcher3.close(); | ||
if (filename instanceof Buffer && filename.toString('utf8') === fn) | ||
done(watcher3); | ||
else if (filename === null) | ||
done(watcher3); | ||
} | ||
); | ||
registerWatcher(watcher3); | ||
|
||
const fd = fs.openSync(a, 'w+'); | ||
fs.closeSync(fd); | ||
const done = common.mustCall(unregisterWatcher, watchers.size); | ||
|
||
process.on('exit', () => { | ||
fs.unlink(a); | ||
}); | ||
// OS X and perhaps other systems can have surprising race conditions with | ||
// file events. So repeat the operation in case it is missed the first time. | ||
const interval = setInterval(() => { | ||
const fd = fs.openSync(a, 'w+'); | ||
fs.closeSync(fd); | ||
fs.unlinkSync(a); | ||
}, common.platformTimeout(100)); |