'use strict'; const common = require('../common'); const assert = require('assert'); const { Worker, isMainThread } = require('worker_threads'); const { once } = require('events'); const fs = require('fs'); if (!isMainThread) common.skip('test needs to be able to freely set `trackUnmanagedFds`'); // All the tests here are run sequentially, to avoid accidentally opening an fd // which another part of the test expects to be closed. const preamble = ` const fs = require("fs"); const { parentPort } = require('worker_threads'); const __filename = ${JSON.stringify(__filename)}; process.on('warning', (warning) => parentPort.postMessage({ warning })); `; (async () => { // Consistency check: Without trackUnmanagedFds, FDs are *not* closed. { const w = new Worker(`${preamble} parentPort.postMessage(fs.openSync(__filename)); `, { eval: true, trackUnmanagedFds: false }); const [ [ fd ] ] = await Promise.all([once(w, 'message'), once(w, 'exit')]); assert(fd > 2); fs.fstatSync(fd); // Does not throw. fs.closeSync(fd); } // With trackUnmanagedFds, FDs are closed automatically. { const w = new Worker(`${preamble} parentPort.postMessage(fs.openSync(__filename)); `, { eval: true, trackUnmanagedFds: true }); const [ [ fd ] ] = await Promise.all([once(w, 'message'), once(w, 'exit')]); assert(fd > 2); assert.throws(() => fs.fstatSync(fd), { code: 'EBADF' }); } // The same, but trackUnmanagedFds is used only as the implied default. { const w = new Worker(`${preamble} parentPort.postMessage(fs.openSync(__filename)); `, { eval: true }); const [ [ fd ] ] = await Promise.all([once(w, 'message'), once(w, 'exit')]); assert(fd > 2); assert.throws(() => fs.fstatSync(fd), { code: 'EBADF' }); } // There is a warning when an fd is unexpectedly opened twice. { const w = new Worker(`${preamble} parentPort.postMessage(fs.openSync(__filename)); parentPort.once('message', () => { const reopened = fs.openSync(__filename); fs.closeSync(reopened); }); `, { eval: true, trackUnmanagedFds: true }); const [ fd ] = await once(w, 'message'); fs.closeSync(fd); w.postMessage(''); const [ { warning } ] = await once(w, 'message'); assert.match(warning.message, /File descriptor \d+ opened in unmanaged mode twice/); } // There is a warning when an fd is unexpectedly closed. { const w = new Worker(`${preamble} parentPort.once('message', (fd) => { fs.closeSync(fd); }); `, { eval: true, trackUnmanagedFds: true }); w.postMessage(fs.openSync(__filename)); const [ { warning } ] = await once(w, 'message'); assert.match(warning.message, /File descriptor \d+ closed but not opened in unmanaged mode/); } })().then(common.mustCall());