diff --git a/Makefile b/Makefile index 706dd54425e..33411a9e1a1 100644 --- a/Makefile +++ b/Makefile @@ -1077,6 +1077,7 @@ boringssl_pqueue_test: $(BINDIR)/$(CONFIG)/boringssl_pqueue_test boringssl_ssl_test: $(BINDIR)/$(CONFIG)/boringssl_ssl_test badreq_bad_client_test: $(BINDIR)/$(CONFIG)/badreq_bad_client_test connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test +head_of_line_blocking_bad_client_test: $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test headers_bad_client_test: $(BINDIR)/$(CONFIG)/headers_bad_client_test initial_settings_frame_bad_client_test: $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test server_registered_method_bad_client_test: $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test @@ -1300,6 +1301,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/public_headers_must_be_c89 \ $(BINDIR)/$(CONFIG)/badreq_bad_client_test \ $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test \ + $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test \ $(BINDIR)/$(CONFIG)/headers_bad_client_test \ $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test \ $(BINDIR)/$(CONFIG)/server_registered_method_bad_client_test \ @@ -1623,6 +1625,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/badreq_bad_client_test || ( echo test badreq_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing connection_prefix_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test || ( echo test connection_prefix_bad_client_test failed ; exit 1 ) + $(E) "[RUN] Testing head_of_line_blocking_bad_client_test" + $(Q) $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test || ( echo test head_of_line_blocking_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing headers_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/headers_bad_client_test || ( echo test headers_bad_client_test failed ; exit 1 ) $(E) "[RUN] Testing initial_settings_frame_bad_client_test" @@ -5851,6 +5855,7 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/default_host.c \ test/core/end2end/tests/disappearing_server.c \ test/core/end2end/tests/empty_batch.c \ + test/core/end2end/tests/filter_causes_close.c \ test/core/end2end/tests/graceful_server_shutdown.c \ test/core/end2end/tests/high_initial_seqno.c \ test/core/end2end/tests/hpack_size.c \ @@ -5926,6 +5931,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/default_host.c \ test/core/end2end/tests/disappearing_server.c \ test/core/end2end/tests/empty_batch.c \ + test/core/end2end/tests/filter_causes_close.c \ test/core/end2end/tests/graceful_server_shutdown.c \ test/core/end2end/tests/high_initial_seqno.c \ test/core/end2end/tests/hpack_size.c \ @@ -12713,6 +12719,26 @@ ifneq ($(NO_DEPS),true) endif +HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC = \ + test/core/bad_client/tests/head_of_line_blocking.c \ + +HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_SRC)))) + + +$(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/head_of_line_blocking_bad_client_test + +$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/head_of_line_blocking.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_head_of_line_blocking_bad_client_test: $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(HEAD_OF_LINE_BLOCKING_BAD_CLIENT_TEST_OBJS:.o=.dep) +endif + + HEADERS_BAD_CLIENT_TEST_SRC = \ test/core/bad_client/tests/headers.c \ diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 8b460722e25..5c868aece37 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -289,6 +289,14 @@ GRPCAPI grpc_call_error grpc_server_request_call( grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new); +/** How to handle payloads for a registered method */ +typedef enum { + /** Don't try to read the payload */ + GRPC_SRM_PAYLOAD_NONE, + /** Read the initial payload as a byte buffer */ + GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER +} grpc_server_register_method_payload_handling; + /** Registers a method in the server. Methods to this (host, method) pair will not be reported by grpc_server_request_call, but instead be reported by @@ -296,9 +304,10 @@ GRPCAPI grpc_call_error grpc_server_request_call( registered_method (as returned by this function). Must be called before grpc_server_start. Returns NULL on failure. */ -GRPCAPI void *grpc_server_register_method(grpc_server *server, - const char *method, const char *host, - uint32_t flags); +GRPCAPI void *grpc_server_register_method( + grpc_server *server, const char *method, const char *host, + grpc_server_register_method_payload_handling payload_handling, + uint32_t flags); /** Request notification of a new pre-registered call. 'cq_for_notification' must have been registered to the server via diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index b09b1cdf441..38da99b4d72 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -185,7 +185,9 @@ typedef enum grpc_call_error { server */ GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE, /** this batch of operations leads to more operations than allowed */ - GRPC_CALL_ERROR_BATCH_TOO_BIG + GRPC_CALL_ERROR_BATCH_TOO_BIG, + /** payload type requested is not the type registered */ + GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH } grpc_call_error; /* Write Flags: */ diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index 62f0c53e0d5..b4cd185e62e 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -1147,16 +1147,18 @@ static void cancel_from_api(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, grpc_status_code status) { - if (stream_global->id != 0) { - gpr_slice_buffer_add( - &transport_global->qbuf, - grpc_chttp2_rst_stream_create( - stream_global->id, - (uint32_t)grpc_chttp2_grpc_status_to_http2_error(status), - &stream_global->stats.outgoing)); + if (!stream_global->read_closed || !stream_global->write_closed) { + if (stream_global->id != 0) { + gpr_slice_buffer_add( + &transport_global->qbuf, + grpc_chttp2_rst_stream_create( + stream_global->id, + (uint32_t)grpc_chttp2_grpc_status_to_http2_error(status), + &stream_global->stats.outgoing)); + } + grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status, + NULL); } - grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status, - NULL); grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1, 1); } diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index 6c42f612af0..b22bd69f44f 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -1080,7 +1080,6 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, grpc_metadata_batch *md = &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */]; grpc_metadata_batch_filter(md, recv_initial_filter, call); - call->has_initial_md_been_received = true; if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) != 0 && @@ -1089,15 +1088,16 @@ static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx, set_deadline_alarm(exec_ctx, call, md->deadline); GPR_TIMER_END("set_deadline_alarm", 0); } + } - if (call->saved_receiving_stream_ready_ctx.bctlp != NULL) { - grpc_closure *saved_rsr_closure = grpc_closure_create( - receiving_stream_ready, call->saved_receiving_stream_ready_ctx.bctlp); - grpc_exec_ctx_enqueue(exec_ctx, saved_rsr_closure, - call->saved_receiving_stream_ready_ctx.success, - NULL); - call->saved_receiving_stream_ready_ctx.bctlp = NULL; - } + call->has_initial_md_been_received = true; + if (call->saved_receiving_stream_ready_ctx.bctlp != NULL) { + grpc_closure *saved_rsr_closure = grpc_closure_create( + receiving_stream_ready, call->saved_receiving_stream_ready_ctx.bctlp); + grpc_exec_ctx_enqueue( + exec_ctx, saved_rsr_closure, + call->saved_receiving_stream_ready_ctx.success && success, NULL); + call->saved_receiving_stream_ready_ctx.bctlp = NULL; } gpr_mu_unlock(&call->mu); diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 1898bee1c1d..37cc2bd101d 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -95,7 +95,6 @@ typedef struct requested_call { grpc_byte_buffer **optional_payload; } registered; } data; - grpc_closure publish; } requested_call; typedef struct channel_registered_method { @@ -156,15 +155,21 @@ struct call_data { bool recv_idempotent_request; grpc_metadata_array initial_metadata; + request_matcher *request_matcher; + grpc_byte_buffer *payload; + grpc_closure got_initial_metadata; grpc_closure server_on_recv_initial_metadata; grpc_closure kill_zombie_closure; grpc_closure *on_done_recv_initial_metadata; + grpc_closure publish; + call_data *pending_next; }; struct request_matcher { + grpc_server *server; call_data *pending_head; call_data *pending_tail; gpr_stack_lockfree *requests; @@ -173,6 +178,7 @@ struct request_matcher { struct registered_method { char *method; char *host; + grpc_server_register_method_payload_handling payload_handling; uint32_t flags; request_matcher request_matcher; registered_method *next; @@ -226,8 +232,7 @@ struct grpc_server { #define SERVER_FROM_CALL_ELEM(elem) \ (((channel_data *)(elem)->channel_data)->server) -static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server, - call_data *calld, requested_call *rc); +static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *calld, bool success); static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, requested_call *rc); /* Before calling maybe_finish_shutdown, we must hold mu_global and not @@ -303,8 +308,10 @@ static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx, * request_matcher */ -static void request_matcher_init(request_matcher *rm, size_t entries) { +static void request_matcher_init(request_matcher *rm, size_t entries, + grpc_server *server) { memset(rm, 0, sizeof(*rm)); + rm->server = server; rm->requests = gpr_stack_lockfree_create(entries); } @@ -417,21 +424,90 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, channel_data *chand) { &op); } -static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server, - grpc_call_element *elem, request_matcher *rm) { - call_data *calld = elem->call_data; - int request_id; +static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) { + gpr_slice slice = value->slice; + size_t len = GPR_SLICE_LENGTH(slice); - if (gpr_atm_acq_load(&server->shutdown_flag)) { + if (len + 1 > *capacity) { + *capacity = GPR_MAX(len + 1, *capacity * 2); + *dest = gpr_realloc(*dest, *capacity); + } + memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1); +} + +static void done_request_event(grpc_exec_ctx *exec_ctx, void *req, + grpc_cq_completion *c) { + requested_call *rc = req; + grpc_server *server = rc->server; + + if (rc >= server->requested_calls && + rc < server->requested_calls + server->max_requested_calls) { + GPR_ASSERT(rc - server->requested_calls <= INT_MAX); + gpr_stack_lockfree_push(server->request_freelist, + (int)(rc - server->requested_calls)); + } else { + gpr_free(req); + } + + server_unref(exec_ctx, server); +} + +static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server, + call_data *calld, requested_call *rc) { + grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call); + grpc_call *call = calld->call; + *rc->call = call; + calld->cq_new = rc->cq_for_notification; + GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata); + switch (rc->type) { + case BATCH_CALL: + GPR_ASSERT(calld->host != NULL); + GPR_ASSERT(calld->path != NULL); + cpstr(&rc->data.batch.details->host, + &rc->data.batch.details->host_capacity, calld->host); + cpstr(&rc->data.batch.details->method, + &rc->data.batch.details->method_capacity, calld->path); + rc->data.batch.details->deadline = calld->deadline; + rc->data.batch.details->flags = + 0 | (calld->recv_idempotent_request + ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST + : 0); + break; + case REGISTERED_CALL: + *rc->data.registered.deadline = calld->deadline; + if (rc->data.registered.optional_payload) { + *rc->data.registered.optional_payload = calld->payload; + } + break; + default: + GPR_UNREACHABLE_CODE(return ); + } + + grpc_call_element *elem = + grpc_call_stack_element(grpc_call_get_call_stack(call), 0); + channel_data *chand = elem->channel_data; + server_ref(chand->server); + grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, true, done_request_event, rc, + &rc->completion); +} + +static void publish_new_rpc(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + call_data *calld = arg; + request_matcher *rm = calld->request_matcher; + grpc_server *server = rm->server; + + if (!success || gpr_atm_acq_load(&server->shutdown_flag)) { gpr_mu_lock(&calld->mu_state); calld->state = ZOMBIED; gpr_mu_unlock(&calld->mu_state); - grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem); + grpc_closure_init( + &calld->kill_zombie_closure, kill_zombie, + grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0)); grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); return; } - request_id = gpr_stack_lockfree_pop(rm->requests); + int request_id = gpr_stack_lockfree_pop(rm->requests); if (request_id == -1) { gpr_mu_lock(&server->mu_call); gpr_mu_lock(&calld->mu_state); @@ -449,7 +525,41 @@ static void finish_start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_server *server, gpr_mu_lock(&calld->mu_state); calld->state = ACTIVATED; gpr_mu_unlock(&calld->mu_state); - begin_call(exec_ctx, server, calld, &server->requested_calls[request_id]); + publish_call(exec_ctx, server, calld, &server->requested_calls[request_id]); + } +} + +static void finish_start_new_rpc( + grpc_exec_ctx *exec_ctx, grpc_server *server, grpc_call_element *elem, + request_matcher *rm, + grpc_server_register_method_payload_handling payload_handling) { + call_data *calld = elem->call_data; + + if (gpr_atm_acq_load(&server->shutdown_flag)) { + gpr_mu_lock(&calld->mu_state); + calld->state = ZOMBIED; + gpr_mu_unlock(&calld->mu_state); + grpc_closure_init(&calld->kill_zombie_closure, kill_zombie, elem); + grpc_exec_ctx_enqueue(exec_ctx, &calld->kill_zombie_closure, true, NULL); + return; + } + + calld->request_matcher = rm; + + switch (payload_handling) { + case GRPC_SRM_PAYLOAD_NONE: + publish_new_rpc(exec_ctx, calld, true); + break; + case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: { + grpc_op op; + memset(&op, 0, sizeof(op)); + op.op = GRPC_OP_RECV_MESSAGE; + op.data.recv_message = &calld->payload; + grpc_closure_init(&calld->publish, publish_new_rpc, calld); + grpc_call_start_batch_and_execute(exec_ctx, calld->call, &op, 1, + &calld->publish); + break; + } } } @@ -475,7 +585,8 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { !calld->recv_idempotent_request) continue; finish_start_new_rpc(exec_ctx, server, elem, - &rm->server_registered_method->request_matcher); + &rm->server_registered_method->request_matcher, + rm->server_registered_method->payload_handling); return; } /* check for a wildcard method definition (no host set) */ @@ -490,12 +601,14 @@ static void start_new_rpc(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { !calld->recv_idempotent_request) continue; finish_start_new_rpc(exec_ctx, server, elem, - &rm->server_registered_method->request_matcher); + &rm->server_registered_method->request_matcher, + rm->server_registered_method->payload_handling); return; } } finish_start_new_rpc(exec_ctx, server, elem, - &server->unregistered_request_matcher); + &server->unregistered_request_matcher, + GRPC_SRM_PAYLOAD_NONE); } static int num_listeners(grpc_server *server) { @@ -824,7 +937,7 @@ grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) { gpr_stack_lockfree_push(server->request_freelist, (int)i); } request_matcher_init(&server->unregistered_request_matcher, - server->max_requested_calls); + server->max_requested_calls, server); server->requested_calls = gpr_malloc(server->max_requested_calls * sizeof(*server->requested_calls)); @@ -840,8 +953,10 @@ static int streq(const char *a, const char *b) { return 0 == strcmp(a, b); } -void *grpc_server_register_method(grpc_server *server, const char *method, - const char *host, uint32_t flags) { +void *grpc_server_register_method( + grpc_server *server, const char *method, const char *host, + grpc_server_register_method_payload_handling payload_handling, + uint32_t flags) { registered_method *m; GRPC_API_TRACE( "grpc_server_register_method(server=%p, method=%s, host=%s, " @@ -866,10 +981,12 @@ void *grpc_server_register_method(grpc_server *server, const char *method, } m = gpr_malloc(sizeof(registered_method)); memset(m, 0, sizeof(*m)); - request_matcher_init(&m->request_matcher, server->max_requested_calls); + request_matcher_init(&m->request_matcher, server->max_requested_calls, + server); m->method = gpr_strdup(method); m->host = gpr_strdup(host); m->next = server->registered_methods; + m->payload_handling = payload_handling; m->flags = flags; server->registered_methods = m; return m; @@ -1143,8 +1260,8 @@ static grpc_call_error queue_call_request(grpc_exec_ctx *exec_ctx, GPR_ASSERT(calld->state == PENDING); calld->state = ACTIVATED; gpr_mu_unlock(&calld->mu_state); - begin_call(exec_ctx, server, calld, - &server->requested_calls[request_id]); + publish_call(exec_ctx, server, calld, + &server->requested_calls[request_id]); } gpr_mu_lock(&server->mu_call); } @@ -1209,6 +1326,12 @@ grpc_call_error grpc_server_request_registered_call( error = GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE; goto done; } + if ((optional_payload == NULL) != + (rm->payload_handling == GRPC_SRM_PAYLOAD_NONE)) { + gpr_free(rc); + error = GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH; + goto done; + } grpc_cq_begin_op(cq_for_notification, tag); rc->type = REGISTERED_CALL; rc->server = server; @@ -1226,86 +1349,6 @@ done: return error; } -static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, - void *user_data, bool success); - -static void cpstr(char **dest, size_t *capacity, grpc_mdstr *value) { - gpr_slice slice = value->slice; - size_t len = GPR_SLICE_LENGTH(slice); - - if (len + 1 > *capacity) { - *capacity = GPR_MAX(len + 1, *capacity * 2); - *dest = gpr_realloc(*dest, *capacity); - } - memcpy(*dest, grpc_mdstr_as_c_string(value), len + 1); -} - -static void begin_call(grpc_exec_ctx *exec_ctx, grpc_server *server, - call_data *calld, requested_call *rc) { - grpc_op ops[1]; - grpc_op *op = ops; - - memset(ops, 0, sizeof(ops)); - - /* called once initial metadata has been read by the call, but BEFORE - the ioreq to fetch it out of the call has been executed. - This means metadata related fields can be relied on in calld, but to - fill in the metadata array passed by the client, we need to perform - an ioreq op, that should complete immediately. */ - - grpc_call_set_completion_queue(exec_ctx, calld->call, rc->cq_bound_to_call); - grpc_closure_init(&rc->publish, publish_registered_or_batch, rc); - *rc->call = calld->call; - calld->cq_new = rc->cq_for_notification; - GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata); - switch (rc->type) { - case BATCH_CALL: - GPR_ASSERT(calld->host != NULL); - GPR_ASSERT(calld->path != NULL); - cpstr(&rc->data.batch.details->host, - &rc->data.batch.details->host_capacity, calld->host); - cpstr(&rc->data.batch.details->method, - &rc->data.batch.details->method_capacity, calld->path); - rc->data.batch.details->deadline = calld->deadline; - rc->data.batch.details->flags = - 0 | (calld->recv_idempotent_request - ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST - : 0); - break; - case REGISTERED_CALL: - *rc->data.registered.deadline = calld->deadline; - if (rc->data.registered.optional_payload) { - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = rc->data.registered.optional_payload; - op++; - } - break; - default: - GPR_UNREACHABLE_CODE(return ); - } - - GRPC_CALL_INTERNAL_REF(calld->call, "server"); - grpc_call_start_batch_and_execute(exec_ctx, calld->call, ops, - (size_t)(op - ops), &rc->publish); -} - -static void done_request_event(grpc_exec_ctx *exec_ctx, void *req, - grpc_cq_completion *c) { - requested_call *rc = req; - grpc_server *server = rc->server; - - if (rc >= server->requested_calls && - rc < server->requested_calls + server->max_requested_calls) { - GPR_ASSERT(rc - server->requested_calls <= INT_MAX); - gpr_stack_lockfree_push(server->request_freelist, - (int)(rc - server->requested_calls)); - } else { - gpr_free(req); - } - - server_unref(exec_ctx, server); -} - static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, requested_call *rc) { *rc->call = NULL; @@ -1316,20 +1359,6 @@ static void fail_call(grpc_exec_ctx *exec_ctx, grpc_server *server, done_request_event, rc, &rc->completion); } -static void publish_registered_or_batch(grpc_exec_ctx *exec_ctx, void *prc, - bool success) { - requested_call *rc = prc; - grpc_call *call = *rc->call; - grpc_call_element *elem = - grpc_call_stack_element(grpc_call_get_call_stack(call), 0); - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - server_ref(chand->server); - grpc_cq_end_op(exec_ctx, calld->cq_new, rc->tag, success, done_request_event, - rc, &rc->completion); - GRPC_CALL_INTERNAL_UNREF(exec_ctx, call, "server"); -} - const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) { return server->channel_args; } diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 3e44c502fce..fafe31e84c1 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -321,6 +321,19 @@ void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { g_callbacks.reset(callbacks); } +static grpc_server_register_method_payload_handling PayloadHandlingForMethod( + RpcServiceMethod* method) { + switch (method->method_type()) { + case RpcMethod::NORMAL_RPC: + case RpcMethod::SERVER_STREAMING: + return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER; + case RpcMethod::CLIENT_STREAMING: + case RpcMethod::BIDI_STREAMING: + return GRPC_SRM_PAYLOAD_NONE; + } + GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;); +} + bool Server::RegisterService(const grpc::string* host, Service* service) { bool has_async_methods = service->has_async_methods(); if (has_async_methods) { @@ -334,8 +347,9 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { continue; } RpcServiceMethod* method = it->get(); - void* tag = grpc_server_register_method(server_, method->name(), - host ? host->c_str() : nullptr, 0); + void* tag = grpc_server_register_method( + server_, method->name(), host ? host->c_str() : nullptr, + PayloadHandlingForMethod(method), 0); if (tag == nullptr) { gpr_log(GPR_DEBUG, "Attempt to register %s multiple times", method->name()); diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h index adcd8e954a3..272e85b4857 100644 --- a/src/python/grpcio/grpc/_cython/imports.generated.h +++ b/src/python/grpcio/grpc/_cython/imports.generated.h @@ -283,7 +283,7 @@ extern grpc_call_destroy_type grpc_call_destroy_import; typedef grpc_call_error(*grpc_server_request_call_type)(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new); extern grpc_server_request_call_type grpc_server_request_call_import; #define grpc_server_request_call grpc_server_request_call_import -typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, uint32_t flags); +typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, grpc_server_register_method_payload_handling payload_handling, uint32_t flags); extern grpc_server_register_method_type grpc_server_register_method_import; #define grpc_server_register_method grpc_server_register_method_import typedef grpc_call_error(*grpc_server_request_registered_call_type)(grpc_server *server, void *registered_method, grpc_call **call, gpr_timespec *deadline, grpc_metadata_array *request_metadata, grpc_byte_buffer **optional_payload, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 22ea84c7509..c526f434c61 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -283,7 +283,7 @@ extern grpc_call_destroy_type grpc_call_destroy_import; typedef grpc_call_error(*grpc_server_request_call_type)(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new); extern grpc_server_request_call_type grpc_server_request_call_import; #define grpc_server_request_call grpc_server_request_call_import -typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, uint32_t flags); +typedef void *(*grpc_server_register_method_type)(grpc_server *server, const char *method, const char *host, grpc_server_register_method_payload_handling payload_handling, uint32_t flags); extern grpc_server_register_method_type grpc_server_register_method_import; #define grpc_server_register_method grpc_server_register_method_import typedef grpc_call_error(*grpc_server_request_registered_call_type)(grpc_server *server, void *registered_method, grpc_call **call, gpr_timespec *deadline, grpc_metadata_array *request_metadata, grpc_byte_buffer **optional_payload, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new); diff --git a/templates/test/core/end2end/end2end_defs.include b/templates/test/core/end2end/end2end_defs.include index fb44271158c..b828f84f1c6 100644 --- a/templates/test/core/end2end/end2end_defs.include +++ b/templates/test/core/end2end/end2end_defs.include @@ -37,18 +37,32 @@ #include "test/core/end2end/end2end_tests.h" +#include #include #include +static bool g_pre_init_called = false; + % for test in tests: extern void ${test}(grpc_end2end_test_config config); +extern void ${test}_pre_init(void); % endfor +void grpc_end2end_tests_pre_init(void) { + GPR_ASSERT(!g_pre_init_called); + g_pre_init_called = true; +% for test in tests: + ${test}_pre_init(); +% endfor +} + void grpc_end2end_tests(int argc, char **argv, grpc_end2end_test_config config) { int i; + GPR_ASSERT(g_pre_init_called); + if (argc <= 1) { % for test in tests: ${test}(config); diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c index 2b9a551dfb7..cd5b5412492 100644 --- a/test/core/bad_client/bad_client.c +++ b/test/core/bad_client/bad_client.c @@ -112,7 +112,8 @@ void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator, grpc_server_register_completion_queue(a.server, a.cq, NULL); a.registered_method = grpc_server_register_method(a.server, GRPC_BAD_CLIENT_REGISTERED_METHOD, - GRPC_BAD_CLIENT_REGISTERED_HOST, 0); + GRPC_BAD_CLIENT_REGISTERED_HOST, + GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, 0); grpc_server_start(a.server); transport = grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, 0); server_setup_transport(&a, transport); diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py index ca26eda170a..d49858ed6d8 100755 --- a/test/core/bad_client/gen_build_yaml.py +++ b/test/core/bad_client/gen_build_yaml.py @@ -44,6 +44,7 @@ BAD_CLIENT_TESTS = { 'connection_prefix': default_test_options._replace(cpu_cost=0.2), 'headers': default_test_options._replace(cpu_cost=0.2), 'initial_settings_frame': default_test_options._replace(cpu_cost=0.2), + 'head_of_line_blocking': default_test_options, 'server_registered_method': default_test_options, 'simple_request': default_test_options, 'window_overflow': default_test_options, diff --git a/test/core/bad_client/tests/head_of_line_blocking.c b/test/core/bad_client/tests/head_of_line_blocking.c new file mode 100644 index 00000000000..53cd4537b2f --- /dev/null +++ b/test/core/bad_client/tests/head_of_line_blocking.c @@ -0,0 +1,151 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/core/bad_client/bad_client.h" + +#include + +#include + +#include "src/core/lib/surface/server.h" +#include "test/core/end2end/cq_verifier.h" + +static const char prefix[] = + "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" + // settings frame + "\x00\x00\x00\x04\x00\x00\x00\x00\x00" + // stream 1 headers: generated from server_registered_method.headers in this + // directory + "\x00\x00\xd0\x01\x04\x00\x00\x00\x01" + "\x10\x05:path\x0f/registered/bar" + "\x10\x07:scheme\x04http" + "\x10\x07:method\x04POST" + "\x10\x0a:authority\x09localhost" + "\x10\x0c" + "content-type\x10" + "application/grpc" + "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip" + "\x10\x02te\x08trailers" + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + // data frame for stream 1: advertise a 10000 byte payload (that we won't + // fulfill) + "\x00\x00\x05\x00\x00\x00\x00\x00\x01" + "\x01\x00\x00\x27\x10" + // stream 3 headers: generated from server_registered_method.headers in this + // directory + "\x00\x00\xd0\x01\x04\x00\x00\x00\x03" + "\x10\x05:path\x0f/registered/bar" + "\x10\x07:scheme\x04http" + "\x10\x07:method\x04POST" + "\x10\x0a:authority\x09localhost" + "\x10\x0c" + "content-type\x10" + "application/grpc" + "\x10\x14grpc-accept-encoding\x15identity,deflate,gzip" + "\x10\x02te\x08trailers" + "\x10\x0auser-agent\"bad-client grpc-c/0.12.0.0 (linux)" + // data frame for stream 3: advertise a 10000 byte payload (that we will + // fulfill) + "\x00\x00\x05\x00\x00\x00\x00\x00\x03" + "\x01\x00\x00\x27\x10" + ""; + +static void *tag(intptr_t t) { return (void *)t; } + +static void verifier(grpc_server *server, grpc_completion_queue *cq, + void *registered_method) { + grpc_call_error error; + grpc_call *s; + cq_verifier *cqv = cq_verifier_create(cq); + grpc_metadata_array request_metadata_recv; + gpr_timespec deadline; + grpc_byte_buffer *payload = NULL; + + grpc_metadata_array_init(&request_metadata_recv); + + error = grpc_server_request_registered_call(server, registered_method, &s, + &deadline, &request_metadata_recv, + &payload, cq, cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + cq_expect_completion(cqv, tag(101), 1); + cq_verify(cqv); + + GPR_ASSERT(payload != NULL); + + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_destroy(s); + grpc_byte_buffer_destroy(payload); + cq_verifier_destroy(cqv); +} + +char *g_buffer; +size_t g_cap = 0; +size_t g_count = 0; + +static void addbuf(const void *data, size_t len) { + if (g_count + len > g_cap) { + g_cap = GPR_MAX(g_count + len, g_cap * 2); + g_buffer = gpr_realloc(g_buffer, g_cap); + } + memcpy(g_buffer + g_count, data, len); + g_count += len; +} + +int main(int argc, char **argv) { + int i; + grpc_test_init(argc, argv); + +#define NUM_FRAMES 10 +#define FRAME_SIZE 1000 + + addbuf(prefix, sizeof(prefix) - 1); + for (i = 0; i < NUM_FRAMES; i++) { + uint8_t hdr[9] = {(uint8_t)(FRAME_SIZE >> 16), + (uint8_t)(FRAME_SIZE >> 8), + (uint8_t)FRAME_SIZE, + 0, + 0, + 0, + 0, + 0, + 3}; + uint8_t msg[FRAME_SIZE]; + memset(msg, 'a', sizeof(msg)); + addbuf(hdr, sizeof(hdr)); + addbuf(msg, FRAME_SIZE); + } + grpc_run_bad_client_test(verifier, g_buffer, g_count, 0); + gpr_free(g_buffer); + + return 0; +} diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c index deb73395e04..b71299c09e0 100644 --- a/test/core/end2end/end2end_nosec_tests.c +++ b/test/core/end2end/end2end_nosec_tests.c @@ -36,51 +36,136 @@ #include "test/core/end2end/end2end_tests.h" +#include #include #include +static bool g_pre_init_called = false; + extern void bad_hostname(grpc_end2end_test_config config); +extern void bad_hostname_pre_init(void); extern void binary_metadata(grpc_end2end_test_config config); +extern void binary_metadata_pre_init(void); extern void cancel_after_accept(grpc_end2end_test_config config); +extern void cancel_after_accept_pre_init(void); extern void cancel_after_client_done(grpc_end2end_test_config config); +extern void cancel_after_client_done_pre_init(void); extern void cancel_after_invoke(grpc_end2end_test_config config); +extern void cancel_after_invoke_pre_init(void); extern void cancel_before_invoke(grpc_end2end_test_config config); +extern void cancel_before_invoke_pre_init(void); extern void cancel_in_a_vacuum(grpc_end2end_test_config config); +extern void cancel_in_a_vacuum_pre_init(void); extern void cancel_with_status(grpc_end2end_test_config config); +extern void cancel_with_status_pre_init(void); extern void compressed_payload(grpc_end2end_test_config config); +extern void compressed_payload_pre_init(void); extern void connectivity(grpc_end2end_test_config config); +extern void connectivity_pre_init(void); extern void default_host(grpc_end2end_test_config config); +extern void default_host_pre_init(void); extern void disappearing_server(grpc_end2end_test_config config); +extern void disappearing_server_pre_init(void); extern void empty_batch(grpc_end2end_test_config config); +extern void empty_batch_pre_init(void); +extern void filter_causes_close(grpc_end2end_test_config config); +extern void filter_causes_close_pre_init(void); extern void graceful_server_shutdown(grpc_end2end_test_config config); +extern void graceful_server_shutdown_pre_init(void); extern void high_initial_seqno(grpc_end2end_test_config config); +extern void high_initial_seqno_pre_init(void); extern void hpack_size(grpc_end2end_test_config config); +extern void hpack_size_pre_init(void); extern void idempotent_request(grpc_end2end_test_config config); +extern void idempotent_request_pre_init(void); extern void invoke_large_request(grpc_end2end_test_config config); +extern void invoke_large_request_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); +extern void large_metadata_pre_init(void); extern void max_concurrent_streams(grpc_end2end_test_config config); +extern void max_concurrent_streams_pre_init(void); extern void max_message_length(grpc_end2end_test_config config); +extern void max_message_length_pre_init(void); extern void negative_deadline(grpc_end2end_test_config config); +extern void negative_deadline_pre_init(void); extern void no_op(grpc_end2end_test_config config); +extern void no_op_pre_init(void); extern void payload(grpc_end2end_test_config config); +extern void payload_pre_init(void); extern void ping(grpc_end2end_test_config config); +extern void ping_pre_init(void); extern void ping_pong_streaming(grpc_end2end_test_config config); +extern void ping_pong_streaming_pre_init(void); extern void registered_call(grpc_end2end_test_config config); +extern void registered_call_pre_init(void); extern void request_with_flags(grpc_end2end_test_config config); +extern void request_with_flags_pre_init(void); extern void request_with_payload(grpc_end2end_test_config config); +extern void request_with_payload_pre_init(void); extern void server_finishes_request(grpc_end2end_test_config config); +extern void server_finishes_request_pre_init(void); extern void shutdown_finishes_calls(grpc_end2end_test_config config); +extern void shutdown_finishes_calls_pre_init(void); extern void shutdown_finishes_tags(grpc_end2end_test_config config); +extern void shutdown_finishes_tags_pre_init(void); extern void simple_delayed_request(grpc_end2end_test_config config); +extern void simple_delayed_request_pre_init(void); extern void simple_metadata(grpc_end2end_test_config config); +extern void simple_metadata_pre_init(void); extern void simple_request(grpc_end2end_test_config config); +extern void simple_request_pre_init(void); extern void trailing_metadata(grpc_end2end_test_config config); +extern void trailing_metadata_pre_init(void); + +void grpc_end2end_tests_pre_init(void) { + GPR_ASSERT(!g_pre_init_called); + g_pre_init_called = true; + bad_hostname_pre_init(); + binary_metadata_pre_init(); + cancel_after_accept_pre_init(); + cancel_after_client_done_pre_init(); + cancel_after_invoke_pre_init(); + cancel_before_invoke_pre_init(); + cancel_in_a_vacuum_pre_init(); + cancel_with_status_pre_init(); + compressed_payload_pre_init(); + connectivity_pre_init(); + default_host_pre_init(); + disappearing_server_pre_init(); + empty_batch_pre_init(); + filter_causes_close_pre_init(); + graceful_server_shutdown_pre_init(); + high_initial_seqno_pre_init(); + hpack_size_pre_init(); + idempotent_request_pre_init(); + invoke_large_request_pre_init(); + large_metadata_pre_init(); + max_concurrent_streams_pre_init(); + max_message_length_pre_init(); + negative_deadline_pre_init(); + no_op_pre_init(); + payload_pre_init(); + ping_pre_init(); + ping_pong_streaming_pre_init(); + registered_call_pre_init(); + request_with_flags_pre_init(); + request_with_payload_pre_init(); + server_finishes_request_pre_init(); + shutdown_finishes_calls_pre_init(); + shutdown_finishes_tags_pre_init(); + simple_delayed_request_pre_init(); + simple_metadata_pre_init(); + simple_request_pre_init(); + trailing_metadata_pre_init(); +} void grpc_end2end_tests(int argc, char **argv, grpc_end2end_test_config config) { int i; + GPR_ASSERT(g_pre_init_called); + if (argc <= 1) { bad_hostname(config); binary_metadata(config); @@ -95,6 +180,7 @@ void grpc_end2end_tests(int argc, char **argv, default_host(config); disappearing_server(config); empty_batch(config); + filter_causes_close(config); graceful_server_shutdown(config); high_initial_seqno(config); hpack_size(config); @@ -174,6 +260,10 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); continue; } + if (0 == strcmp("filter_causes_close", argv[i])) { + filter_causes_close(config); + continue; + } if (0 == strcmp("graceful_server_shutdown", argv[i])) { graceful_server_shutdown(config); continue; diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c index dd7f6a2a311..00c9c44a78c 100644 --- a/test/core/end2end/end2end_tests.c +++ b/test/core/end2end/end2end_tests.c @@ -36,52 +36,139 @@ #include "test/core/end2end/end2end_tests.h" +#include #include #include +static bool g_pre_init_called = false; + extern void bad_hostname(grpc_end2end_test_config config); +extern void bad_hostname_pre_init(void); extern void binary_metadata(grpc_end2end_test_config config); +extern void binary_metadata_pre_init(void); extern void call_creds(grpc_end2end_test_config config); +extern void call_creds_pre_init(void); extern void cancel_after_accept(grpc_end2end_test_config config); +extern void cancel_after_accept_pre_init(void); extern void cancel_after_client_done(grpc_end2end_test_config config); +extern void cancel_after_client_done_pre_init(void); extern void cancel_after_invoke(grpc_end2end_test_config config); +extern void cancel_after_invoke_pre_init(void); extern void cancel_before_invoke(grpc_end2end_test_config config); +extern void cancel_before_invoke_pre_init(void); extern void cancel_in_a_vacuum(grpc_end2end_test_config config); +extern void cancel_in_a_vacuum_pre_init(void); extern void cancel_with_status(grpc_end2end_test_config config); +extern void cancel_with_status_pre_init(void); extern void compressed_payload(grpc_end2end_test_config config); +extern void compressed_payload_pre_init(void); extern void connectivity(grpc_end2end_test_config config); +extern void connectivity_pre_init(void); extern void default_host(grpc_end2end_test_config config); +extern void default_host_pre_init(void); extern void disappearing_server(grpc_end2end_test_config config); +extern void disappearing_server_pre_init(void); extern void empty_batch(grpc_end2end_test_config config); +extern void empty_batch_pre_init(void); +extern void filter_causes_close(grpc_end2end_test_config config); +extern void filter_causes_close_pre_init(void); extern void graceful_server_shutdown(grpc_end2end_test_config config); +extern void graceful_server_shutdown_pre_init(void); extern void high_initial_seqno(grpc_end2end_test_config config); +extern void high_initial_seqno_pre_init(void); extern void hpack_size(grpc_end2end_test_config config); +extern void hpack_size_pre_init(void); extern void idempotent_request(grpc_end2end_test_config config); +extern void idempotent_request_pre_init(void); extern void invoke_large_request(grpc_end2end_test_config config); +extern void invoke_large_request_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); +extern void large_metadata_pre_init(void); extern void max_concurrent_streams(grpc_end2end_test_config config); +extern void max_concurrent_streams_pre_init(void); extern void max_message_length(grpc_end2end_test_config config); +extern void max_message_length_pre_init(void); extern void negative_deadline(grpc_end2end_test_config config); +extern void negative_deadline_pre_init(void); extern void no_op(grpc_end2end_test_config config); +extern void no_op_pre_init(void); extern void payload(grpc_end2end_test_config config); +extern void payload_pre_init(void); extern void ping(grpc_end2end_test_config config); +extern void ping_pre_init(void); extern void ping_pong_streaming(grpc_end2end_test_config config); +extern void ping_pong_streaming_pre_init(void); extern void registered_call(grpc_end2end_test_config config); +extern void registered_call_pre_init(void); extern void request_with_flags(grpc_end2end_test_config config); +extern void request_with_flags_pre_init(void); extern void request_with_payload(grpc_end2end_test_config config); +extern void request_with_payload_pre_init(void); extern void server_finishes_request(grpc_end2end_test_config config); +extern void server_finishes_request_pre_init(void); extern void shutdown_finishes_calls(grpc_end2end_test_config config); +extern void shutdown_finishes_calls_pre_init(void); extern void shutdown_finishes_tags(grpc_end2end_test_config config); +extern void shutdown_finishes_tags_pre_init(void); extern void simple_delayed_request(grpc_end2end_test_config config); +extern void simple_delayed_request_pre_init(void); extern void simple_metadata(grpc_end2end_test_config config); +extern void simple_metadata_pre_init(void); extern void simple_request(grpc_end2end_test_config config); +extern void simple_request_pre_init(void); extern void trailing_metadata(grpc_end2end_test_config config); +extern void trailing_metadata_pre_init(void); + +void grpc_end2end_tests_pre_init(void) { + GPR_ASSERT(!g_pre_init_called); + g_pre_init_called = true; + bad_hostname_pre_init(); + binary_metadata_pre_init(); + call_creds_pre_init(); + cancel_after_accept_pre_init(); + cancel_after_client_done_pre_init(); + cancel_after_invoke_pre_init(); + cancel_before_invoke_pre_init(); + cancel_in_a_vacuum_pre_init(); + cancel_with_status_pre_init(); + compressed_payload_pre_init(); + connectivity_pre_init(); + default_host_pre_init(); + disappearing_server_pre_init(); + empty_batch_pre_init(); + filter_causes_close_pre_init(); + graceful_server_shutdown_pre_init(); + high_initial_seqno_pre_init(); + hpack_size_pre_init(); + idempotent_request_pre_init(); + invoke_large_request_pre_init(); + large_metadata_pre_init(); + max_concurrent_streams_pre_init(); + max_message_length_pre_init(); + negative_deadline_pre_init(); + no_op_pre_init(); + payload_pre_init(); + ping_pre_init(); + ping_pong_streaming_pre_init(); + registered_call_pre_init(); + request_with_flags_pre_init(); + request_with_payload_pre_init(); + server_finishes_request_pre_init(); + shutdown_finishes_calls_pre_init(); + shutdown_finishes_tags_pre_init(); + simple_delayed_request_pre_init(); + simple_metadata_pre_init(); + simple_request_pre_init(); + trailing_metadata_pre_init(); +} void grpc_end2end_tests(int argc, char **argv, grpc_end2end_test_config config) { int i; + GPR_ASSERT(g_pre_init_called); + if (argc <= 1) { bad_hostname(config); binary_metadata(config); @@ -97,6 +184,7 @@ void grpc_end2end_tests(int argc, char **argv, default_host(config); disappearing_server(config); empty_batch(config); + filter_causes_close(config); graceful_server_shutdown(config); high_initial_seqno(config); hpack_size(config); @@ -180,6 +268,10 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); continue; } + if (0 == strcmp("filter_causes_close", argv[i])) { + filter_causes_close(config); + continue; + } if (0 == strcmp("graceful_server_shutdown", argv[i])) { graceful_server_shutdown(config); continue; diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h index bc44f43a178..dfa041c0c64 100644 --- a/test/core/end2end/end2end_tests.h +++ b/test/core/end2end/end2end_tests.h @@ -64,6 +64,7 @@ struct grpc_end2end_test_config { void (*tear_down_data)(grpc_end2end_test_fixture *f); }; +void grpc_end2end_tests_pre_init(void); void grpc_end2end_tests(int argc, char **argv, grpc_end2end_test_config config); #endif /* GRPC_TEST_CORE_END2END_END2END_TESTS_H */ diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c index 9d41ff2dbb4..9b6f2bf80db 100644 --- a/test/core/end2end/fixtures/h2_census.c +++ b/test/core/end2end/fixtures/h2_census.c @@ -120,6 +120,7 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c index 55355b58dda..fe72c6851f1 100644 --- a/test/core/end2end/fixtures/h2_compress.c +++ b/test/core/end2end/fixtures/h2_compress.c @@ -124,6 +124,7 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/fixtures/h2_fakesec.c b/test/core/end2end/fixtures/h2_fakesec.c index a312585946a..246619bf685 100644 --- a/test/core/end2end/fixtures/h2_fakesec.c +++ b/test/core/end2end/fixtures/h2_fakesec.c @@ -150,7 +150,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); - + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/fixtures/h2_full+pipe.c b/test/core/end2end/fixtures/h2_full+pipe.c index a3e2196bf62..11e6d0eff2e 100644 --- a/test/core/end2end/fixtures/h2_full+pipe.c +++ b/test/core/end2end/fixtures/h2_full+pipe.c @@ -108,6 +108,7 @@ int main(int argc, char **argv) { grpc_allow_specialized_wakeup_fd = 0; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/fixtures/h2_full+trace.c b/test/core/end2end/fixtures/h2_full+trace.c index 986a06bd010..7599412dfbb 100644 --- a/test/core/end2end/fixtures/h2_full+trace.c +++ b/test/core/end2end/fixtures/h2_full+trace.c @@ -116,6 +116,7 @@ int main(int argc, char **argv) { #endif grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); GPR_ASSERT(0 == grpc_tracer_set_enabled("also-doesnt-exist", 0)); diff --git a/test/core/end2end/fixtures/h2_full.c b/test/core/end2end/fixtures/h2_full.c index d0797e0a644..d4ee2aeb9d7 100644 --- a/test/core/end2end/fixtures/h2_full.c +++ b/test/core/end2end/fixtures/h2_full.c @@ -105,6 +105,7 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/fixtures/h2_oauth2.c b/test/core/end2end/fixtures/h2_oauth2.c index 9e7d8d31253..550ff331408 100644 --- a/test/core/end2end/fixtures/h2_oauth2.c +++ b/test/core/end2end/fixtures/h2_oauth2.c @@ -226,7 +226,7 @@ static grpc_end2end_test_config configs[] = { int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); - + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/fixtures/h2_proxy.c b/test/core/end2end/fixtures/h2_proxy.c index 4650da98e37..8f6f156ef7e 100644 --- a/test/core/end2end/fixtures/h2_proxy.c +++ b/test/core/end2end/fixtures/h2_proxy.c @@ -120,6 +120,7 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c index 9fdceabbaf7..4eb1c57302f 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.c +++ b/test/core/end2end/fixtures/h2_sockpair+trace.c @@ -150,6 +150,7 @@ int main(int argc, char **argv) { #endif grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); grpc_exec_ctx_finish(&exec_ctx); diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c index 84777158b6d..7760d38100f 100644 --- a/test/core/end2end/fixtures/h2_sockpair.c +++ b/test/core/end2end/fixtures/h2_sockpair.c @@ -139,6 +139,7 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c index 6b6ca19885f..23a5a19c598 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.c +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c @@ -139,6 +139,7 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/fixtures/h2_ssl.c b/test/core/end2end/fixtures/h2_ssl.c index e5a255f7c3f..69f76160746 100644 --- a/test/core/end2end/fixtures/h2_ssl.c +++ b/test/core/end2end/fixtures/h2_ssl.c @@ -165,6 +165,7 @@ int main(int argc, char **argv) { char *roots_filename; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); /* Set the SSL roots env var. */ roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c index 9edc8a0c234..1403b760f50 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.c +++ b/test/core/end2end/fixtures/h2_ssl_proxy.c @@ -195,6 +195,7 @@ int main(int argc, char **argv) { char *roots_filename; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); /* Set the SSL roots env var. */ roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename); diff --git a/test/core/end2end/fixtures/h2_uds.c b/test/core/end2end/fixtures/h2_uds.c index 9216860a646..d454a103cef 100644 --- a/test/core/end2end/fixtures/h2_uds.c +++ b/test/core/end2end/fixtures/h2_uds.c @@ -110,6 +110,7 @@ int main(int argc, char **argv) { size_t i; grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); grpc_init(); for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 43ad22e714c..9a940a4ab51 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -94,6 +94,7 @@ END2END_TESTS = { needs_dns=True), 'disappearing_server': connectivity_test_options, 'empty_batch': default_test_options, + 'filter_causes_close': default_test_options, 'graceful_server_shutdown': default_test_options._replace(cpu_cost=LOWCPU), 'hpack_size': default_test_options._replace(proxyable=False, traceable=False), diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c index eb1fa46de39..3cb9b3d4b12 100644 --- a/test/core/end2end/tests/bad_hostname.c +++ b/test/core/end2end/tests/bad_hostname.c @@ -179,3 +179,5 @@ void bad_hostname(grpc_end2end_test_config config) { test_invoke_simple_request(config); } } + +void bad_hostname_pre_init(void) {} diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c index 54583b09bc1..994c3bf1dd2 100644 --- a/test/core/end2end/tests/binary_metadata.c +++ b/test/core/end2end/tests/binary_metadata.c @@ -287,3 +287,5 @@ static void test_request_response_with_metadata_and_payload( void binary_metadata(grpc_end2end_test_config config) { test_request_response_with_metadata_and_payload(config); } + +void binary_metadata_pre_init(void) {} diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c index a3f86a76c7d..b555bea740b 100644 --- a/test/core/end2end/tests/call_creds.c +++ b/test/core/end2end/tests/call_creds.c @@ -475,3 +475,5 @@ void call_creds(grpc_end2end_test_config config) { test_request_with_server_rejecting_client_creds(config); } } + +void call_creds_pre_init(void) {} diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 08d0ef6e51c..fc2a64a6c18 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -233,3 +233,5 @@ void cancel_after_accept(grpc_end2end_test_config config) { test_cancel_after_accept(config, cancellation_modes[i]); } } + +void cancel_after_accept_pre_init(void) {} diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c index f85ffad1181..3bafa8c85fd 100644 --- a/test/core/end2end/tests/cancel_after_client_done.c +++ b/test/core/end2end/tests/cancel_after_client_done.c @@ -237,3 +237,5 @@ void cancel_after_client_done(grpc_end2end_test_config config) { test_cancel_after_accept_and_writes_closed(config, cancellation_modes[i]); } } + +void cancel_after_client_done_pre_init(void) {} diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c index e7d6e0098a1..fc2751af8e1 100644 --- a/test/core/end2end/tests/cancel_after_invoke.c +++ b/test/core/end2end/tests/cancel_after_invoke.c @@ -199,3 +199,5 @@ void cancel_after_invoke(grpc_end2end_test_config config) { } } } + +void cancel_after_invoke_pre_init(void) {} diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c index a4f47f01fa6..33005db9e45 100644 --- a/test/core/end2end/tests/cancel_before_invoke.c +++ b/test/core/end2end/tests/cancel_before_invoke.c @@ -194,3 +194,5 @@ void cancel_before_invoke(grpc_end2end_test_config config) { test_cancel_before_invoke(config, i); } } + +void cancel_before_invoke_pre_init(void) {} diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c index 73a6fc452ab..0c893b5f9ef 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum.c @@ -127,3 +127,5 @@ void cancel_in_a_vacuum(grpc_end2end_test_config config) { test_cancel_in_a_vacuum(config, cancellation_modes[i]); } } + +void cancel_in_a_vacuum_pre_init(void) {} diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c index aa73d488910..c3ee4a6a0ee 100644 --- a/test/core/end2end/tests/cancel_with_status.c +++ b/test/core/end2end/tests/cancel_with_status.c @@ -182,3 +182,5 @@ void cancel_with_status(grpc_end2end_test_config config) { test_invoke_simple_request(config, i); } } + +void cancel_with_status_pre_init(void) {} diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c index d5cf9a78584..589bc314f8e 100644 --- a/test/core/end2end/tests/compressed_payload.c +++ b/test/core/end2end/tests/compressed_payload.c @@ -336,3 +336,5 @@ void compressed_payload(grpc_end2end_test_config config) { test_invoke_request_with_compressed_payload(config); test_invoke_request_with_compressed_payload_md_override(config); } + +void compressed_payload_pre_init(void) {} diff --git a/test/core/end2end/tests/connectivity.c b/test/core/end2end/tests/connectivity.c index edef2ff68b7..5775976b1cb 100644 --- a/test/core/end2end/tests/connectivity.c +++ b/test/core/end2end/tests/connectivity.c @@ -172,3 +172,5 @@ void connectivity(grpc_end2end_test_config config) { GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION); test_connectivity(config); } + +void connectivity_pre_init(void) {} diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c index 105f4e68f0f..44384a783ec 100644 --- a/test/core/end2end/tests/default_host.c +++ b/test/core/end2end/tests/default_host.c @@ -232,3 +232,5 @@ void default_host(grpc_end2end_test_config config) { return; test_invoke_simple_request(config); } + +void default_host_pre_init(void) {} diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c index 5b2bbaf70cd..03d1ded04cf 100644 --- a/test/core/end2end/tests/disappearing_server.c +++ b/test/core/end2end/tests/disappearing_server.c @@ -213,3 +213,5 @@ void disappearing_server(grpc_end2end_test_config config) { GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION); disappearing_server_test(config); } + +void disappearing_server_pre_init(void) {} diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c index 95df93ac5b5..c05b9199146 100644 --- a/test/core/end2end/tests/empty_batch.c +++ b/test/core/end2end/tests/empty_batch.c @@ -132,3 +132,5 @@ static void test_invoke_empty_body(grpc_end2end_test_config config) { void empty_batch(grpc_end2end_test_config config) { test_invoke_empty_body(config); } + +void empty_batch_pre_init(void) {} diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c new file mode 100644 index 00000000000..d4a9f6fac4a --- /dev/null +++ b/test/core/end2end/tests/filter_causes_close.c @@ -0,0 +1,290 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include "src/core/lib/channel/channel_stack_builder.h" +#include "src/core/lib/surface/channel_init.h" +#include "test/core/end2end/cq_verifier.h" + +enum { TIMEOUT = 200000 }; + +static bool g_enable_filter = false; + +static void *tag(intptr_t t) { return (void *)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char *test_name, + grpc_channel_args *client_args, + grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "%s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_time(int n) { + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); +} + +static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture *f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = NULL; +} + +static void shutdown_client(grpc_end2end_test_fixture *f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = NULL; +} + +static void end_test(grpc_end2end_test_fixture *f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); +} + +/* Request with a large amount of metadata.*/ +static void test_request(grpc_end2end_test_config config) { + grpc_call *c; + grpc_call *s; + gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); + grpc_byte_buffer *request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + gpr_timespec deadline = five_seconds_time(); + grpc_end2end_test_fixture f = + begin_test(config, "filter_causes_close", NULL, NULL); + cq_verifier *cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer *request_payload_recv = NULL; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + char *details = NULL; + size_t details_capacity = 0; + + c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + "/foo", "foo.test.google.fr", deadline, NULL); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->data.send_initial_metadata.metadata = NULL; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = request_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->data.recv_status_on_client.status_details_capacity = &details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + + cq_expect_completion(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED); + GPR_ASSERT(0 == strcmp(details, "Random failure that's not preventable.")); + + gpr_free(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_destroy(c); + + cq_verifier_destroy(cqv); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(request_payload_recv); + + end_test(&f); + config.tear_down_data(&f); +} + +/******************************************************************************* + * Test filter - always closes incoming requests + */ + +typedef struct { grpc_closure *recv_im_ready; } call_data; + +typedef struct { +} channel_data; + +static void recv_im_ready(grpc_exec_ctx *exec_ctx, void *arg, bool success) { + grpc_call_element *elem = arg; + call_data *calld = elem->call_data; + if (success) { + // close the stream with an error. + gpr_slice message; + grpc_transport_stream_op close_op; + memset(&close_op, 0, sizeof(close_op)); + message = + gpr_slice_from_copied_string("Random failure that's not preventable."); + grpc_transport_stream_op op; + memset(&op, 0, sizeof(op)); + grpc_transport_stream_op_add_close(&op, GRPC_STATUS_PERMISSION_DENIED, + &message); + grpc_call_next_op(exec_ctx, elem, &op); + } + calld->recv_im_ready->cb(exec_ctx, calld->recv_im_ready->cb_arg, false); +} + +static void start_transport_stream_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + call_data *calld = elem->call_data; + if (op->recv_initial_metadata != NULL) { + calld->recv_im_ready = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = grpc_closure_create(recv_im_ready, elem); + } + grpc_call_next_op(exec_ctx, elem, op); +} + +static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_call_element_args *args) {} + +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) {} + +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) {} + +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) {} + +static const grpc_channel_filter test_filter = { + start_transport_stream_op, + grpc_channel_next_op, + sizeof(call_data), + init_call_elem, + grpc_call_stack_ignore_set_pollset, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "filter_causes_close"}; + +/******************************************************************************* + * Registration + */ + +static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) { + if (g_enable_filter) { + return grpc_channel_stack_builder_prepend_filter(builder, &test_filter, + NULL, NULL); + } else { + return true; + } +} + +static void init_plugin(void) { + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, 0, maybe_add_filter, + NULL); +} + +static void destroy_plugin(void) {} + +void filter_causes_close(grpc_end2end_test_config config) { + g_enable_filter = true; + test_request(config); + g_enable_filter = false; +} + +void filter_causes_close_pre_init(void) { + grpc_register_plugin(init_plugin, destroy_plugin); +} diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c index cc6a9d44f8a..26198f3bdfc 100644 --- a/test/core/end2end/tests/graceful_server_shutdown.c +++ b/test/core/end2end/tests/graceful_server_shutdown.c @@ -210,3 +210,5 @@ static void test_early_server_shutdown_finishes_inflight_calls( void graceful_server_shutdown(grpc_end2end_test_config config) { test_early_server_shutdown_finishes_inflight_calls(config); } + +void graceful_server_shutdown_pre_init(void) {} diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c index 8b6e50bdd8d..374606dcb73 100644 --- a/test/core/end2end/tests/high_initial_seqno.c +++ b/test/core/end2end/tests/high_initial_seqno.c @@ -237,3 +237,5 @@ void high_initial_seqno(grpc_end2end_test_config config) { test_invoke_10_simple_requests(config, 2147483645); } } + +void high_initial_seqno_pre_init(void) {} diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c index 15efcd23bff..07d5d387b4c 100644 --- a/test/core/end2end/tests/hpack_size.c +++ b/test/core/end2end/tests/hpack_size.c @@ -444,3 +444,5 @@ void hpack_size(grpc_end2end_test_config config) { } } } + +void hpack_size_pre_init(void) {} diff --git a/test/core/end2end/tests/idempotent_request.c b/test/core/end2end/tests/idempotent_request.c index 485a8544419..42a672bf199 100644 --- a/test/core/end2end/tests/idempotent_request.c +++ b/test/core/end2end/tests/idempotent_request.c @@ -246,3 +246,5 @@ void idempotent_request(grpc_end2end_test_config config) { } test_invoke_10_simple_requests(config); } + +void idempotent_request_pre_init(void) {} diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c index 28c0e364616..6410305451a 100644 --- a/test/core/end2end/tests/invoke_large_request.c +++ b/test/core/end2end/tests/invoke_large_request.c @@ -254,3 +254,5 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { void invoke_large_request(grpc_end2end_test_config config) { test_invoke_large_request(config); } + +void invoke_large_request_pre_init(void) {} diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c index 173c20996ea..0e5d6b4fe01 100644 --- a/test/core/end2end/tests/large_metadata.c +++ b/test/core/end2end/tests/large_metadata.c @@ -245,3 +245,5 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { void large_metadata(grpc_end2end_test_config config) { test_request_with_large_metadata(config); } + +void large_metadata_pre_init(void) {} diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c index 60e9ecd7d8c..1bb53073cb0 100644 --- a/test/core/end2end/tests/max_concurrent_streams.c +++ b/test/core/end2end/tests/max_concurrent_streams.c @@ -436,3 +436,5 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { void max_concurrent_streams(grpc_end2end_test_config config) { test_max_concurrent_streams(config); } + +void max_concurrent_streams_pre_init(void) {} diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c index 00a83ecb336..b5dbc1382a8 100644 --- a/test/core/end2end/tests/max_message_length.c +++ b/test/core/end2end/tests/max_message_length.c @@ -221,3 +221,5 @@ static void test_max_message_length(grpc_end2end_test_config config) { void max_message_length(grpc_end2end_test_config config) { test_max_message_length(config); } + +void max_message_length_pre_init(void) {} diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c index 0cc68a33a1d..03e57a90f6f 100644 --- a/test/core/end2end/tests/negative_deadline.c +++ b/test/core/end2end/tests/negative_deadline.c @@ -179,3 +179,5 @@ void negative_deadline(grpc_end2end_test_config config) { test_invoke_simple_request(config, i); } } + +void negative_deadline_pre_init(void) {} diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c index 9dda569cb9f..284be7af2ae 100644 --- a/test/core/end2end/tests/no_op.c +++ b/test/core/end2end/tests/no_op.c @@ -104,3 +104,5 @@ static void test_no_op(grpc_end2end_test_config config) { } void no_op(grpc_end2end_test_config config) { test_no_op(config); } + +void no_op_pre_init(void) {} diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index e9272b6bce2..bdfb1354068 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -268,3 +268,5 @@ void payload(grpc_end2end_test_config config) { test_invoke_request_response_with_payload(config); test_invoke_10_request_response_with_payload(config); } + +void payload_pre_init(void) {} diff --git a/test/core/end2end/tests/ping.c b/test/core/end2end/tests/ping.c index f42f1865020..d49bec983be 100644 --- a/test/core/end2end/tests/ping.c +++ b/test/core/end2end/tests/ping.c @@ -95,3 +95,5 @@ void ping(grpc_end2end_test_config config) { GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION); test_ping(config); } + +void ping_pre_init(void) {} diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c index ac4e8105731..15e1c6e338a 100644 --- a/test/core/end2end/tests/ping_pong_streaming.c +++ b/test/core/end2end/tests/ping_pong_streaming.c @@ -275,3 +275,5 @@ void ping_pong_streaming(grpc_end2end_test_config config) { test_pingpong_streaming(config, i); } } + +void ping_pong_streaming_pre_init(void) {} diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c index a67df863d54..3c4edbae7dc 100644 --- a/test/core/end2end/tests/registered_call.c +++ b/test/core/end2end/tests/registered_call.c @@ -231,3 +231,5 @@ void registered_call(grpc_end2end_test_config config) { test_invoke_simple_request(config); test_invoke_10_simple_requests(config); } + +void registered_call_pre_init(void) {} diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c index 9d01ddc94ce..779895b9701 100644 --- a/test/core/end2end/tests/request_with_flags.c +++ b/test/core/end2end/tests/request_with_flags.c @@ -214,3 +214,5 @@ void request_with_flags(grpc_end2end_test_config config) { } } } + +void request_with_flags_pre_init(void) {} diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c index 9866d390000..77064040909 100644 --- a/test/core/end2end/tests/request_with_payload.c +++ b/test/core/end2end/tests/request_with_payload.c @@ -232,3 +232,5 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { void request_with_payload(grpc_end2end_test_config config) { test_invoke_request_with_payload(config); } + +void request_with_payload_pre_init(void) {} diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c index 2a26c989162..a4f5319e5b4 100644 --- a/test/core/end2end/tests/server_finishes_request.c +++ b/test/core/end2end/tests/server_finishes_request.c @@ -210,3 +210,5 @@ static void test_invoke_simple_request(grpc_end2end_test_config config) { void server_finishes_request(grpc_end2end_test_config config) { test_invoke_simple_request(config); } + +void server_finishes_request_pre_init(void) {} diff --git a/test/core/end2end/tests/shutdown_finishes_calls.c b/test/core/end2end/tests/shutdown_finishes_calls.c index b56ba464b9b..80287cd507a 100644 --- a/test/core/end2end/tests/shutdown_finishes_calls.c +++ b/test/core/end2end/tests/shutdown_finishes_calls.c @@ -192,3 +192,5 @@ static void test_early_server_shutdown_finishes_inflight_calls( void shutdown_finishes_calls(grpc_end2end_test_config config) { test_early_server_shutdown_finishes_inflight_calls(config); } + +void shutdown_finishes_calls_pre_init(void) {} diff --git a/test/core/end2end/tests/shutdown_finishes_tags.c b/test/core/end2end/tests/shutdown_finishes_tags.c index 4a060de716b..b1f3c94562a 100644 --- a/test/core/end2end/tests/shutdown_finishes_tags.c +++ b/test/core/end2end/tests/shutdown_finishes_tags.c @@ -119,3 +119,5 @@ static void test_early_server_shutdown_finishes_tags( void shutdown_finishes_tags(grpc_end2end_test_config config) { test_early_server_shutdown_finishes_tags(config); } + +void shutdown_finishes_tags_pre_init(void) {} diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c index bb9d462cef1..013f1e39810 100644 --- a/test/core/end2end/tests/simple_delayed_request.c +++ b/test/core/end2end/tests/simple_delayed_request.c @@ -221,3 +221,5 @@ void simple_delayed_request(grpc_end2end_test_config config) { test_simple_delayed_request_short(config); test_simple_delayed_request_long(config); } + +void simple_delayed_request_pre_init(void) {} diff --git a/test/core/end2end/tests/simple_metadata.c b/test/core/end2end/tests/simple_metadata.c index 084c0df817b..707b3c9512c 100644 --- a/test/core/end2end/tests/simple_metadata.c +++ b/test/core/end2end/tests/simple_metadata.c @@ -263,3 +263,5 @@ static void test_request_response_with_metadata_and_payload( void simple_metadata(grpc_end2end_test_config config) { test_request_response_with_metadata_and_payload(config); } + +void simple_metadata_pre_init(void) {} diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index 68db58d225c..42108425e6f 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -246,3 +246,5 @@ void simple_request(grpc_end2end_test_config config) { } test_invoke_10_simple_requests(config); } + +void simple_request_pre_init(void) {} diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c index 99e1e2264a5..4dd8c12cba9 100644 --- a/test/core/end2end/tests/trailing_metadata.c +++ b/test/core/end2end/tests/trailing_metadata.c @@ -268,3 +268,5 @@ static void test_request_response_with_metadata_and_payload( void trailing_metadata(grpc_end2end_test_config config) { test_request_response_with_metadata_and_payload(config); } + +void trailing_metadata_pre_init(void) {} diff --git a/test/core/surface/server_test.c b/test/core/surface/server_test.c index 4c62d8caadb..7bb45434f47 100644 --- a/test/core/surface/server_test.c +++ b/test/core/surface/server_test.c @@ -42,19 +42,25 @@ void test_register_method_fail(void) { grpc_server *server = grpc_server_create(NULL, NULL); void *method; void *method_old; - method = grpc_server_register_method(server, NULL, NULL, 0); + method = + grpc_server_register_method(server, NULL, NULL, GRPC_SRM_PAYLOAD_NONE, 0); GPR_ASSERT(method == NULL); - method_old = grpc_server_register_method(server, "m", "h", 0); + method_old = + grpc_server_register_method(server, "m", "h", GRPC_SRM_PAYLOAD_NONE, 0); GPR_ASSERT(method_old != NULL); - method = grpc_server_register_method(server, "m", "h", 0); + method = grpc_server_register_method( + server, "m", "h", GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, 0); GPR_ASSERT(method == NULL); - method_old = grpc_server_register_method( - server, "m2", "h2", GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST); + method_old = + grpc_server_register_method(server, "m2", "h2", GRPC_SRM_PAYLOAD_NONE, + GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST); GPR_ASSERT(method_old != NULL); - method = grpc_server_register_method(server, "m2", "h2", 0); + method = + grpc_server_register_method(server, "m2", "h2", GRPC_SRM_PAYLOAD_NONE, 0); GPR_ASSERT(method == NULL); method = grpc_server_register_method( - server, "m2", "h2", GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST); + server, "m2", "h2", GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, + GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST); GPR_ASSERT(method == NULL); grpc_server_destroy(server); } diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index f81c88c44b9..75d21e77dfc 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -3176,6 +3176,23 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "bad_client_test", + "gpr", + "gpr_test_util", + "grpc_test_util_unsecure", + "grpc_unsecure" + ], + "headers": [], + "language": "c", + "name": "head_of_line_blocking_bad_client_test", + "src": [ + "test/core/bad_client/tests/head_of_line_blocking.c" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "bad_client_test", @@ -6611,6 +6628,7 @@ "test/core/end2end/tests/default_host.c", "test/core/end2end/tests/disappearing_server.c", "test/core/end2end/tests/empty_batch.c", + "test/core/end2end/tests/filter_causes_close.c", "test/core/end2end/tests/graceful_server_shutdown.c", "test/core/end2end/tests/high_initial_seqno.c", "test/core/end2end/tests/hpack_size.c", @@ -6668,6 +6686,7 @@ "test/core/end2end/tests/default_host.c", "test/core/end2end/tests/disappearing_server.c", "test/core/end2end/tests/empty_batch.c", + "test/core/end2end/tests/filter_causes_close.c", "test/core/end2end/tests/graceful_server_shutdown.c", "test/core/end2end/tests/high_initial_seqno.c", "test/core/end2end/tests/hpack_size.c", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 05f52923d3a..d0e80e35fe9 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -2608,6 +2608,27 @@ "windows" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "head_of_line_blocking_bad_client_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ @@ -4602,6 +4623,28 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_census_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -5416,6 +5459,28 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_compress_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -6216,6 +6281,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_fakesec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -7007,6 +7093,28 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -7737,6 +7845,22 @@ "linux" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full+pipe_test", + "platforms": [ + "linux" + ] + }, { "args": [ "graceful_server_shutdown" @@ -8413,6 +8537,28 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full+trace_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -9191,6 +9337,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_oauth2_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -9926,6 +10093,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_proxy_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -10556,6 +10744,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -11228,6 +11437,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -11879,6 +12109,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -12628,6 +12879,28 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -13386,6 +13659,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_ssl_proxy_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -14045,6 +14339,26 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_uds_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -14791,6 +15105,28 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_census_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -15583,6 +15919,28 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_compress_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -16375,6 +16733,28 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -17089,6 +17469,22 @@ "linux" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "linux" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full+pipe_nosec_test", + "platforms": [ + "linux" + ] + }, { "args": [ "graceful_server_shutdown" @@ -17743,6 +18139,28 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_full+trace_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -18458,6 +18876,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_proxy_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -19067,6 +19506,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -19718,6 +20178,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair+trace_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -20348,6 +20829,27 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "windows", + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_sockpair_1byte_nosec_test", + "platforms": [ + "windows", + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" @@ -21029,6 +21531,26 @@ "posix" ] }, + { + "args": [ + "filter_causes_close" + ], + "ci_platforms": [ + "linux", + "mac", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "language": "c", + "name": "h2_uds_nosec_test", + "platforms": [ + "linux", + "mac", + "posix" + ] + }, { "args": [ "graceful_server_shutdown" diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln index 01c060421c6..a582f2b7196 100644 --- a/vsprojects/buildtests_c.sln +++ b/vsprojects/buildtests_c.sln @@ -1066,6 +1066,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "connection_prefix_bad_clien {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "head_of_line_blocking_bad_client_test", "vcxproj\test\head_of_line_blocking_bad_client_test\head_of_line_blocking_bad_client_test.vcxproj", "{23DF0572-DBF1-08DA-8EAD-8508354C90A4}" + ProjectSection(myProperties) = preProject + lib = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5} + {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} + {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "headers_bad_client_test", "vcxproj\test\headers_bad_client_test\headers_bad_client_test.vcxproj", "{7819A11E-607E-F0C0-FC47-C704CF7D818C}" ProjectSection(myProperties) = preProject lib = "False" @@ -3038,6 +3050,22 @@ Global {AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|Win32.Build.0 = Release|Win32 {AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|x64.ActiveCfg = Release|x64 {AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|x64.Build.0 = Release|x64 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|Win32.ActiveCfg = Debug|Win32 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|x64.ActiveCfg = Debug|x64 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|Win32.ActiveCfg = Release|Win32 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|x64.ActiveCfg = Release|x64 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|Win32.Build.0 = Debug|Win32 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|x64.Build.0 = Debug|x64 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|Win32.Build.0 = Release|Win32 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|x64.Build.0 = Release|x64 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|Win32.Build.0 = Debug|Win32 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|x64.ActiveCfg = Debug|x64 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|x64.Build.0 = Debug|x64 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|Win32.ActiveCfg = Release|Win32 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|Win32.Build.0 = Release|Win32 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|x64.ActiveCfg = Release|x64 + {23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|x64.Build.0 = Release|x64 {7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|Win32.ActiveCfg = Debug|Win32 {7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|x64.ActiveCfg = Debug|x64 {7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj index d54d21b66e3..dfd1e3a6d08 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj @@ -179,6 +179,8 @@ + + diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters index 99622e228d6..5fef6bd0128 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters @@ -43,6 +43,9 @@ test\core\end2end\tests + + test\core\end2end\tests + test\core\end2end\tests diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj index c0b21c9ae14..a580fa4576b 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj @@ -181,6 +181,8 @@ + + diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters index 791589863e0..8de70029718 100644 --- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters +++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters @@ -46,6 +46,9 @@ test\core\end2end\tests + + test\core\end2end\tests + test\core\end2end\tests diff --git a/vsprojects/vcxproj/test/head_of_line_blocking_bad_client_test/head_of_line_blocking_bad_client_test.vcxproj b/vsprojects/vcxproj/test/head_of_line_blocking_bad_client_test/head_of_line_blocking_bad_client_test.vcxproj new file mode 100644 index 00000000000..fb10f95574c --- /dev/null +++ b/vsprojects/vcxproj/test/head_of_line_blocking_bad_client_test/head_of_line_blocking_bad_client_test.vcxproj @@ -0,0 +1,202 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {23DF0572-DBF1-08DA-8EAD-8508354C90A4} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + head_of_line_blocking_bad_client_test + static + Debug + static + Debug + + + head_of_line_blocking_bad_client_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {BA67B418-B699-E41A-9CC4-0279C49481A5} + + + {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} + + + {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/head_of_line_blocking_bad_client_test/head_of_line_blocking_bad_client_test.vcxproj.filters b/vsprojects/vcxproj/test/head_of_line_blocking_bad_client_test/head_of_line_blocking_bad_client_test.vcxproj.filters new file mode 100644 index 00000000000..c3609f0de42 --- /dev/null +++ b/vsprojects/vcxproj/test/head_of_line_blocking_bad_client_test/head_of_line_blocking_bad_client_test.vcxproj.filters @@ -0,0 +1,24 @@ + + + + + test\core\bad_client\tests + + + + + + {c7d7f2b5-9afd-5668-b11f-ceb3a3503569} + + + {3175d310-96bd-0c78-72e3-b5985873fa82} + + + {d7e592e2-acda-4572-59b7-20845fb05bd5} + + + {1fa3207b-dc88-d316-7c13-9ac70ddc850e} + + + +