summaryrefslogtreecommitdiff
path: root/test/addons/async-resource
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2017-05-25 19:56:50 +0200
committerAnna Henningsen <anna@addaleax.net>2017-05-27 11:53:02 +0200
commit1a2cd91b208f3117063ea93b241940bb3e15e6f6 (patch)
tree15bed02a97db452550375c03ef84724896cd215f /test/addons/async-resource
parenta86323dc647d9689af5ff0838b20b440d0abb986 (diff)
downloadandroid-node-v8-1a2cd91b208f3117063ea93b241940bb3e15e6f6.tar.gz
android-node-v8-1a2cd91b208f3117063ea93b241940bb3e15e6f6.tar.bz2
android-node-v8-1a2cd91b208f3117063ea93b241940bb3e15e6f6.zip
test: add AsyncResource addon test
PR-URL: https://github.com/nodejs/node/pull/13142 Reviewed-By: Matthew Loring <mattloring@google.com> Reviewed-By: Andreas Madsen <amwebdk@gmail.com>
Diffstat (limited to 'test/addons/async-resource')
-rw-r--r--test/addons/async-resource/binding.cc112
-rw-r--r--test/addons/async-resource/binding.gyp9
-rw-r--r--test/addons/async-resource/test.js80
3 files changed, 201 insertions, 0 deletions
diff --git a/test/addons/async-resource/binding.cc b/test/addons/async-resource/binding.cc
new file mode 100644
index 0000000000..093adfcba6
--- /dev/null
+++ b/test/addons/async-resource/binding.cc
@@ -0,0 +1,112 @@
+#include "node.h"
+
+#include <assert.h>
+#include <vector>
+
+namespace {
+
+using node::AsyncResource;
+using v8::External;
+using v8::Function;
+using v8::FunctionCallbackInfo;
+using v8::Integer;
+using v8::Isolate;
+using v8::Local;
+using v8::MaybeLocal;
+using v8::Object;
+using v8::String;
+using v8::Value;
+
+void CreateAsyncResource(const FunctionCallbackInfo<Value>& args) {
+ Isolate* isolate = args.GetIsolate();
+ assert(args[0]->IsObject());
+ AsyncResource* r;
+ if (args[1]->IsInt32()) {
+ r = new AsyncResource(isolate, args[0].As<Object>(), "foobär",
+ args[1].As<Integer>()->Value());
+ } else {
+ r = new AsyncResource(isolate, args[0].As<Object>(), "foobär");
+ }
+
+ args.GetReturnValue().Set(
+ External::New(isolate, static_cast<void*>(r)));
+}
+
+void DestroyAsyncResource(const FunctionCallbackInfo<Value>& args) {
+ assert(args[0]->IsExternal());
+ auto r = static_cast<AsyncResource*>(args[0].As<External>()->Value());
+ delete r;
+}
+
+void CallViaFunction(const FunctionCallbackInfo<Value>& args) {
+ Isolate* isolate = args.GetIsolate();
+ assert(args[0]->IsExternal());
+ auto r = static_cast<AsyncResource*>(args[0].As<External>()->Value());
+
+ Local<String> name =
+ String::NewFromUtf8(isolate, "methöd", v8::NewStringType::kNormal)
+ .ToLocalChecked();
+ Local<Value> fn =
+ r->get_resource()->Get(isolate->GetCurrentContext(), name)
+ .ToLocalChecked();
+ assert(fn->IsFunction());
+
+ Local<Value> arg = Integer::New(isolate, 42);
+ MaybeLocal<Value> ret = r->MakeCallback(fn.As<Function>(), 1, &arg);
+ args.GetReturnValue().Set(ret.FromMaybe(Local<Value>()));
+}
+
+void CallViaString(const FunctionCallbackInfo<Value>& args) {
+ Isolate* isolate = args.GetIsolate();
+ assert(args[0]->IsExternal());
+ auto r = static_cast<AsyncResource*>(args[0].As<External>()->Value());
+
+ Local<String> name =
+ String::NewFromUtf8(isolate, "methöd", v8::NewStringType::kNormal)
+ .ToLocalChecked();
+
+ Local<Value> arg = Integer::New(isolate, 42);
+ MaybeLocal<Value> ret = r->MakeCallback(name, 1, &arg);
+ args.GetReturnValue().Set(ret.FromMaybe(Local<Value>()));
+}
+
+void CallViaUtf8Name(const FunctionCallbackInfo<Value>& args) {
+ Isolate* isolate = args.GetIsolate();
+ assert(args[0]->IsExternal());
+ auto r = static_cast<AsyncResource*>(args[0].As<External>()->Value());
+
+ Local<Value> arg = Integer::New(isolate, 42);
+ MaybeLocal<Value> ret = r->MakeCallback("methöd", 1, &arg);
+ args.GetReturnValue().Set(ret.FromMaybe(Local<Value>()));
+}
+
+void GetUid(const FunctionCallbackInfo<Value>& args) {
+ assert(args[0]->IsExternal());
+ auto r = static_cast<AsyncResource*>(args[0].As<External>()->Value());
+ args.GetReturnValue().Set(r->get_uid());
+}
+
+void GetResource(const FunctionCallbackInfo<Value>& args) {
+ assert(args[0]->IsExternal());
+ auto r = static_cast<AsyncResource*>(args[0].As<External>()->Value());
+ args.GetReturnValue().Set(r->get_resource());
+}
+
+void GetCurrentId(const FunctionCallbackInfo<Value>& args) {
+ args.GetReturnValue().Set(node::AsyncHooksGetCurrentId(args.GetIsolate()));
+}
+
+void Initialize(Local<Object> exports) {
+ NODE_SET_METHOD(exports, "createAsyncResource", CreateAsyncResource);
+ NODE_SET_METHOD(exports, "destroyAsyncResource", DestroyAsyncResource);
+ NODE_SET_METHOD(exports, "callViaFunction", CallViaFunction);
+ NODE_SET_METHOD(exports, "callViaString", CallViaString);
+ NODE_SET_METHOD(exports, "callViaUtf8Name", CallViaUtf8Name);
+ NODE_SET_METHOD(exports, "getUid", GetUid);
+ NODE_SET_METHOD(exports, "getResource", GetResource);
+ NODE_SET_METHOD(exports, "getCurrentId", GetCurrentId);
+}
+
+} // namespace
+
+NODE_MODULE(binding, Initialize)
diff --git a/test/addons/async-resource/binding.gyp b/test/addons/async-resource/binding.gyp
new file mode 100644
index 0000000000..7ede63d94a
--- /dev/null
+++ b/test/addons/async-resource/binding.gyp
@@ -0,0 +1,9 @@
+{
+ 'targets': [
+ {
+ 'target_name': 'binding',
+ 'defines': [ 'V8_DEPRECATION_WARNINGS=1' ],
+ 'sources': [ 'binding.cc' ]
+ }
+ ]
+}
diff --git a/test/addons/async-resource/test.js b/test/addons/async-resource/test.js
new file mode 100644
index 0000000000..34017750ce
--- /dev/null
+++ b/test/addons/async-resource/test.js
@@ -0,0 +1,80 @@
+'use strict';
+
+const common = require('../../common');
+const assert = require('assert');
+const binding = require(`./build/${common.buildType}/binding`);
+const async_hooks = require('async_hooks');
+
+const kObjectTag = Symbol('kObjectTag');
+
+const bindingUids = [];
+let expectedTriggerId;
+let before = 0;
+let after = 0;
+let destroy = 0;
+
+async_hooks.createHook({
+ init(id, type, triggerId, resource) {
+ assert.strictEqual(typeof id, 'number');
+ assert.strictEqual(typeof resource, 'object');
+ assert(id > 1);
+ if (type === 'foobär') {
+ assert.strictEqual(resource.kObjectTag, kObjectTag);
+ assert.strictEqual(triggerId, expectedTriggerId);
+ bindingUids.push(id);
+ }
+ },
+
+ before(id) {
+ if (bindingUids.includes(id)) before++;
+ },
+
+ after(id) {
+ if (bindingUids.includes(id)) after++;
+ },
+
+ destroy(id) {
+ if (bindingUids.includes(id)) destroy++;
+ }
+}).enable();
+
+assert.strictEqual(binding.getCurrentId(), 1);
+
+for (const call of [binding.callViaFunction,
+ binding.callViaString,
+ binding.callViaUtf8Name]) {
+ for (const passedTriggerId of [undefined, 12345]) {
+ let uid;
+ const object = {
+ methöd(arg) {
+ assert.strictEqual(this, object);
+ assert.strictEqual(arg, 42);
+ assert.strictEqual(binding.getCurrentId(), uid);
+ return 'baz';
+ },
+ kObjectTag
+ };
+
+ if (passedTriggerId === undefined)
+ expectedTriggerId = 1;
+ else
+ expectedTriggerId = passedTriggerId;
+
+ const resource = binding.createAsyncResource(object, passedTriggerId);
+ uid = bindingUids[bindingUids.length - 1];
+
+ const ret = call(resource);
+ assert.strictEqual(ret, 'baz');
+ assert.strictEqual(binding.getResource(resource), object);
+ assert.strictEqual(binding.getUid(resource), uid);
+
+ binding.destroyAsyncResource(resource);
+ }
+}
+
+setImmediate(common.mustCall(() => {
+ assert.strictEqual(bindingUids.length, 6);
+ assert.strictEqual(before, bindingUids.length);
+ assert.strictEqual(after, bindingUids.length);
+ assert.strictEqual(destroy, bindingUids.length);
+}));