diff options
author | Anna Henningsen <anna@addaleax.net> | 2017-05-25 19:56:50 +0200 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2017-05-27 11:53:02 +0200 |
commit | 1a2cd91b208f3117063ea93b241940bb3e15e6f6 (patch) | |
tree | 15bed02a97db452550375c03ef84724896cd215f /test/addons/async-resource | |
parent | a86323dc647d9689af5ff0838b20b440d0abb986 (diff) | |
download | android-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.cc | 112 | ||||
-rw-r--r-- | test/addons/async-resource/binding.gyp | 9 | ||||
-rw-r--r-- | test/addons/async-resource/test.js | 80 |
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); +})); |