aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/node/test
diff options
context:
space:
mode:
authorGravatar murgatroid99 <mlumish@google.com>2015-07-28 15:18:57 -0700
committerGravatar murgatroid99 <mlumish@google.com>2015-07-28 15:18:57 -0700
commitc7f4d4fb84566992bc89d2ffceefdec1a2e83040 (patch)
tree64e813e8127ec9efb3cce41a1d8ccda7bdfd1037 /src/node/test
parent8e06c2e62e0be2606598dd1f2a6582b585364520 (diff)
Wrap connectivity API, expose it to client as waitForReady
Diffstat (limited to 'src/node/test')
-rw-r--r--src/node/test/channel_test.js88
-rw-r--r--src/node/test/constant_test.js19
-rw-r--r--src/node/test/surface_test.js76
3 files changed, 180 insertions, 3 deletions
diff --git a/src/node/test/channel_test.js b/src/node/test/channel_test.js
index 3e61d3bbc6..feb3e67227 100644
--- a/src/node/test/channel_test.js
+++ b/src/node/test/channel_test.js
@@ -36,6 +36,27 @@
var assert = require('assert');
var grpc = require('bindings')('grpc.node');
+/**
+ * This is used for testing functions with multiple asynchronous calls that
+ * can happen in different orders. This should be passed the number of async
+ * function invocations that can occur last, and each of those should call this
+ * function's return value
+ * @param {function()} done The function that should be called when a test is
+ * complete.
+ * @param {number} count The number of calls to the resulting function if the
+ * test passes.
+ * @return {function()} The function that should be called at the end of each
+ * sequence of asynchronous functions.
+ */
+function multiDone(done, count) {
+ return function() {
+ count -= 1;
+ if (count <= 0) {
+ done();
+ }
+ };
+}
+
describe('channel', function() {
describe('constructor', function() {
it('should require a string for the first argument', function() {
@@ -73,14 +94,16 @@ describe('channel', function() {
});
});
describe('close', function() {
+ var channel;
+ beforeEach(function() {
+ channel = new grpc.Channel('hostname', {});
+ });
it('should succeed silently', function() {
- var channel = new grpc.Channel('hostname', {});
assert.doesNotThrow(function() {
channel.close();
});
});
it('should be idempotent', function() {
- var channel = new grpc.Channel('hostname', {});
assert.doesNotThrow(function() {
channel.close();
channel.close();
@@ -88,9 +111,68 @@ describe('channel', function() {
});
});
describe('getTarget', function() {
+ var channel;
+ beforeEach(function() {
+ channel = new grpc.Channel('hostname', {});
+ });
it('should return a string', function() {
- var channel = new grpc.Channel('localhost', {});
assert.strictEqual(typeof channel.getTarget(), 'string');
});
});
+ describe('getConnectivityState', function() {
+ var channel;
+ beforeEach(function() {
+ channel = new grpc.Channel('hostname', {});
+ });
+ it('should return IDLE for a new channel', function() {
+ assert.strictEqual(channel.getConnectivityState(),
+ grpc.connectivityState.IDLE);
+ });
+ });
+ describe('watchConnectivityState', function() {
+ var channel;
+ beforeEach(function() {
+ channel = new grpc.Channel('localhost', {});
+ });
+ afterEach(function() {
+ channel.close();
+ });
+ it('should time out if called alone', function(done) {
+ var old_state = channel.getConnectivityState();
+ var deadline = new Date();
+ deadline.setSeconds(deadline.getSeconds() + 1);
+ channel.watchConnectivityState(old_state, deadline, function(err, value) {
+ assert(err);
+ done();
+ });
+ });
+ it('should complete if a connection attempt is forced', function(done) {
+ var old_state = channel.getConnectivityState();
+ var deadline = new Date();
+ deadline.setSeconds(deadline.getSeconds() + 1);
+ channel.watchConnectivityState(old_state, deadline, function(err, value) {
+ assert.ifError(err);
+ assert.notEqual(value.new_state, old_state);
+ done();
+ });
+ channel.getConnectivityState(true);
+ });
+ it('should complete twice if called twice', function(done) {
+ done = multiDone(done, 2);
+ var old_state = channel.getConnectivityState();
+ var deadline = new Date();
+ deadline.setSeconds(deadline.getSeconds() + 1);
+ channel.watchConnectivityState(old_state, deadline, function(err, value) {
+ assert.ifError(err);
+ assert.notEqual(value.new_state, old_state);
+ done();
+ });
+ channel.watchConnectivityState(old_state, deadline, function(err, value) {
+ assert.ifError(err);
+ assert.notEqual(value.new_state, old_state);
+ done();
+ });
+ channel.getConnectivityState(true);
+ });
+ });
});
diff --git a/src/node/test/constant_test.js b/src/node/test/constant_test.js
index ecc98ec443..93bf0c8ada 100644
--- a/src/node/test/constant_test.js
+++ b/src/node/test/constant_test.js
@@ -78,6 +78,19 @@ var callErrorNames = [
'INVALID_FLAGS'
];
+/**
+ * List of all connectivity state names
+ * @const
+ * @type {Array.<string>}
+ */
+var connectivityStateNames = [
+ 'IDLE',
+ 'CONNECTING',
+ 'READY',
+ 'TRANSIENT_FAILURE',
+ 'FATAL_FAILURE'
+];
+
describe('constants', function() {
it('should have all of the status constants', function() {
for (var i = 0; i < statusNames.length; i++) {
@@ -91,4 +104,10 @@ describe('constants', function() {
'call error missing: ' + callErrorNames[i]);
}
});
+ it('should have all of the connectivity states', function() {
+ for (var i = 0; i < connectivityStateNames.length; i++) {
+ assert(grpc.connectivityState.hasOwnProperty(connectivityStateNames[i]),
+ 'connectivity status missing: ' + connectivityStateNames[i]);
+ }
+ });
});
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index 98f9b15bfc..4711658e2f 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -47,6 +47,27 @@ var mathService = math_proto.lookup('math.Math');
var _ = require('lodash');
+/**
+ * This is used for testing functions with multiple asynchronous calls that
+ * can happen in different orders. This should be passed the number of async
+ * function invocations that can occur last, and each of those should call this
+ * function's return value
+ * @param {function()} done The function that should be called when a test is
+ * complete.
+ * @param {number} count The number of calls to the resulting function if the
+ * test passes.
+ * @return {function()} The function that should be called at the end of each
+ * sequence of asynchronous functions.
+ */
+function multiDone(done, count) {
+ return function() {
+ count -= 1;
+ if (count <= 0) {
+ done();
+ }
+ };
+}
+
describe('File loader', function() {
it('Should load a proto file by default', function() {
assert.doesNotThrow(function() {
@@ -110,6 +131,61 @@ describe('Server.prototype.addProtoService', function() {
});
});
});
+describe('Client#$waitForReady', function() {
+ var server;
+ var port;
+ var Client;
+ var client;
+ before(function() {
+ server = new grpc.Server();
+ port = server.bind('localhost:0');
+ server.start();
+ Client = surface_client.makeProtobufClientConstructor(mathService);
+ });
+ beforeEach(function() {
+ client = new Client('localhost:' + port);
+ });
+ after(function() {
+ server.shutdown();
+ });
+ it('should complete when a call is initiated', function(done) {
+ client.$waitForReady(Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ var call = client.div({}, function(err, response) {});
+ call.cancel();
+ });
+ it('should complete if $tryConnect is called', function(done) {
+ client.$waitForReady(Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ client.$tryConnect();
+ });
+ it('should complete if called more than once', function(done) {
+ done = multiDone(done, 2);
+ client.$waitForReady(Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ client.$waitForReady(Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ client.$tryConnect();
+ });
+ it('should complete if called when already ready', function(done) {
+ client.$waitForReady(Infinity, function(error) {
+ assert.ifError(error);
+ client.$waitForReady(Infinity, function(error) {
+ assert.ifError(error);
+ done();
+ });
+ });
+ client.$tryConnect();
+ });
+});
describe('Echo service', function() {
var server;
var client;