1'use strict'; 2const common = require('../common'); 3const assert = require('assert'); 4const { Worker } = require('worker_threads'); 5const { once } = require('events'); 6const fs = require('fs'); 7 8// All the tests here are run sequentially, to avoid accidentally opening an fd 9// which another part of the test expects to be closed. 10 11const preamble = ` 12const fs = require("fs"); 13const { parentPort } = require('worker_threads'); 14const __filename = ${JSON.stringify(__filename)}; 15process.on('warning', (warning) => parentPort.postMessage({ warning })); 16`; 17 18(async () => { 19 // Consistency check: Without trackUnmanagedFds, FDs are *not* closed. 20 { 21 const w = new Worker(`${preamble} 22 parentPort.postMessage(fs.openSync(__filename)); 23 `, { eval: true, trackUnmanagedFds: false }); 24 const [ [ fd ] ] = await Promise.all([once(w, 'message'), once(w, 'exit')]); 25 assert(fd > 2); 26 fs.fstatSync(fd); // Does not throw. 27 fs.closeSync(fd); 28 } 29 30 // With trackUnmanagedFds, FDs are closed automatically. 31 { 32 const w = new Worker(`${preamble} 33 parentPort.postMessage(fs.openSync(__filename)); 34 `, { eval: true, trackUnmanagedFds: true }); 35 const [ [ fd ] ] = await Promise.all([once(w, 'message'), once(w, 'exit')]); 36 assert(fd > 2); 37 assert.throws(() => fs.fstatSync(fd), { code: 'EBADF' }); 38 } 39 40 // There is a warning when an fd is unexpectedly opened twice. 41 { 42 const w = new Worker(`${preamble} 43 parentPort.postMessage(fs.openSync(__filename)); 44 parentPort.once('message', () => { 45 const reopened = fs.openSync(__filename); 46 fs.closeSync(reopened); 47 }); 48 `, { eval: true, trackUnmanagedFds: true }); 49 const [ fd ] = await once(w, 'message'); 50 fs.closeSync(fd); 51 w.postMessage(''); 52 const [ { warning } ] = await once(w, 'message'); 53 assert.match(warning.message, 54 /File descriptor \d+ opened in unmanaged mode twice/); 55 } 56 57 // There is a warning when an fd is unexpectedly closed. 58 { 59 const w = new Worker(`${preamble} 60 parentPort.once('message', (fd) => { 61 fs.closeSync(fd); 62 }); 63 `, { eval: true, trackUnmanagedFds: true }); 64 w.postMessage(fs.openSync(__filename)); 65 const [ { warning } ] = await once(w, 'message'); 66 assert.match(warning.message, 67 /File descriptor \d+ closed but not opened in unmanaged mode/); 68 } 69})().then(common.mustCall()); 70