diff options
27 files changed, 190 insertions, 111 deletions
diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h index 434dd6de87..f98038da52 100644 --- a/include/grpc/support/port_platform.h +++ b/include/grpc/support/port_platform.h @@ -181,6 +181,7 @@ #ifndef _BSD_SOURCE #define _BSD_SOURCE #endif +#define GPR_FORBID_UNREACHABLE_CODE #define GPR_MSG_IOVLEN_TYPE int #if TARGET_OS_IPHONE #define GPR_PLATFORM_STRING "ios" @@ -336,4 +337,15 @@ typedef uintptr_t gpr_uintptr; #endif #endif +#ifdef GPR_FORBID_UNREACHABLE_CODE +#define GPR_UNREACHABLE_CODE(STATEMENT) +#else +#define GPR_UNREACHABLE_CODE(STATEMENT) \ + do { \ + gpr_log(GPR_ERROR, "Should never reach here."); \ + abort(); \ + STATEMENT; \ + } while (0) +#endif /* GPR_FORBID_UNREACHABLE_CODE */ + #endif /* GRPC_SUPPORT_PORT_PLATFORM_H */ diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 8e7cb27cfd..08aa721a4d 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -645,9 +645,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, case CALL_WAITING_FOR_CONFIG: case CALL_WAITING_FOR_CALL: case CALL_WAITING_FOR_SEND: - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - break; + GPR_UNREACHABLE_CODE(return ); } } diff --git a/src/core/client_config/uri_parser.c b/src/core/client_config/uri_parser.c index df9f32d403..cbdfffcf8e 100644 --- a/src/core/client_config/uri_parser.c +++ b/src/core/client_config/uri_parser.c @@ -37,6 +37,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include <grpc/support/port_platform.h> #include <grpc/support/string_util.h> /** a size_t default value... maps to all 1's */ @@ -120,8 +121,7 @@ static int parse_fragment_or_query(const char *uri_text, size_t *i) { } else { return 1; } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); + GPR_UNREACHABLE_CODE(return 0); default: (*i) += advance; break; diff --git a/src/core/httpcli/parser.c b/src/core/httpcli/parser.c index 404906d5ae..046770c094 100644 --- a/src/core/httpcli/parser.c +++ b/src/core/httpcli/parser.c @@ -139,8 +139,7 @@ static int finish_line(grpc_httpcli_parser *parser) { } break; case GRPC_HTTPCLI_BODY: - gpr_log(GPR_ERROR, "should never reach here"); - abort(); + GPR_UNREACHABLE_CODE(return 0); } parser->cur_line_length = 0; @@ -165,8 +164,7 @@ static int addbyte(grpc_httpcli_parser *parser, gpr_uint8 byte) { } else { return 1; } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); + GPR_UNREACHABLE_CODE(return 0); case GRPC_HTTPCLI_BODY: if (parser->r.body_length == parser->body_capacity) { parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2); @@ -177,10 +175,7 @@ static int addbyte(grpc_httpcli_parser *parser, gpr_uint8 byte) { parser->r.body_length++; return 1; } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - - return 0; + GPR_UNREACHABLE_CODE(return 0); } void grpc_httpcli_parser_init(grpc_httpcli_parser *parser) { diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c index aca2691c41..fe20039264 100644 --- a/src/core/iomgr/tcp_client_posix.c +++ b/src/core/iomgr/tcp_client_posix.c @@ -191,7 +191,7 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, int success) { goto finish; } - abort(); + GPR_UNREACHABLE_CODE(return ); finish: if (fd != NULL) { diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 13bd67576f..99c76dcbe9 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -352,7 +352,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) { gpr_free(addr_str); } - abort(); + GPR_UNREACHABLE_CODE(return ); error: gpr_mu_lock(&sp->server->mu); diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c index 398db20e8c..5e155d83b9 100644 --- a/src/core/security/credentials.c +++ b/src/core/security/credentials.c @@ -181,6 +181,48 @@ void grpc_server_credentials_set_auth_metadata_processor( creds->processor = processor; } +static void server_credentials_pointer_arg_destroy(void *p) { + grpc_server_credentials_unref(p); +} + +static void *server_credentials_pointer_arg_copy(void *p) { + return grpc_server_credentials_ref(p); +} + +grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) { + grpc_arg arg; + memset(&arg, 0, sizeof(grpc_arg)); + arg.type = GRPC_ARG_POINTER; + arg.key = GRPC_SERVER_CREDENTIALS_ARG; + arg.value.pointer.p = p; + arg.value.pointer.copy = server_credentials_pointer_arg_copy; + arg.value.pointer.destroy = server_credentials_pointer_arg_destroy; + return arg; +} + +grpc_server_credentials *grpc_server_credentials_from_arg( + const grpc_arg *arg) { + if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL; + if (arg->type != GRPC_ARG_POINTER) { + gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, + GRPC_SERVER_CREDENTIALS_ARG); + return NULL; + } + return arg->value.pointer.p; +} + +grpc_server_credentials *grpc_find_server_credentials_in_args( + const grpc_channel_args *args) { + size_t i; + if (args == NULL) return NULL; + for (i = 0; i < args->num_args; i++) { + grpc_server_credentials *p = + grpc_server_credentials_from_arg(&args->args[i]); + if (p != NULL) return p; + } + return NULL; +} + /* -- Ssl credentials. -- */ static void ssl_destruct(grpc_credentials *creds) { diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h index b213e052d3..01203b08f1 100644 --- a/src/core/security/credentials.h +++ b/src/core/security/credentials.h @@ -215,7 +215,6 @@ typedef struct { grpc_server_credentials *c, grpc_security_connector **sc); } grpc_server_credentials_vtable; -/* TODO(jboeuf): Add a refcount. */ struct grpc_server_credentials { const grpc_server_credentials_vtable *vtable; const char *type; @@ -231,6 +230,13 @@ grpc_server_credentials *grpc_server_credentials_ref( void grpc_server_credentials_unref(grpc_server_credentials *creds); +#define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials" + +grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *c); +grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg); +grpc_server_credentials *grpc_find_server_credentials_in_args( + const grpc_channel_args *args); + /* -- Ssl credentials. -- */ typedef struct { diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index fb905e0b22..f544c1d943 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -305,33 +305,43 @@ void grpc_auth_property_reset(grpc_auth_property *property) { memset(property, 0, sizeof(grpc_auth_property)); } -grpc_arg grpc_auth_metadata_processor_to_arg(grpc_auth_metadata_processor *p) { +static void auth_context_pointer_arg_destroy(void *p) { + GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg"); +} + +static void *auth_context_pointer_arg_copy(void *p) { + return GRPC_AUTH_CONTEXT_REF(p, "auth_context_pointer_arg"); +} + +grpc_arg grpc_auth_context_to_arg(grpc_auth_context *p) { grpc_arg arg; memset(&arg, 0, sizeof(grpc_arg)); arg.type = GRPC_ARG_POINTER; - arg.key = GRPC_AUTH_METADATA_PROCESSOR_ARG; + arg.key = GRPC_AUTH_CONTEXT_ARG; arg.value.pointer.p = p; + arg.value.pointer.copy = auth_context_pointer_arg_copy; + arg.value.pointer.destroy = auth_context_pointer_arg_destroy; return arg; } -grpc_auth_metadata_processor *grpc_auth_metadata_processor_from_arg( +grpc_auth_context *grpc_auth_context_from_arg( const grpc_arg *arg) { - if (strcmp(arg->key, GRPC_AUTH_METADATA_PROCESSOR_ARG) != 0) return NULL; + if (strcmp(arg->key, GRPC_AUTH_CONTEXT_ARG) != 0) return NULL; if (arg->type != GRPC_ARG_POINTER) { gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, - GRPC_AUTH_METADATA_PROCESSOR_ARG); + GRPC_AUTH_CONTEXT_ARG); return NULL; } return arg->value.pointer.p; } -grpc_auth_metadata_processor *grpc_find_auth_metadata_processor_in_args( +grpc_auth_context *grpc_find_auth_context_in_args( const grpc_channel_args *args) { size_t i; if (args == NULL) return NULL; for (i = 0; i < args->num_args; i++) { - grpc_auth_metadata_processor *p = - grpc_auth_metadata_processor_from_arg(&args->args[i]); + grpc_auth_context *p = + grpc_auth_context_from_arg(&args->args[i]); if (p != NULL) return p; } return NULL; diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h index a9a0306410..2bbdc4be97 100644 --- a/src/core/security/security_context.h +++ b/src/core/security/security_context.h @@ -103,13 +103,12 @@ typedef struct { grpc_server_security_context *grpc_server_security_context_create(void); void grpc_server_security_context_destroy(void *ctx); -/* --- Auth metadata processing. --- */ -#define GRPC_AUTH_METADATA_PROCESSOR_ARG "grpc.auth_metadata_processor" +/* --- Channel args for auth context --- */ +#define GRPC_AUTH_CONTEXT_ARG "grpc.auth_context" -grpc_arg grpc_auth_metadata_processor_to_arg(grpc_auth_metadata_processor *p); -grpc_auth_metadata_processor *grpc_auth_metadata_processor_from_arg( - const grpc_arg *arg); -grpc_auth_metadata_processor *grpc_find_auth_metadata_processor_in_args( +grpc_arg grpc_auth_context_to_arg(grpc_auth_context *c); +grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg); +grpc_auth_context *grpc_find_auth_context_in_args( const grpc_channel_args *args); #endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */ diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index 30ca9f57a2..2e18369fe8 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -34,7 +34,7 @@ #include <string.h> #include "src/core/security/auth_filters.h" -#include "src/core/security/security_connector.h" +#include "src/core/security/credentials.h" #include "src/core/security/security_context.h" #include <grpc/support/alloc.h> @@ -58,8 +58,8 @@ typedef struct call_data { } call_data; typedef struct channel_data { - grpc_security_connector *security_connector; - grpc_auth_metadata_processor processor; + grpc_auth_context *auth_context; + grpc_server_credentials *creds; grpc_mdctx *mdctx; } channel_data; @@ -160,12 +160,12 @@ static void auth_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, grpc_stream_op *op = &ops[i]; if (op->type != GRPC_OP_METADATA || calld->got_client_metadata) continue; calld->got_client_metadata = 1; - if (chand->processor.process == NULL) continue; + if (chand->creds->processor.process == NULL) continue; calld->md_op = op; calld->md = metadata_batch_to_md_array(&op->data.metadata); - chand->processor.process(chand->processor.state, calld->auth_context, - calld->md.metadata, calld->md.count, - on_md_processing_done, elem); + chand->creds->processor.process( + chand->creds->processor.state, calld->auth_context, + calld->md.metadata, calld->md.count, on_md_processing_done, elem); return; } } @@ -221,7 +221,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, } server_ctx = grpc_server_security_context_create(); server_ctx->auth_context = - grpc_auth_context_create(chand->security_connector->auth_context); + grpc_auth_context_create(chand->auth_context); server_ctx->auth_context->pollset = initial_op->bind_pollset; initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx; initial_op->context[GRPC_CONTEXT_SECURITY].destroy = @@ -241,9 +241,8 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { - grpc_security_connector *sc = grpc_find_security_connector_in_args(args); - grpc_auth_metadata_processor *processor = - grpc_find_auth_metadata_processor_in_args(args); + grpc_auth_context *auth_context = grpc_find_auth_context_in_args(args); + grpc_server_credentials *creds = grpc_find_server_credentials_in_args(args); /* grab pointers to our data from the channel element */ channel_data *chand = elem->channel_data; @@ -252,15 +251,14 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx, path */ GPR_ASSERT(!is_first); GPR_ASSERT(!is_last); - GPR_ASSERT(sc != NULL); - GPR_ASSERT(processor != NULL); + GPR_ASSERT(auth_context != NULL); + GPR_ASSERT(creds != NULL); /* initialize members */ - GPR_ASSERT(!sc->is_client_side); - chand->security_connector = - GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter"); + chand->auth_context = + GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter"); + chand->creds = grpc_server_credentials_ref(creds); chand->mdctx = mdctx; - chand->processor = *processor; } /* Destructor for channel data */ @@ -268,8 +266,8 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) { /* grab pointers to our data from the channel element */ channel_data *chand = elem->channel_data; - GRPC_SECURITY_CONNECTOR_UNREF(chand->security_connector, - "server_auth_filter"); + GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter"); + grpc_server_credentials_unref(chand->creds); } const grpc_channel_filter grpc_server_auth_filter = { diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index 881e44a3fe..82c639e830 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -93,9 +93,9 @@ static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep, grpc_server_secure_state *state = statep; grpc_channel_args *args_copy; grpc_arg args_to_add[2]; - args_to_add[0] = grpc_security_connector_to_arg(state->sc); + args_to_add[0] = grpc_server_credentials_to_arg(state->creds); args_to_add[1] = - grpc_auth_metadata_processor_to_arg(&state->creds->processor); + grpc_auth_context_to_arg(state->sc->auth_context); args_copy = grpc_channel_args_copy_and_add( grpc_server_get_channel_args(state->server), args_to_add, GPR_ARRAY_SIZE(args_to_add)); diff --git a/src/core/surface/byte_buffer.c b/src/core/surface/byte_buffer.c index 295ef5ab0e..fb39c4531d 100644 --- a/src/core/surface/byte_buffer.c +++ b/src/core/surface/byte_buffer.c @@ -75,9 +75,7 @@ grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb) { return grpc_raw_byte_buffer_create(bb->data.raw.slice_buffer.slices, bb->data.raw.slice_buffer.count); } - gpr_log(GPR_INFO, "should never get here"); - abort(); - return NULL; + GPR_UNREACHABLE_CODE(return NULL); } void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) { @@ -95,7 +93,5 @@ size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) { case GRPC_BB_RAW: return bb->data.raw.slice_buffer.length; } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - return 0; + GPR_UNREACHABLE_CODE(return 0); } diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 022ca191cd..386a4a6b29 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -434,8 +434,7 @@ static grpc_cq_completion *allocate_completion(grpc_call *call) { gpr_mu_unlock(&call->completion_mu); return &call->completions[i]; } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); + GPR_UNREACHABLE_CODE(return NULL); return NULL; } diff --git a/src/core/surface/channel_connectivity.c b/src/core/surface/channel_connectivity.c index f72fb04142..ca3c02c536 100644 --- a/src/core/surface/channel_connectivity.c +++ b/src/core/surface/channel_connectivity.c @@ -100,9 +100,7 @@ static void finished_completion(grpc_exec_ctx *exec_ctx, void *pw, switch (w->phase) { case WAITING: case CALLED_BACK: - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - break; + GPR_UNREACHABLE_CODE(return ); case CALLING_BACK: w->phase = CALLED_BACK; break; @@ -149,9 +147,7 @@ static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w, w->phase = CALLING_BACK_AND_FINISHED; break; case CALLING_BACK_AND_FINISHED: - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - break; + GPR_UNREACHABLE_CODE(return ); case CALLED_BACK: delete = 1; break; diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c index e818ccba48..9e552c2cdf 100644 --- a/src/core/surface/completion_queue.c +++ b/src/core/surface/completion_queue.c @@ -254,8 +254,7 @@ static void del_plucker(grpc_completion_queue *cc, void *tag, return; } } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); + GPR_UNREACHABLE_CODE(return ); } grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c index acfa7c002e..07179a4571 100644 --- a/src/core/transport/chttp2/frame_data.c +++ b/src/core/transport/chttp2/frame_data.c @@ -168,7 +168,5 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse( } } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - return GRPC_CHTTP2_CONNECTION_ERROR; + GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR); } diff --git a/src/core/transport/chttp2/frame_goaway.c b/src/core/transport/chttp2/frame_goaway.c index 2ff1eda89b..c5758bcb71 100644 --- a/src/core/transport/chttp2/frame_goaway.c +++ b/src/core/transport/chttp2/frame_goaway.c @@ -152,9 +152,7 @@ grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse( } return GRPC_CHTTP2_PARSE_OK; } - gpr_log(GPR_ERROR, "Should never end up here"); - abort(); - return GRPC_CHTTP2_CONNECTION_ERROR; + GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR); } void grpc_chttp2_goaway_append(gpr_uint32 last_stream_id, gpr_uint32 error_code, diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c index 20ea513375..20d8312d54 100644 --- a/src/core/transport/chttp2/hpack_parser.c +++ b/src/core/transport/chttp2/hpack_parser.c @@ -1166,9 +1166,7 @@ static int append_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur, append_bytes(str, decoded, 3); goto b64_byte0; } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - return 1; + GPR_UNREACHABLE_CODE(return 1); } /* append a null terminator to a string */ @@ -1313,9 +1311,7 @@ static int parse_value_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur, return 0; } /* Add code to prevent return without value error */ - gpr_log(GPR_ERROR, "Should never reach beyond switch in parse_value_string"); - abort(); - return 0; + GPR_UNREACHABLE_CODE(return 0); } static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p, diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c index f7a0a10581..a0977ccaf6 100644 --- a/src/core/transport/chttp2/parsing.c +++ b/src/core/transport/chttp2/parsing.c @@ -417,14 +417,10 @@ int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx, transport_parsing->incoming_frame_size -= (gpr_uint32)(end - cur); return 1; } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); + GPR_UNREACHABLE_CODE(return 0); } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - - return 0; + GPR_UNREACHABLE_CODE(return 0); } static int init_frame_parser(grpc_chttp2_transport_parsing *transport_parsing) { @@ -580,9 +576,7 @@ static int init_data_frame_parser( case GRPC_CHTTP2_CONNECTION_ERROR: return 0; } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - return 0; + GPR_UNREACHABLE_CODE(return 0); } static void free_timeout(void *p) { gpr_free(p); } @@ -820,7 +814,5 @@ static int parse_frame_slice(grpc_exec_ctx *exec_ctx, case GRPC_CHTTP2_CONNECTION_ERROR: return 0; } - gpr_log(GPR_ERROR, "should never reach here"); - abort(); - return 0; + GPR_UNREACHABLE_CODE(return 0); } diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c index 83227e677d..6c7f7a9ea7 100644 --- a/src/core/transport/chttp2/stream_encoder.c +++ b/src/core/transport/chttp2/stream_encoder.c @@ -428,7 +428,7 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c, emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st); return elem; } - abort(); + GPR_UNREACHABLE_CODE(return NULL); } indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)]; @@ -442,7 +442,7 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c, emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st); return elem; } - abort(); + GPR_UNREACHABLE_CODE(return NULL); } /* no elem, key in the table... fall back to literal emission */ @@ -454,7 +454,7 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c, emit_lithdr_noidx_v(c, elem, st); return elem; } - abort(); + GPR_UNREACHABLE_CODE(return NULL); } #define STRLEN_LIT(x) (sizeof(x) - 1) diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index a44e1d2025..e09744b842 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -153,8 +153,7 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag { GPR_ASSERT((*req)->in_flight_); return true; } - gpr_log(GPR_ERROR, "Should never reach here"); - abort(); + GPR_UNREACHABLE_CODE(return false); } void SetupRequest() { cq_ = grpc_completion_queue_create(nullptr); } diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index d55d5629b7..0590264ef8 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -251,6 +251,23 @@ function pingPong($stub) { } /** + * Run the empty_stream test. + * Passes when run against the Node server as of 2015-10-09 + * @param $stub Stub object that has service methods. + */ +function emptyStream($stub) { + // for the current PHP implementation, $call->read() will wait + // forever for a server response if the server is not sending any. + // so this test is imeplemented as a timeout to indicate the absence + // of receiving any response from the server + $call = $stub->FullDuplexCall(array('timeout' => 100000)); + $call->writesDone(); + hardAssert($call->read() === null, 'Server returned too many responses'); + hardAssert($call->getStatus()->code === Grpc\STATUS_OK, + 'Call did not complete successfully'); +} + +/** * Run the cancel_after_begin test. * Passes when run against the Node server as of 2015-08-28 * @param $stub Stub object that has service methods. @@ -370,6 +387,9 @@ switch ($args['test_case']) { case 'ping_pong': pingPong($stub); break; + case 'empty_stream': + emptyStream($stub); + break; case 'cancel_after_begin': cancelAfterBegin($stub); break; diff --git a/tools/jenkins/grpc_jenkins_slave/Dockerfile b/tools/jenkins/grpc_jenkins_slave/Dockerfile index 5f2b425c8c..129a8db24f 100644 --- a/tools/jenkins/grpc_jenkins_slave/Dockerfile +++ b/tools/jenkins/grpc_jenkins_slave/Dockerfile @@ -157,6 +157,12 @@ RUN apt-get update && apt-get install -y \ RUN apt-get install -y libzookeeper-mt-dev +################## +# Docker "inception". +# Note this is quite the ugly hack. +# This makes sure that the docker binary we inject has its dependencies. +RUN curl https://get.docker.com/ | sh +RUN apt-get remove --purge -y docker-engine RUN mkdir /var/local/jenkins diff --git a/tools/run_tests/dockerjob.py b/tools/run_tests/dockerjob.py index 266edd4375..1d67fe3033 100755 --- a/tools/run_tests/dockerjob.py +++ b/tools/run_tests/dockerjob.py @@ -46,13 +46,24 @@ def random_name(base_name): def docker_kill(cid): """Kills a docker container. Returns True if successful.""" - return subprocess.call(['docker','kill', str(cid)]) == 0 + return subprocess.call(['docker','kill', str(cid)], + stdout=_DEVNULL, + stderr=subprocess.STDOUT) == 0 -def docker_mapped_port(cid, port): +def docker_mapped_port(cid, port, timeout_seconds=15): """Get port mapped to internal given internal port for given container.""" - output = subprocess.check_output('docker port %s %s' % (cid, port), shell=True) - return int(output.split(':', 2)[1]) + started = time.time() + while time.time() - started < timeout_seconds: + try: + output = subprocess.check_output('docker port %s %s' % (cid, port), + stderr=_DEVNULL, + shell=True) + return int(output.split(':', 2)[1]) + except subprocess.CalledProcessError as e: + pass + raise Exception('Failed to get exposed port %s for container %s.' % + (port, cid)) def finish_jobs(jobs): @@ -68,7 +79,7 @@ def image_exists(image): """Returns True if given docker image exists.""" return subprocess.call(['docker','inspect', image], stdout=_DEVNULL, - stderr=_DEVNULL) == 0 + stderr=subprocess.STDOUT) == 0 def remove_image(image, skip_nonexistent=False, max_retries=10): @@ -76,7 +87,9 @@ def remove_image(image, skip_nonexistent=False, max_retries=10): if skip_nonexistent and not image_exists(image): return True for attempt in range(0, max_retries): - if subprocess.call(['docker','rmi', '-f', image]) == 0: + if subprocess.call(['docker','rmi', '-f', image], + stdout=_DEVNULL, + stderr=subprocess.STDOUT) == 0: return True time.sleep(2) print 'Failed to remove docker image %s' % image diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 4d09ae7fcd..6daa967bba 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -71,6 +71,7 @@ class CXXLanguage: self.client_cmdline_base = ['bins/opt/interop_client'] self.client_cwd = None self.server_cwd = None + self.safename = 'cxx' def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -96,6 +97,7 @@ class CSharpLanguage: self.client_cmdline_base = ['mono', 'Grpc.IntegrationTesting.Client.exe'] self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug' self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug' + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -121,6 +123,7 @@ class JavaLanguage: self.client_cmdline_base = ['./run-test-client.sh'] self.client_cwd = '../grpc-java' self.server_cwd = '../grpc-java' + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -147,6 +150,7 @@ class GoLanguage: # TODO: this relies on running inside docker self.client_cwd = '/go/src/google.golang.org/grpc/interop/client' self.server_cwd = '/go/src/google.golang.org/grpc/interop/server' + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -172,6 +176,7 @@ class NodeLanguage: self.client_cmdline_base = ['node', 'src/node/interop/interop_client.js'] self.client_cwd = None self.server_cwd = None + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -196,6 +201,7 @@ class PHPLanguage: def __init__(self): self.client_cmdline_base = ['src/php/bin/interop_client.sh'] self.client_cwd = None + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -218,6 +224,7 @@ class RubyLanguage: self.client_cmdline_base = ['ruby', 'src/ruby/bin/interop/interop_client.rb'] self.client_cwd = None self.server_cwd = None + self.safename = str(self) def cloud_to_prod_args(self): return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + @@ -251,11 +258,9 @@ _LANGUAGES = { # languages supported as cloud_to_cloud servers _SERVERS = ['c++', 'node', 'csharp', 'java', 'go', 'ruby'] -# TODO(jtattermusch): add empty_stream once PHP starts supporting it. # TODO(jtattermusch): add timeout_on_sleeping_server once java starts supporting it. -# TODO(jtattermusch): add support for auth tests. _TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong', - 'client_streaming', 'server_streaming', + 'empty_stream', 'client_streaming', 'server_streaming', 'cancel_after_begin', 'cancel_after_first_response'] _AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds', @@ -337,7 +342,7 @@ def cloud_to_prod_jobspec(language, test_case, docker_image=None, auth=False): cmdline = bash_login_cmdline(cmdline) if docker_image: - container_name = dockerjob.random_name('interop_client_%s' % language) + container_name = dockerjob.random_name('interop_client_%s' % language.safename) cmdline = docker_run_cmdline(cmdline, image=docker_image, cwd=cwd, @@ -370,7 +375,7 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, '--server_port=%s' % server_port ]) cwd = language.client_cwd if docker_image: - container_name = dockerjob.random_name('interop_client_%s' % language) + container_name = dockerjob.random_name('interop_client_%s' % language.safename) cmdline = docker_run_cmdline(cmdline, image=docker_image, cwd=cwd, @@ -393,7 +398,7 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host, def server_jobspec(language, docker_image): """Create jobspec for running a server""" - container_name = dockerjob.random_name('interop_server_%s' % language) + container_name = dockerjob.random_name('interop_server_%s' % language.safename) cmdline = bash_login_cmdline(language.server_args() + ['--port=%s' % _DEFAULT_SERVER_PORT]) docker_cmdline = docker_run_cmdline(cmdline, @@ -411,10 +416,10 @@ def server_jobspec(language, docker_image): def build_interop_image_jobspec(language, tag=None): """Creates jobspec for building interop docker image for a language""" - safelang = str(language).replace("+", "x") if not tag: - tag = 'grpc_interop_%s:%s' % (safelang, uuid.uuid4()) - env = {'INTEROP_IMAGE': tag, 'BASE_NAME': 'grpc_interop_%s' % safelang} + tag = 'grpc_interop_%s:%s' % (language.safename, uuid.uuid4()) + env = {'INTEROP_IMAGE': tag, + 'BASE_NAME': 'grpc_interop_%s' % language.safename} if not args.travis: env['TTY_FLAG'] = '-t' build_job = jobset.JobSpec( diff --git a/tools/run_tests/run_node.sh b/tools/run_tests/run_node.sh index 780969089d..0a11e87c37 100755 --- a/tools/run_tests/run_node.sh +++ b/tools/run_tests/run_node.sh @@ -46,6 +46,8 @@ then lcov --base-directory . --directory . -c -o coverage.info genhtml -o ../reports/node_ext_coverage --num-spaces 2 \ -t 'Node gRPC test coverage' coverage.info + echo '<html><head><meta http-equiv="refresh" content="0;URL=lcov-report/index.html"></head></html>' > \ + ../reports/node_coverage/index.html else ./node_modules/mocha/bin/mocha --timeout 8000 src/node/test fi |