Permalink
Browse files

test: add coverage for napi_cancel_async_work

adding test coverage for napi_cancel_async_work based
on coverage report

PR-URL: #12575
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
  • Loading branch information...
mhdawson committed Apr 21, 2017
1 parent 35d2137 commit 1d968030d45e110f00a8d5e03b2bce45ae0806d0
Showing with 80 additions and 7 deletions.
  1. +4 −1 test/addons-napi/test_async/test.js
  2. +76 −6 test/addons-napi/test_async/test_async.cc
@@ -3,8 +3,11 @@ const common = require('../../common');
const assert = require('assert');
const test_async = require(`./build/${common.buildType}/test_async`);
-test_async(5, common.mustCall(function(err, val) {
+test_async.Test(5, common.mustCall(function(err, val) {
assert.strictEqual(err, null);
assert.strictEqual(val, 10);
process.nextTick(common.mustCall(function() {}));
}));
+
+const cancelSuceeded = function() {};
+test_async.TestCancel(common.mustCall(cancelSuceeded));
@@ -7,6 +7,9 @@
#include <unistd.h>
#endif
+// this needs to be greater than the thread pool size
+#define MAX_CANCEL_THREADS 6
+
typedef struct {
int32_t _input;
int32_t _output;
@@ -15,6 +18,7 @@ typedef struct {
} carrier;
carrier the_carrier;
+carrier async_carrier[MAX_CANCEL_THREADS];
struct AutoHandleScope {
explicit AutoHandleScope(napi_env env)
@@ -74,7 +78,7 @@ void Complete(napi_env env, napi_status status, void* data) {
napi_value result;
NAPI_CALL_RETURN_VOID(env,
- napi_call_function(env, global, callback, 2, argv, &result));
+ napi_make_callback(env, global, callback, 2, argv, &result));
NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, c->_callback));
NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, c->_request));
@@ -111,12 +115,78 @@ napi_value Test(napi_env env, napi_callback_info info) {
return nullptr;
}
+void BusyCancelComplete(napi_env env, napi_status status, void* data) {
+ AutoHandleScope scope(env);
+ carrier* c = static_cast<carrier*>(data);
+ NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, c->_request));
+}
+
+void CancelComplete(napi_env env, napi_status status, void* data) {
+ AutoHandleScope scope(env);
+ carrier* c = static_cast<carrier*>(data);
+
+ if (status == napi_cancelled) {
+ // ok we got the status we expected so make the callback to
+ // indicate the cancel succeeded.
+ napi_value callback;
+ NAPI_CALL_RETURN_VOID(env,
+ napi_get_reference_value(env, c->_callback, &callback));
+ napi_value global;
+ NAPI_CALL_RETURN_VOID(env, napi_get_global(env, &global));
+ napi_value result;
+ NAPI_CALL_RETURN_VOID(env,
+ napi_make_callback(env, global, callback, 0, nullptr, &result));
+ }
+
+ NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, c->_request));
+ NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, c->_callback));
+}
+
+void CancelExecute(napi_env env, void* data) {
+#if defined _WIN32
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+}
+
+napi_value TestCancel(napi_env env, napi_callback_info info) {
+ size_t argc = 1;
+ napi_value argv[1];
+ napi_value _this;
+ void* data;
+
+ // make sure the work we are going to cancel will not be
+ // able to start by using all the threads in the pool
+ for (int i = 1; i < MAX_CANCEL_THREADS; i++) {
+ NAPI_CALL(env, napi_create_async_work(env, CancelExecute,
+ BusyCancelComplete, &async_carrier[i], &async_carrier[i]._request));
+ NAPI_CALL(env, napi_queue_async_work(env, async_carrier[i]._request));
+ }
+
+ // now queue the work we are going to cancel and then cancel it.
+ // cancel will fail if the work has already started, but
+ // we have prevented it from starting by consuming all of the
+ // workers above.
+ NAPI_CALL(env,
+ napi_get_cb_info(env, info, &argc, argv, &_this, &data));
+ NAPI_CALL(env, napi_create_async_work(env, CancelExecute,
+ CancelComplete, &async_carrier[0], &async_carrier[0]._request));
+ NAPI_CALL(env,
+ napi_create_reference(env, argv[0], 1, &async_carrier[0]._callback));
+ NAPI_CALL(env, napi_queue_async_work(env, async_carrier[0]._request));
+ NAPI_CALL(env, napi_cancel_async_work(env, async_carrier[0]._request));
+ return nullptr;
+}
+
void Init(napi_env env, napi_value exports, napi_value module, void* priv) {
- napi_value test;
- NAPI_CALL_RETURN_VOID(env,
- napi_create_function(env, "Test", Test, nullptr, &test));
- NAPI_CALL_RETURN_VOID(env,
- napi_set_named_property(env, module, "exports", test));
+ napi_property_descriptor properties[] = {
+ DECLARE_NAPI_PROPERTY("Test", Test),
+ DECLARE_NAPI_PROPERTY("TestCancel", TestCancel),
+ };
+
+ NAPI_CALL_RETURN_VOID(env, napi_define_properties(
+ env, exports, sizeof(properties) / sizeof(*properties), properties));
}
NAPI_MODULE(addon, Init)

0 comments on commit 1d96803

Please sign in to comment.