/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v26.5.1
test/async-hooks/test-statwatcher.js
133 строки
4 KB
Trivikram Kamat
test: deflake async-hooks statwatcher test
27 май 2026, 12:35
Не верифицирован
27 май 2026, 12:35
1bf875b
Код
Авторство
О чём код?
'use strict'; const common = require('../common'); const tmpdir = require('../common/tmpdir'); const assert = require('assert'); const initHooks = require('./init-hooks'); const { checkInvocations } = require('./hook-checks'); const fs = require('fs'); const { isMainThread } = require('worker_threads'); if (!isMainThread) { common.skip('Worker bootstrapping works differently -> different async IDs'); } tmpdir.refresh(); const file1 = tmpdir.resolve('file1'); const file2 = tmpdir.resolve('file2'); const onchangex = (x) => (curr, prev) => { console.log(`Watcher: ${x}`); console.log('current stat data:', curr); console.log('previous stat data:', prev); }; const checkWatcherStart = common.mustCall((name, watcher) => { assert.strictEqual(watcher.type, 'STATWATCHER'); assert.strictEqual(typeof watcher.uid, 'number'); assert.strictEqual(watcher.triggerAsyncId, 1); checkInvocations(watcher, { init: 1 }, `${name}: when started to watch file`); }, 2); const hooks = initHooks(); hooks.enable(); // Install first file watcher. const w1 = fs.watchFile(file1, { interval: 10 }, onchangex('w1')); let as = hooks.activitiesOfTypes('STATWATCHER'); assert.strictEqual(as.length, 1); // Count all change events to account for all of them in checkInvocations. let w1HookCount = 0; w1.on('change', () => w1HookCount++); const statwatcher1 = as[0]; checkWatcherStart('watcher1', statwatcher1); // Install second file watcher const w2 = fs.watchFile(file2, { interval: 10 }, onchangex('w2')); as = hooks.activitiesOfTypes('STATWATCHER'); assert.strictEqual(as.length, 2); // Count all change events to account for all of them in checkInvocations. let w2HookCount = 0; w2.on('change', () => w2HookCount++); const statwatcher2 = as[1]; checkInvocations(statwatcher1, { init: 1 }, 'watcher1: when started to watch second file'); checkWatcherStart('watcher2', statwatcher2); let w2Initialized = false; let writeFile2AfterW1 = false; const onW2Initialized = (curr, prev) => { if (curr.nlink !== 0 || prev.nlink !== 0) return; w2.removeListener('change', onW2Initialized); w2Initialized = true; if (writeFile2AfterW1) { setTimeout(() => fs.writeFileSync(file2, 'bar++'), common.platformTimeout(100)); } }; w2.on('change', onW2Initialized); w1.on('change', common.mustCallAtLeast((curr, prev) => { console.log('w1 change to', curr, 'from', prev); // Wait for the initial ENOENT poll before creating the file. Otherwise the // first stat can race with the write and use the created file as the baseline. if (curr.nlink === 0 && prev.nlink === 0) { setTimeout(() => fs.writeFileSync(file1, 'foo++'), common.platformTimeout(100)); return; } // Wait until we get the write above. if (prev.size !== 0 || curr.size !== 5) return; setImmediate(common.mustCall(() => { checkInvocations(statwatcher1, { init: 1, before: w1HookCount, after: w1HookCount }, 'watcher1: when unwatched first file'); checkInvocations(statwatcher2, { init: 1 }, 'watcher2: when unwatched first file'); writeFile2AfterW1 = true; if (w2Initialized) { setTimeout(() => fs.writeFileSync(file2, 'bar++'), common.platformTimeout(100)); } w2.on('change', common.mustCallAtLeast((curr, prev) => { console.log('w2 change to', curr, 'from', prev); // Wait until we get the write above. if (prev.size !== 0 || curr.size !== 5) return; setImmediate(() => { checkInvocations(statwatcher1, { init: 1, before: w1HookCount, after: w1HookCount }, 'watcher1: when unwatched second file'); checkInvocations(statwatcher2, { init: 1, before: w2HookCount, after: w2HookCount }, 'watcher2: when unwatched second file'); fs.unwatchFile(file1); fs.unwatchFile(file2); }); })); })); })); process.once('exit', () => { hooks.disable(); hooks.sanityCheck('STATWATCHER'); checkInvocations(statwatcher1, { init: 1, before: w1HookCount, after: w1HookCount }, 'watcher1: when process exits'); checkInvocations(statwatcher2, { init: 1, before: w2HookCount, after: w2HookCount }, 'watcher2: when process exits'); });