/* * * Copyright 2014, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ 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('end-to-end', function() { var server; var channel; before(function() { server = new grpc.Server(); var port_num = server.addHttp2Port('0.0.0.0:0'); server.start(); channel = new grpc.Channel('localhost:' + port_num); }); after(function() { server.shutdown(); }); it('should start and end a request without error', function(complete) { var done = multiDone(complete, 2); var deadline = new Date(); deadline.setSeconds(deadline.getSeconds() + 3); var status_text = 'xyz'; var call = new grpc.Call(channel, 'dummy_method', deadline); call.invoke(function(event) { assert.strictEqual(event.type, grpc.completionType.CLIENT_METADATA_READ); },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); done(); }, 0); server.requestCall(function(event) { assert.strictEqual(event.type, grpc.completionType.SERVER_RPC_NEW); var server_call = event.call; assert.notEqual(server_call, null); server_call.serverAccept(function(event) { assert.strictEqual(event.type, grpc.completionType.FINISHED); }, 0); 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); }); }); it('should successfully send and receive metadata', function(complete) { var done = multiDone(complete, 2); 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); done(); }, 0); server.requestCall(function(event) { assert.strictEqual(event.type, grpc.completionType.SERVER_RPC_NEW); assert.strictEqual(event.data.metadata.client_key[0].toString(), 'client_value'); var server_call = event.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); }); }); it('should send and receive data without error', function(complete) { var req_text = 'client_request'; var reply_text = 'server_response'; var done = multiDone(complete, 6); var deadline = new Date(); deadline.setSeconds(deadline.getSeconds() + 3); var status_text = 'success'; var call = new grpc.Call(channel, 'dummy_method', deadline); call.invoke(function(event) { assert.strictEqual(event.type, grpc.completionType.CLIENT_METADATA_READ); done(); },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); done(); }, 0); call.startWrite( new Buffer(req_text), function(event) { assert.strictEqual(event.type, grpc.completionType.WRITE_ACCEPTED); assert.strictEqual(event.data, grpc.opError.OK); call.writesDone(function(event) { assert.strictEqual(event.type, grpc.completionType.FINISH_ACCEPTED); assert.strictEqual(event.data, grpc.opError.OK); done(); }); }, 0); call.startRead(function(event) { assert.strictEqual(event.type, grpc.completionType.READ); assert.strictEqual(event.data.toString(), reply_text); done(); }); server.requestCall(function(event) { assert.strictEqual(event.type, grpc.completionType.SERVER_RPC_NEW); var server_call = event.call; assert.notEqual(server_call, null); server_call.serverAccept(function(event) { assert.strictEqual(event.type, grpc.completionType.FINISHED); done(); }); server_call.serverEndInitialMetadata(0); server_call.startRead(function(event) { assert.strictEqual(event.type, grpc.completionType.READ); assert.strictEqual(event.data.toString(), req_text); server_call.startWrite( new Buffer(reply_text), function(event) { assert.strictEqual(event.type, grpc.completionType.WRITE_ACCEPTED); assert.strictEqual(event.data, grpc.opError.OK); 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(); }); }, 0); }); }); }); });