koffi
Version:
Fast and simple C FFI (foreign function interface) for Node.js
86 lines (75 loc) • 2.76 kB
JavaScript
const assert = require('assert');
const { spawnSync } = require('child_process');
const testUtil = require('./testUtil');
if (process.argv.length === 3) {
let interval;
// Running as the child process, hook up an `uncaughtException` handler to
// examine the error thrown by the finalizer.
process.on('uncaughtException', (error) => {
// TODO (gabrielschulhof): Use assert.matches() when we drop support for
// Node.js v10.x.
assert(!!error.message.match(/Finalizer exception/));
if (interval) {
clearInterval(interval);
}
process.exit(0);
});
// Create an external whose finalizer throws.
(() =>
require(process.argv[2]).external.createExternalWithFinalizeException())();
// gc until the external's finalizer throws or until we give up. Since the
// exception is thrown from a native `SetImmediate()` we cannot catch it
// anywhere except in the process' `uncaughtException` handler.
let maxGCTries = 10;
(function gcInterval () {
global.gc();
if (!interval) {
interval = setInterval(gcInterval, 100);
} else if (--maxGCTries === 0) {
throw new Error('Timed out waiting for the gc to throw');
}
})();
} else {
module.exports = require('./common').runTestWithBindingPath(test);
function test (bindingPath) {
const binding = require(bindingPath);
const child = spawnSync(process.execPath, [
'--expose-gc', __filename, bindingPath
], { stdio: 'inherit' });
assert.strictEqual(child.status, 0);
assert.strictEqual(child.signal, null);
return testUtil.runGCTests([
'External without finalizer',
() => {
const test = binding.external.createExternal();
assert.strictEqual(typeof test, 'object');
binding.external.checkExternal(test);
assert.strictEqual(0, binding.external.getFinalizeCount());
},
() => {
assert.strictEqual(0, binding.external.getFinalizeCount());
},
'External with finalizer',
() => {
const test = binding.external.createExternalWithFinalize();
assert.strictEqual(typeof test, 'object');
binding.external.checkExternal(test);
assert.strictEqual(0, binding.external.getFinalizeCount());
},
() => {
assert.strictEqual(1, binding.external.getFinalizeCount());
},
'External with finalizer hint',
() => {
const test = binding.external.createExternalWithFinalizeHint();
assert.strictEqual(typeof test, 'object');
binding.external.checkExternal(test);
assert.strictEqual(0, binding.external.getFinalizeCount());
},
() => {
assert.strictEqual(1, binding.external.getFinalizeCount());
}
]);
}
}
;