Skip to content

Commit

Permalink
test: fix unreliable assumption in js-native-api/test_cannot_run_js
Browse files Browse the repository at this point in the history
Previously the test assumes that when the queued finalizer is run,
it must be run at a point where env->can_call_into_js() is false
(typically, during Environment shutdown), which is not certain.
If GC kicks in early and the second pass finalizer is queued before
the event loop runs the check callbacks, the finalizer would then
be called in check callbacks (via native immediates), where
the finalizer can still call into JS. Essentially, addons can't
make assumptions about where the queued finalizer would be called.
This patch updates the assertions in the test to account for that.

PR-URL: #51898
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
  • Loading branch information
joyeecheung authored and richardlau committed Mar 25, 2024
1 parent dcbf88f commit 136b6a9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
32 changes: 24 additions & 8 deletions test/js-native-api/test_cannot_run_js/test_cannot_run_js.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,33 @@
static void Finalize(napi_env env, void* data, void* hint) {
napi_value global, set_timeout;
napi_ref* ref = data;

NODE_API_NOGC_ASSERT_RETURN_VOID(
napi_delete_reference(env, *ref) == napi_ok,
"deleting reference in finalizer should succeed");
NODE_API_NOGC_ASSERT_RETURN_VOID(
napi_get_global(env, &global) == napi_ok,
"getting global reference in finalizer should succeed");
napi_status result =
napi_get_named_property(env, global, "setTimeout", &set_timeout);

// The finalizer could be invoked either from check callbacks (as native
// immediates) if the event loop is still running (where napi_ok is returned)
// or during environment shutdown (where napi_cannot_run_js or
// napi_pending_exception is returned). This is not deterministic from
// the point of view of the addon.

#ifdef NAPI_EXPERIMENTAL
napi_status expected_status = napi_cannot_run_js;
NODE_API_NOGC_ASSERT_RETURN_VOID(
result == napi_cannot_run_js || result == napi_ok,
"getting named property from global in finalizer should succeed "
"or return napi_cannot_run_js");
#else
napi_status expected_status = napi_pending_exception;
NODE_API_NOGC_ASSERT_RETURN_VOID(
result == napi_pending_exception || result == napi_ok,
"getting named property from global in finalizer should succeed "
"or return napi_pending_exception");
#endif // NAPI_EXPERIMENTAL

if (napi_delete_reference(env, *ref) != napi_ok) abort();
if (napi_get_global(env, &global) != napi_ok) abort();
if (napi_get_named_property(env, global, "setTimeout", &set_timeout) !=
expected_status)
abort();
free(ref);
}

Expand Down
1 change: 0 additions & 1 deletion test/root.status
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[true]
js-native-api/test_cannot_run_js/test: PASS,FLAKY

[$mode==debug]
async-hooks/test-callback-error: SLOW
Expand Down

0 comments on commit 136b6a9

Please sign in to comment.