Merge github.com:grpc/grpc into direct-calls

pull/8008/head
Craig Tiller 8 years ago
commit 7d2f0b0d19
  1. 25
      doc/interop-test-descriptions.md
  2. 22
      src/core/ext/client_config/client_channel.c
  3. 6
      src/core/ext/client_config/lb_policy.h
  4. 17
      src/core/ext/lb_policy/grpclb/grpclb.c
  5. 12
      src/core/ext/lb_policy/pick_first/pick_first.c
  6. 12
      src/core/ext/lb_policy/round_robin/round_robin.c
  7. 20
      src/core/ext/load_reporting/load_reporting.h
  8. 4
      src/core/ext/load_reporting/load_reporting_filter.c
  9. 4
      src/core/lib/transport/static_metadata.c
  10. 21
      src/core/lib/transport/static_metadata.h
  11. 4
      src/proto/grpc/testing/test.proto
  12. 8
      test/core/end2end/fuzzers/hpack.dictionary
  13. 4
      test/core/end2end/tests/load_reporting_hook.c
  14. 3
      test/cpp/grpclb/grpclb_test.cc
  15. 9
      test/cpp/interop/client.cc
  16. 18
      test/cpp/interop/interop_client.cc
  17. 1
      test/cpp/interop/interop_client.h
  18. 4
      tools/codegen/core/gen_static_metadata.py

@ -779,25 +779,38 @@ Client asserts:
### unimplemented_method
Status: Ready for implementation. Blocking beta.
This test verifies calling unimplemented RPC method returns the UNIMPLEMENTED status code.
This test verifies that calling an unimplemented RPC method returns the
UNIMPLEMENTED status code.
Server features:
N/A
Procedure:
* Client calls `grpc.testing.UnimplementedService/UnimplementedCall` with an
empty request (defined as `grpc.testing.Empty`):
* Client calls `grpc.testing.TestService/UnimplementedMethod` with an empty
request (defined as `grpc.testing.Empty`):
```
{
}
```
Client asserts:
* received status code is 12 (UNIMPLEMENTED)
### unimplemented_service
This test verifies calling an unimplemented server returns the UNIMPLEMENTED
status code.
Server features:
N/A
Procedure:
* Client calls `grpc.testing.UnimplementedService/UnimplementedCall` with an
empty request (defined as `grpc.testing.Empty`)
Client asserts:
* received status code is 12 (UNIMPLEMENTED)
* received status message is empty or null/unset
### cancel_after_begin

@ -513,10 +513,14 @@ static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
call_data *calld = arg;
grpc_call_element *elem = arg;
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
gpr_mu_lock(&calld->mu);
GPR_ASSERT(calld->creation_phase ==
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL);
grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent,
chand->interested_parties);
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
if (calld->connected_subchannel == NULL) {
gpr_atm_no_barrier_store(&calld->subchannel_call, 1);
@ -564,6 +568,9 @@ typedef struct {
grpc_closure closure;
} continue_picking_args;
/** Return true if subchannel is available immediately (in which case on_ready
should not be called), or false otherwise (in which case on_ready should be
called when the subchannel is available). */
static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_metadata_batch *initial_metadata,
uint32_t initial_metadata_flags,
@ -629,8 +636,8 @@ static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
gpr_mu_unlock(&chand->mu);
// TODO(dgq): make this deadline configurable somehow.
const grpc_lb_policy_pick_args inputs = {
calld->pollent, initial_metadata, initial_metadata_flags,
&calld->lb_token_mdelem, gpr_inf_future(GPR_CLOCK_MONOTONIC)};
initial_metadata, initial_metadata_flags, &calld->lb_token_mdelem,
gpr_inf_future(GPR_CLOCK_MONOTONIC)};
r = grpc_lb_policy_pick(exec_ctx, lb_policy, &inputs, connected_subchannel,
NULL, on_ready);
GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel");
@ -672,6 +679,7 @@ static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_transport_stream_op *op) {
call_data *calld = elem->call_data;
channel_data *chand = elem->channel_data;
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
grpc_deadline_state_client_start_transport_stream_op(exec_ctx, elem, op);
/* try to (atomically) get the call */
@ -739,14 +747,20 @@ retry:
calld->connected_subchannel == NULL &&
op->send_initial_metadata != NULL) {
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
grpc_closure_init(&calld->next_step, subchannel_ready, calld);
grpc_closure_init(&calld->next_step, subchannel_ready, elem);
GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel");
/* If a subchannel is not available immediately, the polling entity from
call_data should be provided to channel_data's interested_parties, so
that IO of the lb_policy and resolver could be done under it. */
if (pick_subchannel(exec_ctx, elem, op->send_initial_metadata,
op->send_initial_metadata_flags,
&calld->connected_subchannel, &calld->next_step,
GRPC_ERROR_NONE)) {
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
} else {
grpc_polling_entity_add_to_pollset_set(exec_ctx, calld->pollent,
chand->interested_parties);
}
}
/* if we've got a subchannel, then let's ask it to create a call */

@ -35,7 +35,6 @@
#define GRPC_CORE_EXT_CLIENT_CONFIG_LB_POLICY_H
#include "src/core/ext/client_config/subchannel.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/transport/connectivity_state.h"
/** A load balancing policy: specified by a vtable and a struct (which
@ -55,8 +54,6 @@ struct grpc_lb_policy {
/** Extra arguments for an LB pick */
typedef struct grpc_lb_policy_pick_args {
/** Parties interested in the pick's progress */
grpc_polling_entity *pollent;
/** Initial metadata associated with the picking call. */
grpc_metadata_batch *initial_metadata;
/** Bitmask used for selective cancelling. See \a
@ -153,7 +150,8 @@ void grpc_lb_policy_init(grpc_lb_policy *policy,
once the pick is complete with its error argument set to indicate
success or failure.
Any I/O should be done under \a pick_args->pollent. */
Any IO should be done under the \a interested_parties \a grpc_pollset_set
in the \a grpc_lb_policy struct. */
int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
const grpc_lb_policy_pick_args *pick_args,
grpc_connected_subchannel **target, void **user_data,

@ -399,14 +399,14 @@ static grpc_lb_addresses *process_serverlist(
GPR_ARRAY_SIZE(server->load_balance_token) - 1;
grpc_mdstr *lb_token_mdstr = grpc_mdstr_from_buffer(
(uint8_t *)server->load_balance_token, lb_token_size);
user_data = grpc_mdelem_from_metadata_strings(
GRPC_MDSTR_LOAD_REPORTING_INITIAL, lb_token_mdstr);
user_data = grpc_mdelem_from_metadata_strings(GRPC_MDSTR_LB_TOKEN,
lb_token_mdstr);
} else {
gpr_log(GPR_ERROR,
"Missing LB token for backend address '%s'. The empty token will "
"be used instead",
grpc_sockaddr_to_uri((struct sockaddr *)&addr.addr));
user_data = GRPC_MDELEM_LOAD_REPORTING_INITIAL_EMPTY;
user_data = GRPC_MDELEM_LB_TOKEN_EMPTY;
}
grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len,
@ -458,6 +458,9 @@ static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy,
(intptr_t)glb_policy->rr_policy);
}
GPR_ASSERT(glb_policy->rr_policy != NULL);
grpc_pollset_set_add_pollset_set(exec_ctx,
glb_policy->rr_policy->interested_parties,
glb_policy->base.interested_parties);
glb_policy->rr_connectivity->state = grpc_lb_policy_check_connectivity(
exec_ctx, glb_policy->rr_policy, &error);
grpc_lb_policy_notify_on_state_change(
@ -686,8 +689,6 @@ static void glb_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
while (pp != NULL) {
pending_pick *next = pp->next;
if (pp->target == target) {
grpc_polling_entity_del_from_pollset_set(
exec_ctx, pp->pick_args.pollent, glb_policy->base.interested_parties);
*target = NULL;
grpc_exec_ctx_sched(
exec_ctx, &pp->wrapped_on_complete,
@ -719,8 +720,6 @@ static void glb_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
pending_pick *next = pp->next;
if ((pp->pick_args.initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
grpc_polling_entity_del_from_pollset_set(
exec_ctx, pp->pick_args.pollent, glb_policy->base.interested_parties);
grpc_exec_ctx_sched(
exec_ctx, &pp->wrapped_on_complete,
GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1), NULL);
@ -806,8 +805,6 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
} else {
/* else, the pending pick will be registered and taken care of by the
* pending pick list inside the RR policy (glb_policy->rr_policy) */
grpc_polling_entity_add_to_pollset_set(exec_ctx, pick_args->pollent,
glb_policy->base.interested_parties);
add_pending_pick(&glb_policy->pending_picks, pick_args, target,
on_complete);
@ -931,7 +928,7 @@ static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) {
/* Note the following LB call progresses every time there's activity in \a
* glb_policy->base.interested_parties, which is comprised of the polling
* entities passed to glb_pick(). */
* entities from \a client_channel. */
lb_client->lb_call = grpc_channel_create_pollset_set_call(
glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
glb_policy->base.interested_parties,

@ -39,7 +39,6 @@
typedef struct pending_pick {
struct pending_pick *next;
grpc_polling_entity *pollent;
uint32_t initial_metadata_flags;
grpc_connected_subchannel **target;
grpc_closure *on_complete;
@ -119,8 +118,6 @@ static void pf_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
while (pp != NULL) {
pending_pick *next = pp->next;
*pp->target = NULL;
grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
p->base.interested_parties);
grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
gpr_free(pp);
pp = next;
@ -138,8 +135,6 @@ static void pf_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
while (pp != NULL) {
pending_pick *next = pp->next;
if (pp->target == target) {
grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
p->base.interested_parties);
*target = NULL;
grpc_exec_ctx_sched(
exec_ctx, pp->on_complete,
@ -168,8 +163,6 @@ static void pf_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
pending_pick *next = pp->next;
if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
p->base.interested_parties);
grpc_exec_ctx_sched(
exec_ctx, pp->on_complete,
GRPC_ERROR_CREATE_REFERENCING("Pick Cancelled", &error, 1), NULL);
@ -229,11 +222,8 @@ static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
if (!p->started_picking) {
start_picking(exec_ctx, p);
}
grpc_polling_entity_add_to_pollset_set(exec_ctx, pick_args->pollent,
p->base.interested_parties);
pp = gpr_malloc(sizeof(*pp));
pp->next = p->pending_picks;
pp->pollent = pick_args->pollent;
pp->target = target;
pp->initial_metadata_flags = pick_args->initial_metadata_flags;
pp->on_complete = on_complete;
@ -319,8 +309,6 @@ static void pf_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
while ((pp = p->pending_picks)) {
p->pending_picks = pp->next;
*pp->target = selected;
grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
p->base.interested_parties);
grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
gpr_free(pp);
}

@ -78,9 +78,6 @@ int grpc_lb_round_robin_trace = 0;
typedef struct pending_pick {
struct pending_pick *next;
/* polling entity for the pick()'s async notification */
grpc_polling_entity *pollent;
/* output argument where to store the pick()ed user_data. It'll be NULL if no
* such data is present or there's an error (the definite test for errors is
* \a target being NULL). */
@ -318,8 +315,6 @@ static void rr_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
while (pp != NULL) {
pending_pick *next = pp->next;
if (pp->target == target) {
grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
p->base.interested_parties);
*target = NULL;
grpc_exec_ctx_sched(
exec_ctx, pp->on_complete,
@ -348,8 +343,6 @@ static void rr_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
pending_pick *next = pp->next;
if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
p->base.interested_parties);
*pp->target = NULL;
grpc_exec_ctx_sched(
exec_ctx, pp->on_complete,
@ -422,11 +415,8 @@ static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
if (!p->started_picking) {
start_picking(exec_ctx, p);
}
grpc_polling_entity_add_to_pollset_set(exec_ctx, pick_args->pollent,
p->base.interested_parties);
pp = gpr_malloc(sizeof(*pp));
pp->next = p->pending_picks;
pp->pollent = pick_args->pollent;
pp->target = target;
pp->on_complete = on_complete;
pp->initial_metadata_flags = pick_args->initial_metadata_flags;
@ -482,8 +472,6 @@ static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
"[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
(void *)selected->subchannel, (void *)selected);
}
grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
p->base.interested_parties);
grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
gpr_free(pp);
}

@ -37,13 +37,21 @@
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/channel/channel_stack.h"
/** Metadata key for initial metadata coming from clients */
/* TODO(dgq): change to the final value TBD */
#define GRPC_LOAD_REPORTING_INITIAL_MD_KEY "load-reporting-initial"
/** Metadata key for the gRPC LB load balancer token.
*
* The value corresponding to this key is an opaque token that is given to the
* frontend as part of each pick; the frontend sends this token to the backend
* in each request it sends when using that pick. The token is used by the
* backend to verify the request and to allow the backend to report load to the
* gRPC LB system. */
#define GRPC_LB_TOKEN_MD_KEY "lb-token"
/** Metadata key for trailing metadata from servers */
/* TODO(dgq): change to the final value TBD */
#define GRPC_LOAD_REPORTING_TRAILING_MD_KEY "load-reporting-trailing"
/** Metadata key for gRPC LB cost reporting.
*
* The value corresponding to this key is an opaque binary blob reported by the
* backend as part of its trailing metadata containing cost information for the
* call. */
#define GRPC_LB_COST_MD_KEY "lb-cost"
/** Identifiers for the invocation point of the users LR callback */
typedef enum grpc_load_reporting_source {

@ -75,7 +75,7 @@ static grpc_mdelem *recv_md_filter(void *user_data, grpc_mdelem *md) {
if (md->key == GRPC_MDSTR_PATH) {
calld->service_method = grpc_mdstr_as_c_string(md->value);
} else if (md->key == GRPC_MDSTR_LOAD_REPORTING_INITIAL) {
} else if (md->key == GRPC_MDSTR_LB_TOKEN) {
calld->initial_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value));
return NULL;
}
@ -193,7 +193,7 @@ static grpc_mdelem *lr_trailing_md_filter(void *user_data, grpc_mdelem *md) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
if (md->key == GRPC_MDSTR_LOAD_REPORTING_TRAILING) {
if (md->key == GRPC_MDSTR_LB_COST) {
calld->trailing_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value));
return NULL;
}

@ -126,9 +126,9 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
"if-range",
"if-unmodified-since",
"last-modified",
"lb-cost",
"lb-token",
"link",
"load-reporting-initial",
"load-reporting-trailing",
"location",
"max-forwards",
":method",

@ -175,12 +175,12 @@ extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[62])
/* "last-modified" */
#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[63])
/* "lb-cost" */
#define GRPC_MDSTR_LB_COST (&grpc_static_mdstr_table[64])
/* "lb-token" */
#define GRPC_MDSTR_LB_TOKEN (&grpc_static_mdstr_table[65])
/* "link" */
#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[64])
/* "load-reporting-initial" */
#define GRPC_MDSTR_LOAD_REPORTING_INITIAL (&grpc_static_mdstr_table[65])
/* "load-reporting-trailing" */
#define GRPC_MDSTR_LOAD_REPORTING_TRAILING (&grpc_static_mdstr_table[66])
#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[66])
/* "location" */
#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[67])
/* "max-forwards" */
@ -337,13 +337,12 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
#define GRPC_MDELEM_IF_UNMODIFIED_SINCE_EMPTY (&grpc_static_mdelem_table[44])
/* "last-modified": "" */
#define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[45])
/* "lb-cost": "" */
#define GRPC_MDELEM_LB_COST_EMPTY (&grpc_static_mdelem_table[46])
/* "lb-token": "" */
#define GRPC_MDELEM_LB_TOKEN_EMPTY (&grpc_static_mdelem_table[47])
/* "link": "" */
#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[46])
/* "load-reporting-initial": "" */
#define GRPC_MDELEM_LOAD_REPORTING_INITIAL_EMPTY (&grpc_static_mdelem_table[47])
/* "load-reporting-trailing": "" */
#define GRPC_MDELEM_LOAD_REPORTING_TRAILING_EMPTY \
(&grpc_static_mdelem_table[48])
#define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[48])
/* "location": "" */
#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[49])
/* "max-forwards": "" */

@ -74,6 +74,10 @@ service TestService {
// first request.
rpc HalfDuplexCall(stream StreamingOutputCallRequest)
returns (stream StreamingOutputCallResponse);
// The test server will not implement this method. It will be used
// to test the behavior when clients call unimplemented methods.
rpc UnimplementedMethod(grpc.testing.Empty) returns (grpc.testing.Empty);
}
// A simple service NOT implemented at servers so clients can test for

@ -63,9 +63,9 @@
"\x08if-range"
"\x13if-unmodified-since"
"\x0Dlast-modified"
"\x07lb-cost"
"\x08lb-token"
"\x04link"
"\x16load-reporting-initial"
"\x17load-reporting-trailing"
"\x08location"
"\x0Cmax-forwards"
"\x07:method"
@ -138,9 +138,9 @@
"\x00\x08if-range\x00"
"\x00\x13if-unmodified-since\x00"
"\x00\x0Dlast-modified\x00"
"\x00\x07lb-cost\x00"
"\x00\x08lb-token\x00"
"\x00\x04link\x00"
"\x00\x16load-reporting-initial\x00"
"\x00\x17load-reporting-trailing\x00"
"\x00\x08location\x00"
"\x00\x0Cmax-forwards\x00"
"\x00\x07:method\x03GET"

@ -295,13 +295,13 @@ static void test_load_reporting_hook(grpc_end2end_test_config config) {
grpc_metadata initial_lr_metadata;
grpc_metadata trailing_lr_metadata;
initial_lr_metadata.key = GRPC_LOAD_REPORTING_INITIAL_MD_KEY;
initial_lr_metadata.key = GRPC_LB_TOKEN_MD_KEY;
initial_lr_metadata.value = "client-token";
initial_lr_metadata.value_length = strlen(initial_lr_metadata.value);
memset(&initial_lr_metadata.internal_data, 0,
sizeof(initial_lr_metadata.internal_data));
trailing_lr_metadata.key = GRPC_LOAD_REPORTING_TRAILING_MD_KEY;
trailing_lr_metadata.key = GRPC_LB_COST_MD_KEY;
trailing_lr_metadata.value = "server-token";
trailing_lr_metadata.value_length = strlen(trailing_lr_metadata.value);
memset(&trailing_lr_metadata.internal_data, 0,

@ -334,8 +334,7 @@ static void start_backend_server(server_fixture *sf) {
// have a version for int but does have one for long long int.
string expected_token = "token" + std::to_string((long long int)sf->port);
expected_token.resize(64, '-');
GPR_ASSERT(contains_metadata(&request_metadata_recv,
"load-reporting-initial",
GPR_ASSERT(contains_metadata(&request_metadata_recv, "lb-token",
expected_token.c_str()));
gpr_log(GPR_INFO, "Server[%s] after tag 100", sf->servers_hostport);

@ -79,7 +79,8 @@ DEFINE_string(test_case, "large_unary",
"slow_consumer : single request with response streaming with "
"slow client consumer;\n"
"status_code_and_message: verify status code & message;\n"
"timeout_on_sleeping_server: deadline exceeds on stream;\n");
"timeout_on_sleeping_server: deadline exceeds on stream;\n"
"unimplemented_method: client calls an unimplemented_method;\n");
DEFINE_string(default_service_account, "",
"Email of GCE default service account");
DEFINE_string(service_account_key_file, "",
@ -149,6 +150,8 @@ int main(int argc, char** argv) {
client.DoStatusWithMessage();
} else if (FLAGS_test_case == "custom_metadata") {
client.DoCustomMetadata();
} else if (FLAGS_test_case == "unimplemented_method") {
client.DoUnimplementedMethod();
} else if (FLAGS_test_case == "cacheable_unary") {
client.DoCacheableUnary();
} else if (FLAGS_test_case == "all") {
@ -168,6 +171,7 @@ int main(int argc, char** argv) {
client.DoEmptyStream();
client.DoStatusWithMessage();
client.DoCustomMetadata();
client.DoUnimplementedMethod();
client.DoCacheableUnary();
// service_account_creds and jwt_token_creds can only run with ssl.
if (FLAGS_use_tls) {
@ -202,7 +206,8 @@ int main(int argc, char** argv) {
"server_compressed_unary",
"server_streaming",
"status_code_and_message",
"timeout_on_sleeping_server"};
"timeout_on_sleeping_server",
"unimplemented_method"};
char* joined_testcases =
gpr_strjoin_sep(testcases, GPR_ARRAY_SIZE(testcases), "\n", NULL);

@ -981,5 +981,23 @@ bool InteropClient::DoCustomMetadata() {
return true;
}
bool InteropClient::DoUnimplementedMethod() {
gpr_log(GPR_DEBUG, "Sending a request for an unimplemented rpc...");
Empty request = Empty::default_instance();
Empty response = Empty::default_instance();
ClientContext context;
Status s =
serviceStub_.Get()->UnimplementedMethod(&context, request, &response);
if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED)) {
return false;
}
gpr_log(GPR_DEBUG, "unimplemented rpc done.");
return true;
}
} // namespace testing
} // namespace grpc

@ -79,6 +79,7 @@ class InteropClient {
bool DoEmptyStream();
bool DoStatusWithMessage();
bool DoCustomMetadata();
bool DoUnimplementedMethod();
bool DoCacheableUnary();
// Auth tests.
// username is a string containing the user email

@ -109,8 +109,8 @@ CONFIG = [
('if-range', ''),
('if-unmodified-since', ''),
('last-modified', ''),
('load-reporting-initial', ''),
('load-reporting-trailing', ''),
('lb-token', ''),
('lb-cost', ''),
('link', ''),
('location', ''),
('max-forwards', ''),

Loading…
Cancel
Save