diff options
author | murgatroid99 <mlumish@google.com> | 2015-02-09 15:55:10 -0800 |
---|---|---|
committer | murgatroid99 <mlumish@google.com> | 2015-02-09 15:55:10 -0800 |
commit | 016bb50e763978b27ddf73612f65fdd84b89f478 (patch) | |
tree | bd5ea0d02aa4a293134c4b212b55e68429591587 /src/node | |
parent | 5efd50fd985cf90d8cd82c8537e26eafe7855200 (diff) |
Extension module now compiles and some tests pass
Diffstat (limited to 'src/node')
-rw-r--r-- | src/node/binding.gyp | 2 | ||||
-rw-r--r-- | src/node/ext/call.cc | 109 | ||||
-rw-r--r-- | src/node/ext/call.h | 14 | ||||
-rw-r--r-- | src/node/ext/completion_queue_async_worker.cc | 4 | ||||
-rw-r--r-- | src/node/ext/node_grpc.cc | 33 | ||||
-rw-r--r-- | src/node/ext/server.cc | 27 | ||||
-rw-r--r-- | src/node/test/call_test.js | 128 | ||||
-rw-r--r-- | src/node/test/constant_test.js | 37 | ||||
-rw-r--r-- | src/node/test/end_to_end_test.js | 81 |
9 files changed, 195 insertions, 240 deletions
diff --git a/src/node/binding.gyp b/src/node/binding.gyp index a289b9b9e8..fb4c779f8e 100644 --- a/src/node/binding.gyp +++ b/src/node/binding.gyp @@ -34,11 +34,9 @@ "ext/channel.cc", "ext/completion_queue_async_worker.cc", "ext/credentials.cc", - "ext/event.cc", "ext/node_grpc.cc", "ext/server.cc", "ext/server_credentials.cc", - "ext/tag.cc", "ext/timeval.cc" ], 'conditions' : [ diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index 4751621c9f..785cee8d3e 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -55,6 +55,7 @@ namespace node { using ::node::Buffer; using v8::Arguments; using v8::Array; +using v8::Boolean; using v8::Exception; using v8::External; using v8::Function; @@ -80,6 +81,7 @@ bool CreateMetadataArray( std::vector<unique_ptr<NanUtf8String> > *string_handles, std::vector<unique_ptr<PersistentHolder> > *handles) { NanScope(); + grpc_metadata_array_init(array); Handle<Array> keys(metadata->GetOwnPropertyNames()); for (unsigned int i = 0; i < keys->Length(); i++) { Handle<String> current_key(keys->Get(i)->ToString()); @@ -156,12 +158,12 @@ Handle<Value> ParseMetadata(const grpc_metadata_array *metadata_array) { Handle<Value> Op::GetOpType() const { NanEscapableScope(); - return NanEscapeScope(NanNew(GetTypeString())); + return NanEscapeScope(NanNew<String>(GetTypeString())); } class SendMetadataOp : public Op { public: - Handle<Value> GetNodeValue() { + Handle<Value> GetNodeValue() const { NanEscapableScope(); return NanEscapeScope(NanTrue()); } @@ -180,14 +182,14 @@ class SendMetadataOp : public Op { return true; } protected: - std::string GetTypeString() { + std::string GetTypeString() const { return "send metadata"; } }; class SendMessageOp : public Op { public: - Handle<Value> GetNodeValue() { + Handle<Value> GetNodeValue() const { NanEscapableScope(); return NanEscapeScope(NanTrue()); } @@ -197,20 +199,22 @@ class SendMessageOp : public Op { if (!Buffer::HasInstance(value)) { return false; } - out->data.send_message = BufferToByteBuffer(obj->Get(type)); + out->data.send_message = BufferToByteBuffer(value); + Persistent<Value> handle; NanAssignPersistent(handle, value); handles->push_back(unique_ptr<PersistentHolder>( new PersistentHolder(handle))); + return true; } protected: - std::string GetTypeString() { + std::string GetTypeString() const { return "send message"; } }; class SendClientCloseOp : public Op { public: - Handle<Value> GetNodeValue() { + Handle<Value> GetNodeValue() const { NanEscapableScope(); return NanEscapeScope(NanTrue()); } @@ -220,14 +224,14 @@ class SendClientCloseOp : public Op { return true; } protected: - std::string GetTypeString() { + std::string GetTypeString() const { return "client close"; } }; class SendServerStatusOp : public Op { public: - Handle<Value> GetNodeValue() { + Handle<Value> GetNodeValue() const { NanEscapableScope(); return NanEscapeScope(NanTrue()); } @@ -265,10 +269,10 @@ class SendServerStatusOp : public Op { return true; } protected: - std::string GetTypeString() { + std::string GetTypeString() const { return "send status"; } -} +}; class GetMetadataOp : public Op { public: @@ -289,10 +293,11 @@ class GetMetadataOp : public Op { std::vector<unique_ptr<NanUtf8String> > *strings, std::vector<unique_ptr<PersistentHolder> > *handles) { out->data.recv_initial_metadata = &recv_metadata; + return true; } protected: - std::string GetTypeString() { + std::string GetTypeString() const { return "metadata"; } @@ -323,7 +328,7 @@ class ReadMessageOp : public Op { } protected: - std::string GetTypeString() { + std::string GetTypeString() const { return "read"; } @@ -334,12 +339,13 @@ class ReadMessageOp : public Op { class ClientStatusOp : public Op { public: ClientStatusOp() { - grpc_metadata_array_init(&metadata); + grpc_metadata_array_init(&metadata_array); status_details = NULL; + details_capacity = 0; } ~ClientStatusOp() { - gprc_metadata_array_destroy(&metadata_array); + grpc_metadata_array_destroy(&metadata_array); gpr_free(status_details); } @@ -357,7 +363,7 @@ class ClientStatusOp : public Op { NanEscapableScope(); Handle<Object> status_obj = NanNew<Object>(); status_obj->Set(NanNew("code"), NanNew<Number>(status)); - if (event->data.finished.details != NULL) { + if (status_details != NULL) { status_obj->Set(NanNew("details"), String::New(status_details)); } status_obj->Set(NanNew("metadata"), ParseMetadata(&metadata_array)); @@ -378,7 +384,7 @@ class ServerCloseResponseOp : public Op { public: Handle<Value> GetNodeValue() const { NanEscapableScope(); - NanEscapeScope(NanNew<Boolean>(cancelled)); + return NanEscapeScope(NanNew<Boolean>(cancelled)); } bool ParseOp(Handle<Value> value, grpc_op *out, @@ -397,27 +403,43 @@ class ServerCloseResponseOp : public Op { int cancelled; }; -struct tag { - tag(NanCallback *callback, std::vector<unique_ptr<Op> > *ops, - std::vector<unique_ptr<PersistentHolder> > *handles, - std::vector<unique_ptr<NanUtf8String> > *strings) : - callback(callback), ops(ops), handles(handles), strings(strings){ - } - ~tag() { - if (strings != null) { - for (std::vector<NanUtf8String *>::iterator it = strings.begin(); - it != strings.end(); ++it) { - delete *it; - } - delete strings; - } - delete callback; - delete ops; - if (handles != null) { - delete handles; - } +tag::tag(NanCallback *callback, std::vector<unique_ptr<Op> > *ops, + std::vector<unique_ptr<PersistentHolder> > *handles, + std::vector<unique_ptr<NanUtf8String> > *strings) : + callback(callback), ops(ops), handles(handles), strings(strings){ +} +tag::~tag() { + delete callback; + delete ops; + if (handles != NULL) { + delete handles; } -}; + if (strings != NULL) { + delete strings; + } +} + +Handle<Value> GetTagNodeValue(void *tag) { + NanEscapableScope(); + struct tag *tag_struct = reinterpret_cast<struct tag *>(tag); + Handle<Object> tag_obj = NanNew<Object>(); + for (std::vector<unique_ptr<Op> >::iterator it = tag_struct->ops->begin(); + it != tag_struct->ops->end(); ++it) { + Op *op_ptr = it->get(); + tag_obj->Set(op_ptr->GetOpType(), op_ptr->GetNodeValue()); + } + return NanEscapeScope(tag_obj); +} + +NanCallback GetTagCallback(void *tag) { + struct tag *tag_struct = reinterpret_cast<struct tag *>(tag); + return *tag_struct->callback; +} + +void DestroyTag(void *tag) { + struct tag *tag_struct = reinterpret_cast<struct tag *>(tag); + delete tag_struct; +} Call::Call(grpc_call *call) : wrapped_call(call) {} @@ -559,13 +581,16 @@ NAN_METHOD(Call::StartBatch) { default: return NanThrowError("Argument object had an unrecognized key"); } - op.ParseOp(obj.get(type), &ops[i], strings, handles); - op_vector.push_back(unique_ptr<Op>(op)); + if (!op->ParseOp(obj->Get(type), &ops[i], strings, handles)) { + return NanThrowTypeError("Incorrectly typed arguments to startBatch"); + } + op_vector->push_back(unique_ptr<Op>(op)); } grpc_call_error error = grpc_call_start_batch( - call->wrapped_call, ops, nops, new struct tag(args[1].As<Function>(), - op_vector, nops, handles, - strings)); + call->wrapped_call, ops, nops, new struct tag( + new NanCallback(args[1].As<Function>()), + op_vector, handles, + strings)); if (error != GRPC_CALL_OK) { return NanThrowError("startBatch failed", error); } diff --git a/src/node/ext/call.h b/src/node/ext/call.h index 880ce7c451..434bcf8a63 100644 --- a/src/node/ext/call.h +++ b/src/node/ext/call.h @@ -35,6 +35,7 @@ #define NET_GRPC_NODE_CALL_H_ #include <memory> +#include <vector> #include <node.h> #include <nan.h> @@ -47,9 +48,12 @@ namespace node { using std::unique_ptr; +v8::Handle<v8::Value> ParseMetadata(const grpc_metadata_array *metadata_array); + class PersistentHolder { public: - explicit PersistentHolder(v8::Persistent<v8::Value> persist) : persist(persist) { + explicit PersistentHolder(v8::Persistent<v8::Value> persist) : + persist(persist) { } ~PersistentHolder() { @@ -69,7 +73,7 @@ class Op { v8::Handle<v8::Value> GetOpType() const; protected: - virtual std::string GetTypeString() const; + virtual std::string GetTypeString() const = 0; }; struct tag { @@ -83,6 +87,12 @@ struct tag { std::vector<unique_ptr<NanUtf8String> > *strings; }; +v8::Handle<v8::Value> GetTagNodeValue(void *tag); + +NanCallback GetTagCallback(void *tag); + +void DestroyTag(void *tag); + /* Wrapper class for grpc_call structs. */ class Call : public ::node::ObjectWrap { public: diff --git a/src/node/ext/completion_queue_async_worker.cc b/src/node/ext/completion_queue_async_worker.cc index bb0e39180e..5c0e27e6a7 100644 --- a/src/node/ext/completion_queue_async_worker.cc +++ b/src/node/ext/completion_queue_async_worker.cc @@ -37,7 +37,7 @@ #include "grpc/grpc.h" #include "grpc/support/time.h" #include "completion_queue_async_worker.h" -#include "tag.h" +#include "call.h" namespace grpc { namespace node { @@ -78,7 +78,7 @@ void CompletionQueueAsyncWorker::Init(Handle<Object> exports) { void CompletionQueueAsyncWorker::HandleOKCallback() { NanScope(); NanCallback callback = GetTagCallback(result->tag); - Handle<Value> argv[] = {NanNull(), GetNodeValue(result->tag)}; + Handle<Value> argv[] = {NanNull(), GetTagNodeValue(result->tag)}; DestroyTag(result->tag); grpc_event_finish(result); diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc index c9388940ad..9b0fe82976 100644 --- a/src/node/ext/node_grpc.cc +++ b/src/node/ext/node_grpc.cc @@ -130,37 +130,6 @@ void InitCallErrorConstants(Handle<Object> exports) { call_error->Set(NanNew("INVALID_FLAGS"), INVALID_FLAGS); } -void InitOpErrorConstants(Handle<Object> exports) { - NanScope(); - Handle<Object> op_error = Object::New(); - exports->Set(NanNew("opError"), op_error); - Handle<Value> OK(NanNew<Uint32, uint32_t>(GRPC_OP_OK)); - op_error->Set(NanNew("OK"), OK); - Handle<Value> ERROR(NanNew<Uint32, uint32_t>(GRPC_OP_ERROR)); - op_error->Set(NanNew("ERROR"), ERROR); -} - -void InitCompletionTypeConstants(Handle<Object> exports) { - NanScope(); - Handle<Object> completion_type = Object::New(); - exports->Set(NanNew("completionType"), completion_type); - Handle<Value> QUEUE_SHUTDOWN(NanNew<Uint32, uint32_t>(GRPC_QUEUE_SHUTDOWN)); - completion_type->Set(NanNew("QUEUE_SHUTDOWN"), QUEUE_SHUTDOWN); - Handle<Value> READ(NanNew<Uint32, uint32_t>(GRPC_READ)); - completion_type->Set(NanNew("READ"), READ); - Handle<Value> WRITE_ACCEPTED(NanNew<Uint32, uint32_t>(GRPC_WRITE_ACCEPTED)); - completion_type->Set(NanNew("WRITE_ACCEPTED"), WRITE_ACCEPTED); - Handle<Value> FINISH_ACCEPTED(NanNew<Uint32, uint32_t>(GRPC_FINISH_ACCEPTED)); - completion_type->Set(NanNew("FINISH_ACCEPTED"), FINISH_ACCEPTED); - Handle<Value> CLIENT_METADATA_READ( - NanNew<Uint32, uint32_t>(GRPC_CLIENT_METADATA_READ)); - completion_type->Set(NanNew("CLIENT_METADATA_READ"), CLIENT_METADATA_READ); - Handle<Value> FINISHED(NanNew<Uint32, uint32_t>(GRPC_FINISHED)); - completion_type->Set(NanNew("FINISHED"), FINISHED); - Handle<Value> SERVER_RPC_NEW(NanNew<Uint32, uint32_t>(GRPC_SERVER_RPC_NEW)); - completion_type->Set(NanNew("SERVER_RPC_NEW"), SERVER_RPC_NEW); -} - void InitOpTypeConstants(Handle<Object> exports) { NanScope(); Handle<Object> op_type = Object::New(); @@ -196,8 +165,6 @@ void init(Handle<Object> exports) { grpc_init(); InitStatusConstants(exports); InitCallErrorConstants(exports); - InitOpErrorConstants(exports); - InitCompletionTypeConstants(exports); InitOpTypeConstants(exports); grpc::node::Call::Init(exports); diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc index c0ccf1f381..75ea681fa7 100644 --- a/src/node/ext/server.cc +++ b/src/node/ext/server.cc @@ -45,8 +45,8 @@ #include "grpc/grpc_security.h" #include "call.h" #include "completion_queue_async_worker.h" -#include "tag.h" #include "server_credentials.h" +#include "timeval.h" namespace grpc { namespace node { @@ -55,6 +55,7 @@ using std::unique_ptr; using v8::Arguments; using v8::Array; using v8::Boolean; +using v8::Date; using v8::Exception; using v8::Function; using v8::FunctionTemplate; @@ -80,12 +81,12 @@ class NewCallOp : public Op { ~NewCallOp() { grpc_call_details_destroy(&details); - grpc_metadata_array_destroy(&details); + grpc_metadata_array_destroy(&request_metadata); } Handle<Value> GetNodeValue() const { NanEscapableScope(); - if (*call == NULL) { + if (call == NULL) { return NanEscapeScope(NanNull()); } Handle<Object> obj = NanNew<Object>(); @@ -99,15 +100,20 @@ class NewCallOp : public Op { } bool ParseOp(Handle<Value> value, grpc_op *out, - std::vector<unique_ptr<NanUtf8String> > strings, - std::vector<unique_ptr<PersistentHolder> > handles) { + std::vector<unique_ptr<NanUtf8String> > *strings, + std::vector<unique_ptr<PersistentHolder> > *handles) { return true; } grpc_call *call; grpc_call_details details; grpc_metadata_array request_metadata; -} + + protected: + std::string GetTypeString() const { + return "new call"; + } +}; Server::Server(grpc_server *server) : wrapped_server(server) {} @@ -217,12 +223,13 @@ NAN_METHOD(Server::RequestCall) { return NanThrowTypeError("requestCall can only be called on a Server"); } Server *server = ObjectWrap::Unwrap<Server>(args.This()); - Op *op = new NewCallOp(); - std::vector<unique_ptr<Op> > *ops = { unique_ptr<Op>(op) }; + NewCallOp *op = new NewCallOp(); + std::vector<unique_ptr<Op> > *ops = new std::vector<unique_ptr<Op> >(); + ops->push_back(unique_ptr<Op>(op)); grpc_call_error error = grpc_server_request_call( - server->wrapped_server, &op->call, &op->details, &op->metadata, + server->wrapped_server, &op->call, &op->details, &op->request_metadata, CompletionQueueAsyncWorker::GetQueue(), - new struct tag(args[0].As<Function>(), ops, NULL, NULL)); + new struct tag(new NanCallback(args[0].As<Function>()), ops, NULL, NULL)); if (error != GRPC_CALL_OK) { return NanThrowError("requestCall failed", error); } diff --git a/src/node/test/call_test.js b/src/node/test/call_test.js index dfa9aaa1a7..e341092ff8 100644 --- a/src/node/test/call_test.js +++ b/src/node/test/call_test.js @@ -98,104 +98,80 @@ describe('call', function() { }, TypeError); }); }); - describe('addMetadata', function() { - it('should succeed with a map from strings to string arrays', function() { + describe('startBatch', function() { + it('should fail without an object and a function', function() { var call = new grpc.Call(channel, 'method', getDeadline(1)); - assert.doesNotThrow(function() { - call.addMetadata({'key': ['value']}); + assert.throws(function() { + call.startBatch(); }); - assert.doesNotThrow(function() { - call.addMetadata({'key1': ['value1'], 'key2': ['value2']}); + assert.throws(function() { + call.startBatch({}); + }); + assert.throws(function() { + call.startBatch(null, function(){}); }); }); - it('should succeed with a map from strings to buffer arrays', function() { + it.skip('should succeed with an empty object', function(done) { var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.doesNotThrow(function() { - call.addMetadata({'key': [new Buffer('value')]}); - }); - assert.doesNotThrow(function() { - call.addMetadata({'key1': [new Buffer('value1')], - 'key2': [new Buffer('value2')]}); + call.startBatch({}, function(err) { + assert.ifError(err); + done(); + }); }); }); - it('should fail with other parameter types', function() { + }); + describe('startBatch with metadata', function() { + it('should succeed with a map of strings to string arrays', function(done) { var call = new grpc.Call(channel, 'method', getDeadline(1)); - assert.throws(function() { - call.addMetadata(); + assert.doesNotThrow(function() { + var batch = {}; + batch[grpc.opType.SEND_INITIAL_METADATA] = {'key1': ['value1'], + 'key2': ['value2']}; + call.startBatch(batch, function(err, resp) { + assert.ifError(err); + assert.deepEqual(resp, {'send metadata': true}); + done(); + }); }); - assert.throws(function() { - call.addMetadata(null); - }, TypeError); - assert.throws(function() { - call.addMetadata('value'); - }, TypeError); - assert.throws(function() { - call.addMetadata(5); - }, TypeError); }); - it('should fail if invoke was already called', function(done) { + it('should succeed with a map of strings to buffer arrays', function(done) { var call = new grpc.Call(channel, 'method', getDeadline(1)); - call.invoke(function() {}, - function() {done();}, - 0); - assert.throws(function() { - call.addMetadata({'key': ['value']}); - }, function(err) { - return err.code === grpc.callError.ALREADY_INVOKED; + assert.doesNotThrow(function() { + var batch = {}; + batch[grpc.opType.SEND_INITIAL_METADATA] = { + 'key1': [new Buffer('value1')], + 'key2': [new Buffer('value2')] + }; + call.startBatch(batch, function(err, resp) { + assert.ifError(err); + assert.deepEqual(resp, {'send metadata': true}); + done(); + }); }); - // Cancel to speed up the test - call.cancel(); }); - }); - describe('invoke', function() { - it('should fail with fewer than 3 arguments', function() { + it('should fail with other parameter types', function() { var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.throws(function() { - call.invoke(); - }, TypeError); - assert.throws(function() { - call.invoke(function() {}); - }, TypeError); - assert.throws(function() { - call.invoke(function() {}, - function() {}); - }, TypeError); - }); - it('should work with 2 args and an int', function(done) { - assert.doesNotThrow(function() { - var call = new grpc.Call(channel, 'method', getDeadline(1)); - call.invoke(function() {}, - function() {done();}, - 0); - // Cancel to speed up the test - call.cancel(); + var batch = {}; + batch[grpc.opType.SEND_INITIAL_METADATA] = undefined; + call.startBatch(batch, function(){}); }); - }); - it('should reject incorrectly typed arguments', function() { - var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.throws(function() { - call.invoke(0, 0, 0); + var batch = {}; + batch[grpc.opType.SEND_INITIAL_METADATA] = null; + call.startBatch(batch, function(){}); }, TypeError); assert.throws(function() { - call.invoke(function() {}, - function() {}, 'test'); - }); - }); - }); - describe('serverAccept', function() { - it('should fail with fewer than 1 argument1', function() { - var call = new grpc.Call(channel, 'method', getDeadline(1)); - assert.throws(function() { - call.serverAccept(); + var batch = {}; + batch[grpc.opType.SEND_INITIAL_METADATA] = 'value'; + call.startBatch(batch, function(){}); }, TypeError); - }); - it('should return an error when called on a client Call', function() { - var call = new grpc.Call(channel, 'method', getDeadline(1)); assert.throws(function() { - call.serverAccept(function() {}); - }, function(err) { - return err.code === grpc.callError.NOT_ON_CLIENT; - }); + var batch = {}; + batch[grpc.opType.SEND_INITIAL_METADATA] = 5; + call.startBatch(batch, function(){}); + }, TypeError); }); }); describe('cancel', function() { diff --git a/src/node/test/constant_test.js b/src/node/test/constant_test.js index 0138a55226..4d11e6f527 100644 --- a/src/node/test/constant_test.js +++ b/src/node/test/constant_test.js @@ -76,31 +76,6 @@ var callErrorNames = [ 'INVALID_FLAGS' ]; -/** - * List of all op error names - * @const - * @type {Array.<string>} - */ -var opErrorNames = [ - 'OK', - 'ERROR' -]; - -/** - * List of all completion type names - * @const - * @type {Array.<string>} - */ -var completionTypeNames = [ - 'QUEUE_SHUTDOWN', - 'READ', - 'WRITE_ACCEPTED', - 'FINISH_ACCEPTED', - 'CLIENT_METADATA_READ', - 'FINISHED', - 'SERVER_RPC_NEW' -]; - describe('constants', function() { it('should have all of the status constants', function() { for (var i = 0; i < statusNames.length; i++) { @@ -114,16 +89,4 @@ describe('constants', function() { 'call error missing: ' + callErrorNames[i]); } }); - it('should have all of the op errors', function() { - for (var i = 0; i < opErrorNames.length; i++) { - assert(grpc.opError.hasOwnProperty(opErrorNames[i]), - 'op error missing: ' + opErrorNames[i]); - } - }); - it('should have all of the completion types', function() { - for (var i = 0; i < completionTypeNames.length; i++) { - assert(grpc.completionType.hasOwnProperty(completionTypeNames[i]), - 'completion type missing: ' + completionTypeNames[i]); - } - }); }); diff --git a/src/node/test/end_to_end_test.js b/src/node/test/end_to_end_test.js index 1f53df23f3..e0ad9a8874 100644 --- a/src/node/test/end_to_end_test.js +++ b/src/node/test/end_to_end_test.js @@ -110,52 +110,61 @@ describe('end-to-end', function() { assert.strictEqual(event.data, grpc.opError.OK); }); }); - it('should successfully send and receive metadata', function(complete) { - var done = multiDone(complete, 2); + it.only('should successfully send and receive metadata', function(done) { + debugger; var deadline = new Date(); deadline.setSeconds(deadline.getSeconds() + 3); var status_text = 'xyz'; var call = new grpc.Call(channel, 'dummy_method', deadline); - call.addMetadata({'client_key': ['client_value']}); - call.invoke(function(event) { - assert.strictEqual(event.type, - grpc.completionType.CLIENT_METADATA_READ); - assert.strictEqual(event.data.server_key[0].toString(), 'server_value'); - },function(event) { - assert.strictEqual(event.type, grpc.completionType.FINISHED); - var status = event.data; - assert.strictEqual(status.code, grpc.status.OK); - assert.strictEqual(status.details, status_text); + var client_batch = {}; + client_batch[grpc.opType.SEND_INITIAL_METADATA] = { + 'client_key': ['client_value'] + }; + client_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true; + client_batch[grpc.opType.RECV_INITIAL_METADATA] = true; + client_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true; + call.startBatch(client_batch, function(err, response) { + assert.ifError(err); + assert.deepEqual(response, { + 'send metadata': true, + 'client close': true, + 'metadata': {'server_key': [new Buffer('server_value')]}, + 'status': { + 'code': grpc.status.OK, + 'details': status_text + } + }); done(); - }, 0); + }); - server.requestCall(function(event) { - assert.strictEqual(event.type, grpc.completionType.SERVER_RPC_NEW); - assert.strictEqual(event.data.metadata.client_key[0].toString(), + server.requestCall(function(err, call_details) { + var new_call = call_details['new call']; + assert.notEqual(new_call, null); + assert.strictEqual(new_call.metadata.client_key[0].toString(), 'client_value'); - var server_call = event.call; + var server_call = new_call.call; assert.notEqual(server_call, null); - server_call.serverAccept(function(event) { - assert.strictEqual(event.type, grpc.completionType.FINISHED); - }, 0); - server_call.addMetadata({'server_key': ['server_value']}); - server_call.serverEndInitialMetadata(0); - server_call.startWriteStatus( - grpc.status.OK, - status_text, - function(event) { - assert.strictEqual(event.type, - grpc.completionType.FINISH_ACCEPTED); - assert.strictEqual(event.data, grpc.opError.OK); - done(); - }); - }); - call.writesDone(function(event) { - assert.strictEqual(event.type, - grpc.completionType.FINISH_ACCEPTED); - assert.strictEqual(event.data, grpc.opError.OK); + var server_batch = {}; + server_batch[grpc.opType.SEND_INITIAL_METADATA] = { + 'server_key': ['server_value'] + }; + server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { + 'metadata': {}, + 'code': grpc.status.OK, + 'details': status_text + }; + server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; + console.log(server_batch); + server_call.startBatch(server_batch, function(err, response) { + assert.ifError(err); + assert.deepEqual(response, { + 'send metadata': true, + 'send status': true, + 'cancelled': false + }); + }); }); }); it('should send and receive data without error', function(complete) { |