1'use strict'; 2 3const common = require('../common'); 4const tmpdir = require('../common/tmpdir'); 5const assert = require('assert'); 6const initHooks = require('./init-hooks'); 7const { checkInvocations } = require('./hook-checks'); 8const fs = require('fs'); 9const path = require('path'); 10 11if (!common.isMainThread) 12 common.skip('Worker bootstrapping works differently -> different async IDs'); 13 14tmpdir.refresh(); 15 16const file1 = path.join(tmpdir.path, 'file1'); 17const file2 = path.join(tmpdir.path, 'file2'); 18 19const onchangex = (x) => (curr, prev) => { 20 console.log(`Watcher: ${x}`); 21 console.log('current stat data:', curr); 22 console.log('previous stat data:', prev); 23}; 24 25const checkWatcherStart = (name, watcher) => { 26 assert.strictEqual(watcher.type, 'STATWATCHER'); 27 assert.strictEqual(typeof watcher.uid, 'number'); 28 assert.strictEqual(watcher.triggerAsyncId, 1); 29 checkInvocations(watcher, { init: 1 }, 30 `${name}: when started to watch file`); 31}; 32 33const hooks = initHooks(); 34hooks.enable(); 35 36// Install first file watcher. 37const w1 = fs.watchFile(file1, { interval: 10 }, onchangex('w1')); 38let as = hooks.activitiesOfTypes('STATWATCHER'); 39assert.strictEqual(as.length, 1); 40// Count all change events to account for all of them in checkInvocations. 41let w1HookCount = 0; 42w1.on('change', () => w1HookCount++); 43 44const statwatcher1 = as[0]; 45checkWatcherStart('watcher1', statwatcher1); 46 47// Install second file watcher 48const w2 = fs.watchFile(file2, { interval: 10 }, onchangex('w2')); 49as = hooks.activitiesOfTypes('STATWATCHER'); 50assert.strictEqual(as.length, 2); 51// Count all change events to account for all of them in checkInvocations. 52let w2HookCount = 0; 53w2.on('change', () => w2HookCount++); 54 55const statwatcher2 = as[1]; 56checkInvocations(statwatcher1, { init: 1 }, 57 'watcher1: when started to watch second file'); 58checkWatcherStart('watcher2', statwatcher2); 59 60setTimeout(() => fs.writeFileSync(file1, 'foo++'), 61 common.platformTimeout(100)); 62w1.on('change', common.mustCallAtLeast((curr, prev) => { 63 console.log('w1 change to', curr, 'from', prev); 64 // Wait until we get the write above. 65 if (prev.size !== 0 || curr.size !== 5) 66 return; 67 68 setImmediate(() => { 69 checkInvocations(statwatcher1, 70 { init: 1, before: w1HookCount, after: w1HookCount }, 71 'watcher1: when unwatched first file'); 72 checkInvocations(statwatcher2, { init: 1 }, 73 'watcher2: when unwatched first file'); 74 75 setTimeout(() => fs.writeFileSync(file2, 'bar++'), 76 common.platformTimeout(100)); 77 w2.on('change', common.mustCallAtLeast((curr, prev) => { 78 console.log('w2 change to', curr, 'from', prev); 79 // Wait until we get the write above. 80 if (prev.size !== 0 || curr.size !== 5) 81 return; 82 83 setImmediate(() => { 84 checkInvocations(statwatcher1, 85 { init: 1, before: w1HookCount, after: w1HookCount }, 86 'watcher1: when unwatched second file'); 87 checkInvocations(statwatcher2, 88 { init: 1, before: w2HookCount, after: w2HookCount }, 89 'watcher2: when unwatched second file'); 90 fs.unwatchFile(file1); 91 fs.unwatchFile(file2); 92 }); 93 })); 94 }); 95})); 96 97process.once('exit', () => { 98 hooks.disable(); 99 hooks.sanityCheck('STATWATCHER'); 100 checkInvocations(statwatcher1, 101 { init: 1, before: w1HookCount, after: w1HookCount }, 102 'watcher1: when process exits'); 103 checkInvocations(statwatcher2, 104 { init: 1, before: w2HookCount, after: w2HookCount }, 105 'watcher2: when process exits'); 106}); 107