Skip to content

Commit

Permalink
test: add finalizer exception test
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Schulhof committed Jul 9, 2020
1 parent ef16dfb commit 698b105
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
15 changes: 15 additions & 0 deletions test/external.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,28 @@ Value GetFinalizeCount(const CallbackInfo& info) {
return Number::New(info.Env(), finalizeCount);
}

Value CreateExternalWithFinalizeException(const CallbackInfo& info) {
return External<int>::New(info.Env(), new int(1),
[](Env env, int* data) {
Error error = Error::New(env, "Finalizer exception");
delete data;
#ifdef NAPI_CPP_EXCEPTIONS
throw error;
#else
error.ThrowAsJavaScriptException();
#endif
});
}

} // end anonymous namespace

Object InitExternal(Env env) {
Object exports = Object::New(env);

exports["createExternal"] = Function::New(env, CreateExternal);
exports["createExternalWithFinalize"] = Function::New(env, CreateExternalWithFinalize);
exports["createExternalWithFinalizeException"] =
Function::New(env, CreateExternalWithFinalizeException);
exports["createExternalWithFinalizeHint"] = Function::New(env, CreateExternalWithFinalizeHint);
exports["checkExternal"] = Function::New(env, CheckExternal);
exports["getFinalizeCount"] = Function::New(env, GetFinalizeCount);
Expand Down
33 changes: 30 additions & 3 deletions test/external.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
'use strict';
const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');
const path = require('path');
const { spawnSync } = require('child_process');
const testUtil = require('./testUtil');

test(require(`./build/${buildType}/binding.node`));
test(require(`./build/${buildType}/binding_noexcept.node`));
if (process.argv.length === 3) {
let x =
require(process.argv[2]).external.createExternalWithFinalizeException();
x = null;

function test(binding) {
// Keep calling `global.gc()` until it throws.
const interval = setInterval(() => {
try {
global.gc();
} catch (anException) {
assert(!!anException.message.match(/Finalizer exception/));
clearInterval(interval);
process.exit(0);
}
}, 100);
return;
}

test(path.resolve(path.join(__dirname, `./build/${buildType}/binding.node`)));
test(path.resolve(path.join(__dirname,
`./build/${buildType}/binding_noexcept.node`)));

function test(bindingPath) {
const binding = require(bindingPath);
testUtil.runGCTests([
'External without finalizer',
() => {
Expand Down Expand Up @@ -41,4 +63,9 @@ function test(binding) {
assert.strictEqual(1, binding.external.getFinalizeCount());
},
]);

const child = spawnSync(process.execPath, [
'--expose-gc', __filename, bindingPath
], { stdio: 'inherit' });
assert(!child.signal && child.status === 0);
}

0 comments on commit 698b105

Please sign in to comment.