Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

n-api: Reference and external tests #12551

Closed
wants to merge 2 commits into from
Closed

Conversation

jasongin
Copy link
Member

  • Add a test project to addons-napi that covers the N-API reference and external APIs
  • Fix a bug in napi_typeof() that was found by the new tests

This improves the code coverage of N-API by a few percent. See also #12219

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines
Affected core subsystem(s)

 - Add a test project to addons-napi that covers the
   N-API reference and external APIs
 - Fix a bug in napi_typeof that was found by the new tests
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. node-api Issues and PRs related to the Node-API. labels Apr 20, 2017
@jasongin
Copy link
Member Author

@mhdawson

Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if the CI is happy

assert.strictEqual(0, test_reference.finalizeCount);

// External value without a finalizer
let value = test_reference.createExternal();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you turn these groups into {} blocks and use const where that works? That makes it a bit easier to see how different parts of a test (don’t) interact :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const won't work because value must later be set to null in order to allow it to be garbage-collected.

... unless the scope of the { } blocks is narrowed to just around where each value is live. But then I think that would actually hurt readability because the blocks would not correspond to the logical test cases.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I think allowing value to go out of scope to enable GC is less obvious than assigning null.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @addaleax. Unless necessary for the purposes of the test, we've been moving toward using block scopes in the tests for better isolation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasongin Yea, let seems fine here. You can still do both assigning null and using block scopes, if you think that’s more readable (I would say it is)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'm adding block scopes around each test case, keeping the null assignment within.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in caf86ed

const common = require('../../common');
const assert = require('assert');

const test_reference = require(`./build/${common.buildType}/test_reference`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you stick to camelCase in JavaScript code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The underscore matches the name of the module. I was trying to follow precedent in node.js JavaScript code, often with the child_process module, for example at https://github.com/nodejs/node/blob/master/test/common.js#L28

assert.strictEqual(0, test_reference.finalizeCount);

// External value without a finalizer
let value = test_reference.createExternal();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @addaleax. Unless necessary for the purposes of the test, we've been moving toward using block scopes in the tests for better isolation.

// This test script uses external values with finalizer callbacks
// in order to track when values get garbage-collected. Each invocation
// of a finalizer callback increments the finalizeCount property.
assert.strictEqual(0, test_reference.finalizeCount);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change the order of the arguments to actual, expected in strictEqual() throughout the test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good catch. I'm used to some other testing frameworks that use the opposite order.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in caf86ed

 - Make test cases more isolated with block scoping
   and reset finalize count
 - Fix order of actual, expected in asserts
Copy link
Member

@mhdawson mhdawson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, subject to fixing up Colin's comment. I've seen lots of issues with tests relying on triggering a gc in the Java world, but provided this passes consistently well worth running.

@jasongin
Copy link
Member Author

I've responded to all the feedback. @cjihrig did you want to take another look?

Copy link
Contributor

@cjihrig cjihrig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think the JS code should camelCase, but ¯\_(ツ)_/¯

@mhdawson
Copy link
Member

@mhdawson
Copy link
Member

CI good landing

@mhdawson
Copy link
Member

Landed as 4271254

@mhdawson mhdawson closed this Apr 27, 2017
mhdawson pushed a commit that referenced this pull request Apr 27, 2017
 - Add a test project to addons-napi that covers the
   N-API reference and external APIs
 - Fix a bug in napi_typeof that was found by the new tests

PR-URL: #12551
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
@targos
Copy link
Member

targos commented Apr 28, 2017

The new test fails on the canary branch:

$ ./node --expose-gc --napi-modules test/addons-napi/test_reference/test.js

assert.js:86
  throw new assert.AssertionError({
  ^
AssertionError: [External] === undefined
    at Object.<anonymous> (/home/mzasso/git/nodejs/node-canary/test/addons-napi/test_reference/test.js:44:10)
    at Module._compile (module.js:582:30)
    at Object.Module._extensions..js (module.js:593:10)
    at Module.load (module.js:516:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Function.Module.runMain (module.js:618:10)
    at startup (bootstrap_node.js:144:16)
    at bootstrap_node.js:548:3

@jasongin jasongin deleted the reftests branch April 28, 2017 16:18
@jasongin
Copy link
Member Author

Apparently the GC behavior related to weak-references changed in the newer version of V8 that's in the canary branch. @mhdawson's concern above about tests relying on triggering GC has been validated.

I found that this test case can be fixed in the canary branch by triggering the GC after a setImmediate() callback (just before the failed assertion), though I don't understand why that's required now. Oddly the other test cases also using weak references didn't have any problem. So to avoid refactoring to deal with the one asynchronous test case, that one can be moved to the end.

@targos
Copy link
Member

targos commented May 5, 2017

@jasongin I'm trying to add this setImmediate callback but still get the same error:

diff --git a/test/addons-napi/test_reference/test.js b/test/addons-napi/test_reference/test.js
index ddfec58..645b852 100644
--- a/test/addons-napi/test_reference/test.js
+++ b/test/addons-napi/test_reference/test.js
@@ -34,19 +34,6 @@ assert.strictEqual(test_reference.finalizeCount, 0);
 }

 {
-  // Weak reference
-  let value = test_reference.createExternalWithFinalize();
-  assert.strictEqual(test_reference.finalizeCount, 0);
-  test_reference.createReference(value, 0);
-  assert.strictEqual(test_reference.referenceValue, value);
-  value = null;
-  global.gc(); // Value should be GC'd because there is only a weak ref
-  assert.strictEqual(test_reference.referenceValue, undefined);
-  assert.strictEqual(test_reference.finalizeCount, 1);
-  test_reference.deleteReference();
-}
-
-{
   // Strong reference
   let value = test_reference.createExternalWithFinalize();
   assert.strictEqual(test_reference.finalizeCount, 0);
@@ -85,3 +72,18 @@ assert.strictEqual(test_reference.finalizeCount, 0);
   global.gc(); // Value was already GC'd
   assert.strictEqual(test_reference.finalizeCount, 1);
 }
+
+{
+  // Weak reference
+  let value = test_reference.createExternalWithFinalize();
+  assert.strictEqual(test_reference.finalizeCount, 0);
+  test_reference.createReference(value, 0);
+  assert.strictEqual(test_reference.referenceValue, value);
+  value = null;
+  global.gc(); // Value should be GC'd because there is only a weak ref
+  setImmediate(common.mustCall(() => {
+    assert.strictEqual(test_reference.referenceValue, undefined);
+    assert.strictEqual(test_reference.finalizeCount, 1);
+    test_reference.deleteReference();
+  }));
+}

@jasongin
Copy link
Member Author

jasongin commented May 5, 2017

@targos Try moving the gc() call into the setImmediate() callback.

targos added a commit that referenced this pull request May 7, 2017
PR-URL: #12864
Ref: #12551 (comment)
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
anchnk pushed a commit to anchnk/node that referenced this pull request May 19, 2017
PR-URL: nodejs#12864
Ref: nodejs#12551 (comment)
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
@jasnell jasnell mentioned this pull request May 11, 2017
@gibfahn gibfahn mentioned this pull request Jun 15, 2017
3 tasks
gabrielschulhof pushed a commit to gabrielschulhof/node that referenced this pull request Apr 10, 2018
 - Add a test project to addons-napi that covers the
   N-API reference and external APIs
 - Fix a bug in napi_typeof that was found by the new tests

PR-URL: nodejs#12551
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
gabrielschulhof pushed a commit to gabrielschulhof/node that referenced this pull request Apr 10, 2018
PR-URL: nodejs#12864
Ref: nodejs#12551 (comment)
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
MylesBorins pushed a commit that referenced this pull request Apr 16, 2018
 - Add a test project to addons-napi that covers the
   N-API reference and external APIs
 - Fix a bug in napi_typeof that was found by the new tests

Backport-PR-URL: #19447
PR-URL: #12551
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
MylesBorins pushed a commit that referenced this pull request Apr 16, 2018
Backport-PR-URL: #19447
PR-URL: #12864
Ref: #12551 (comment)
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
@MylesBorins MylesBorins mentioned this pull request Apr 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. node-api Issues and PRs related to the Node-API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants