From 26dab31f6ec8c6b6ede97aa00eaaa4b68d6363a7 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 7 Dec 2015 14:43:47 -0800 Subject: Start of ping sketch --- src/core/channel/client_channel.c | 12 +++- src/core/client_config/lb_policies/pick_first.c | 2 +- src/core/client_config/lb_policy.h | 4 ++ src/core/surface/channel_ping.c | 76 +++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/core/surface/channel_ping.c (limited to 'src') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 020138bf15..1a22801c07 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -243,7 +243,7 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx, grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, 1); GPR_ASSERT(op->set_accept_stream == NULL); - GPR_ASSERT(op->bind_pollset == NULL); + GPR_ASSERT(op->bind_pollset == NULL || op->send_ping != NULL); gpr_mu_lock(&chand->mu_config); if (op->on_connectivity_state_change != NULL) { @@ -259,6 +259,16 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx, GRPC_LB_POLICY_REF(lb_policy, "broadcast"); } + if (op->send_ping != NULL) { + if (lb_policy == NULL) { + grpc_exec_ctx_enqueue(exec_ctx, op->send_ping, 0); + } else { + grpc_lb_policy_ping_one(exec_ctx, lb_policy, op->bind_pollset, op->send_ping); + op->bind_pollset = NULL; + } + op->send_ping = NULL; + } + if (op->disconnect && chand->resolver != NULL) { grpc_connectivity_state_set(exec_ctx, &chand->state_tracker, GRPC_CHANNEL_FATAL_FAILURE, "disconnect"); diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index 93312abb00..c007e4c584 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -390,7 +390,7 @@ void pf_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, } static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = { - pf_destroy, pf_shutdown, pf_pick, pf_cancel_pick, pf_exit_idle, + pf_destroy, pf_shutdown, pf_pick, pf_cancel_pick, pf_ping_one, pf_exit_idle, pf_broadcast, pf_check_connectivity, pf_notify_on_state_change}; static void pick_first_factory_ref(grpc_lb_policy_factory *factory) {} diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h index a696c3ce64..894a94e0ec 100644 --- a/src/core/client_config/lb_policy.h +++ b/src/core/client_config/lb_policy.h @@ -62,6 +62,8 @@ struct grpc_lb_policy_vtable { void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_subchannel **target); + void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_pollset *pollset, grpc_closure *closure); + /** try to enter a READY connectivity state */ void (*exit_idle)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); @@ -113,6 +115,8 @@ int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_metadata_batch *initial_metadata, grpc_subchannel **target, grpc_closure *on_complete); +void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_pollset *pollset, grpc_closure *closure); + void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_subchannel **target); diff --git a/src/core/surface/channel_ping.c b/src/core/surface/channel_ping.c new file mode 100644 index 0000000000..c6d04802ed --- /dev/null +++ b/src/core/surface/channel_ping.c @@ -0,0 +1,76 @@ +/* + * + * 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. + * + */ + +#include "src/core/surface/channel.h" + +#include + +#include +#include + +#include "src/core/surface/api_trace.h" +#include "src/core/surface/completion_queue.h" + +typedef struct { + grpc_closure closure; + void *tag; + grpc_completion_queue *cq; + grpc_cq_completion completion_storage; +} ping_result; + +static void ping_destroy(grpc_exec_ctx *exec_ctx, void *arg, grpc_cq_completion *storage) { + gpr_free(arg); +} + +static void ping_done(grpc_exec_ctx *exec_ctx, void *arg, int success) { + ping_result *pr = arg; + grpc_cq_end_op(exec_ctx, pr->cq, pr->tag, success, ping_destroy, pr, &pr->completion_storage); +} + +void grpc_channel_ping( + grpc_channel *channel, grpc_completion_queue *cq, void *tag, void *reserved) { + grpc_transport_op op; + ping_result *pr = gpr_malloc(sizeof(*pr)); + grpc_channel_element *top_elem = grpc_channel_stack_element( + grpc_channel_get_channel_stack(channel), 0); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + memset(&op, 0, sizeof(op)); + pr->tag = tag; + pr->cq = cq; + grpc_closure_init(&pr->closure, ping_done, pr); + op.send_ping = &pr->closure; + op.bind_pollset = grpc_cq_pollset(cq); + grpc_cq_begin_op(cq); + top_elem->filter->start_transport_op(&exec_ctx, top_elem, &op); + grpc_exec_ctx_finish(&exec_ctx); +} -- cgit v1.2.3 From 28bf8912fd4d5aa3e30710f6871abd52abbb9420 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 7 Dec 2015 16:07:04 -0800 Subject: Ping API --- src/core/channel/client_channel.c | 6 ++++-- src/core/client_config/lb_policies/pick_first.c | 11 +++++++++++ src/core/client_config/lb_policies/round_robin.c | 18 +++++++++++++++++- src/core/client_config/lb_policy.c | 4 ++++ src/core/client_config/lb_policy.h | 4 ++-- src/core/client_config/subchannel.c | 11 +++++++++++ src/core/client_config/subchannel.h | 3 +++ src/core/transport/chttp2/frame_ping.c | 11 +---------- src/core/transport/chttp2/internal.h | 7 ++++--- src/core/transport/chttp2_transport.c | 19 +++++++++++++++++++ test/core/end2end/tests/channel_ping.c | 20 ++++++++++++++++++++ 11 files changed, 96 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 0212f4f2c8..c2a6648f18 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -252,7 +252,9 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx, grpc_exec_ctx_enqueue(exec_ctx, op->on_consumed, 1); GPR_ASSERT(op->set_accept_stream == NULL); - GPR_ASSERT(op->bind_pollset == NULL || op->send_ping != NULL); + if (op->bind_pollset != NULL) { + grpc_pollset_set_add_pollset(exec_ctx, &chand->interested_parties, op->bind_pollset); + } gpr_mu_lock(&chand->mu_config); if (op->on_connectivity_state_change != NULL) { @@ -267,7 +269,7 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx, if (chand->lb_policy == NULL) { grpc_exec_ctx_enqueue(exec_ctx, op->send_ping, 0); } else { - grpc_lb_policy_ping_one(exec_ctx, chand->lb_policy, op->bind_pollset, op->send_ping); + grpc_lb_policy_ping_one(exec_ctx, chand->lb_policy, op->send_ping); op->bind_pollset = NULL; } op->send_ping = NULL; diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index 8a8b60ba39..7dad7f7cd4 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -348,6 +348,17 @@ void pf_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, gpr_mu_unlock(&p->mu); } +void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_closure *closure) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + gpr_mu_lock(&p->mu); + if (p->selected) { + grpc_connected_subchannel_ping(exec_ctx, p->selected, closure); + } else { + grpc_exec_ctx_enqueue(exec_ctx, closure, 0); + } + gpr_mu_unlock(&p->mu); +} + static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = { pf_destroy, pf_shutdown, pf_pick, pf_cancel_pick, pf_ping_one, pf_exit_idle, pf_check_connectivity, pf_notify_on_state_change}; diff --git a/src/core/client_config/lb_policies/round_robin.c b/src/core/client_config/lb_policies/round_robin.c index b86dba20ee..d487456363 100644 --- a/src/core/client_config/lb_policies/round_robin.c +++ b/src/core/client_config/lb_policies/round_robin.c @@ -467,8 +467,24 @@ static void rr_notify_on_state_change(grpc_exec_ctx *exec_ctx, gpr_mu_unlock(&p->mu); } +static void rr_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_closure *closure) { + round_robin_lb_policy *p = (round_robin_lb_policy *)pol; + ready_list *selected; + grpc_connected_subchannel *target; + gpr_mu_lock(&p->mu); + if ((selected = peek_next_connected_locked(p))) { + gpr_mu_unlock(&p->mu); + target = grpc_subchannel_get_connected_subchannel(selected->subchannel); + grpc_connected_subchannel_ping(exec_ctx, target, closure); + } else { + gpr_mu_unlock(&p->mu); + grpc_exec_ctx_enqueue(exec_ctx, closure, 0); + } +} + static const grpc_lb_policy_vtable round_robin_lb_policy_vtable = { - rr_destroy, rr_shutdown, rr_pick, rr_cancel_pick, rr_exit_idle, + rr_destroy, rr_shutdown, rr_pick, rr_cancel_pick, rr_ping_one, rr_exit_idle, rr_check_connectivity, rr_notify_on_state_change}; static void round_robin_factory_ref(grpc_lb_policy_factory *factory) {} diff --git a/src/core/client_config/lb_policy.c b/src/core/client_config/lb_policy.c index d254161546..3230434966 100644 --- a/src/core/client_config/lb_policy.c +++ b/src/core/client_config/lb_policy.c @@ -116,6 +116,10 @@ void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy) { policy->vtable->exit_idle(exec_ctx, policy); } +void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_closure *closure) { + policy->vtable->ping_one(exec_ctx, policy, closure); +} + void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_connectivity_state *state, diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h index 01c57a24ff..c194bf11fe 100644 --- a/src/core/client_config/lb_policy.h +++ b/src/core/client_config/lb_policy.h @@ -63,7 +63,7 @@ struct grpc_lb_policy_vtable { void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_connected_subchannel **target); - void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_pollset *pollset, grpc_closure *closure); + void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_closure *closure); /** try to enter a READY connectivity state */ void (*exit_idle)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); @@ -123,7 +123,7 @@ int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_connected_subchannel **target, grpc_closure *on_complete); -void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_pollset *pollset, grpc_closure *closure); +void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_closure *closure); void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_connected_subchannel **target); diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index 6631e9bae2..ce4919a8cb 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -461,6 +461,17 @@ void grpc_connected_subchannel_notify_on_state_change( closure); } +void grpc_connected_subchannel_ping( + grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, + grpc_closure *closure) { + grpc_transport_op op; + grpc_channel_element *elem; + memset(&op, 0, sizeof(op)); + op.send_ping = closure; + elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(con), 0); + elem->filter->start_transport_op(exec_ctx, elem, &op); +} + static void publish_transport(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) { size_t channel_stack_size; grpc_connected_subchannel *con; diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 74ebcecfba..c28c3a86c9 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -124,6 +124,9 @@ void grpc_connected_subchannel_notify_on_state_change( grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *channel, grpc_pollset_set *interested_parties, grpc_connectivity_state *state, grpc_closure *notify); +void grpc_connected_subchannel_ping( + grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *channel, + grpc_closure *notify); /** retrieve the grpc_connected_subchannel - or NULL if called before the subchannel becomes connected */ diff --git a/src/core/transport/chttp2/frame_ping.c b/src/core/transport/chttp2/frame_ping.c index 4d2c54269d..8e763278ff 100644 --- a/src/core/transport/chttp2/frame_ping.c +++ b/src/core/transport/chttp2/frame_ping.c @@ -76,7 +76,6 @@ grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse( gpr_uint8 *const end = GPR_SLICE_END_PTR(slice); gpr_uint8 *cur = beg; grpc_chttp2_ping_parser *p = parser; - grpc_chttp2_outstanding_ping *ping; while (p->byte != 8 && cur != end) { p->opaque_8bytes[p->byte] = *cur; @@ -87,15 +86,7 @@ grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse( if (p->byte == 8) { GPR_ASSERT(is_last); if (p->is_ack) { - for (ping = transport_parsing->pings.next; - ping != &transport_parsing->pings; ping = ping->next) { - if (0 == memcmp(p->opaque_8bytes, ping->id, 8)) { - grpc_exec_ctx_enqueue(exec_ctx, ping->on_recv, 1); - } - ping->next->prev = ping->prev; - ping->prev->next = ping->next; - gpr_free(ping); - } + grpc_chttp2_ack_ping(exec_ctx, transport_parsing, p->opaque_8bytes); } else { gpr_slice_buffer_add(&transport_parsing->qbuf, grpc_chttp2_ping_create(1, p->opaque_8bytes)); diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h index 45d2599cdc..fc35ea6f93 100644 --- a/src/core/transport/chttp2/internal.h +++ b/src/core/transport/chttp2/internal.h @@ -283,9 +283,6 @@ struct grpc_chttp2_transport_parsing { gpr_slice goaway_text; gpr_int64 outgoing_window; - - /** pings awaiting responses */ - grpc_chttp2_outstanding_ping pings; }; struct grpc_chttp2_transport { @@ -747,4 +744,8 @@ void grpc_chttp2_incoming_byte_stream_push(grpc_exec_ctx *exec_ctx, void grpc_chttp2_incoming_byte_stream_finished( grpc_exec_ctx *exec_ctx, grpc_chttp2_incoming_byte_stream *bs); +void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *parsing, + const gpr_uint8 *opaque_8bytes); + #endif diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 6ba9db8348..661e80d3a4 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -901,6 +901,25 @@ static void send_ping_locked(grpc_chttp2_transport *t, grpc_closure *on_recv) { gpr_slice_buffer_add(&t->global.qbuf, grpc_chttp2_ping_create(0, p->id)); } +void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + const gpr_uint8 *opaque_8bytes) { + grpc_chttp2_outstanding_ping *ping; + grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); + grpc_chttp2_transport_global *transport_global = &t->global; + lock(t); + for (ping = transport_global->pings.next; + ping != &transport_global->pings; ping = ping->next) { + if (0 == memcmp(opaque_8bytes, ping->id, 8)) { + grpc_exec_ctx_enqueue(exec_ctx, ping->on_recv, 1); + } + ping->next->prev = ping->prev; + ping->prev->next = ping->next; + gpr_free(ping); + } + unlock(exec_ctx, t); +} + static void perform_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_transport_op *op) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; diff --git a/test/core/end2end/tests/channel_ping.c b/test/core/end2end/tests/channel_ping.c index 9598b16bec..441e49ee7a 100644 --- a/test/core/end2end/tests/channel_ping.c +++ b/test/core/end2end/tests/channel_ping.c @@ -45,11 +45,31 @@ static void *tag(gpr_intptr t) { return (void *)t; } static void test_ping(grpc_end2end_test_config config) { grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL); cq_verifier *cqv = cq_verifier_create(f.cq); + grpc_connectivity_state state = GRPC_CHANNEL_IDLE; int i; config.init_client(&f, NULL); config.init_server(&f, NULL); + grpc_channel_ping(f.client, f.cq, tag(0), NULL); + cq_expect_completion(cqv, tag(0), 0); + + /* check that we're still in idle, and start connecting */ + GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) == + GRPC_CHANNEL_IDLE); + /* we'll go through some set of transitions (some might be missed), until + READY is reached */ + while (state != GRPC_CHANNEL_READY) { + grpc_channel_watch_connectivity_state( + f.client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(99)); + cq_expect_completion(cqv, tag(99), 1); + cq_verify(cqv); + state = grpc_channel_check_connectivity_state(f.client, 0); + GPR_ASSERT(state == GRPC_CHANNEL_READY || + state == GRPC_CHANNEL_CONNECTING || + state == GRPC_CHANNEL_TRANSIENT_FAILURE); + } + for (i = 1; i <= 5; i++) { grpc_channel_ping(f.client, f.cq, tag(i), NULL); cq_expect_completion(cqv, tag(i), 1); -- cgit v1.2.3 From e2c62375e47eb9f8d887357466c34575a7ed54cc Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 7 Dec 2015 16:11:03 -0800 Subject: clang-format --- include/grpc/grpc.h | 4 ++-- src/core/channel/client_channel.c | 3 ++- src/core/client_config/lb_policies/pick_first.c | 3 ++- src/core/client_config/lb_policy.c | 3 ++- src/core/client_config/lb_policy.h | 6 ++++-- src/core/client_config/subchannel.c | 6 +++--- src/core/client_config/subchannel.h | 6 +++--- src/core/surface/channel_ping.c | 14 ++++++++------ src/core/transport/chttp2_transport.c | 10 +++++----- test/core/bad_client/tests/initial_settings_frame.c | 3 ++- 10 files changed, 33 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index b673497c25..d52aab0dd3 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -531,9 +531,9 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, const char *method, const char *host, gpr_timespec deadline, void *reserved); -/** Ping the channels peer (load balanced channels will select one sub-channel +/** Ping the channels peer (load balanced channels will select one sub-channel to ping); if the channel is not connected, posts a failed. */ -void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq, +void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq, void *tag, void *reserved); /** Pre-register a method/host pair on a channel. */ diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index c2a6648f18..385ae3be9b 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -253,7 +253,8 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx, GPR_ASSERT(op->set_accept_stream == NULL); if (op->bind_pollset != NULL) { - grpc_pollset_set_add_pollset(exec_ctx, &chand->interested_parties, op->bind_pollset); + grpc_pollset_set_add_pollset(exec_ctx, &chand->interested_parties, + op->bind_pollset); } gpr_mu_lock(&chand->mu_config); diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index 7dad7f7cd4..37de3e9f68 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -348,7 +348,8 @@ void pf_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, gpr_mu_unlock(&p->mu); } -void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, grpc_closure *closure) { +void pf_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_closure *closure) { pick_first_lb_policy *p = (pick_first_lb_policy *)pol; gpr_mu_lock(&p->mu); if (p->selected) { diff --git a/src/core/client_config/lb_policy.c b/src/core/client_config/lb_policy.c index 3230434966..d4672f6b25 100644 --- a/src/core/client_config/lb_policy.c +++ b/src/core/client_config/lb_policy.c @@ -116,7 +116,8 @@ void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy) { policy->vtable->exit_idle(exec_ctx, policy); } -void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_closure *closure) { +void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_closure *closure) { policy->vtable->ping_one(exec_ctx, policy, closure); } diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h index c194bf11fe..db5238c8ca 100644 --- a/src/core/client_config/lb_policy.h +++ b/src/core/client_config/lb_policy.h @@ -63,7 +63,8 @@ struct grpc_lb_policy_vtable { void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_connected_subchannel **target); - void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_closure *closure); + void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_closure *closure); /** try to enter a READY connectivity state */ void (*exit_idle)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); @@ -123,7 +124,8 @@ int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_connected_subchannel **target, grpc_closure *on_complete); -void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_closure *closure); +void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, + grpc_closure *closure); void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_connected_subchannel **target); diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index ce4919a8cb..afb1cdbd6d 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -461,9 +461,9 @@ void grpc_connected_subchannel_notify_on_state_change( closure); } -void grpc_connected_subchannel_ping( - grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, - grpc_closure *closure) { +void grpc_connected_subchannel_ping(grpc_exec_ctx *exec_ctx, + grpc_connected_subchannel *con, + grpc_closure *closure) { grpc_transport_op op; grpc_channel_element *elem; memset(&op, 0, sizeof(op)); diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index c28c3a86c9..57c7c9dc67 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -124,9 +124,9 @@ void grpc_connected_subchannel_notify_on_state_change( grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *channel, grpc_pollset_set *interested_parties, grpc_connectivity_state *state, grpc_closure *notify); -void grpc_connected_subchannel_ping( - grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *channel, - grpc_closure *notify); +void grpc_connected_subchannel_ping(grpc_exec_ctx *exec_ctx, + grpc_connected_subchannel *channel, + grpc_closure *notify); /** retrieve the grpc_connected_subchannel - or NULL if called before the subchannel becomes connected */ diff --git a/src/core/surface/channel_ping.c b/src/core/surface/channel_ping.c index c6d04802ed..f00a52c2c4 100644 --- a/src/core/surface/channel_ping.c +++ b/src/core/surface/channel_ping.c @@ -48,21 +48,23 @@ typedef struct { grpc_cq_completion completion_storage; } ping_result; -static void ping_destroy(grpc_exec_ctx *exec_ctx, void *arg, grpc_cq_completion *storage) { +static void ping_destroy(grpc_exec_ctx *exec_ctx, void *arg, + grpc_cq_completion *storage) { gpr_free(arg); } static void ping_done(grpc_exec_ctx *exec_ctx, void *arg, int success) { ping_result *pr = arg; - grpc_cq_end_op(exec_ctx, pr->cq, pr->tag, success, ping_destroy, pr, &pr->completion_storage); + grpc_cq_end_op(exec_ctx, pr->cq, pr->tag, success, ping_destroy, pr, + &pr->completion_storage); } -void grpc_channel_ping( - grpc_channel *channel, grpc_completion_queue *cq, void *tag, void *reserved) { +void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq, + void *tag, void *reserved) { grpc_transport_op op; ping_result *pr = gpr_malloc(sizeof(*pr)); - grpc_channel_element *top_elem = grpc_channel_stack_element( - grpc_channel_get_channel_stack(channel), 0); + grpc_channel_element *top_elem = + grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; memset(&op, 0, sizeof(op)); pr->tag = tag; diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 661e80d3a4..325453b099 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -901,15 +901,15 @@ static void send_ping_locked(grpc_chttp2_transport *t, grpc_closure *on_recv) { gpr_slice_buffer_add(&t->global.qbuf, grpc_chttp2_ping_create(0, p->id)); } -void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport_parsing *transport_parsing, - const gpr_uint8 *opaque_8bytes) { +void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, + grpc_chttp2_transport_parsing *transport_parsing, + const gpr_uint8 *opaque_8bytes) { grpc_chttp2_outstanding_ping *ping; grpc_chttp2_transport *t = TRANSPORT_FROM_PARSING(transport_parsing); grpc_chttp2_transport_global *transport_global = &t->global; lock(t); - for (ping = transport_global->pings.next; - ping != &transport_global->pings; ping = ping->next) { + for (ping = transport_global->pings.next; ping != &transport_global->pings; + ping = ping->next) { if (0 == memcmp(opaque_8bytes, ping->id, 8)) { grpc_exec_ctx_enqueue(exec_ctx, ping->on_recv, 1); } diff --git a/test/core/bad_client/tests/initial_settings_frame.c b/test/core/bad_client/tests/initial_settings_frame.c index 6ed15bbed1..1959dc6ef2 100644 --- a/test/core/bad_client/tests/initial_settings_frame.c +++ b/test/core/bad_client/tests/initial_settings_frame.c @@ -94,7 +94,8 @@ int main(int argc, char **argv) { /* some settings values are illegal */ /* max frame size = 0 */ GRPC_RUN_BAD_CLIENT_TEST(verifier, - PFX_STR ONE_SETTING_HDR "\x00\x05\x00\x00\x00\x00", GRPC_BAD_CLIENT_DISCONNECT); + PFX_STR ONE_SETTING_HDR "\x00\x05\x00\x00\x00\x00", + GRPC_BAD_CLIENT_DISCONNECT); return 0; } -- cgit v1.2.3 From 30798c0fb9a5c86bf9d007f45e2837a66d0e22ee Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 8 Dec 2015 08:23:20 -0800 Subject: Fix ping response code --- src/core/transport/chttp2_transport.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 325453b099..aa459c8bac 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -912,10 +912,11 @@ void grpc_chttp2_ack_ping(grpc_exec_ctx *exec_ctx, ping = ping->next) { if (0 == memcmp(opaque_8bytes, ping->id, 8)) { grpc_exec_ctx_enqueue(exec_ctx, ping->on_recv, 1); + ping->next->prev = ping->prev; + ping->prev->next = ping->next; + gpr_free(ping); + break; } - ping->next->prev = ping->prev; - ping->prev->next = ping->next; - gpr_free(ping); } unlock(exec_ctx, t); } -- cgit v1.2.3 From f88008c00bf94e0337586357a25a91cf746ae9c3 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 10 Dec 2015 10:38:48 -0800 Subject: Fixed a busy-wait in Ruby server run_till_terminated --- src/ruby/lib/grpc/generic/rpc_server.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 0e318bd53b..410156ff03 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -48,6 +48,8 @@ module GRPC return false when 'TERM' return false + when nil + return true end end true -- cgit v1.2.3 From d482e59d3a05edc0797cbc49639ee7a320e82055 Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 10 Dec 2015 14:04:00 -0800 Subject: add a test for secure_channel_create and fix cleanup code --- Makefile | 33 ++++ build.yaml | 10 ++ src/core/surface/secure_channel_create.c | 7 + test/core/surface/secure_channel_create_test.c | 95 +++++++++++ tools/run_tests/sources_and_headers.json | 14 ++ tools/run_tests/tests.json | 18 ++ vsprojects/buildtests_c.sln | 27 +++ .../secure_channel_create_test.vcxproj | 184 +++++++++++++++++++++ .../secure_channel_create_test.vcxproj.filters | 21 +++ 9 files changed, 409 insertions(+) create mode 100644 test/core/surface/secure_channel_create_test.c create mode 100644 vsprojects/vcxproj/test/secure_channel_create_test/secure_channel_create_test.vcxproj create mode 100644 vsprojects/vcxproj/test/secure_channel_create_test/secure_channel_create_test.vcxproj.filters (limited to 'src') diff --git a/Makefile b/Makefile index f30fd1b667..a94ef7172b 100644 --- a/Makefile +++ b/Makefile @@ -847,6 +847,7 @@ multiple_server_queues_test: $(BINDIR)/$(CONFIG)/multiple_server_queues_test murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test no_server_test: $(BINDIR)/$(CONFIG)/no_server_test resolve_address_test: $(BINDIR)/$(CONFIG)/resolve_address_test +secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test secure_endpoint_test: $(BINDIR)/$(CONFIG)/secure_endpoint_test server_chttp2_test: $(BINDIR)/$(CONFIG)/server_chttp2_test set_initial_connect_string_test: $(BINDIR)/$(CONFIG)/set_initial_connect_string_test @@ -1948,6 +1949,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/murmur_hash_test \ $(BINDIR)/$(CONFIG)/no_server_test \ $(BINDIR)/$(CONFIG)/resolve_address_test \ + $(BINDIR)/$(CONFIG)/secure_channel_create_test \ $(BINDIR)/$(CONFIG)/secure_endpoint_test \ $(BINDIR)/$(CONFIG)/server_chttp2_test \ $(BINDIR)/$(CONFIG)/set_initial_connect_string_test \ @@ -2992,6 +2994,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/no_server_test || ( echo test no_server_test failed ; exit 1 ) $(E) "[RUN] Testing resolve_address_test" $(Q) $(BINDIR)/$(CONFIG)/resolve_address_test || ( echo test resolve_address_test failed ; exit 1 ) + $(E) "[RUN] Testing secure_channel_create_test" + $(Q) $(BINDIR)/$(CONFIG)/secure_channel_create_test || ( echo test secure_channel_create_test failed ; exit 1 ) $(E) "[RUN] Testing secure_endpoint_test" $(Q) $(BINDIR)/$(CONFIG)/secure_endpoint_test || ( echo test secure_endpoint_test failed ; exit 1 ) $(E) "[RUN] Testing server_chttp2_test" @@ -11244,6 +11248,35 @@ endif endif +SECURE_CHANNEL_CREATE_TEST_SRC = \ + test/core/surface/secure_channel_create_test.c \ + +SECURE_CHANNEL_CREATE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SECURE_CHANNEL_CREATE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/secure_channel_create_test: openssl_dep_error + +else + +$(BINDIR)/$(CONFIG)/secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(SECURE_CHANNEL_CREATE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/secure_channel_create_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/surface/secure_channel_create_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +deps_secure_channel_create_test: $(SECURE_CHANNEL_CREATE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(SECURE_CHANNEL_CREATE_TEST_OBJS:.o=.dep) +endif +endif + + SECURE_ENDPOINT_TEST_SRC = \ test/core/security/secure_endpoint_test.c \ diff --git a/build.yaml b/build.yaml index a67e7d0e71..843b6668fd 100644 --- a/build.yaml +++ b/build.yaml @@ -1500,6 +1500,16 @@ targets: - grpc - gpr_test_util - gpr +- name: secure_channel_create_test + build: test + language: c + src: + - test/core/surface/secure_channel_create_test.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr - name: secure_endpoint_test build: test language: c diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index c9a54d9237..c0a53e9cc0 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -306,6 +306,13 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds, GRPC_CHANNEL_INTERNAL_REF(channel, "subchannel_factory"); resolver = grpc_resolver_create(target, &f->base); if (!resolver) { + grpc_subchannel_factory_unref(&exec_ctx, &f->base); + GRPC_SECURITY_CONNECTOR_UNREF(&security_connector->base, "channel_create"); + grpc_channel_args_destroy(args_copy); + if (new_args_from_connector != NULL) { + grpc_channel_args_destroy(new_args_from_connector); + } + GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "subchannel_factory"); grpc_exec_ctx_finish(&exec_ctx); return NULL; } diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c new file mode 100644 index 0000000000..f3e5fefaf0 --- /dev/null +++ b/test/core/surface/secure_channel_create_test.c @@ -0,0 +1,95 @@ +/* + * + * 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. + * + */ + +#include + +#include +#include +#include +#include "src/core/client_config/resolver_registry.h" +#include "src/core/security/credentials.h" +#include "src/core/security/security_connector.h" +#include "src/core/surface/channel.h" +#include "test/core/util/test_config.h" + +void test_unknown_scheme_target(void) { + grpc_channel *chan; + grpc_channel_credentials *creds; + grpc_resolver_registry_shutdown(); + grpc_resolver_registry_init(""); + + creds = grpc_fake_transport_security_credentials_create(); + chan = grpc_secure_channel_create(creds, "blah://blah", NULL, NULL); + GPR_ASSERT(chan == NULL); + grpc_channel_credentials_unref(creds); +} + +void test_security_connector_already_in_arg(void) { + grpc_channel *chan; + grpc_channel_element *elem; + grpc_channel_args args; + grpc_arg arg; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + + arg.type = GRPC_ARG_POINTER; + arg.value.pointer.p = NULL; + arg.key = GRPC_SECURITY_CONNECTOR_ARG; + args.num_args = 1; + args.args = &arg; + chan = grpc_secure_channel_create(NULL, NULL, &args, NULL); + elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0); + GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client")); + GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, chan, "test"); + grpc_exec_ctx_finish(&exec_ctx); +} + +void test_null_creds(void) { + grpc_channel *chan; + grpc_channel_element *elem; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + chan = grpc_secure_channel_create(NULL, NULL, NULL, NULL); + elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0); + GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client")); + GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, chan, "test"); + grpc_exec_ctx_finish(&exec_ctx); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + grpc_init(); + test_security_connector_already_in_arg(); + test_null_creds(); + test_unknown_scheme_target(); + grpc_shutdown(); + return 0; +} diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 704131d5be..d8263621c4 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -934,6 +934,20 @@ "test/core/iomgr/resolve_address_test.c" ] }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "language": "c", + "name": "secure_channel_create_test", + "src": [ + "test/core/surface/secure_channel_create_test.c" + ] + }, { "deps": [ "gpr", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 289a13d8c4..fd36a99290 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -1061,6 +1061,24 @@ "windows" ] }, + { + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "secure_channel_create_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "ci_platforms": [ "linux", diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln index 8ca27b0215..b0b41edfab 100644 --- a/vsprojects/buildtests_c.sln +++ b/vsprojects/buildtests_c.sln @@ -1758,6 +1758,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resolve_address_test", "vcx {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "secure_channel_create_test", "vcxproj\test\secure_channel_create_test\secure_channel_create_test.vcxproj", "{62B25398-7173-928E-689E-53860B0ACFC4}" + ProjectSection(myProperties) = preProject + lib = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "secure_endpoint_test", "vcxproj\test\secure_endpoint_test\secure_endpoint_test.vcxproj", "{A7747106-A6BC-62D4-2A21-04A4F0CC2683}" ProjectSection(myProperties) = preProject lib = "False" @@ -12728,6 +12739,22 @@ Global {8279AF6C-9584-67F3-1547-B204864FCCA7}.Release-DLL|Win32.Build.0 = Release|Win32 {8279AF6C-9584-67F3-1547-B204864FCCA7}.Release-DLL|x64.ActiveCfg = Release|x64 {8279AF6C-9584-67F3-1547-B204864FCCA7}.Release-DLL|x64.Build.0 = Release|x64 + {62B25398-7173-928E-689E-53860B0ACFC4}.Debug|Win32.ActiveCfg = Debug|Win32 + {62B25398-7173-928E-689E-53860B0ACFC4}.Debug|x64.ActiveCfg = Debug|x64 + {62B25398-7173-928E-689E-53860B0ACFC4}.Release|Win32.ActiveCfg = Release|Win32 + {62B25398-7173-928E-689E-53860B0ACFC4}.Release|x64.ActiveCfg = Release|x64 + {62B25398-7173-928E-689E-53860B0ACFC4}.Debug|Win32.Build.0 = Debug|Win32 + {62B25398-7173-928E-689E-53860B0ACFC4}.Debug|x64.Build.0 = Debug|x64 + {62B25398-7173-928E-689E-53860B0ACFC4}.Release|Win32.Build.0 = Release|Win32 + {62B25398-7173-928E-689E-53860B0ACFC4}.Release|x64.Build.0 = Release|x64 + {62B25398-7173-928E-689E-53860B0ACFC4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 + {62B25398-7173-928E-689E-53860B0ACFC4}.Debug-DLL|Win32.Build.0 = Debug|Win32 + {62B25398-7173-928E-689E-53860B0ACFC4}.Debug-DLL|x64.ActiveCfg = Debug|x64 + {62B25398-7173-928E-689E-53860B0ACFC4}.Debug-DLL|x64.Build.0 = Debug|x64 + {62B25398-7173-928E-689E-53860B0ACFC4}.Release-DLL|Win32.ActiveCfg = Release|Win32 + {62B25398-7173-928E-689E-53860B0ACFC4}.Release-DLL|Win32.Build.0 = Release|Win32 + {62B25398-7173-928E-689E-53860B0ACFC4}.Release-DLL|x64.ActiveCfg = Release|x64 + {62B25398-7173-928E-689E-53860B0ACFC4}.Release-DLL|x64.Build.0 = Release|x64 {A7747106-A6BC-62D4-2A21-04A4F0CC2683}.Debug|Win32.ActiveCfg = Debug|Win32 {A7747106-A6BC-62D4-2A21-04A4F0CC2683}.Debug|x64.ActiveCfg = Debug|x64 {A7747106-A6BC-62D4-2A21-04A4F0CC2683}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/vsprojects/vcxproj/test/secure_channel_create_test/secure_channel_create_test.vcxproj b/vsprojects/vcxproj/test/secure_channel_create_test/secure_channel_create_test.vcxproj new file mode 100644 index 0000000000..183168ef9d --- /dev/null +++ b/vsprojects/vcxproj/test/secure_channel_create_test/secure_channel_create_test.vcxproj @@ -0,0 +1,184 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {62B25398-7173-928E-689E-53860B0ACFC4} + + + + v100 + + + v110 + + + v120 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + secure_channel_create_test + static + Debug + Debug + + + secure_channel_create_test + static + Debug + Debug + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + + + Console + true + false + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + + + Console + true + false + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions) + true + MultiThreaded + true + None + + + Console + true + false + true + true + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + true + None + + + Console + true + false + true + true + + + + + + + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/secure_channel_create_test/secure_channel_create_test.vcxproj.filters b/vsprojects/vcxproj/test/secure_channel_create_test/secure_channel_create_test.vcxproj.filters new file mode 100644 index 0000000000..3b016bee30 --- /dev/null +++ b/vsprojects/vcxproj/test/secure_channel_create_test/secure_channel_create_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\core\surface + + + + + + {d8e20b8b-50bc-458b-48c2-661874410760} + + + {96fd1a22-522a-1535-4d66-9005d106375f} + + + {4acd30f5-eb6e-f414-9f72-bb4af1ae128c} + + + + -- cgit v1.2.3 From 03f6406b6d908949132f6e3afbdc0b59a12c44fb Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 10 Dec 2015 14:31:54 -0800 Subject: Ensure reserved argument is NULL --- src/core/surface/channel_ping.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/core/surface/channel_ping.c b/src/core/surface/channel_ping.c index f00a52c2c4..1b6f06ded1 100644 --- a/src/core/surface/channel_ping.c +++ b/src/core/surface/channel_ping.c @@ -66,6 +66,7 @@ void grpc_channel_ping(grpc_channel *channel, grpc_completion_queue *cq, grpc_channel_element *top_elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GPR_ASSERT(reserved == NULL); memset(&op, 0, sizeof(op)); pr->tag = tag; pr->cq = cq; -- cgit v1.2.3 From 2908a76181d92afe3df9a8bc890ddc76341eb03b Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 10 Dec 2015 14:48:24 -0800 Subject: Exclude UDP code for now --- src/core/iomgr/udp_server.c | 2 ++ test/core/iomgr/udp_server_test.c | 8 ++++++++ 2 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/core/iomgr/udp_server.c b/src/core/iomgr/udp_server.c index 782fbd9f46..28f1bfae26 100644 --- a/src/core/iomgr/udp_server.c +++ b/src/core/iomgr/udp_server.c @@ -38,6 +38,7 @@ #include +#ifdef GRPC_NEED_UDP #ifdef GPR_POSIX_SOCKET #include "src/core/iomgr/udp_server.h" @@ -435,3 +436,4 @@ void grpc_udp_server_write(server_port *sp, const char *buffer, size_t buf_len, } #endif +#endif diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c index 86e8767937..85e28732e4 100644 --- a/test/core/iomgr/udp_server_test.c +++ b/test/core/iomgr/udp_server_test.c @@ -43,6 +43,8 @@ #include #include +#ifdef GRPC_NEED_UDP + #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x) static grpc_pollset g_pollset; @@ -195,3 +197,9 @@ int main(int argc, char **argv) { grpc_iomgr_shutdown(); return 0; } + +#else + +int main(int argc, char **argv) { return 0; } + +#endif -- cgit v1.2.3 From d47a44d8ad170d78aa675c3aa7d3b2af19f63e3b Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 10 Dec 2015 15:44:25 -0800 Subject: cleanup a bit --- src/core/surface/secure_channel_create.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index c0a53e9cc0..88cddf4316 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -305,29 +305,22 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds, f->master = channel; GRPC_CHANNEL_INTERNAL_REF(channel, "subchannel_factory"); resolver = grpc_resolver_create(target, &f->base); - if (!resolver) { - grpc_subchannel_factory_unref(&exec_ctx, &f->base); - GRPC_SECURITY_CONNECTOR_UNREF(&security_connector->base, "channel_create"); - grpc_channel_args_destroy(args_copy); - if (new_args_from_connector != NULL) { - grpc_channel_args_destroy(new_args_from_connector); - } - GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "subchannel_factory"); - grpc_exec_ctx_finish(&exec_ctx); - return NULL; + if (resolver) { + grpc_client_channel_set_resolver( + &exec_ctx, grpc_channel_get_channel_stack(channel), resolver); + GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create"); } - - grpc_client_channel_set_resolver( - &exec_ctx, grpc_channel_get_channel_stack(channel), resolver); - GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create"); grpc_subchannel_factory_unref(&exec_ctx, &f->base); GRPC_SECURITY_CONNECTOR_UNREF(&security_connector->base, "channel_create"); - grpc_channel_args_destroy(args_copy); if (new_args_from_connector != NULL) { grpc_channel_args_destroy(new_args_from_connector); } + if (!resolver) { + GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "subchannel_factory"); + channel = NULL; + } grpc_exec_ctx_finish(&exec_ctx); return channel; -- cgit v1.2.3 From a6b2c4ce468f06094810252cfa7f136d398ddd9e Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Dec 2015 16:41:11 -0800 Subject: Get rid of SSL_CERT_FILE env entirely --- src/python/grpcio/tests/interop/client.py | 2 +- src/python/grpcio/tests/interop/resources.py | 4 ---- src/python/grpcio/tests/unit/resources.py | 4 ---- src/ruby/bin/apis/pubsub_demo.rb | 12 +----------- src/ruby/ext/grpc/rb_channel_credentials.c | 23 ++++++++++------------- src/ruby/pb/test/client.rb | 10 +--------- tools/run_tests/run_interop_tests.py | 15 +++++---------- 7 files changed, 18 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/python/grpcio/tests/interop/client.py b/src/python/grpcio/tests/interop/client.py index 5c00bce014..573ec2bd71 100644 --- a/src/python/grpcio/tests/interop/client.py +++ b/src/python/grpcio/tests/interop/client.py @@ -90,7 +90,7 @@ def _stub(args): if args.use_test_ca: root_certificates = resources.test_root_certificates() else: - root_certificates = resources.prod_root_certificates() + root_certificates = None # will load default roots. channel = test_utilities.not_really_secure_channel( args.server_host, args.server_port, diff --git a/src/python/grpcio/tests/interop/resources.py b/src/python/grpcio/tests/interop/resources.py index 1122499418..c424385cf6 100644 --- a/src/python/grpcio/tests/interop/resources.py +++ b/src/python/grpcio/tests/interop/resources.py @@ -44,10 +44,6 @@ def test_root_certificates(): __name__, _ROOT_CERTIFICATES_RESOURCE_PATH) -def prod_root_certificates(): - return open(os.environ['SSL_CERT_FILE'], mode='rb').read() - - def private_key(): return pkg_resources.resource_string(__name__, _PRIVATE_KEY_RESOURCE_PATH) diff --git a/src/python/grpcio/tests/unit/resources.py b/src/python/grpcio/tests/unit/resources.py index 2c3045313d..023cdb155f 100644 --- a/src/python/grpcio/tests/unit/resources.py +++ b/src/python/grpcio/tests/unit/resources.py @@ -43,10 +43,6 @@ def test_root_certificates(): __name__, _ROOT_CERTIFICATES_RESOURCE_PATH) -def prod_root_certificates(): - return open(os.environ['SSL_CERT_FILE'], mode='rb').read() - - def private_key(): return pkg_resources.resource_string(__name__, _PRIVATE_KEY_RESOURCE_PATH) diff --git a/src/ruby/bin/apis/pubsub_demo.rb b/src/ruby/bin/apis/pubsub_demo.rb index 003e91a6b3..983be6e823 100755 --- a/src/ruby/bin/apis/pubsub_demo.rb +++ b/src/ruby/bin/apis/pubsub_demo.rb @@ -32,7 +32,6 @@ # pubsub_demo demos accesses the Google PubSub API via its gRPC interface # # $ GOOGLE_APPLICATION_CREDENTIALS= \ -# SSL_CERT_FILE= \ # path/to/pubsub_demo.rb \ # [--action= ] # @@ -55,18 +54,9 @@ require 'google/protobuf/empty' require 'tech/pubsub/proto/pubsub' require 'tech/pubsub/proto/pubsub_services' -# loads the certificates used to access the test server securely. -def load_prod_cert - fail 'could not find a production cert' if ENV['SSL_CERT_FILE'].nil? - p "loading prod certs from #{ENV['SSL_CERT_FILE']}" - File.open(ENV['SSL_CERT_FILE']) do |f| - return f.read - end -end - # creates a SSL Credentials from the production certificates. def ssl_creds - GRPC::Core::ChannelCredentials.new(load_prod_cert) + GRPC::Core::ChannelCredentials.new() end # Builds the metadata authentication update proc. diff --git a/src/ruby/ext/grpc/rb_channel_credentials.c b/src/ruby/ext/grpc/rb_channel_credentials.c index 072a6f54ab..c7f4914997 100644 --- a/src/ruby/ext/grpc/rb_channel_credentials.c +++ b/src/ruby/ext/grpc/rb_channel_credentials.c @@ -148,11 +148,13 @@ static ID id_pem_cert_chain; /* call-seq: - creds1 = Credentials.new(pem_root_certs) + creds1 = Credentials.new() ... - creds2 = Credentials.new(pem_root_certs, pem_private_key, + creds2 = Credentials.new(pem_root_certs) + ... + creds3 = Credentials.new(pem_root_certs, pem_private_key, pem_cert_chain) - pem_root_certs: (required) PEM encoding of the server root certificate + pem_root_certs: (optional) PEM encoding of the server root certificate pem_private_key: (optional) PEM encoding of the client's private key pem_cert_chain: (optional) PEM encoding of the client's cert chain Initializes Credential instances. */ @@ -164,21 +166,16 @@ static VALUE grpc_rb_channel_credentials_init(int argc, VALUE *argv, VALUE self) grpc_channel_credentials *creds = NULL; grpc_ssl_pem_key_cert_pair key_cert_pair; MEMZERO(&key_cert_pair, grpc_ssl_pem_key_cert_pair, 1); - /* TODO: Remove mandatory arg when we support default roots. */ - /* "12" == 1 mandatory arg, 2 (credentials) is optional */ - rb_scan_args(argc, argv, "12", &pem_root_certs, &pem_private_key, + /* "03" == no mandatory arg, 3 optional */ + rb_scan_args(argc, argv, "03", &pem_root_certs, &pem_private_key, &pem_cert_chain); TypedData_Get_Struct(self, grpc_rb_channel_credentials, &grpc_rb_channel_credentials_data_type, wrapper); - if (pem_root_certs == Qnil) { - rb_raise(rb_eRuntimeError, - "could not create a credential: nil pem_root_certs"); - return Qnil; - } if (pem_private_key == Qnil && pem_cert_chain == Qnil) { - creds = - grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), NULL, NULL); + creds = grpc_ssl_credentials_create( + pem_root_certs == Qnil ? NULL : RSTRING_PTR(pem_root_certs), + NULL, NULL); } else { key_cert_pair.private_key = RSTRING_PTR(pem_private_key); key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain); diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index 329e2dc98b..6eb727ccbe 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -93,13 +93,6 @@ def load_test_certs files.map { |f| File.open(File.join(data_dir, f)).read } end -# loads the certificates used to access the test server securely. -def load_prod_cert - fail 'could not find a production cert' if ENV['SSL_CERT_FILE'].nil? - GRPC.logger.info("loading prod certs from #{ENV['SSL_CERT_FILE']}") - File.open(ENV['SSL_CERT_FILE']).read -end - # creates SSL Credentials from the test certificates. def test_creds certs = load_test_certs @@ -108,8 +101,7 @@ end # creates SSL Credentials from the production certificates. def prod_creds - cert_text = load_prod_cert - GRPC::Core::ChannelCredentials.new(cert_text) + GRPC::Core::ChannelCredentials.new() end # creates the SSL Credentials. diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 7a09feb70d..e69e9877c5 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -54,11 +54,6 @@ os.chdir(ROOT) _DEFAULT_SERVER_PORT=8080 -# TOOD(jtattermusch) wrapped languages use this variable for location -# of roots.pem. We might want to use GRPC_DEFAULT_SSL_ROOTS_FILE_PATH -# supported by C core SslCredentials instead. -_SSL_CERT_ENV = { 'SSL_CERT_FILE':'/usr/local/share/grpc/roots.pem' } - _SKIP_COMPRESSION = ['large_compressed_unary', 'server_compressed_streaming'] @@ -105,7 +100,7 @@ class CSharpLanguage: return ['mono', 'Grpc.IntegrationTesting.Client.exe'] + args def cloud_to_prod_env(self): - return _SSL_CERT_ENV + return {} def server_cmd(self, args): return ['mono', 'Grpc.IntegrationTesting.Server.exe', '--use_tls=true'] + args @@ -222,7 +217,7 @@ class NodeLanguage: return ['node', 'src/node/interop/interop_client.js'] + args def cloud_to_prod_env(self): - return _SSL_CERT_ENV + return {} def server_cmd(self, args): return ['node', 'src/node/interop/interop_server.js', '--use_tls=true'] + args @@ -250,7 +245,7 @@ class PHPLanguage: return ['src/php/bin/interop_client.sh'] + args def cloud_to_prod_env(self): - return _SSL_CERT_ENV + return {} def global_env(self): return {} @@ -276,7 +271,7 @@ class RubyLanguage: return ['ruby', 'src/ruby/bin/interop/interop_client.rb'] + args def cloud_to_prod_env(self): - return _SSL_CERT_ENV + return {} def server_cmd(self, args): return ['ruby', 'src/ruby/bin/interop/interop_server.rb', '--use_tls=true'] + args @@ -311,7 +306,7 @@ class PythonLanguage: ] def cloud_to_prod_env(self): - return _SSL_CERT_ENV + return {} def server_cmd(self, args): return [ -- cgit v1.2.3 From 3d45afe8dff2b9dc9a8cbff49cb703e0bd49289d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Dec 2015 18:11:22 -0800 Subject: add coverage for call options --- src/csharp/Grpc.Core.Tests/CallOptionsTest.cs | 88 +++++++++++++++++++++++ src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj | 1 + src/csharp/Grpc.Core/CallOptions.cs | 1 + 3 files changed, 90 insertions(+) create mode 100644 src/csharp/Grpc.Core.Tests/CallOptionsTest.cs (limited to 'src') diff --git a/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs new file mode 100644 index 0000000000..519cebb145 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs @@ -0,0 +1,88 @@ +#region Copyright notice and license + +// 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. + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; + +namespace Grpc.Core.Internal.Tests +{ + public class CallOptionsTest + { + [Test] + public void WithMethods() + { + var options = new CallOptions(); + + var metadata = new Metadata(); + Assert.AreSame(metadata, options.WithHeaders(metadata).Headers); + + var deadline = DateTime.UtcNow; + Assert.AreEqual(deadline, options.WithDeadline(deadline).Deadline.Value); + + var token = new CancellationTokenSource().Token; + Assert.AreEqual(token, options.WithCancellationToken(token).CancellationToken); + + // Change original instance is unchanged. + Assert.IsNull(options.Headers); + Assert.IsNull(options.Deadline); + Assert.AreEqual(CancellationToken.None, options.CancellationToken); + Assert.IsNull(options.WriteOptions); + Assert.IsNull(options.PropagationToken); + Assert.IsNull(options.Credentials); + } + + [Test] + public void Normalize() + { + Assert.AreSame(Metadata.Empty, new CallOptions().Normalize().Headers); + Assert.AreEqual(DateTime.MaxValue, new CallOptions().Normalize().Deadline.Value); + + var deadline = DateTime.UtcNow; + var propagationToken1 = new ContextPropagationToken(CallSafeHandle.NullInstance, deadline, CancellationToken.None, + new ContextPropagationOptions(propagateDeadline: true, propagateCancellation: false)); + Assert.AreEqual(deadline, new CallOptions(propagationToken: propagationToken1).Normalize().Deadline.Value); + Assert.Throws(typeof(ArgumentException), () => new CallOptions(deadline: deadline, propagationToken: propagationToken1).Normalize()); + + var token = new CancellationTokenSource().Token; + var propagationToken2 = new ContextPropagationToken(CallSafeHandle.NullInstance, deadline, token, + new ContextPropagationOptions(propagateDeadline: false, propagateCancellation: true)); + Assert.AreEqual(token, new CallOptions(propagationToken: propagationToken2).Normalize().CancellationToken); + Assert.Throws(typeof(ArgumentException), () => new CallOptions(cancellationToken: token, propagationToken: propagationToken2).Normalize()); + } + } +} diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 70b83f7fb1..a171855ee0 100644 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -64,6 +64,7 @@ Version.cs + diff --git a/src/csharp/Grpc.Core/CallOptions.cs b/src/csharp/Grpc.Core/CallOptions.cs index c0f94c63c2..1fda80cb90 100644 --- a/src/csharp/Grpc.Core/CallOptions.cs +++ b/src/csharp/Grpc.Core/CallOptions.cs @@ -184,6 +184,7 @@ namespace Grpc.Core { Preconditions.CheckArgument(!newOptions.cancellationToken.CanBeCanceled, "Cannot propagate cancellation token from parent call. The cancellation token has already been set to a non-default value."); + newOptions.cancellationToken = propagationToken.ParentCancellationToken; } } -- cgit v1.2.3 From de0d8b534fb4bdc4af4bbff257f62c447cde125c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Dec 2015 18:53:55 -0800 Subject: improve PropagateCancellation test --- src/csharp/Grpc.Core.Tests/CallOptionsTest.cs | 2 +- src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs | 2 +- .../Grpc.Core.Tests/ContextPropagationTest.cs | 32 +++++++++++++++++----- 3 files changed, 27 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs index 519cebb145..a3a613be74 100644 --- a/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs +++ b/src/csharp/Grpc.Core.Tests/CallOptionsTest.cs @@ -39,7 +39,7 @@ using Grpc.Core.Internal; using Grpc.Core.Utils; using NUnit.Framework; -namespace Grpc.Core.Internal.Tests +namespace Grpc.Core.Tests { public class CallOptionsTest { diff --git a/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs b/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs index 52be77c846..d2b5a436fd 100644 --- a/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs +++ b/src/csharp/Grpc.Core.Tests/ChannelOptionsTest.cs @@ -38,7 +38,7 @@ using Grpc.Core.Internal; using Grpc.Core.Utils; using NUnit.Framework; -namespace Grpc.Core.Internal.Tests +namespace Grpc.Core.Tests { public class ChannelOptionsTest { diff --git a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs index 2db3f286f7..90c510ec61 100644 --- a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs +++ b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs @@ -69,11 +69,19 @@ namespace Grpc.Core.Tests [Test] public async Task PropagateCancellation() { + var readyToCancelTcs = new TaskCompletionSource(); + var successTcs = new TaskCompletionSource(); + helper.UnaryHandler = new UnaryServerMethod(async (request, context) => { - // check that we didn't obtain the default cancellation token. - Assert.IsTrue(context.CancellationToken.CanBeCanceled); - return "PASS"; + readyToCancelTcs.SetResult(null); // child call running, ready to parent call + + while (!context.CancellationToken.IsCancellationRequested) + { + await Task.Delay(10); + } + successTcs.SetResult("CHILD_CALL_CANCELLED"); + return ""; }); helper.ClientStreamingHandler = new ClientStreamingServerMethod(async (requestStream, context) => @@ -82,13 +90,23 @@ namespace Grpc.Core.Tests Assert.IsNotNull(propagationToken.ParentCall); var callOptions = new CallOptions(propagationToken: propagationToken); - return await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz"); + try + { + await Calls.AsyncUnaryCall(helper.CreateUnaryCall(callOptions), "xyz"); + } + catch(RpcException) + { + // Child call will get cancelled, eat the exception. + } + return ""; }); var cts = new CancellationTokenSource(); - var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall(new CallOptions(cancellationToken: cts.Token))); - await call.RequestStream.CompleteAsync(); - Assert.AreEqual("PASS", await call); + var parentCall = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall(new CallOptions(cancellationToken: cts.Token))); + await readyToCancelTcs.Task; + cts.Cancel(); + Assert.Throws(typeof(RpcException), async () => await parentCall); + Assert.AreEqual("CHILD_CALL_CANCELLED", await successTcs.Task); } [Test] -- cgit v1.2.3 From 66a653df5eb62339d4f82a3e2046f51bd8701789 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Dec 2015 19:33:36 -0800 Subject: add ClientBase coverage --- .../Grpc.IntegrationTesting.csproj | 1 + .../HeaderInterceptorTest.cs | 113 +++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 src/csharp/Grpc.IntegrationTesting/HeaderInterceptorTest.cs (limited to 'src') diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 012de45524..c48ac71630 100644 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -83,6 +83,7 @@ Version.cs + diff --git a/src/csharp/Grpc.IntegrationTesting/HeaderInterceptorTest.cs b/src/csharp/Grpc.IntegrationTesting/HeaderInterceptorTest.cs new file mode 100644 index 0000000000..1d758b7540 --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/HeaderInterceptorTest.cs @@ -0,0 +1,113 @@ +#region Copyright notice and license + +// 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. + +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Utils; +using Grpc.Testing; +using NUnit.Framework; + +namespace Grpc.IntegrationTesting +{ + public class HeaderInterceptorTest + { + const string Host = "localhost"; + Server server; + Channel channel; + TestService.TestServiceClient client; + + [TestFixtureSetUp] + public void Init() + { + server = new Server + { + Services = { TestService.BindService(new TestServiceImpl()) }, + Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } } + }; + server.Start(); + + channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure); + client = TestService.NewClient(channel); + } + + [TestFixtureTearDown] + public void Cleanup() + { + channel.ShutdownAsync().Wait(); + server.ShutdownAsync().Wait(); + } + + [Test] + public async Task HeaderInterceptor_CreateMetadata() + { + var key = "x-grpc-test-echo-initial"; + client.HeaderInterceptor = new HeaderInterceptor((method, metadata) => + { + metadata.Add(key, "ABC"); + }); + + var call = client.UnaryCallAsync(new SimpleRequest()); + await call; + + var responseHeaders = await call.ResponseHeadersAsync; + Assert.AreEqual("ABC", responseHeaders.First((entry) => entry.Key == key).Value); + } + + [Test] + public async Task HeaderInterceptor_AppendMetadata() + { + var initialKey = "x-grpc-test-echo-initial"; + var trailingKey = "x-grpc-test-echo-trailing-bin"; + + client.HeaderInterceptor = new HeaderInterceptor((method, metadata) => + { + metadata.Add(initialKey, "ABC"); + }); + + var headers = new Metadata + { + { trailingKey, new byte[] {0xaa} } + }; + var call = client.UnaryCallAsync(new SimpleRequest(), headers: headers); + await call; + + var responseHeaders = await call.ResponseHeadersAsync; + Assert.AreEqual("ABC", responseHeaders.First((entry) => entry.Key == initialKey).Value); + CollectionAssert.AreEqual(new byte[] {0xaa}, call.GetTrailers().First((entry) => entry.Key == trailingKey).ValueBytes); + } + } +} -- cgit v1.2.3 From a1e6097d3957fb24a601b89367659ece042c800f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Dec 2015 19:54:10 -0800 Subject: added coverage for Async*StreamingCall classes --- src/csharp/Grpc.Core.Tests/ClientServerTest.cs | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src') diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs index b683751bc0..e3df143fc9 100644 --- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs @@ -32,6 +32,7 @@ #endregion using System; +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; @@ -144,6 +145,48 @@ namespace Grpc.Core.Tests var call = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall()); await call.RequestStream.WriteAllAsync(new string[] { "A", "B", "C" }); Assert.AreEqual("ABC", await call.ResponseAsync); + + Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); + Assert.IsNotNull(call.GetTrailers()); + } + + [Test] + public async Task ServerStreamingCall() + { + helper.ServerStreamingHandler = new ServerStreamingServerMethod(async (request, responseStream, context) => + { + foreach (string response in request.Split(new []{' '})) + { + await responseStream.WriteAsync(response); + } + context.ResponseTrailers.Add("xyz", ""); + }); + + var call = Calls.AsyncServerStreamingCall(helper.CreateServerStreamingCall(), "A B C"); + CollectionAssert.AreEqual(new string[] { "A", "B", "C" }, await call.ResponseStream.ToListAsync()); + + Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); + Assert.IsNotNull("xyz", call.GetTrailers()[0].Key); + } + + [Test] + public async Task DuplexStreamingCall() + { + helper.DuplexStreamingHandler = new DuplexStreamingServerMethod(async (requestStream, responseStream, context) => + { + while (await requestStream.MoveNext()) + { + await responseStream.WriteAsync(requestStream.Current); + } + context.ResponseTrailers.Add("xyz", "xyz-value"); + }); + + var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall()); + await call.RequestStream.WriteAllAsync(new string[] { "A", "B", "C" }); + CollectionAssert.AreEqual(new string[] { "A", "B", "C" }, await call.ResponseStream.ToListAsync()); + + Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode); + Assert.IsNotNull("xyz-value", call.GetTrailers()[0].Value); } [Test] -- cgit v1.2.3 From 00c144a8d219345519fa1ecccca3f7137a86b7d6 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Dec 2015 20:04:01 -0800 Subject: increase coverage of ServerCallContext --- src/csharp/Grpc.Core.Tests/ClientServerTest.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs index e3df143fc9..e324471120 100644 --- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs @@ -262,7 +262,7 @@ namespace Grpc.Core.Tests } [Test] - public void PeerInfoPresent() + public void ServerCallContext_PeerInfoPresent() { helper.UnaryHandler = new UnaryServerMethod(async (request, context) => { @@ -273,6 +273,18 @@ namespace Grpc.Core.Tests Assert.IsTrue(peer.Contains(Host)); } + [Test] + public void ServerCallContext_HostAndMethodPresent() + { + helper.UnaryHandler = new UnaryServerMethod(async (request, context) => + { + Assert.IsTrue(context.Host.Contains(Host)); + Assert.AreEqual("/tests.Test/Unary", context.Method); + return "PASS"; + }); + Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "abc")); + } + [Test] public async Task Channel_WaitForStateChangedAsync() { -- cgit v1.2.3 From 839e1d1324fe6ca01a12a1a049c0206f54d1a508 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Thu, 10 Dec 2015 20:09:34 -0800 Subject: remove dead code from AsyncCallBase --- src/csharp/Grpc.Core/Internal/AsyncCallBase.cs | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src') diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index 953f61aa1e..92f8d77e85 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -238,20 +238,6 @@ namespace Grpc.Core.Internal } } - protected Exception TrySerialize(TWrite msg, out byte[] payload) - { - try - { - payload = serializer(msg); - return null; - } - catch (Exception e) - { - payload = null; - return e; - } - } - protected Exception TryDeserialize(byte[] payload, out TRead msg) { using (Profilers.ForCurrentThread().NewScope("AsyncCallBase.TryDeserialize")) -- cgit v1.2.3 From 0a0237183a6f8dfe4ca0cf320e0c5c4b189cbde7 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 11 Dec 2015 07:35:28 -0800 Subject: Address comments --- src/ruby/ext/grpc/rb_channel_credentials.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/ruby/ext/grpc/rb_channel_credentials.c b/src/ruby/ext/grpc/rb_channel_credentials.c index c7f4914997..5badd4bd7d 100644 --- a/src/ruby/ext/grpc/rb_channel_credentials.c +++ b/src/ruby/ext/grpc/rb_channel_credentials.c @@ -165,6 +165,7 @@ static VALUE grpc_rb_channel_credentials_init(int argc, VALUE *argv, VALUE self) grpc_rb_channel_credentials *wrapper = NULL; grpc_channel_credentials *creds = NULL; grpc_ssl_pem_key_cert_pair key_cert_pair; + const char *pem_root_certs_cstr = NULL; MEMZERO(&key_cert_pair, grpc_ssl_pem_key_cert_pair, 1); /* "03" == no mandatory arg, 3 optional */ rb_scan_args(argc, argv, "03", &pem_root_certs, &pem_private_key, @@ -172,14 +173,15 @@ static VALUE grpc_rb_channel_credentials_init(int argc, VALUE *argv, VALUE self) TypedData_Get_Struct(self, grpc_rb_channel_credentials, &grpc_rb_channel_credentials_data_type, wrapper); + if (pem_root_certs != Qnil) { + pem_root_certs_cstr = RSTRING_PTR(pem_root_certs); + } if (pem_private_key == Qnil && pem_cert_chain == Qnil) { - creds = grpc_ssl_credentials_create( - pem_root_certs == Qnil ? NULL : RSTRING_PTR(pem_root_certs), - NULL, NULL); + creds = grpc_ssl_credentials_create(pem_root_certs_cstr, NULL, NULL); } else { key_cert_pair.private_key = RSTRING_PTR(pem_private_key); key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain); - creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), + creds = grpc_ssl_credentials_create(pem_root_certs_cstr, &key_cert_pair, NULL); } if (creds == NULL) { -- cgit v1.2.3 From f3cfb70a3a87417f8a8568190a33dd8e7eb9c09c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 11 Dec 2015 09:53:39 -0800 Subject: update channel_credentials_spec --- src/ruby/spec/channel_credentials_spec.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/ruby/spec/channel_credentials_spec.rb b/src/ruby/spec/channel_credentials_spec.rb index b2bdf7032e..f25cd78c91 100644 --- a/src/ruby/spec/channel_credentials_spec.rb +++ b/src/ruby/spec/channel_credentials_spec.rb @@ -54,10 +54,15 @@ describe GRPC::Core::ChannelCredentials do expect { ChannelCredentials.new(root_cert) }.not_to raise_error end - it 'cannot be constructed with a nil server roots' do + it 'can be constructed with a nil server roots' do _, client_key, client_chain = load_test_certs blk = proc { ChannelCredentials.new(nil, client_key, client_chain) } - expect(&blk).to raise_error + expect(&blk).not_to raise_error + end + + it 'can be constructed with no params' do + blk = proc { ChannelCredentials.new(nil) } + expect(&blk).not_to raise_error end end end -- cgit v1.2.3