aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/node/binding.gyp2
-rw-r--r--src/node/ext/call.cc109
-rw-r--r--src/node/ext/call.h14
-rw-r--r--src/node/ext/completion_queue_async_worker.cc4
-rw-r--r--src/node/ext/node_grpc.cc33
-rw-r--r--src/node/ext/server.cc27
-rw-r--r--src/node/test/call_test.js128
-rw-r--r--src/node/test/constant_test.js37
-rw-r--r--src/node/test/end_to_end_test.js81
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) {