aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/PROTOCOL-HTTP2.md16
-rw-r--r--include/grpc++/alarm.h21
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c45
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c38
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h2
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c2
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c15
-rw-r--r--src/core/ext/filters/http/message_compress/message_compress_filter.c35
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.c2
-rw-r--r--src/core/lib/http/httpcli_security_connector.c10
-rw-r--r--src/core/lib/iomgr/closure.h4
-rw-r--r--src/core/lib/iomgr/ev_epollsig_linux.c5
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.c5
-rw-r--r--src/core/lib/support/time_precise.c2
-rw-r--r--src/core/lib/surface/server.c2
-rw-r--r--src/core/lib/transport/transport.c5
-rw-r--r--src/core/lib/transport/transport.h10
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Control.cs260
-rw-r--r--src/csharp/Grpc.IntegrationTesting/CustomErrorDetailsTest.cs112
-rw-r--r--src/csharp/Grpc.IntegrationTesting/EchoMessages.cs1354
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Services.cs34
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs266
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Stats.cs93
-rwxr-xr-xsrc/csharp/generate_proto_csharp.sh2
-rw-r--r--src/csharp/tests.json1
-rw-r--r--src/objective-c/GRPCClient/private/GRPCWrappedCall.m4
-rw-r--r--test/core/end2end/tests/compressed_payload.c91
-rw-r--r--test/cpp/common/alarm_cpp_test.cc31
-rw-r--r--test/cpp/end2end/client_lb_end2end_test.cc60
-rw-r--r--third_party/cares/cares.BUILD1
-rwxr-xr-xtools/gcp/utils/big_query_utils.py27
-rw-r--r--tools/internal_ci/helper_scripts/prepare_build_macos_rc54
-rwxr-xr-xtools/internal_ci/macos/grpc_build_artifacts.sh27
-rwxr-xr-xtools/internal_ci/macos/grpc_master.sh2
-rwxr-xr-xtools/run_tests/performance/patch_scenario_results_schema.py55
-rw-r--r--tools/run_tests/performance/scenario_result_schema.json20
-rwxr-xr-xtools/run_tests/run_tests.py2
37 files changed, 2494 insertions, 221 deletions
diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md
index 68af1f2ca1..29d3cc2e76 100644
--- a/doc/PROTOCOL-HTTP2.md
+++ b/doc/PROTOCOL-HTTP2.md
@@ -24,7 +24,8 @@ Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames.
* **Call-Definition** → Method Scheme Path TE [Authority] [Timeout] Content-Type [Message-Type] [Message-Encoding] [Message-Accept-Encoding] [User-Agent]
* **Method** → ":method POST"
* **Scheme** → ":scheme " ("http" / "https")
-* **Path** → ":path" {_path identifying method within exposed API_}
+* **Path** → ":path" "/" Service-Name "/" {_method name_}
+* **Service-Name** → {_IDL-specific service name_}
* **Authority** → ":authority" {_virtual host name of authority_}
* **TE** → "te" "trailers" # Used to detect incompatible proxies
* **Timeout** → "grpc-timeout" TimeoutValue TimeoutUnit
@@ -51,6 +52,13 @@ Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames.
HTTP2 requires that reserved headers, ones starting with ":" appear before all other headers. Additionally implementations should send **Timeout** immediately after the reserved headers and they should send the **Call-Definition** headers before sending **Custom-Metadata**.
+Some gRPC implementations may allow the **Path** format shown above
+to be overridden, but this functionality is strongly discouraged.
+gRPC does not go out of its way to break users that are using this kind
+of override, but we do not actively support it, and some functionality
+(e.g., service config support) will not work when the path is not of
+the form shown above.
+
If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements.
**Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Header names starting with "grpc-" but not listed here are reserved for future GRPC use and should not be used by applications as **Custom-Metadata**.
@@ -238,10 +246,10 @@ If a detectable connection failure occurs on the client all calls will be closed
### Appendix A - GRPC for Protobuf
-The service interfaces declared by protobuf are easily mapped onto GRPC by code generation extensions to protoc. The following defines the mapping to be used
-
+The service interfaces declared by protobuf are easily mapped onto GRPC by
+code generation extensions to protoc. The following defines the mapping
+to be used.
-* **Path** → / Service-Name / {_method name_}
* **Service-Name** → ?( {_proto package name_} "." ) {_service name_}
* **Message-Type** → {_fully qualified proto message name_}
* **Content-Type** → "application/grpc+proto"
diff --git a/include/grpc++/alarm.h b/include/grpc++/alarm.h
index bd000cf4f7..ed8dacbc94 100644
--- a/include/grpc++/alarm.h
+++ b/include/grpc++/alarm.h
@@ -52,8 +52,25 @@ class Alarm : private GrpcLibraryCodegen {
alarm_(grpc_alarm_create(cq->cq(), TimePoint<T>(deadline).raw_time(),
static_cast<void*>(&tag_))) {}
+ /// Alarms aren't copyable.
+ Alarm(const Alarm&) = delete;
+ Alarm& operator=(const Alarm&) = delete;
+
+ /// Alarms are movable.
+ Alarm(Alarm&& rhs) : tag_(rhs.tag_), alarm_(rhs.alarm_) {
+ rhs.alarm_ = nullptr;
+ }
+ Alarm& operator=(Alarm&& rhs) {
+ tag_ = rhs.tag_;
+ alarm_ = rhs.alarm_;
+ rhs.alarm_ = nullptr;
+ return *this;
+ }
+
/// Destroy the given completion queue alarm, cancelling it in the process.
- ~Alarm() { grpc_alarm_destroy(alarm_); }
+ ~Alarm() {
+ if (alarm_ != nullptr) grpc_alarm_destroy(alarm_);
+ }
/// Cancel a completion queue alarm. Calling this function over an alarm that
/// has already fired has no effect.
@@ -73,7 +90,7 @@ class Alarm : private GrpcLibraryCodegen {
};
AlarmEntry tag_;
- grpc_alarm* const alarm_; // owned
+ grpc_alarm* alarm_; // owned
};
} // namespace grpc
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
index 307e3bad67..d0acd7a901 100644
--- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c
@@ -95,6 +95,9 @@ static void pf_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
gpr_free(p->subchannels);
gpr_free(p->new_subchannels);
gpr_free(p);
+ if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ gpr_log(GPR_DEBUG, "Pick First %p destroyed.", (void *)p);
+ }
}
static void pf_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
@@ -268,11 +271,20 @@ static void stop_connectivity_watchers(grpc_exec_ctx *exec_ctx,
pick_first_lb_policy *p) {
if (p->num_subchannels > 0) {
GPR_ASSERT(p->selected == NULL);
+ if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ gpr_log(GPR_DEBUG, "Pick First %p unsubscribing from subchannel %p",
+ (void *)p, (void *)p->subchannels[p->checking_subchannel]);
+ }
grpc_subchannel_notify_on_state_change(
exec_ctx, p->subchannels[p->checking_subchannel], NULL, NULL,
&p->connectivity_changed);
p->updating_subchannels = true;
} else if (p->selected != NULL) {
+ if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ gpr_log(GPR_DEBUG,
+ "Pick First %p unsubscribing from selected subchannel %p",
+ (void *)p, (void *)p->selected);
+ }
grpc_connected_subchannel_notify_on_state_change(
exec_ctx, p->selected, NULL, NULL, &p->connectivity_changed);
p->updating_selected = true;
@@ -451,12 +463,25 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
grpc_subchannel *selected_subchannel;
pending_pick *pp;
+ if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ gpr_log(
+ GPR_DEBUG,
+ "Pick First %p connectivity changed. Updating selected: %d; Updating "
+ "subchannels: %d; Checking %lu index (%lu total); State: %d; ",
+ (void *)p, p->updating_selected, p->updating_subchannels,
+ (unsigned long)p->checking_subchannel,
+ (unsigned long)p->num_subchannels, p->checking_connectivity);
+ }
bool restart = false;
- if (p->updating_selected && error == GRPC_ERROR_CANCELLED) {
+ if (p->updating_selected && error != GRPC_ERROR_NONE) {
/* Captured the unsubscription for p->selected */
GPR_ASSERT(p->selected != NULL);
GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, p->selected,
"pf_update_connectivity");
+ if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ gpr_log(GPR_DEBUG, "Pick First %p unreffing selected subchannel %p",
+ (void *)p, (void *)p->selected);
+ }
p->updating_selected = false;
if (p->num_new_subchannels == 0) {
p->selected = NULL;
@@ -464,12 +489,16 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
}
restart = true;
}
- if (p->updating_subchannels && error == GRPC_ERROR_CANCELLED) {
+ if (p->updating_subchannels && error != GRPC_ERROR_NONE) {
/* Captured the unsubscription for the checking subchannel */
GPR_ASSERT(p->selected == NULL);
for (size_t i = 0; i < p->num_subchannels; i++) {
GRPC_SUBCHANNEL_UNREF(exec_ctx, p->subchannels[i],
"pf_update_connectivity");
+ if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ gpr_log(GPR_DEBUG, "Pick First %p unreffing subchannel %p", (void *)p,
+ (void *)p->subchannels[i]);
+ }
}
gpr_free(p->subchannels);
p->subchannels = NULL;
@@ -481,14 +510,12 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
if (restart) {
p->selected = NULL;
p->selected_key = NULL;
-
GPR_ASSERT(p->new_subchannels != NULL);
GPR_ASSERT(p->num_new_subchannels > 0);
p->num_subchannels = p->num_new_subchannels;
p->subchannels = p->new_subchannels;
p->num_new_subchannels = 0;
p->new_subchannels = NULL;
-
if (p->started_picking) {
/* If we were picking, continue to do so over the new subchannels,
* starting from the 0th index. */
@@ -542,7 +569,9 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
"picked_first");
if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
- gpr_log(GPR_INFO, "Selected subchannel %p", (void *)p->selected);
+ gpr_log(GPR_INFO,
+ "Pick First %p selected subchannel %p (connected %p)",
+ (void *)p, (void *)selected_subchannel, (void *)p->selected);
}
p->selected_key = grpc_subchannel_get_key(selected_subchannel);
/* drop the pick list: we are connected now */
@@ -568,7 +597,8 @@ static void pf_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
p->checking_subchannel =
(p->checking_subchannel + 1) % p->num_subchannels;
if (p->checking_subchannel == 0) {
- /* only trigger transient failure when we've tried all alternatives */
+ /* only trigger transient failure when we've tried all alternatives
+ */
grpc_connectivity_state_set(
exec_ctx, &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "connecting_transient_failure");
@@ -652,6 +682,9 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
grpc_lb_policy_args *args) {
GPR_ASSERT(args->client_channel_factory != NULL);
pick_first_lb_policy *p = gpr_zalloc(sizeof(*p));
+ if (GRPC_TRACER_ON(grpc_lb_pick_first_trace)) {
+ gpr_log(GPR_DEBUG, "Pick First %p created.", (void *)p);
+ }
pf_update_locked(exec_ctx, &p->base, args);
grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable, args->combiner);
GRPC_CLOSURE_INIT(&p->connectivity_changed, pf_connectivity_changed_locked, p,
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
index 3c8520cc1c..8e9d6b0f47 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
@@ -126,6 +126,8 @@ struct rr_subchannel_list {
size_t num_ready;
/** how many subchannels are in state TRANSIENT_FAILURE */
size_t num_transient_failures;
+ /** how many subchannels are in state SHUTDOWN */
+ size_t num_shutdown;
/** how many subchannels are in state IDLE */
size_t num_idle;
@@ -425,6 +427,9 @@ static void update_state_counters_locked(subchannel_data *sd) {
} else if (sd->prev_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
GPR_ASSERT(subchannel_list->num_transient_failures > 0);
--subchannel_list->num_transient_failures;
+ } else if (sd->prev_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
+ GPR_ASSERT(subchannel_list->num_shutdown > 0);
+ --subchannel_list->num_shutdown;
} else if (sd->prev_connectivity_state == GRPC_CHANNEL_IDLE) {
GPR_ASSERT(subchannel_list->num_idle > 0);
--subchannel_list->num_idle;
@@ -433,6 +438,8 @@ static void update_state_counters_locked(subchannel_data *sd) {
++subchannel_list->num_ready;
} else if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
++subchannel_list->num_transient_failures;
+ } else if (sd->curr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
+ ++subchannel_list->num_shutdown;
} else if (sd->curr_connectivity_state == GRPC_CHANNEL_IDLE) {
++subchannel_list->num_idle;
}
@@ -455,7 +462,8 @@ static grpc_connectivity_state update_lb_connectivity_status_locked(
* CHECK: sd->curr_connectivity_state == CONNECTING.
*
* 3) RULE: ALL subchannels are SHUTDOWN => policy is SHUTDOWN.
- * CHECK: p->subchannel_list->num_subchannels = 0.
+ * CHECK: p->subchannel_list->num_shutdown ==
+ * p->subchannel_list->num_subchannels.
*
* 4) RULE: ALL subchannels are TRANSIENT_FAILURE => policy is
* TRANSIENT_FAILURE.
@@ -464,37 +472,39 @@ static grpc_connectivity_state update_lb_connectivity_status_locked(
* 5) RULE: ALL subchannels are IDLE => policy is IDLE.
* CHECK: p->num_idle == p->subchannel_list->num_subchannels.
*/
+ grpc_connectivity_state new_state = sd->curr_connectivity_state;
rr_subchannel_list *subchannel_list = sd->subchannel_list;
round_robin_lb_policy *p = subchannel_list->policy;
if (subchannel_list->num_ready > 0) { /* 1) READY */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "rr_ready");
- return GRPC_CHANNEL_READY;
+ new_state = GRPC_CHANNEL_READY;
} else if (sd->curr_connectivity_state ==
GRPC_CHANNEL_CONNECTING) { /* 2) CONNECTING */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
"rr_connecting");
- return GRPC_CHANNEL_CONNECTING;
- } else if (p->subchannel_list->num_subchannels == 0) { /* 3) SHUTDOWN */
+ new_state = GRPC_CHANNEL_CONNECTING;
+ } else if (p->subchannel_list->num_shutdown ==
+ p->subchannel_list->num_subchannels) { /* 3) SHUTDOWN */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_SHUTDOWN, GRPC_ERROR_REF(error),
"rr_shutdown");
- return GRPC_CHANNEL_SHUTDOWN;
+ new_state = GRPC_CHANNEL_SHUTDOWN;
} else if (subchannel_list->num_transient_failures ==
p->subchannel_list->num_subchannels) { /* 4) TRANSIENT_FAILURE */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "rr_transient_failure");
- return GRPC_CHANNEL_TRANSIENT_FAILURE;
+ new_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
} else if (subchannel_list->num_idle ==
p->subchannel_list->num_subchannels) { /* 5) IDLE */
grpc_connectivity_state_set(exec_ctx, &p->state_tracker, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE, "rr_idle");
- return GRPC_CHANNEL_IDLE;
+ new_state = GRPC_CHANNEL_IDLE;
}
- /* no change */
- return sd->curr_connectivity_state;
+ GRPC_ERROR_UNREF(error);
+ return new_state;
}
static void rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
@@ -571,13 +581,15 @@ static void rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
GPR_ASSERT(sd->subchannel_list == p->latest_pending_subchannel_list);
GPR_ASSERT(!sd->subchannel_list->shutting_down);
if (GRPC_TRACER_ON(grpc_lb_round_robin_trace)) {
+ const unsigned long num_subchannels =
+ p->subchannel_list != NULL
+ ? (unsigned long)p->subchannel_list->num_subchannels
+ : 0;
gpr_log(GPR_DEBUG,
"[RR %p] phasing out subchannel list %p (size %lu) in favor "
"of %p (size %lu)",
- (void *)p, (void *)p->subchannel_list,
- (unsigned long)p->subchannel_list->num_subchannels,
- (void *)sd->subchannel_list,
- (unsigned long)sd->subchannel_list->num_subchannels);
+ (void *)p, (void *)p->subchannel_list, num_subchannels,
+ (void *)sd->subchannel_list, num_subchannels);
}
if (p->subchannel_list != NULL) {
// dispose of the current subchannel_list
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
index eb1a8ab011..386012d2ed 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
@@ -19,8 +19,6 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
-#include <ares.h>
-
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/pollset_set.h"
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
index 4e79c44ba3..1ab8295e9e 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c
@@ -19,6 +19,8 @@
#include "src/core/lib/iomgr/port.h"
#if GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET)
+#include <ares.h>
+
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
#include <grpc/support/alloc.h>
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c
index a311334d13..56ed4371a9 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c
@@ -56,6 +56,10 @@ typedef struct {
// grpc_resolver_next_locked()'s closure.
grpc_channel_args* next_results;
+ // Results to use for the pretended re-resolution in
+ // fake_resolver_channel_saw_error_locked().
+ grpc_channel_args* results_upon_error;
+
// pending next completion, or NULL
grpc_closure* next_completion;
// target result address for next completion
@@ -65,6 +69,7 @@ typedef struct {
static void fake_resolver_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
fake_resolver* r = (fake_resolver*)gr;
grpc_channel_args_destroy(exec_ctx, r->next_results);
+ grpc_channel_args_destroy(exec_ctx, r->results_upon_error);
grpc_channel_args_destroy(exec_ctx, r->channel_args);
gpr_free(r);
}
@@ -87,15 +92,19 @@ static void fake_resolver_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
*r->target_result =
grpc_channel_args_union(r->next_results, r->channel_args);
grpc_channel_args_destroy(exec_ctx, r->next_results);
+ r->next_results = NULL;
GRPC_CLOSURE_SCHED(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
r->next_completion = NULL;
- r->next_results = NULL;
}
}
static void fake_resolver_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
grpc_resolver* resolver) {
fake_resolver* r = (fake_resolver*)resolver;
+ if (r->next_results == NULL && r->results_upon_error != NULL) {
+ // Pretend we re-resolved.
+ r->next_results = grpc_channel_args_copy(r->results_upon_error);
+ }
fake_resolver_maybe_finish_next_locked(exec_ctx, r);
}
@@ -151,6 +160,10 @@ static void set_response_cb(grpc_exec_ctx* exec_ctx, void* arg,
grpc_channel_args_destroy(exec_ctx, r->next_results);
}
r->next_results = generator->next_response;
+ if (r->results_upon_error != NULL) {
+ grpc_channel_args_destroy(exec_ctx, r->results_upon_error);
+ }
+ r->results_upon_error = grpc_channel_args_copy(generator->next_response);
fake_resolver_maybe_finish_next_locked(exec_ctx, r);
}
diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.c b/src/core/ext/filters/http/message_compress/message_compress_filter.c
index 04cb1d94f8..71a8bc5bec 100644
--- a/src/core/ext/filters/http/message_compress/message_compress_filter.c
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.c
@@ -255,6 +255,23 @@ static void continue_send_message(grpc_exec_ctx *exec_ctx,
}
}
+static void handle_send_message_batch(grpc_exec_ctx *exec_ctx,
+ grpc_call_element *elem,
+ grpc_transport_stream_op_batch *op,
+ bool has_compression_algorithm) {
+ call_data *calld = elem->call_data;
+ if (!skip_compression(elem, op->payload->send_message.send_message->flags,
+ has_compression_algorithm)) {
+ calld->send_op = op;
+ calld->send_length = op->payload->send_message.send_message->length;
+ calld->send_flags = op->payload->send_message.send_message->flags;
+ continue_send_message(exec_ctx, elem);
+ } else {
+ /* pass control down the stack */
+ grpc_call_next_op(exec_ctx, elem, op);
+ }
+}
+
static void compress_start_transport_stream_op_batch(
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_transport_stream_op_batch *op) {
@@ -307,8 +324,9 @@ static void compress_start_transport_stream_op_batch(
goto retry_send_im;
}
if (cur != INITIAL_METADATA_UNSEEN) {
- grpc_call_next_op(exec_ctx, elem,
- (grpc_transport_stream_op_batch *)cur);
+ handle_send_message_batch(exec_ctx, elem,
+ (grpc_transport_stream_op_batch *)cur,
+ has_compression_algorithm);
}
}
}
@@ -325,17 +343,8 @@ static void compress_start_transport_stream_op_batch(
break;
case HAS_COMPRESSION_ALGORITHM:
case NO_COMPRESSION_ALGORITHM:
- if (!skip_compression(elem,
- op->payload->send_message.send_message->flags,
- cur == HAS_COMPRESSION_ALGORITHM)) {
- calld->send_op = op;
- calld->send_length = op->payload->send_message.send_message->length;
- calld->send_flags = op->payload->send_message.send_message->flags;
- continue_send_message(exec_ctx, elem);
- } else {
- /* pass control down the stack */
- grpc_call_next_op(exec_ctx, elem, op);
- }
+ handle_send_message_batch(exec_ctx, elem, op,
+ cur == HAS_COMPRESSION_ALGORITHM);
break;
default:
if (cur & CANCELLED_BIT) {
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index cd788e9ce3..6e8eadf7a1 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -52,7 +52,7 @@
#define DEFAULT_CONNECTION_WINDOW_TARGET (1024 * 1024)
#define MAX_WINDOW 0x7fffffffu
#define MAX_WRITE_BUFFER_SIZE (64 * 1024 * 1024)
-#define DEFAULT_MAX_HEADER_LIST_SIZE (16 * 1024)
+#define DEFAULT_MAX_HEADER_LIST_SIZE (8 * 1024)
#define DEFAULT_CLIENT_KEEPALIVE_TIME_MS INT_MAX
#define DEFAULT_CLIENT_KEEPALIVE_TIMEOUT_MS 20000 /* 20 seconds */
diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c
index 34a77c3bf4..97c2886525 100644
--- a/src/core/lib/http/httpcli_security_connector.c
+++ b/src/core/lib/http/httpcli_security_connector.c
@@ -25,6 +25,7 @@
#include <grpc/support/string_util.h>
#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/support/string.h"
@@ -157,7 +158,6 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
gpr_timespec deadline,
void (*on_done)(grpc_exec_ctx *exec_ctx, void *arg,
grpc_endpoint *endpoint)) {
- grpc_channel_security_connector *sc = NULL;
on_done_closure *c = gpr_malloc(sizeof(*c));
const char *pem_root_certs = grpc_get_default_ssl_roots();
if (pem_root_certs == NULL) {
@@ -168,11 +168,13 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg,
}
c->func = on_done;
c->arg = arg;
- c->handshake_mgr = grpc_handshake_manager_create();
+ grpc_channel_security_connector *sc = NULL;
GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
exec_ctx, pem_root_certs, host, &sc) == GRPC_SECURITY_OK);
- grpc_channel_security_connector_add_handshakers(exec_ctx, sc,
- c->handshake_mgr);
+ grpc_arg channel_arg = grpc_security_connector_to_arg(&sc->base);
+ grpc_channel_args args = {1, &channel_arg};
+ c->handshake_mgr = grpc_handshake_manager_create();
+ grpc_handshakers_add(exec_ctx, HANDSHAKER_CLIENT, &args, c->handshake_mgr);
grpc_handshake_manager_do_handshake(
exec_ctx, c->handshake_mgr, tcp, NULL /* channel_args */, deadline,
NULL /* acceptor */, on_handshake_done, c /* user_data */);
diff --git a/src/core/lib/iomgr/closure.h b/src/core/lib/iomgr/closure.h
index 2ec6f77e76..2560bf4527 100644
--- a/src/core/lib/iomgr/closure.h
+++ b/src/core/lib/iomgr/closure.h
@@ -42,7 +42,9 @@ typedef struct grpc_closure_list {
*
* \param arg Arbitrary input.
* \param error GRPC_ERROR_NONE if no error occurred, otherwise some grpc_error
- * describing what went wrong */
+ * describing what went wrong.
+ * Error contract: it is not the cb's job to unref this error;
+ * the closure scheduler will do that after the cb returns */
typedef void (*grpc_iomgr_cb_func)(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error);
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.c b/src/core/lib/iomgr/ev_epollsig_linux.c
index 17fef01e6e..255e07010b 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.c
+++ b/src/core/lib/iomgr/ev_epollsig_linux.c
@@ -840,11 +840,6 @@ static grpc_fd *fd_create(int fd, const char *name) {
char *fd_name;
gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
grpc_iomgr_register_object(&new_fd->iomgr_object, fd_name);
-#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
- gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, new_fd, fd_name);
- }
-#endif
gpr_free(fd_name);
return new_fd;
}
diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c
index 1f66159c4a..1f8d7eef26 100644
--- a/src/core/lib/iomgr/ev_poll_posix.c
+++ b/src/core/lib/iomgr/ev_poll_posix.c
@@ -323,11 +323,6 @@ static grpc_fd *fd_create(int fd, const char *name) {
gpr_asprintf(&name2, "%s fd=%d", name, fd);
grpc_iomgr_register_object(&r->iomgr_object, name2);
gpr_free(name2);
-#ifndef NDEBUG
- if (GRPC_TRACER_ON(grpc_trace_fd_refcount)) {
- gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, r, name);
- }
-#endif
return r;
}
diff --git a/src/core/lib/support/time_precise.c b/src/core/lib/support/time_precise.c
index 22971ef6c3..6ce19e53cc 100644
--- a/src/core/lib/support/time_precise.c
+++ b/src/core/lib/support/time_precise.c
@@ -31,7 +31,7 @@ static void gpr_get_cycle_counter(int64_t int *clk) {
// ----------------------------------------------------------------
#elif defined(__x86_64__) || defined(__amd64__)
static void gpr_get_cycle_counter(int64_t *clk) {
- unsigned int64_t low, high;
+ uint64_t low, high;
__asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
*clk = (int64_t)(high << 32) | (int64_t)low;
}
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index 8a2616b027..84ddf74ab9 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -475,6 +475,7 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
*rc->data.registered.deadline = calld->deadline;
if (rc->data.registered.optional_payload) {
*rc->data.registered.optional_payload = calld->payload;
+ calld->payload = NULL;
}
break;
default:
@@ -878,6 +879,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_slice_unref_internal(exec_ctx, calld->path);
}
grpc_metadata_array_destroy(&calld->initial_metadata);
+ grpc_byte_buffer_destroy(calld->payload);
gpr_mu_destroy(&calld->mu_state);
diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c
index 52725846e6..6a9eba110d 100644
--- a/src/core/lib/transport/transport.c
+++ b/src/core/lib/transport/transport.c
@@ -206,6 +206,11 @@ grpc_endpoint *grpc_transport_get_endpoint(grpc_exec_ctx *exec_ctx,
return transport->vtable->get_endpoint(exec_ctx, transport);
}
+// grpc_transport_stream_op_batch_finish_with_failure
+// is a function that must always unref cancel_error
+// though it lives in lib, it handles transport stream ops sure
+// it's grpc_transport_stream_op_batch_finish_with_failure
+
void grpc_transport_stream_op_batch_finish_with_failure(
grpc_exec_ctx *exec_ctx, grpc_transport_stream_op_batch *op,
grpc_error *error) {
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index 2a1a24db20..84e53e683a 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -198,6 +198,8 @@ struct grpc_transport_stream_op_batch_payload {
grpc_chttp2_grpc_status_to_http2_error. Send a RST_STREAM with this
error. */
struct {
+ // Error contract: the transport that gets this op must cause cancel_error
+ // to be unref'ed after processing it
grpc_error *cancel_error;
} cancel_stream;
@@ -212,9 +214,13 @@ typedef struct grpc_transport_op {
/** connectivity monitoring - set connectivity_state to NULL to unsubscribe */
grpc_closure *on_connectivity_state_change;
grpc_connectivity_state *connectivity_state;
- /** should the transport be disconnected */
+ /** should the transport be disconnected
+ * Error contract: the transport that gets this op must cause
+ * disconnect_with_error to be unref'ed after processing it */
grpc_error *disconnect_with_error;
- /** what should the goaway contain? */
+ /** what should the goaway contain?
+ * Error contract: the transport that gets this op must cause
+ * goaway_error to be unref'ed after processing it */
grpc_error *goaway_error;
/** set the callback for accepting new streams;
this is a permanent callback, unlike the other one-shot closures.
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 6c0176fb43..d62b5a1c5b 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -32,7 +32,7 @@ namespace Grpc.Testing {
"U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy",
"X2hvc3Rfb3ZlcnJpZGUYAiABKAkiTQoKQ2hhbm5lbEFyZxIMCgRuYW1lGAEg",
"ASgJEhMKCXN0cl92YWx1ZRgCIAEoCUgAEhMKCWludF92YWx1ZRgDIAEoBUgA",
- "QgcKBXZhbHVlIqAECgxDbGllbnRDb25maWcSFgoOc2VydmVyX3RhcmdldHMY",
+ "QgcKBXZhbHVlItUECgxDbGllbnRDb25maWcSFgoOc2VydmVyX3RhcmdldHMY",
"ASADKAkSLQoLY2xpZW50X3R5cGUYAiABKA4yGC5ncnBjLnRlc3RpbmcuQ2xp",
"ZW50VHlwZRI1Cg9zZWN1cml0eV9wYXJhbXMYAyABKAsyHC5ncnBjLnRlc3Rp",
"bmcuU2VjdXJpdHlQYXJhbXMSJAocb3V0c3RhbmRpbmdfcnBjc19wZXJfY2hh",
@@ -44,52 +44,57 @@ namespace Grpc.Testing {
"cxgMIAEoCzIdLmdycGMudGVzdGluZy5IaXN0b2dyYW1QYXJhbXMSEQoJY29y",
"ZV9saXN0GA0gAygFEhIKCmNvcmVfbGltaXQYDiABKAUSGAoQb3RoZXJfY2xp",
"ZW50X2FwaRgPIAEoCRIuCgxjaGFubmVsX2FyZ3MYECADKAsyGC5ncnBjLnRl",
- "c3RpbmcuQ2hhbm5lbEFyZyI4CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASAB",
- "KAsyGS5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNl",
- "dBgBIAEoCCJoCgpDbGllbnRBcmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50",
- "ZXN0aW5nLkNsaWVudENvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRl",
- "c3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUitAIKDFNlcnZlckNvbmZpZxItCgtz",
- "ZXJ2ZXJfdHlwZRgBIAEoDjIYLmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUK",
- "D3NlY3VyaXR5X3BhcmFtcxgCIAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0",
- "eVBhcmFtcxIMCgRwb3J0GAQgASgFEhwKFGFzeW5jX3NlcnZlcl90aHJlYWRz",
- "GAcgASgFEhIKCmNvcmVfbGltaXQYCCABKAUSMwoOcGF5bG9hZF9jb25maWcY",
- "CSABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxIRCgljb3JlX2xp",
- "c3QYCiADKAUSGAoQb3RoZXJfc2VydmVyX2FwaRgLIAEoCRIcChNyZXNvdXJj",
- "ZV9xdW90YV9zaXplGOkHIAEoBSJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEg",
- "ASgLMhouZ3JwYy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiAB",
- "KAsyEi5ncnBjLnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVy",
- "U3RhdHVzEigKBXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0",
- "YXRzEgwKBHBvcnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVl",
- "c3QiHQoMQ29yZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEK",
- "CFNjZW5hcmlvEgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEo",
- "CzIaLmdycGMudGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMY",
- "AyABKAUSMQoNc2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5T",
- "ZXJ2ZXJDb25maWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3Nl",
- "Y29uZHMYBiABKAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bh",
- "d25fbG9jYWxfd29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglz",
- "Y2VuYXJpb3MYASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8i+AIKFVNj",
- "ZW5hcmlvUmVzdWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9z",
- "ZXJ2ZXJfY29yZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAES",
- "GAoQc2VydmVyX3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3Rp",
- "bWUYBSABKAESGAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5",
- "XzUwGAcgASgBEhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJ",
- "IAEoARISCgpsYXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgB",
- "EhgKEHNlcnZlcl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1",
- "ZXN0c19wZXJfc2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJf",
- "c2Vjb25kGA4gASgBIoMDCg5TY2VuYXJpb1Jlc3VsdBIoCghzY2VuYXJpbxgB",
- "IAEoCzIWLmdycGMudGVzdGluZy5TY2VuYXJpbxIuCglsYXRlbmNpZXMYAiAB",
- "KAsyGy5ncnBjLnRlc3RpbmcuSGlzdG9ncmFtRGF0YRIvCgxjbGllbnRfc3Rh",
- "dHMYAyADKAsyGS5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHMSLwoMc2VydmVy",
- "X3N0YXRzGAQgAygLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRzEhQKDHNl",
- "cnZlcl9jb3JlcxgFIAMoBRI0CgdzdW1tYXJ5GAYgASgLMiMuZ3JwYy50ZXN0",
- "aW5nLlNjZW5hcmlvUmVzdWx0U3VtbWFyeRIWCg5jbGllbnRfc3VjY2VzcxgH",
- "IAMoCBIWCg5zZXJ2ZXJfc3VjY2VzcxgIIAMoCBI5Cg9yZXF1ZXN0X3Jlc3Vs",
- "dHMYCSADKAsyIC5ncnBjLnRlc3RpbmcuUmVxdWVzdFJlc3VsdENvdW50KkEK",
- "CkNsaWVudFR5cGUSDwoLU1lOQ19DTElFTlQQABIQCgxBU1lOQ19DTElFTlQQ",
- "ARIQCgxPVEhFUl9DTElFTlQQAipbCgpTZXJ2ZXJUeXBlEg8KC1NZTkNfU0VS",
- "VkVSEAASEAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZTkNfR0VORVJJQ19TRVJW",
- "RVIQAhIQCgxPVEhFUl9TRVJWRVIQAyojCgdScGNUeXBlEgkKBVVOQVJZEAAS",
- "DQoJU1RSRUFNSU5HEAFiBnByb3RvMw=="));
+ "c3RpbmcuQ2hhbm5lbEFyZxIWCg50aHJlYWRzX3Blcl9jcRgRIAEoBRIbChNt",
+ "ZXNzYWdlc19wZXJfc3RyZWFtGBIgASgFIjgKDENsaWVudFN0YXR1cxIoCgVz",
+ "dGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIVCgRNYXJr",
+ "Eg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAYASABKAsy",
+ "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgCIAEoCzIS",
+ "LmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSLMAgoMU2VydmVyQ29u",
+ "ZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5nLlNlcnZl",
+ "clR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50ZXN0aW5n",
+ "LlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVy",
+ "X3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2Fk",
+ "X2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnEhEK",
+ "CWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsgASgJEhYK",
+ "DnRocmVhZHNfcGVyX2NxGAwgASgFEhwKE3Jlc291cmNlX3F1b3RhX3NpemUY",
+ "6QcgASgFImgKClNlcnZlckFyZ3MSKwoFc2V0dXAYASABKAsyGi5ncnBjLnRl",
+ "c3RpbmcuU2VydmVyQ29uZmlnSAASIgoEbWFyaxgCIAEoCzISLmdycGMudGVz",
+ "dGluZy5NYXJrSABCCQoHYXJndHlwZSJVCgxTZXJ2ZXJTdGF0dXMSKAoFc3Rh",
+ "dHMYASABKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSDAoEcG9ydBgC",
+ "IAEoBRINCgVjb3JlcxgDIAEoBSINCgtDb3JlUmVxdWVzdCIdCgxDb3JlUmVz",
+ "cG9uc2USDQoFY29yZXMYASABKAUiBgoEVm9pZCL9AQoIU2NlbmFyaW8SDAoE",
+ "bmFtZRgBIAEoCRIxCg1jbGllbnRfY29uZmlnGAIgASgLMhouZ3JwYy50ZXN0",
+ "aW5nLkNsaWVudENvbmZpZxITCgtudW1fY2xpZW50cxgDIAEoBRIxCg1zZXJ2",
+ "ZXJfY29uZmlnGAQgASgLMhouZ3JwYy50ZXN0aW5nLlNlcnZlckNvbmZpZxIT",
+ "CgtudW1fc2VydmVycxgFIAEoBRIWCg53YXJtdXBfc2Vjb25kcxgGIAEoBRIZ",
+ "ChFiZW5jaG1hcmtfc2Vjb25kcxgHIAEoBRIgChhzcGF3bl9sb2NhbF93b3Jr",
+ "ZXJfY291bnQYCCABKAUiNgoJU2NlbmFyaW9zEikKCXNjZW5hcmlvcxgBIAMo",
+ "CzIWLmdycGMudGVzdGluZy5TY2VuYXJpbyK8AwoVU2NlbmFyaW9SZXN1bHRT",
+ "dW1tYXJ5EgsKA3FwcxgBIAEoARIbChNxcHNfcGVyX3NlcnZlcl9jb3JlGAIg",
+ "ASgBEhoKEnNlcnZlcl9zeXN0ZW1fdGltZRgDIAEoARIYChBzZXJ2ZXJfdXNl",
+ "cl90aW1lGAQgASgBEhoKEmNsaWVudF9zeXN0ZW1fdGltZRgFIAEoARIYChBj",
+ "bGllbnRfdXNlcl90aW1lGAYgASgBEhIKCmxhdGVuY3lfNTAYByABKAESEgoK",
+ "bGF0ZW5jeV85MBgIIAEoARISCgpsYXRlbmN5Xzk1GAkgASgBEhIKCmxhdGVu",
+ "Y3lfOTkYCiABKAESEwoLbGF0ZW5jeV85OTkYCyABKAESGAoQc2VydmVyX2Nw",
+ "dV91c2FnZRgMIAEoARImCh5zdWNjZXNzZnVsX3JlcXVlc3RzX3Blcl9zZWNv",
+ "bmQYDSABKAESIgoaZmFpbGVkX3JlcXVlc3RzX3Blcl9zZWNvbmQYDiABKAES",
+ "IAoYY2xpZW50X3BvbGxzX3Blcl9yZXF1ZXN0GA8gASgBEiAKGHNlcnZlcl9w",
+ "b2xsc19wZXJfcmVxdWVzdBgQIAEoASKDAwoOU2NlbmFyaW9SZXN1bHQSKAoI",
+ "c2NlbmFyaW8YASABKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8SLgoJbGF0",
+ "ZW5jaWVzGAIgASgLMhsuZ3JwYy50ZXN0aW5nLkhpc3RvZ3JhbURhdGESLwoM",
+ "Y2xpZW50X3N0YXRzGAMgAygLMhkuZ3JwYy50ZXN0aW5nLkNsaWVudFN0YXRz",
+ "Ei8KDHNlcnZlcl9zdGF0cxgEIAMoCzIZLmdycGMudGVzdGluZy5TZXJ2ZXJT",
+ "dGF0cxIUCgxzZXJ2ZXJfY29yZXMYBSADKAUSNAoHc3VtbWFyeRgGIAEoCzIj",
+ "LmdycGMudGVzdGluZy5TY2VuYXJpb1Jlc3VsdFN1bW1hcnkSFgoOY2xpZW50",
+ "X3N1Y2Nlc3MYByADKAgSFgoOc2VydmVyX3N1Y2Nlc3MYCCADKAgSOQoPcmVx",
+ "dWVzdF9yZXN1bHRzGAkgAygLMiAuZ3JwYy50ZXN0aW5nLlJlcXVlc3RSZXN1",
+ "bHRDb3VudCpBCgpDbGllbnRUeXBlEg8KC1NZTkNfQ0xJRU5UEAASEAoMQVNZ",
+ "TkNfQ0xJRU5UEAESEAoMT1RIRVJfQ0xJRU5UEAIqWwoKU2VydmVyVHlwZRIP",
+ "CgtTWU5DX1NFUlZFUhAAEhAKDEFTWU5DX1NFUlZFUhABEhgKFEFTWU5DX0dF",
+ "TkVSSUNfU0VSVkVSEAISEAoMT1RIRVJfU0VSVkVSEAMqcgoHUnBjVHlwZRIJ",
+ "CgVVTkFSWRAAEg0KCVNUUkVBTUlORxABEhkKFVNUUkVBTUlOR19GUk9NX0NM",
+ "SUVOVBACEhkKFVNUUkVBTUlOR19GUk9NX1NFUlZFUhADEhcKE1NUUkVBTUlO",
+ "R19CT1RIX1dBWVMQBGIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] {
@@ -98,11 +103,11 @@ namespace Grpc.Testing {
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson" }, new[]{ "Load" }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ChannelArg), global::Grpc.Testing.ChannelArg.Parser, new[]{ "Name", "StrValue", "IntValue" }, new[]{ "Value" }, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs", "ThreadsPerCq", "MessagesPerStream" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerConfig), global::Grpc.Testing.ServerConfig.Parser, new[]{ "ServerType", "SecurityParams", "Port", "AsyncServerThreads", "CoreLimit", "PayloadConfig", "CoreList", "OtherServerApi", "ResourceQuotaSize" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerConfig), global::Grpc.Testing.ServerConfig.Parser, new[]{ "ServerType", "SecurityParams", "Port", "AsyncServerThreads", "CoreLimit", "PayloadConfig", "CoreList", "OtherServerApi", "ThreadsPerCq", "ResourceQuotaSize" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerArgs), global::Grpc.Testing.ServerArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerStatus), global::Grpc.Testing.ServerStatus.Parser, new[]{ "Stats", "Port", "Cores" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.CoreRequest), global::Grpc.Testing.CoreRequest.Parser, null, null, null, null),
@@ -110,7 +115,7 @@ namespace Grpc.Testing {
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Void), global::Grpc.Testing.Void.Parser, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Scenario), global::Grpc.Testing.Scenario.Parser, new[]{ "Name", "ClientConfig", "NumClients", "ServerConfig", "NumServers", "WarmupSeconds", "BenchmarkSeconds", "SpawnLocalWorkerCount" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Scenarios), global::Grpc.Testing.Scenarios.Parser, new[]{ "Scenarios_" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResultSummary), global::Grpc.Testing.ScenarioResultSummary.Parser, new[]{ "Qps", "QpsPerServerCore", "ServerSystemTime", "ServerUserTime", "ClientSystemTime", "ClientUserTime", "Latency50", "Latency90", "Latency95", "Latency99", "Latency999", "ServerCpuUsage", "SuccessfulRequestsPerSecond", "FailedRequestsPerSecond" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResultSummary), global::Grpc.Testing.ScenarioResultSummary.Parser, new[]{ "Qps", "QpsPerServerCore", "ServerSystemTime", "ServerUserTime", "ClientSystemTime", "ClientUserTime", "Latency50", "Latency90", "Latency95", "Latency99", "Latency999", "ServerCpuUsage", "SuccessfulRequestsPerSecond", "FailedRequestsPerSecond", "ClientPollsPerRequest", "ServerPollsPerRequest" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ScenarioResult), global::Grpc.Testing.ScenarioResult.Parser, new[]{ "Scenario", "Latencies", "ClientStats", "ServerStats", "ServerCores", "Summary", "ClientSuccess", "ServerSuccess", "RequestResults" }, null, null, null)
}));
}
@@ -144,6 +149,9 @@ namespace Grpc.Testing {
public enum RpcType {
[pbr::OriginalName("UNARY")] Unary = 0,
[pbr::OriginalName("STREAMING")] Streaming = 1,
+ [pbr::OriginalName("STREAMING_FROM_CLIENT")] StreamingFromClient = 2,
+ [pbr::OriginalName("STREAMING_FROM_SERVER")] StreamingFromServer = 3,
+ [pbr::OriginalName("STREAMING_BOTH_WAYS")] StreamingBothWays = 4,
}
#endregion
@@ -942,6 +950,8 @@ namespace Grpc.Testing {
coreLimit_ = other.coreLimit_;
otherClientApi_ = other.otherClientApi_;
channelArgs_ = other.channelArgs_.Clone();
+ threadsPerCq_ = other.threadsPerCq_;
+ messagesPerStream_ = other.messagesPerStream_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1123,6 +1133,34 @@ namespace Grpc.Testing {
get { return channelArgs_; }
}
+ /// <summary>Field number for the "threads_per_cq" field.</summary>
+ public const int ThreadsPerCqFieldNumber = 17;
+ private int threadsPerCq_;
+ /// <summary>
+ /// Number of threads that share each completion queue
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int ThreadsPerCq {
+ get { return threadsPerCq_; }
+ set {
+ threadsPerCq_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "messages_per_stream" field.</summary>
+ public const int MessagesPerStreamFieldNumber = 18;
+ private int messagesPerStream_;
+ /// <summary>
+ /// Number of messages on a stream before it gets finished/restarted
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int MessagesPerStream {
+ get { return messagesPerStream_; }
+ set {
+ messagesPerStream_ = value;
+ }
+ }
+
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ClientConfig);
@@ -1150,6 +1188,8 @@ namespace Grpc.Testing {
if (CoreLimit != other.CoreLimit) return false;
if (OtherClientApi != other.OtherClientApi) return false;
if(!channelArgs_.Equals(other.channelArgs_)) return false;
+ if (ThreadsPerCq != other.ThreadsPerCq) return false;
+ if (MessagesPerStream != other.MessagesPerStream) return false;
return true;
}
@@ -1170,6 +1210,8 @@ namespace Grpc.Testing {
if (CoreLimit != 0) hash ^= CoreLimit.GetHashCode();
if (OtherClientApi.Length != 0) hash ^= OtherClientApi.GetHashCode();
hash ^= channelArgs_.GetHashCode();
+ if (ThreadsPerCq != 0) hash ^= ThreadsPerCq.GetHashCode();
+ if (MessagesPerStream != 0) hash ^= MessagesPerStream.GetHashCode();
return hash;
}
@@ -1227,6 +1269,14 @@ namespace Grpc.Testing {
output.WriteString(OtherClientApi);
}
channelArgs_.WriteTo(output, _repeated_channelArgs_codec);
+ if (ThreadsPerCq != 0) {
+ output.WriteRawTag(136, 1);
+ output.WriteInt32(ThreadsPerCq);
+ }
+ if (MessagesPerStream != 0) {
+ output.WriteRawTag(144, 1);
+ output.WriteInt32(MessagesPerStream);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1268,6 +1318,12 @@ namespace Grpc.Testing {
size += 1 + pb::CodedOutputStream.ComputeStringSize(OtherClientApi);
}
size += channelArgs_.CalculateSize(_repeated_channelArgs_codec);
+ if (ThreadsPerCq != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(ThreadsPerCq);
+ }
+ if (MessagesPerStream != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(MessagesPerStream);
+ }
return size;
}
@@ -1324,6 +1380,12 @@ namespace Grpc.Testing {
OtherClientApi = other.OtherClientApi;
}
channelArgs_.Add(other.channelArgs_);
+ if (other.ThreadsPerCq != 0) {
+ ThreadsPerCq = other.ThreadsPerCq;
+ }
+ if (other.MessagesPerStream != 0) {
+ MessagesPerStream = other.MessagesPerStream;
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1403,6 +1465,14 @@ namespace Grpc.Testing {
channelArgs_.AddEntriesFrom(input, _repeated_channelArgs_codec);
break;
}
+ case 136: {
+ ThreadsPerCq = input.ReadInt32();
+ break;
+ }
+ case 144: {
+ MessagesPerStream = input.ReadInt32();
+ break;
+ }
}
}
}
@@ -1873,6 +1943,7 @@ namespace Grpc.Testing {
PayloadConfig = other.payloadConfig_ != null ? other.PayloadConfig.Clone() : null;
coreList_ = other.coreList_.Clone();
otherServerApi_ = other.otherServerApi_;
+ threadsPerCq_ = other.threadsPerCq_;
resourceQuotaSize_ = other.resourceQuotaSize_;
}
@@ -1989,6 +2060,20 @@ namespace Grpc.Testing {
}
}
+ /// <summary>Field number for the "threads_per_cq" field.</summary>
+ public const int ThreadsPerCqFieldNumber = 12;
+ private int threadsPerCq_;
+ /// <summary>
+ /// Number of threads that share each completion queue
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int ThreadsPerCq {
+ get { return threadsPerCq_; }
+ set {
+ threadsPerCq_ = value;
+ }
+ }
+
/// <summary>Field number for the "resource_quota_size" field.</summary>
public const int ResourceQuotaSizeFieldNumber = 1001;
private int resourceQuotaSize_;
@@ -2024,6 +2109,7 @@ namespace Grpc.Testing {
if (!object.Equals(PayloadConfig, other.PayloadConfig)) return false;
if(!coreList_.Equals(other.coreList_)) return false;
if (OtherServerApi != other.OtherServerApi) return false;
+ if (ThreadsPerCq != other.ThreadsPerCq) return false;
if (ResourceQuotaSize != other.ResourceQuotaSize) return false;
return true;
}
@@ -2039,6 +2125,7 @@ namespace Grpc.Testing {
if (payloadConfig_ != null) hash ^= PayloadConfig.GetHashCode();
hash ^= coreList_.GetHashCode();
if (OtherServerApi.Length != 0) hash ^= OtherServerApi.GetHashCode();
+ if (ThreadsPerCq != 0) hash ^= ThreadsPerCq.GetHashCode();
if (ResourceQuotaSize != 0) hash ^= ResourceQuotaSize.GetHashCode();
return hash;
}
@@ -2079,6 +2166,10 @@ namespace Grpc.Testing {
output.WriteRawTag(90);
output.WriteString(OtherServerApi);
}
+ if (ThreadsPerCq != 0) {
+ output.WriteRawTag(96);
+ output.WriteInt32(ThreadsPerCq);
+ }
if (ResourceQuotaSize != 0) {
output.WriteRawTag(200, 62);
output.WriteInt32(ResourceQuotaSize);
@@ -2110,6 +2201,9 @@ namespace Grpc.Testing {
if (OtherServerApi.Length != 0) {
size += 1 + pb::CodedOutputStream.ComputeStringSize(OtherServerApi);
}
+ if (ThreadsPerCq != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(ThreadsPerCq);
+ }
if (ResourceQuotaSize != 0) {
size += 2 + pb::CodedOutputStream.ComputeInt32Size(ResourceQuotaSize);
}
@@ -2149,6 +2243,9 @@ namespace Grpc.Testing {
if (other.OtherServerApi.Length != 0) {
OtherServerApi = other.OtherServerApi;
}
+ if (other.ThreadsPerCq != 0) {
+ ThreadsPerCq = other.ThreadsPerCq;
+ }
if (other.ResourceQuotaSize != 0) {
ResourceQuotaSize = other.ResourceQuotaSize;
}
@@ -2201,6 +2298,10 @@ namespace Grpc.Testing {
OtherServerApi = input.ReadString();
break;
}
+ case 96: {
+ ThreadsPerCq = input.ReadInt32();
+ break;
+ }
case 8008: {
ResourceQuotaSize = input.ReadInt32();
break;
@@ -3386,6 +3487,8 @@ namespace Grpc.Testing {
serverCpuUsage_ = other.serverCpuUsage_;
successfulRequestsPerSecond_ = other.successfulRequestsPerSecond_;
failedRequestsPerSecond_ = other.failedRequestsPerSecond_;
+ clientPollsPerRequest_ = other.clientPollsPerRequest_;
+ serverPollsPerRequest_ = other.serverPollsPerRequest_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3574,6 +3677,31 @@ namespace Grpc.Testing {
}
}
+ /// <summary>Field number for the "client_polls_per_request" field.</summary>
+ public const int ClientPollsPerRequestFieldNumber = 15;
+ private double clientPollsPerRequest_;
+ /// <summary>
+ /// Number of polls called inside completion queue per request
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public double ClientPollsPerRequest {
+ get { return clientPollsPerRequest_; }
+ set {
+ clientPollsPerRequest_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "server_polls_per_request" field.</summary>
+ public const int ServerPollsPerRequestFieldNumber = 16;
+ private double serverPollsPerRequest_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public double ServerPollsPerRequest {
+ get { return serverPollsPerRequest_; }
+ set {
+ serverPollsPerRequest_ = value;
+ }
+ }
+
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ScenarioResultSummary);
@@ -3601,6 +3729,8 @@ namespace Grpc.Testing {
if (ServerCpuUsage != other.ServerCpuUsage) return false;
if (SuccessfulRequestsPerSecond != other.SuccessfulRequestsPerSecond) return false;
if (FailedRequestsPerSecond != other.FailedRequestsPerSecond) return false;
+ if (ClientPollsPerRequest != other.ClientPollsPerRequest) return false;
+ if (ServerPollsPerRequest != other.ServerPollsPerRequest) return false;
return true;
}
@@ -3621,6 +3751,8 @@ namespace Grpc.Testing {
if (ServerCpuUsage != 0D) hash ^= ServerCpuUsage.GetHashCode();
if (SuccessfulRequestsPerSecond != 0D) hash ^= SuccessfulRequestsPerSecond.GetHashCode();
if (FailedRequestsPerSecond != 0D) hash ^= FailedRequestsPerSecond.GetHashCode();
+ if (ClientPollsPerRequest != 0D) hash ^= ClientPollsPerRequest.GetHashCode();
+ if (ServerPollsPerRequest != 0D) hash ^= ServerPollsPerRequest.GetHashCode();
return hash;
}
@@ -3687,6 +3819,14 @@ namespace Grpc.Testing {
output.WriteRawTag(113);
output.WriteDouble(FailedRequestsPerSecond);
}
+ if (ClientPollsPerRequest != 0D) {
+ output.WriteRawTag(121);
+ output.WriteDouble(ClientPollsPerRequest);
+ }
+ if (ServerPollsPerRequest != 0D) {
+ output.WriteRawTag(129, 1);
+ output.WriteDouble(ServerPollsPerRequest);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3734,6 +3874,12 @@ namespace Grpc.Testing {
if (FailedRequestsPerSecond != 0D) {
size += 1 + 8;
}
+ if (ClientPollsPerRequest != 0D) {
+ size += 1 + 8;
+ }
+ if (ServerPollsPerRequest != 0D) {
+ size += 2 + 8;
+ }
return size;
}
@@ -3784,6 +3930,12 @@ namespace Grpc.Testing {
if (other.FailedRequestsPerSecond != 0D) {
FailedRequestsPerSecond = other.FailedRequestsPerSecond;
}
+ if (other.ClientPollsPerRequest != 0D) {
+ ClientPollsPerRequest = other.ClientPollsPerRequest;
+ }
+ if (other.ServerPollsPerRequest != 0D) {
+ ServerPollsPerRequest = other.ServerPollsPerRequest;
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -3850,6 +4002,14 @@ namespace Grpc.Testing {
FailedRequestsPerSecond = input.ReadDouble();
break;
}
+ case 121: {
+ ClientPollsPerRequest = input.ReadDouble();
+ break;
+ }
+ case 129: {
+ ServerPollsPerRequest = input.ReadDouble();
+ break;
+ }
}
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/CustomErrorDetailsTest.cs b/src/csharp/Grpc.IntegrationTesting/CustomErrorDetailsTest.cs
new file mode 100644
index 0000000000..be996f91e0
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/CustomErrorDetailsTest.cs
@@ -0,0 +1,112 @@
+#region Copyright notice and license
+
+// Copyright 2015-2016 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using Grpc.Testing;
+using NUnit.Framework;
+
+namespace Grpc.IntegrationTesting
+{
+ /// <summary>
+ /// Shows how to attach custom error details as a binary trailer.
+ /// </summary>
+ public class CustomErrorDetailsTest
+ {
+ const string DebugInfoTrailerName = "debug-info-bin";
+ const string ExceptionDetail = "Exception thrown on purpose.";
+ const string Host = "localhost";
+ Server server;
+ Channel channel;
+ TestService.TestServiceClient client;
+
+ [TestFixtureSetUp]
+ public void Init()
+ {
+ // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
+ server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
+ {
+ Services = { TestService.BindService(new CustomErrorDetailsTestServiceImpl()) },
+ Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
+ };
+ server.Start();
+
+ channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);
+ client = new TestService.TestServiceClient(channel);
+ }
+
+ [TestFixtureTearDown]
+ public void Cleanup()
+ {
+ channel.ShutdownAsync().Wait();
+ server.ShutdownAsync().Wait();
+ }
+
+ [Test]
+ public async Task UnaryCall()
+ {
+ var call = client.UnaryCallAsync(new SimpleRequest { ResponseSize = 10 });
+
+ try
+ {
+ await call.ResponseAsync;
+ Assert.Fail();
+ }
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode);
+ var debugInfo = GetDebugInfo(call.GetTrailers());
+ Assert.AreEqual(debugInfo.Detail, ExceptionDetail);
+ Assert.IsNotEmpty(debugInfo.StackEntries);
+ }
+ }
+
+ private DebugInfo GetDebugInfo(Metadata trailers)
+ {
+ var entry = trailers.First((e) => e.Key == DebugInfoTrailerName);
+ return DebugInfo.Parser.ParseFrom(entry.ValueBytes);
+ }
+
+ private class CustomErrorDetailsTestServiceImpl : TestService.TestServiceBase
+ {
+ public override async Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
+ {
+ try
+ {
+ throw new ArgumentException(ExceptionDetail);
+ }
+ catch (Exception e)
+ {
+ // Fill debug info with some structured details about the failure.
+ var debugInfo = new DebugInfo();
+ debugInfo.Detail = e.Message;
+ debugInfo.StackEntries.AddRange(e.StackTrace.Split(new[] { Environment.NewLine }, StringSplitOptions.None));
+ context.ResponseTrailers.Add(DebugInfoTrailerName, debugInfo.ToByteArray());
+ throw new RpcException(new Status(StatusCode.Unknown, "The handler threw exception."));
+ }
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs
new file mode 100644
index 0000000000..b2fe73acdf
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/EchoMessages.cs
@@ -0,0 +1,1354 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: src/proto/grpc/testing/echo_messages.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+ /// <summary>Holder for reflection information generated from src/proto/grpc/testing/echo_messages.proto</summary>
+ public static partial class EchoMessagesReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for src/proto/grpc/testing/echo_messages.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static EchoMessagesReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "CipzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL2VjaG9fbWVzc2FnZXMucHJvdG8S",
+ "DGdycGMudGVzdGluZyIyCglEZWJ1Z0luZm8SFQoNc3RhY2tfZW50cmllcxgB",
+ "IAMoCRIOCgZkZXRhaWwYAiABKAkiUAoLRXJyb3JTdGF0dXMSDAoEY29kZRgB",
+ "IAEoBRIVCg1lcnJvcl9tZXNzYWdlGAIgASgJEhwKFGJpbmFyeV9lcnJvcl9k",
+ "ZXRhaWxzGAMgASgJIskDCg1SZXF1ZXN0UGFyYW1zEhUKDWVjaG9fZGVhZGxp",
+ "bmUYASABKAgSHgoWY2xpZW50X2NhbmNlbF9hZnRlcl91cxgCIAEoBRIeChZz",
+ "ZXJ2ZXJfY2FuY2VsX2FmdGVyX3VzGAMgASgFEhUKDWVjaG9fbWV0YWRhdGEY",
+ "BCABKAgSGgoSY2hlY2tfYXV0aF9jb250ZXh0GAUgASgIEh8KF3Jlc3BvbnNl",
+ "X21lc3NhZ2VfbGVuZ3RoGAYgASgFEhEKCWVjaG9fcGVlchgHIAEoCBIgChhl",
+ "eHBlY3RlZF9jbGllbnRfaWRlbnRpdHkYCCABKAkSHAoUc2tpcF9jYW5jZWxs",
+ "ZWRfY2hlY2sYCSABKAgSKAogZXhwZWN0ZWRfdHJhbnNwb3J0X3NlY3VyaXR5",
+ "X3R5cGUYCiABKAkSKwoKZGVidWdfaW5mbxgLIAEoCzIXLmdycGMudGVzdGlu",
+ "Zy5EZWJ1Z0luZm8SEgoKc2VydmVyX2RpZRgMIAEoCBIcChRiaW5hcnlfZXJy",
+ "b3JfZGV0YWlscxgNIAEoCRIxCg5leHBlY3RlZF9lcnJvchgOIAEoCzIZLmdy",
+ "cGMudGVzdGluZy5FcnJvclN0YXR1cyJKCgtFY2hvUmVxdWVzdBIPCgdtZXNz",
+ "YWdlGAEgASgJEioKBXBhcmFtGAIgASgLMhsuZ3JwYy50ZXN0aW5nLlJlcXVl",
+ "c3RQYXJhbXMiRgoOUmVzcG9uc2VQYXJhbXMSGAoQcmVxdWVzdF9kZWFkbGlu",
+ "ZRgBIAEoAxIMCgRob3N0GAIgASgJEgwKBHBlZXIYAyABKAkiTAoMRWNob1Jl",
+ "c3BvbnNlEg8KB21lc3NhZ2UYASABKAkSKwoFcGFyYW0YAiABKAsyHC5ncnBj",
+ "LnRlc3RpbmcuUmVzcG9uc2VQYXJhbXNiBnByb3RvMw=="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.DebugInfo), global::Grpc.Testing.DebugInfo.Parser, new[]{ "StackEntries", "Detail" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ErrorStatus), global::Grpc.Testing.ErrorStatus.Parser, new[]{ "Code", "ErrorMessage", "BinaryErrorDetails" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestParams), global::Grpc.Testing.RequestParams.Parser, new[]{ "EchoDeadline", "ClientCancelAfterUs", "ServerCancelAfterUs", "EchoMetadata", "CheckAuthContext", "ResponseMessageLength", "EchoPeer", "ExpectedClientIdentity", "SkipCancelledCheck", "ExpectedTransportSecurityType", "DebugInfo", "ServerDie", "BinaryErrorDetails", "ExpectedError" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.EchoRequest), global::Grpc.Testing.EchoRequest.Parser, new[]{ "Message", "Param" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ResponseParams), global::Grpc.Testing.ResponseParams.Parser, new[]{ "RequestDeadline", "Host", "Peer" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.EchoResponse), global::Grpc.Testing.EchoResponse.Parser, new[]{ "Message", "Param" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ /// <summary>
+ /// Message to be echoed back serialized in trailer.
+ /// </summary>
+ public sealed partial class DebugInfo : pb::IMessage<DebugInfo> {
+ private static readonly pb::MessageParser<DebugInfo> _parser = new pb::MessageParser<DebugInfo>(() => new DebugInfo());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<DebugInfo> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Testing.EchoMessagesReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public DebugInfo() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public DebugInfo(DebugInfo other) : this() {
+ stackEntries_ = other.stackEntries_.Clone();
+ detail_ = other.detail_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public DebugInfo Clone() {
+ return new DebugInfo(this);
+ }
+
+ /// <summary>Field number for the "stack_entries" field.</summary>
+ public const int StackEntriesFieldNumber = 1;
+ private static readonly pb::FieldCodec<string> _repeated_stackEntries_codec
+ = pb::FieldCodec.ForString(10);
+ private readonly pbc::RepeatedField<string> stackEntries_ = new pbc::RepeatedField<string>();
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public pbc::RepeatedField<string> StackEntries {
+ get { return stackEntries_; }
+ }
+
+ /// <summary>Field number for the "detail" field.</summary>
+ public const int DetailFieldNumber = 2;
+ private string detail_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Detail {
+ get { return detail_; }
+ set {
+ detail_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as DebugInfo);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(DebugInfo other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if(!stackEntries_.Equals(other.stackEntries_)) return false;
+ if (Detail != other.Detail) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ hash ^= stackEntries_.GetHashCode();
+ if (Detail.Length != 0) hash ^= Detail.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ stackEntries_.WriteTo(output, _repeated_stackEntries_codec);
+ if (Detail.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(Detail);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ size += stackEntries_.CalculateSize(_repeated_stackEntries_codec);
+ if (Detail.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Detail);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(DebugInfo other) {
+ if (other == null) {
+ return;
+ }
+ stackEntries_.Add(other.stackEntries_);
+ if (other.Detail.Length != 0) {
+ Detail = other.Detail;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ stackEntries_.AddEntriesFrom(input, _repeated_stackEntries_codec);
+ break;
+ }
+ case 18: {
+ Detail = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// Error status client expects to see.
+ /// </summary>
+ public sealed partial class ErrorStatus : pb::IMessage<ErrorStatus> {
+ private static readonly pb::MessageParser<ErrorStatus> _parser = new pb::MessageParser<ErrorStatus>(() => new ErrorStatus());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ErrorStatus> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Testing.EchoMessagesReflection.Descriptor.MessageTypes[1]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ErrorStatus() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ErrorStatus(ErrorStatus other) : this() {
+ code_ = other.code_;
+ errorMessage_ = other.errorMessage_;
+ binaryErrorDetails_ = other.binaryErrorDetails_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ErrorStatus Clone() {
+ return new ErrorStatus(this);
+ }
+
+ /// <summary>Field number for the "code" field.</summary>
+ public const int CodeFieldNumber = 1;
+ private int code_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int Code {
+ get { return code_; }
+ set {
+ code_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "error_message" field.</summary>
+ public const int ErrorMessageFieldNumber = 2;
+ private string errorMessage_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string ErrorMessage {
+ get { return errorMessage_; }
+ set {
+ errorMessage_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "binary_error_details" field.</summary>
+ public const int BinaryErrorDetailsFieldNumber = 3;
+ private string binaryErrorDetails_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string BinaryErrorDetails {
+ get { return binaryErrorDetails_; }
+ set {
+ binaryErrorDetails_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ErrorStatus);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ErrorStatus other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Code != other.Code) return false;
+ if (ErrorMessage != other.ErrorMessage) return false;
+ if (BinaryErrorDetails != other.BinaryErrorDetails) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Code != 0) hash ^= Code.GetHashCode();
+ if (ErrorMessage.Length != 0) hash ^= ErrorMessage.GetHashCode();
+ if (BinaryErrorDetails.Length != 0) hash ^= BinaryErrorDetails.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Code != 0) {
+ output.WriteRawTag(8);
+ output.WriteInt32(Code);
+ }
+ if (ErrorMessage.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(ErrorMessage);
+ }
+ if (BinaryErrorDetails.Length != 0) {
+ output.WriteRawTag(26);
+ output.WriteString(BinaryErrorDetails);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Code != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(Code);
+ }
+ if (ErrorMessage.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(ErrorMessage);
+ }
+ if (BinaryErrorDetails.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(BinaryErrorDetails);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ErrorStatus other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Code != 0) {
+ Code = other.Code;
+ }
+ if (other.ErrorMessage.Length != 0) {
+ ErrorMessage = other.ErrorMessage;
+ }
+ if (other.BinaryErrorDetails.Length != 0) {
+ BinaryErrorDetails = other.BinaryErrorDetails;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 8: {
+ Code = input.ReadInt32();
+ break;
+ }
+ case 18: {
+ ErrorMessage = input.ReadString();
+ break;
+ }
+ case 26: {
+ BinaryErrorDetails = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ public sealed partial class RequestParams : pb::IMessage<RequestParams> {
+ private static readonly pb::MessageParser<RequestParams> _parser = new pb::MessageParser<RequestParams>(() => new RequestParams());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<RequestParams> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Testing.EchoMessagesReflection.Descriptor.MessageTypes[2]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public RequestParams() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public RequestParams(RequestParams other) : this() {
+ echoDeadline_ = other.echoDeadline_;
+ clientCancelAfterUs_ = other.clientCancelAfterUs_;
+ serverCancelAfterUs_ = other.serverCancelAfterUs_;
+ echoMetadata_ = other.echoMetadata_;
+ checkAuthContext_ = other.checkAuthContext_;
+ responseMessageLength_ = other.responseMessageLength_;
+ echoPeer_ = other.echoPeer_;
+ expectedClientIdentity_ = other.expectedClientIdentity_;
+ skipCancelledCheck_ = other.skipCancelledCheck_;
+ expectedTransportSecurityType_ = other.expectedTransportSecurityType_;
+ DebugInfo = other.debugInfo_ != null ? other.DebugInfo.Clone() : null;
+ serverDie_ = other.serverDie_;
+ binaryErrorDetails_ = other.binaryErrorDetails_;
+ ExpectedError = other.expectedError_ != null ? other.ExpectedError.Clone() : null;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public RequestParams Clone() {
+ return new RequestParams(this);
+ }
+
+ /// <summary>Field number for the "echo_deadline" field.</summary>
+ public const int EchoDeadlineFieldNumber = 1;
+ private bool echoDeadline_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool EchoDeadline {
+ get { return echoDeadline_; }
+ set {
+ echoDeadline_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "client_cancel_after_us" field.</summary>
+ public const int ClientCancelAfterUsFieldNumber = 2;
+ private int clientCancelAfterUs_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int ClientCancelAfterUs {
+ get { return clientCancelAfterUs_; }
+ set {
+ clientCancelAfterUs_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "server_cancel_after_us" field.</summary>
+ public const int ServerCancelAfterUsFieldNumber = 3;
+ private int serverCancelAfterUs_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int ServerCancelAfterUs {
+ get { return serverCancelAfterUs_; }
+ set {
+ serverCancelAfterUs_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "echo_metadata" field.</summary>
+ public const int EchoMetadataFieldNumber = 4;
+ private bool echoMetadata_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool EchoMetadata {
+ get { return echoMetadata_; }
+ set {
+ echoMetadata_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "check_auth_context" field.</summary>
+ public const int CheckAuthContextFieldNumber = 5;
+ private bool checkAuthContext_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool CheckAuthContext {
+ get { return checkAuthContext_; }
+ set {
+ checkAuthContext_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "response_message_length" field.</summary>
+ public const int ResponseMessageLengthFieldNumber = 6;
+ private int responseMessageLength_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int ResponseMessageLength {
+ get { return responseMessageLength_; }
+ set {
+ responseMessageLength_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "echo_peer" field.</summary>
+ public const int EchoPeerFieldNumber = 7;
+ private bool echoPeer_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool EchoPeer {
+ get { return echoPeer_; }
+ set {
+ echoPeer_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "expected_client_identity" field.</summary>
+ public const int ExpectedClientIdentityFieldNumber = 8;
+ private string expectedClientIdentity_ = "";
+ /// <summary>
+ /// will force check_auth_context.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string ExpectedClientIdentity {
+ get { return expectedClientIdentity_; }
+ set {
+ expectedClientIdentity_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "skip_cancelled_check" field.</summary>
+ public const int SkipCancelledCheckFieldNumber = 9;
+ private bool skipCancelledCheck_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool SkipCancelledCheck {
+ get { return skipCancelledCheck_; }
+ set {
+ skipCancelledCheck_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "expected_transport_security_type" field.</summary>
+ public const int ExpectedTransportSecurityTypeFieldNumber = 10;
+ private string expectedTransportSecurityType_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string ExpectedTransportSecurityType {
+ get { return expectedTransportSecurityType_; }
+ set {
+ expectedTransportSecurityType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "debug_info" field.</summary>
+ public const int DebugInfoFieldNumber = 11;
+ private global::Grpc.Testing.DebugInfo debugInfo_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Testing.DebugInfo DebugInfo {
+ get { return debugInfo_; }
+ set {
+ debugInfo_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "server_die" field.</summary>
+ public const int ServerDieFieldNumber = 12;
+ private bool serverDie_;
+ /// <summary>
+ /// Server should not see a request with this set.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool ServerDie {
+ get { return serverDie_; }
+ set {
+ serverDie_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "binary_error_details" field.</summary>
+ public const int BinaryErrorDetailsFieldNumber = 13;
+ private string binaryErrorDetails_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string BinaryErrorDetails {
+ get { return binaryErrorDetails_; }
+ set {
+ binaryErrorDetails_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "expected_error" field.</summary>
+ public const int ExpectedErrorFieldNumber = 14;
+ private global::Grpc.Testing.ErrorStatus expectedError_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Testing.ErrorStatus ExpectedError {
+ get { return expectedError_; }
+ set {
+ expectedError_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as RequestParams);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(RequestParams other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (EchoDeadline != other.EchoDeadline) return false;
+ if (ClientCancelAfterUs != other.ClientCancelAfterUs) return false;
+ if (ServerCancelAfterUs != other.ServerCancelAfterUs) return false;
+ if (EchoMetadata != other.EchoMetadata) return false;
+ if (CheckAuthContext != other.CheckAuthContext) return false;
+ if (ResponseMessageLength != other.ResponseMessageLength) return false;
+ if (EchoPeer != other.EchoPeer) return false;
+ if (ExpectedClientIdentity != other.ExpectedClientIdentity) return false;
+ if (SkipCancelledCheck != other.SkipCancelledCheck) return false;
+ if (ExpectedTransportSecurityType != other.ExpectedTransportSecurityType) return false;
+ if (!object.Equals(DebugInfo, other.DebugInfo)) return false;
+ if (ServerDie != other.ServerDie) return false;
+ if (BinaryErrorDetails != other.BinaryErrorDetails) return false;
+ if (!object.Equals(ExpectedError, other.ExpectedError)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (EchoDeadline != false) hash ^= EchoDeadline.GetHashCode();
+ if (ClientCancelAfterUs != 0) hash ^= ClientCancelAfterUs.GetHashCode();
+ if (ServerCancelAfterUs != 0) hash ^= ServerCancelAfterUs.GetHashCode();
+ if (EchoMetadata != false) hash ^= EchoMetadata.GetHashCode();
+ if (CheckAuthContext != false) hash ^= CheckAuthContext.GetHashCode();
+ if (ResponseMessageLength != 0) hash ^= ResponseMessageLength.GetHashCode();
+ if (EchoPeer != false) hash ^= EchoPeer.GetHashCode();
+ if (ExpectedClientIdentity.Length != 0) hash ^= ExpectedClientIdentity.GetHashCode();
+ if (SkipCancelledCheck != false) hash ^= SkipCancelledCheck.GetHashCode();
+ if (ExpectedTransportSecurityType.Length != 0) hash ^= ExpectedTransportSecurityType.GetHashCode();
+ if (debugInfo_ != null) hash ^= DebugInfo.GetHashCode();
+ if (ServerDie != false) hash ^= ServerDie.GetHashCode();
+ if (BinaryErrorDetails.Length != 0) hash ^= BinaryErrorDetails.GetHashCode();
+ if (expectedError_ != null) hash ^= ExpectedError.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (EchoDeadline != false) {
+ output.WriteRawTag(8);
+ output.WriteBool(EchoDeadline);
+ }
+ if (ClientCancelAfterUs != 0) {
+ output.WriteRawTag(16);
+ output.WriteInt32(ClientCancelAfterUs);
+ }
+ if (ServerCancelAfterUs != 0) {
+ output.WriteRawTag(24);
+ output.WriteInt32(ServerCancelAfterUs);
+ }
+ if (EchoMetadata != false) {
+ output.WriteRawTag(32);
+ output.WriteBool(EchoMetadata);
+ }
+ if (CheckAuthContext != false) {
+ output.WriteRawTag(40);
+ output.WriteBool(CheckAuthContext);
+ }
+ if (ResponseMessageLength != 0) {
+ output.WriteRawTag(48);
+ output.WriteInt32(ResponseMessageLength);
+ }
+ if (EchoPeer != false) {
+ output.WriteRawTag(56);
+ output.WriteBool(EchoPeer);
+ }
+ if (ExpectedClientIdentity.Length != 0) {
+ output.WriteRawTag(66);
+ output.WriteString(ExpectedClientIdentity);
+ }
+ if (SkipCancelledCheck != false) {
+ output.WriteRawTag(72);
+ output.WriteBool(SkipCancelledCheck);
+ }
+ if (ExpectedTransportSecurityType.Length != 0) {
+ output.WriteRawTag(82);
+ output.WriteString(ExpectedTransportSecurityType);
+ }
+ if (debugInfo_ != null) {
+ output.WriteRawTag(90);
+ output.WriteMessage(DebugInfo);
+ }
+ if (ServerDie != false) {
+ output.WriteRawTag(96);
+ output.WriteBool(ServerDie);
+ }
+ if (BinaryErrorDetails.Length != 0) {
+ output.WriteRawTag(106);
+ output.WriteString(BinaryErrorDetails);
+ }
+ if (expectedError_ != null) {
+ output.WriteRawTag(114);
+ output.WriteMessage(ExpectedError);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (EchoDeadline != false) {
+ size += 1 + 1;
+ }
+ if (ClientCancelAfterUs != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(ClientCancelAfterUs);
+ }
+ if (ServerCancelAfterUs != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(ServerCancelAfterUs);
+ }
+ if (EchoMetadata != false) {
+ size += 1 + 1;
+ }
+ if (CheckAuthContext != false) {
+ size += 1 + 1;
+ }
+ if (ResponseMessageLength != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeInt32Size(ResponseMessageLength);
+ }
+ if (EchoPeer != false) {
+ size += 1 + 1;
+ }
+ if (ExpectedClientIdentity.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(ExpectedClientIdentity);
+ }
+ if (SkipCancelledCheck != false) {
+ size += 1 + 1;
+ }
+ if (ExpectedTransportSecurityType.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(ExpectedTransportSecurityType);
+ }
+ if (debugInfo_ != null) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(DebugInfo);
+ }
+ if (ServerDie != false) {
+ size += 1 + 1;
+ }
+ if (BinaryErrorDetails.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(BinaryErrorDetails);
+ }
+ if (expectedError_ != null) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(ExpectedError);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(RequestParams other) {
+ if (other == null) {
+ return;
+ }
+ if (other.EchoDeadline != false) {
+ EchoDeadline = other.EchoDeadline;
+ }
+ if (other.ClientCancelAfterUs != 0) {
+ ClientCancelAfterUs = other.ClientCancelAfterUs;
+ }
+ if (other.ServerCancelAfterUs != 0) {
+ ServerCancelAfterUs = other.ServerCancelAfterUs;
+ }
+ if (other.EchoMetadata != false) {
+ EchoMetadata = other.EchoMetadata;
+ }
+ if (other.CheckAuthContext != false) {
+ CheckAuthContext = other.CheckAuthContext;
+ }
+ if (other.ResponseMessageLength != 0) {
+ ResponseMessageLength = other.ResponseMessageLength;
+ }
+ if (other.EchoPeer != false) {
+ EchoPeer = other.EchoPeer;
+ }
+ if (other.ExpectedClientIdentity.Length != 0) {
+ ExpectedClientIdentity = other.ExpectedClientIdentity;
+ }
+ if (other.SkipCancelledCheck != false) {
+ SkipCancelledCheck = other.SkipCancelledCheck;
+ }
+ if (other.ExpectedTransportSecurityType.Length != 0) {
+ ExpectedTransportSecurityType = other.ExpectedTransportSecurityType;
+ }
+ if (other.debugInfo_ != null) {
+ if (debugInfo_ == null) {
+ debugInfo_ = new global::Grpc.Testing.DebugInfo();
+ }
+ DebugInfo.MergeFrom(other.DebugInfo);
+ }
+ if (other.ServerDie != false) {
+ ServerDie = other.ServerDie;
+ }
+ if (other.BinaryErrorDetails.Length != 0) {
+ BinaryErrorDetails = other.BinaryErrorDetails;
+ }
+ if (other.expectedError_ != null) {
+ if (expectedError_ == null) {
+ expectedError_ = new global::Grpc.Testing.ErrorStatus();
+ }
+ ExpectedError.MergeFrom(other.ExpectedError);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 8: {
+ EchoDeadline = input.ReadBool();
+ break;
+ }
+ case 16: {
+ ClientCancelAfterUs = input.ReadInt32();
+ break;
+ }
+ case 24: {
+ ServerCancelAfterUs = input.ReadInt32();
+ break;
+ }
+ case 32: {
+ EchoMetadata = input.ReadBool();
+ break;
+ }
+ case 40: {
+ CheckAuthContext = input.ReadBool();
+ break;
+ }
+ case 48: {
+ ResponseMessageLength = input.ReadInt32();
+ break;
+ }
+ case 56: {
+ EchoPeer = input.ReadBool();
+ break;
+ }
+ case 66: {
+ ExpectedClientIdentity = input.ReadString();
+ break;
+ }
+ case 72: {
+ SkipCancelledCheck = input.ReadBool();
+ break;
+ }
+ case 82: {
+ ExpectedTransportSecurityType = input.ReadString();
+ break;
+ }
+ case 90: {
+ if (debugInfo_ == null) {
+ debugInfo_ = new global::Grpc.Testing.DebugInfo();
+ }
+ input.ReadMessage(debugInfo_);
+ break;
+ }
+ case 96: {
+ ServerDie = input.ReadBool();
+ break;
+ }
+ case 106: {
+ BinaryErrorDetails = input.ReadString();
+ break;
+ }
+ case 114: {
+ if (expectedError_ == null) {
+ expectedError_ = new global::Grpc.Testing.ErrorStatus();
+ }
+ input.ReadMessage(expectedError_);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ public sealed partial class EchoRequest : pb::IMessage<EchoRequest> {
+ private static readonly pb::MessageParser<EchoRequest> _parser = new pb::MessageParser<EchoRequest>(() => new EchoRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<EchoRequest> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Testing.EchoMessagesReflection.Descriptor.MessageTypes[3]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public EchoRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public EchoRequest(EchoRequest other) : this() {
+ message_ = other.message_;
+ Param = other.param_ != null ? other.Param.Clone() : null;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public EchoRequest Clone() {
+ return new EchoRequest(this);
+ }
+
+ /// <summary>Field number for the "message" field.</summary>
+ public const int MessageFieldNumber = 1;
+ private string message_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Message {
+ get { return message_; }
+ set {
+ message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "param" field.</summary>
+ public const int ParamFieldNumber = 2;
+ private global::Grpc.Testing.RequestParams param_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Testing.RequestParams Param {
+ get { return param_; }
+ set {
+ param_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as EchoRequest);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(EchoRequest other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Message != other.Message) return false;
+ if (!object.Equals(Param, other.Param)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Message.Length != 0) hash ^= Message.GetHashCode();
+ if (param_ != null) hash ^= Param.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Message.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Message);
+ }
+ if (param_ != null) {
+ output.WriteRawTag(18);
+ output.WriteMessage(Param);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Message.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
+ }
+ if (param_ != null) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(Param);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(EchoRequest other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Message.Length != 0) {
+ Message = other.Message;
+ }
+ if (other.param_ != null) {
+ if (param_ == null) {
+ param_ = new global::Grpc.Testing.RequestParams();
+ }
+ Param.MergeFrom(other.Param);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Message = input.ReadString();
+ break;
+ }
+ case 18: {
+ if (param_ == null) {
+ param_ = new global::Grpc.Testing.RequestParams();
+ }
+ input.ReadMessage(param_);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ public sealed partial class ResponseParams : pb::IMessage<ResponseParams> {
+ private static readonly pb::MessageParser<ResponseParams> _parser = new pb::MessageParser<ResponseParams>(() => new ResponseParams());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<ResponseParams> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Testing.EchoMessagesReflection.Descriptor.MessageTypes[4]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ResponseParams() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ResponseParams(ResponseParams other) : this() {
+ requestDeadline_ = other.requestDeadline_;
+ host_ = other.host_;
+ peer_ = other.peer_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ResponseParams Clone() {
+ return new ResponseParams(this);
+ }
+
+ /// <summary>Field number for the "request_deadline" field.</summary>
+ public const int RequestDeadlineFieldNumber = 1;
+ private long requestDeadline_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public long RequestDeadline {
+ get { return requestDeadline_; }
+ set {
+ requestDeadline_ = value;
+ }
+ }
+
+ /// <summary>Field number for the "host" field.</summary>
+ public const int HostFieldNumber = 2;
+ private string host_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Host {
+ get { return host_; }
+ set {
+ host_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "peer" field.</summary>
+ public const int PeerFieldNumber = 3;
+ private string peer_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Peer {
+ get { return peer_; }
+ set {
+ peer_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as ResponseParams);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(ResponseParams other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (RequestDeadline != other.RequestDeadline) return false;
+ if (Host != other.Host) return false;
+ if (Peer != other.Peer) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (RequestDeadline != 0L) hash ^= RequestDeadline.GetHashCode();
+ if (Host.Length != 0) hash ^= Host.GetHashCode();
+ if (Peer.Length != 0) hash ^= Peer.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (RequestDeadline != 0L) {
+ output.WriteRawTag(8);
+ output.WriteInt64(RequestDeadline);
+ }
+ if (Host.Length != 0) {
+ output.WriteRawTag(18);
+ output.WriteString(Host);
+ }
+ if (Peer.Length != 0) {
+ output.WriteRawTag(26);
+ output.WriteString(Peer);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (RequestDeadline != 0L) {
+ size += 1 + pb::CodedOutputStream.ComputeInt64Size(RequestDeadline);
+ }
+ if (Host.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Host);
+ }
+ if (Peer.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Peer);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(ResponseParams other) {
+ if (other == null) {
+ return;
+ }
+ if (other.RequestDeadline != 0L) {
+ RequestDeadline = other.RequestDeadline;
+ }
+ if (other.Host.Length != 0) {
+ Host = other.Host;
+ }
+ if (other.Peer.Length != 0) {
+ Peer = other.Peer;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 8: {
+ RequestDeadline = input.ReadInt64();
+ break;
+ }
+ case 18: {
+ Host = input.ReadString();
+ break;
+ }
+ case 26: {
+ Peer = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ public sealed partial class EchoResponse : pb::IMessage<EchoResponse> {
+ private static readonly pb::MessageParser<EchoResponse> _parser = new pb::MessageParser<EchoResponse>(() => new EchoResponse());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<EchoResponse> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Grpc.Testing.EchoMessagesReflection.Descriptor.MessageTypes[5]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public EchoResponse() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public EchoResponse(EchoResponse other) : this() {
+ message_ = other.message_;
+ Param = other.param_ != null ? other.Param.Clone() : null;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public EchoResponse Clone() {
+ return new EchoResponse(this);
+ }
+
+ /// <summary>Field number for the "message" field.</summary>
+ public const int MessageFieldNumber = 1;
+ private string message_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Message {
+ get { return message_; }
+ set {
+ message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ /// <summary>Field number for the "param" field.</summary>
+ public const int ParamFieldNumber = 2;
+ private global::Grpc.Testing.ResponseParams param_;
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public global::Grpc.Testing.ResponseParams Param {
+ get { return param_; }
+ set {
+ param_ = value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as EchoResponse);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(EchoResponse other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Message != other.Message) return false;
+ if (!object.Equals(Param, other.Param)) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Message.Length != 0) hash ^= Message.GetHashCode();
+ if (param_ != null) hash ^= Param.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Message.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Message);
+ }
+ if (param_ != null) {
+ output.WriteRawTag(18);
+ output.WriteMessage(Param);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Message.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
+ }
+ if (param_ != null) {
+ size += 1 + pb::CodedOutputStream.ComputeMessageSize(Param);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(EchoResponse other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Message.Length != 0) {
+ Message = other.Message;
+ }
+ if (other.param_ != null) {
+ if (param_ == null) {
+ param_ = new global::Grpc.Testing.ResponseParams();
+ }
+ Param.MergeFrom(other.Param);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Message = input.ReadString();
+ break;
+ }
+ case 18: {
+ if (param_ == null) {
+ param_ = new global::Grpc.Testing.ResponseParams();
+ }
+ input.ReadMessage(param_);
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/Services.cs b/src/csharp/Grpc.IntegrationTesting/Services.cs
index bf36a0253b..7a0845dffb 100644
--- a/src/csharp/Grpc.IntegrationTesting/Services.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Services.cs
@@ -24,20 +24,28 @@ namespace Grpc.Testing {
string.Concat(
"CiVzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3NlcnZpY2VzLnByb3RvEgxncnBj",
"LnRlc3RpbmcaJXNyYy9wcm90by9ncnBjL3Rlc3RpbmcvbWVzc2FnZXMucHJv",
- "dG8aJHNyYy9wcm90by9ncnBjL3Rlc3RpbmcvY29udHJvbC5wcm90bzKqAQoQ",
- "QmVuY2htYXJrU2VydmljZRJGCglVbmFyeUNhbGwSGy5ncnBjLnRlc3Rpbmcu",
- "U2ltcGxlUmVxdWVzdBocLmdycGMudGVzdGluZy5TaW1wbGVSZXNwb25zZRJO",
- "Cg1TdHJlYW1pbmdDYWxsEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3Qa",
- "HC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2UoATABMpcCCg1Xb3JrZXJT",
- "ZXJ2aWNlEkUKCVJ1blNlcnZlchIYLmdycGMudGVzdGluZy5TZXJ2ZXJBcmdz",
- "GhouZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXR1cygBMAESRQoJUnVuQ2xpZW50",
- "EhguZ3JwYy50ZXN0aW5nLkNsaWVudEFyZ3MaGi5ncnBjLnRlc3RpbmcuQ2xp",
- "ZW50U3RhdHVzKAEwARJCCglDb3JlQ291bnQSGS5ncnBjLnRlc3RpbmcuQ29y",
- "ZVJlcXVlc3QaGi5ncnBjLnRlc3RpbmcuQ29yZVJlc3BvbnNlEjQKClF1aXRX",
- "b3JrZXISEi5ncnBjLnRlc3RpbmcuVm9pZBoSLmdycGMudGVzdGluZy5Wb2lk",
- "YgZwcm90bzM="));
+ "dG8aJHNyYy9wcm90by9ncnBjL3Rlc3RpbmcvY29udHJvbC5wcm90bxoic3Jj",
+ "L3Byb3RvL2dycGMvdGVzdGluZy9zdGF0cy5wcm90bzKmAwoQQmVuY2htYXJr",
+ "U2VydmljZRJGCglVbmFyeUNhbGwSGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVx",
+ "dWVzdBocLmdycGMudGVzdGluZy5TaW1wbGVSZXNwb25zZRJOCg1TdHJlYW1p",
+ "bmdDYWxsEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3QaHC5ncnBjLnRl",
+ "c3RpbmcuU2ltcGxlUmVzcG9uc2UoATABElIKE1N0cmVhbWluZ0Zyb21DbGll",
+ "bnQSGy5ncnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdycGMudGVzdGlu",
+ "Zy5TaW1wbGVSZXNwb25zZSgBElIKE1N0cmVhbWluZ0Zyb21TZXJ2ZXISGy5n",
+ "cnBjLnRlc3RpbmcuU2ltcGxlUmVxdWVzdBocLmdycGMudGVzdGluZy5TaW1w",
+ "bGVSZXNwb25zZTABElIKEVN0cmVhbWluZ0JvdGhXYXlzEhsuZ3JwYy50ZXN0",
+ "aW5nLlNpbXBsZVJlcXVlc3QaHC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9u",
+ "c2UoATABMpcCCg1Xb3JrZXJTZXJ2aWNlEkUKCVJ1blNlcnZlchIYLmdycGMu",
+ "dGVzdGluZy5TZXJ2ZXJBcmdzGhouZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXR1",
+ "cygBMAESRQoJUnVuQ2xpZW50EhguZ3JwYy50ZXN0aW5nLkNsaWVudEFyZ3Ma",
+ "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50U3RhdHVzKAEwARJCCglDb3JlQ291bnQS",
+ "GS5ncnBjLnRlc3RpbmcuQ29yZVJlcXVlc3QaGi5ncnBjLnRlc3RpbmcuQ29y",
+ "ZVJlc3BvbnNlEjQKClF1aXRXb3JrZXISEi5ncnBjLnRlc3RpbmcuVm9pZBoS",
+ "LmdycGMudGVzdGluZy5Wb2lkMl4KGFJlcG9ydFFwc1NjZW5hcmlvU2Vydmlj",
+ "ZRJCCg5SZXBvcnRTY2VuYXJpbxIcLmdycGMudGVzdGluZy5TY2VuYXJpb1Jl",
+ "c3VsdBoSLmdycGMudGVzdGluZy5Wb2lkYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { global::Grpc.Testing.MessagesReflection.Descriptor, global::Grpc.Testing.ControlReflection.Descriptor, },
+ new pbr::FileDescriptor[] { global::Grpc.Testing.MessagesReflection.Descriptor, global::Grpc.Testing.ControlReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(null, null));
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index 143c9ac9fc..bd5971e296 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -46,6 +46,27 @@ namespace Grpc.Testing {
__Marshaller_SimpleRequest,
__Marshaller_SimpleResponse);
+ static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromClient = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+ grpc::MethodType.ClientStreaming,
+ __ServiceName,
+ "StreamingFromClient",
+ __Marshaller_SimpleRequest,
+ __Marshaller_SimpleResponse);
+
+ static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingFromServer = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+ grpc::MethodType.ServerStreaming,
+ __ServiceName,
+ "StreamingFromServer",
+ __Marshaller_SimpleRequest,
+ __Marshaller_SimpleResponse);
+
+ static readonly grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingBothWays = new grpc::Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+ grpc::MethodType.DuplexStreaming,
+ __ServiceName,
+ "StreamingBothWays",
+ __Marshaller_SimpleRequest,
+ __Marshaller_SimpleResponse);
+
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
{
@@ -68,8 +89,9 @@ namespace Grpc.Testing {
}
/// <summary>
- /// One request followed by one response.
- /// The server returns the client payload as-is.
+ /// Repeated sequence of one request followed by one response.
+ /// Should be called streaming ping-pong
+ /// The server returns the client payload as-is on each response
/// </summary>
/// <param name="requestStream">Used for reading requests from the client.</param>
/// <param name="responseStream">Used for sending responses back to the client.</param>
@@ -80,6 +102,44 @@ namespace Grpc.Testing {
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
+ /// <summary>
+ /// Single-sided unbounded streaming from client to server
+ /// The server returns the client payload as-is once the client does WritesDone
+ /// </summary>
+ /// <param name="requestStream">Used for reading requests from the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>The response to send back to the client (wrapped by a task).</returns>
+ public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ /// <summary>
+ /// Single-sided unbounded streaming from server to client
+ /// The server repeatedly returns the client payload as-is
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="responseStream">Used for sending responses back to the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>A task indicating completion of the handler.</returns>
+ public virtual global::System.Threading.Tasks.Task StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ /// <summary>
+ /// Two-sided unbounded streaming between server to client
+ /// Both sides send the content of their own choice to the other
+ /// </summary>
+ /// <param name="requestStream">Used for reading requests from the client.</param>
+ /// <param name="responseStream">Used for sending responses back to the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>A task indicating completion of the handler.</returns>
+ public virtual global::System.Threading.Tasks.Task StreamingBothWays(grpc::IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, grpc::IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
}
/// <summary>Client for BenchmarkService</summary>
@@ -154,8 +214,9 @@ namespace Grpc.Testing {
return CallInvoker.AsyncUnaryCall(__Method_UnaryCall, null, options, request);
}
/// <summary>
- /// One request followed by one response.
- /// The server returns the client payload as-is.
+ /// Repeated sequence of one request followed by one response.
+ /// Should be called streaming ping-pong
+ /// The server returns the client payload as-is on each response
/// </summary>
/// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
@@ -166,8 +227,9 @@ namespace Grpc.Testing {
return StreamingCall(new grpc::CallOptions(headers, deadline, cancellationToken));
}
/// <summary>
- /// One request followed by one response.
- /// The server returns the client payload as-is.
+ /// Repeated sequence of one request followed by one response.
+ /// Should be called streaming ping-pong
+ /// The server returns the client payload as-is on each response
/// </summary>
/// <param name="options">The options for the call.</param>
/// <returns>The call object.</returns>
@@ -175,6 +237,74 @@ namespace Grpc.Testing {
{
return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingCall, null, options);
}
+ /// <summary>
+ /// Single-sided unbounded streaming from client to server
+ /// The server returns the client payload as-is once the client does WritesDone
+ /// </summary>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return StreamingFromClient(new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Single-sided unbounded streaming from client to server
+ /// The server returns the client payload as-is once the client does WritesDone
+ /// </summary>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncClientStreamingCall(__Method_StreamingFromClient, null, options);
+ }
+ /// <summary>
+ /// Single-sided unbounded streaming from server to client
+ /// The server repeatedly returns the client payload as-is
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return StreamingFromServer(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Single-sided unbounded streaming from server to client
+ /// The server repeatedly returns the client payload as-is
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncServerStreamingCall(__Method_StreamingFromServer, null, options, request);
+ }
+ /// <summary>
+ /// Two-sided unbounded streaming between server to client
+ /// Both sides send the content of their own choice to the other
+ /// </summary>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return StreamingBothWays(new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Two-sided unbounded streaming between server to client
+ /// Both sides send the content of their own choice to the other
+ /// </summary>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncDuplexStreamingCall(__Method_StreamingBothWays, null, options);
+ }
/// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
protected override BenchmarkServiceClient NewInstance(ClientBaseConfiguration configuration)
{
@@ -188,7 +318,10 @@ namespace Grpc.Testing {
{
return grpc::ServerServiceDefinition.CreateBuilder()
.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
- .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
+ .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall)
+ .AddMethod(__Method_StreamingFromClient, serviceImpl.StreamingFromClient)
+ .AddMethod(__Method_StreamingFromServer, serviceImpl.StreamingFromServer)
+ .AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build();
}
}
@@ -489,5 +622,124 @@ namespace Grpc.Testing {
}
}
+ public static partial class ReportQpsScenarioService
+ {
+ static readonly string __ServiceName = "grpc.testing.ReportQpsScenarioService";
+
+ static readonly grpc::Marshaller<global::Grpc.Testing.ScenarioResult> __Marshaller_ScenarioResult = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ScenarioResult.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Grpc.Testing.Void> __Marshaller_Void = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.Void.Parser.ParseFrom);
+
+ static readonly grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void> __Method_ReportScenario = new grpc::Method<global::Grpc.Testing.ScenarioResult, global::Grpc.Testing.Void>(
+ grpc::MethodType.Unary,
+ __ServiceName,
+ "ReportScenario",
+ __Marshaller_ScenarioResult,
+ __Marshaller_Void);
+
+ /// <summary>Service descriptor</summary>
+ public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+ {
+ get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[2]; }
+ }
+
+ /// <summary>Base class for server-side implementations of ReportQpsScenarioService</summary>
+ public abstract partial class ReportQpsScenarioServiceBase
+ {
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>The response to send back to the client (wrapped by a task).</returns>
+ public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ }
+
+ /// <summary>Client for ReportQpsScenarioService</summary>
+ public partial class ReportQpsScenarioServiceClient : grpc::ClientBase<ReportQpsScenarioServiceClient>
+ {
+ /// <summary>Creates a new client for ReportQpsScenarioService</summary>
+ /// <param name="channel">The channel to use to make remote calls.</param>
+ public ReportQpsScenarioServiceClient(grpc::Channel channel) : base(channel)
+ {
+ }
+ /// <summary>Creates a new client for ReportQpsScenarioService that uses a custom <c>CallInvoker</c>.</summary>
+ /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+ public ReportQpsScenarioServiceClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected ReportQpsScenarioServiceClient() : base()
+ {
+ }
+ /// <summary>Protected constructor to allow creation of configured clients.</summary>
+ /// <param name="configuration">The client configuration.</param>
+ protected ReportQpsScenarioServiceClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return ReportScenario(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The response received from the server.</returns>
+ public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
+ {
+ return CallInvoker.BlockingUnaryCall(__Method_ReportScenario, null, options, request);
+ }
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return ReportScenarioAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Report results of a QPS test benchmark scenario.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_ReportScenario, null, options, request);
+ }
+ /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+ protected override ReportQpsScenarioServiceClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new ReportQpsScenarioServiceClient(configuration);
+ }
+ }
+
+ /// <summary>Creates service definition that can be registered with a server</summary>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static grpc::ServerServiceDefinition BindService(ReportQpsScenarioServiceBase serviceImpl)
+ {
+ return grpc::ServerServiceDefinition.CreateBuilder()
+ .AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build();
+ }
+
+ }
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs
index 79ff220436..23b56df6bd 100644
--- a/src/csharp/Grpc.IntegrationTesting/Stats.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs
@@ -23,27 +23,28 @@ namespace Grpc.Testing {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CiJzcmMvcHJvdG8vZ3JwYy90ZXN0aW5nL3N0YXRzLnByb3RvEgxncnBjLnRl",
- "c3RpbmciegoLU2VydmVyU3RhdHMSFAoMdGltZV9lbGFwc2VkGAEgASgBEhEK",
- "CXRpbWVfdXNlchgCIAEoARITCgt0aW1lX3N5c3RlbRgDIAEoARIWCg50b3Rh",
- "bF9jcHVfdGltZRgEIAEoBBIVCg1pZGxlX2NwdV90aW1lGAUgASgEIjsKD0hp",
- "c3RvZ3JhbVBhcmFtcxISCgpyZXNvbHV0aW9uGAEgASgBEhQKDG1heF9wb3Nz",
- "aWJsZRgCIAEoASJ3Cg1IaXN0b2dyYW1EYXRhEg4KBmJ1Y2tldBgBIAMoDRIQ",
- "CghtaW5fc2VlbhgCIAEoARIQCghtYXhfc2VlbhgDIAEoARILCgNzdW0YBCAB",
- "KAESFgoOc3VtX29mX3NxdWFyZXMYBSABKAESDQoFY291bnQYBiABKAEiOAoS",
- "UmVxdWVzdFJlc3VsdENvdW50EhMKC3N0YXR1c19jb2RlGAEgASgFEg0KBWNv",
- "dW50GAIgASgDIrYBCgtDbGllbnRTdGF0cxIuCglsYXRlbmNpZXMYASABKAsy",
- "Gy5ncnBjLnRlc3RpbmcuSGlzdG9ncmFtRGF0YRIUCgx0aW1lX2VsYXBzZWQY",
- "AiABKAESEQoJdGltZV91c2VyGAMgASgBEhMKC3RpbWVfc3lzdGVtGAQgASgB",
- "EjkKD3JlcXVlc3RfcmVzdWx0cxgFIAMoCzIgLmdycGMudGVzdGluZy5SZXF1",
- "ZXN0UmVzdWx0Q291bnRiBnByb3RvMw=="));
+ "c3RpbmcikQEKC1NlcnZlclN0YXRzEhQKDHRpbWVfZWxhcHNlZBgBIAEoARIR",
+ "Cgl0aW1lX3VzZXIYAiABKAESEwoLdGltZV9zeXN0ZW0YAyABKAESFgoOdG90",
+ "YWxfY3B1X3RpbWUYBCABKAQSFQoNaWRsZV9jcHVfdGltZRgFIAEoBBIVCg1j",
+ "cV9wb2xsX2NvdW50GAYgASgEIjsKD0hpc3RvZ3JhbVBhcmFtcxISCgpyZXNv",
+ "bHV0aW9uGAEgASgBEhQKDG1heF9wb3NzaWJsZRgCIAEoASJ3Cg1IaXN0b2dy",
+ "YW1EYXRhEg4KBmJ1Y2tldBgBIAMoDRIQCghtaW5fc2VlbhgCIAEoARIQCght",
+ "YXhfc2VlbhgDIAEoARILCgNzdW0YBCABKAESFgoOc3VtX29mX3NxdWFyZXMY",
+ "BSABKAESDQoFY291bnQYBiABKAEiOAoSUmVxdWVzdFJlc3VsdENvdW50EhMK",
+ "C3N0YXR1c19jb2RlGAEgASgFEg0KBWNvdW50GAIgASgDIs0BCgtDbGllbnRT",
+ "dGF0cxIuCglsYXRlbmNpZXMYASABKAsyGy5ncnBjLnRlc3RpbmcuSGlzdG9n",
+ "cmFtRGF0YRIUCgx0aW1lX2VsYXBzZWQYAiABKAESEQoJdGltZV91c2VyGAMg",
+ "ASgBEhMKC3RpbWVfc3lzdGVtGAQgASgBEjkKD3JlcXVlc3RfcmVzdWx0cxgF",
+ "IAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQSFQoNY3Ff",
+ "cG9sbF9jb3VudBgGIAEoBGIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerStats), global::Grpc.Testing.ServerStats.Parser, new[]{ "TimeElapsed", "TimeUser", "TimeSystem", "TotalCpuTime", "IdleCpuTime" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ServerStats), global::Grpc.Testing.ServerStats.Parser, new[]{ "TimeElapsed", "TimeUser", "TimeSystem", "TotalCpuTime", "IdleCpuTime", "CqPollCount" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.HistogramParams), global::Grpc.Testing.HistogramParams.Parser, new[]{ "Resolution", "MaxPossible" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.HistogramData), global::Grpc.Testing.HistogramData.Parser, new[]{ "Bucket", "MinSeen", "MaxSeen", "Sum", "SumOfSquares", "Count" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.RequestResultCount), global::Grpc.Testing.RequestResultCount.Parser, new[]{ "StatusCode", "Count" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStats), global::Grpc.Testing.ClientStats.Parser, new[]{ "Latencies", "TimeElapsed", "TimeUser", "TimeSystem", "RequestResults" }, null, null, null)
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStats), global::Grpc.Testing.ClientStats.Parser, new[]{ "Latencies", "TimeElapsed", "TimeUser", "TimeSystem", "RequestResults", "CqPollCount" }, null, null, null)
}));
}
#endregion
@@ -79,6 +80,7 @@ namespace Grpc.Testing {
timeSystem_ = other.timeSystem_;
totalCpuTime_ = other.totalCpuTime_;
idleCpuTime_ = other.idleCpuTime_;
+ cqPollCount_ = other.cqPollCount_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -157,6 +159,20 @@ namespace Grpc.Testing {
}
}
+ /// <summary>Field number for the "cq_poll_count" field.</summary>
+ public const int CqPollCountFieldNumber = 6;
+ private ulong cqPollCount_;
+ /// <summary>
+ /// Number of polls called inside completion queue
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ulong CqPollCount {
+ get { return cqPollCount_; }
+ set {
+ cqPollCount_ = value;
+ }
+ }
+
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ServerStats);
@@ -175,6 +191,7 @@ namespace Grpc.Testing {
if (TimeSystem != other.TimeSystem) return false;
if (TotalCpuTime != other.TotalCpuTime) return false;
if (IdleCpuTime != other.IdleCpuTime) return false;
+ if (CqPollCount != other.CqPollCount) return false;
return true;
}
@@ -186,6 +203,7 @@ namespace Grpc.Testing {
if (TimeSystem != 0D) hash ^= TimeSystem.GetHashCode();
if (TotalCpuTime != 0UL) hash ^= TotalCpuTime.GetHashCode();
if (IdleCpuTime != 0UL) hash ^= IdleCpuTime.GetHashCode();
+ if (CqPollCount != 0UL) hash ^= CqPollCount.GetHashCode();
return hash;
}
@@ -216,6 +234,10 @@ namespace Grpc.Testing {
output.WriteRawTag(40);
output.WriteUInt64(IdleCpuTime);
}
+ if (CqPollCount != 0UL) {
+ output.WriteRawTag(48);
+ output.WriteUInt64(CqPollCount);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -236,6 +258,9 @@ namespace Grpc.Testing {
if (IdleCpuTime != 0UL) {
size += 1 + pb::CodedOutputStream.ComputeUInt64Size(IdleCpuTime);
}
+ if (CqPollCount != 0UL) {
+ size += 1 + pb::CodedOutputStream.ComputeUInt64Size(CqPollCount);
+ }
return size;
}
@@ -259,6 +284,9 @@ namespace Grpc.Testing {
if (other.IdleCpuTime != 0UL) {
IdleCpuTime = other.IdleCpuTime;
}
+ if (other.CqPollCount != 0UL) {
+ CqPollCount = other.CqPollCount;
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -289,6 +317,10 @@ namespace Grpc.Testing {
IdleCpuTime = input.ReadUInt64();
break;
}
+ case 48: {
+ CqPollCount = input.ReadUInt64();
+ break;
+ }
}
}
}
@@ -876,6 +908,7 @@ namespace Grpc.Testing {
timeUser_ = other.timeUser_;
timeSystem_ = other.timeSystem_;
requestResults_ = other.requestResults_.Clone();
+ cqPollCount_ = other.cqPollCount_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -946,6 +979,20 @@ namespace Grpc.Testing {
get { return requestResults_; }
}
+ /// <summary>Field number for the "cq_poll_count" field.</summary>
+ public const int CqPollCountFieldNumber = 6;
+ private ulong cqPollCount_;
+ /// <summary>
+ /// Number of polls called inside completion queue
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public ulong CqPollCount {
+ get { return cqPollCount_; }
+ set {
+ cqPollCount_ = value;
+ }
+ }
+
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ClientStats);
@@ -964,6 +1011,7 @@ namespace Grpc.Testing {
if (TimeUser != other.TimeUser) return false;
if (TimeSystem != other.TimeSystem) return false;
if(!requestResults_.Equals(other.requestResults_)) return false;
+ if (CqPollCount != other.CqPollCount) return false;
return true;
}
@@ -975,6 +1023,7 @@ namespace Grpc.Testing {
if (TimeUser != 0D) hash ^= TimeUser.GetHashCode();
if (TimeSystem != 0D) hash ^= TimeSystem.GetHashCode();
hash ^= requestResults_.GetHashCode();
+ if (CqPollCount != 0UL) hash ^= CqPollCount.GetHashCode();
return hash;
}
@@ -1002,6 +1051,10 @@ namespace Grpc.Testing {
output.WriteDouble(TimeSystem);
}
requestResults_.WriteTo(output, _repeated_requestResults_codec);
+ if (CqPollCount != 0UL) {
+ output.WriteRawTag(48);
+ output.WriteUInt64(CqPollCount);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1020,6 +1073,9 @@ namespace Grpc.Testing {
size += 1 + 8;
}
size += requestResults_.CalculateSize(_repeated_requestResults_codec);
+ if (CqPollCount != 0UL) {
+ size += 1 + pb::CodedOutputStream.ComputeUInt64Size(CqPollCount);
+ }
return size;
}
@@ -1044,6 +1100,9 @@ namespace Grpc.Testing {
TimeSystem = other.TimeSystem;
}
requestResults_.Add(other.requestResults_);
+ if (other.CqPollCount != 0UL) {
+ CqPollCount = other.CqPollCount;
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1077,6 +1136,10 @@ namespace Grpc.Testing {
requestResults_.AddEntriesFrom(input, _repeated_requestResults_codec);
break;
}
+ case 48: {
+ CqPollCount = input.ReadUInt64();
+ break;
+ }
}
}
}
diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh
index 8caaaabe0f..1a1adbbae5 100755
--- a/src/csharp/generate_proto_csharp.sh
+++ b/src/csharp/generate_proto_csharp.sh
@@ -37,4 +37,4 @@ $PROTOC --plugin=$PLUGIN --csharp_out=$REFLECTION_DIR --grpc_out=$REFLECTION_DIR
# don't match the package names. Setting -I to the correct value src/proto
# breaks the code generation.
$PROTOC --plugin=$PLUGIN --csharp_out=$TESTING_DIR --grpc_out=$TESTING_DIR \
- -I . src/proto/grpc/testing/{control,empty,messages,metrics,payloads,services,stats,test}.proto
+ -I . src/proto/grpc/testing/{control,echo_messages,empty,messages,metrics,payloads,services,stats,test}.proto
diff --git a/src/csharp/tests.json b/src/csharp/tests.json
index 707d140f62..bc6adbbfe8 100644
--- a/src/csharp/tests.json
+++ b/src/csharp/tests.json
@@ -42,6 +42,7 @@
"Grpc.HealthCheck.Tests.HealthServiceImplTest"
],
"Grpc.IntegrationTesting": [
+ "Grpc.IntegrationTesting.CustomErrorDetailsTest",
"Grpc.IntegrationTesting.GeneratedClientTest",
"Grpc.IntegrationTesting.GeneratedServiceBaseTest",
"Grpc.IntegrationTesting.HistogramTest",
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index 7593a8ab0d..9802465001 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -75,6 +75,10 @@
}
- (void)dealloc {
+ for (int i = 0; i < _op.data.send_initial_metadata.count; i++) {
+ grpc_slice_unref(_op.data.send_initial_metadata.metadata[i].key);
+ grpc_slice_unref(_op.data.send_initial_metadata.metadata[i].value);
+ }
gpr_free(_op.data.send_initial_metadata.metadata);
}
diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c
index 35e2fd13dd..429717a7be 100644
--- a/test/core/end2end/tests/compressed_payload.c
+++ b/test/core/end2end/tests/compressed_payload.c
@@ -274,11 +274,12 @@ static void request_with_payload_template(
grpc_compression_algorithm expected_algorithm_from_client,
grpc_compression_algorithm expected_algorithm_from_server,
grpc_metadata *client_init_metadata, bool set_server_level,
- grpc_compression_level server_compression_level) {
+ grpc_compression_level server_compression_level,
+ bool send_message_before_initial_metadata) {
grpc_call *c;
grpc_call *s;
grpc_slice request_payload_slice;
- grpc_byte_buffer *request_payload;
+ grpc_byte_buffer *request_payload = NULL;
grpc_channel_args *client_args;
grpc_channel_args *server_args;
grpc_end2end_test_fixture f;
@@ -330,6 +331,20 @@ static void request_with_payload_template(
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
+ if (send_message_before_initial_metadata) {
+ request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op->flags = client_send_flags_bitmask;
+ op->reserved = NULL;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(2), true);
+ }
+
memset(ops, 0, sizeof(ops));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
@@ -394,23 +409,21 @@ static void request_with_payload_template(
GPR_ASSERT(GRPC_CALL_OK == error);
for (int i = 0; i < 2; i++) {
- request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
- memset(ops, 0, sizeof(ops));
- op = ops;
- op->op = GRPC_OP_SEND_MESSAGE;
- op->data.send_message.send_message = request_payload;
- op->flags = client_send_flags_bitmask;
- op->reserved = NULL;
- op++;
- op->op = GRPC_OP_RECV_MESSAGE;
- op->data.recv_message.recv_message = &response_payload_recv;
- op->flags = 0;
- op->reserved = NULL;
- op++;
- error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
- GPR_ASSERT(GRPC_CALL_OK == error);
+ if (i > 0 || !send_message_before_initial_metadata) {
+ request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op->flags = client_send_flags_bitmask;
+ op->reserved = NULL;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
+ }
memset(ops, 0, sizeof(ops));
op = ops;
@@ -421,6 +434,7 @@ static void request_with_payload_template(
op++;
error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
+
CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
cq_verify(cqv);
@@ -438,8 +452,19 @@ static void request_with_payload_template(
op++;
error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
- CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
+ CQ_EXPECT_COMPLETION(cqv, tag(3), 1);
cq_verify(cqv);
GPR_ASSERT(response_payload_recv->type == GRPC_BB_RAW);
@@ -469,7 +494,7 @@ static void request_with_payload_template(
op->flags = 0;
op->reserved = NULL;
op++;
- error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), NULL);
GPR_ASSERT(GRPC_CALL_OK == error);
memset(ops, 0, sizeof(ops));
@@ -486,7 +511,7 @@ static void request_with_payload_template(
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
- CQ_EXPECT_COMPLETION(cqv, tag(3), 1);
+ CQ_EXPECT_COMPLETION(cqv, tag(4), 1);
CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
CQ_EXPECT_COMPLETION(cqv, tag(104), 1);
cq_verify(cqv);
@@ -526,7 +551,7 @@ static void test_invoke_request_with_exceptionally_uncompressed_payload(
config, "test_invoke_request_with_exceptionally_uncompressed_payload",
GRPC_WRITE_NO_COMPRESS, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, NULL, false,
- /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
+ /* ignored */ GRPC_COMPRESS_LEVEL_NONE, false);
}
static void test_invoke_request_with_uncompressed_payload(
@@ -534,7 +559,8 @@ static void test_invoke_request_with_uncompressed_payload(
request_with_payload_template(
config, "test_invoke_request_with_uncompressed_payload", 0,
GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
- GRPC_COMPRESS_NONE, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
+ GRPC_COMPRESS_NONE, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE,
+ false);
}
static void test_invoke_request_with_compressed_payload(
@@ -542,7 +568,17 @@ static void test_invoke_request_with_compressed_payload(
request_with_payload_template(
config, "test_invoke_request_with_compressed_payload", 0,
GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
- GRPC_COMPRESS_GZIP, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
+ GRPC_COMPRESS_GZIP, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE,
+ false);
+}
+
+static void test_invoke_request_with_send_message_before_initial_metadata(
+ grpc_end2end_test_config config) {
+ request_with_payload_template(
+ config, "test_invoke_request_with_compressed_payload", 0,
+ GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
+ GRPC_COMPRESS_GZIP, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE,
+ true);
}
static void test_invoke_request_with_server_level(
@@ -550,7 +586,7 @@ static void test_invoke_request_with_server_level(
request_with_payload_template(
config, "test_invoke_request_with_server_level", 0, GRPC_COMPRESS_NONE,
GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE /* ignored */,
- NULL, true, GRPC_COMPRESS_LEVEL_HIGH);
+ NULL, true, GRPC_COMPRESS_LEVEL_HIGH, false);
}
static void test_invoke_request_with_compressed_payload_md_override(
@@ -574,21 +610,21 @@ static void test_invoke_request_with_compressed_payload_md_override(
config, "test_invoke_request_with_compressed_payload_md_override_1", 0,
GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
GRPC_COMPRESS_NONE, &gzip_compression_override, false,
- /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
+ /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
/* Channel default DEFLATE, call override to GZIP */
request_with_payload_template(
config, "test_invoke_request_with_compressed_payload_md_override_2", 0,
GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
GRPC_COMPRESS_NONE, &gzip_compression_override, false,
- /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
+ /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
/* Channel default DEFLATE, call override to NONE (aka IDENTITY) */
request_with_payload_template(
config, "test_invoke_request_with_compressed_payload_md_override_3", 0,
GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
GRPC_COMPRESS_NONE, &identity_compression_override, false,
- /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
+ /*ignored*/ GRPC_COMPRESS_LEVEL_NONE, false);
}
static void test_invoke_request_with_disabled_algorithm(
@@ -602,6 +638,7 @@ void compressed_payload(grpc_end2end_test_config config) {
test_invoke_request_with_exceptionally_uncompressed_payload(config);
test_invoke_request_with_uncompressed_payload(config);
test_invoke_request_with_compressed_payload(config);
+ test_invoke_request_with_send_message_before_initial_metadata(config);
test_invoke_request_with_server_level(config);
test_invoke_request_with_compressed_payload_md_override(config);
test_invoke_request_with_disabled_algorithm(config);
diff --git a/test/cpp/common/alarm_cpp_test.cc b/test/cpp/common/alarm_cpp_test.cc
index 3e4999994a..ce4168843c 100644
--- a/test/cpp/common/alarm_cpp_test.cc
+++ b/test/cpp/common/alarm_cpp_test.cc
@@ -40,6 +40,37 @@ TEST(AlarmTest, RegularExpiry) {
EXPECT_EQ(junk, output_tag);
}
+TEST(AlarmTest, MoveConstructor) {
+ CompletionQueue cq;
+ void* junk = reinterpret_cast<void*>(1618033);
+ Alarm first(&cq, grpc_timeout_seconds_to_deadline(1), junk);
+ Alarm second(std::move(first));
+ void* output_tag;
+ bool ok;
+ const CompletionQueue::NextStatus status = cq.AsyncNext(
+ (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(2));
+ EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
+ EXPECT_TRUE(ok);
+ EXPECT_EQ(junk, output_tag);
+}
+
+TEST(AlarmTest, MoveAssignment) {
+ CompletionQueue cq;
+ void* junk = reinterpret_cast<void*>(1618033);
+ Alarm first(&cq, grpc_timeout_seconds_to_deadline(1), junk);
+ Alarm second(std::move(first));
+ first = std::move(second);
+
+ void* output_tag;
+ bool ok;
+ const CompletionQueue::NextStatus status = cq.AsyncNext(
+ (void**)&output_tag, &ok, grpc_timeout_seconds_to_deadline(2));
+
+ EXPECT_EQ(status, CompletionQueue::GOT_EVENT);
+ EXPECT_TRUE(ok);
+ EXPECT_EQ(junk, output_tag);
+}
+
TEST(AlarmTest, RegularExpiryChrono) {
CompletionQueue cq;
void* junk = reinterpret_cast<void*>(1618033);
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index 776d94d3b6..f71e557450 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -97,9 +97,12 @@ class ClientLbEnd2endTest : public ::testing::Test {
}
}
- void StartServers(int num_servers) {
- for (int i = 0; i < num_servers; ++i) {
- servers_.emplace_back(new ServerData(server_host_));
+ void StartServers(size_t num_servers,
+ std::vector<int> ports = std::vector<int>()) {
+ for (size_t i = 0; i < num_servers; ++i) {
+ int port = 0;
+ if (ports.size() == num_servers) port = ports[i];
+ servers_.emplace_back(new ServerData(server_host_, port));
}
}
@@ -146,14 +149,18 @@ class ClientLbEnd2endTest : public ::testing::Test {
stub_ = grpc::testing::EchoTestService::NewStub(channel_);
}
- void SendRpc() {
+ void SendRpc(bool expect_ok = true) {
EchoRequest request;
EchoResponse response;
request.set_message("Live long and prosper.");
ClientContext context;
Status status = stub_->Echo(&context, request, &response);
- EXPECT_TRUE(status.ok());
- EXPECT_EQ(response.message(), request.message());
+ if (expect_ok) {
+ EXPECT_TRUE(status.ok());
+ EXPECT_EQ(response.message(), request.message());
+ } else {
+ EXPECT_FALSE(status.ok());
+ }
}
struct ServerData {
@@ -162,8 +169,8 @@ class ClientLbEnd2endTest : public ::testing::Test {
MyTestServiceImpl service_;
std::unique_ptr<std::thread> thread_;
- explicit ServerData(const grpc::string& server_host) {
- port_ = grpc_pick_unused_port_or_die();
+ explicit ServerData(const grpc::string& server_host, int port = 0) {
+ port_ = port > 0 ? port : grpc_pick_unused_port_or_die();
gpr_log(GPR_INFO, "starting server on port %d", port_);
std::mutex mu;
std::condition_variable cond;
@@ -187,9 +194,9 @@ class ClientLbEnd2endTest : public ::testing::Test {
cond->notify_one();
}
- void Shutdown() {
+ void Shutdown(bool join = true) {
server_->Shutdown();
- thread_->join();
+ if (join) thread_->join();
}
};
@@ -456,6 +463,39 @@ TEST_F(ClientLbEnd2endTest, RoundRobinManyUpdates) {
EXPECT_EQ("round_robin", channel_->GetLoadBalancingPolicyName());
}
+TEST_F(ClientLbEnd2endTest, RoundRobinReconnect) {
+ // Start servers and send one RPC per server.
+ const int kNumServers = 1;
+ std::vector<int> ports;
+ ports.push_back(grpc_pick_unused_port_or_die());
+ StartServers(kNumServers, ports);
+ ResetStub("round_robin");
+ SetNextResolution(ports);
+ // Send one RPC per backend and make sure they are used in order.
+ // Note: This relies on the fact that the subchannels are reported in
+ // state READY in the order in which the addresses are specified,
+ // which is only true because the backends are all local.
+ for (size_t i = 0; i < servers_.size(); ++i) {
+ SendRpc();
+ EXPECT_EQ(1, servers_[i]->service_.request_count()) << "for backend #" << i;
+ }
+ // Check LB policy name for the channel.
+ EXPECT_EQ("round_robin", channel_->GetLoadBalancingPolicyName());
+
+ // Kill all servers
+ for (size_t i = 0; i < servers_.size(); ++i) {
+ servers_[i]->Shutdown(false);
+ }
+ // Client request should fail.
+ SendRpc(false);
+
+ // Bring servers back up on the same port (we aren't recreating the channel).
+ StartServers(kNumServers, ports);
+
+ // Client request should succeed.
+ SendRpc();
+}
+
} // namespace
} // namespace testing
} // namespace grpc
diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD
index 3583720ef3..978e9b1ed9 100644
--- a/third_party/cares/cares.BUILD
+++ b/third_party/cares/cares.BUILD
@@ -78,6 +78,7 @@ cc_library(
"cares/ares_version.h",
"cares/bitncmp.h",
"cares/config-win32.h",
+ "cares/nameser.h",
"cares/setup_once.h",
] + select({
":darwin": ["config_darwin/ares_config.h"],
diff --git a/tools/gcp/utils/big_query_utils.py b/tools/gcp/utils/big_query_utils.py
index 76c86645b7..77a5f5691e 100755
--- a/tools/gcp/utils/big_query_utils.py
+++ b/tools/gcp/utils/big_query_utils.py
@@ -116,6 +116,33 @@ def create_table2(big_query, project_id, dataset_id, table_id, fields_schema,
return is_success
+def patch_table(big_query, project_id, dataset_id, table_id, fields_schema):
+ is_success = True
+
+ body = {
+ 'schema': {
+ 'fields': fields_schema
+ },
+ 'tableReference': {
+ 'datasetId': dataset_id,
+ 'projectId': project_id,
+ 'tableId': table_id
+ }
+ }
+
+ try:
+ table_req = big_query.tables().patch(projectId=project_id,
+ datasetId=dataset_id,
+ tableId=table_id,
+ body=body)
+ res = table_req.execute(num_retries=NUM_RETRIES)
+ print 'Successfully patched %s "%s"' % (res['kind'], res['id'])
+ except HttpError as http_error:
+ print 'Error in creating table: %s. Err: %s' % (table_id, http_error)
+ is_success = False
+ return is_success
+
+
def insert_rows(big_query, project_id, dataset_id, table_id, rows_list):
is_success = True
body = {'rows': rows_list}
diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
index 3851e565a4..22e80d2afa 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
@@ -15,53 +15,37 @@
# Source this rc script to prepare the environment for macos builds
-# TODO(jtattermusch): remove all deps once installed on MacOS workers
+ulimit -n 1000
-# brew and C++ deps
-yes | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
-brew install autoconf automake libtool ccache cmake gflags gpg wget
+# show current limits
+ulimit -a
-# TODO(jtattermusch): hkp://keys.gnupg.net fails with "No route to host"
-gpg --keyserver hkp://193.164.133.100 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
-curl -sSL https://get.rvm.io | sudo bash -s stable
-# add ourselves to rvm group to prevent later "access denied" errors.
-sudo dseditgroup -o edit -a `whoami` -t user rvm
-
-set +ex
-source /etc/profile.d/rvm.sh
-rvm install ruby-2.3
-gem install bundler
+# required to build protobuf
+brew install gflags
+set +ex # rvm script is very verbose and exits with errorcode
+source $HOME/.rvm/scripts/rvm
+set -e # rvm commands are very verbose
+rvm install ruby-2.4
rvm osx-ssl-certs status all
rvm osx-ssl-certs update all
set -ex
+gem install bundler
+
# cocoapods
-gem install cocoapods --version 1.0.0
+export LANG=en_US.UTF-8
+gem install cocoapods
+pod repo update # needed by python
# python
-wget -q https://bootstrap.pypa.io/get-pip.py
-sudo python get-pip.py
+brew install coreutils # we need grealpath
sudo pip install virtualenv
+sudo pip install -U six tox setuptools
-# TODO(jtattermusch): install python3
-
-# mono
-wget -q https://download.mono-project.com/archive/5.0.1/macos-10-universal/MonoFramework-MDK-5.0.1.1.macos10.xamarin.universal.pkg
-sudo installer -pkg MonoFramework-MDK-5.0.1.1.macos10.xamarin.universal.pkg -target /
-ln -s /Library/Frameworks/Mono.framework/Versions/Current/bin/mono /usr/local/bin/mono
-
-# dotnet SDK
-brew install openssl
-wget -q https://go.microsoft.com/fwlink/?linkid=843444 -O dotnet-dev-osx-x64.1.0.1.pkg
-sudo installer -pkg dotnet-dev-osx-x64.1.0.1.pkg -target /
-ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/dotnet
-dotnet --version # bootstrap dotnet SDK
-
-# nvm
-wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash
-
-# TODO(jtattermusch): install node if needed
+# python 3.4
+wget -q https://www.python.org/ftp/python/3.4.4/python-3.4.4-macosx10.6.pkg
+sudo installer -pkg python-3.4.4-macosx10.6.pkg -target /
git submodule update --init
diff --git a/tools/internal_ci/macos/grpc_build_artifacts.sh b/tools/internal_ci/macos/grpc_build_artifacts.sh
index aad99b068d..603c15f210 100755
--- a/tools/internal_ci/macos/grpc_build_artifacts.sh
+++ b/tools/internal_ci/macos/grpc_build_artifacts.sh
@@ -18,6 +18,31 @@ set -ex
# change to grpc repo root
cd $(dirname $0)/../../..
-git submodule update --init
+source tools/internal_ci/helper_scripts/prepare_build_macos_rc
+
+# python 3.5
+wget -q https://www.python.org/ftp/python/3.5.2/python-3.5.2-macosx10.6.pkg
+sudo installer -pkg python-3.5.2-macosx10.6.pkg -target /
+
+# install cython for all python versions
+python2.7 -m pip install cython setuptools wheel
+python3.4 -m pip install cython setuptools wheel
+python3.5 -m pip install cython setuptools wheel
+python3.6 -m pip install cython setuptools wheel
+
+# node-gyp (needed for node artifacts)
+npm install -g node-gyp
+
+# php dependencies: pecl
+curl -O http://pear.php.net/go-pear.phar
+sudo php -d detect_unicode=0 go-pear.phar
+
+# needed to build ruby artifacts
+gem install rake-compiler
+wget https://raw.githubusercontent.com/grpc/grpc/master/tools/distrib/build_ruby_environment_macos.sh
+bash build_ruby_environment_macos.sh
+
+gem install rubygems-update
+update_rubygems
tools/run_tests/task_runner.py -f artifact macos
diff --git a/tools/internal_ci/macos/grpc_master.sh b/tools/internal_ci/macos/grpc_master.sh
index 786859be3f..c64666b2de 100755
--- a/tools/internal_ci/macos/grpc_master.sh
+++ b/tools/internal_ci/macos/grpc_master.sh
@@ -20,7 +20,7 @@ cd $(dirname $0)/../../..
source tools/internal_ci/helper_scripts/prepare_build_macos_rc
-tools/run_tests/run_tests_matrix.py -f basictests macos --internal_ci || FAILED="true"
+tools/run_tests/run_tests_matrix.py -f basictests macos --internal_ci -j 2 --inner_jobs 4 || FAILED="true"
# kill port_server.py to prevent the build from hanging
ps aux | grep port_server\\.py | awk '{print $2}' | xargs kill -9
diff --git a/tools/run_tests/performance/patch_scenario_results_schema.py b/tools/run_tests/performance/patch_scenario_results_schema.py
new file mode 100755
index 0000000000..81ba5381b3
--- /dev/null
+++ b/tools/run_tests/performance/patch_scenario_results_schema.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# Copyright 2016 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Use to patch schema of existing scenario results tables (after adding fields).
+
+from __future__ import print_function
+
+import argparse
+import calendar
+import json
+import os
+import sys
+import time
+import uuid
+
+
+gcp_utils_dir = os.path.abspath(os.path.join(
+ os.path.dirname(__file__), '../../gcp/utils'))
+sys.path.append(gcp_utils_dir)
+import big_query_utils
+
+
+_PROJECT_ID='grpc-testing'
+
+def _patch_results_table(dataset_id, table_id):
+ bq = big_query_utils.create_big_query()
+ with open(os.path.dirname(__file__) + '/scenario_result_schema.json', 'r') as f:
+ table_schema = json.loads(f.read())
+ desc = 'Results of performance benchmarks.'
+ return big_query_utils.patch_table(bq, _PROJECT_ID, dataset_id,
+ table_id, table_schema)
+
+
+argp = argparse.ArgumentParser(description='Patch schema of scenario results table.')
+argp.add_argument('--bq_result_table', required=True, default=None, type=str,
+ help='Bigquery "dataset.table" to patch.')
+
+args = argp.parse_args()
+
+dataset_id, table_id = args.bq_result_table.split('.', 2)
+
+_patch_results_table(dataset_id, table_id)
+print('Successfully patched schema of %s.\n' % args.bq_result_table)
diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json
index 8ec41c377c..245861f8c2 100644
--- a/tools/run_tests/performance/scenario_result_schema.json
+++ b/tools/run_tests/performance/scenario_result_schema.json
@@ -107,6 +107,11 @@
"name": "timeSystem",
"type": "FLOAT",
"mode": "NULLABLE"
+ },
+ {
+ "name": "cqPollCount",
+ "type": "INTEGER",
+ "mode": "NULLABLE"
}
]
},
@@ -129,6 +134,11 @@
"name": "timeSystem",
"type": "FLOAT",
"mode": "NULLABLE"
+ },
+ {
+ "name": "cqPollCount",
+ "type": "INTEGER",
+ "mode": "NULLABLE"
}
]
},
@@ -196,6 +206,16 @@
"name": "latency999",
"type": "FLOAT",
"mode": "NULLABLE"
+ },
+ {
+ "name": "clientPollsPerRequest",
+ "type": "FLOAT",
+ "mode": "NULLABLE"
+ },
+ {
+ "name": "serverPollsPerRequest",
+ "type": "FLOAT",
+ "mode": "NULLABLE"
}
]
},
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 6541ebc52a..611868ce5a 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -81,7 +81,7 @@ def get_flaky_tests(limit=None):
FROM
[grpc-testing:jenkins_test_results.aggregate_results]
WHERE
- timestamp >= DATE_ADD(DATE(CURRENT_TIMESTAMP()), -1, "WEEK")
+ timestamp >= DATE_ADD(CURRENT_DATE(), -1, "WEEK")
AND NOT REGEXP_MATCH(job_name, '.*portability.*')
GROUP BY
test_name