UNPKG

koffi

Version:

Fast and simple C FFI (foreign function interface) for Node.js

99 lines (81 loc) 2.74 kB
'use strict'; const assert = require('assert'); const isMainProcess = process.argv[1] !== __filename; /** * In order to test that the event loop exits even with an active TSFN, we need * to spawn a new process for the test. * - Main process: spawns new node instance, executing this script * - Child process: creates TSFN. Native module Unref's via setTimeout after some time but does NOT call Release. * * Main process should expect child process to exit. * * We also added a new test case for `Ref`. The idea being, if a TSFN is active, the event loop that it belongs to should not exit * Our setup is similar to the test for the `Unref` case, with the difference being now we are expecting the child process to hang */ if (isMainProcess) { module.exports = require('../common').runTestWithBindingPath(test); } else { const isTestingRef = (process.argv[3] === 'true'); if (isTestingRef) { execTSFNRefTest(process.argv[2]); } else { execTSFNUnrefTest(process.argv[2]); } } function testUnRefCallback (resolve, reject, bindingFile) { const child = require('../napi_child').spawn(process.argv[0], [ '--expose-gc', __filename, bindingFile, false ], { stdio: 'inherit' }); let timeout = setTimeout(function () { child.kill(); timeout = 0; reject(new Error('Expected child to die')); }, 5000); child.on('error', (err) => { clearTimeout(timeout); timeout = 0; reject(new Error(err)); }); child.on('close', (code) => { if (timeout) clearTimeout(timeout); assert.strictEqual(code, 0, 'Expected return value 0'); resolve(); }); } function testRefCallback (resolve, reject, bindingFile) { const child = require('../napi_child').spawn(process.argv[0], [ '--expose-gc', __filename, bindingFile, true ], { stdio: 'inherit' }); let timeout = setTimeout(function () { child.kill(); timeout = 0; resolve(); }, 1000); child.on('error', (err) => { clearTimeout(timeout); timeout = 0; reject(new Error(err)); }); child.on('close', (code) => { if (timeout) clearTimeout(timeout); reject(new Error('We expected Child to hang')); }); } function test (bindingFile) { // Main process return new Promise((resolve, reject) => { testUnRefCallback(resolve, reject, bindingFile); }).then(() => { return new Promise((resolve, reject) => { testRefCallback(resolve, reject, bindingFile); }); }); } function execTSFNUnrefTest (bindingFile) { const binding = require(bindingFile); binding.threadsafe_function_unref.testUnref({}, () => { }); } function execTSFNRefTest (bindingFile) { const binding = require(bindingFile); binding.threadsafe_function_unref.testRef({}, () => { }); }