Skip to content

Commit 225ca35

Browse files
authored
test: Add test coverage for "TSFN::Ref()" (#1196)
* test:Reference the tsfn * test: Add a more sophiscated test case for ref * test: Unref tsfn before ref'n it again * test: Using different function overload
1 parent 5a5a213 commit 225ca35

File tree

2 files changed

+88
-29
lines changed

2 files changed

+88
-29
lines changed

test/typed_threadsafe_function/typed_threadsafe_function_unref.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ static Value TestUnref(const CallbackInfo& info) {
3232
static_cast<FinalizerDataType*>(nullptr));
3333

3434
tsfn->BlockingCall();
35+
tsfn->Ref(info.Env());
3536

3637
setTimeout.Call(
3738
global,
@@ -42,11 +43,24 @@ static Value TestUnref(const CallbackInfo& info) {
4243
return info.Env().Undefined();
4344
}
4445

46+
static Value TestRef(const CallbackInfo& info) {
47+
Function cb = info[1].As<Function>();
48+
49+
auto tsfn = TSFN::New(info.Env(), cb, "testRes", 1, 1, nullptr);
50+
51+
tsfn.BlockingCall();
52+
tsfn.Unref(info.Env());
53+
tsfn.Ref(info.Env());
54+
55+
return info.Env().Undefined();
56+
}
57+
4558
} // namespace
4659

4760
Object InitTypedThreadSafeFunctionUnref(Env env) {
4861
Object exports = Object::New(env);
4962
exports["testUnref"] = Function::New(env, TestUnref);
63+
exports["testRef"] = Function::New(env, TestRef);
5064
return exports;
5165
}
5266

test/typed_threadsafe_function/typed_threadsafe_function_unref.js

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,88 @@ const isMainProcess = process.argv[1] !== __filename;
1111
* - Child process: creates TSFN. Native module Unref's via setTimeout after some time but does NOT call Release.
1212
*
1313
* Main process should expect child process to exit.
14+
*
15+
* 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
16+
* Our setup is similar to the test for the `Unref` case, with the difference being now we are expecting the child process to hang
1417
*/
1518

1619
if (isMainProcess) {
1720
module.exports = require('../common').runTestWithBindingPath(test);
1821
} else {
19-
test(process.argv[2]);
22+
const isTestingRef = (process.argv[3] === 'true');
23+
24+
if (isTestingRef) {
25+
execTSFNRefTest(process.argv[2]);
26+
} else {
27+
execTSFNUnrefTest(process.argv[2]);
28+
}
29+
}
30+
31+
function testUnRefCallback (resolve, reject, bindingFile) {
32+
const child = require('../napi_child').spawn(process.argv[0], [
33+
'--expose-gc', __filename, bindingFile, false
34+
], { stdio: 'inherit' });
35+
36+
let timeout = setTimeout(function () {
37+
child.kill();
38+
timeout = 0;
39+
reject(new Error('Expected child to die'));
40+
}, 5000);
41+
42+
child.on('error', (err) => {
43+
clearTimeout(timeout);
44+
timeout = 0;
45+
reject(new Error(err));
46+
});
47+
48+
child.on('close', (code) => {
49+
if (timeout) clearTimeout(timeout);
50+
assert.strictEqual(code, 0, 'Expected return value 0');
51+
resolve();
52+
});
53+
}
54+
55+
function testRefCallback (resolve, reject, bindingFile) {
56+
const child = require('../napi_child').spawn(process.argv[0], [
57+
'--expose-gc', __filename, bindingFile, true
58+
], { stdio: 'inherit' });
59+
60+
let timeout = setTimeout(function () {
61+
child.kill();
62+
timeout = 0;
63+
resolve();
64+
}, 1000);
65+
66+
child.on('error', (err) => {
67+
clearTimeout(timeout);
68+
timeout = 0;
69+
reject(new Error(err));
70+
});
71+
72+
child.on('close', (code) => {
73+
if (timeout) clearTimeout(timeout);
74+
75+
reject(new Error('We expected Child to hang'));
76+
});
2077
}
2178

2279
function test (bindingFile) {
23-
if (isMainProcess) {
24-
// Main process
80+
// Main process
81+
return new Promise((resolve, reject) => {
82+
testUnRefCallback(resolve, reject, bindingFile);
83+
}).then(() => {
2584
return new Promise((resolve, reject) => {
26-
const child = require('../napi_child').spawn(process.argv[0], [
27-
'--expose-gc', __filename, bindingFile
28-
], { stdio: 'inherit' });
29-
30-
let timeout = setTimeout(function () {
31-
child.kill();
32-
timeout = 0;
33-
reject(new Error('Expected child to die'));
34-
}, 5000);
35-
36-
child.on('error', (err) => {
37-
clearTimeout(timeout);
38-
timeout = 0;
39-
reject(new Error(err));
40-
});
41-
42-
child.on('close', (code) => {
43-
if (timeout) clearTimeout(timeout);
44-
assert.strictEqual(code, 0, 'Expected return value 0');
45-
resolve();
46-
});
85+
testRefCallback(resolve, reject, bindingFile);
4786
});
48-
} else {
49-
// Child process
50-
const binding = require(bindingFile);
51-
binding.typed_threadsafe_function_unref.testUnref({}, () => { });
52-
}
87+
});
88+
}
89+
90+
function execTSFNUnrefTest (bindingFile) {
91+
const binding = require(bindingFile);
92+
binding.typed_threadsafe_function_unref.testUnref({}, () => { });
93+
}
94+
95+
function execTSFNRefTest (bindingFile) {
96+
const binding = require(bindingFile);
97+
binding.typed_threadsafe_function_unref.testRef({}, () => { });
5398
}

0 commit comments

Comments
 (0)