aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Sree Kuchibhotla <sreek@google.com>2016-06-10 09:24:40 -0700
committerGravatar Sree Kuchibhotla <sreek@google.com>2016-06-10 09:24:40 -0700
commit11e3c07616fdbf4576969334e0cf57680b2dd3fd (patch)
tree730c8dfb2a5190d3e8c5d799c7520bb5790e4eab
parent492fd961824447e7f12974893dd9bbf37291e5cc (diff)
parent698d3e91ff42db3fe640cc369e8edf85abc5343d (diff)
Merge branch 'master' into epoll_changes
-rw-r--r--examples/cpp/helloworld/greeter_async_client.cc4
-rw-r--r--examples/cpp/helloworld/greeter_async_server.cc4
-rw-r--r--setup.py3
-rw-r--r--src/compiler/objective_c_generator.cc42
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.c71
-rw-r--r--src/core/ext/transport/chttp2/transport/internal.h3
-rw-r--r--src/core/lib/channel/channel_stack.c2
-rw-r--r--src/core/lib/channel/channel_stack.h3
-rw-r--r--src/core/lib/channel/channel_stack_builder.c4
-rw-r--r--src/core/lib/channel/http_client_filter.c13
-rw-r--r--src/core/lib/channel/http_client_filter.h2
-rw-r--r--src/csharp/Grpc.Core.Tests/ServerTest.cs15
-rw-r--r--src/csharp/Grpc.Core/Server.cs3
-rw-r--r--src/python/grpcio/tests/unit/_cython/cygrpc_test.py284
-rw-r--r--src/python/grpcio/tests/unit/_cython/test_utilities.py34
-rw-r--r--test/core/channel/channel_stack_test.c2
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206bin0 -> 100 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/552199651d942e7220141a93ec33dd8256210a18bin0 -> 46 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/7a946bf3cd91b63001f2cf3f40c515c747f2ecdebin0 -> 696 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/7d25c28298fb4d0fe41209d0d14307e4aa67c59ebin0 -> 47 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/8138b18a9a743659befc2f2b23d23cb9c3086a09bin0 -> 348 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/925011abb99fd56bb0f425ae5e0d92e6d341f804bin0 -> 49 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/crash-c1f66840627e3bfdedf2e4c225bc4de0c267ed37bin0 -> 100 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/d6bed9cc3c10338a8c5f41064ff8bec0bbc267cebin0 -> 48 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/dda9643679f8c8b796e64232a7d153e447d64991bin0 -> 650 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/e7b08e36420fa107f0aee652e62158af85a4ef15bin0 -> 1091 bytes
-rw-r--r--test/cpp/end2end/end2end_test.cc10
-rwxr-xr-xtools/distrib/python/check_grpcio_tools.py2
-rw-r--r--tools/distrib/python/grpcio_tools/README.rst10
-rw-r--r--tools/distrib/python/grpcio_tools/grpc/tools/protoc.py5
-rw-r--r--tools/distrib/python/grpcio_tools/protoc_lib_deps.py4
-rw-r--r--tools/distrib/python/grpcio_tools/setup.py36
-rwxr-xr-xtools/distrib/python/make_grpcio_tools.py35
-rw-r--r--tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile7
-rw-r--r--tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile7
-rwxr-xr-xtools/run_tests/build_artifact_python.sh4
-rw-r--r--tools/run_tests/tests.json170
37 files changed, 561 insertions, 218 deletions
diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc
index c1f5eb55f0..33de59fb95 100644
--- a/examples/cpp/helloworld/greeter_async_client.cc
+++ b/examples/cpp/helloworld/greeter_async_client.cc
@@ -87,7 +87,9 @@ class GreeterClient {
void* got_tag;
bool ok = false;
// Block until the next result is available in the completion queue "cq".
- cq.Next(&got_tag, &ok);
+ // The return value of Next should always be checked. This return value
+ // tells us whether there is any kind of event or the cq_ is shutting down.
+ GPR_ASSERT(cq.Next(&got_tag, &ok));
// Verify that the result from "cq" corresponds, by its tag, our previous
// request.
diff --git a/examples/cpp/helloworld/greeter_async_server.cc b/examples/cpp/helloworld/greeter_async_server.cc
index 64e065b1e4..ead44182e5 100644
--- a/examples/cpp/helloworld/greeter_async_server.cc
+++ b/examples/cpp/helloworld/greeter_async_server.cc
@@ -160,7 +160,9 @@ class ServerImpl final {
// Block waiting to read the next event from the completion queue. The
// event is uniquely identified by its tag, which in this case is the
// memory address of a CallData instance.
- cq_->Next(&tag, &ok);
+ // The return value of Next should always be checked. This return value
+ // tells us whether there is any kind of event or cq_ is shutting down.
+ GPR_ASSERT(cq_->Next(&tag, &ok));
GPR_ASSERT(ok);
static_cast<CallData*>(tag)->Proceed();
}
diff --git a/setup.py b/setup.py
index 0e2646d5d2..018d0470f4 100644
--- a/setup.py
+++ b/setup.py
@@ -234,8 +234,7 @@ setuptools.setup(
ext_modules=CYTHON_EXTENSION_MODULES,
packages=list(PACKAGES),
package_dir=PACKAGE_DIRECTORIES,
- # TODO(atash): Figure out why auditwheel doesn't like namespace packages.
- #namespace_packages=['grpc'],
+ namespace_packages=['grpc'],
package_data=PACKAGE_DATA,
install_requires=INSTALL_REQUIRES,
setup_requires=SETUP_REQUIRES,
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
index 71a674174d..4be8cb4187 100644
--- a/src/compiler/objective_c_generator.cc
+++ b/src/compiler/objective_c_generator.cc
@@ -60,9 +60,34 @@ void PrintProtoRpcDeclarationAsPragma(Printer *printer,
" returns ($server_stream$$response_type$)\n\n");
}
+template <typename DescriptorType>
+static void PrintAllComments(const DescriptorType* desc, Printer* printer) {
+ std::vector<grpc::string> comments;
+ grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED,
+ &comments);
+ grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING,
+ &comments);
+ grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_TRAILING,
+ &comments);
+ if (comments.empty()) {
+ return;
+ }
+ printer->Print("/**\n");
+ for (auto it = comments.begin(); it != comments.end(); ++it) {
+ printer->Print(" * ");
+ size_t start_pos = it->find_first_not_of(' ');
+ if (start_pos != grpc::string::npos) {
+ printer->Print(it->c_str() + start_pos);
+ }
+ printer->Print("\n");
+ }
+ printer->Print(" */\n");
+}
+
void PrintMethodSignature(Printer *printer, const MethodDescriptor *method,
const map< ::grpc::string, ::grpc::string> &vars) {
- // TODO(jcanizales): Print method comments.
+ // Print comment
+ PrintAllComments(method, printer);
printer->Print(vars, "- ($return_type$)$method_name$With");
if (method->client_streaming()) {
@@ -195,8 +220,10 @@ void PrintMethodImplementations(Printer *printer,
printer.Print("@end\n\n");
printer.Print(
- "// Basic service implementation, over gRPC, that only does"
- " marshalling and parsing.\n");
+ "/**\n"
+ " * Basic service implementation, over gRPC, that only does\n"
+ " * marshalling and parsing.\n"
+ " */\n");
printer.Print(vars,
"@interface $service_class$ :"
" GRPCProtoService<$service_class$>\n");
@@ -220,18 +247,13 @@ void PrintMethodImplementations(Printer *printer,
{"service_class", ServiceClassName(service)},
{"package", service->file()->package()}};
- printer.Print(vars,
- "static NSString *const kPackageName = @\"$package$\";\n");
- printer.Print(
- vars, "static NSString *const kServiceName = @\"$service_name$\";\n\n");
-
printer.Print(vars, "@implementation $service_class$\n\n");
printer.Print("// Designated initializer\n");
printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
- printer.Print(
+ printer.Print(vars,
" return (self = [super initWithHost:host"
- " packageName:kPackageName serviceName:kServiceName]);\n");
+ " packageName:@\"$package$\" serviceName:@\"$service_name$\"]);\n");
printer.Print("}\n\n");
printer.Print(
"// Override superclass initializer to disallow different"
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 046b395001..2375a4587f 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -47,6 +47,7 @@
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include "src/core/ext/transport/chttp2/transport/status_conversion.h"
#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h"
+#include "src/core/lib/http/parser.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h"
@@ -107,7 +108,8 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
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);
+ grpc_status_code status,
+ gpr_slice *optional_message);
static void close_from_api(grpc_exec_ctx *exec_ctx,
grpc_chttp2_transport_global *transport_global,
@@ -161,6 +163,8 @@ static void destruct_transport(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(t->ep == NULL);
+ gpr_slice_unref(t->optional_drop_message);
+
gpr_slice_buffer_destroy(&t->global.qbuf);
gpr_slice_buffer_destroy(&t->writing.outbuf);
@@ -260,6 +264,7 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
t->parsing.deframe_state =
is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
t->writing.is_client = is_client;
+ t->optional_drop_message = gpr_empty_slice();
grpc_connectivity_state_init(
&t->channel_callback.state_tracker, GRPC_CHANNEL_READY,
is_client ? "client_transport" : "server_transport");
@@ -804,8 +809,10 @@ void grpc_chttp2_add_incoming_goaway(
gpr_free(msg);
gpr_slice_unref(goaway_text);
transport_global->seen_goaway = 1;
- connectivity_state_set(exec_ctx, transport_global, GRPC_CHANNEL_SHUTDOWN,
- "got_goaway");
+ /* lie: use transient failure from the transport to indicate goaway has been
+ * received */
+ connectivity_state_set(exec_ctx, transport_global,
+ GRPC_CHANNEL_TRANSIENT_FAILURE, "got_goaway");
}
static void maybe_start_some_streams(
@@ -859,7 +866,7 @@ static void maybe_start_some_streams(
grpc_chttp2_list_pop_waiting_for_concurrency(transport_global,
&stream_global)) {
cancel_from_api(exec_ctx, transport_global, stream_global,
- GRPC_STATUS_UNAVAILABLE);
+ GRPC_STATUS_UNAVAILABLE, NULL);
}
}
@@ -936,7 +943,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
if (op->cancel_with_status != GRPC_STATUS_OK) {
cancel_from_api(exec_ctx, transport_global, stream_global,
- op->cancel_with_status);
+ op->cancel_with_status, op->optional_close_message);
}
if (op->close_with_status != GRPC_STATUS_OK) {
@@ -960,7 +967,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
"(%lu vs. %lu)",
metadata_size, metadata_peer_limit);
cancel_from_api(exec_ctx, transport_global, stream_global,
- GRPC_STATUS_RESOURCE_EXHAUSTED);
+ GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
} else {
if (contains_non_ok_status(transport_global, op->send_initial_metadata)) {
stream_global->seen_error = true;
@@ -1015,7 +1022,7 @@ static void perform_stream_op_locked(grpc_exec_ctx *exec_ctx,
"(%lu vs. %lu)",
metadata_size, metadata_peer_limit);
cancel_from_api(exec_ctx, transport_global, stream_global,
- GRPC_STATUS_RESOURCE_EXHAUSTED);
+ GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
} else {
if (contains_non_ok_status(transport_global,
op->send_trailing_metadata)) {
@@ -1201,7 +1208,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx,
}
if (stream_global->exceeded_metadata_size) {
cancel_from_api(exec_ctx, transport_global, stream_global,
- GRPC_STATUS_RESOURCE_EXHAUSTED);
+ GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
}
}
grpc_chttp2_incoming_metadata_buffer_publish(
@@ -1240,7 +1247,7 @@ static void check_read_ops(grpc_exec_ctx *exec_ctx,
}
if (stream_global->exceeded_metadata_size) {
cancel_from_api(exec_ctx, transport_global, stream_global,
- GRPC_STATUS_RESOURCE_EXHAUSTED);
+ GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
}
}
if (stream_global->all_incoming_byte_streams_finished) {
@@ -1303,7 +1310,8 @@ static void remove_stream(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
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) {
+ grpc_status_code status,
+ gpr_slice *optional_message) {
if (!stream_global->read_closed || !stream_global->write_closed) {
if (stream_global->id != 0) {
gpr_slice_buffer_add(
@@ -1313,8 +1321,12 @@ static void cancel_from_api(grpc_exec_ctx *exec_ctx,
(uint32_t)grpc_chttp2_grpc_status_to_http2_error(status),
&stream_global->stats.outgoing));
}
+
+ if (optional_message) {
+ gpr_slice_ref(*optional_message);
+ }
grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status,
- NULL);
+ optional_message);
}
if (status != GRPC_STATUS_OK && !stream_global->seen_error) {
stream_global->seen_error = true;
@@ -1524,8 +1536,12 @@ static void close_from_api(grpc_exec_ctx *exec_ctx,
static void cancel_stream_cb(grpc_chttp2_transport_global *transport_global,
void *user_data,
grpc_chttp2_stream_global *stream_global) {
+ grpc_chttp2_transport *transport = TRANSPORT_FROM_GLOBAL(transport_global);
cancel_from_api(user_data, transport_global, stream_global,
- GRPC_STATUS_UNAVAILABLE);
+ GRPC_STATUS_UNAVAILABLE,
+ GPR_SLICE_IS_EMPTY(transport->optional_drop_message)
+ ? NULL
+ : &transport->optional_drop_message);
}
static void end_all_the_calls(grpc_exec_ctx *exec_ctx,
@@ -1601,6 +1617,29 @@ static void reading_action_locked(grpc_exec_ctx *exec_ctx,
}
}
+static bool try_http_parsing(grpc_exec_ctx *exec_ctx,
+ grpc_chttp2_transport *t) {
+ grpc_http_parser parser;
+ size_t i = 0;
+ bool success = false;
+
+ grpc_http_parser_init(&parser);
+
+ for (; i < t->read_buffer.count &&
+ grpc_http_parser_parse(&parser, t->read_buffer.slices[i]);
+ i++)
+ ;
+ if (grpc_http_parser_eof(&parser) && parser.type == GRPC_HTTP_RESPONSE) {
+ success = true;
+ GRPC_CHTTP2_IF_TRACING(gpr_log(
+ GPR_DEBUG, "Trying to connect an http1.x server, received status:%d",
+ parser.http.response.status));
+ }
+
+ grpc_http_parser_destroy(&parser);
+ return success;
+}
+
static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
grpc_chttp2_transport *t = arg;
GPR_TIMER_BEGIN("reading_action.parse", 0);
@@ -1612,6 +1651,14 @@ static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
;
if (i != t->read_buffer.count) {
success = false;
+ gpr_slice_unref(t->optional_drop_message);
+ if (try_http_parsing(exec_ctx, t)) {
+ t->optional_drop_message = gpr_slice_from_copied_string(
+ "Connection dropped: received http1.x response");
+ } else {
+ t->optional_drop_message = gpr_slice_from_copied_string(
+ "Connection dropped: received unparseable response");
+ }
}
GPR_TIMER_END("reading_action.parse", 0);
grpc_chttp2_run_with_global_lock(exec_ctx, t, NULL, post_parse_locked,
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 5872fd8e0a..7f3339a620 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -383,6 +383,9 @@ struct grpc_chttp2_transport {
/** Transport op to be applied post-parsing */
grpc_transport_op *post_parsing_op;
+
+ /** Message explaining the reason of dropping connection */
+ gpr_slice optional_drop_message;
};
typedef struct {
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index 5c161652ac..bbba85d80b 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -106,6 +106,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
const grpc_channel_filter **filters,
size_t filter_count,
const grpc_channel_args *channel_args,
+ grpc_transport *optional_transport,
const char *name, grpc_channel_stack *stack) {
size_t call_size =
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
@@ -127,6 +128,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
for (i = 0; i < filter_count; i++) {
args.channel_stack = stack;
args.channel_args = channel_args;
+ args.optional_transport = optional_transport;
args.is_first = i == 0;
args.is_last = i == (filter_count - 1);
elems[i].filter = filters[i];
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 3ca643c893..41dd4a0d8a 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -60,6 +60,8 @@ typedef struct grpc_call_stack grpc_call_stack;
typedef struct {
grpc_channel_stack *channel_stack;
const grpc_channel_args *channel_args;
+ /** Transport, iff it is known */
+ grpc_transport *optional_transport;
int is_first;
int is_last;
} grpc_channel_element_args;
@@ -198,6 +200,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
grpc_iomgr_cb_func destroy, void *destroy_arg,
const grpc_channel_filter **filters,
size_t filter_count, const grpc_channel_args *args,
+ grpc_transport *optional_transport,
const char *name, grpc_channel_stack *stack);
/* Destroy a channel stack */
void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index a8646c9565..eda4968f48 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -257,8 +257,8 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
// and initialize it
grpc_channel_stack_init(exec_ctx, initial_refs, destroy,
destroy_arg == NULL ? result : destroy_arg, filters,
- num_filters, builder->args, builder->name,
- channel_stack);
+ num_filters, builder->args, builder->transport,
+ builder->name, channel_stack);
// run post-initialization functions
i = 0;
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index 2245a52599..792f0d8ae6 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -38,6 +38,7 @@
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h"
+#include "src/core/lib/transport/transport_impl.h"
#define EXPECTED_CONTENT_TYPE "application/grpc"
#define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1
@@ -199,7 +200,8 @@ static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
return GRPC_MDELEM_SCHEME_HTTP;
}
-static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args) {
+static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
+ const char *transport_name) {
gpr_strvec v;
size_t i;
int is_first = 1;
@@ -221,8 +223,8 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args) {
}
}
- gpr_asprintf(&tmp, "%sgrpc-c/%s (%s)", is_first ? "" : " ",
- grpc_version_string(), GPR_PLATFORM_STRING);
+ gpr_asprintf(&tmp, "%sgrpc-c/%s (%s; %s)", is_first ? "" : " ",
+ grpc_version_string(), GPR_PLATFORM_STRING, transport_name);
is_first = 0;
gpr_strvec_add(&v, tmp);
@@ -253,9 +255,12 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element_args *args) {
channel_data *chand = elem->channel_data;
GPR_ASSERT(!args->is_last);
+ GPR_ASSERT(args->optional_transport != NULL);
chand->static_scheme = scheme_from_args(args->channel_args);
chand->user_agent = grpc_mdelem_from_metadata_strings(
- GRPC_MDSTR_USER_AGENT, user_agent_from_args(args->channel_args));
+ GRPC_MDSTR_USER_AGENT,
+ user_agent_from_args(args->channel_args,
+ args->optional_transport->vtable->name));
}
/* Destructor for channel data */
diff --git a/src/core/lib/channel/http_client_filter.h b/src/core/lib/channel/http_client_filter.h
index a884b36318..47081175ea 100644
--- a/src/core/lib/channel/http_client_filter.h
+++ b/src/core/lib/channel/http_client_filter.h
@@ -1,5 +1,4 @@
/*
- *
* Copyright 2015, Google Inc.
* All rights reserved.
*
@@ -39,6 +38,7 @@
/* Processes metadata on the client side for HTTP2 transports */
extern const grpc_channel_filter grpc_http_client_filter;
+/* Channel arg to override the http2 :scheme header */
#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
#endif /* GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H */
diff --git a/src/csharp/Grpc.Core.Tests/ServerTest.cs b/src/csharp/Grpc.Core.Tests/ServerTest.cs
index fa693162ad..3b51aa6330 100644
--- a/src/csharp/Grpc.Core.Tests/ServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ServerTest.cs
@@ -93,5 +93,20 @@ namespace Grpc.Core.Tests
server.ShutdownAsync().Wait();
}
+
+ [Test]
+ public void UnstartedServerCanBeShutdown()
+ {
+ var server = new Server();
+ server.ShutdownAsync().Wait();
+ Assert.Throws(typeof(InvalidOperationException), () => server.Start());
+ }
+
+ [Test]
+ public void UnstartedServerDoesNotPreventShutdown()
+ {
+ // just create a server, don't start it, and make sure it doesn't prevent shutdown.
+ var server = new Server();
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index ae7a8c9a9a..3b554e5e87 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -140,6 +140,7 @@ namespace Grpc.Core
lock (myLock)
{
GrpcPreconditions.CheckState(!startRequested);
+ GrpcPreconditions.CheckState(!shutdownRequested);
startRequested = true;
handle.Start();
@@ -203,7 +204,6 @@ namespace Grpc.Core
{
lock (myLock)
{
- GrpcPreconditions.CheckState(startRequested);
GrpcPreconditions.CheckState(!shutdownRequested);
shutdownRequested = true;
}
@@ -215,7 +215,6 @@ namespace Grpc.Core
{
handle.CancelAllCalls();
}
-
await ShutdownCompleteOrEnvironmentDeadAsync().ConfigureAwait(false);
DisposeHandle();
diff --git a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
index 0a511101f0..4039c1b99b 100644
--- a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
@@ -143,22 +143,60 @@ class TypeSmokeTest(unittest.TestCase):
del completion_queue
-class InsecureServerInsecureClient(unittest.TestCase):
+class ServerClientMixin(object):
- def setUp(self):
+ def setUpMixin(self, server_credentials, client_credentials, host_override):
self.server_completion_queue = cygrpc.CompletionQueue()
self.server = cygrpc.Server()
self.server.register_completion_queue(self.server_completion_queue)
- self.port = self.server.add_http2_port('[::]:0')
+ if server_credentials:
+ self.port = self.server.add_http2_port('[::]:0', server_credentials)
+ else:
+ self.port = self.server.add_http2_port('[::]:0')
self.server.start()
self.client_completion_queue = cygrpc.CompletionQueue()
- self.client_channel = cygrpc.Channel('localhost:{}'.format(self.port))
-
- def tearDown(self):
+ if client_credentials:
+ client_channel_arguments = cygrpc.ChannelArgs([
+ cygrpc.ChannelArg(cygrpc.ChannelArgKey.ssl_target_name_override,
+ host_override)])
+ self.client_channel = cygrpc.Channel(
+ 'localhost:{}'.format(self.port), client_channel_arguments,
+ client_credentials)
+ else:
+ self.client_channel = cygrpc.Channel('localhost:{}'.format(self.port))
+ if host_override:
+ self.host_argument = None # default host
+ self.expected_host = host_override
+ else:
+ # arbitrary host name necessitating no further identification
+ self.host_argument = b'hostess'
+ self.expected_host = self.host_argument
+
+ def tearDownMixin(self):
del self.server
del self.client_completion_queue
del self.server_completion_queue
+ def _perform_operations(self, operations, call, queue, deadline, description):
+ """Perform the list of operations with given call, queue, and deadline.
+
+ Invocation errors are reported with as an exception with `description` in
+ the message. Performs the operations asynchronously, returning a future.
+ """
+ def performer():
+ tag = object()
+ try:
+ call_result = call.start_batch(cygrpc.Operations(operations), tag)
+ self.assertEqual(cygrpc.CallError.ok, call_result)
+ event = queue.poll(deadline)
+ self.assertEqual(cygrpc.CompletionType.operation_complete, event.type)
+ self.assertTrue(event.success)
+ self.assertIs(tag, event.tag)
+ except Exception as error:
+ raise Exception("Error in '{}': {}".format(description, error.message))
+ return event
+ return test_utilities.SimpleFuture(performer)
+
def testEcho(self):
DEADLINE = time.time()+5
DEADLINE_TOLERANCE = 0.25
@@ -175,7 +213,6 @@ class InsecureServerInsecureClient(unittest.TestCase):
REQUEST = b'in death a member of project mayhem has a name'
RESPONSE = b'his name is robert paulson'
METHOD = b'twinkies'
- HOST = b'hostess'
cygrpc_deadline = cygrpc.Timespec(DEADLINE)
@@ -188,7 +225,8 @@ class InsecureServerInsecureClient(unittest.TestCase):
client_call_tag = object()
client_call = self.client_channel.create_call(
- None, 0, self.client_completion_queue, METHOD, HOST, cygrpc_deadline)
+ None, 0, self.client_completion_queue, METHOD, self.host_argument,
+ cygrpc_deadline)
client_initial_metadata = cygrpc.Metadata([
cygrpc.Metadatum(CLIENT_METADATA_ASCII_KEY,
CLIENT_METADATA_ASCII_VALUE),
@@ -216,7 +254,8 @@ class InsecureServerInsecureClient(unittest.TestCase):
test_common.metadata_transmitted(client_initial_metadata,
request_event.request_metadata))
self.assertEqual(METHOD, request_event.request_call_details.method)
- self.assertEqual(HOST, request_event.request_call_details.host)
+ self.assertEqual(self.expected_host,
+ request_event.request_call_details.host)
self.assertLess(
abs(DEADLINE - float(request_event.request_call_details.deadline)),
DEADLINE_TOLERANCE)
@@ -292,172 +331,101 @@ class InsecureServerInsecureClient(unittest.TestCase):
del client_call
del server_call
-
-class SecureServerSecureClient(unittest.TestCase):
-
- def setUp(self):
- server_credentials = cygrpc.server_credentials_ssl(
- None, [cygrpc.SslPemKeyCertPair(resources.private_key(),
- resources.certificate_chain())], False)
- channel_credentials = cygrpc.channel_credentials_ssl(
- resources.test_root_certificates(), None)
- self.server_completion_queue = cygrpc.CompletionQueue()
- self.server = cygrpc.Server()
- self.server.register_completion_queue(self.server_completion_queue)
- self.port = self.server.add_http2_port('[::]:0', server_credentials)
- self.server.start()
- self.client_completion_queue = cygrpc.CompletionQueue()
- client_channel_arguments = cygrpc.ChannelArgs([
- cygrpc.ChannelArg(cygrpc.ChannelArgKey.ssl_target_name_override,
- _SSL_HOST_OVERRIDE)])
- self.client_channel = cygrpc.Channel(
- 'localhost:{}'.format(self.port), client_channel_arguments,
- channel_credentials)
-
- def tearDown(self):
- del self.server
- del self.client_completion_queue
- del self.server_completion_queue
-
- def testEcho(self):
+ def test6522(self):
DEADLINE = time.time()+5
DEADLINE_TOLERANCE = 0.25
- CLIENT_METADATA_ASCII_KEY = b'key'
- CLIENT_METADATA_ASCII_VALUE = b'val'
- CLIENT_METADATA_BIN_KEY = b'key-bin'
- CLIENT_METADATA_BIN_VALUE = b'\0'*1000
- SERVER_INITIAL_METADATA_KEY = b'init_me_me_me'
- SERVER_INITIAL_METADATA_VALUE = b'whodawha?'
- SERVER_TRAILING_METADATA_KEY = b'california_is_in_a_drought'
- SERVER_TRAILING_METADATA_VALUE = b'zomg it is'
- SERVER_STATUS_CODE = cygrpc.StatusCode.ok
- SERVER_STATUS_DETAILS = b'our work is never over'
- REQUEST = b'in death a member of project mayhem has a name'
- RESPONSE = b'his name is robert paulson'
- METHOD = b'/twinkies'
- HOST = None # Default host
+ METHOD = b'twinkies'
cygrpc_deadline = cygrpc.Timespec(DEADLINE)
+ empty_metadata = cygrpc.Metadata([])
server_request_tag = object()
- request_call_result = self.server.request_call(
+ self.server.request_call(
self.server_completion_queue, self.server_completion_queue,
server_request_tag)
+ client_call = self.client_channel.create_call(
+ None, 0, self.client_completion_queue, METHOD, self.host_argument,
+ cygrpc_deadline)
- self.assertEqual(cygrpc.CallError.ok, request_call_result)
-
- plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, '')
- call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)
+ # Prologue
+ def perform_client_operations(operations, description):
+ return self._perform_operations(
+ operations, client_call,
+ self.client_completion_queue, cygrpc_deadline, description)
- client_call_tag = object()
- client_call = self.client_channel.create_call(
- None, 0, self.client_completion_queue, METHOD, HOST, cygrpc_deadline)
- client_call.set_credentials(call_credentials)
- client_initial_metadata = cygrpc.Metadata([
- cygrpc.Metadatum(CLIENT_METADATA_ASCII_KEY,
- CLIENT_METADATA_ASCII_VALUE),
- cygrpc.Metadatum(CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)])
- client_start_batch_result = client_call.start_batch(cygrpc.Operations([
- cygrpc.operation_send_initial_metadata(client_initial_metadata,
- _EMPTY_FLAGS),
- cygrpc.operation_send_message(REQUEST, _EMPTY_FLAGS),
- cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
- cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
- cygrpc.operation_receive_message(_EMPTY_FLAGS),
- cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS)
- ]), client_call_tag)
- self.assertEqual(cygrpc.CallError.ok, client_start_batch_result)
- client_event_future = test_utilities.CompletionQueuePollFuture(
- self.client_completion_queue, cygrpc_deadline)
+ client_event_future = perform_client_operations([
+ cygrpc.operation_send_initial_metadata(empty_metadata,
+ _EMPTY_FLAGS),
+ cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+ ], "Client prologue")
request_event = self.server_completion_queue.poll(cygrpc_deadline)
- self.assertEqual(cygrpc.CompletionType.operation_complete,
- request_event.type)
- self.assertIsInstance(request_event.operation_call, cygrpc.Call)
- self.assertIs(server_request_tag, request_event.tag)
- self.assertEqual(0, len(request_event.batch_operations))
- client_metadata_with_credentials = list(client_initial_metadata) + [
- (_CALL_CREDENTIALS_METADATA_KEY, _CALL_CREDENTIALS_METADATA_VALUE)]
- self.assertTrue(
- test_common.metadata_transmitted(client_metadata_with_credentials,
- request_event.request_metadata))
- self.assertEqual(METHOD, request_event.request_call_details.method)
- self.assertEqual(_SSL_HOST_OVERRIDE,
- request_event.request_call_details.host)
- self.assertLess(
- abs(DEADLINE - float(request_event.request_call_details.deadline)),
- DEADLINE_TOLERANCE)
-
- server_call_tag = object()
server_call = request_event.operation_call
- server_initial_metadata = cygrpc.Metadata([
- cygrpc.Metadatum(SERVER_INITIAL_METADATA_KEY,
- SERVER_INITIAL_METADATA_VALUE)])
- server_trailing_metadata = cygrpc.Metadata([
- cygrpc.Metadatum(SERVER_TRAILING_METADATA_KEY,
- SERVER_TRAILING_METADATA_VALUE)])
- server_start_batch_result = server_call.start_batch([
- cygrpc.operation_send_initial_metadata(server_initial_metadata,
- _EMPTY_FLAGS),
- cygrpc.operation_receive_message(_EMPTY_FLAGS),
- cygrpc.operation_send_message(RESPONSE, _EMPTY_FLAGS),
- cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
- cygrpc.operation_send_status_from_server(
- server_trailing_metadata, SERVER_STATUS_CODE,
- SERVER_STATUS_DETAILS, _EMPTY_FLAGS)
- ], server_call_tag)
- self.assertEqual(cygrpc.CallError.ok, server_start_batch_result)
- client_event = client_event_future.result()
- server_event = self.server_completion_queue.poll(cygrpc_deadline)
+ def perform_server_operations(operations, description):
+ return self._perform_operations(
+ operations, server_call,
+ self.server_completion_queue, cygrpc_deadline, description)
- self.assertEqual(6, len(client_event.batch_operations))
- found_client_op_types = set()
- for client_result in client_event.batch_operations:
- # we expect each op type to be unique
- self.assertNotIn(client_result.type, found_client_op_types)
- found_client_op_types.add(client_result.type)
- if client_result.type == cygrpc.OperationType.receive_initial_metadata:
- self.assertTrue(
- test_common.metadata_transmitted(server_initial_metadata,
- client_result.received_metadata))
- elif client_result.type == cygrpc.OperationType.receive_message:
- self.assertEqual(RESPONSE, client_result.received_message.bytes())
- elif client_result.type == cygrpc.OperationType.receive_status_on_client:
- self.assertTrue(
- test_common.metadata_transmitted(server_trailing_metadata,
- client_result.received_metadata))
- self.assertEqual(SERVER_STATUS_DETAILS,
- client_result.received_status_details)
- self.assertEqual(SERVER_STATUS_CODE, client_result.received_status_code)
- self.assertEqual(set([
- cygrpc.OperationType.send_initial_metadata,
- cygrpc.OperationType.send_message,
- cygrpc.OperationType.send_close_from_client,
- cygrpc.OperationType.receive_initial_metadata,
- cygrpc.OperationType.receive_message,
- cygrpc.OperationType.receive_status_on_client
- ]), found_client_op_types)
+ server_event_future = perform_server_operations([
+ cygrpc.operation_send_initial_metadata(empty_metadata,
+ _EMPTY_FLAGS),
+ ], "Server prologue")
- self.assertEqual(5, len(server_event.batch_operations))
- found_server_op_types = set()
- for server_result in server_event.batch_operations:
- self.assertNotIn(client_result.type, found_server_op_types)
- found_server_op_types.add(server_result.type)
- if server_result.type == cygrpc.OperationType.receive_message:
- self.assertEqual(REQUEST, server_result.received_message.bytes())
- elif server_result.type == cygrpc.OperationType.receive_close_on_server:
- self.assertFalse(server_result.received_cancelled)
- self.assertEqual(set([
- cygrpc.OperationType.send_initial_metadata,
- cygrpc.OperationType.receive_message,
- cygrpc.OperationType.send_message,
- cygrpc.OperationType.receive_close_on_server,
- cygrpc.OperationType.send_status_from_server
- ]), found_server_op_types)
+ client_event_future.result() # force completion
+ server_event_future.result()
- del client_call
- del server_call
+ # Messaging
+ for _ in range(10):
+ client_event_future = perform_client_operations([
+ cygrpc.operation_send_message(b'', _EMPTY_FLAGS),
+ cygrpc.operation_receive_message(_EMPTY_FLAGS),
+ ], "Client message")
+ server_event_future = perform_server_operations([
+ cygrpc.operation_send_message(b'', _EMPTY_FLAGS),
+ cygrpc.operation_receive_message(_EMPTY_FLAGS),
+ ], "Server receive")
+
+ client_event_future.result() # force completion
+ server_event_future.result()
+
+ # Epilogue
+ client_event_future = perform_client_operations([
+ cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+ cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS)
+ ], "Client epilogue")
+
+ server_event_future = perform_server_operations([
+ cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
+ cygrpc.operation_send_status_from_server(
+ empty_metadata, cygrpc.StatusCode.ok, b'', _EMPTY_FLAGS)
+ ], "Server epilogue")
+
+ client_event_future.result() # force completion
+ server_event_future.result()
+
+
+class InsecureServerInsecureClient(unittest.TestCase, ServerClientMixin):
+
+ def setUp(self):
+ self.setUpMixin(None, None, None)
+
+ def tearDown(self):
+ self.tearDownMixin()
+
+
+class SecureServerSecureClient(unittest.TestCase, ServerClientMixin):
+
+ def setUp(self):
+ server_credentials = cygrpc.server_credentials_ssl(
+ None, [cygrpc.SslPemKeyCertPair(resources.private_key(),
+ resources.certificate_chain())], False)
+ client_credentials = cygrpc.channel_credentials_ssl(
+ resources.test_root_certificates(), None)
+ self.setUpMixin(server_credentials, client_credentials, _SSL_HOST_OVERRIDE)
+
+ def tearDown(self):
+ self.tearDownMixin()
if __name__ == '__main__':
diff --git a/src/python/grpcio/tests/unit/_cython/test_utilities.py b/src/python/grpcio/tests/unit/_cython/test_utilities.py
index 6a09739643..6280ce74c4 100644
--- a/src/python/grpcio/tests/unit/_cython/test_utilities.py
+++ b/src/python/grpcio/tests/unit/_cython/test_utilities.py
@@ -32,15 +32,35 @@ import threading
from grpc._cython import cygrpc
-class CompletionQueuePollFuture:
+class SimpleFuture(object):
+ """A simple future mechanism."""
- def __init__(self, completion_queue, deadline):
- def poller_function():
- self._event_result = completion_queue.poll(deadline)
- self._event_result = None
- self._thread = threading.Thread(target=poller_function)
+ def __init__(self, function, *args, **kwargs):
+ def wrapped_function():
+ try:
+ self._result = function(*args, **kwargs)
+ except Exception as error:
+ self._error = error
+ self._result = None
+ self._error = None
+ self._thread = threading.Thread(target=wrapped_function)
self._thread.start()
def result(self):
+ """The resulting value of this future.
+
+ Re-raises any exceptions.
+ """
self._thread.join()
- return self._event_result
+ if self._error:
+ # TODO(atash): re-raise exceptions in a way that preserves tracebacks
+ raise self._error
+ return self._result
+
+
+class CompletionQueuePollFuture(SimpleFuture):
+
+ def __init__(self, completion_queue, deadline):
+ super(CompletionQueuePollFuture, self).__init__(
+ lambda: completion_queue.poll(deadline))
+
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index b5476c8f6a..2d77bc5bd4 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -124,7 +124,7 @@ static void test_create_channel_stack(void) {
channel_stack = gpr_malloc(grpc_channel_stack_size(&filters, 1));
grpc_channel_stack_init(&exec_ctx, 1, free_channel, channel_stack, &filters,
- 1, &chan_args, "test", channel_stack);
+ 1, &chan_args, NULL, "test", channel_stack);
GPR_ASSERT(channel_stack->count == 1);
channel_elem = grpc_channel_stack_element(channel_stack, 0);
channel_data = (int *)channel_elem->channel_data;
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206 b/test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206
new file mode 100644
index 0000000000..1452256ec7
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/552199651d942e7220141a93ec33dd8256210a18 b/test/core/end2end/fuzzers/server_fuzzer_corpus/552199651d942e7220141a93ec33dd8256210a18
new file mode 100644
index 0000000000..c8c54f443d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/552199651d942e7220141a93ec33dd8256210a18
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/7a946bf3cd91b63001f2cf3f40c515c747f2ecde b/test/core/end2end/fuzzers/server_fuzzer_corpus/7a946bf3cd91b63001f2cf3f40c515c747f2ecde
new file mode 100644
index 0000000000..8ef1b0ad7e
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/7a946bf3cd91b63001f2cf3f40c515c747f2ecde
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/7d25c28298fb4d0fe41209d0d14307e4aa67c59e b/test/core/end2end/fuzzers/server_fuzzer_corpus/7d25c28298fb4d0fe41209d0d14307e4aa67c59e
new file mode 100644
index 0000000000..a323f7a1ab
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/7d25c28298fb4d0fe41209d0d14307e4aa67c59e
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/8138b18a9a743659befc2f2b23d23cb9c3086a09 b/test/core/end2end/fuzzers/server_fuzzer_corpus/8138b18a9a743659befc2f2b23d23cb9c3086a09
new file mode 100644
index 0000000000..2bcef177a3
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/8138b18a9a743659befc2f2b23d23cb9c3086a09
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/925011abb99fd56bb0f425ae5e0d92e6d341f804 b/test/core/end2end/fuzzers/server_fuzzer_corpus/925011abb99fd56bb0f425ae5e0d92e6d341f804
new file mode 100644
index 0000000000..948d5fafa3
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/925011abb99fd56bb0f425ae5e0d92e6d341f804
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-c1f66840627e3bfdedf2e4c225bc4de0c267ed37 b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-c1f66840627e3bfdedf2e4c225bc4de0c267ed37
new file mode 100644
index 0000000000..a7fa57e78e
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-c1f66840627e3bfdedf2e4c225bc4de0c267ed37
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/d6bed9cc3c10338a8c5f41064ff8bec0bbc267ce b/test/core/end2end/fuzzers/server_fuzzer_corpus/d6bed9cc3c10338a8c5f41064ff8bec0bbc267ce
new file mode 100644
index 0000000000..2b3424a332
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/d6bed9cc3c10338a8c5f41064ff8bec0bbc267ce
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/dda9643679f8c8b796e64232a7d153e447d64991 b/test/core/end2end/fuzzers/server_fuzzer_corpus/dda9643679f8c8b796e64232a7d153e447d64991
new file mode 100644
index 0000000000..b8ba07b16b
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/dda9643679f8c8b796e64232a7d153e447d64991
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/e7b08e36420fa107f0aee652e62158af85a4ef15 b/test/core/end2end/fuzzers/server_fuzzer_corpus/e7b08e36420fa107f0aee652e62158af85a4ef15
new file mode 100644
index 0000000000..523c785612
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/e7b08e36420fa107f0aee652e62158af85a4ef15
Binary files differ
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index f52aa52f39..e3667cf26b 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -1014,6 +1014,16 @@ TEST_P(ProxyEnd2endTest, SimpleRpc) {
SendRpc(stub_.get(), 1, false);
}
+TEST_P(ProxyEnd2endTest, SimpleRpcWithEmptyMessages) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+
+ ClientContext context;
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+}
+
TEST_P(ProxyEnd2endTest, MultipleRpcs) {
ResetStub();
std::vector<std::thread*> threads;
diff --git a/tools/distrib/python/check_grpcio_tools.py b/tools/distrib/python/check_grpcio_tools.py
index baf2ff4eff..80c63278f4 100755
--- a/tools/distrib/python/check_grpcio_tools.py
+++ b/tools/distrib/python/check_grpcio_tools.py
@@ -37,7 +37,7 @@ OUT_OF_DATE_MESSAGE = """file {} is out of date
Have you called tools/distrib/python/make_grpcio_tools.py since upgrading protobuf?"""
-check_protoc_lib_deps_content = make.get_deps(make.BAZEL_DEPS_PROTOC_LIB_QUERY)
+check_protoc_lib_deps_content = make.get_deps()
with open(make.GRPC_PYTHON_PROTOC_LIB_DEPS, 'r') as protoc_lib_deps_file:
if protoc_lib_deps_file.read() != check_protoc_lib_deps_content:
diff --git a/tools/distrib/python/grpcio_tools/README.rst b/tools/distrib/python/grpcio_tools/README.rst
index 10d2fe8c30..e9f137493b 100644
--- a/tools/distrib/python/grpcio_tools/README.rst
+++ b/tools/distrib/python/grpcio_tools/README.rst
@@ -126,3 +126,13 @@ Help, I ...
GCC 6.0), this is probably a bug where GCC chokes on constant expressions
when the :code:`-fwrapv` flag is specified. You should consider setting your
environment with :code:`CFLAGS=-fno-wrapv` or using clang (:code:`CC=clang`).
+
+Usage
+-----
+
+Given protobuf include directories :code:`$INCLUDE`, an output directory
+:code:`$OUTPUT`, and proto files :code:`$PROTO_FILES`, invoke as:
+
+::
+
+ $ python -m grpc.tools.protoc -I$INCLUDE --python_out=$OUTPUT --grpc_python_out=$OUTPUT $PROTO_FILES
diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py b/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py
index b4dd0ecae2..1c69e78920 100644
--- a/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py
+++ b/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py
@@ -29,10 +29,13 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import pkg_resources
import sys
from grpc.tools import protoc_compiler
if __name__ == '__main__':
- protoc_compiler.run_main(sys.argv)
+ proto_include = pkg_resources.resource_filename('grpc.tools', '_proto')
+ protoc_compiler.run_main(
+ sys.argv + ['-I{}'.format(proto_include)])
diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
index 135ac5cbb3..cd4effa7ae 100644
--- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
+++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
@@ -30,3 +30,7 @@
# AUTO-GENERATED BY make_grpcio_tools.py!
CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc']
+PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'google/protobuf/timestamp.proto', 'google/protobuf/struct.proto', 'google/protobuf/source_context.proto', 'google/protobuf/field_mask.proto', 'google/protobuf/empty.proto', 'google/protobuf/duration.proto', 'google/protobuf/descriptor.proto', 'google/protobuf/compiler/plugin.proto', 'google/protobuf/api.proto', 'google/protobuf/any.proto']
+
+CC_INCLUDE='third_party/protobuf/src'
+PROTO_INCLUDE='third_party/protobuf/src'
diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py
index 576f7ae32a..fbe69f43d5 100644
--- a/tools/distrib/python/grpcio_tools/setup.py
+++ b/tools/distrib/python/grpcio_tools/setup.py
@@ -28,9 +28,11 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from distutils import extension
+import errno
import os
import os.path
import shlex
+import shutil
import sys
import setuptools
@@ -47,18 +49,41 @@ sys.path.insert(0, os.path.abspath('.'))
# ourselves in w.r.t. the multitude of operating systems this ought to build on.
# By default we assume a GCC-like compiler.
EXTRA_COMPILE_ARGS = shlex.split(os.environ.get('GRPC_PYTHON_CFLAGS',
- '-frtti -std=c++11'))
+ '-fno-wrapv -frtti -std=c++11'))
EXTRA_LINK_ARGS = shlex.split(os.environ.get('GRPC_PYTHON_LDFLAGS',
'-lpthread'))
+GRPC_PYTHON_TOOLS_PACKAGE = 'grpc.tools'
+GRPC_PYTHON_PROTO_RESOURCES_NAME = '_proto'
+
import protoc_lib_deps
import grpc_version
+def package_data():
+ tools_path = GRPC_PYTHON_TOOLS_PACKAGE.replace('.', os.path.sep)
+ proto_resources_path = os.path.join(tools_path,
+ GRPC_PYTHON_PROTO_RESOURCES_NAME)
+ proto_files = []
+ for proto_file in protoc_lib_deps.PROTO_FILES:
+ source = os.path.join(protoc_lib_deps.PROTO_INCLUDE, proto_file)
+ target = os.path.join(proto_resources_path, proto_file)
+ relative_target = os.path.join(GRPC_PYTHON_PROTO_RESOURCES_NAME, proto_file)
+ try:
+ os.makedirs(os.path.dirname(target))
+ except OSError as error:
+ if error.errno == errno.EEXIST:
+ pass
+ else:
+ raise
+ shutil.copy(source, target)
+ proto_files.append(relative_target)
+ return {GRPC_PYTHON_TOOLS_PACKAGE: proto_files}
+
def protoc_ext_module():
plugin_sources = [
'grpc/tools/main.cc',
'grpc_root/src/compiler/python_generator.cc'] + [
- os.path.join('third_party/protobuf/src', cc_file)
+ os.path.join(protoc_lib_deps.CC_INCLUDE, cc_file)
for cc_file in protoc_lib_deps.CC_FILES]
plugin_ext = extension.Extension(
name='grpc.tools.protoc_compiler',
@@ -67,7 +92,7 @@ def protoc_ext_module():
'.',
'grpc_root',
'grpc_root/include',
- 'third_party/protobuf/src',
+ protoc_lib_deps.CC_INCLUDE,
],
language='c++',
define_macros=[('HAVE_PTHREAD', 1)],
@@ -88,9 +113,10 @@ setuptools.setup(
protoc_ext_module(),
]),
packages=setuptools.find_packages('.'),
- # TODO(atash): Figure out why auditwheel doesn't like namespace packages.
- #namespace_packages=['grpc'],
+ namespace_packages=['grpc'],
install_requires=[
'protobuf>=3.0.0a3',
+ 'grpcio>=0.14.0',
],
+ package_data=package_data(),
)
diff --git a/tools/distrib/python/make_grpcio_tools.py b/tools/distrib/python/make_grpcio_tools.py
index 50fbdbb14c..fd9b38b084 100755
--- a/tools/distrib/python/make_grpcio_tools.py
+++ b/tools/distrib/python/make_grpcio_tools.py
@@ -67,11 +67,16 @@ DEPS_FILE_CONTENT="""
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# AUTO-GENERATED BY make_grpcio_tools.py!
-CC_FILES={}
+CC_FILES={cc_files}
+PROTO_FILES={proto_files}
+
+CC_INCLUDE={cc_include}
+PROTO_INCLUDE={proto_include}
"""
# Bazel query result prefix for expected source files in protobuf.
PROTOBUF_CC_PREFIX = '//:src/'
+PROTOBUF_PROTO_PREFIX = '//:src/'
GRPC_ROOT = os.path.abspath(
os.path.join(os.path.dirname(os.path.abspath(__file__)),
@@ -79,7 +84,8 @@ GRPC_ROOT = os.path.abspath(
GRPC_PYTHON_ROOT = os.path.join(GRPC_ROOT, 'tools/distrib/python/grpcio_tools')
-GRPC_PROTOBUF = os.path.join(GRPC_ROOT, 'third_party/protobuf/src')
+GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT = 'third_party/protobuf/src'
+GRPC_PROTOBUF = os.path.join(GRPC_ROOT, GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT)
GRPC_PROTOC_PLUGINS = os.path.join(GRPC_ROOT, 'src/compiler')
GRPC_PYTHON_PROTOBUF = os.path.join(GRPC_PYTHON_ROOT,
'third_party/protobuf/src')
@@ -93,18 +99,29 @@ GRPC_PYTHON_INCLUDE = os.path.join(GRPC_PYTHON_ROOT, 'grpc_root/include')
BAZEL_DEPS = os.path.join(GRPC_ROOT, 'tools/distrib/python/bazel_deps.sh')
BAZEL_DEPS_PROTOC_LIB_QUERY = '//:protoc_lib'
+BAZEL_DEPS_COMMON_PROTOS_QUERY = '//:well_known_protos'
+
+def bazel_query(query):
+ output = subprocess.check_output([BAZEL_DEPS, query])
+ return output.splitlines()
-def get_deps(query):
+def get_deps():
"""Write the result of the bazel query `query` against protobuf to
`out_file`."""
- output = subprocess.check_output([BAZEL_DEPS, query])
- output = output.splitlines()
+ cc_files_output = bazel_query(BAZEL_DEPS_PROTOC_LIB_QUERY)
cc_files = [
- name for name in output
+ name[len(PROTOBUF_CC_PREFIX):] for name in cc_files_output
if name.endswith('.cc') and name.startswith(PROTOBUF_CC_PREFIX)]
- cc_files = [cc_file[len(PROTOBUF_CC_PREFIX):] for cc_file in cc_files]
- deps_file_content = DEPS_FILE_CONTENT.format(cc_files)
+ proto_files_output = bazel_query(BAZEL_DEPS_COMMON_PROTOS_QUERY)
+ proto_files = [
+ name[len(PROTOBUF_PROTO_PREFIX):] for name in proto_files_output
+ if name.endswith('.proto') and name.startswith(PROTOBUF_PROTO_PREFIX)]
+ deps_file_content = DEPS_FILE_CONTENT.format(
+ cc_files=cc_files,
+ proto_files=proto_files,
+ cc_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT),
+ proto_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT))
return deps_file_content
@@ -123,7 +140,7 @@ def main():
shutil.copytree(GRPC_INCLUDE, GRPC_PYTHON_INCLUDE)
try:
- protoc_lib_deps_content = get_deps(BAZEL_DEPS_PROTOC_LIB_QUERY)
+ protoc_lib_deps_content = get_deps()
except Exception as error:
# We allow this script to succeed even if we couldn't get the dependencies,
# as then we can assume that even without a successful bazel run the
diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
index 3e31a2b623..1d4e8e1a4a 100644
--- a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
@@ -41,3 +41,10 @@ RUN /opt/python/cp27-cp27mu/bin/pip install cython
RUN /opt/python/cp34-cp34m/bin/pip install cython
RUN /opt/python/cp35-cp35m/bin/pip install cython
+####################################################
+# Install auditwheel with fix for namespace packages
+RUN git clone https://github.com/pypa/auditwheel /usr/local/src/auditwheel
+RUN cd /usr/local/src/auditwheel && git checkout bf071b38c9fe78b025ea05c78b1cb61d7cb09939
+RUN /opt/python/cp35-cp35m/bin/pip install /usr/local/src/auditwheel
+RUN rm /usr/local/bin/auditwheel
+RUN cd /usr/local/bin && ln -s /opt/python/cp35-cp35m/bin/auditwheel
diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
index 5fe62c28b7..810499695e 100644
--- a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
@@ -41,3 +41,10 @@ RUN /opt/python/cp27-cp27mu/bin/pip install cython
RUN /opt/python/cp34-cp34m/bin/pip install cython
RUN /opt/python/cp35-cp35m/bin/pip install cython
+####################################################
+# Install auditwheel with fix for namespace packages
+RUN git clone https://github.com/pypa/auditwheel /usr/local/src/auditwheel
+RUN cd /usr/local/src/auditwheel && git checkout bf071b38c9fe78b025ea05c78b1cb61d7cb09939
+RUN /opt/python/cp35-cp35m/bin/pip install /usr/local/src/auditwheel
+RUN rm /usr/local/bin/auditwheel
+RUN cd /usr/local/bin && ln -s /opt/python/cp35-cp35m/bin/auditwheel
diff --git a/tools/run_tests/build_artifact_python.sh b/tools/run_tests/build_artifact_python.sh
index 4320f978e3..55f8eb634b 100755
--- a/tools/run_tests/build_artifact_python.sh
+++ b/tools/run_tests/build_artifact_python.sh
@@ -59,12 +59,14 @@ ${SETARCH_CMD} ${PYTHON} setup.py \
${SETARCH_CMD} ${PYTHON} setup.py \
bdist_wheel
+# Build gRPC tools package distribution
+${PYTHON} tools/distrib/python/make_grpcio_tools.py
+
# Build gRPC tools package source distribution
${SETARCH_CMD} ${PYTHON} tools/distrib/python/grpcio_tools/setup.py \
sdist
# Build gRPC tools package binary distribution
-${PYTHON} tools/distrib/python/make_grpcio_tools.py
CFLAGS="$CFLAGS -fno-wrapv" ${SETARCH_CMD} \
${PYTHON} tools/distrib/python/grpcio_tools/setup.py bdist_wheel
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 59933e3962..6624e399d4 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -73465,6 +73465,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/2463aea879c5ab49f8409d0e5c062c7e086b034b"
],
"ci_platforms": [
@@ -74893,6 +74910,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/552199651d942e7220141a93ec33dd8256210a18"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/55af20415ead0ddd417f37fa91a4c767b749ee34"
],
"ci_platforms": [
@@ -75658,6 +75692,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/7a946bf3cd91b63001f2cf3f40c515c747f2ecde"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/7b453adcb9c4bf31dbc448ff32c2bc90ebcbdf0f"
],
"ci_platforms": [
@@ -75675,6 +75726,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/7d25c28298fb4d0fe41209d0d14307e4aa67c59e"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/7ddfac7d7845b424bf670070781ca6ff8586c63b"
],
"ci_platforms": [
@@ -75726,6 +75794,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/8138b18a9a743659befc2f2b23d23cb9c3086a09"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/8164d3c4af043c47cfd6966873bccd2353d072bf"
],
"ci_platforms": [
@@ -76134,6 +76219,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/925011abb99fd56bb0f425ae5e0d92e6d341f804"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/93beeba2.bin"
],
"ci_platforms": [
@@ -77545,6 +77647,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/crash-c1f66840627e3bfdedf2e4c225bc4de0c267ed37"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/crash-dae0f07934a527989f23f06e630710ff6ca8c809"
],
"ci_platforms": [
@@ -77647,6 +77766,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/d6bed9cc3c10338a8c5f41064ff8bec0bbc267ce"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/d8a1d141a9e3876b71c7decbe6e3affccf6de397"
],
"ci_platforms": [
@@ -77800,6 +77936,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/dda9643679f8c8b796e64232a7d153e447d64991"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/df5d3cf5f05eab65ef9d385e263780ae73c42b19"
],
"ci_platforms": [
@@ -77902,6 +78055,23 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/server_fuzzer_corpus/e7b08e36420fa107f0aee652e62158af85a4ef15"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "server_fuzzer_one_entry",
+ "platforms": [
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/server_fuzzer_corpus/e96ad9c17795e52edc810a08d4fc61fe8790002a"
],
"ci_platforms": [