diff --git a/.gitignore b/.gitignore index 5202b53ad25..3cae07ed12f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ bins +coverage deps +*.gcno +gens libs objs *.pyc - diff --git a/.gitmodules b/.gitmodules index 9a287d9ee2d..97b7197be32 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,10 +9,6 @@ path = third_party/protobuf url = https://github.com/google/protobuf.git branch = v3.0.0-alpha-1 -[submodule "third_party/libevent"] - path = third_party/libevent - url = https://github.com/libevent/libevent.git - branch = patches-2.0 [submodule "third_party/gflags"] path = third_party/gflags url = https://code.google.com/p/gflags diff --git a/INSTALL b/INSTALL index 20e27c1b805..a9b0b58aa6e 100644 --- a/INSTALL +++ b/INSTALL @@ -12,8 +12,7 @@ Note that the Makefile makes it much easier for you to compile from sources if you were to clone recursively our git repository. -grpc core currently depends on zlib and OpenSSL 1.0.2beta3, and also requires -libevent2 for the Linux port. +grpc core currently depends on zlib and OpenSSL 1.0.2beta3. grpc++'s tests depends on protobuf 3.0.0, gtests and gflags. @@ -46,7 +45,7 @@ and let the Makefile build them itself. You may also install the dependencies yourself, from the sources, or from your distribution's package manager. -The development packages needed for grpc are libevent2 under Linux, and zlib. +The only development package needed for grpc is zlib. The development packages needed for grpc++'s tests are gtests, and gflags. To the best of our knowledge, no distribution has an OpenSSL package that diff --git a/Makefile b/Makefile index a102746f4f1..76e6407b880 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,15 @@ CPPFLAGS_msan = -O1 -fsanitize=memory -fno-omit-frame-pointer LDFLAGS_msan = -fsanitize=memory DEFINES_msan = NDEBUG +VALID_CONFIG_gcov = 1 +CC_gcov = gcc +CXX_gcov = g++ +LD_gcov = gcc +LDXX_gcov = g++ +CPPFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage +LDFLAGS_gcov = -fprofile-arcs -ftest-coverage +DEFINES_gcov = NDEBUG + # General settings. # You may want to change these depending on your system. @@ -487,9 +496,9 @@ shared_cxx: dep_cxx libs/$(CONFIG)/libgrpc++.$(SHARED_EXT) privatelibs: privatelibs_c privatelibs_cxx -privatelibs_c: dep_c libs/$(CONFIG)/libgpr_test_util.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc++_test_util.a libs/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a libs/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a libs/$(CONFIG)/libend2end_test_cancel_after_accept.a libs/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a libs/$(CONFIG)/libend2end_test_cancel_after_invoke.a libs/$(CONFIG)/libend2end_test_cancel_before_invoke.a libs/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_test_disappearing_server.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a libs/$(CONFIG)/libend2end_test_invoke_large_request.a libs/$(CONFIG)/libend2end_test_max_concurrent_streams.a libs/$(CONFIG)/libend2end_test_no_op.a libs/$(CONFIG)/libend2end_test_ping_pong_streaming.a libs/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_simple_delayed_request.a libs/$(CONFIG)/libend2end_test_simple_request.a libs/$(CONFIG)/libend2end_test_thread_stress.a libs/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a libs/$(CONFIG)/libend2end_certs.a +privatelibs_c: dep_c libs/$(CONFIG)/libgpr_test_util.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a libs/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a libs/$(CONFIG)/libend2end_test_cancel_after_accept.a libs/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a libs/$(CONFIG)/libend2end_test_cancel_after_invoke.a libs/$(CONFIG)/libend2end_test_cancel_before_invoke.a libs/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_test_disappearing_server.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a libs/$(CONFIG)/libend2end_test_invoke_large_request.a libs/$(CONFIG)/libend2end_test_max_concurrent_streams.a libs/$(CONFIG)/libend2end_test_no_op.a libs/$(CONFIG)/libend2end_test_ping_pong_streaming.a libs/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_simple_delayed_request.a libs/$(CONFIG)/libend2end_test_simple_request.a libs/$(CONFIG)/libend2end_test_thread_stress.a libs/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a libs/$(CONFIG)/libend2end_certs.a -privatelibs_cxx: dep_cxx libs/$(CONFIG)/libgpr_test_util.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc++_test_util.a libs/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a libs/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a libs/$(CONFIG)/libend2end_test_cancel_after_accept.a libs/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a libs/$(CONFIG)/libend2end_test_cancel_after_invoke.a libs/$(CONFIG)/libend2end_test_cancel_before_invoke.a libs/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_test_disappearing_server.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a libs/$(CONFIG)/libend2end_test_invoke_large_request.a libs/$(CONFIG)/libend2end_test_max_concurrent_streams.a libs/$(CONFIG)/libend2end_test_no_op.a libs/$(CONFIG)/libend2end_test_ping_pong_streaming.a libs/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_simple_delayed_request.a libs/$(CONFIG)/libend2end_test_simple_request.a libs/$(CONFIG)/libend2end_test_thread_stress.a libs/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a libs/$(CONFIG)/libend2end_certs.a +privatelibs_cxx: dep_cxx libs/$(CONFIG)/libgrpc++_test_util.a buildtests: buildtests_c buildtests_cxx diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h index 9c999b9c811..05a5bbe1bc9 100644 --- a/include/grpc/support/port_platform.h +++ b/include/grpc/support/port_platform.h @@ -45,15 +45,16 @@ #if defined(_WIN64) || defined(WIN64) #define GPR_WIN32 1 #define GPR_ARCH_64 1 +#define GPR_GETPID_IN_PROCESS_H 1 #elif defined(_WIN32) || defined(WIN32) #define GPR_ARCH_32 1 #define GPR_WIN32 1 +#define GPR_GETPID_IN_PROCESS_H 1 #elif defined(ANDROID) || defined(__ANDROID__) #define GPR_ANDROID 1 #define GPR_ARCH_32 1 #define GPR_CPU_LINUX 1 #define GPR_GCC_SYNC 1 -#define GPR_LIBEVENT 1 #define GPR_POSIX_MULTIPOLL_WITH_POLL 1 #define GPR_POSIX_SOCKET 1 #define GPR_POSIX_SOCKETADDR 1 @@ -61,10 +62,10 @@ #define GPR_POSIX_STRING 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_GETPID_IN_UNISTD_H 1 #elif defined(__linux__) #define GPR_CPU_LINUX 1 #define GPR_GCC_ATOMIC 1 -#define GPR_LIBEVENT 1 #define GPR_LINUX 1 #define GPR_POSIX_MULTIPOLL_WITH_POLL 1 #define GPR_POSIX_SOCKET 1 @@ -72,6 +73,7 @@ #define GPR_POSIX_STRING 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ @@ -80,7 +82,6 @@ #elif defined(__APPLE__) #define GPR_CPU_POSIX 1 #define GPR_GCC_ATOMIC 1 -#define GPR_LIBEVENT 1 #define GPR_POSIX_LOG 1 #define GPR_POSIX_MULTIPOLL_WITH_POLL 1 #define GPR_POSIX_SOCKET 1 @@ -89,6 +90,7 @@ #define GPR_POSIX_STRING 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 #else /* _LP64 */ diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c index 0420570a3ec..55a38b136d0 100644 --- a/src/core/support/log_posix.c +++ b/src/core/support/log_posix.c @@ -31,21 +31,27 @@ * */ -#define _POSIX_SOURCE + +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L +#endif + #define _GNU_SOURCE #include #if defined(GPR_POSIX_LOG) +#include #include #include #include #include #include +#include #include #include -static long gettid() { return pthread_self(); } +static gpr_intptr gettid() { return (gpr_intptr)pthread_self(); } void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format, ...) { @@ -55,7 +61,7 @@ void gpr_log(const char *file, int line, gpr_log_severity severity, int ret; va_list args; va_start(args, format); - ret = vsnprintf(buf, format, args); + ret = vsnprintf(buf, sizeof(buf), format, args); va_end(args); if (ret < 0) { message = NULL; @@ -64,7 +70,7 @@ void gpr_log(const char *file, int line, gpr_log_severity severity, } else { message = allocated = gpr_malloc(ret + 1); va_start(args, format); - vsnprintf(message, format, args); + vsnprintf(message, ret, format, args); va_end(args); } gpr_log_message(file, line, severity, message); @@ -91,7 +97,7 @@ void gpr_default_log(gpr_log_func_args *args) { strcpy(time_buffer, "error:strftime"); } - fprintf(stderr, "%s%s.%09d %7ld %s:%d] %s\n", + fprintf(stderr, "%s%s.%09d %7tu %s:%d] %s\n", gpr_log_severity_string(args->severity), time_buffer, (int)(now.tv_nsec), gettid(), display_file, args->line, args->message); diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c index ae5f23a90dc..dc8c1d0785a 100644 --- a/src/core/support/log_win32.c +++ b/src/core/support/log_win32.c @@ -36,12 +36,13 @@ #ifdef GPR_WIN32 #include +#include #include #include void gpr_log(const char *file, int line, gpr_log_severity severity, - const char *message) { - const char *message = NULL; + const char *format, ...) { + char *message = NULL; va_list args; int ret; @@ -53,7 +54,7 @@ void gpr_log(const char *file, int line, gpr_log_severity severity, message = NULL; } else { /* Allocate a new buffer, with space for the NUL terminator. */ - strp_buflen = (size_t)ret + 1; + size_t strp_buflen = (size_t)ret + 1; message = gpr_malloc(strp_buflen); /* Print to the buffer. */ @@ -73,7 +74,7 @@ void gpr_log(const char *file, int line, gpr_log_severity severity, /* Simple starter implementation */ void gpr_default_log(gpr_log_func_args *args) { - fprintf(stderr, "%s %s:%d: %s\n", gpr_log_severity_string(severity), + fprintf(stderr, "%s %s:%d: %s\n", gpr_log_severity_string(args->severity), args->file, args->line, args->message); } diff --git a/src/core/support/time.c b/src/core/support/time.c index 0e88c65be0c..97243318fda 100644 --- a/src/core/support/time.c +++ b/src/core/support/time.c @@ -259,7 +259,7 @@ gpr_int32 gpr_time_to_millis(gpr_timespec t) { } else if (t.tv_sec <= -2147483) { /* TODO(ctiller): correct handling here (it's so far in the past do we care?) */ - return -2147483648; + return -2147483647; } else { return t.tv_sec * GPR_MS_PER_SEC + t.tv_nsec / GPR_NS_PER_MS; } diff --git a/src/node/server.js b/src/node/server.js index 7f3e0259a0b..2704c68f17c 100644 --- a/src/node/server.js +++ b/src/node/server.js @@ -73,6 +73,7 @@ function GrpcServerStream(call, options) { * @param {Error} err The error object */ function setStatus(err) { + console.log('Server setting status to', err); var code = grpc.status.INTERNAL; var details = 'Unknown Error'; diff --git a/src/node/surface_client.js b/src/node/surface_client.js index 9c40b0a3a00..acd22089ce1 100644 --- a/src/node/surface_client.js +++ b/src/node/surface_client.js @@ -178,7 +178,7 @@ function makeUnaryRequestFunction(method, serialize, deserialize) { /** * Make a unary request with this method on the given channel with the given * argument, callback, etc. - * @param {client.Channel} channel The channel on which to make the request + * @this {SurfaceClient} Client object. Must have a channel member. * @param {*} argument The argument to the call. Should be serializable with * serialize * @param {function(?Error, value=)} callback The callback to for when the @@ -189,8 +189,8 @@ function makeUnaryRequestFunction(method, serialize, deserialize) { * Defaults to infinite future * @return {EventEmitter} An event emitter for stream related events */ - function makeUnaryRequest(channel, argument, callback, metadata, deadline) { - var stream = client.makeRequest(channel, method, metadata, deadline); + function makeUnaryRequest(argument, callback, metadata, deadline) { + var stream = client.makeRequest(this.channel, method, metadata, deadline); var emitter = new EventEmitter(); forwardEvent(stream, emitter, 'status'); forwardEvent(stream, emitter, 'metadata'); @@ -220,7 +220,7 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) { /** * Make a client stream request with this method on the given channel with the * given callback, etc. - * @param {client.Channel} channel The channel on which to make the request + * @this {SurfaceClient} Client object. Must have a channel member. * @param {function(?Error, value=)} callback The callback to for when the * response is received * @param {array=} metadata Array of metadata key/value pairs to add to the @@ -229,8 +229,8 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) { * Defaults to infinite future * @return {EventEmitter} An event emitter for stream related events */ - function makeClientStreamRequest(channel, callback, metadata, deadline) { - var stream = client.makeRequest(channel, method, metadata, deadline); + function makeClientStreamRequest(callback, metadata, deadline) { + var stream = client.makeRequest(this.channel, method, metadata, deadline); var obj_stream = new ClientWritableObjectStream(stream, serialize, {}); stream.on('data', function forwardData(chunk) { try { @@ -256,7 +256,7 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) { /** * Make a server stream request with this method on the given channel with the * given argument, etc. - * @param {client.Channel} channel The channel on which to make the request + * @this {SurfaceClient} Client object. Must have a channel member. * @param {*} argument The argument to the call. Should be serializable with * serialize * @param {array=} metadata Array of metadata key/value pairs to add to the @@ -265,8 +265,8 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) { * Defaults to infinite future * @return {EventEmitter} An event emitter for stream related events */ - function makeServerStreamRequest(channel, argument, metadata, deadline) { - var stream = client.makeRequest(channel, method, metadata, deadline); + function makeServerStreamRequest(argument, metadata, deadline) { + var stream = client.makeRequest(this.channel, method, metadata, deadline); var obj_stream = new ClientReadableObjectStream(stream, deserialize, {}); stream.write(serialize(argument)); stream.end(); @@ -287,15 +287,15 @@ function makeServerStreamRequestFunction(method, serialize, deserialize) { function makeBidiStreamRequestFunction(method, serialize, deserialize) { /** * Make a bidirectional stream request with this method on the given channel. - * @param {client.Channel} channel The channel on which to make the request + * @this {SurfaceClient} Client object. Must have a channel member. * @param {array=} metadata Array of metadata key/value pairs to add to the * call * @param {(number|Date)=} deadline The deadline for processing this request. * Defaults to infinite future * @return {EventEmitter} An event emitter for stream related events */ - function makeBidiStreamRequest(channel, metadata, deadline) { - var stream = client.makeRequest(channel, method, metadata, deadline); + function makeBidiStreamRequest(metadata, deadline) { + var stream = client.makeRequest(this.channel, method, metadata, deadline); var obj_stream = new ClientBidiObjectStream(stream, serialize, deserialize, @@ -306,29 +306,63 @@ function makeBidiStreamRequestFunction(method, serialize, deserialize) { } /** - * See docs for makeUnaryRequestFunction + * Map with short names for each of the requester maker functions. Used in + * makeClientConstructor */ -exports.makeUnaryRequestFunction = makeUnaryRequestFunction; +var requester_makers = { + unary: makeUnaryRequestFunction, + server_stream: makeServerStreamRequestFunction, + client_stream: makeClientStreamRequestFunction, + bidi: makeBidiStreamRequestFunction +} /** - * See docs for makeClientStreamRequestFunction + * Creates a constructor for clients with a service defined by the methods + * object. The methods object has string keys and values of this form: + * {serialize: function, deserialize: function, client_stream: bool, + * server_stream: bool} + * @param {!Object} methods Method descriptor for each method + * the client should expose + * @param {string} prefix The prefix to prepend to each method name + * @return {function(string, Object)} New client constructor */ -exports.makeClientStreamRequestFunction = makeClientStreamRequestFunction; +function makeClientConstructor(methods, prefix) { + /** + * Create a client with the given methods + * @constructor + * @param {string} address The address of the server to connect to + * @param {Object} options Options to pass to the underlying channel + */ + function SurfaceClient(address, options) { + this.channel = new client.Channel(address, options); + } -/** - * See docs for makeServerStreamRequestFunction - */ -exports.makeServerStreamRequestFunction = makeServerStreamRequestFunction; + _.each(methods, function(method, name) { + var method_type; + if (method.client_stream) { + if (method.server_stream) { + method_type = 'bidi'; + } else { + method_type = 'client_stream'; + } + } else { + if (method.server_stream) { + method_type = 'server_stream'; + } else { + method_type = 'unary'; + } + } + SurfaceClient.prototype[name] = requester_makers[method_type]( + prefix + name, + method.serialize, + method.deserialize); + }); -/** - * See docs for makeBidiStreamRequestFunction - */ -exports.makeBidiStreamRequestFunction = makeBidiStreamRequestFunction; + return SurfaceClient; +} + +exports.makeClientConstructor = makeClientConstructor; -/** - * See docs for client.Channel - */ -exports.Channel = client.Channel; /** * See docs for client.status */ diff --git a/src/node/test/math_client_test.js b/src/node/test/math_client_test.js index f3697aca98e..5b34a228ad3 100644 --- a/src/node/test/math_client_test.js +++ b/src/node/test/math_client_test.js @@ -32,13 +32,14 @@ */ var assert = require('assert'); -var client = require('../surface_client.js'); var ProtoBuf = require('protobufjs'); var port_picker = require('../port_picker'); var builder = ProtoBuf.loadProtoFile(__dirname + '/../examples/math.proto'); var math = builder.build('math'); +var client = require('../surface_client.js'); +var makeConstructor = client.makeClientConstructor; /** * Get a function that deserializes a specific type of protobuf. * @param {function()} cls The constructor of the message type to deserialize @@ -56,78 +57,60 @@ function deserializeCls(cls) { } /** - * Serialize an object to a buffer - * @param {*} arg The object to serialize - * @return {Buffer} The serialized object + * Get a function that serializes objects to a buffer by protobuf class. + * @param {function()} Cls The constructor of the message type to serialize + * @return {function(Cls):Buffer} The serialization function */ -function serialize(arg) { - return new Buffer(arg.encode().toBuffer()); +function serializeCls(Cls) { + /** + * Serialize an object to a Buffer + * @param {Object} arg The object to serialize + * @return {Buffer} The serialized object + */ + return function serialize(arg) { + return new Buffer(new Cls(arg).encode().toBuffer()); + }; } -/** - * Sends a Div request on the channel. - * @param {client.Channel} channel The channel on which to make the request - * @param {DivArg} argument The argument to the call. Should be serializable - * with serialize - * @param {function(?Error, value=)} The callback to for when the response is - * received - * @param {array=} Array of metadata key/value pairs to add to the call - * @param {(number|Date)=} deadline The deadline for processing this request. - * Defaults to infinite future - * @return {EventEmitter} An event emitter for stream related events - */ -var div = client.makeUnaryRequestFunction( - '/Math/Div', - serialize, - deserializeCls(math.DivReply)); - -/** - * Sends a Fib request on the channel. - * @param {client.Channel} channel The channel on which to make the request - * @param {*} argument The argument to the call. Should be serializable with - * serialize - * @param {array=} Array of metadata key/value pairs to add to the call - * @param {(number|Date)=} deadline The deadline for processing this request. - * Defaults to infinite future - * @return {EventEmitter} An event emitter for stream related events - */ -var fib = client.makeServerStreamRequestFunction( - '/Math/Fib', - serialize, - deserializeCls(math.Num)); - -/** - * Sends a Sum request on the channel. - * @param {client.Channel} channel The channel on which to make the request - * @param {function(?Error, value=)} The callback to for when the response is - * received - * @param {array=} Array of metadata key/value pairs to add to the call - * @param {(number|Date)=} deadline The deadline for processing this request. - * Defaults to infinite future - * @return {EventEmitter} An event emitter for stream related events - */ -var sum = client.makeClientStreamRequestFunction( - '/Math/Sum', - serialize, - deserializeCls(math.Num)); - -/** - * Sends a DivMany request on the channel. - * @param {client.Channel} channel The channel on which to make the request - * @param {array=} Array of metadata key/value pairs to add to the call - * @param {(number|Date)=} deadline The deadline for processing this request. - * Defaults to infinite future - * @return {EventEmitter} An event emitter for stream related events - */ -var divMany = client.makeBidiStreamRequestFunction( - '/Math/DivMany', - serialize, - deserializeCls(math.DivReply)); +/* This function call creates a client constructor for clients that expose the + * four specified methods. This specifies how to serialize messages that the + * client sends and deserialize messages that the server sends, and whether the + * client or the server will send a stream of messages, for each method. This + * also specifies a prefix that will be added to method names when sending them + * on the wire. This function call and all of the preceding code in this file + * are intended to approximate what the generated code will look like for the + * math client */ +var MathClient = makeConstructor({ + Div: { + serialize: serializeCls(math.DivArgs), + deserialize: deserializeCls(math.DivReply), + client_stream: false, + server_stream: false + }, + Fib: { + serialize: serializeCls(math.FibArgs), + deserialize: deserializeCls(math.Num), + client_stream: false, + server_stream: true + }, + Sum: { + serialize: serializeCls(math.Num), + deserialize: deserializeCls(math.Num), + client_stream: true, + server_stream: false + }, + DivMany: { + serialize: serializeCls(math.DivArgs), + deserialize: deserializeCls(math.DivReply), + client_stream: true, + server_stream: true + } +}, '/Math/'); /** * Channel to use to make requests to a running server. */ -var channel; +var math_client; /** * Server to test against @@ -139,7 +122,7 @@ describe('Math client', function() { before(function(done) { port_picker.nextAvailablePort(function(port) { server.bind(port).listen(); - channel = new client.Channel(port); + math_client = new MathClient(port); done(); }); }); @@ -147,11 +130,11 @@ describe('Math client', function() { server.shutdown(); }); it('should handle a single request', function(done) { - var arg = new math.DivArgs({dividend: 7, divisor: 4}); - var call = div(channel, arg, function handleDivResult(err, value) { + var arg = {dividend: 7, divisor: 4}; + var call = math_client.Div(arg, function handleDivResult(err, value) { assert.ifError(err); - assert.equal(value.get('quotient'), 1); - assert.equal(value.get('remainder'), 3); + assert.equal(value.quotient, 1); + assert.equal(value.remainder, 3); }); call.on('status', function checkStatus(status) { assert.strictEqual(status.code, client.status.OK); @@ -159,12 +142,11 @@ describe('Math client', function() { }); }); it('should handle a server streaming request', function(done) { - var arg = new math.FibArgs({limit: 7}); - var call = fib(channel, arg); + var call = math_client.Fib({limit: 7}); var expected_results = [1, 1, 2, 3, 5, 8, 13]; var next_expected = 0; call.on('data', function checkResponse(value) { - assert.equal(value.get('num'), expected_results[next_expected]); + assert.equal(value.num, expected_results[next_expected]); next_expected += 1; }); call.on('status', function checkStatus(status) { @@ -173,12 +155,12 @@ describe('Math client', function() { }); }); it('should handle a client streaming request', function(done) { - var call = sum(channel, function handleSumResult(err, value) { + var call = math_client.Sum(function handleSumResult(err, value) { assert.ifError(err); - assert.equal(value.get('num'), 21); + assert.equal(value.num, 21); }); for (var i = 0; i < 7; i++) { - call.write(new math.Num({'num': i})); + call.write({'num': i}); } call.end(); call.on('status', function checkStatus(status) { @@ -188,17 +170,17 @@ describe('Math client', function() { }); it('should handle a bidirectional streaming request', function(done) { function checkResponse(index, value) { - assert.equal(value.get('quotient'), index); - assert.equal(value.get('remainder'), 1); + assert.equal(value.quotient, index); + assert.equal(value.remainder, 1); } - var call = divMany(channel); + var call = math_client.DivMany(); var response_index = 0; call.on('data', function(value) { checkResponse(response_index, value); response_index += 1; }); for (var i = 0; i < 7; i++) { - call.write(new math.DivArgs({dividend: 2 * i + 1, divisor: 2})); + call.write({dividend: 2 * i + 1, divisor: 2}); } call.end(); call.on('status', function checkStatus(status) { diff --git a/templates/Makefile.template b/templates/Makefile.template index d0ebb102408..256380c2ddc 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -66,6 +66,15 @@ CPPFLAGS_msan = -O1 -fsanitize=memory -fno-omit-frame-pointer LDFLAGS_msan = -fsanitize=memory DEFINES_msan = NDEBUG +VALID_CONFIG_gcov = 1 +CC_gcov = gcc +CXX_gcov = g++ +LD_gcov = gcc +LDXX_gcov = g++ +CPPFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage +LDFLAGS_gcov = -fprofile-arcs -ftest-coverage +DEFINES_gcov = NDEBUG + # General settings. # You may want to change these depending on your system. @@ -329,7 +338,7 @@ privatelibs: privatelibs_c privatelibs_cxx privatelibs_c: dep_c\ % for lib in libs: -% if lib.build == 'private': +% if lib.build == 'private' and not lib.get('c++', False): libs/$(CONFIG)/lib${lib.name}.a\ % endif % endfor @@ -337,7 +346,7 @@ privatelibs_c: dep_c\ privatelibs_cxx: dep_cxx\ % for lib in libs: -% if lib.build == 'private': +% if lib.build == 'private' and lib.get('c++', False): libs/$(CONFIG)/lib${lib.name}.a\ % endif % endfor diff --git a/templates/vsprojects/vs2013/build_and_run_tests.bat.template b/templates/vsprojects/vs2013/build_and_run_tests.bat.template index 8679bee3fc3..4a15e01c522 100644 --- a/templates/vsprojects/vs2013/build_and_run_tests.bat.template +++ b/templates/vsprojects/vs2013/build_and_run_tests.bat.template @@ -13,7 +13,7 @@ @rem Build the library dependencies first MSBuild.exe gpr.vcxproj /p:Configuration=Debug -MSBuild.exe grpc_test_util.vcxproj /p:Configuration=Debug +MSBuild.exe gpr_test_util.vcxproj /p:Configuration=Debug mkdir ${test_bin_dir} diff --git a/test/build/event2.c b/test/build/event2.c deleted file mode 100644 index f632b1e43e6..00000000000 --- a/test/build/event2.c +++ /dev/null @@ -1,8 +0,0 @@ -/* This is only a compilation test, to see if we have libevent installed. */ - -#include - -int main() { - event_base_new(); - return 0; -} diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c index 1a8f1a5f496..94245d85bcc 100644 --- a/test/core/util/test_config.c +++ b/test/core/util/test_config.c @@ -33,14 +33,28 @@ #include "test/core/util/test_config.h" +#include #include #include + +#if GPR_GETPID_IN_UNISTD_H #include +static int seed() { + return getpid(); +} +#endif + +#if GPR_GETPID_IN_PROCESS_H +#include +static int seed(void) { + return _getpid(); +} +#endif void grpc_test_init(int argc, char **argv) { /* disable SIGPIPE */ signal(SIGPIPE, SIG_IGN); /* seed rng with pid, so we don't end up with the same random numbers as a concurrently running test binary */ - srand(getpid()); + srand(seed()); } diff --git a/third_party/libevent b/third_party/libevent deleted file mode 160000 index f7d92c63928..00000000000 --- a/third_party/libevent +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f7d92c63928a1460f3d99b9bc418bd3b686a0dca diff --git a/tools/dockerfile/grpc_base/Dockerfile b/tools/dockerfile/grpc_base/Dockerfile index 76e585a7d0d..45be1725935 100644 --- a/tools/dockerfile/grpc_base/Dockerfile +++ b/tools/dockerfile/grpc_base/Dockerfile @@ -13,7 +13,6 @@ RUN apt-get update && apt-get install -y \ libc6 \ libc6-dbg \ libc6-dev \ - libevent-dev \ libtool \ make \ strace \ diff --git a/tools/run_tests/run_lcov.sh b/tools/run_tests/run_lcov.sh new file mode 100755 index 00000000000..6f22b0e8a41 --- /dev/null +++ b/tools/run_tests/run_lcov.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -ex + +out=`realpath ${1:-coverage}` + +root=`realpath $(dirname $0)/../..` +tmp=`mktemp` +cd $root +tools/run_tests/run_tests.py -c gcov +lcov --capture --directory . --output-file $tmp +genhtml $tmp --output-directory $out +rm $tmp +if which xdg-open > /dev/null +then + xdg-open file://$out/index.html +fi + diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 6ab80d90453..bb25b38e570 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -36,6 +36,7 @@ _CONFIGS = { 'tsan': SimpleConfig('tsan'), 'msan': SimpleConfig('msan'), 'asan': SimpleConfig('asan'), + 'gcov': SimpleConfig('gcov'), 'valgrind': ValgrindConfig('dbg'), } diff --git a/vsprojects/vs2013/build_and_run_tests.bat b/vsprojects/vs2013/build_and_run_tests.bat index 06e9776d862..3e36dcf6002 100644 --- a/vsprojects/vs2013/build_and_run_tests.bat +++ b/vsprojects/vs2013/build_and_run_tests.bat @@ -5,7 +5,7 @@ @rem Build the library dependencies first MSBuild.exe gpr.vcxproj /p:Configuration=Debug -MSBuild.exe grpc_test_util.vcxproj /p:Configuration=Debug +MSBuild.exe gpr_test_util.vcxproj /p:Configuration=Debug mkdir test_bin