diff --git a/build.yaml b/build.yaml index a8832294e42..5260fe6721f 100644 --- a/build.yaml +++ b/build.yaml @@ -4581,6 +4581,7 @@ node_modules: - src/node/src/client.js - src/node/src/common.js - src/node/src/credentials.js + - src/node/src/constants.js - src/node/src/grpc_extension.js - src/node/src/metadata.js - src/node/src/server.js diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc index e193e82179a..c444ad0b7b1 100644 --- a/src/node/ext/node_grpc.cc +++ b/src/node/ext/node_grpc.cc @@ -85,98 +85,6 @@ logger_state grpc_logger_state; static char *pem_root_certs = NULL; -void InitStatusConstants(Local exports) { - Nan::HandleScope scope; - Local status = Nan::New(); - Nan::Set(exports, Nan::New("status").ToLocalChecked(), status); - Local OK(Nan::New(GRPC_STATUS_OK)); - Nan::Set(status, Nan::New("OK").ToLocalChecked(), OK); - Local CANCELLED(Nan::New(GRPC_STATUS_CANCELLED)); - Nan::Set(status, Nan::New("CANCELLED").ToLocalChecked(), CANCELLED); - Local UNKNOWN(Nan::New(GRPC_STATUS_UNKNOWN)); - Nan::Set(status, Nan::New("UNKNOWN").ToLocalChecked(), UNKNOWN); - Local INVALID_ARGUMENT( - Nan::New(GRPC_STATUS_INVALID_ARGUMENT)); - Nan::Set(status, Nan::New("INVALID_ARGUMENT").ToLocalChecked(), - INVALID_ARGUMENT); - Local DEADLINE_EXCEEDED( - Nan::New(GRPC_STATUS_DEADLINE_EXCEEDED)); - Nan::Set(status, Nan::New("DEADLINE_EXCEEDED").ToLocalChecked(), - DEADLINE_EXCEEDED); - Local NOT_FOUND(Nan::New(GRPC_STATUS_NOT_FOUND)); - Nan::Set(status, Nan::New("NOT_FOUND").ToLocalChecked(), NOT_FOUND); - Local ALREADY_EXISTS( - Nan::New(GRPC_STATUS_ALREADY_EXISTS)); - Nan::Set(status, Nan::New("ALREADY_EXISTS").ToLocalChecked(), ALREADY_EXISTS); - Local PERMISSION_DENIED( - Nan::New(GRPC_STATUS_PERMISSION_DENIED)); - Nan::Set(status, Nan::New("PERMISSION_DENIED").ToLocalChecked(), - PERMISSION_DENIED); - Local UNAUTHENTICATED( - Nan::New(GRPC_STATUS_UNAUTHENTICATED)); - Nan::Set(status, Nan::New("UNAUTHENTICATED").ToLocalChecked(), - UNAUTHENTICATED); - Local RESOURCE_EXHAUSTED( - Nan::New(GRPC_STATUS_RESOURCE_EXHAUSTED)); - Nan::Set(status, Nan::New("RESOURCE_EXHAUSTED").ToLocalChecked(), - RESOURCE_EXHAUSTED); - Local FAILED_PRECONDITION( - Nan::New(GRPC_STATUS_FAILED_PRECONDITION)); - Nan::Set(status, Nan::New("FAILED_PRECONDITION").ToLocalChecked(), - FAILED_PRECONDITION); - Local ABORTED(Nan::New(GRPC_STATUS_ABORTED)); - Nan::Set(status, Nan::New("ABORTED").ToLocalChecked(), ABORTED); - Local OUT_OF_RANGE( - Nan::New(GRPC_STATUS_OUT_OF_RANGE)); - Nan::Set(status, Nan::New("OUT_OF_RANGE").ToLocalChecked(), OUT_OF_RANGE); - Local UNIMPLEMENTED( - Nan::New(GRPC_STATUS_UNIMPLEMENTED)); - Nan::Set(status, Nan::New("UNIMPLEMENTED").ToLocalChecked(), UNIMPLEMENTED); - Local INTERNAL(Nan::New(GRPC_STATUS_INTERNAL)); - Nan::Set(status, Nan::New("INTERNAL").ToLocalChecked(), INTERNAL); - Local UNAVAILABLE(Nan::New(GRPC_STATUS_UNAVAILABLE)); - Nan::Set(status, Nan::New("UNAVAILABLE").ToLocalChecked(), UNAVAILABLE); - Local DATA_LOSS(Nan::New(GRPC_STATUS_DATA_LOSS)); - Nan::Set(status, Nan::New("DATA_LOSS").ToLocalChecked(), DATA_LOSS); -} - -void InitCallErrorConstants(Local exports) { - Nan::HandleScope scope; - Local call_error = Nan::New(); - Nan::Set(exports, Nan::New("callError").ToLocalChecked(), call_error); - Local OK(Nan::New(GRPC_CALL_OK)); - Nan::Set(call_error, Nan::New("OK").ToLocalChecked(), OK); - Local CALL_ERROR(Nan::New(GRPC_CALL_ERROR)); - Nan::Set(call_error, Nan::New("ERROR").ToLocalChecked(), CALL_ERROR); - Local NOT_ON_SERVER( - Nan::New(GRPC_CALL_ERROR_NOT_ON_SERVER)); - Nan::Set(call_error, Nan::New("NOT_ON_SERVER").ToLocalChecked(), - NOT_ON_SERVER); - Local NOT_ON_CLIENT( - Nan::New(GRPC_CALL_ERROR_NOT_ON_CLIENT)); - Nan::Set(call_error, Nan::New("NOT_ON_CLIENT").ToLocalChecked(), - NOT_ON_CLIENT); - Local ALREADY_INVOKED( - Nan::New(GRPC_CALL_ERROR_ALREADY_INVOKED)); - Nan::Set(call_error, Nan::New("ALREADY_INVOKED").ToLocalChecked(), - ALREADY_INVOKED); - Local NOT_INVOKED( - Nan::New(GRPC_CALL_ERROR_NOT_INVOKED)); - Nan::Set(call_error, Nan::New("NOT_INVOKED").ToLocalChecked(), NOT_INVOKED); - Local ALREADY_FINISHED( - Nan::New(GRPC_CALL_ERROR_ALREADY_FINISHED)); - Nan::Set(call_error, Nan::New("ALREADY_FINISHED").ToLocalChecked(), - ALREADY_FINISHED); - Local TOO_MANY_OPERATIONS( - Nan::New(GRPC_CALL_ERROR_TOO_MANY_OPERATIONS)); - Nan::Set(call_error, Nan::New("TOO_MANY_OPERATIONS").ToLocalChecked(), - TOO_MANY_OPERATIONS); - Local INVALID_FLAGS( - Nan::New(GRPC_CALL_ERROR_INVALID_FLAGS)); - Nan::Set(call_error, Nan::New("INVALID_FLAGS").ToLocalChecked(), - INVALID_FLAGS); -} - void InitOpTypeConstants(Local exports) { Nan::HandleScope scope; Local op_type = Nan::New(); @@ -211,27 +119,6 @@ void InitOpTypeConstants(Local exports) { RECV_CLOSE_ON_SERVER); } -void InitPropagateConstants(Local exports) { - Nan::HandleScope scope; - Local propagate = Nan::New(); - Nan::Set(exports, Nan::New("propagate").ToLocalChecked(), propagate); - Local DEADLINE(Nan::New(GRPC_PROPAGATE_DEADLINE)); - Nan::Set(propagate, Nan::New("DEADLINE").ToLocalChecked(), DEADLINE); - Local CENSUS_STATS_CONTEXT( - Nan::New(GRPC_PROPAGATE_CENSUS_STATS_CONTEXT)); - Nan::Set(propagate, Nan::New("CENSUS_STATS_CONTEXT").ToLocalChecked(), - CENSUS_STATS_CONTEXT); - Local CENSUS_TRACING_CONTEXT( - Nan::New(GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT)); - Nan::Set(propagate, Nan::New("CENSUS_TRACING_CONTEXT").ToLocalChecked(), - CENSUS_TRACING_CONTEXT); - Local CANCELLATION( - Nan::New(GRPC_PROPAGATE_CANCELLATION)); - Nan::Set(propagate, Nan::New("CANCELLATION").ToLocalChecked(), CANCELLATION); - Local DEFAULTS(Nan::New(GRPC_PROPAGATE_DEFAULTS)); - Nan::Set(propagate, Nan::New("DEFAULTS").ToLocalChecked(), DEFAULTS); -} - void InitConnectivityStateConstants(Local exports) { Nan::HandleScope scope; Local channel_state = Nan::New(); @@ -252,28 +139,6 @@ void InitConnectivityStateConstants(Local exports) { FATAL_FAILURE); } -void InitWriteFlags(Local exports) { - Nan::HandleScope scope; - Local write_flags = Nan::New(); - Nan::Set(exports, Nan::New("writeFlags").ToLocalChecked(), write_flags); - Local BUFFER_HINT(Nan::New(GRPC_WRITE_BUFFER_HINT)); - Nan::Set(write_flags, Nan::New("BUFFER_HINT").ToLocalChecked(), BUFFER_HINT); - Local NO_COMPRESS(Nan::New(GRPC_WRITE_NO_COMPRESS)); - Nan::Set(write_flags, Nan::New("NO_COMPRESS").ToLocalChecked(), NO_COMPRESS); -} - -void InitLogConstants(Local exports) { - Nan::HandleScope scope; - Local log_verbosity = Nan::New(); - Nan::Set(exports, Nan::New("logVerbosity").ToLocalChecked(), log_verbosity); - Local LOG_DEBUG(Nan::New(GPR_LOG_SEVERITY_DEBUG)); - Nan::Set(log_verbosity, Nan::New("DEBUG").ToLocalChecked(), LOG_DEBUG); - Local LOG_INFO(Nan::New(GPR_LOG_SEVERITY_INFO)); - Nan::Set(log_verbosity, Nan::New("INFO").ToLocalChecked(), LOG_INFO); - Local LOG_ERROR(Nan::New(GPR_LOG_SEVERITY_ERROR)); - Nan::Set(log_verbosity, Nan::New("ERROR").ToLocalChecked(), LOG_ERROR); -} - NAN_METHOD(MetadataKeyIsLegal) { if (!info[0]->IsString()) { return Nan::ThrowTypeError("headerKeyIsLegal's argument must be a string"); @@ -421,13 +286,8 @@ void init(Local exports) { grpc_set_ssl_roots_override_callback(get_ssl_roots_override); init_logger(); - InitStatusConstants(exports); - InitCallErrorConstants(exports); InitOpTypeConstants(exports); - InitPropagateConstants(exports); InitConnectivityStateConstants(exports); - InitWriteFlags(exports); - InitLogConstants(exports); grpc_pollset_work_run_loop = 0; diff --git a/src/node/index.js b/src/node/index.js index 76ab1744b00..0da3440eb77 100644 --- a/src/node/index.js +++ b/src/node/index.js @@ -59,6 +59,8 @@ var grpc = require('./src/grpc_extension'); var protobuf_js_5_common = require('./src/protobuf_js_5_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')); /** @@ -212,27 +214,27 @@ exports.Metadata = Metadata; /** * Status name to code number mapping */ -exports.status = grpc.status; +exports.status = constants.status; /** * Propagate flag name to number mapping */ -exports.propagate = grpc.propagate; +exports.propagate = constants.propagate; /** * Call error name to code number mapping */ -exports.callError = grpc.callError; +exports.callError = constants.callError; /** * Write flag name to code number mapping */ -exports.writeFlags = grpc.writeFlags; +exports.writeFlags = constants.writeFlags; /** * Log verbosity setting name to code number mapping */ -exports.logVerbosity = grpc.logVerbosity; +exports.logVerbosity = constants.logVerbosity; /** * Credentials factories diff --git a/src/node/jsdoc_conf.json b/src/node/jsdoc_conf.json index c3a0174f0e3..2d967753c1e 100644 --- a/src/node/jsdoc_conf.json +++ b/src/node/jsdoc_conf.json @@ -11,7 +11,7 @@ "package": "package.json", "readme": "src/node/README.md" }, - "plugins": [], + "plugins": ["plugins/markdown"], "templates": { "cleverLinks": false, "monospaceLinks": false, diff --git a/src/node/src/client.js b/src/node/src/client.js index 43502da6af6..16fe06a54d2 100644 --- a/src/node/src/client.js +++ b/src/node/src/client.js @@ -58,6 +58,8 @@ var common = require('./common'); var Metadata = require('./metadata'); +var constants = require('./constants'); + var EventEmitter = require('events').EventEmitter; 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 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 */ - this.call.cancelWithStatus(grpc.status.INTERNAL, 'Serialization failure'); + this.call.cancelWithStatus(constants.status.INTERNAL, + 'Serialization failure'); callback(e); } if (_.isFinite(encoding)) { @@ -185,9 +188,9 @@ function ClientReadableStream(call, deserialize) { function _readsDone(status) { /* jshint validthis: true */ 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.finished = true; @@ -218,12 +221,12 @@ function _emitStatusIfDone() { /* jshint validthis: true */ var 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; } else { status = this.received_status; } - if (status.code === grpc.status.OK) { + if (status.code === constants.status.OK) { this.push(null); } else { var error = new Error(status.details); @@ -262,7 +265,7 @@ function _read(size) { try { deserialized = self.deserialize(data); } catch (e) { - self._readsDone({code: grpc.status.INTERNAL, + self._readsDone({code: constants.status.INTERNAL, details: 'Failed to parse server response'}); return; } @@ -510,7 +513,7 @@ Client.prototype.makeUnaryRequest = function(method, serialize, deserialize, var deserialized; emitter.emit('metadata', Metadata._fromCoreRepresentation( response.metadata)); - if (status.code === grpc.status.OK) { + if (status.code === constants.status.OK) { if (err) { // Got a batch error, but OK status. Something went wrong args.callback(err); @@ -522,13 +525,13 @@ Client.prototype.makeUnaryRequest = function(method, serialize, deserialize, /* Change status to indicate bad server response. This will result * in passing an error to the callback */ status = { - code: grpc.status.INTERNAL, + code: constants.status.INTERNAL, details: 'Failed to parse server response' }; } } } - if (status.code !== grpc.status.OK) { + if (status.code !== constants.status.OK) { error = new Error(status.details); error.code = status.code; error.metadata = status.metadata; @@ -593,7 +596,7 @@ Client.prototype.makeClientStreamRequest = function(method, serialize, var status = response.status; var error; var deserialized; - if (status.code === grpc.status.OK) { + if (status.code === constants.status.OK) { if (err) { // Got a batch error, but OK status. Something went wrong args.callback(err); @@ -605,13 +608,13 @@ Client.prototype.makeClientStreamRequest = function(method, serialize, /* Change status to indicate bad server response. This will result * in passing an error to the callback */ status = { - code: grpc.status.INTERNAL, + code: constants.status.INTERNAL, 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.code = status.code; error.metadata = status.metadata; @@ -921,7 +924,7 @@ exports.waitForClientReady = function(client, deadline, callback) { /** * Map of status code names to status codes */ -exports.status = grpc.status; +exports.status = constants.status; /** * See docs for client.callError diff --git a/src/node/src/constants.js b/src/node/src/constants.js new file mode 100644 index 00000000000..528dab120e0 --- /dev/null +++ b/src/node/src/constants.js @@ -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 +}; diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js index 51ff1da01ec..b1e86bbd090 100644 --- a/src/node/src/credentials.js +++ b/src/node/src/credentials.js @@ -71,6 +71,8 @@ var Metadata = require('./metadata.js'); var common = require('./common.js'); +var constants = require('./constants'); + var _ = require('lodash'); /** @@ -97,14 +99,14 @@ exports.createFromMetadataGenerator = function(metadata_generator) { return CallCredentials.createFromPlugin(function(service_url, cb_data, callback) { metadata_generator({service_url: service_url}, function(error, metadata) { - var code = grpc.status.OK; + var code = constants.status.OK; var message = ''; if (error) { message = error.message; if (error.hasOwnProperty('code') && _.isFinite(error.code)) { code = error.code; } else { - code = grpc.status.UNAUTHENTICATED; + code = constants.status.UNAUTHENTICATED; } if (!metadata) { metadata = new Metadata(); @@ -125,7 +127,7 @@ exports.createFromGoogleCredential = function(google_credential) { var service_url = auth_context.service_url; google_credential.getRequestMetadata(service_url, function(err, header) { if (err) { - common.log(grpc.logVerbosity.INFO, 'Auth error:' + err); + common.log(constants.logVerbosity.INFO, 'Auth error:' + err); callback(err); return; } diff --git a/src/node/src/server.js b/src/node/src/server.js index 3450abed08f..08417a74c1e 100644 --- a/src/node/src/server.js +++ b/src/node/src/server.js @@ -57,6 +57,8 @@ var common = require('./common'); var Metadata = require('./metadata'); +var constants = require('./constants'); + var stream = require('stream'); var Readable = stream.Readable; @@ -75,7 +77,7 @@ var EventEmitter = require('events').EventEmitter; function handleError(call, error) { var statusMetadata = new Metadata(); var status = { - code: grpc.status.UNKNOWN, + code: constants.status.UNKNOWN, details: 'Unknown Error' }; if (error.hasOwnProperty('message')) { @@ -115,7 +117,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) { var end_batch = {}; var statusMetadata = new Metadata(); var status = { - code: grpc.status.OK, + code: constants.status.OK, details: 'OK' }; if (metadata) { @@ -125,7 +127,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) { try { message = serialize(value); } catch (e) { - e.code = grpc.status.INTERNAL; + e.code = constants.status.INTERNAL; handleError(call, e); return; } @@ -151,7 +153,7 @@ function sendUnaryResponse(call, value, serialize, metadata, flags) { function setUpWritable(stream, serialize) { stream.finished = false; stream.status = { - code : grpc.status.OK, + code : constants.status.OK, details : 'OK', metadata : new Metadata() }; @@ -178,7 +180,7 @@ function setUpWritable(stream, serialize) { * @param {Error} err The error object */ function setStatus(err) { - var code = grpc.status.UNKNOWN; + var code = constants.status.UNKNOWN; var details = 'Unknown Error'; var metadata = new Metadata(); if (err.hasOwnProperty('message')) { @@ -284,7 +286,7 @@ function _write(chunk, encoding, callback) { try { message = this.serialize(chunk); } catch (e) { - e.code = grpc.status.INTERNAL; + e.code = constants.status.INTERNAL; callback(e); return; } @@ -353,7 +355,7 @@ function _read(size) { try { deserialized = self.deserialize(data); } catch (e) { - e.code = grpc.status.INTERNAL; + e.code = constants.status.INTERNAL; self.emit('error', e); return; } @@ -489,7 +491,7 @@ function handleUnary(call, handler, metadata) { try { emitter.request = handler.deserialize(result.read); } catch (e) { - e.code = grpc.status.INTERNAL; + e.code = constants.status.INTERNAL; handleError(call, e); return; } @@ -530,7 +532,7 @@ function handleServerStreaming(call, handler, metadata) { try { stream.request = handler.deserialize(result.read); } catch (e) { - e.code = grpc.status.INTERNAL; + e.code = constants.status.INTERNAL; stream.emit('error', e); return; } @@ -636,7 +638,7 @@ function Server(options) { batch[grpc.opType.SEND_INITIAL_METADATA] = (new Metadata())._getCoreRepresentation(); batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { - code: grpc.status.UNIMPLEMENTED, + code: constants.status.UNIMPLEMENTED, details: '', metadata: {} }; @@ -699,7 +701,7 @@ Server.prototype.register = function(name, handler, serialize, deserialize, }; var unimplementedStatusResponse = { - code: grpc.status.UNIMPLEMENTED, + code: constants.status.UNIMPLEMENTED, 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 naming style */ if (implementation[attrs.originalName] === undefined) { - common.log(grpc.logVerbosity.ERROR, 'Method handler ' + name + ' for ' + - attrs.path + ' expected but not provided'); + common.log(constants.logVerbosity.ERROR, 'Method handler ' + name + + ' for ' + attrs.path + ' expected but not provided'); impl = defaultHandler[method_type]; } else { impl = _.bind(implementation[attrs.originalName], implementation); @@ -790,7 +792,7 @@ Server.prototype.addProtoService = function(service, implementation) { var options; var protobuf_js_5_common = require('./protobuf_js_5_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'); if (protobuf_js_5_common.isProbablyProtobufJs5(service)) { options = _.defaults(service.grpc_options, common.defaultGrpcOptions); diff --git a/src/node/test/call_test.js b/src/node/test/call_test.js index eb268603ead..f25268e8e6d 100644 --- a/src/node/test/call_test.js +++ b/src/node/test/call_test.js @@ -35,6 +35,7 @@ var assert = require('assert'); var grpc = require('../src/grpc_extension'); +var constants = require('../src/constants'); /** * Helper function to return an absolute deadline given a relative timeout in @@ -120,7 +121,8 @@ describe('call', function() { var batch = {}; batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true; 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(); }); }); diff --git a/src/node/test/constant_test.js b/src/node/test/constant_test.js deleted file mode 100644 index 414b1ac9c01..00000000000 --- a/src/node/test/constant_test.js +++ /dev/null @@ -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.} - */ -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.} - */ -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.} - */ -var propagateFlagNames = [ - 'DEADLINE', - 'CENSUS_STATS_CONTEXT', - 'CENSUS_TRACING_CONTEXT', - 'CANCELLATION', - 'DEFAULTS' -]; -/* - * List of all connectivity state names - * @const - * @type {Array.} - */ -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]); - } - }); -}); diff --git a/src/node/test/end_to_end_test.js b/src/node/test/end_to_end_test.js index f127a41de9f..af455e2716d 100644 --- a/src/node/test/end_to_end_test.js +++ b/src/node/test/end_to_end_test.js @@ -35,6 +35,7 @@ var assert = require('assert'); var grpc = require('../src/grpc_extension'); +var constants = require('../src/constants'); /** * This is used for testing functions with multiple asynchronous calls that @@ -90,7 +91,7 @@ describe('end-to-end', function() { client_close: true, metadata: {}, status: { - code: grpc.status.OK, + code: constants.status.OK, details: status_text, metadata: {} } @@ -107,7 +108,7 @@ describe('end-to-end', function() { server_batch[grpc.opType.SEND_INITIAL_METADATA] = {}; server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { metadata: {}, - code: grpc.status.OK, + code: constants.status.OK, details: status_text }; server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; @@ -141,7 +142,7 @@ describe('end-to-end', function() { send_metadata: true, client_close: true, metadata: {server_key: ['server_value']}, - status: {code: grpc.status.OK, + status: {code: constants.status.OK, details: status_text, metadata: {}} }); @@ -161,7 +162,7 @@ describe('end-to-end', function() { }; server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { metadata: {}, - code: grpc.status.OK, + code: constants.status.OK, details: status_text }; server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; @@ -198,7 +199,7 @@ describe('end-to-end', function() { assert.deepEqual(response.metadata, {}); assert(response.send_message); 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, metadata: {}}); 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_STATUS_FROM_SERVER] = { metadata: {}, - code: grpc.status.OK, + code: constants.status.OK, details: status_text }; response_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; @@ -260,7 +261,7 @@ describe('end-to-end', function() { send_message: true, client_close: true, status: { - code: grpc.status.OK, + code: constants.status.OK, details: status_text, metadata: {} } @@ -290,7 +291,7 @@ describe('end-to-end', function() { end_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { metadata: {}, - code: grpc.status.OK, + code: constants.status.OK, details: status_text }; server_call.startBatch(end_batch, function(err, response) { diff --git a/templates/vsprojects/protoc.props.template b/templates/vsprojects/protoc.props.template index 2c3844a9a4e..65771fc5a3a 100644 --- a/templates/vsprojects/protoc.props.template +++ b/templates/vsprojects/protoc.props.template @@ -5,7 +5,7 @@ - 4244;4267;%(DisableSpecificWarnings) + 4244;4267;4800;%(DisableSpecificWarnings) libprotoc.lib;%(AdditionalDependencies) diff --git a/tools/gce/create_linux_worker.sh b/tools/gce/create_linux_worker.sh index 322a592c073..b934f22a673 100755 --- a/tools/gce/create_linux_worker.sh +++ b/tools/gce/create_linux_worker.sh @@ -45,7 +45,8 @@ gcloud compute instances create $INSTANCE_NAME \ --machine-type n1-standard-16 \ --image=ubuntu-1510 \ --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.' sleep 60 diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 48f24ab6230..df5474e1119 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -41350,6 +41350,56 @@ "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": [ "--scenarios_json", @@ -42908,6 +42958,82 @@ "shortname": "json_run_localhost:cpp_protobuf_async_streaming_from_server_qps_unconstrained_insecure", "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": [ "--scenarios_json", diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index 8ed675ecc3c..c2ffd67dbf4 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -112,6 +112,7 @@ def _ping_pong_scenario(name, rpc_type, categories=DEFAULT_CATEGORIES, channels=None, outstanding=None, + num_clients=None, resource_quota_size=None, messages_per_stream=None, excluded_poll_engines=[]): @@ -158,7 +159,7 @@ def _ping_pong_scenario(name, rpc_type, wide = channels if channels is not None else 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']['client_channels'] = wide scenario['client_config']['async_client_threads'] = 0 @@ -196,6 +197,24 @@ class CXXLanguage: def scenarios(self): # 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]: secstr = 'secure' if secure else 'insecure' smoketest_categories = ([SMOKETEST] if secure else []) + [SCALABLE] diff --git a/tools/run_tests/python_utils/jobset.py b/tools/run_tests/python_utils/jobset.py index 4e97128d467..c1b1c88f550 100755 --- a/tools/run_tests/python_utils/jobset.py +++ b/tools/run_tests/python_utils/jobset.py @@ -255,7 +255,7 @@ class Job(object): self._start = time.time() cmdline = self._spec.cmdline if measure_cpu_costs: - cmdline = ['time', '--portability'] + cmdline + cmdline = ['time', '-p'] + cmdline try_start = lambda: subprocess.Popen(args=cmdline, stderr=subprocess.STDOUT, stdout=self._tempfile, @@ -307,7 +307,7 @@ class Job(object): self._state = _SUCCESS measurement = '' 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)) user = float(m.group(2)) sys = float(m.group(3)) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 83a83948a57..196e26e1b60 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -340,7 +340,8 @@ class CLanguage(object): if self.platform == 'windows': # don't build tools on windows just yet 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): return self._make_options; diff --git a/vsprojects/protoc.props b/vsprojects/protoc.props index 87fff8f1288..6c842c282ee 100644 --- a/vsprojects/protoc.props +++ b/vsprojects/protoc.props @@ -1 +1 @@ - 4244;4267;%(DisableSpecificWarnings) libprotoc.lib;%(AdditionalDependencies) $(SolutionDir)\..\third_party\protobuf\cmake\build\solution\$(Configuration);%(AdditionalLibraryDirectories) \ No newline at end of file + 4244;4267;4800;%(DisableSpecificWarnings) libprotoc.lib;%(AdditionalDependencies) $(SolutionDir)\..\third_party\protobuf\cmake\build\solution\$(Configuration);%(AdditionalLibraryDirectories) \ No newline at end of file