Merge github.com:grpc/grpc into serve_fries

pull/10897/head
Craig Tiller 8 years ago
commit 3cf000fb2f
  1. 1
      build.yaml
  2. 1
      src/cpp/server/server_cc.cc
  3. 2
      src/csharp/Grpc.Core/Version.csproj.include
  4. 140
      src/node/ext/node_grpc.cc
  5. 12
      src/node/index.js
  6. 2
      src/node/jsdoc_conf.json
  7. 29
      src/node/src/client.js
  8. 241
      src/node/src/constants.js
  9. 8
      src/node/src/credentials.js
  10. 30
      src/node/src/server.js
  11. 4
      src/node/test/call_test.js
  12. 131
      src/node/test/constant_test.js
  13. 17
      src/node/test/end_to_end_test.js
  14. 2
      templates/src/csharp/Grpc.Core/Version.csproj.include.template
  15. 2
      templates/vsprojects/protoc.props.template
  16. 21
      test/cpp/end2end/generic_end2end_test.cc
  17. 3
      tools/gce/create_linux_worker.sh
  18. 126
      tools/run_tests/generated/tests.json
  19. 21
      tools/run_tests/performance/scenario_config.py
  20. 4
      tools/run_tests/python_utils/jobset.py
  21. 3
      tools/run_tests/run_tests.py
  22. 2
      vsprojects/protoc.props

@ -4581,6 +4581,7 @@ node_modules:
- src/node/src/client.js - src/node/src/client.js
- src/node/src/common.js - src/node/src/common.js
- src/node/src/credentials.js - src/node/src/credentials.js
- src/node/src/constants.js
- src/node/src/grpc_extension.js - src/node/src/grpc_extension.js
- src/node/src/metadata.js - src/node/src/metadata.js
- src/node/src/server.js - src/node/src/server.js

@ -686,6 +686,7 @@ bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag,
StringFromCopiedSlice(call_details_.method); StringFromCopiedSlice(call_details_.method);
static_cast<GenericServerContext*>(context_)->host_ = static_cast<GenericServerContext*>(context_)->host_ =
StringFromCopiedSlice(call_details_.host); StringFromCopiedSlice(call_details_.host);
context_->deadline_ = call_details_.deadline;
} }
grpc_slice_unref(call_details_.method); grpc_slice_unref(call_details_.method);
grpc_slice_unref(call_details_.host); grpc_slice_unref(call_details_.host);

@ -2,6 +2,6 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<GrpcCsharpVersion>1.4.0-dev</GrpcCsharpVersion> <GrpcCsharpVersion>1.4.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.2.0</GoogleProtobufVersion> <GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

@ -85,98 +85,6 @@ logger_state grpc_logger_state;
static char *pem_root_certs = NULL; static char *pem_root_certs = NULL;
void InitStatusConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> status = Nan::New<Object>();
Nan::Set(exports, Nan::New("status").ToLocalChecked(), status);
Local<Value> OK(Nan::New<Uint32, uint32_t>(GRPC_STATUS_OK));
Nan::Set(status, Nan::New("OK").ToLocalChecked(), OK);
Local<Value> CANCELLED(Nan::New<Uint32, uint32_t>(GRPC_STATUS_CANCELLED));
Nan::Set(status, Nan::New("CANCELLED").ToLocalChecked(), CANCELLED);
Local<Value> UNKNOWN(Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNKNOWN));
Nan::Set(status, Nan::New("UNKNOWN").ToLocalChecked(), UNKNOWN);
Local<Value> INVALID_ARGUMENT(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_INVALID_ARGUMENT));
Nan::Set(status, Nan::New("INVALID_ARGUMENT").ToLocalChecked(),
INVALID_ARGUMENT);
Local<Value> DEADLINE_EXCEEDED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_DEADLINE_EXCEEDED));
Nan::Set(status, Nan::New("DEADLINE_EXCEEDED").ToLocalChecked(),
DEADLINE_EXCEEDED);
Local<Value> NOT_FOUND(Nan::New<Uint32, uint32_t>(GRPC_STATUS_NOT_FOUND));
Nan::Set(status, Nan::New("NOT_FOUND").ToLocalChecked(), NOT_FOUND);
Local<Value> ALREADY_EXISTS(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_ALREADY_EXISTS));
Nan::Set(status, Nan::New("ALREADY_EXISTS").ToLocalChecked(), ALREADY_EXISTS);
Local<Value> PERMISSION_DENIED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_PERMISSION_DENIED));
Nan::Set(status, Nan::New("PERMISSION_DENIED").ToLocalChecked(),
PERMISSION_DENIED);
Local<Value> UNAUTHENTICATED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNAUTHENTICATED));
Nan::Set(status, Nan::New("UNAUTHENTICATED").ToLocalChecked(),
UNAUTHENTICATED);
Local<Value> RESOURCE_EXHAUSTED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_RESOURCE_EXHAUSTED));
Nan::Set(status, Nan::New("RESOURCE_EXHAUSTED").ToLocalChecked(),
RESOURCE_EXHAUSTED);
Local<Value> FAILED_PRECONDITION(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_FAILED_PRECONDITION));
Nan::Set(status, Nan::New("FAILED_PRECONDITION").ToLocalChecked(),
FAILED_PRECONDITION);
Local<Value> ABORTED(Nan::New<Uint32, uint32_t>(GRPC_STATUS_ABORTED));
Nan::Set(status, Nan::New("ABORTED").ToLocalChecked(), ABORTED);
Local<Value> OUT_OF_RANGE(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_OUT_OF_RANGE));
Nan::Set(status, Nan::New("OUT_OF_RANGE").ToLocalChecked(), OUT_OF_RANGE);
Local<Value> UNIMPLEMENTED(
Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNIMPLEMENTED));
Nan::Set(status, Nan::New("UNIMPLEMENTED").ToLocalChecked(), UNIMPLEMENTED);
Local<Value> INTERNAL(Nan::New<Uint32, uint32_t>(GRPC_STATUS_INTERNAL));
Nan::Set(status, Nan::New("INTERNAL").ToLocalChecked(), INTERNAL);
Local<Value> UNAVAILABLE(Nan::New<Uint32, uint32_t>(GRPC_STATUS_UNAVAILABLE));
Nan::Set(status, Nan::New("UNAVAILABLE").ToLocalChecked(), UNAVAILABLE);
Local<Value> DATA_LOSS(Nan::New<Uint32, uint32_t>(GRPC_STATUS_DATA_LOSS));
Nan::Set(status, Nan::New("DATA_LOSS").ToLocalChecked(), DATA_LOSS);
}
void InitCallErrorConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> call_error = Nan::New<Object>();
Nan::Set(exports, Nan::New("callError").ToLocalChecked(), call_error);
Local<Value> OK(Nan::New<Uint32, uint32_t>(GRPC_CALL_OK));
Nan::Set(call_error, Nan::New("OK").ToLocalChecked(), OK);
Local<Value> CALL_ERROR(Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR));
Nan::Set(call_error, Nan::New("ERROR").ToLocalChecked(), CALL_ERROR);
Local<Value> NOT_ON_SERVER(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_ON_SERVER));
Nan::Set(call_error, Nan::New("NOT_ON_SERVER").ToLocalChecked(),
NOT_ON_SERVER);
Local<Value> NOT_ON_CLIENT(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_ON_CLIENT));
Nan::Set(call_error, Nan::New("NOT_ON_CLIENT").ToLocalChecked(),
NOT_ON_CLIENT);
Local<Value> ALREADY_INVOKED(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_ALREADY_INVOKED));
Nan::Set(call_error, Nan::New("ALREADY_INVOKED").ToLocalChecked(),
ALREADY_INVOKED);
Local<Value> NOT_INVOKED(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_NOT_INVOKED));
Nan::Set(call_error, Nan::New("NOT_INVOKED").ToLocalChecked(), NOT_INVOKED);
Local<Value> ALREADY_FINISHED(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_ALREADY_FINISHED));
Nan::Set(call_error, Nan::New("ALREADY_FINISHED").ToLocalChecked(),
ALREADY_FINISHED);
Local<Value> TOO_MANY_OPERATIONS(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS));
Nan::Set(call_error, Nan::New("TOO_MANY_OPERATIONS").ToLocalChecked(),
TOO_MANY_OPERATIONS);
Local<Value> INVALID_FLAGS(
Nan::New<Uint32, uint32_t>(GRPC_CALL_ERROR_INVALID_FLAGS));
Nan::Set(call_error, Nan::New("INVALID_FLAGS").ToLocalChecked(),
INVALID_FLAGS);
}
void InitOpTypeConstants(Local<Object> exports) { void InitOpTypeConstants(Local<Object> exports) {
Nan::HandleScope scope; Nan::HandleScope scope;
Local<Object> op_type = Nan::New<Object>(); Local<Object> op_type = Nan::New<Object>();
@ -211,27 +119,6 @@ void InitOpTypeConstants(Local<Object> exports) {
RECV_CLOSE_ON_SERVER); RECV_CLOSE_ON_SERVER);
} }
void InitPropagateConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> propagate = Nan::New<Object>();
Nan::Set(exports, Nan::New("propagate").ToLocalChecked(), propagate);
Local<Value> DEADLINE(Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_DEADLINE));
Nan::Set(propagate, Nan::New("DEADLINE").ToLocalChecked(), DEADLINE);
Local<Value> CENSUS_STATS_CONTEXT(
Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CENSUS_STATS_CONTEXT));
Nan::Set(propagate, Nan::New("CENSUS_STATS_CONTEXT").ToLocalChecked(),
CENSUS_STATS_CONTEXT);
Local<Value> CENSUS_TRACING_CONTEXT(
Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT));
Nan::Set(propagate, Nan::New("CENSUS_TRACING_CONTEXT").ToLocalChecked(),
CENSUS_TRACING_CONTEXT);
Local<Value> CANCELLATION(
Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_CANCELLATION));
Nan::Set(propagate, Nan::New("CANCELLATION").ToLocalChecked(), CANCELLATION);
Local<Value> DEFAULTS(Nan::New<Uint32, uint32_t>(GRPC_PROPAGATE_DEFAULTS));
Nan::Set(propagate, Nan::New("DEFAULTS").ToLocalChecked(), DEFAULTS);
}
void InitConnectivityStateConstants(Local<Object> exports) { void InitConnectivityStateConstants(Local<Object> exports) {
Nan::HandleScope scope; Nan::HandleScope scope;
Local<Object> channel_state = Nan::New<Object>(); Local<Object> channel_state = Nan::New<Object>();
@ -252,28 +139,6 @@ void InitConnectivityStateConstants(Local<Object> exports) {
FATAL_FAILURE); FATAL_FAILURE);
} }
void InitWriteFlags(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> write_flags = Nan::New<Object>();
Nan::Set(exports, Nan::New("writeFlags").ToLocalChecked(), write_flags);
Local<Value> BUFFER_HINT(Nan::New<Uint32, uint32_t>(GRPC_WRITE_BUFFER_HINT));
Nan::Set(write_flags, Nan::New("BUFFER_HINT").ToLocalChecked(), BUFFER_HINT);
Local<Value> NO_COMPRESS(Nan::New<Uint32, uint32_t>(GRPC_WRITE_NO_COMPRESS));
Nan::Set(write_flags, Nan::New("NO_COMPRESS").ToLocalChecked(), NO_COMPRESS);
}
void InitLogConstants(Local<Object> exports) {
Nan::HandleScope scope;
Local<Object> log_verbosity = Nan::New<Object>();
Nan::Set(exports, Nan::New("logVerbosity").ToLocalChecked(), log_verbosity);
Local<Value> LOG_DEBUG(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_DEBUG));
Nan::Set(log_verbosity, Nan::New("DEBUG").ToLocalChecked(), LOG_DEBUG);
Local<Value> LOG_INFO(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_INFO));
Nan::Set(log_verbosity, Nan::New("INFO").ToLocalChecked(), LOG_INFO);
Local<Value> LOG_ERROR(Nan::New<Uint32, uint32_t>(GPR_LOG_SEVERITY_ERROR));
Nan::Set(log_verbosity, Nan::New("ERROR").ToLocalChecked(), LOG_ERROR);
}
NAN_METHOD(MetadataKeyIsLegal) { NAN_METHOD(MetadataKeyIsLegal) {
if (!info[0]->IsString()) { if (!info[0]->IsString()) {
return Nan::ThrowTypeError("headerKeyIsLegal's argument must be a string"); return Nan::ThrowTypeError("headerKeyIsLegal's argument must be a string");
@ -421,13 +286,8 @@ void init(Local<Object> exports) {
grpc_set_ssl_roots_override_callback(get_ssl_roots_override); grpc_set_ssl_roots_override_callback(get_ssl_roots_override);
init_logger(); init_logger();
InitStatusConstants(exports);
InitCallErrorConstants(exports);
InitOpTypeConstants(exports); InitOpTypeConstants(exports);
InitPropagateConstants(exports);
InitConnectivityStateConstants(exports); InitConnectivityStateConstants(exports);
InitWriteFlags(exports);
InitLogConstants(exports);
grpc_pollset_work_run_loop = 0; grpc_pollset_work_run_loop = 0;

@ -59,6 +59,8 @@ var grpc = require('./src/grpc_extension');
var protobuf_js_5_common = require('./src/protobuf_js_5_common'); var protobuf_js_5_common = require('./src/protobuf_js_5_common');
var protobuf_js_6_common = require('./src/protobuf_js_6_common'); var protobuf_js_6_common = require('./src/protobuf_js_6_common');
var constants = require('./src/constants.js');
grpc.setDefaultRootsPem(fs.readFileSync(SSL_ROOTS_PATH, 'ascii')); grpc.setDefaultRootsPem(fs.readFileSync(SSL_ROOTS_PATH, 'ascii'));
/** /**
@ -212,27 +214,27 @@ exports.Metadata = Metadata;
/** /**
* Status name to code number mapping * Status name to code number mapping
*/ */
exports.status = grpc.status; exports.status = constants.status;
/** /**
* Propagate flag name to number mapping * Propagate flag name to number mapping
*/ */
exports.propagate = grpc.propagate; exports.propagate = constants.propagate;
/** /**
* Call error name to code number mapping * Call error name to code number mapping
*/ */
exports.callError = grpc.callError; exports.callError = constants.callError;
/** /**
* Write flag name to code number mapping * Write flag name to code number mapping
*/ */
exports.writeFlags = grpc.writeFlags; exports.writeFlags = constants.writeFlags;
/** /**
* Log verbosity setting name to code number mapping * Log verbosity setting name to code number mapping
*/ */
exports.logVerbosity = grpc.logVerbosity; exports.logVerbosity = constants.logVerbosity;
/** /**
* Credentials factories * Credentials factories

@ -11,7 +11,7 @@
"package": "package.json", "package": "package.json",
"readme": "src/node/README.md" "readme": "src/node/README.md"
}, },
"plugins": [], "plugins": ["plugins/markdown"],
"templates": { "templates": {
"cleverLinks": false, "cleverLinks": false,
"monospaceLinks": false, "monospaceLinks": false,

@ -58,6 +58,8 @@ var common = require('./common');
var Metadata = require('./metadata'); var Metadata = require('./metadata');
var constants = require('./constants');
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var stream = require('stream'); var stream = require('stream');
@ -127,7 +129,8 @@ function _write(chunk, encoding, callback) {
but passing an object that causes a serialization failure is a misuse but passing an object that causes a serialization failure is a misuse
of the API anyway, so that's OK. The primary purpose here is to give the of the API anyway, so that's OK. The primary purpose here is to give the
programmer a useful error and to stop the stream properly */ programmer a useful error and to stop the stream properly */
this.call.cancelWithStatus(grpc.status.INTERNAL, 'Serialization failure'); this.call.cancelWithStatus(constants.status.INTERNAL,
'Serialization failure');
callback(e); callback(e);
} }
if (_.isFinite(encoding)) { if (_.isFinite(encoding)) {
@ -185,9 +188,9 @@ function ClientReadableStream(call, deserialize) {
function _readsDone(status) { function _readsDone(status) {
/* jshint validthis: true */ /* jshint validthis: true */
if (!status) { if (!status) {
status = {code: grpc.status.OK, details: 'OK'}; status = {code: constants.status.OK, details: 'OK'};
} }
if (status.code !== grpc.status.OK) { if (status.code !== constants.status.OK) {
this.call.cancelWithStatus(status.code, status.details); this.call.cancelWithStatus(status.code, status.details);
} }
this.finished = true; this.finished = true;
@ -218,12 +221,12 @@ function _emitStatusIfDone() {
/* jshint validthis: true */ /* jshint validthis: true */
var status; var status;
if (this.read_status && this.received_status) { if (this.read_status && this.received_status) {
if (this.read_status.code !== grpc.status.OK) { if (this.read_status.code !== constants.status.OK) {
status = this.read_status; status = this.read_status;
} else { } else {
status = this.received_status; status = this.received_status;
} }
if (status.code === grpc.status.OK) { if (status.code === constants.status.OK) {
this.push(null); this.push(null);
} else { } else {
var error = new Error(status.details); var error = new Error(status.details);
@ -262,7 +265,7 @@ function _read(size) {
try { try {
deserialized = self.deserialize(data); deserialized = self.deserialize(data);
} catch (e) { } catch (e) {
self._readsDone({code: grpc.status.INTERNAL, self._readsDone({code: constants.status.INTERNAL,
details: 'Failed to parse server response'}); details: 'Failed to parse server response'});
return; return;
} }
@ -510,7 +513,7 @@ Client.prototype.makeUnaryRequest = function(method, serialize, deserialize,
var deserialized; var deserialized;
emitter.emit('metadata', Metadata._fromCoreRepresentation( emitter.emit('metadata', Metadata._fromCoreRepresentation(
response.metadata)); response.metadata));
if (status.code === grpc.status.OK) { if (status.code === constants.status.OK) {
if (err) { if (err) {
// Got a batch error, but OK status. Something went wrong // Got a batch error, but OK status. Something went wrong
args.callback(err); args.callback(err);
@ -522,13 +525,13 @@ Client.prototype.makeUnaryRequest = function(method, serialize, deserialize,
/* Change status to indicate bad server response. This will result /* Change status to indicate bad server response. This will result
* in passing an error to the callback */ * in passing an error to the callback */
status = { status = {
code: grpc.status.INTERNAL, code: constants.status.INTERNAL,
details: 'Failed to parse server response' details: 'Failed to parse server response'
}; };
} }
} }
} }
if (status.code !== grpc.status.OK) { if (status.code !== constants.status.OK) {
error = new Error(status.details); error = new Error(status.details);
error.code = status.code; error.code = status.code;
error.metadata = status.metadata; error.metadata = status.metadata;
@ -593,7 +596,7 @@ Client.prototype.makeClientStreamRequest = function(method, serialize,
var status = response.status; var status = response.status;
var error; var error;
var deserialized; var deserialized;
if (status.code === grpc.status.OK) { if (status.code === constants.status.OK) {
if (err) { if (err) {
// Got a batch error, but OK status. Something went wrong // Got a batch error, but OK status. Something went wrong
args.callback(err); args.callback(err);
@ -605,13 +608,13 @@ Client.prototype.makeClientStreamRequest = function(method, serialize,
/* Change status to indicate bad server response. This will result /* Change status to indicate bad server response. This will result
* in passing an error to the callback */ * in passing an error to the callback */
status = { status = {
code: grpc.status.INTERNAL, code: constants.status.INTERNAL,
details: 'Failed to parse server response' details: 'Failed to parse server response'
}; };
} }
} }
} }
if (status.code !== grpc.status.OK) { if (status.code !== constants.status.OK) {
error = new Error(response.status.details); error = new Error(response.status.details);
error.code = status.code; error.code = status.code;
error.metadata = status.metadata; error.metadata = status.metadata;
@ -921,7 +924,7 @@ exports.waitForClientReady = function(client, deadline, callback) {
/** /**
* Map of status code names to status codes * Map of status code names to status codes
*/ */
exports.status = grpc.status; exports.status = constants.status;
/** /**
* See docs for client.callError * See docs for client.callError

@ -0,0 +1,241 @@
/*
*
* Copyright 2017, 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.
*
*/
/**
* @module
*/
/* The comments about status codes are copied verbatim (with some formatting
* modifications) from include/grpc/impl/codegen/status.h, for the purpose of
* including them in generated documentation.
*/
/**
* Enum of status codes that gRPC can return
* @readonly
* @enum {number}
*/
exports.status = {
/** Not an error; returned on success */
OK: 0,
/** The operation was cancelled (typically by the caller). */
CANCELLED: 1,
/**
* Unknown error. An example of where this error may be returned is
* if a status value received from another address space belongs to
* an error-space that is not known in this address space. Also
* errors raised by APIs that do not return enough error information
* may be converted to this error.
*/
UNKNOWN: 2,
/**
* Client specified an invalid argument. Note that this differs
* from FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments
* that are problematic regardless of the state of the system
* (e.g., a malformed file name).
*/
INVALID_ARGUMENT: 3,
/**
* Deadline expired before operation could complete. For operations
* that change the state of the system, this error may be returned
* even if the operation has completed successfully. For example, a
* successful response from a server could have been delayed long
* enough for the deadline to expire.
*/
DEADLINE_EXCEEDED: 4,
/** Some requested entity (e.g., file or directory) was not found. */
NOT_FOUND: 5,
/**
* Some entity that we attempted to create (e.g., file or directory)
* already exists.
*/
ALREADY_EXISTS: 6,
/**
* The caller does not have permission to execute the specified
* operation. PERMISSION_DENIED must not be used for rejections
* caused by exhausting some resource (use RESOURCE_EXHAUSTED
* instead for those errors). PERMISSION_DENIED must not be
* used if the caller can not be identified (use UNAUTHENTICATED
* instead for those errors).
*/
PERMISSION_DENIED: 7,
/**
* Some resource has been exhausted, perhaps a per-user quota, or
* perhaps the entire file system is out of space.
*/
RESOURCE_EXHAUSTED: 8,
/**
* Operation was rejected because the system is not in a state
* required for the operation's execution. For example, directory
* to be deleted may be non-empty, an rmdir operation is applied to
* a non-directory, etc.
*
* A litmus test that may help a service implementor in deciding
* between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
*
* - Use UNAVAILABLE if the client can retry just the failing call.
* - Use ABORTED if the client should retry at a higher-level
* (e.g., restarting a read-modify-write sequence).
* - Use FAILED_PRECONDITION if the client should not retry until
* the system state has been explicitly fixed. E.g., if an "rmdir"
* fails because the directory is non-empty, FAILED_PRECONDITION
* should be returned since the client should not retry unless
* they have first fixed up the directory by deleting files from it.
* - Use FAILED_PRECONDITION if the client performs conditional
* REST Get/Update/Delete on a resource and the resource on the
* server does not match the condition. E.g., conflicting
* read-modify-write on the same resource.
*/
FAILED_PRECONDITION: 9,
/**
* The operation was aborted, typically due to a concurrency issue
* like sequencer check failures, transaction aborts, etc.
*
* See litmus test above for deciding between FAILED_PRECONDITION,
* ABORTED, and UNAVAILABLE.
*/
ABORTED: 10,
/**
* Operation was attempted past the valid range. E.g., seeking or
* reading past end of file.
*
* Unlike INVALID_ARGUMENT, this error indicates a problem that may
* be fixed if the system state changes. For example, a 32-bit file
* system will generate INVALID_ARGUMENT if asked to read at an
* offset that is not in the range [0,2^32-1], but it will generate
* OUT_OF_RANGE if asked to read from an offset past the current
* file size.
*
* There is a fair bit of overlap between FAILED_PRECONDITION and
* OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific
* error) when it applies so that callers who are iterating through
* a space can easily look for an OUT_OF_RANGE error to detect when
* they are done.
*/
OUT_OF_RANGE: 11,
/** Operation is not implemented or not supported/enabled in this service. */
UNIMPLEMENTED: 12,
/**
* Internal errors. Means some invariants expected by underlying
* system has been broken. If you see one of these errors,
* something is very broken.
*/
INTERNAL: 13,
/**
* The service is currently unavailable. This is a most likely a
* transient condition and may be corrected by retrying with
* a backoff.
*
* See litmus test above for deciding between FAILED_PRECONDITION,
* ABORTED, and UNAVAILABLE. */
UNAVAILABLE: 14,
/** Unrecoverable data loss or corruption. */
DATA_LOSS: 15,
/**
* The request does not have valid authentication credentials for the
* operation.
*/
UNAUTHENTICATED: 16
};
/* The comments about propagation bit flags are copied rom
* include/grpc/impl/codegen/propagation_bits.h for the purpose of including
* them in generated documentation.
*/
/**
* Propagation flags: these can be bitwise or-ed to form the propagation option
* for calls.
*
* Users are encouraged to write propagation masks as deltas from the default.
* i.e. write `grpc.propagate.DEFAULTS & ~grpc.propagate.DEADLINE` to disable
* deadline propagation.
* @enum {number}
*/
exports.propagate = {
DEADLINE: 1,
CENSUS_STATS_CONTEXT: 2,
CENSUS_TRACING_CONTEXT: 4,
CANCELLATION: 8,
DEFAULTS: 65535
};
/* Many of the following comments are copied from
* include/grpc/impl/codegen/grpc_types.h
*/
/**
* Call error constants. Call errors almost always indicate bugs in the gRPC
* library, and these error codes are mainly useful for finding those bugs.
* @enum {number}
*/
exports.callError = {
OK: 0,
ERROR: 1,
NOT_ON_SERVER: 2,
NOT_ON_CLIENT: 3,
ALREADY_INVOKED: 5,
NOT_INVOKED: 6,
ALREADY_FINISHED: 7,
TOO_MANY_OPERATIONS: 8,
INVALID_FLAGS: 9,
INVALID_METADATA: 10,
INVALID_MESSAGE: 11,
NOT_SERVER_COMPLETION_QUEUE: 12,
BATCH_TOO_BIG: 13,
PAYLOAD_TYPE_MISMATCH: 14
};
/**
* Write flags: these can be bitwise or-ed to form write options that modify
* how data is written.
* @enum {number}
*/
exports.writeFlags = {
/**
* Hint that the write may be buffered and need not go out on the wire
* immediately. GRPC is free to buffer the message until the next non-buffered
* write, or until writes_done, but it need not buffer completely or at all.
*/
BUFFER_HINT: 1,
/**
* Force compression to be disabled for a particular write
*/
NO_COMPRESS: 2
};
/**
* @enum {number}
*/
exports.logVerbosity = {
DEBUG: 0,
INFO: 1,
ERROR: 2
};

@ -71,6 +71,8 @@ var Metadata = require('./metadata.js');
var common = require('./common.js'); var common = require('./common.js');
var constants = require('./constants');
var _ = require('lodash'); var _ = require('lodash');
/** /**
@ -97,14 +99,14 @@ exports.createFromMetadataGenerator = function(metadata_generator) {
return CallCredentials.createFromPlugin(function(service_url, cb_data, return CallCredentials.createFromPlugin(function(service_url, cb_data,
callback) { callback) {
metadata_generator({service_url: service_url}, function(error, metadata) { metadata_generator({service_url: service_url}, function(error, metadata) {
var code = grpc.status.OK; var code = constants.status.OK;
var message = ''; var message = '';
if (error) { if (error) {
message = error.message; message = error.message;
if (error.hasOwnProperty('code') && _.isFinite(error.code)) { if (error.hasOwnProperty('code') && _.isFinite(error.code)) {
code = error.code; code = error.code;
} else { } else {
code = grpc.status.UNAUTHENTICATED; code = constants.status.UNAUTHENTICATED;
} }
if (!metadata) { if (!metadata) {
metadata = new Metadata(); metadata = new Metadata();
@ -125,7 +127,7 @@ exports.createFromGoogleCredential = function(google_credential) {
var service_url = auth_context.service_url; var service_url = auth_context.service_url;
google_credential.getRequestMetadata(service_url, function(err, header) { google_credential.getRequestMetadata(service_url, function(err, header) {
if (err) { if (err) {
common.log(grpc.logVerbosity.INFO, 'Auth error:' + err); common.log(constants.logVerbosity.INFO, 'Auth error:' + err);
callback(err); callback(err);
return; return;
} }

@ -57,6 +57,8 @@ var common = require('./common');
var Metadata = require('./metadata'); var Metadata = require('./metadata');
var constants = require('./constants');
var stream = require('stream'); var stream = require('stream');
var Readable = stream.Readable; var Readable = stream.Readable;
@ -75,7 +77,7 @@ var EventEmitter = require('events').EventEmitter;
function handleError(call, error) { function handleError(call, error) {
var statusMetadata = new Metadata(); var statusMetadata = new Metadata();
var status = { var status = {
code: grpc.status.UNKNOWN, code: constants.status.UNKNOWN,
details: 'Unknown Error' details: 'Unknown Error'
}; };
if (error.hasOwnProperty('message')) { if (error.hasOwnProperty('message')) {
@ -115,7 +117,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) {
var end_batch = {}; var end_batch = {};
var statusMetadata = new Metadata(); var statusMetadata = new Metadata();
var status = { var status = {
code: grpc.status.OK, code: constants.status.OK,
details: 'OK' details: 'OK'
}; };
if (metadata) { if (metadata) {
@ -125,7 +127,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) {
try { try {
message = serialize(value); message = serialize(value);
} catch (e) { } catch (e) {
e.code = grpc.status.INTERNAL; e.code = constants.status.INTERNAL;
handleError(call, e); handleError(call, e);
return; return;
} }
@ -151,7 +153,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) {
function setUpWritable(stream, serialize) { function setUpWritable(stream, serialize) {
stream.finished = false; stream.finished = false;
stream.status = { stream.status = {
code : grpc.status.OK, code : constants.status.OK,
details : 'OK', details : 'OK',
metadata : new Metadata() metadata : new Metadata()
}; };
@ -178,7 +180,7 @@ function setUpWritable(stream, serialize) {
* @param {Error} err The error object * @param {Error} err The error object
*/ */
function setStatus(err) { function setStatus(err) {
var code = grpc.status.UNKNOWN; var code = constants.status.UNKNOWN;
var details = 'Unknown Error'; var details = 'Unknown Error';
var metadata = new Metadata(); var metadata = new Metadata();
if (err.hasOwnProperty('message')) { if (err.hasOwnProperty('message')) {
@ -284,7 +286,7 @@ function _write(chunk, encoding, callback) {
try { try {
message = this.serialize(chunk); message = this.serialize(chunk);
} catch (e) { } catch (e) {
e.code = grpc.status.INTERNAL; e.code = constants.status.INTERNAL;
callback(e); callback(e);
return; return;
} }
@ -353,7 +355,7 @@ function _read(size) {
try { try {
deserialized = self.deserialize(data); deserialized = self.deserialize(data);
} catch (e) { } catch (e) {
e.code = grpc.status.INTERNAL; e.code = constants.status.INTERNAL;
self.emit('error', e); self.emit('error', e);
return; return;
} }
@ -489,7 +491,7 @@ function handleUnary(call, handler, metadata) {
try { try {
emitter.request = handler.deserialize(result.read); emitter.request = handler.deserialize(result.read);
} catch (e) { } catch (e) {
e.code = grpc.status.INTERNAL; e.code = constants.status.INTERNAL;
handleError(call, e); handleError(call, e);
return; return;
} }
@ -530,7 +532,7 @@ function handleServerStreaming(call, handler, metadata) {
try { try {
stream.request = handler.deserialize(result.read); stream.request = handler.deserialize(result.read);
} catch (e) { } catch (e) {
e.code = grpc.status.INTERNAL; e.code = constants.status.INTERNAL;
stream.emit('error', e); stream.emit('error', e);
return; return;
} }
@ -636,7 +638,7 @@ function Server(options) {
batch[grpc.opType.SEND_INITIAL_METADATA] = batch[grpc.opType.SEND_INITIAL_METADATA] =
(new Metadata())._getCoreRepresentation(); (new Metadata())._getCoreRepresentation();
batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
code: grpc.status.UNIMPLEMENTED, code: constants.status.UNIMPLEMENTED,
details: '', details: '',
metadata: {} metadata: {}
}; };
@ -699,7 +701,7 @@ Server.prototype.register = function(name, handler, serialize, deserialize,
}; };
var unimplementedStatusResponse = { var unimplementedStatusResponse = {
code: grpc.status.UNIMPLEMENTED, code: constants.status.UNIMPLEMENTED,
details: 'The server does not implement this method' details: 'The server does not implement this method'
}; };
@ -759,8 +761,8 @@ Server.prototype.addService = function(service, implementation) {
written in the proto file, instead of using JavaScript function written in the proto file, instead of using JavaScript function
naming style */ naming style */
if (implementation[attrs.originalName] === undefined) { if (implementation[attrs.originalName] === undefined) {
common.log(grpc.logVerbosity.ERROR, 'Method handler ' + name + ' for ' + common.log(constants.logVerbosity.ERROR, 'Method handler ' + name +
attrs.path + ' expected but not provided'); ' for ' + attrs.path + ' expected but not provided');
impl = defaultHandler[method_type]; impl = defaultHandler[method_type];
} else { } else {
impl = _.bind(implementation[attrs.originalName], implementation); impl = _.bind(implementation[attrs.originalName], implementation);
@ -790,7 +792,7 @@ Server.prototype.addProtoService = function(service, implementation) {
var options; var options;
var protobuf_js_5_common = require('./protobuf_js_5_common'); var protobuf_js_5_common = require('./protobuf_js_5_common');
var protobuf_js_6_common = require('./protobuf_js_6_common'); var protobuf_js_6_common = require('./protobuf_js_6_common');
common.log(grpc.logVerbosity.INFO, common.log(constants.logVerbosity.INFO,
'Server#addProtoService is deprecated. Use addService instead'); 'Server#addProtoService is deprecated. Use addService instead');
if (protobuf_js_5_common.isProbablyProtobufJs5(service)) { if (protobuf_js_5_common.isProbablyProtobufJs5(service)) {
options = _.defaults(service.grpc_options, common.defaultGrpcOptions); options = _.defaults(service.grpc_options, common.defaultGrpcOptions);

@ -35,6 +35,7 @@
var assert = require('assert'); var assert = require('assert');
var grpc = require('../src/grpc_extension'); var grpc = require('../src/grpc_extension');
var constants = require('../src/constants');
/** /**
* Helper function to return an absolute deadline given a relative timeout in * Helper function to return an absolute deadline given a relative timeout in
@ -120,7 +121,8 @@ describe('call', function() {
var batch = {}; var batch = {};
batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true; batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
call.startBatch(batch, function(err, response) { call.startBatch(batch, function(err, response) {
assert.strictEqual(response.status.code, grpc.status.DEADLINE_EXCEEDED); assert.strictEqual(response.status.code,
constants.status.DEADLINE_EXCEEDED);
done(); done();
}); });
}); });

@ -1,131 +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.
*
*/
'use strict';
var assert = require('assert');
var grpc = require('../src/grpc_extension');
/**
* List of all status names
* @const
* @type {Array.<string>}
*/
var statusNames = [
'OK',
'CANCELLED',
'UNKNOWN',
'INVALID_ARGUMENT',
'DEADLINE_EXCEEDED',
'NOT_FOUND',
'ALREADY_EXISTS',
'PERMISSION_DENIED',
'UNAUTHENTICATED',
'RESOURCE_EXHAUSTED',
'FAILED_PRECONDITION',
'ABORTED',
'OUT_OF_RANGE',
'UNIMPLEMENTED',
'INTERNAL',
'UNAVAILABLE',
'DATA_LOSS'
];
/**
* List of all call error names
* @const
* @type {Array.<string>}
*/
var callErrorNames = [
'OK',
'ERROR',
'NOT_ON_SERVER',
'NOT_ON_CLIENT',
'ALREADY_INVOKED',
'NOT_INVOKED',
'ALREADY_FINISHED',
'TOO_MANY_OPERATIONS',
'INVALID_FLAGS'
];
/**
* List of all propagate flag names
* @const
* @type {Array.<string>}
*/
var propagateFlagNames = [
'DEADLINE',
'CENSUS_STATS_CONTEXT',
'CENSUS_TRACING_CONTEXT',
'CANCELLATION',
'DEFAULTS'
];
/*
* 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++) {
assert(grpc.status.hasOwnProperty(statusNames[i]),
'status missing: ' + statusNames[i]);
}
});
it('should have all of the call errors', function() {
for (var i = 0; i < callErrorNames.length; i++) {
assert(grpc.callError.hasOwnProperty(callErrorNames[i]),
'call error missing: ' + callErrorNames[i]);
}
});
it('should have all of the propagate flags', function() {
for (var i = 0; i < propagateFlagNames.length; i++) {
assert(grpc.propagate.hasOwnProperty(propagateFlagNames[i]),
'call error missing: ' + propagateFlagNames[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]);
}
});
});

@ -35,6 +35,7 @@
var assert = require('assert'); var assert = require('assert');
var grpc = require('../src/grpc_extension'); var grpc = require('../src/grpc_extension');
var constants = require('../src/constants');
/** /**
* This is used for testing functions with multiple asynchronous calls that * This is used for testing functions with multiple asynchronous calls that
@ -90,7 +91,7 @@ describe('end-to-end', function() {
client_close: true, client_close: true,
metadata: {}, metadata: {},
status: { status: {
code: grpc.status.OK, code: constants.status.OK,
details: status_text, details: status_text,
metadata: {} metadata: {}
} }
@ -107,7 +108,7 @@ describe('end-to-end', function() {
server_batch[grpc.opType.SEND_INITIAL_METADATA] = {}; server_batch[grpc.opType.SEND_INITIAL_METADATA] = {};
server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
metadata: {}, metadata: {},
code: grpc.status.OK, code: constants.status.OK,
details: status_text details: status_text
}; };
server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
@ -141,7 +142,7 @@ describe('end-to-end', function() {
send_metadata: true, send_metadata: true,
client_close: true, client_close: true,
metadata: {server_key: ['server_value']}, metadata: {server_key: ['server_value']},
status: {code: grpc.status.OK, status: {code: constants.status.OK,
details: status_text, details: status_text,
metadata: {}} metadata: {}}
}); });
@ -161,7 +162,7 @@ describe('end-to-end', function() {
}; };
server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
metadata: {}, metadata: {},
code: grpc.status.OK, code: constants.status.OK,
details: status_text details: status_text
}; };
server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
@ -198,7 +199,7 @@ describe('end-to-end', function() {
assert.deepEqual(response.metadata, {}); assert.deepEqual(response.metadata, {});
assert(response.send_message); assert(response.send_message);
assert.strictEqual(response.read.toString(), reply_text); assert.strictEqual(response.read.toString(), reply_text);
assert.deepEqual(response.status, {code: grpc.status.OK, assert.deepEqual(response.status, {code: constants.status.OK,
details: status_text, details: status_text,
metadata: {}}); metadata: {}});
done(); done();
@ -220,7 +221,7 @@ describe('end-to-end', function() {
response_batch[grpc.opType.SEND_MESSAGE] = new Buffer(reply_text); response_batch[grpc.opType.SEND_MESSAGE] = new Buffer(reply_text);
response_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { response_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
metadata: {}, metadata: {},
code: grpc.status.OK, code: constants.status.OK,
details: status_text details: status_text
}; };
response_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; response_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
@ -260,7 +261,7 @@ describe('end-to-end', function() {
send_message: true, send_message: true,
client_close: true, client_close: true,
status: { status: {
code: grpc.status.OK, code: constants.status.OK,
details: status_text, details: status_text,
metadata: {} metadata: {}
} }
@ -290,7 +291,7 @@ describe('end-to-end', function() {
end_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; end_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
metadata: {}, metadata: {},
code: grpc.status.OK, code: constants.status.OK,
details: status_text details: status_text
}; };
server_call.startBatch(end_batch, function(err, response) { server_call.startBatch(end_batch, function(err, response) {

@ -4,6 +4,6 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<GrpcCsharpVersion>${settings.csharp_version}</GrpcCsharpVersion> <GrpcCsharpVersion>${settings.csharp_version}</GrpcCsharpVersion>
<GoogleProtobufVersion>3.2.0</GoogleProtobufVersion> <GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

@ -5,7 +5,7 @@
<PropertyGroup /> <PropertyGroup />
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>
<DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> <DisableSpecificWarnings>4244;4267;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>libprotoc.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>libprotoc.lib;%(AdditionalDependencies)</AdditionalDependencies>

@ -115,6 +115,10 @@ class GenericEnd2endTest : public ::testing::Test {
void client_fail(int i) { verify_ok(&cli_cq_, i, false); } void client_fail(int i) { verify_ok(&cli_cq_, i, false); }
void SendRpc(int num_rpcs) { void SendRpc(int num_rpcs) {
SendRpc(num_rpcs, false, gpr_inf_future(GPR_CLOCK_MONOTONIC));
}
void SendRpc(int num_rpcs, bool check_deadline, gpr_timespec deadline) {
const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo");
for (int i = 0; i < num_rpcs; i++) { for (int i = 0; i < num_rpcs; i++) {
EchoRequest send_request; EchoRequest send_request;
@ -129,6 +133,11 @@ class GenericEnd2endTest : public ::testing::Test {
// The string needs to be long enough to test heap-based slice. // The string needs to be long enough to test heap-based slice.
send_request.set_message("Hello world. Hello world. Hello world."); send_request.set_message("Hello world. Hello world. Hello world.");
if (check_deadline) {
cli_ctx.set_deadline(deadline);
}
std::unique_ptr<GenericClientAsyncReaderWriter> call = std::unique_ptr<GenericClientAsyncReaderWriter> call =
generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
client_ok(1); client_ok(1);
@ -147,6 +156,12 @@ class GenericEnd2endTest : public ::testing::Test {
verify_ok(srv_cq_.get(), 4, true); verify_ok(srv_cq_.get(), 4, true);
EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length()));
EXPECT_EQ(kMethodName, srv_ctx.method()); EXPECT_EQ(kMethodName, srv_ctx.method());
if (check_deadline) {
EXPECT_TRUE(gpr_time_similar(deadline, srv_ctx.raw_deadline(),
gpr_time_from_millis(100, GPR_TIMESPAN)));
}
ByteBuffer recv_buffer; ByteBuffer recv_buffer;
stream.Read(&recv_buffer, tag(5)); stream.Read(&recv_buffer, tag(5));
server_ok(5); server_ok(5);
@ -262,6 +277,12 @@ TEST_F(GenericEnd2endTest, SimpleBidiStreaming) {
EXPECT_TRUE(recv_status.ok()); EXPECT_TRUE(recv_status.ok());
} }
TEST_F(GenericEnd2endTest, Deadline) {
ResetStub();
SendRpc(1, true, gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_seconds(10, GPR_TIMESPAN)));
}
} // namespace } // namespace
} // namespace testing } // namespace testing
} // namespace grpc } // namespace grpc

@ -45,7 +45,8 @@ gcloud compute instances create $INSTANCE_NAME \
--machine-type n1-standard-16 \ --machine-type n1-standard-16 \
--image=ubuntu-1510 \ --image=ubuntu-1510 \
--image-project=grpc-testing \ --image-project=grpc-testing \
--boot-disk-size 1000 --boot-disk-size 1000 \
--scopes https://www.googleapis.com/auth/bigquery
echo 'Created GCE instance, waiting 60 seconds for it to come online.' echo 'Created GCE instance, waiting 60 seconds for it to come online.'
sleep 60 sleep 60

@ -41350,6 +41350,56 @@
"posix" "posix"
] ]
}, },
{
"args": [
"--scenarios_json",
"{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_1channel_100rpcs_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
"linux"
],
"cpu_cost": "capacity",
"defaults": "boringssl",
"exclude_configs": [
"tsan",
"asan"
],
"excluded_poll_engines": [],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
"platforms": [
"linux"
],
"shortname": "json_run_localhost:cpp_protobuf_async_unary_1channel_100rpcs_1MB",
"timeout_seconds": 360
},
{
"args": [
"--scenarios_json",
"{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_from_client_1channel_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING_FROM_CLIENT\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
"linux"
],
"cpu_cost": "capacity",
"defaults": "boringssl",
"exclude_configs": [
"tsan",
"asan"
],
"excluded_poll_engines": [],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
"platforms": [
"linux"
],
"shortname": "json_run_localhost:cpp_protobuf_async_streaming_from_client_1channel_1MB",
"timeout_seconds": 360
},
{ {
"args": [ "args": [
"--scenarios_json", "--scenarios_json",
@ -42908,6 +42958,82 @@
"shortname": "json_run_localhost:cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "shortname": "json_run_localhost:cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure",
"timeout_seconds": 360 "timeout_seconds": 360
}, },
{
"args": [
"--scenarios_json",
"{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_1channel_100rpcs_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
"linux"
],
"cpu_cost": "capacity",
"defaults": "boringssl",
"exclude_configs": [
"asan-noleaks",
"asan-trace-cmp",
"basicprof",
"c++-compat",
"counters",
"dbg",
"gcov",
"helgrind",
"lto",
"memcheck",
"msan",
"mutrace",
"opt",
"stapprof",
"ubsan"
],
"excluded_poll_engines": [],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
"platforms": [
"linux"
],
"shortname": "json_run_localhost:cpp_protobuf_async_unary_1channel_100rpcs_1MB_low_thread_count",
"timeout_seconds": 360
},
{
"args": [
"--scenarios_json",
"{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_from_client_1channel_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING_FROM_CLIENT\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}"
],
"boringssl": true,
"ci_platforms": [
"linux"
],
"cpu_cost": "capacity",
"defaults": "boringssl",
"exclude_configs": [
"asan-noleaks",
"asan-trace-cmp",
"basicprof",
"c++-compat",
"counters",
"dbg",
"gcov",
"helgrind",
"lto",
"memcheck",
"msan",
"mutrace",
"opt",
"stapprof",
"ubsan"
],
"excluded_poll_engines": [],
"flaky": false,
"language": "c++",
"name": "json_run_localhost",
"platforms": [
"linux"
],
"shortname": "json_run_localhost:cpp_protobuf_async_streaming_from_client_1channel_1MB_low_thread_count",
"timeout_seconds": 360
},
{ {
"args": [ "args": [
"--scenarios_json", "--scenarios_json",

@ -112,6 +112,7 @@ def _ping_pong_scenario(name, rpc_type,
categories=DEFAULT_CATEGORIES, categories=DEFAULT_CATEGORIES,
channels=None, channels=None,
outstanding=None, outstanding=None,
num_clients=None,
resource_quota_size=None, resource_quota_size=None,
messages_per_stream=None, messages_per_stream=None,
excluded_poll_engines=[]): excluded_poll_engines=[]):
@ -158,7 +159,7 @@ def _ping_pong_scenario(name, rpc_type,
wide = channels if channels is not None else WIDE wide = channels if channels is not None else WIDE
deep = int(math.ceil(1.0 * outstanding_calls / wide)) deep = int(math.ceil(1.0 * outstanding_calls / wide))
scenario['num_clients'] = 0 # use as many client as available. scenario['num_clients'] = num_clients if num_clients is not None else 0 # use as many clients as available.
scenario['client_config']['outstanding_rpcs_per_channel'] = deep scenario['client_config']['outstanding_rpcs_per_channel'] = deep
scenario['client_config']['client_channels'] = wide scenario['client_config']['client_channels'] = wide
scenario['client_config']['async_client_threads'] = 0 scenario['client_config']['async_client_threads'] = 0
@ -196,6 +197,24 @@ class CXXLanguage:
def scenarios(self): def scenarios(self):
# TODO(ctiller): add 70% load latency test # TODO(ctiller): add 70% load latency test
yield _ping_pong_scenario(
'cpp_protobuf_async_unary_1channel_100rpcs_1MB', rpc_type='UNARY',
client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
req_size=1024*1024, resp_size=1024*1024,
unconstrained_client='async', outstanding=100, channels=1,
num_clients=1,
secure=False,
categories=[SMOKETEST] + [SCALABLE])
yield _ping_pong_scenario(
'cpp_protobuf_async_streaming_from_client_1channel_1MB', rpc_type='STREAMING_FROM_CLIENT',
client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
req_size=1024*1024, resp_size=1024*1024,
unconstrained_client='async', outstanding=1, channels=1,
num_clients=1,
secure=False,
categories=[SMOKETEST] + [SCALABLE])
for secure in [True, False]: for secure in [True, False]:
secstr = 'secure' if secure else 'insecure' secstr = 'secure' if secure else 'insecure'
smoketest_categories = ([SMOKETEST] if secure else []) + [SCALABLE] smoketest_categories = ([SMOKETEST] if secure else []) + [SCALABLE]

@ -255,7 +255,7 @@ class Job(object):
self._start = time.time() self._start = time.time()
cmdline = self._spec.cmdline cmdline = self._spec.cmdline
if measure_cpu_costs: if measure_cpu_costs:
cmdline = ['time', '--portability'] + cmdline cmdline = ['time', '-p'] + cmdline
try_start = lambda: subprocess.Popen(args=cmdline, try_start = lambda: subprocess.Popen(args=cmdline,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
stdout=self._tempfile, stdout=self._tempfile,
@ -307,7 +307,7 @@ class Job(object):
self._state = _SUCCESS self._state = _SUCCESS
measurement = '' measurement = ''
if measure_cpu_costs: if measure_cpu_costs:
m = re.search(r'real ([0-9.]+)\nuser ([0-9.]+)\nsys ([0-9.]+)', stdout()) m = re.search(r'real\s+([0-9.]+)\nuser\s+([0-9.]+)\nsys\s+([0-9.]+)', stdout())
real = float(m.group(1)) real = float(m.group(1))
user = float(m.group(2)) user = float(m.group(2))
sys = float(m.group(3)) sys = float(m.group(3))

@ -340,7 +340,8 @@ class CLanguage(object):
if self.platform == 'windows': if self.platform == 'windows':
# don't build tools on windows just yet # don't build tools on windows just yet
return ['buildtests_%s' % self.make_target] return ['buildtests_%s' % self.make_target]
return ['buildtests_%s' % self.make_target, 'tools_%s' % self.make_target] return ['buildtests_%s' % self.make_target, 'tools_%s' % self.make_target,
'check_epollexclusive']
def make_options(self): def make_options(self):
return self._make_options; return self._make_options;

@ -1 +1 @@
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ImportGroup Label="PropertySheets" /> <PropertyGroup Label="UserMacros" /> <PropertyGroup /> <ItemDefinitionGroup> <ClCompile> <DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> </ClCompile> <Link> <AdditionalDependencies>libprotoc.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)\..\third_party\protobuf\cmake\build\solution\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemGroup /> </Project> <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ImportGroup Label="PropertySheets" /> <PropertyGroup Label="UserMacros" /> <PropertyGroup /> <ItemDefinitionGroup> <ClCompile> <DisableSpecificWarnings>4244;4267;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings> </ClCompile> <Link> <AdditionalDependencies>libprotoc.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)\..\third_party\protobuf\cmake\build\solution\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemGroup /> </Project>
Loading…
Cancel
Save