diff --git a/lib/internal/vfs/providers/real.js b/lib/internal/vfs/providers/real.js index 2f25f582244c..a3a5d6329a93 100644 --- a/lib/internal/vfs/providers/real.js +++ b/lib/internal/vfs/providers/real.js @@ -632,9 +632,9 @@ class RealFSProvider extends VirtualProvider { return fs.promises.watch(realPath, options); } - watchFile(vfsPath, options) { + watchFile(vfsPath, options, listener) { const realPath = this.#resolvePath(vfsPath); - return fs.watchFile(realPath, options, () => {}); + return fs.watchFile(realPath, options, listener); } unwatchFile(vfsPath, listener) { diff --git a/test/parallel/test-vfs-real-provider-watch.js b/test/parallel/test-vfs-real-provider-watch.js index 056744c5fd0c..d0f30b75233a 100644 --- a/test/parallel/test-vfs-real-provider-watch.js +++ b/test/parallel/test-vfs-real-provider-watch.js @@ -35,10 +35,20 @@ assert.strictEqual(myVfs.provider.supportsWatch, true); await iter.return(); })().then(common.mustCall()); -// watchFile / unwatchFile +// watchFile / unwatchFile: the listener must be forwarded to the real fs +// watcher (not stubbed), fire on change, and be removable by identity. { fs.writeFileSync(path.join(root, 'wf.txt'), 'a'); - const listener = () => {}; - myVfs.watchFile('/wf.txt', { persistent: false }, listener); - myVfs.unwatchFile('/wf.txt', listener); + const listener = common.mustCall(); + myVfs.watchFile('/wf.txt', { interval: 10, persistent: false }, listener); + // uv_fs_poll records the first stat asynchronously as the baseline and + // only reports subsequent changes, so mutate the file only after that + // baseline reflects 'a'; otherwise the change is folded into the baseline + // and the listener never fires. Change the size too, because some + // platforms (e.g. AIX) only report timestamps to the second, so a + // same-size rewrite within that second would look unchanged. + setTimeout(() => fs.writeFileSync(path.join(root, 'wf.txt'), 'bb'), 100); + setTimeout(() => { + myVfs.unwatchFile('/wf.txt', listener); + }, 500); }