Resolved merge conflicts

This commit is contained in:
murgatroid99 2015-10-07 12:37:58 -07:00
commit 697fd0b69a
23 changed files with 144 additions and 497 deletions

View File

@ -1,6 +0,0 @@
reporting:
watermarks:
statements: [80, 95]
lines: [80, 95]
functions: [80, 95]
branches: [80, 95]

28
LICENSE
View File

@ -1,28 +0,0 @@
Copyright 2015, 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.

View File

@ -5,51 +5,19 @@ Beta
## PREREQUISITES ## PREREQUISITES
- `node`: This requires `node` to be installed. If you instead have the `nodejs` executable on Debian, you should install the [`nodejs-legacy`](https://packages.debian.org/sid/nodejs-legacy) package. - `node`: This requires `node` to be installed. If you instead have the `nodejs` executable on Debian, you should install the [`nodejs-legacy`](https://packages.debian.org/sid/nodejs-legacy) package.
- [homebrew][] on Mac OS X. These simplify the installation of the gRPC C core.
## INSTALLATION ## INSTALLATION
**Linux (Debian):**
Add [Debian jessie-backports][] to your `sources.list` file. Example:
```sh
echo "deb http://http.debian.net/debian jessie-backports main" | \
sudo tee -a /etc/apt/sources.list
```
Install the gRPC Debian package
```sh
sudo apt-get update
sudo apt-get install libgrpc-dev
```
Install the gRPC NPM package Install the gRPC NPM package
```sh ```sh
npm install grpc npm install grpc
``` ```
**Mac OS X**
Install [homebrew][]. Run the following command to install gRPC Node.js.
```sh
$ curl -fsSL https://goo.gl/getgrpc | bash -s nodejs
```
This will download and run the [gRPC install script][], then install the latest version of gRPC Nodejs npm package.
## BUILD FROM SOURCE ## BUILD FROM SOURCE
1. Clone [the grpc Git Repository](https://github.com/grpc/grpc). 1. Clone [the grpc Git Repository](https://github.com/grpc/grpc).
2. Follow the instructions in the `INSTALL` file in the root of that repository to install the C core library that this package depends on.
3. Run `npm install`. 3. Run `npm install`.
If you install the gRPC C core library in a custom location, then you need to set some environment variables to install this library. The command will look like this:
```sh
CXXFLAGS=-I<custom location>/include LDFLAGS=-L<custom location>/lib npm install [grpc]
```
## TESTING ## TESTING
To run the test suite, simply run `npm test` in the install location. To run the test suite, simply run `npm test` in the install location.
@ -110,7 +78,3 @@ ServerCredentials
``` ```
An object with factory methods for creating credential objects for servers. An object with factory methods for creating credential objects for servers.
[homebrew]:http://brew.sh
[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
[Debian jessie-backports]:http://backports.debian.org/Instructions/

View File

@ -1,100 +0,0 @@
{
"variables" : {
'config': '<!(echo $CONFIG)'
},
"targets" : [
{
'include_dirs': [
"<!(node -e \"require('nan')\")"
],
'cflags': [
'-std=c++0x',
'-Wall',
'-pthread',
'-g',
'-zdefs',
'-Werror',
'-Wno-error=deprecated-declarations'
],
'ldflags': [
'-g'
],
"conditions": [
['OS != "win"', {
'variables': {
'pkg_config_grpc': '<!(pkg-config --exists grpc >/dev/null 2>&1 && echo true || echo false)'
},
'conditions': [
['config=="gcov"', {
'cflags': [
'-ftest-coverage',
'-fprofile-arcs',
'-O0'
],
'ldflags': [
'-ftest-coverage',
'-fprofile-arcs'
]
}
],
['pkg_config_grpc == "true"', {
'link_settings': {
'libraries': [
'<!@(pkg-config --libs-only-l --static grpc)'
]
},
'cflags': [
'<!@(pkg-config --cflags grpc)'
],
'libraries': [
'<!@(pkg-config --libs-only-L --static grpc)'
],
'ldflags': [
'<!@(pkg-config --libs-only-other --static grpc)'
]
}, {
'link_settings': {
'libraries': [
'-lpthread',
'-lgrpc',
'-lgpr'
],
},
'conditions':[
['OS != "mac"', {
'link_settings': {
'libraries': [
'-lrt'
]
}
}]
]
}
]
]
}],
['OS == "mac"', {
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET': '10.9',
'OTHER_CFLAGS': [
'-std=c++11',
'-stdlib=libc++'
]
}
}]
],
"target_name": "grpc",
"sources": [
"ext/byte_buffer.cc",
"ext/call.cc",
"ext/channel.cc",
"ext/completion_queue_async_worker.cc",
"ext/credentials.cc",
"ext/node_grpc.cc",
"ext/server.cc",
"ext/server_credentials.cc",
"ext/timeval.cc"
]
}
]
}

View File

@ -168,8 +168,9 @@ Local<Value> ParseMetadata(const grpc_metadata_array *metadata_array) {
} }
if (EndsWith(elem->key, "-bin")) { if (EndsWith(elem->key, "-bin")) {
Nan::Set(array, index_map[elem->key], Nan::Set(array, index_map[elem->key],
MakeFastBuffer(
Nan::CopyBuffer(elem->value, Nan::CopyBuffer(elem->value,
elem->value_length).ToLocalChecked()); elem->value_length).ToLocalChecked()));
} else { } else {
Nan::Set(array, index_map[elem->key], Nan::Set(array, index_map[elem->key],
Nan::New(elem->value).ToLocalChecked()); Nan::New(elem->value).ToLocalChecked());

View File

@ -247,4 +247,4 @@ void init(Local<Object> exports) {
grpc::node::ServerCredentials::Init(exports); grpc::node::ServerCredentials::Init(exports);
} }
NODE_MODULE(grpc, init) NODE_MODULE(grpc_node, init)

View File

@ -43,7 +43,7 @@ var server = require('./src/server.js');
var Metadata = require('./src/metadata.js'); var Metadata = require('./src/metadata.js');
var grpc = require('bindings')('grpc'); var grpc = require('bindings')('grpc_node');
/** /**
* Load a gRPC object from an existing ProtoBuf.Reflect object. * Load a gRPC object from an existing ProtoBuf.Reflect object.
@ -90,7 +90,6 @@ exports.load = function load(filename, format) {
default: default:
throw new Error('Unrecognized format "' + format + '"'); throw new Error('Unrecognized format "' + format + '"');
} }
return loadObject(builder.ns); return loadObject(builder.ns);
}; };

View File

@ -1,43 +0,0 @@
// Copyright 2015, 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.
syntax = "proto3";
package grpc.testing;
// An empty message that you can re-use to avoid defining duplicated empty
// messages in your project. A typical example is to use it as argument or the
// return value of a service API. For instance:
//
// service Foo {
// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
// };
//
message Empty {}

View File

@ -37,7 +37,9 @@ var fs = require('fs');
var path = require('path'); var path = require('path');
var _ = require('lodash'); var _ = require('lodash');
var grpc = require('..'); var grpc = require('..');
var testProto = grpc.load(__dirname + '/test.proto').grpc.testing; var testProto = grpc.load({
root: __dirname + '/../../..',
file: 'test/proto/test.proto'}).grpc.testing;
var GoogleAuth = require('google-auth-library'); var GoogleAuth = require('google-auth-library');
var assert = require('assert'); var assert = require('assert');
@ -49,6 +51,9 @@ var AUTH_USER = ('155450119199-vefjjaekcc6cmsd5914v6lqufunmh9ue' +
var COMPUTE_ENGINE_USER = ('155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel' + var COMPUTE_ENGINE_USER = ('155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel' +
'@developer.gserviceaccount.com'); '@developer.gserviceaccount.com');
var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
/** /**
* Create a buffer filled with size zeroes * Create a buffer filled with size zeroes
* @param {number} size The length of the buffer * @param {number} size The length of the buffer
@ -60,6 +65,27 @@ function zeroBuffer(size) {
return zeros; return zeros;
} }
/**
* 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();
}
};
}
/** /**
* Run the empty_unary test * Run the empty_unary test
* @param {Client} client The client to test against * @param {Client} client The client to test against
@ -271,6 +297,54 @@ function timeoutOnSleepingServer(client, done) {
}); });
} }
function customMetadata(client, done) {
done = multiDone(done, 5);
var metadata = new grpc.Metadata();
metadata.set(ECHO_INITIAL_KEY, 'test_initial_metadata_value');
metadata.set(ECHO_TRAILING_KEY, new Buffer('ababab', 'hex'));
var arg = {
response_type: 'COMPRESSABLE',
response_size: 314159,
payload: {
body: zeroBuffer(271828)
}
};
var streaming_arg = {
payload: {
body: zeroBuffer(271828)
}
};
var unary = client.unaryCall(arg, function(err, resp) {
assert.ifError(err);
done();
}, metadata);
unary.on('metadata', function(metadata) {
assert.deepEqual(metadata.get(ECHO_INITIAL_KEY),
['test_initial_metadata_value']);
done();
});
unary.on('status', function(status) {
var echo_trailer = status.metadata.get(ECHO_TRAILING_KEY);
assert(echo_trailer.length > 0);
assert.strictEqual(echo_trailer[0].toString('hex'), 'ababab');
done();
});
var stream = client.fullDuplexCall(metadata);
stream.on('metadata', function(metadata) {
assert.deepEqual(metadata.get(ECHO_INITIAL_KEY),
['test_initial_metadata_value']);
done();
});
stream.on('status', function(status) {
var echo_trailer = status.metadata.get(ECHO_TRAILING_KEY);
assert(echo_trailer.length > 0);
assert.strictEqual(echo_trailer[0].toString('hex'), 'ababab');
done();
});
stream.write(streaming_arg);
stream.end();
}
/** /**
* Run one of the authentication tests. * Run one of the authentication tests.
* @param {string} expected_user The expected username in the response * @param {string} expected_user The expected username in the response
@ -358,6 +432,7 @@ var test_cases = {
cancel_after_begin: cancelAfterBegin, cancel_after_begin: cancelAfterBegin,
cancel_after_first_response: cancelAfterFirstResponse, cancel_after_first_response: cancelAfterFirstResponse,
timeout_on_sleeping_server: timeoutOnSleepingServer, timeout_on_sleeping_server: timeoutOnSleepingServer,
custom_metadata: customMetadata,
compute_engine_creds: _.partial(authTest, COMPUTE_ENGINE_USER, null), compute_engine_creds: _.partial(authTest, COMPUTE_ENGINE_USER, null),
service_account_creds: _.partial(authTest, AUTH_USER, AUTH_SCOPE), service_account_creds: _.partial(authTest, AUTH_USER, AUTH_SCOPE),
jwt_token_creds: _.partial(authTest, AUTH_USER, null), jwt_token_creds: _.partial(authTest, AUTH_USER, null),

View File

@ -37,7 +37,12 @@ var fs = require('fs');
var path = require('path'); var path = require('path');
var _ = require('lodash'); var _ = require('lodash');
var grpc = require('..'); var grpc = require('..');
var testProto = grpc.load(__dirname + '/test.proto').grpc.testing; var testProto = grpc.load({
root: __dirname + '/../../..',
file: 'test/proto/test.proto'}).grpc.testing;
var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
/** /**
* Create a buffer filled with size zeroes * Create a buffer filled with size zeroes
@ -50,6 +55,34 @@ function zeroBuffer(size) {
return zeros; return zeros;
} }
/**
* Echos a header metadata item as specified in the interop spec.
* @param {Call} call The call to echo metadata on
*/
function echoHeader(call) {
var echo_initial = call.metadata.get(ECHO_INITIAL_KEY);
if (echo_initial.length > 0) {
var response_metadata = new grpc.Metadata();
response_metadata.set(ECHO_INITIAL_KEY, echo_initial[0]);
call.sendMetadata(response_metadata);
}
}
/**
* Gets the trailer metadata that should be echoed when the call is done,
* as specified in the interop spec.
* @param {Call} call The call to get metadata from
* @return {grpc.Metadata} The metadata to send as a trailer
*/
function getEchoTrailer(call) {
var echo_trailer = call.metadata.get(ECHO_TRAILING_KEY);
var response_trailer = new grpc.Metadata();
if (echo_trailer.length > 0) {
response_trailer.set(ECHO_TRAILING_KEY, echo_trailer[0]);
}
return response_trailer;
}
/** /**
* Respond to an empty parameter with an empty response. * Respond to an empty parameter with an empty response.
* NOTE: this currently does not work due to issue #137 * NOTE: this currently does not work due to issue #137
@ -58,7 +91,8 @@ function zeroBuffer(size) {
* or error * or error
*/ */
function handleEmpty(call, callback) { function handleEmpty(call, callback) {
callback(null, {}); echoHeader(call);
callback(null, {}, getEchoTrailer(call));
} }
/** /**
@ -68,6 +102,7 @@ function handleEmpty(call, callback) {
* error * error
*/ */
function handleUnary(call, callback) { function handleUnary(call, callback) {
echoHeader(call);
var req = call.request; var req = call.request;
var zeros = zeroBuffer(req.response_size); var zeros = zeroBuffer(req.response_size);
var payload_type = req.response_type; var payload_type = req.response_type;
@ -75,7 +110,8 @@ function handleUnary(call, callback) {
payload_type = ['COMPRESSABLE', payload_type = ['COMPRESSABLE',
'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1]; 'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1];
} }
callback(null, {payload: {type: payload_type, body: zeros}}); callback(null, {payload: {type: payload_type, body: zeros}},
getEchoTrailer(call));
} }
/** /**
@ -85,12 +121,14 @@ function handleUnary(call, callback) {
* error * error
*/ */
function handleStreamingInput(call, callback) { function handleStreamingInput(call, callback) {
echoHeader(call);
var aggregate_size = 0; var aggregate_size = 0;
call.on('data', function(value) { call.on('data', function(value) {
aggregate_size += value.payload.body.length; aggregate_size += value.payload.body.length;
}); });
call.on('end', function() { call.on('end', function() {
callback(null, {aggregated_payload_size: aggregate_size}); callback(null, {aggregated_payload_size: aggregate_size},
getEchoTrailer(call));
}); });
} }
@ -99,6 +137,7 @@ function handleStreamingInput(call, callback) {
* @param {Call} call Call to handle * @param {Call} call Call to handle
*/ */
function handleStreamingOutput(call) { function handleStreamingOutput(call) {
echoHeader(call);
var req = call.request; var req = call.request;
var payload_type = req.response_type; var payload_type = req.response_type;
if (payload_type === 'RANDOM') { if (payload_type === 'RANDOM') {
@ -113,7 +152,7 @@ function handleStreamingOutput(call) {
} }
}); });
}); });
call.end(); call.end(getEchoTrailer(call));
} }
/** /**
@ -122,6 +161,7 @@ function handleStreamingOutput(call) {
* @param {Call} call Call to handle * @param {Call} call Call to handle
*/ */
function handleFullDuplex(call) { function handleFullDuplex(call) {
echoHeader(call);
call.on('data', function(value) { call.on('data', function(value) {
var payload_type = value.response_type; var payload_type = value.response_type;
if (payload_type === 'RANDOM') { if (payload_type === 'RANDOM') {
@ -138,7 +178,7 @@ function handleFullDuplex(call) {
}); });
}); });
call.on('end', function() { call.on('end', function() {
call.end(); call.end(getEchoTrailer(call));
}); });
} }

View File

@ -1,132 +0,0 @@
// Copyright 2015, 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.
// Message definitions to be used by integration test service definitions.
syntax = "proto3";
package grpc.testing;
// The type of payload that should be returned.
enum PayloadType {
// Compressable text format.
COMPRESSABLE = 0;
// Uncompressable binary format.
UNCOMPRESSABLE = 1;
// Randomly chosen from all other formats defined in this enum.
RANDOM = 2;
}
// A block of data, to simply increase gRPC message size.
message Payload {
// The type of data in body.
PayloadType type = 1;
// Primary contents of payload.
bytes body = 2;
}
// Unary request.
message SimpleRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, server randomly chooses one from other formats.
PayloadType response_type = 1;
// Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
int32 response_size = 2;
// Optional input payload sent along with the request.
Payload payload = 3;
// Whether SimpleResponse should include username.
bool fill_username = 4;
// Whether SimpleResponse should include OAuth scope.
bool fill_oauth_scope = 5;
}
// Unary response, as configured by the request.
message SimpleResponse {
// Payload to increase message size.
Payload payload = 1;
// The user the request came from, for verifying authentication was
// successful when the client expected it.
string username = 2;
// OAuth scope.
string oauth_scope = 3;
}
// Client-streaming request.
message StreamingInputCallRequest {
// Optional input payload sent along with the request.
Payload payload = 1;
// Not expecting any payload from the response.
}
// Client-streaming response.
message StreamingInputCallResponse {
// Aggregated size of payloads received from the client.
int32 aggregated_payload_size = 1;
}
// Configuration for a particular response.
message ResponseParameters {
// Desired payload sizes in responses from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
int32 size = 1;
// Desired interval between consecutive responses in the response stream in
// microseconds.
int32 interval_us = 2;
}
// Server-streaming request.
message StreamingOutputCallRequest {
// Desired payload type in the response from the server.
// If response_type is RANDOM, the payload from each response in the stream
// might be of different types. This is to simulate a mixed type of payload
// stream.
PayloadType response_type = 1;
// Configuration for each expected response message.
repeated ResponseParameters response_parameters = 2;
// Optional input payload sent along with the request.
Payload payload = 3;
}
// Server-streaming response, as configured by the request and parameters.
message StreamingOutputCallResponse {
// Payload to increase response size.
Payload payload = 1;
}

View File

@ -1,72 +0,0 @@
// Copyright 2015, 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.
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
syntax = "proto3";
import "empty.proto";
import "messages.proto";
package grpc.testing;
// A simple service to test the various types of RPCs and experiment with
// performance with various types of payload.
service TestService {
// One empty request followed by one empty response.
rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty);
// One request followed by one response.
rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
// One request followed by a sequence of responses (streamed download).
// The server returns the payload with client desired type and sizes.
rpc StreamingOutputCall(StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
// A sequence of requests followed by one response (streamed upload).
// The server returns the aggregated size of client payload as the result.
rpc StreamingInputCall(stream StreamingInputCallRequest)
returns (StreamingInputCallResponse);
// A sequence of requests with each request served by the server immediately.
// As one request could lead to multiple responses, this interface
// demonstrates the idea of full duplexing.
rpc FullDuplexCall(stream StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
// A sequence of requests followed by a sequence of responses.
// The server buffers all the client requests and then serves them in order. A
// stream of responses are returned to the client when the server starts with
// first request.
rpc HalfDuplexCall(stream StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
}

View File

@ -1,58 +0,0 @@
{
"name": "grpc",
"version": "0.11.1",
"author": "Google Inc.",
"description": "gRPC Library for Node",
"homepage": "http://www.grpc.io/",
"repository": {
"type": "git",
"url": "https://github.com/grpc/grpc.git"
},
"bugs": "https://github.com/grpc/grpc/issues",
"contributors": [
{
"name": "Michael Lumish",
"email": "mlumish@google.com"
}
],
"directories": {
"lib": "src",
"example": "examples"
},
"scripts": {
"lint": "node ./node_modules/jshint/bin/jshint src test examples interop index.js",
"test": "./node_modules/.bin/mocha && npm run-script lint",
"gen_docs": "./node_modules/.bin/jsdoc -c jsdoc_conf.json",
"coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha"
},
"dependencies": {
"bindings": "^1.2.0",
"lodash": "^3.9.3",
"nan": "^2.0.0",
"protobufjs": "^4.0.0"
},
"devDependencies": {
"async": "^0.9.0",
"google-auth-library": "^0.9.2",
"istanbul": "^0.3.21",
"jsdoc": "^3.3.2",
"jshint": "^2.5.0",
"minimist": "^1.1.0",
"mocha": "~1.21.0",
"mustache": "^2.0.0"
},
"engines": {
"node": ">=0.10.13"
},
"files": [
"LICENSE",
"README.md",
"index.js",
"binding.gyp",
"ext",
"health_check",
"src"
],
"main": "index.js",
"license": "BSD-3-Clause"
}

View File

@ -40,7 +40,7 @@
var _ = require('lodash'); var _ = require('lodash');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
var common = require('./common'); var common = require('./common');
@ -54,7 +54,7 @@ var Readable = stream.Readable;
var Writable = stream.Writable; var Writable = stream.Writable;
var Duplex = stream.Duplex; var Duplex = stream.Duplex;
var util = require('util'); var util = require('util');
var version = require('../package.json').version; var version = require('../../../package.json').version;
util.inherits(ClientWritableStream, Writable); util.inherits(ClientWritableStream, Writable);

View File

@ -59,6 +59,7 @@ function normalizeKey(key) {
function validate(key, value) { function validate(key, value) {
if (_.endsWith(key, '-bin')) { if (_.endsWith(key, '-bin')) {
if (!(value instanceof Buffer)) { if (!(value instanceof Buffer)) {
console.log(value.constructor.toString());
throw new Error('keys that end with \'-bin\' must have Buffer values'); throw new Error('keys that end with \'-bin\' must have Buffer values');
} }
} else { } else {
@ -173,7 +174,9 @@ Metadata.prototype._getCoreRepresentation = function() {
Metadata._fromCoreRepresentation = function(metadata) { Metadata._fromCoreRepresentation = function(metadata) {
var newMetadata = new Metadata(); var newMetadata = new Metadata();
if (metadata) { if (metadata) {
newMetadata._internal_repr = _.cloneDeep(metadata); _.forOwn(metadata, function(value, key) {
newMetadata._internal_repr[key] = _.clone(value);
});
} }
return newMetadata; return newMetadata;
}; };

View File

@ -40,7 +40,7 @@
var _ = require('lodash'); var _ = require('lodash');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
var common = require('./common'); var common = require('./common');

View File

@ -34,7 +34,7 @@
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
/** /**
* Helper function to return an absolute deadline given a relative timeout in * Helper function to return an absolute deadline given a relative timeout in

View File

@ -34,7 +34,7 @@
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
/** /**
* This is used for testing functions with multiple asynchronous calls that * This is used for testing functions with multiple asynchronous calls that

View File

@ -34,7 +34,7 @@
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
/** /**
* List of all status names * List of all status names

View File

@ -34,7 +34,7 @@
'use strict'; 'use strict';
var assert = require('assert'); var assert = require('assert');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
/** /**
* This is used for testing functions with multiple asynchronous calls that * This is used for testing functions with multiple asynchronous calls that

View File

@ -90,4 +90,8 @@ describe('Interop tests', function() {
interop_client.runTest(port, name_override, 'timeout_on_sleeping_server', interop_client.runTest(port, name_override, 'timeout_on_sleeping_server',
true, true, done); true, true, done);
}); });
it('should pass custom_metadata', function(done) {
interop_client.runTest(port, name_override, 'custom_metadata',
true, true, done);
});
}); });

View File

@ -36,7 +36,7 @@
var assert = require('assert'); var assert = require('assert');
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc_node');
describe('server', function() { describe('server', function() {
describe('constructor', function() { describe('constructor', function() {

View File

@ -356,7 +356,7 @@ describe('Echo metadata', function() {
call.end(); call.end();
}); });
it('shows the correct user-agent string', function(done) { it('shows the correct user-agent string', function(done) {
var version = require('../package.json').version; var version = require('../../../package.json').version;
var call = client.unary({}, function(err, data) { assert.ifError(err); }, var call = client.unary({}, function(err, data) { assert.ifError(err); },
metadata); metadata);
call.on('metadata', function(metadata) { call.on('metadata', function(metadata) {