Skip to content

Commit

Permalink
test: adding ref for threadsafefunctions
Browse files Browse the repository at this point in the history
PR-URL: #1222
Reviewed-By: Michael Dawson <midawson@redhat.com>
  • Loading branch information
JckXia authored and mhdawson committed Oct 26, 2022
1 parent a8afb2d commit e408804
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 29 deletions.
13 changes: 13 additions & 0 deletions test/threadsafe_function/threadsafe_function_unref.cc
Expand Up @@ -31,11 +31,24 @@ static Value TestUnref(const CallbackInfo& info) {
return info.Env().Undefined();
}

static Value TestRef(const CallbackInfo& info) {
Function cb = info[1].As<Function>();

auto tsfn = ThreadSafeFunction::New(info.Env(), cb, "testRes", 1, 1);

tsfn.BlockingCall();
tsfn.Unref(info.Env());
tsfn.Ref(info.Env());

return info.Env().Undefined();
}

} // namespace

Object InitThreadSafeFunctionUnref(Env env) {
Object exports = Object::New(env);
exports["testUnref"] = Function::New(env, TestUnref);
exports["testRef"] = Function::New(env, TestRef);
return exports;
}

Expand Down
103 changes: 74 additions & 29 deletions test/threadsafe_function/threadsafe_function_unref.js
Expand Up @@ -11,43 +11,88 @@ const isMainProcess = process.argv[1] !== __filename;
* - 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 {
test(process.argv[2]);
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) {
if (isMainProcess) {
// Main process
// Main process
return new Promise((resolve, reject) => {
testUnRefCallback(resolve, reject, bindingFile);
}).then(() => {
return new Promise((resolve, reject) => {
const child = require('../napi_child').spawn(process.argv[0], [
'--expose-gc', __filename, bindingFile
], { 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();
});
testRefCallback(resolve, reject, bindingFile);
});
} else {
// Child process
const binding = require(bindingFile);
binding.threadsafe_function_unref.testUnref({}, () => { });
}
});
}

function execTSFNUnrefTest (bindingFile) {
const binding = require(bindingFile);
binding.threadsafe_function_unref.testUnref({}, () => { });
}

function execTSFNRefTest (bindingFile) {
const binding = require(bindingFile);
binding.threadsafe_function_unref.testRef({}, () => { });
}

0 comments on commit e408804

Please sign in to comment.