Merge github.com:grpc/grpc into pollset_kick_stats

pull/12370/head
Craig Tiller 8 years ago
commit 1ed11b7d66
  1. 8
      BUILD
  2. 2
      config.m4
  3. 1
      doc/environment_variables.md
  4. 1
      grpc.gemspec
  5. 4
      include/grpc/compression.h
  6. 5
      package.xml
  7. 2
      setup.py
  8. 28
      src/core/ext/census/base_resources.c
  9. 13
      src/core/ext/filters/client_channel/client_channel.c
  10. 2
      src/core/ext/filters/client_channel/client_channel_factory.c
  11. 4
      src/core/ext/filters/client_channel/client_channel_plugin.c
  12. 6
      src/core/ext/filters/client_channel/http_proxy.c
  13. 7
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
  14. 2
      src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c
  15. 2
      src/core/ext/filters/client_channel/lb_policy_factory.c
  16. 4
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c
  17. 2
      src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c
  18. 2
      src/core/ext/filters/client_channel/subchannel.c
  19. 4
      src/core/ext/filters/http/message_compress/message_compress_filter.c
  20. 3
      src/core/ext/filters/load_reporting/server_load_reporting_plugin.c
  21. 2
      src/core/ext/transport/chttp2/client/insecure/channel_create.c
  22. 2
      src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
  23. 1
      src/core/ext/transport/chttp2/transport/chttp2_plugin.c
  24. 1
      src/core/ext/transport/chttp2/transport/chttp2_transport.h
  25. 52
      src/core/ext/transport/chttp2/transport/stream_lists.c
  26. 4
      src/core/ext/transport/inproc/inproc_transport.c
  27. 12
      src/core/lib/channel/channel_args.c
  28. 2
      src/core/lib/channel/channel_stack.h
  29. 4
      src/core/lib/compression/compression.c
  30. 2
      src/core/lib/debug/trace.h
  31. 3
      src/core/lib/http/httpcli_security_connector.c
  32. 18
      src/core/lib/iomgr/closure.c
  33. 2
      src/core/lib/iomgr/error.c
  34. 2
      src/core/lib/iomgr/resolve_address_posix.c
  35. 22
      src/core/lib/security/transport/security_connector.c
  36. 2
      src/core/lib/support/log_linux.c
  37. 2
      src/core/lib/support/string.c
  38. 8
      src/core/lib/surface/call.c
  39. 19
      src/core/lib/surface/completion_queue.c
  40. 2
      src/core/lib/transport/transport_op_string.c
  41. 113
      src/core/tsi/ssl_transport_security.c
  42. 37
      src/core/tsi/ssl_transport_security.h
  43. 2
      src/cpp/client/client_context.cc
  44. 2
      src/cpp/server/server_context.cc
  45. 1
      src/csharp/Grpc.Auth/Grpc.Auth.csproj
  46. 1
      src/csharp/Grpc.Core.Testing/Grpc.Core.Testing.csproj
  47. 3
      src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
  48. 3
      src/csharp/Grpc.Core/Grpc.Core.csproj
  49. 1
      src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
  50. 1
      src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
  51. 2
      src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
  52. 1
      src/csharp/Grpc.Examples/Grpc.Examples.csproj
  53. 2
      src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
  54. 1
      src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
  55. 2
      src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
  56. 2
      src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
  57. 2
      src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
  58. 2
      src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj
  59. 6
      src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
  60. 2
      src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj
  61. 2
      src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj
  62. 1
      src/csharp/Grpc.Reflection/Grpc.Reflection.csproj
  63. 2
      src/csharp/doc/.gitignore
  64. 9
      src/csharp/doc/README.md
  65. 37
      src/csharp/doc/docfx.json
  66. 83
      src/csharp/doc/grpc_csharp_public.shfbproj
  67. 3
      src/csharp/doc/toc.yml
  68. 11
      src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
  69. 9
      src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
  70. 1
      src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
  71. 13
      src/python/grpcio/grpc/_cython/_cygrpc/records.pxd.pxi
  72. 118
      src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
  73. 2
      src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
  74. 2
      src/python/grpcio_health_checking/setup.py
  75. 2
      src/python/grpcio_reflection/setup.py
  76. 2
      src/python/grpcio_testing/grpc_testing/__init__.py
  77. 4
      src/python/grpcio_testing/grpc_version.py
  78. 341
      src/python/grpcio_tests/tests/protoc_plugin/beta_python_plugin_test.py
  79. 4
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  80. 28
      src/ruby/lib/grpc/google_rpc_status_utils.rb
  81. 223
      src/ruby/spec/google_rpc_status_utils_spec.rb
  82. 2
      templates/config.m4.template
  83. 1
      templates/grpc.gemspec.template
  84. 5
      templates/package.xml.template
  85. 19
      templates/src/python/grpcio_testing/grpc_version.py.template
  86. 2
      test/core/compression/algorithm_test.c
  87. 2
      test/core/compression/compression_test.c
  88. 2
      test/core/compression/message_compress_test.c
  89. 2
      test/core/end2end/tests/compressed_payload.c
  90. 2
      test/core/end2end/tests/stream_compression_compressed_payload.c
  91. 121
      test/core/tsi/ssl_transport_security_test.c
  92. 2
      tools/distrib/python/grpcio_tools/setup.py
  93. 13
      tools/dockerfile/distribtest/csharp_jessie_x64/Dockerfile
  94. 13
      tools/dockerfile/distribtest/csharp_jessie_x86/Dockerfile
  95. 11
      tools/dockerfile/distribtest/csharp_ubuntu1604_x64/Dockerfile
  96. 114
      tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
  97. 30
      tools/internal_ci/linux/pull_request/grpc_basictests_c_dbg.cfg
  98. 30
      tools/internal_ci/linux/pull_request/grpc_basictests_c_opt.cfg
  99. 30
      tools/internal_ci/linux/pull_request/grpc_basictests_cpp_dbg.cfg
  100. 30
      tools/internal_ci/linux/pull_request/grpc_basictests_cpp_opt.cfg
  101. Some files were not shown because too many files have changed in this diff Show More

@ -574,6 +574,8 @@ grpc_cc_library(
"src/core/lib/compression/compression.c",
"src/core/lib/compression/message_compress.c",
"src/core/lib/compression/stream_compression.c",
"src/core/lib/debug/stats.c",
"src/core/lib/debug/stats_data.c",
"src/core/lib/http/format_request.c",
"src/core/lib/http/httpcli.c",
"src/core/lib/http/parser.c",
@ -690,8 +692,6 @@ grpc_cc_library(
"src/core/lib/transport/timeout_encoding.c",
"src/core/lib/transport/transport.c",
"src/core/lib/transport/transport_op_string.c",
"src/core/lib/debug/stats.c",
"src/core/lib/debug/stats_data.c",
],
hdrs = [
"src/core/lib/channel/channel_args.h",
@ -705,6 +705,8 @@ grpc_cc_library(
"src/core/lib/compression/algorithm_metadata.h",
"src/core/lib/compression/message_compress.h",
"src/core/lib/compression/stream_compression.h",
"src/core/lib/debug/stats.h",
"src/core/lib/debug/stats_data.h",
"src/core/lib/http/format_request.h",
"src/core/lib/http/httpcli.h",
"src/core/lib/http/parser.h",
@ -807,8 +809,6 @@ grpc_cc_library(
"src/core/lib/transport/timeout_encoding.h",
"src/core/lib/transport/transport.h",
"src/core/lib/transport/transport_impl.h",
"src/core/lib/debug/stats.h",
"src/core/lib/debug/stats_data.h",
],
external_deps = [
"zlib",

@ -12,7 +12,7 @@ if test "$PHP_GRPC" != "no"; then
LIBS="-lpthread $LIBS"
CFLAGS="-Wall -Werror -Wno-parentheses-equality -Wno-unused-value -std=c11"
CXXFLAGS="-std=c++11"
CXXFLAGS="-std=c++11 -fno-exceptions -fno-rtti"
GRPC_SHARED_LIBADD="-lpthread $GRPC_SHARED_LIBADD"
PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(pthread)

@ -50,6 +50,7 @@ some configuration as environment variables that can be set.
- channel_stack_builder - traces information about channel stacks being built
- executor - traces grpc's internal thread pool ('the executor')
- http - traces state in the http2 transport engine
- http2_stream_state - traces all http2 stream state mutations.
- http1 - traces HTTP/1.x operations performed by gRPC
- inproc - traces the in-process transport
- flowctl - traces http2 flow control

@ -29,6 +29,7 @@ Gem::Specification.new do |s|
s.add_dependency 'google-protobuf', '~> 3.1'
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0'
s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'facter', '~> 2.4'

@ -44,13 +44,13 @@ int grpc_stream_compression_algorithm_parse(
* algorithm. Note that \a name is statically allocated and must *not* be freed.
* Returns 1 upon success, 0 otherwise. */
GRPCAPI int grpc_compression_algorithm_name(
grpc_compression_algorithm algorithm, char **name);
grpc_compression_algorithm algorithm, const char **name);
/** Updates \a name with the encoding name corresponding to a valid \a
* algorithm. Note that \a name is statically allocated and must *not* be freed.
* Returns 1 upon success, 0 otherwise. */
GRPCAPI int grpc_stream_compression_algorithm_name(
grpc_stream_compression_algorithm algorithm, char **name);
grpc_stream_compression_algorithm algorithm, const char **name);
/** Returns the compression algorithm corresponding to \a level for the
* compression algorithms encoded in the \a accepted_encodings bitset.

@ -10,7 +10,7 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
<date>2017-05-22</date>
<date>2017-08-24</date>
<time>16:06:07</time>
<version>
<release>1.7.0dev</release>
@ -25,6 +25,9 @@
- Channel are now by default persistent #11878
- Some bug fixes from 1.4 branch #12109, #12123
- Fixed hang bug when fork() was used #11814
- License changed to Apache 2.0
- Added support for php_namespace option in codegen plugin #11886
- Updated gRPC C Core library version 1.6
</notes>
<contents>
<dir baseinstalldir="/" name="/">

@ -70,7 +70,7 @@ CLASSIFIERS = [
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'License :: OSI Approved :: Apache Software License',
],
]
# Environment variable to determine whether or not the Cython extension should
# *use* Cython or use the generated C files. Note that this requires the C files

@ -37,20 +37,20 @@
void define_base_resources() {
google_census_Resource_BasicUnit numerator =
google_census_Resource_BasicUnit_SECS;
resource r = {"client_rpc_latency", // name
"Client RPC latency in seconds", // description
0, // prefix
1, // n_numerators
&numerator, // numerators
0, // n_denominators
NULL}; // denominators
resource r = {(char *)"client_rpc_latency", // name
(char *)"Client RPC latency in seconds", // description
0, // prefix
1, // n_numerators
&numerator, // numerators
0, // n_denominators
NULL}; // denominators
define_resource(&r);
r = (resource){"server_rpc_latency", // name
"Server RPC latency in seconds", // description
0, // prefix
1, // n_numerators
&numerator, // numerators
0, // n_denominators
NULL}; // denominators
r = (resource){(char *)"server_rpc_latency", // name
(char *)"Server RPC latency in seconds", // description
0, // prefix
1, // n_numerators
&numerator, // numerators
0, // n_denominators
NULL}; // denominators
define_resource(&r);
}

@ -375,7 +375,7 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
}
// Extract the following fields from the resolver result, if non-NULL.
bool lb_policy_updated = false;
char *lb_policy_name = NULL;
char *lb_policy_name_dup = NULL;
bool lb_policy_name_changed = false;
grpc_lb_policy *new_lb_policy = NULL;
char *service_config_json = NULL;
@ -383,6 +383,7 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
grpc_slice_hash_table *method_params_table = NULL;
if (chand->resolver_result != NULL) {
// Find LB policy name.
const char *lb_policy_name = NULL;
const grpc_arg *channel_arg =
grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_POLICY_NAME);
if (channel_arg != NULL) {
@ -473,7 +474,7 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
// Before we clean up, save a copy of lb_policy_name, since it might
// be pointing to data inside chand->resolver_result.
// The copy will be saved in chand->lb_policy_name below.
lb_policy_name = gpr_strdup(lb_policy_name);
lb_policy_name_dup = gpr_strdup(lb_policy_name);
grpc_channel_args_destroy(exec_ctx, chand->resolver_result);
chand->resolver_result = NULL;
}
@ -481,8 +482,8 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
gpr_log(GPR_DEBUG,
"chand=%p: resolver result: lb_policy_name=\"%s\"%s, "
"service_config=\"%s\"",
chand, lb_policy_name, lb_policy_name_changed ? " (changed)" : "",
service_config_json);
chand, lb_policy_name_dup,
lb_policy_name_changed ? " (changed)" : "", service_config_json);
}
// Now swap out fields in chand. Note that the new values may still
// be NULL if (e.g.) the resolver failed to return results or the
@ -490,9 +491,9 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
//
// First, swap out the data used by cc_get_channel_info().
gpr_mu_lock(&chand->info_mu);
if (lb_policy_name != NULL) {
if (lb_policy_name_dup != NULL) {
gpr_free(chand->info_lb_policy_name);
chand->info_lb_policy_name = lb_policy_name;
chand->info_lb_policy_name = lb_policy_name_dup;
}
if (service_config_json != NULL) {
gpr_free(chand->info_service_config_json);

@ -63,6 +63,6 @@ static const grpc_arg_pointer_vtable factory_arg_vtable = {
grpc_arg grpc_client_channel_factory_create_channel_arg(
grpc_client_channel_factory* factory) {
return grpc_channel_arg_pointer_create(GRPC_ARG_CLIENT_CHANNEL_FACTORY,
return grpc_channel_arg_pointer_create((char*)GRPC_ARG_CLIENT_CHANNEL_FACTORY,
factory, &factory_arg_vtable);
}

@ -54,8 +54,8 @@ static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx,
char *default_authority = grpc_get_default_authority(
exec_ctx, grpc_channel_stack_builder_get_target(builder));
if (default_authority != NULL) {
grpc_arg arg = grpc_channel_arg_string_create(GRPC_ARG_DEFAULT_AUTHORITY,
default_authority);
grpc_arg arg = grpc_channel_arg_string_create(
(char *)GRPC_ARG_DEFAULT_AUTHORITY, default_authority);
grpc_channel_args *new_args = grpc_channel_args_copy_and_add(args, &arg, 1);
grpc_channel_stack_builder_set_channel_arguments(exec_ctx, builder,
new_args);

@ -157,7 +157,7 @@ static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
}
grpc_arg args_to_add[2];
args_to_add[0] = grpc_channel_arg_string_create(
GRPC_ARG_HTTP_CONNECT_SERVER,
(char*)GRPC_ARG_HTTP_CONNECT_SERVER,
uri->path[0] == '/' ? uri->path + 1 : uri->path);
if (user_cred != NULL) {
/* Use base64 encoding for user credentials as stated in RFC 7617 */
@ -166,8 +166,8 @@ static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
char* header;
gpr_asprintf(&header, "Proxy-Authorization:Basic %s", encoded_user_cred);
gpr_free(encoded_user_cred);
args_to_add[1] =
grpc_channel_arg_string_create(GRPC_ARG_HTTP_CONNECT_HEADERS, header);
args_to_add[1] = grpc_channel_arg_string_create(
(char*)GRPC_ARG_HTTP_CONNECT_HEADERS, header);
*new_args = grpc_channel_args_copy_and_add(args, args_to_add, 2);
gpr_free(header);
} else {

@ -1560,6 +1560,9 @@ static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
exec_ctx, glb_policy->lb_call, ops, (size_t)(op - ops),
&glb_policy->lb_on_response_received); /* loop */
GPR_ASSERT(GRPC_CALL_OK == call_error);
} else {
GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
"lb_on_response_received_locked_shutdown");
}
} else { /* empty payload: call cancelled. */
/* dispose of the "lb_on_response_received_locked" weak ref taken in
@ -1830,8 +1833,8 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
// since we use this to trigger the client_load_reporting filter.
grpc_arg new_arg =
grpc_channel_arg_string_create(GRPC_ARG_LB_POLICY_NAME, "grpclb");
grpc_arg new_arg = grpc_channel_arg_string_create(
(char *)GRPC_ARG_LB_POLICY_NAME, (char *)"grpclb");
static const char *args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
glb_policy->args = grpc_channel_args_copy_and_add_and_remove(
args->args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);

@ -589,7 +589,7 @@ static void rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx, void *arg,
// Dispose of outdated subchannel lists.
if (sd->subchannel_list != p->subchannel_list &&
sd->subchannel_list != p->latest_pending_subchannel_list) {
char *reason = NULL;
const char *reason = NULL;
if (sd->subchannel_list->shutting_down) {
reason = "sl_outdated_straggler";
rr_subchannel_list_unref(exec_ctx, sd->subchannel_list, reason);

@ -141,7 +141,7 @@ static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = {
grpc_arg grpc_lb_addresses_create_channel_arg(
const grpc_lb_addresses* addresses) {
return grpc_channel_arg_pointer_create(
GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable);
(char*)GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable);
}
grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(

@ -249,7 +249,7 @@ static void dns_ares_on_resolved_locked(grpc_exec_ctx *exec_ctx, void *arg,
service_config_string);
args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG;
new_args[num_args_to_add++] = grpc_channel_arg_string_create(
GRPC_ARG_SERVICE_CONFIG, service_config_string);
(char *)GRPC_ARG_SERVICE_CONFIG, service_config_string);
service_config = grpc_service_config_create(service_config_string);
if (service_config != NULL) {
const char *lb_policy_name =
@ -257,7 +257,7 @@ static void dns_ares_on_resolved_locked(grpc_exec_ctx *exec_ctx, void *arg,
if (lb_policy_name != NULL) {
args_to_remove[num_args_to_remove++] = GRPC_ARG_LB_POLICY_NAME;
new_args[num_args_to_add++] = grpc_channel_arg_string_create(
GRPC_ARG_LB_POLICY_NAME, (char *)lb_policy_name);
(char *)GRPC_ARG_LB_POLICY_NAME, (char *)lb_policy_name);
}
}
}

@ -210,7 +210,7 @@ grpc_arg grpc_fake_resolver_response_generator_arg(
grpc_fake_resolver_response_generator* generator) {
grpc_arg arg;
arg.type = GRPC_ARG_POINTER;
arg.key = GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR;
arg.key = (char*)GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR;
arg.value.pointer.p = generator;
arg.value.pointer.vtable = &response_generator_arg_vtable;
return arg;

@ -811,6 +811,6 @@ const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args) {
grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr) {
return grpc_channel_arg_string_create(
GRPC_ARG_SUBCHANNEL_ADDRESS,
(char *)GRPC_ARG_SUBCHANNEL_ADDRESS,
addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup(""));
}

@ -244,7 +244,7 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx,
&calld->slices, &tmp);
if (did_compress) {
if (GRPC_TRACER_ON(grpc_compression_trace)) {
char *algo_name;
const char *algo_name;
const size_t before_size = calld->slices.length;
const size_t after_size = tmp.length;
const float savings_ratio = 1.0f - (float)after_size / (float)before_size;
@ -258,7 +258,7 @@ static void finish_send_message(grpc_exec_ctx *exec_ctx,
send_flags |= GRPC_WRITE_INTERNAL_COMPRESS;
} else {
if (GRPC_TRACER_ON(grpc_compression_trace)) {
char *algo_name;
const char *algo_name;
GPR_ASSERT(grpc_compression_algorithm_name(calld->compression_algorithm,
&algo_name));
gpr_log(GPR_DEBUG,

@ -55,7 +55,8 @@ static bool maybe_add_server_load_reporting_filter(
}
grpc_arg grpc_load_reporting_enable_arg() {
return grpc_channel_arg_integer_create(GRPC_ARG_ENABLE_LOAD_REPORTING, 1);
return grpc_channel_arg_integer_create((char *)GRPC_ARG_ENABLE_LOAD_REPORTING,
1);
}
/* Plugin registration */

@ -55,7 +55,7 @@ static grpc_channel *client_channel_factory_create_channel(
}
// Add channel arg containing the server URI.
grpc_arg arg = grpc_channel_arg_string_create(
GRPC_ARG_SERVER_URI,
(char *)GRPC_ARG_SERVER_URI,
grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target));
const char *to_remove[] = {GRPC_ARG_SERVER_URI};
grpc_channel_args *new_args =

@ -42,7 +42,7 @@ grpc_channel *grpc_insecure_channel_create_from_fd(
(target, fd, args));
grpc_arg default_authority_arg = grpc_channel_arg_string_create(
GRPC_ARG_DEFAULT_AUTHORITY, "test.authority");
(char *)GRPC_ARG_DEFAULT_AUTHORITY, (char *)"test.authority");
grpc_channel_args *final_args =
grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);

@ -23,6 +23,7 @@
void grpc_chttp2_plugin_init(void) {
grpc_register_tracer(&grpc_http_trace);
grpc_register_tracer(&grpc_flowctl_trace);
grpc_register_tracer(&grpc_trace_http2_stream_state);
#ifndef NDEBUG
grpc_register_tracer(&grpc_trace_chttp2_refcount);
#endif

@ -25,6 +25,7 @@
extern grpc_tracer_flag grpc_http_trace;
extern grpc_tracer_flag grpc_flowctl_trace;
extern grpc_tracer_flag grpc_trace_http2_stream_state;
#ifndef NDEBUG
extern grpc_tracer_flag grpc_trace_chttp2_refcount;

@ -20,6 +20,27 @@
#include <grpc/support/log.h>
static char *stream_list_id_string(grpc_chttp2_stream_list_id id) {
switch (id) {
case GRPC_CHTTP2_LIST_WRITABLE:
return "writable";
case GRPC_CHTTP2_LIST_WRITING:
return "writing";
case GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT:
return "stalled_by_transport";
case GRPC_CHTTP2_LIST_STALLED_BY_STREAM:
return "stalled_by_stream";
case GRPC_CHTTP2_LIST_WAITING_FOR_CONCURRENCY:
return "waiting_for_concurrency";
case STREAM_LIST_COUNT:
GPR_UNREACHABLE_CODE(return "unknown");
}
GPR_UNREACHABLE_CODE(return "unknown");
}
grpc_tracer_flag grpc_trace_http2_stream_state =
GRPC_TRACER_INITIALIZER(false, "http2_stream_state");
/* core list management */
static bool stream_list_empty(grpc_chttp2_transport *t,
@ -44,6 +65,10 @@ static bool stream_list_pop(grpc_chttp2_transport *t,
s->included[id] = 0;
}
*stream = s;
if (s && GRPC_TRACER_ON(grpc_trace_http2_stream_state)) {
gpr_log(GPR_DEBUG, "%p[%d][%s]: pop from %s", t, s->id,
t->is_client ? "cli" : "svr", stream_list_id_string(id));
}
return s != 0;
}
@ -62,6 +87,10 @@ static void stream_list_remove(grpc_chttp2_transport *t, grpc_chttp2_stream *s,
} else {
t->lists[id].tail = s->links[id].prev;
}
if (GRPC_TRACER_ON(grpc_trace_http2_stream_state)) {
gpr_log(GPR_DEBUG, "%p[%d][%s]: remove from %s", t, s->id,
t->is_client ? "cli" : "svr", stream_list_id_string(id));
}
}
static bool stream_list_maybe_remove(grpc_chttp2_transport *t,
@ -90,6 +119,10 @@ static void stream_list_add_tail(grpc_chttp2_transport *t,
}
t->lists[id].tail = s;
s->included[id] = 1;
if (GRPC_TRACER_ON(grpc_trace_http2_stream_state)) {
gpr_log(GPR_DEBUG, "%p[%d][%s]: add to %s", t, s->id,
t->is_client ? "cli" : "svr", stream_list_id_string(id));
}
}
static bool stream_list_add(grpc_chttp2_transport *t, grpc_chttp2_stream *s,
@ -150,17 +183,12 @@ void grpc_chttp2_list_remove_waiting_for_concurrency(grpc_chttp2_transport *t,
void grpc_chttp2_list_add_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
GRPC_FLOW_CONTROL_IF_TRACING(
gpr_log(GPR_DEBUG, "stream %u stalled by transport", s->id));
stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
}
bool grpc_chttp2_list_pop_stalled_by_transport(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool ret = stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
GRPC_FLOW_CONTROL_IF_TRACING(if (ret) gpr_log(
GPR_DEBUG, "stream %u un-stalled by transport", (*s)->id));
return ret;
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_TRANSPORT);
}
void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t,
@ -170,23 +198,15 @@ void grpc_chttp2_list_remove_stalled_by_transport(grpc_chttp2_transport *t,
void grpc_chttp2_list_add_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
GRPC_FLOW_CONTROL_IF_TRACING(
gpr_log(GPR_DEBUG, "stream %u stalled by stream", s->id));
stream_list_add(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
}
bool grpc_chttp2_list_pop_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream **s) {
bool ret = stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
GRPC_FLOW_CONTROL_IF_TRACING(
if (ret) gpr_log(GPR_DEBUG, "stream %u un-stalled by stream", (*s)->id));
return ret;
return stream_list_pop(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
}
bool grpc_chttp2_list_remove_stalled_by_stream(grpc_chttp2_transport *t,
grpc_chttp2_stream *s) {
bool ret = stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
GRPC_FLOW_CONTROL_IF_TRACING(
if (ret) gpr_log(GPR_DEBUG, "stream %u un-stalled by stream", s->id));
return ret;
return stream_list_maybe_remove(t, s, GRPC_CHTTP2_LIST_STALLED_BY_STREAM);
}

@ -1263,8 +1263,8 @@ grpc_channel *grpc_inproc_channel_create(grpc_server *server,
grpc_arg default_authority_arg;
default_authority_arg.type = GRPC_ARG_STRING;
default_authority_arg.key = GRPC_ARG_DEFAULT_AUTHORITY;
default_authority_arg.value.string = "inproc.authority";
default_authority_arg.key = (char *)GRPC_ARG_DEFAULT_AUTHORITY;
default_authority_arg.value.string = (char *)"inproc.authority";
grpc_channel_args *client_args =
grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);

@ -243,7 +243,7 @@ grpc_channel_args *grpc_channel_args_set_compression_algorithm(
GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT);
grpc_arg tmp;
tmp.type = GRPC_ARG_INTEGER;
tmp.key = GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
tmp.key = (char *)GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
tmp.value.integer = algorithm;
return grpc_channel_args_copy_and_add(a, &tmp, 1);
}
@ -253,7 +253,7 @@ grpc_channel_args *grpc_channel_args_set_stream_compression_algorithm(
GPR_ASSERT(algorithm < GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT);
grpc_arg tmp;
tmp.type = GRPC_ARG_INTEGER;
tmp.key = GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
tmp.key = (char *)GRPC_STREAM_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
tmp.value.integer = algorithm;
return grpc_channel_args_copy_and_add(a, &tmp, 1);
}
@ -308,7 +308,7 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
if (grpc_channel_args_get_compression_algorithm(*a) == algorithm &&
state == 0) {
char *algo_name = NULL;
const char *algo_name = NULL;
GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0);
gpr_log(GPR_ERROR,
"Tried to disable default compression algorithm '%s'. The "
@ -324,7 +324,7 @@ grpc_channel_args *grpc_channel_args_compression_algorithm_set_state(
/* create a new arg */
grpc_arg tmp;
tmp.type = GRPC_ARG_INTEGER;
tmp.key = GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET;
tmp.key = (char *)GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET;
/* all enabled by default */
tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
if (state != 0) {
@ -349,7 +349,7 @@ grpc_channel_args *grpc_channel_args_stream_compression_algorithm_set_state(
if (grpc_channel_args_get_stream_compression_algorithm(*a) == algorithm &&
state == 0) {
char *algo_name = NULL;
const char *algo_name = NULL;
GPR_ASSERT(grpc_stream_compression_algorithm_name(algorithm, &algo_name) !=
0);
gpr_log(GPR_ERROR,
@ -366,7 +366,7 @@ grpc_channel_args *grpc_channel_args_stream_compression_algorithm_set_state(
/* create a new arg */
grpc_arg tmp;
tmp.type = GRPC_ARG_INTEGER;
tmp.key = GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET;
tmp.key = (char *)GRPC_STREAM_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET;
/* all enabled by default */
tmp.value.integer = (1u << GRPC_STREAM_COMPRESS_ALGORITHMS_COUNT) - 1;
if (state != 0) {

@ -281,7 +281,7 @@ grpc_channel_stack *grpc_channel_stack_from_top_element(
/* Given the top element of a call stack, get the call stack itself */
grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem);
void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
void grpc_call_log_op(const char *file, int line, gpr_log_severity severity,
grpc_call_element *elem,
grpc_transport_stream_op_batch *op);

@ -60,7 +60,7 @@ int grpc_stream_compression_algorithm_parse(
}
int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
char **name) {
const char **name) {
GRPC_API_TRACE("grpc_compression_algorithm_parse(algorithm=%d, name=%p)", 2,
((int)algorithm, name));
switch (algorithm) {
@ -80,7 +80,7 @@ int grpc_compression_algorithm_name(grpc_compression_algorithm algorithm,
}
int grpc_stream_compression_algorithm_name(
grpc_stream_compression_algorithm algorithm, char **name) {
grpc_stream_compression_algorithm algorithm, const char **name) {
GRPC_API_TRACE(
"grpc_stream_compression_algorithm_parse(algorithm=%d, name=%p)", 2,
((int)algorithm, name));

@ -35,7 +35,7 @@ typedef struct {
#else
bool value;
#endif
char *name;
const char *name;
} grpc_tracer_flag;
#ifdef GRPC_THREADSAFE_TRACER

@ -43,7 +43,8 @@ static void httpcli_ssl_destroy(grpc_exec_ctx *exec_ctx,
grpc_httpcli_ssl_channel_security_connector *c =
(grpc_httpcli_ssl_channel_security_connector *)sc;
if (c->handshaker_factory != NULL) {
tsi_ssl_client_handshaker_factory_destroy(c->handshaker_factory);
tsi_ssl_client_handshaker_factory_unref(c->handshaker_factory);
c->handshaker_factory = NULL;
}
if (c->secure_peer_name != NULL) gpr_free(c->secure_peer_name);
gpr_free(sc);

@ -167,7 +167,14 @@ void grpc_closure_sched(grpc_exec_ctx *exec_ctx, grpc_closure *c,
GPR_TIMER_BEGIN("grpc_closure_sched", 0);
if (c != NULL) {
#ifndef NDEBUG
GPR_ASSERT(!c->scheduled);
if (c->scheduled) {
gpr_log(GPR_ERROR,
"Closure already scheduled. (closure: %p, created: [%s:%d], "
"previously scheduled at: [%s: %d] run?: %s",
c, c->file_created, c->line_created, c->file_initiated,
c->line_initiated, c->run ? "true" : "false");
abort();
}
c->scheduled = true;
c->file_initiated = file;
c->line_initiated = line;
@ -191,7 +198,14 @@ void grpc_closure_list_sched(grpc_exec_ctx *exec_ctx, grpc_closure_list *list) {
while (c != NULL) {
grpc_closure *next = c->next_data.next;
#ifndef NDEBUG
GPR_ASSERT(!c->scheduled);
if (c->scheduled) {
gpr_log(GPR_ERROR,
"Closure already scheduled. (closure: %p, created: [%s:%d], "
"previously scheduled at: [%s: %d] run?: %s",
c, c->file_created, c->line_created, c->file_initiated,
c->line_initiated, c->run ? "true" : "false");
abort();
}
c->scheduled = true;
c->file_initiated = file;
c->line_initiated = line;

@ -641,7 +641,7 @@ static char *key_time(grpc_error_times which) {
static char *fmt_time(gpr_timespec tm) {
char *out;
char *pfx = "!!";
const char *pfx = "!!";
switch (tm.clock_type) {
case GPR_CLOCK_MONOTONIC:
pfx = "@monotonic:";

@ -85,7 +85,7 @@ static grpc_error *blocking_resolve_address_impl(
if (s != 0) {
/* Retry if well-known service name is recognized */
char *svc[][2] = {{"http", "80"}, {"https", "443"}};
const char *svc[][2] = {{"http", "80"}, {"https", "443"}};
for (i = 0; i < GPR_ARRAY_SIZE(svc); i++) {
if (strcmp(port, svc[i][0]) == 0) {
GRPC_SCHEDULING_START_BLOCKING_REGION;

@ -455,14 +455,14 @@ grpc_server_security_connector *grpc_fake_server_security_connector_create(
typedef struct {
grpc_channel_security_connector base;
tsi_ssl_client_handshaker_factory *handshaker_factory;
tsi_ssl_client_handshaker_factory *client_handshaker_factory;
char *target_name;
char *overridden_target_name;
} grpc_ssl_channel_security_connector;
typedef struct {
grpc_server_security_connector base;
tsi_ssl_server_handshaker_factory *handshaker_factory;
tsi_ssl_server_handshaker_factory *server_handshaker_factory;
} grpc_ssl_server_security_connector;
static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
@ -470,9 +470,8 @@ static void ssl_channel_destroy(grpc_exec_ctx *exec_ctx,
grpc_ssl_channel_security_connector *c =
(grpc_ssl_channel_security_connector *)sc;
grpc_call_credentials_unref(exec_ctx, c->base.request_metadata_creds);
if (c->handshaker_factory != NULL) {
tsi_ssl_client_handshaker_factory_destroy(c->handshaker_factory);
}
tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory);
c->client_handshaker_factory = NULL;
if (c->target_name != NULL) gpr_free(c->target_name);
if (c->overridden_target_name != NULL) gpr_free(c->overridden_target_name);
gpr_free(sc);
@ -482,9 +481,8 @@ static void ssl_server_destroy(grpc_exec_ctx *exec_ctx,
grpc_security_connector *sc) {
grpc_ssl_server_security_connector *c =
(grpc_ssl_server_security_connector *)sc;
if (c->handshaker_factory != NULL) {
tsi_ssl_server_handshaker_factory_destroy(c->handshaker_factory);
}
tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory);
c->server_handshaker_factory = NULL;
gpr_free(sc);
}
@ -496,7 +494,7 @@ static void ssl_channel_add_handshakers(grpc_exec_ctx *exec_ctx,
// Instantiate TSI handshaker.
tsi_handshaker *tsi_hs = NULL;
tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
c->handshaker_factory,
c->client_handshaker_factory,
c->overridden_target_name != NULL ? c->overridden_target_name
: c->target_name,
&tsi_hs);
@ -521,7 +519,7 @@ static void ssl_server_add_handshakers(grpc_exec_ctx *exec_ctx,
// Instantiate TSI handshaker.
tsi_handshaker *tsi_hs = NULL;
tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
c->handshaker_factory, &tsi_hs);
c->server_handshaker_factory, &tsi_hs);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
tsi_result_to_string(result));
@ -852,7 +850,7 @@ grpc_security_status grpc_ssl_channel_security_connector_create(
result = tsi_create_ssl_client_handshaker_factory(
has_key_cert_pair ? &config->pem_key_cert_pair : NULL, pem_root_certs,
ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
&c->handshaker_factory);
&c->client_handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
@ -897,7 +895,7 @@ grpc_security_status grpc_ssl_server_security_connector_create(
config->pem_root_certs, get_tsi_client_certificate_request_type(
config->client_certificate_request),
ssl_cipher_suites(), alpn_protocol_strings, (uint16_t)num_alpn_protocols,
&c->handshaker_factory);
&c->server_handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));

@ -57,7 +57,7 @@ void gpr_log(const char *file, int line, gpr_log_severity severity,
}
void gpr_default_log(gpr_log_func_args *args) {
char *final_slash;
const char *final_slash;
char *prefix;
const char *display_file;
char time_buffer[64];

@ -276,7 +276,7 @@ static void add_string_to_split(const char *beg, const char *end, char ***strs,
void gpr_string_split(const char *input, const char *sep, char ***strs,
size_t *nstrs) {
char *next;
const char *next;
*strs = NULL;
*nstrs = 0;
size_t capstrs = 0;

@ -1512,7 +1512,7 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
} else if (grpc_compression_options_is_stream_compression_algorithm_enabled(
&compression_options, algo) == 0) {
/* check if algorithm is supported by current channel config */
char *algo_name = NULL;
const char *algo_name = NULL;
grpc_stream_compression_algorithm_name(algo, &algo_name);
gpr_asprintf(&error_msg, "Stream compression algorithm '%s' is disabled.",
algo_name);
@ -1526,7 +1526,7 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
if (!GPR_BITGET(call->stream_encodings_accepted_by_peer,
call->incoming_stream_compression_algorithm)) {
if (GRPC_TRACER_ON(grpc_compression_trace)) {
char *algo_name = NULL;
const char *algo_name = NULL;
grpc_stream_compression_algorithm_name(
call->incoming_stream_compression_algorithm, &algo_name);
gpr_log(
@ -1553,7 +1553,7 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
} else if (grpc_compression_options_is_algorithm_enabled(
&compression_options, algo) == 0) {
/* check if algorithm is supported by current channel config */
char *algo_name = NULL;
const char *algo_name = NULL;
grpc_compression_algorithm_name(algo, &algo_name);
gpr_asprintf(&error_msg, "Compression algorithm '%s' is disabled.",
algo_name);
@ -1569,7 +1569,7 @@ static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
if (!GPR_BITGET(call->encodings_accepted_by_peer,
call->incoming_compression_algorithm)) {
if (GRPC_TRACER_ON(grpc_compression_trace)) {
char *algo_name = NULL;
const char *algo_name = NULL;
grpc_compression_algorithm_name(call->incoming_compression_algorithm,
&algo_name);
gpr_log(GPR_ERROR,

@ -566,13 +566,13 @@ static void cq_check_tag(grpc_completion_queue *cq, void *tag, bool lock_cq) {}
* true if the increment was successful; false if the counter is zero */
static bool atm_inc_if_nonzero(gpr_atm *counter) {
while (true) {
gpr_atm count = gpr_atm_no_barrier_load(counter);
gpr_atm count = gpr_atm_acq_load(counter);
/* If zero, we are done. If not, we must to a CAS (instead of an atomic
* increment) to maintain the contract: do not increment the counter if it
* is zero. */
if (count == 0) {
return false;
} else if (gpr_atm_no_barrier_cas(counter, count, count + 1)) {
} else if (gpr_atm_full_cas(counter, count, count + 1)) {
break;
}
}
@ -644,8 +644,12 @@ static void cq_end_op_for_next(grpc_exec_ctx *exec_ctx,
/* Add the completion to the queue */
bool is_first = cq_event_queue_push(&cqd->queue, storage);
gpr_atm_no_barrier_fetch_add(&cqd->things_queued_ever, 1);
bool will_definitely_shutdown =
gpr_atm_no_barrier_load(&cqd->pending_events) == 1;
/* Since we do not hold the cq lock here, it is important to do an 'acquire'
load here (instead of a 'no_barrier' load) to match with the release store
(done via gpr_atm_full_fetch_add(pending_events, -1)) in cq_shutdown_next
*/
bool will_definitely_shutdown = gpr_atm_acq_load(&cqd->pending_events) == 1;
if (!will_definitely_shutdown) {
/* Only kick if this is the first item queued */
@ -889,7 +893,7 @@ static grpc_event cq_next(grpc_completion_queue *cq, gpr_timespec deadline,
}
}
if (gpr_atm_no_barrier_load(&cqd->pending_events) == 0) {
if (gpr_atm_acq_load(&cqd->pending_events) == 0) {
/* Before returning, check if the queue has any items left over (since
gpr_mpscq_pop() can sometimes return NULL even if the queue is not
empty. If so, keep retrying but do not return GRPC_QUEUE_SHUTDOWN */
@ -935,7 +939,7 @@ static grpc_event cq_next(grpc_completion_queue *cq, gpr_timespec deadline,
}
if (cq_event_queue_num_items(&cqd->queue) > 0 &&
gpr_atm_no_barrier_load(&cqd->pending_events) > 0) {
gpr_atm_acq_load(&cqd->pending_events) > 0) {
gpr_mu_lock(cq->mu);
cq->poller_vtable->kick(&exec_ctx, POLLSET_FROM_CQ(cq), NULL);
gpr_mu_unlock(cq->mu);
@ -986,6 +990,9 @@ static void cq_shutdown_next(grpc_exec_ctx *exec_ctx,
return;
}
cqd->shutdown_called = true;
/* Doing a full_fetch_add (i.e acq/release) here to match with
* cq_begin_op_for_next and and cq_end_op_for_next functions which read/write
* on this counter without necessarily holding a lock on cq */
if (gpr_atm_full_fetch_add(&cqd->pending_events, -1) == 1) {
cq_finish_shutdown_next(exec_ctx, cq);
}

@ -197,7 +197,7 @@ char *grpc_transport_op_string(grpc_transport_op *op) {
return out;
}
void grpc_call_log_op(char *file, int line, gpr_log_severity severity,
void grpc_call_log_op(const char *file, int line, gpr_log_severity severity,
grpc_call_element *elem,
grpc_transport_stream_op_batch *op) {
char *str = grpc_transport_stream_op_batch_string(op);

@ -67,7 +67,13 @@
/* --- Structure definitions. ---*/
struct tsi_ssl_handshaker_factory {
const tsi_ssl_handshaker_factory_vtable *vtable;
gpr_refcount refcount;
};
struct tsi_ssl_client_handshaker_factory {
tsi_ssl_handshaker_factory base;
SSL_CTX *ssl_context;
unsigned char *alpn_protocol_list;
size_t alpn_protocol_list_length;
@ -77,6 +83,7 @@ struct tsi_ssl_server_handshaker_factory {
/* Several contexts to support SNI.
The tsi_peer array contains the subject names of the server certificates
associated with the contexts at the same index. */
tsi_ssl_handshaker_factory base;
SSL_CTX **ssl_contexts;
tsi_peer *ssl_context_x509_subject_names;
size_t ssl_context_count;
@ -90,6 +97,7 @@ typedef struct {
BIO *into_ssl;
BIO *from_ssl;
tsi_result result;
tsi_ssl_handshaker_factory *factory_ref;
} tsi_ssl_handshaker;
typedef struct {
@ -846,6 +854,47 @@ static const tsi_frame_protector_vtable frame_protector_vtable = {
ssl_protector_destroy,
};
/* --- tsi_server_handshaker_factory methods implementation. --- */
static void tsi_ssl_handshaker_factory_destroy(
tsi_ssl_handshaker_factory *self) {
if (self == NULL) return;
if (self->vtable != NULL && self->vtable->destroy != NULL) {
self->vtable->destroy(self);
}
/* Note, we don't free(self) here because this object is always directly
* embedded in another object. If tsi_ssl_handshaker_factory_init allocates
* any memory, it should be free'd here. */
}
static tsi_ssl_handshaker_factory *tsi_ssl_handshaker_factory_ref(
tsi_ssl_handshaker_factory *self) {
if (self == NULL) return NULL;
gpr_refn(&self->refcount, 1);
return self;
}
static void tsi_ssl_handshaker_factory_unref(tsi_ssl_handshaker_factory *self) {
if (self == NULL) return;
if (gpr_unref(&self->refcount)) {
tsi_ssl_handshaker_factory_destroy(self);
}
}
static tsi_ssl_handshaker_factory_vtable handshaker_factory_vtable = {NULL};
/* Initializes a tsi_ssl_handshaker_factory object. Caller is responsible for
* allocating memory for the factory. */
static void tsi_ssl_handshaker_factory_init(
tsi_ssl_handshaker_factory *factory) {
GPR_ASSERT(factory != NULL);
factory->vtable = &handshaker_factory_vtable;
gpr_ref_init(&factory->refcount, 1);
}
/* --- tsi_handshaker methods implementation. ---*/
static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker *self,
@ -1013,6 +1062,7 @@ static tsi_result ssl_handshaker_create_frame_protector(
static void ssl_handshaker_destroy(tsi_handshaker *self) {
tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *)self;
SSL_free(impl->ssl); /* The BIO objects are owned by ssl */
tsi_ssl_handshaker_factory_unref(impl->factory_ref);
gpr_free(impl);
}
@ -1030,6 +1080,7 @@ static const tsi_handshaker_vtable handshaker_vtable = {
static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client,
const char *server_name_indication,
tsi_ssl_handshaker_factory *factory,
tsi_handshaker **handshaker) {
SSL *ssl = SSL_new(ctx);
BIO *into_ssl = NULL;
@ -1085,6 +1136,8 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX *ctx, int is_client,
impl->from_ssl = from_ssl;
impl->result = TSI_HANDSHAKE_IN_PROGRESS;
impl->base.vtable = &handshaker_vtable;
impl->factory_ref = tsi_ssl_handshaker_factory_ref(factory);
*handshaker = &impl->base;
return TSI_OK;
}
@ -1121,11 +1174,20 @@ tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
tsi_ssl_client_handshaker_factory *self, const char *server_name_indication,
tsi_handshaker **handshaker) {
return create_tsi_ssl_handshaker(self->ssl_context, 1, server_name_indication,
handshaker);
&self->base, handshaker);
}
void tsi_ssl_client_handshaker_factory_destroy(
void tsi_ssl_client_handshaker_factory_unref(
tsi_ssl_client_handshaker_factory *self) {
if (self == NULL) return;
tsi_ssl_handshaker_factory_unref(&self->base);
}
static void tsi_ssl_client_handshaker_factory_destroy(
tsi_ssl_handshaker_factory *factory) {
if (factory == NULL) return;
tsi_ssl_client_handshaker_factory *self =
(tsi_ssl_client_handshaker_factory *)factory;
if (self->ssl_context != NULL) SSL_CTX_free(self->ssl_context);
if (self->alpn_protocol_list != NULL) gpr_free(self->alpn_protocol_list);
gpr_free(self);
@ -1150,11 +1212,21 @@ tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
if (self->ssl_context_count == 0) return TSI_INVALID_ARGUMENT;
/* Create the handshaker with the first context. We will switch if needed
because of SNI in ssl_server_handshaker_factory_servername_callback. */
return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, NULL, handshaker);
return create_tsi_ssl_handshaker(self->ssl_contexts[0], 0, NULL, &self->base,
handshaker);
}
void tsi_ssl_server_handshaker_factory_destroy(
void tsi_ssl_server_handshaker_factory_unref(
tsi_ssl_server_handshaker_factory *self) {
if (self == NULL) return;
tsi_ssl_handshaker_factory_unref(&self->base);
}
static void tsi_ssl_server_handshaker_factory_destroy(
tsi_ssl_handshaker_factory *factory) {
if (factory == NULL) return;
tsi_ssl_server_handshaker_factory *self =
(tsi_ssl_server_handshaker_factory *)factory;
size_t i;
for (i = 0; i < self->ssl_context_count; i++) {
if (self->ssl_contexts[i] != NULL) {
@ -1263,6 +1335,9 @@ static int server_handshaker_factory_npn_advertised_callback(
/* --- tsi_ssl_handshaker_factory constructors. --- */
static tsi_ssl_handshaker_factory_vtable client_handshaker_factory_vtable = {
tsi_ssl_client_handshaker_factory_destroy};
tsi_result tsi_create_ssl_client_handshaker_factory(
const tsi_ssl_pem_key_cert_pair *pem_key_cert_pair,
const char *pem_root_certs, const char *cipher_suites,
@ -1285,6 +1360,9 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
}
impl = gpr_zalloc(sizeof(*impl));
tsi_ssl_handshaker_factory_init(&impl->base);
impl->base.vtable = &client_handshaker_factory_vtable;
impl->ssl_context = ssl_context;
do {
@ -1322,7 +1400,7 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
}
} while (0);
if (result != TSI_OK) {
tsi_ssl_client_handshaker_factory_destroy(impl);
tsi_ssl_handshaker_factory_unref(&impl->base);
return result;
}
SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL);
@ -1332,6 +1410,9 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
return TSI_OK;
}
static tsi_ssl_handshaker_factory_vtable server_handshaker_factory_vtable = {
tsi_ssl_server_handshaker_factory_destroy};
tsi_result tsi_create_ssl_server_handshaker_factory(
const tsi_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs, const char *pem_client_root_certs,
@ -1364,12 +1445,15 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
}
impl = gpr_zalloc(sizeof(*impl));
tsi_ssl_handshaker_factory_init(&impl->base);
impl->base.vtable = &server_handshaker_factory_vtable;
impl->ssl_contexts = gpr_zalloc(num_key_cert_pairs * sizeof(SSL_CTX *));
impl->ssl_context_x509_subject_names =
gpr_zalloc(num_key_cert_pairs * sizeof(tsi_peer));
if (impl->ssl_contexts == NULL ||
impl->ssl_context_x509_subject_names == NULL) {
tsi_ssl_server_handshaker_factory_destroy(impl);
tsi_ssl_handshaker_factory_unref(&impl->base);
return TSI_OUT_OF_RESOURCES;
}
impl->ssl_context_count = num_key_cert_pairs;
@ -1379,7 +1463,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
&impl->alpn_protocol_list,
&impl->alpn_protocol_list_length);
if (result != TSI_OK) {
tsi_ssl_server_handshaker_factory_destroy(impl);
tsi_ssl_handshaker_factory_unref(&impl->base);
return result;
}
}
@ -1451,10 +1535,11 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
} while (0);
if (result != TSI_OK) {
tsi_ssl_server_handshaker_factory_destroy(impl);
tsi_ssl_handshaker_factory_unref(&impl->base);
return result;
}
}
*factory = impl;
return TSI_OK;
}
@ -1501,3 +1586,15 @@ int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name) {
return 0; /* Not found. */
}
/* --- Testing support. --- */
const tsi_ssl_handshaker_factory_vtable *tsi_ssl_handshaker_factory_swap_vtable(
tsi_ssl_handshaker_factory *factory,
tsi_ssl_handshaker_factory_vtable *new_vtable) {
GPR_ASSERT(factory != NULL);
GPR_ASSERT(factory->vtable != NULL);
const tsi_ssl_handshaker_factory_vtable *orig_vtable = factory->vtable;
factory->vtable = new_vtable;
return orig_vtable;
}

@ -96,10 +96,10 @@ tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
tsi_ssl_client_handshaker_factory *self, const char *server_name_indication,
tsi_handshaker **handshaker);
/* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory
while handshakers created with this factory are still in use. */
void tsi_ssl_client_handshaker_factory_destroy(
tsi_ssl_client_handshaker_factory *self);
/* Decrements reference count of the handshaker factory. Handshaker factory will
* be destroyed once no references exist. */
void tsi_ssl_client_handshaker_factory_unref(
tsi_ssl_client_handshaker_factory *factory);
/* --- tsi_ssl_server_handshaker_factory object ---
@ -158,9 +158,9 @@ tsi_result tsi_create_ssl_server_handshaker_factory_ex(
tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
tsi_ssl_server_handshaker_factory *self, tsi_handshaker **handshaker);
/* Destroys the handshaker factory. WARNING: it is unsafe to destroy a factory
while handshakers created with this factory are still in use. */
void tsi_ssl_server_handshaker_factory_destroy(
/* Decrements reference count of the handshaker factory. Handshaker factory will
* be destroyed once no references exist. */
void tsi_ssl_server_handshaker_factory_unref(
tsi_ssl_server_handshaker_factory *self);
/* Util that checks that an ssl peer matches a specific name.
@ -170,6 +170,29 @@ void tsi_ssl_server_handshaker_factory_destroy(
- handle public suffix wildchar more strictly (e.g. *.co.uk) */
int tsi_ssl_peer_matches_name(const tsi_peer *peer, const char *name);
/* --- Testing support. ---
These functions and typedefs are not intended to be used outside of testing.
*/
/* Base type of client and server handshaker factories. */
typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory;
/* Function pointer to handshaker_factory destructor. */
typedef void (*tsi_ssl_handshaker_factory_destructor)(
tsi_ssl_handshaker_factory *factory);
/* Virtual table for tsi_ssl_handshaker_factory. */
typedef struct {
tsi_ssl_handshaker_factory_destructor destroy;
} tsi_ssl_handshaker_factory_vtable;
/* Set destructor of handshaker_factory to new_destructor, returns previous
destructor. */
const tsi_ssl_handshaker_factory_vtable *tsi_ssl_handshaker_factory_swap_vtable(
tsi_ssl_handshaker_factory *factory,
tsi_ssl_handshaker_factory_vtable *new_vtable);
#ifdef __cplusplus
}
#endif

@ -96,7 +96,7 @@ void ClientContext::set_call(grpc_call* call,
void ClientContext::set_compression_algorithm(
grpc_compression_algorithm algorithm) {
char* algorithm_name = nullptr;
const char* algorithm_name = nullptr;
if (!grpc_compression_algorithm_name(algorithm, &algorithm_name)) {
gpr_log(GPR_ERROR, "Name for compression algorithm '%d' unknown.",
algorithm);

@ -190,7 +190,7 @@ bool ServerContext::IsCancelled() const {
void ServerContext::set_compression_algorithm(
grpc_compression_algorithm algorithm) {
char* algorithm_name = NULL;
const char* algorithm_name = NULL;
if (!grpc_compression_algorithm_name(algorithm, &algorithm_name)) {
gpr_log(GPR_ERROR, "Name for compression algorithm '%d' unknown.",
algorithm);

@ -15,7 +15,6 @@
<PackageTags>gRPC RPC Protocol HTTP/2 Auth OAuth2</PackageTags>
<PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
<IncludeSymbols>true</IncludeSymbols>
<IncludeSource>true</IncludeSource>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

@ -15,7 +15,6 @@
<PackageTags>gRPC test testing</PackageTags>
<PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
<IncludeSymbols>true</IncludeSymbols>
<IncludeSource>true</IncludeSource>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

@ -8,8 +8,6 @@
<AssemblyName>Grpc.Core.Tests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Core.Tests</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
@ -21,7 +19,6 @@
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
<PackageReference Include="NUnit" Version="3.6.0" />
<PackageReference Include="NUnitLite" Version="3.6.0" />
<PackageReference Include="NUnit.ConsoleRunner" Version="3.6.0" />
<PackageReference Include="OpenCover" Version="4.6.519" />
<PackageReference Include="ReportGenerator" Version="2.4.4.0" />
</ItemGroup>

@ -14,7 +14,6 @@
<PackageTags>gRPC RPC Protocol HTTP/2</PackageTags>
<PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
<IncludeSymbols>true</IncludeSymbols>
<IncludeSource>true</IncludeSource>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
@ -65,7 +64,7 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.5' ">
<PackageReference Include="System.Runtime.Loader" Version="4.0.0" />
<PackageReference Include="System.Threading.Thread" Version="4.0.0" />
<PackageReference Include="System.Threading.ThreadPool" Version="4.0.0" />
<PackageReference Include="System.Threading.ThreadPool" Version="4.0.10" />
</ItemGroup>
<Import Project="NativeDeps.csproj.include" />

@ -8,7 +8,6 @@
<AssemblyName>Grpc.Examples.MathClient</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Examples.MathClient</PackageId>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -8,7 +8,6 @@
<AssemblyName>Grpc.Examples.MathServer</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Examples.MathServer</PackageId>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -8,8 +8,6 @@
<AssemblyName>Grpc.Examples.Tests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Examples.Tests</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -7,7 +7,6 @@
<TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
<AssemblyName>Grpc.Examples</AssemblyName>
<PackageId>Grpc.Examples</PackageId>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -8,8 +8,6 @@
<AssemblyName>Grpc.HealthCheck.Tests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.HealthCheck.Tests</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -14,7 +14,6 @@
<PackageTags>gRPC health check</PackageTags>
<PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
<IncludeSymbols>true</IncludeSymbols>
<IncludeSource>true</IncludeSource>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

@ -8,8 +8,6 @@
<AssemblyName>Grpc.IntegrationTesting.Client</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting.Client</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -9,8 +9,6 @@
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting.QpsWorker</PackageId>
<ServerGarbageCollection>true</ServerGarbageCollection>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -8,8 +8,6 @@
<AssemblyName>Grpc.IntegrationTesting.Server</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting.Server</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -8,8 +8,6 @@
<AssemblyName>Grpc.IntegrationTesting.StressClient</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting.StressClient</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -8,8 +8,6 @@
<AssemblyName>Grpc.IntegrationTesting</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
@ -31,10 +29,6 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">
<PackageReference Include="System.Linq.Expressions" Version="4.1.1" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Grpc.Core\Version.cs" />
</ItemGroup>

@ -8,8 +8,6 @@
<AssemblyName>Grpc.Microbenchmarks</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Microbenchmarks</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -8,8 +8,6 @@
<AssemblyName>Grpc.Reflection.Tests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Reflection.Tests</PackageId>
<PackageTargetFallback Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">$(PackageTargetFallback);portable-net45</PackageTargetFallback>
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp1.0' ">1.0.4</RuntimeFrameworkVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

@ -14,7 +14,6 @@
<PackageTags>gRPC reflection</PackageTags>
<PackageProjectUrl>https://github.com/grpc/grpc</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</PackageLicenseUrl>
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.5' ">1.6.0</NetStandardImplicitPackageVersion>
<IncludeSymbols>true</IncludeSymbols>
<IncludeSource>true</IncludeSource>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

@ -0,0 +1,2 @@
html
obj

@ -1,2 +1,9 @@
DocFX-generated C# API Reference
--------------------------------
SandCastle project files to generate HTML reference documentation.
Install docfx based on instructions here: https://github.com/dotnet/docfx
```
# generate docfx documentation into ./html directory
$ docfx
```

@ -0,0 +1,37 @@
{
"metadata": [
{
"src": [
{
"files": ["Grpc.Core/Grpc.Core.csproj",
"Grpc.Auth/Grpc.Auth.csproj",
"Grpc.Core.Testing/Grpc.Core.Testing.csproj",
"Grpc.HealthCheck/Grpc.HealthCheck.csproj",
"Grpc.Reflection/Grpc.HealthCheck.csproj"],
"exclude": [ "**/bin/**", "**/obj/**" ],
"cwd": ".."
}
],
"properties": { "TargetFramework": "net45" },
"dest": "obj/api"
}
],
"build": {
"content": [
{
"files": [ "**/*.yml" ],
"cwd": "obj/api",
"dest": "api"
},
{
"files": [ "toc.yml"],
}
],
"globalMetadata": {
"_appTitle": "gRPC C#",
"_enableSearch": true,
"_disableContribution": true
},
"dest": "html"
}
}

@ -1,83 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- The configuration and platform will be used to determine which assemblies to include from solution and
project documentation sources -->
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{77e3da09-fc92-486f-a90a-99ca788e8b59}</ProjectGuid>
<SHFBSchemaVersion>2015.6.5.0</SHFBSchemaVersion>
<!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual Studio adds them anyway -->
<AssemblyName>Documentation</AssemblyName>
<RootNamespace>Documentation</RootNamespace>
<Name>Documentation</Name>
<!-- SHFB properties -->
<FrameworkVersion>.NET Framework 4.5</FrameworkVersion>
<OutputPath>..\..\..\doc\ref\csharp\html</OutputPath>
<Language>en-US</Language>
<DocumentationSources>
<DocumentationSource sourceFile="..\Grpc.Auth\Grpc.Auth.csproj" />
<DocumentationSource sourceFile="..\Grpc.Core\Grpc.Core.csproj" />
<DocumentationSource sourceFile="..\Grpc.HealthCheck\Grpc.HealthCheck.csproj" />
<DocumentationSource sourceFile="..\Grpc.Reflection\Grpc.Reflection.csproj" />
<DocumentationSource sourceFile="..\Grpc.Core.Testing\Grpc.Core.Testing.csproj" /></DocumentationSources>
<BuildAssemblerVerbosity>OnlyWarningsAndErrors</BuildAssemblerVerbosity>
<HelpFileFormat>Website</HelpFileFormat>
<IndentHtml>False</IndentHtml>
<KeepLogFile>True</KeepLogFile>
<DisableCodeBlockComponent>False</DisableCodeBlockComponent>
<CleanIntermediates>True</CleanIntermediates>
<HelpFileVersion>1.0.0.0</HelpFileVersion>
<MaximumGroupParts>2</MaximumGroupParts>
<NamespaceGrouping>False</NamespaceGrouping>
<SyntaxFilters>Standard</SyntaxFilters>
<SdkLinkTarget>Blank</SdkLinkTarget>
<RootNamespaceContainer>True</RootNamespaceContainer>
<PresentationStyle>VS2013</PresentationStyle>
<Preliminary>False</Preliminary>
<NamingMethod>MemberName</NamingMethod>
<HelpTitle>gRPC C#</HelpTitle>
<ContentPlacement>AboveNamespaces</ContentPlacement>
<HtmlHelpName>Documentation</HtmlHelpName>
<NamespaceSummaries>
<NamespaceSummaryItem name="Grpc.Auth" isDocumented="True">Provides OAuth2 based authentication for gRPC. &lt;c&gt;Grpc.Auth&lt;/c&gt; currently consists of a set of very lightweight wrappers and uses C# &lt;a href="https://www.nuget.org/packages/Google.Apis.Auth/"&gt;Google.Apis.Auth&lt;/a&gt; library.</NamespaceSummaryItem>
<NamespaceSummaryItem name="Grpc.Core" isDocumented="True">Main namespace for gRPC C# functionality. Contains concepts representing both client side and server side gRPC logic.
&lt;seealso cref="Grpc.Core.Channel"/&gt;
&lt;seealso cref="Grpc.Core.Server"/&gt;</NamespaceSummaryItem>
<NamespaceSummaryItem name="Grpc.Core.Logging" isDocumented="True">Provides functionality to redirect gRPC logs to application-specified destination.</NamespaceSummaryItem>
<NamespaceSummaryItem name="Grpc.Core.Utils" isDocumented="True">Various utilities for gRPC C#.</NamespaceSummaryItem>
</NamespaceSummaries>
<MissingTags>Summary, Parameter, AutoDocumentCtors, Namespace, TypeParameter, AutoDocumentDispose</MissingTags>
</PropertyGroup>
<!-- There are no properties for these groups. AnyCPU needs to appear in order for Visual Studio to perform
the build. The others are optional common platform types that may appear. -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
</PropertyGroup>
<!-- Import the SHFB build targets -->
<Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
<!-- The pre-build and post-build event properties must appear *after* the targets file import in order to be
evaluated correctly. -->
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
<PostBuildEvent>
</PostBuildEvent>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
</PropertyGroup>
</Project>

@ -0,0 +1,3 @@
- name: API Documentation
href: obj/api/
homepage: obj/api/Grpc.Core.yml

@ -41,9 +41,8 @@ cdef class CompletionQueue:
cdef object user_tag = None
cdef Call operation_call = None
cdef CallDetails request_call_details = None
cdef Metadata request_metadata = None
cdef object request_metadata = None
cdef Operations batch_operations = None
cdef Operation batch_operation = None
if event.type == GRPC_QUEUE_TIMEOUT:
return Event(
event.type, False, None, None, None, None, False, None)
@ -63,14 +62,8 @@ cdef class CompletionQueue:
operation_call = tag.operation_call
request_call_details = tag.request_call_details
if tag.request_metadata is not None:
request_metadata = tag.request_metadata
request_metadata._claim_slice_ownership()
request_metadata = tuple(tag.request_metadata)
batch_operations = tag.batch_operations
if tag.batch_operations is not None:
for op in batch_operations.operations:
batch_operation = <Operation>op
if batch_operation._received_metadata is not None:
batch_operation._received_metadata._claim_slice_ownership()
if tag.is_new_request:
# Stuff in the tag not explicitly handled by us needs to live through
# the life of the call

@ -76,7 +76,7 @@ cdef class CredentialsMetadataPlugin:
"""
Args:
plugin_callback (callable): Callback accepting a service URL (str/bytes)
and callback object (accepting a Metadata,
and callback object (accepting a MetadataArray,
grpc_status_code, and a str/bytes error message). This argument
when called should be non-blocking and eventually call the callback
object with the appropriate status code/details and metadata (if
@ -129,8 +129,7 @@ cdef void plugin_get_metadata(
def python_callback(
Metadata metadata, grpc_status_code status,
bytes error_details):
cb(user_data, metadata.c_metadata_array.metadata,
metadata.c_metadata_array.count, status, error_details)
cb(user_data, metadata.c_metadata, metadata.c_count, status, error_details)
called_flag[0] = True
cdef CredentialsMetadataPlugin self = <CredentialsMetadataPlugin>state
cdef AuthMetadataContext cy_context = AuthMetadataContext()
@ -139,8 +138,8 @@ cdef void plugin_get_metadata(
self.plugin_callback(cy_context, python_callback)
except Exception as error:
if not called_flag[0]:
cb(user_data, Metadata([]).c_metadata_array.metadata,
0, StatusCode.unknown, traceback.format_exc().encode())
cb(user_data, NULL, 0, StatusCode.unknown,
traceback.format_exc().encode())
cdef void plugin_destroy_c_plugin_state(void *state) with gil:
cpython.Py_DECREF(<CredentialsMetadataPlugin>state)

@ -59,6 +59,7 @@ cdef extern from "grpc/grpc.h":
grpc_slice grpc_slice_malloc(size_t length) nogil
grpc_slice grpc_slice_from_copied_string(const char *source) nogil
grpc_slice grpc_slice_from_copied_buffer(const char *source, size_t len) nogil
grpc_slice grpc_slice_copy(grpc_slice s) nogil
# Declare functions for function-like macros (because Cython)...
void *grpc_slice_start_ptr "GRPC_SLICE_START_PTR" (grpc_slice s) nogil

@ -37,7 +37,7 @@ cdef class OperationTag:
cdef Server shutting_down_server
cdef Call operation_call
cdef CallDetails request_call_details
cdef Metadata request_metadata
cdef MetadataArray request_metadata
cdef Operations batch_operations
cdef bint is_new_request
@ -51,7 +51,7 @@ cdef class Event:
# For Server.request_call
cdef readonly bint is_new_request
cdef readonly CallDetails request_call_details
cdef readonly Metadata request_metadata
cdef readonly object request_metadata
# For server calls
cdef readonly Call operation_call
@ -92,15 +92,20 @@ cdef class Metadatum:
cdef class Metadata:
cdef grpc_metadata *c_metadata
cdef readonly size_t c_count
cdef class MetadataArray:
cdef grpc_metadata_array c_metadata_array
cdef void _claim_slice_ownership(self)
cdef class Operation:
cdef grpc_op c_op
cdef ByteBuffer _received_message
cdef Metadata _received_metadata
cdef MetadataArray _received_metadata
cdef grpc_status_code _received_status_code
cdef grpc_slice _status_details
cdef int _received_cancelled

@ -238,7 +238,7 @@ cdef class Event:
def __cinit__(self, grpc_completion_type type, bint success,
object tag, Call operation_call,
CallDetails request_call_details,
Metadata request_metadata,
object request_metadata,
bint is_new_request,
Operations batch_operations):
self.type = type
@ -437,48 +437,79 @@ cdef class Metadatum:
cdef class _MetadataIterator:
cdef size_t i
cdef Metadata metadata
cdef size_t _length
cdef object _metadatum_indexable
def __cinit__(self, Metadata metadata not None):
def __cinit__(self, length, metadatum_indexable):
self._length = length
self._metadatum_indexable = metadatum_indexable
self.i = 0
self.metadata = metadata
def __iter__(self):
return self
def __next__(self):
if self.i < len(self.metadata):
result = self.metadata[self.i]
if self.i < self._length:
result = self._metadatum_indexable[self.i]
self.i = self.i + 1
return result
else:
raise StopIteration
# TODO(https://github.com/grpc/grpc/issues/7950): Eliminate this; just use an
# ordinary sequence of pairs of bytestrings all the way down to the
# grpc_call_start_batch call.
cdef class Metadata:
"""Metadata being passed from application to core."""
def __cinit__(self, metadata_iterable):
metadata_sequence = tuple(metadata_iterable)
cdef size_t count = len(metadata_sequence)
with nogil:
grpc_init()
grpc_metadata_array_init(&self.c_metadata_array)
metadata = list(metadata_iterable)
for metadatum in metadata:
if not isinstance(metadatum, Metadatum):
raise TypeError("expected list of Metadatum")
self.c_metadata_array.count = len(metadata)
self.c_metadata_array.capacity = len(metadata)
self.c_metadata = <grpc_metadata *>gpr_malloc(
count * sizeof(grpc_metadata))
self.c_count = count
for index, metadatum in enumerate(metadata_sequence):
self.c_metadata[index].key = grpc_slice_copy(
(<Metadatum>metadatum).c_metadata.key)
self.c_metadata[index].value = grpc_slice_copy(
(<Metadatum>metadatum).c_metadata.value)
def __dealloc__(self):
with nogil:
for index in range(self.c_count):
grpc_slice_unref(self.c_metadata[index].key)
grpc_slice_unref(self.c_metadata[index].value)
gpr_free(self.c_metadata)
grpc_shutdown()
def __len__(self):
return self.c_count
def __getitem__(self, size_t index):
if index < self.c_count:
key = _slice_bytes(self.c_metadata[index].key)
value = _slice_bytes(self.c_metadata[index].value)
return Metadatum(key, value)
else:
raise IndexError()
def __iter__(self):
return _MetadataIterator(self.c_count, self)
cdef class MetadataArray:
"""Metadata being passed from core to application."""
def __cinit__(self):
with nogil:
self.c_metadata_array.metadata = <grpc_metadata *>gpr_malloc(
self.c_metadata_array.count*sizeof(grpc_metadata)
)
for i in range(self.c_metadata_array.count):
(<Metadatum>metadata[i])._copy_metadatum(&self.c_metadata_array.metadata[i])
grpc_init()
grpc_metadata_array_init(&self.c_metadata_array)
def __dealloc__(self):
with nogil:
# this frees the allocated memory for the grpc_metadata_array (although
# it'd be nice if that were documented somewhere...)
# TODO(atash): document this in the C core
grpc_metadata_array_destroy(&self.c_metadata_array)
grpc_shutdown()
@ -493,21 +524,7 @@ cdef class Metadata:
return Metadatum(key=key, value=value)
def __iter__(self):
return _MetadataIterator(self)
cdef void _claim_slice_ownership(self):
cdef grpc_metadata_array new_c_metadata_array
grpc_metadata_array_init(&new_c_metadata_array)
new_c_metadata_array.metadata = <grpc_metadata *>gpr_malloc(
self.c_metadata_array.count*sizeof(grpc_metadata))
new_c_metadata_array.count = self.c_metadata_array.count
for i in range(self.c_metadata_array.count):
new_c_metadata_array.metadata[i].key = _copy_slice(
self.c_metadata_array.metadata[i].key)
new_c_metadata_array.metadata[i].value = _copy_slice(
self.c_metadata_array.metadata[i].value)
grpc_metadata_array_destroy(&self.c_metadata_array)
self.c_metadata_array = new_c_metadata_array
return _MetadataIterator(self.c_metadata_array.count, self)
cdef class Operation:
@ -547,14 +564,13 @@ cdef class Operation:
if (self.c_op.type != GRPC_OP_RECV_INITIAL_METADATA and
self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT):
raise TypeError("self must be an operation receiving metadata")
return self._received_metadata
@property
def received_metadata_or_none(self):
if (self.c_op.type != GRPC_OP_RECV_INITIAL_METADATA and
self.c_op.type != GRPC_OP_RECV_STATUS_ON_CLIENT):
return None
return self._received_metadata
# TODO(https://github.com/grpc/grpc/issues/7950): Drop the "all Cython
# objects must be legitimate for use from Python at any time" policy in
# place today, shift the policy toward "Operation objects are only usable
# while their calls are active", and move this making-a-copy-because-this-
# data-needs-to-live-much-longer-than-the-call-from-which-it-arose to the
# lowest Python layer.
return tuple(self._received_metadata)
@property
def received_status_code(self):
@ -601,9 +617,8 @@ def operation_send_initial_metadata(Metadata metadata, int flags):
cdef Operation op = Operation()
op.c_op.type = GRPC_OP_SEND_INITIAL_METADATA
op.c_op.flags = flags
op.c_op.data.send_initial_metadata.count = metadata.c_metadata_array.count
op.c_op.data.send_initial_metadata.metadata = (
metadata.c_metadata_array.metadata)
op.c_op.data.send_initial_metadata.count = metadata.c_count
op.c_op.data.send_initial_metadata.metadata = metadata.c_metadata
op.references.append(metadata)
op.is_valid = True
return op
@ -631,9 +646,8 @@ def operation_send_status_from_server(
op.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER
op.c_op.flags = flags
op.c_op.data.send_status_from_server.trailing_metadata_count = (
metadata.c_metadata_array.count)
op.c_op.data.send_status_from_server.trailing_metadata = (
metadata.c_metadata_array.metadata)
metadata.c_count)
op.c_op.data.send_status_from_server.trailing_metadata = metadata.c_metadata
op.c_op.data.send_status_from_server.status = code
grpc_slice_unref(op._status_details)
op._status_details = _slice_from_bytes(details)
@ -646,7 +660,7 @@ def operation_receive_initial_metadata(int flags):
cdef Operation op = Operation()
op.c_op.type = GRPC_OP_RECV_INITIAL_METADATA
op.c_op.flags = flags
op._received_metadata = Metadata([])
op._received_metadata = MetadataArray()
op.c_op.data.receive_initial_metadata.receive_initial_metadata = (
&op._received_metadata.c_metadata_array)
op.is_valid = True
@ -669,7 +683,7 @@ def operation_receive_status_on_client(int flags):
cdef Operation op = Operation()
op.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT
op.c_op.flags = flags
op._received_metadata = Metadata([])
op._received_metadata = MetadataArray()
op.c_op.data.receive_status_on_client.trailing_metadata = (
&op._received_metadata.c_metadata_array)
op.c_op.data.receive_status_on_client.status = (

@ -44,7 +44,7 @@ cdef class Server:
cdef OperationTag operation_tag = OperationTag(tag)
operation_tag.operation_call = Call()
operation_tag.request_call_details = CallDetails()
operation_tag.request_metadata = Metadata([])
operation_tag.request_metadata = MetadataArray()
operation_tag.references.extend([self, call_queue, server_queue])
operation_tag.is_new_request = True
operation_tag.batch_operations = Operations([])

@ -34,7 +34,7 @@ CLASSIFIERS = [
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'License :: OSI Approved :: Apache Software License',
],
]
PACKAGE_DIRECTORIES = {
'': '.',

@ -35,7 +35,7 @@ CLASSIFIERS = [
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'License :: OSI Approved :: Apache Software License',
],
]
PACKAGE_DIRECTORIES = {
'': '.',

@ -213,7 +213,7 @@ class StreamStreamChannelRpc(six.with_metaclass(abc.ABCMeta)):
raise NotImplementedError()
class Channel(six.with_metaclass(abc.ABCMeta), grpc.Channel):
class Channel(six.with_metaclass(abc.ABCMeta, grpc.Channel)):
"""A grpc.Channel double with which to test a system that invokes RPCs."""
@abc.abstractmethod

@ -12,6 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
VERSION = '1.5.0.dev0'
VERSION='1.7.0.dev0'

@ -12,19 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import contextlib
import distutils.spawn
import errno
import itertools
import importlib
import os
import pkg_resources
from os import path
import pkgutil
import shutil
import subprocess
import sys
import tempfile
import threading
import time
import unittest
from six import moves
@ -33,12 +29,22 @@ from grpc.beta import implementations
from grpc.beta import interfaces
from grpc.framework.foundation import future
from grpc.framework.interfaces.face import face
from grpc_tools import protoc
from tests.unit.framework.common import test_constants
import tests.protoc_plugin.protos.payload.test_payload_pb2 as payload_pb2
import tests.protoc_plugin.protos.requests.r.test_requests_pb2 as request_pb2
import tests.protoc_plugin.protos.responses.test_responses_pb2 as response_pb2
import tests.protoc_plugin.protos.service.test_service_pb2 as service_pb2
_RELATIVE_PROTO_PATH = 'relative_proto_path'
_RELATIVE_PYTHON_OUT = 'relative_python_out'
_PROTO_FILES_PATH_COMPONENTS = (
('beta_grpc_plugin_test', 'payload', 'test_payload.proto',),
('beta_grpc_plugin_test', 'requests', 'r', 'test_requests.proto',),
('beta_grpc_plugin_test', 'responses', 'test_responses.proto',),
('beta_grpc_plugin_test', 'service', 'test_service.proto',),)
_PAYLOAD_PB2 = 'beta_grpc_plugin_test.payload.test_payload_pb2'
_REQUESTS_PB2 = 'beta_grpc_plugin_test.requests.r.test_requests_pb2'
_RESPONSES_PB2 = 'beta_grpc_plugin_test.responses.test_responses_pb2'
_SERVICE_PB2 = 'beta_grpc_plugin_test.service.test_service_pb2'
# Identifiers of entities we expect to find in the generated module.
SERVICER_IDENTIFIER = 'BetaTestServiceServicer'
@ -47,12 +53,50 @@ SERVER_FACTORY_IDENTIFIER = 'beta_create_TestService_server'
STUB_FACTORY_IDENTIFIER = 'beta_create_TestService_stub'
@contextlib.contextmanager
def _system_path(path_insertion):
old_system_path = sys.path[:]
sys.path = sys.path[0:1] + path_insertion + sys.path[1:]
yield
sys.path = old_system_path
def _create_directory_tree(root, path_components_sequence):
created = set()
for path_components in path_components_sequence:
thus_far = ''
for path_component in path_components:
relative_path = path.join(thus_far, path_component)
if relative_path not in created:
os.makedirs(path.join(root, relative_path))
created.add(relative_path)
thus_far = path.join(thus_far, path_component)
def _massage_proto_content(raw_proto_content):
imports_substituted = raw_proto_content.replace(
b'import "tests/protoc_plugin/protos/',
b'import "beta_grpc_plugin_test/')
package_statement_substituted = imports_substituted.replace(
b'package grpc_protoc_plugin;', b'package beta_grpc_protoc_plugin;')
return package_statement_substituted
def _packagify(directory):
for subdirectory, _, _ in os.walk(directory):
init_file_name = path.join(subdirectory, '__init__.py')
with open(init_file_name, 'wb') as init_file:
init_file.write(b'')
class _ServicerMethods(object):
def __init__(self):
def __init__(self, payload_pb2, responses_pb2):
self._condition = threading.Condition()
self._paused = False
self._fail = False
self._payload_pb2 = payload_pb2
self._responses_pb2 = responses_pb2
@contextlib.contextmanager
def pause(self): # pylint: disable=invalid-name
@ -79,22 +123,22 @@ class _ServicerMethods(object):
self._condition.wait()
def UnaryCall(self, request, unused_rpc_context):
response = response_pb2.SimpleResponse()
response.payload.payload_type = payload_pb2.COMPRESSABLE
response = self._responses_pb2.SimpleResponse()
response.payload.payload_type = self._payload_pb2.COMPRESSABLE
response.payload.payload_compressable = 'a' * request.response_size
self._control()
return response
def StreamingOutputCall(self, request, unused_rpc_context):
for parameter in request.response_parameters:
response = response_pb2.StreamingOutputCallResponse()
response.payload.payload_type = payload_pb2.COMPRESSABLE
response = self._responses_pb2.StreamingOutputCallResponse()
response.payload.payload_type = self._payload_pb2.COMPRESSABLE
response.payload.payload_compressable = 'a' * parameter.size
self._control()
yield response
def StreamingInputCall(self, request_iter, unused_rpc_context):
response = response_pb2.StreamingInputCallResponse()
response = self._responses_pb2.StreamingInputCallResponse()
aggregated_payload_size = 0
for request in request_iter:
aggregated_payload_size += len(request.payload.payload_compressable)
@ -105,8 +149,8 @@ class _ServicerMethods(object):
def FullDuplexCall(self, request_iter, unused_rpc_context):
for request in request_iter:
for parameter in request.response_parameters:
response = response_pb2.StreamingOutputCallResponse()
response.payload.payload_type = payload_pb2.COMPRESSABLE
response = self._responses_pb2.StreamingOutputCallResponse()
response.payload.payload_type = self._payload_pb2.COMPRESSABLE
response.payload.payload_compressable = 'a' * parameter.size
self._control()
yield response
@ -115,8 +159,8 @@ class _ServicerMethods(object):
responses = []
for request in request_iter:
for parameter in request.response_parameters:
response = response_pb2.StreamingOutputCallResponse()
response.payload.payload_type = payload_pb2.COMPRESSABLE
response = self._responses_pb2.StreamingOutputCallResponse()
response.payload.payload_type = self._payload_pb2.COMPRESSABLE
response.payload.payload_compressable = 'a' * parameter.size
self._control()
responses.append(response)
@ -125,7 +169,7 @@ class _ServicerMethods(object):
@contextlib.contextmanager
def _CreateService():
def _CreateService(payload_pb2, responses_pb2, service_pb2):
"""Provides a servicer backend and a stub.
The servicer is just the implementation of the actual servicer passed to the
@ -136,7 +180,7 @@ def _CreateService():
the service bound to the stub and and stub is the stub on which to invoke
RPCs.
"""
servicer_methods = _ServicerMethods()
servicer_methods = _ServicerMethods(payload_pb2, responses_pb2)
class Servicer(getattr(service_pb2, SERVICER_IDENTIFIER)):
@ -161,12 +205,12 @@ def _CreateService():
server.start()
channel = implementations.insecure_channel('localhost', port)
stub = getattr(service_pb2, STUB_FACTORY_IDENTIFIER)(channel)
yield (servicer_methods, stub)
yield servicer_methods, stub,
server.stop(0)
@contextlib.contextmanager
def _CreateIncompleteService():
def _CreateIncompleteService(service_pb2):
"""Provides a servicer backend that fails to implement methods and its stub.
The servicer is just the implementation of the actual servicer passed to the
@ -192,16 +236,16 @@ def _CreateIncompleteService():
server.stop(0)
def _streaming_input_request_iterator():
def _streaming_input_request_iterator(payload_pb2, requests_pb2):
for _ in range(3):
request = request_pb2.StreamingInputCallRequest()
request = requests_pb2.StreamingInputCallRequest()
request.payload.payload_type = payload_pb2.COMPRESSABLE
request.payload.payload_compressable = 'a'
yield request
def _streaming_output_request():
request = request_pb2.StreamingOutputCallRequest()
def _streaming_output_request(requests_pb2):
request = requests_pb2.StreamingOutputCallRequest()
sizes = [1, 2, 3]
request.response_parameters.add(size=sizes[0], interval_us=0)
request.response_parameters.add(size=sizes[1], interval_us=0)
@ -209,11 +253,11 @@ def _streaming_output_request():
return request
def _full_duplex_request_iterator():
request = request_pb2.StreamingOutputCallRequest()
def _full_duplex_request_iterator(requests_pb2):
request = requests_pb2.StreamingOutputCallRequest()
request.response_parameters.add(size=1, interval_us=0)
yield request
request = request_pb2.StreamingOutputCallRequest()
request = requests_pb2.StreamingOutputCallRequest()
request.response_parameters.add(size=2, interval_us=0)
request.response_parameters.add(size=3, interval_us=0)
yield request
@ -227,22 +271,78 @@ class PythonPluginTest(unittest.TestCase):
methods and does not exist for response-streaming methods.
"""
def setUp(self):
self._directory = tempfile.mkdtemp(dir='.')
self._proto_path = path.join(self._directory, _RELATIVE_PROTO_PATH)
self._python_out = path.join(self._directory, _RELATIVE_PYTHON_OUT)
os.makedirs(self._proto_path)
os.makedirs(self._python_out)
directories_path_components = {
proto_file_path_components[:-1]
for proto_file_path_components in _PROTO_FILES_PATH_COMPONENTS
}
_create_directory_tree(self._proto_path, directories_path_components)
self._proto_file_names = set()
for proto_file_path_components in _PROTO_FILES_PATH_COMPONENTS:
raw_proto_content = pkgutil.get_data(
'tests.protoc_plugin.protos',
path.join(*proto_file_path_components[1:]))
massaged_proto_content = _massage_proto_content(raw_proto_content)
proto_file_name = path.join(self._proto_path,
*proto_file_path_components)
with open(proto_file_name, 'wb') as proto_file:
proto_file.write(massaged_proto_content)
self._proto_file_names.add(proto_file_name)
def tearDown(self):
shutil.rmtree(self._directory)
def _protoc(self):
args = [
'',
'--proto_path={}'.format(self._proto_path),
'--python_out={}'.format(self._python_out),
'--grpc_python_out=grpc_1_0:{}'.format(self._python_out),
] + list(self._proto_file_names)
protoc_exit_code = protoc.main(args)
self.assertEqual(0, protoc_exit_code)
_packagify(self._python_out)
with _system_path([
self._python_out,
]):
self._payload_pb2 = importlib.import_module(_PAYLOAD_PB2)
self._requests_pb2 = importlib.import_module(_REQUESTS_PB2)
self._responses_pb2 = importlib.import_module(_RESPONSES_PB2)
self._service_pb2 = importlib.import_module(_SERVICE_PB2)
def testImportAttributes(self):
self._protoc()
# check that we can access the generated module and its members.
self.assertIsNotNone(getattr(service_pb2, SERVICER_IDENTIFIER, None))
self.assertIsNotNone(getattr(service_pb2, STUB_IDENTIFIER, None))
self.assertIsNotNone(
getattr(service_pb2, SERVER_FACTORY_IDENTIFIER, None))
getattr(self._service_pb2, SERVICER_IDENTIFIER, None))
self.assertIsNotNone(getattr(self._service_pb2, STUB_IDENTIFIER, None))
self.assertIsNotNone(
getattr(service_pb2, STUB_FACTORY_IDENTIFIER, None))
getattr(self._service_pb2, SERVER_FACTORY_IDENTIFIER, None))
self.assertIsNotNone(
getattr(self._service_pb2, STUB_FACTORY_IDENTIFIER, None))
def testUpDown(self):
with _CreateService():
request_pb2.SimpleRequest(response_size=13)
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2):
self._requests_pb2.SimpleRequest(response_size=13)
def testIncompleteServicer(self):
with _CreateIncompleteService() as (_, stub):
request = request_pb2.SimpleRequest(response_size=13)
self._protoc()
with _CreateIncompleteService(self._service_pb2) as (_, stub):
request = self._requests_pb2.SimpleRequest(response_size=13)
try:
stub.UnaryCall(request, test_constants.LONG_TIMEOUT)
except face.AbortionError as error:
@ -250,15 +350,21 @@ class PythonPluginTest(unittest.TestCase):
error.code)
def testUnaryCall(self):
with _CreateService() as (methods, stub):
request = request_pb2.SimpleRequest(response_size=13)
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request = self._requests_pb2.SimpleRequest(response_size=13)
response = stub.UnaryCall(request, test_constants.LONG_TIMEOUT)
expected_response = methods.UnaryCall(request, 'not a real context!')
self.assertEqual(expected_response, response)
def testUnaryCallFuture(self):
with _CreateService() as (methods, stub):
request = request_pb2.SimpleRequest(response_size=13)
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request = self._requests_pb2.SimpleRequest(response_size=13)
# Check that the call does not block waiting for the server to respond.
with methods.pause():
response_future = stub.UnaryCall.future(
@ -268,8 +374,11 @@ class PythonPluginTest(unittest.TestCase):
self.assertEqual(expected_response, response)
def testUnaryCallFutureExpired(self):
with _CreateService() as (methods, stub):
request = request_pb2.SimpleRequest(response_size=13)
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request = self._requests_pb2.SimpleRequest(response_size=13)
with methods.pause():
response_future = stub.UnaryCall.future(
request, test_constants.SHORT_TIMEOUT)
@ -277,24 +386,33 @@ class PythonPluginTest(unittest.TestCase):
response_future.result()
def testUnaryCallFutureCancelled(self):
with _CreateService() as (methods, stub):
request = request_pb2.SimpleRequest(response_size=13)
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request = self._requests_pb2.SimpleRequest(response_size=13)
with methods.pause():
response_future = stub.UnaryCall.future(request, 1)
response_future.cancel()
self.assertTrue(response_future.cancelled())
def testUnaryCallFutureFailed(self):
with _CreateService() as (methods, stub):
request = request_pb2.SimpleRequest(response_size=13)
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request = self._requests_pb2.SimpleRequest(response_size=13)
with methods.fail():
response_future = stub.UnaryCall.future(
request, test_constants.LONG_TIMEOUT)
self.assertIsNotNone(response_future.exception())
def testStreamingOutputCall(self):
with _CreateService() as (methods, stub):
request = _streaming_output_request()
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request = _streaming_output_request(self._requests_pb2)
responses = stub.StreamingOutputCall(request,
test_constants.LONG_TIMEOUT)
expected_responses = methods.StreamingOutputCall(
@ -304,8 +422,11 @@ class PythonPluginTest(unittest.TestCase):
self.assertEqual(expected_response, response)
def testStreamingOutputCallExpired(self):
with _CreateService() as (methods, stub):
request = _streaming_output_request()
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request = _streaming_output_request(self._requests_pb2)
with methods.pause():
responses = stub.StreamingOutputCall(
request, test_constants.SHORT_TIMEOUT)
@ -313,8 +434,11 @@ class PythonPluginTest(unittest.TestCase):
list(responses)
def testStreamingOutputCallCancelled(self):
with _CreateService() as (methods, stub):
request = _streaming_output_request()
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request = _streaming_output_request(self._requests_pb2)
responses = stub.StreamingOutputCall(request,
test_constants.LONG_TIMEOUT)
next(responses)
@ -323,8 +447,11 @@ class PythonPluginTest(unittest.TestCase):
next(responses)
def testStreamingOutputCallFailed(self):
with _CreateService() as (methods, stub):
request = _streaming_output_request()
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request = _streaming_output_request(self._requests_pb2)
with methods.fail():
responses = stub.StreamingOutputCall(request, 1)
self.assertIsNotNone(responses)
@ -332,30 +459,46 @@ class PythonPluginTest(unittest.TestCase):
next(responses)
def testStreamingInputCall(self):
with _CreateService() as (methods, stub):
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
response = stub.StreamingInputCall(
_streaming_input_request_iterator(),
_streaming_input_request_iterator(self._payload_pb2,
self._requests_pb2),
test_constants.LONG_TIMEOUT)
expected_response = methods.StreamingInputCall(
_streaming_input_request_iterator(), 'not a real RpcContext!')
_streaming_input_request_iterator(self._payload_pb2,
self._requests_pb2),
'not a real RpcContext!')
self.assertEqual(expected_response, response)
def testStreamingInputCallFuture(self):
with _CreateService() as (methods, stub):
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
with methods.pause():
response_future = stub.StreamingInputCall.future(
_streaming_input_request_iterator(),
_streaming_input_request_iterator(self._payload_pb2,
self._requests_pb2),
test_constants.LONG_TIMEOUT)
response = response_future.result()
expected_response = methods.StreamingInputCall(
_streaming_input_request_iterator(), 'not a real RpcContext!')
_streaming_input_request_iterator(self._payload_pb2,
self._requests_pb2),
'not a real RpcContext!')
self.assertEqual(expected_response, response)
def testStreamingInputCallFutureExpired(self):
with _CreateService() as (methods, stub):
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
with methods.pause():
response_future = stub.StreamingInputCall.future(
_streaming_input_request_iterator(),
_streaming_input_request_iterator(self._payload_pb2,
self._requests_pb2),
test_constants.SHORT_TIMEOUT)
with self.assertRaises(face.ExpirationError):
response_future.result()
@ -363,10 +506,14 @@ class PythonPluginTest(unittest.TestCase):
face.ExpirationError)
def testStreamingInputCallFutureCancelled(self):
with _CreateService() as (methods, stub):
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
with methods.pause():
response_future = stub.StreamingInputCall.future(
_streaming_input_request_iterator(),
_streaming_input_request_iterator(self._payload_pb2,
self._requests_pb2),
test_constants.LONG_TIMEOUT)
response_future.cancel()
self.assertTrue(response_future.cancelled())
@ -374,26 +521,38 @@ class PythonPluginTest(unittest.TestCase):
response_future.result()
def testStreamingInputCallFutureFailed(self):
with _CreateService() as (methods, stub):
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
with methods.fail():
response_future = stub.StreamingInputCall.future(
_streaming_input_request_iterator(),
_streaming_input_request_iterator(self._payload_pb2,
self._requests_pb2),
test_constants.LONG_TIMEOUT)
self.assertIsNotNone(response_future.exception())
def testFullDuplexCall(self):
with _CreateService() as (methods, stub):
responses = stub.FullDuplexCall(_full_duplex_request_iterator(),
test_constants.LONG_TIMEOUT)
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
responses = stub.FullDuplexCall(
_full_duplex_request_iterator(self._requests_pb2),
test_constants.LONG_TIMEOUT)
expected_responses = methods.FullDuplexCall(
_full_duplex_request_iterator(), 'not a real RpcContext!')
_full_duplex_request_iterator(self._requests_pb2),
'not a real RpcContext!')
for expected_response, response in moves.zip_longest(
expected_responses, responses):
self.assertEqual(expected_response, response)
def testFullDuplexCallExpired(self):
request_iterator = _full_duplex_request_iterator()
with _CreateService() as (methods, stub):
self._protoc()
request_iterator = _full_duplex_request_iterator(self._requests_pb2)
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
with methods.pause():
responses = stub.FullDuplexCall(request_iterator,
test_constants.SHORT_TIMEOUT)
@ -401,8 +560,11 @@ class PythonPluginTest(unittest.TestCase):
list(responses)
def testFullDuplexCallCancelled(self):
with _CreateService() as (methods, stub):
request_iterator = _full_duplex_request_iterator()
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
request_iterator = _full_duplex_request_iterator(self._requests_pb2)
responses = stub.FullDuplexCall(request_iterator,
test_constants.LONG_TIMEOUT)
next(responses)
@ -411,8 +573,11 @@ class PythonPluginTest(unittest.TestCase):
next(responses)
def testFullDuplexCallFailed(self):
request_iterator = _full_duplex_request_iterator()
with _CreateService() as (methods, stub):
self._protoc()
request_iterator = _full_duplex_request_iterator(self._requests_pb2)
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
with methods.fail():
responses = stub.FullDuplexCall(request_iterator,
test_constants.LONG_TIMEOUT)
@ -421,13 +586,16 @@ class PythonPluginTest(unittest.TestCase):
next(responses)
def testHalfDuplexCall(self):
with _CreateService() as (methods, stub):
self._protoc()
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
def half_duplex_request_iterator():
request = request_pb2.StreamingOutputCallRequest()
request = self._requests_pb2.StreamingOutputCallRequest()
request.response_parameters.add(size=1, interval_us=0)
yield request
request = request_pb2.StreamingOutputCallRequest()
request = self._requests_pb2.StreamingOutputCallRequest()
request.response_parameters.add(size=2, interval_us=0)
request.response_parameters.add(size=3, interval_us=0)
yield request
@ -441,6 +609,8 @@ class PythonPluginTest(unittest.TestCase):
self.assertEqual(expected_response, response)
def testHalfDuplexCallWedged(self):
self._protoc()
condition = threading.Condition()
wait_cell = [False]
@ -455,14 +625,15 @@ class PythonPluginTest(unittest.TestCase):
condition.notify_all()
def half_duplex_request_iterator():
request = request_pb2.StreamingOutputCallRequest()
request = self._requests_pb2.StreamingOutputCallRequest()
request.response_parameters.add(size=1, interval_us=0)
yield request
with condition:
while wait_cell[0]:
condition.wait()
with _CreateService() as (methods, stub):
with _CreateService(self._payload_pb2, self._responses_pb2,
self._service_pb2) as (methods, stub):
with wait():
responses = stub.HalfDuplexCall(half_duplex_request_iterator(),
test_constants.SHORT_TIMEOUT)

@ -164,10 +164,10 @@ extern census_record_values_type census_record_values_import;
typedef int(*grpc_compression_algorithm_parse_type)(grpc_slice value, grpc_compression_algorithm *algorithm);
extern grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import;
#define grpc_compression_algorithm_parse grpc_compression_algorithm_parse_import
typedef int(*grpc_compression_algorithm_name_type)(grpc_compression_algorithm algorithm, char **name);
typedef int(*grpc_compression_algorithm_name_type)(grpc_compression_algorithm algorithm, const char **name);
extern grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import;
#define grpc_compression_algorithm_name grpc_compression_algorithm_name_import
typedef int(*grpc_stream_compression_algorithm_name_type)(grpc_stream_compression_algorithm algorithm, char **name);
typedef int(*grpc_stream_compression_algorithm_name_type)(grpc_stream_compression_algorithm algorithm, const char **name);
extern grpc_stream_compression_algorithm_name_type grpc_stream_compression_algorithm_name_import;
#define grpc_stream_compression_algorithm_name grpc_stream_compression_algorithm_name_import
typedef grpc_compression_algorithm(*grpc_compression_algorithm_for_level_type)(grpc_compression_level level, uint32_t accepted_encodings);

@ -0,0 +1,28 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require_relative './grpc'
require 'google/rpc/status_pb'
# GRPC contains the General RPC module.
module GRPC
# GoogleRpcStatusUtils provides utilities to convert between a
# GRPC::Core::Status and a deserialized Google::Rpc::Status proto
class GoogleRpcStatusUtils
def self.extract_google_rpc_status(status)
fail ArgumentError, 'bad type' unless status.is_a? Struct::Status
Google::Rpc::Status.decode(status.metadata['grpc-status-details-bin'])
end
end
end

@ -0,0 +1,223 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'grpc'
require_relative '../lib/grpc/google_rpc_status_utils'
require_relative '../pb/src/proto/grpc/testing/messages_pb'
require_relative '../pb/src/proto/grpc/testing/messages_pb'
require 'google/protobuf/well_known_types'
include GRPC::Core
describe 'conversion from a status struct to a google protobuf status' do
it 'fails if the input is not a status struct' do
begin
GRPC::GoogleRpcStatusUtils.extract_google_rpc_status('string')
rescue => e
exception = e
end
expect(exception.is_a?(ArgumentError)).to be true
expect(exception.message.include?('bad type')).to be true
end
it 'fails with some error if the header key is missing' do
status = Struct::Status.new(1, 'details', key: 'val')
expect(status.metadata.nil?).to be false
expect do
GRPC::GoogleRpcStatusUtils.extract_google_rpc_status(status)
end.to raise_error(StandardError)
end
it 'fails with some error if the header key fails to deserialize' do
status = Struct::Status.new(1, 'details',
'grpc-status-details-bin' => 'string_val')
expect do
GRPC::GoogleRpcStatusUtils.extract_google_rpc_status(status)
end.to raise_error(StandardError)
end
it 'silently ignores erroneous mismatch between messages in '\
'status struct and protobuf status' do
proto = Google::Rpc::Status.new(code: 1, message: 'proto message')
encoded_proto = Google::Rpc::Status.encode(proto)
status = Struct::Status.new(1, 'struct message',
'grpc-status-details-bin' => encoded_proto)
rpc_status = GRPC::GoogleRpcStatusUtils.extract_google_rpc_status(status)
expect(rpc_status).to eq(proto)
end
it 'silently ignores erroneous mismatch between codes in status struct '\
'and protobuf status' do
proto = Google::Rpc::Status.new(code: 1, message: 'matching message')
encoded_proto = Google::Rpc::Status.encode(proto)
status = Struct::Status.new(2, 'matching message',
'grpc-status-details-bin' => encoded_proto)
rpc_status = GRPC::GoogleRpcStatusUtils.extract_google_rpc_status(status)
expect(rpc_status).to eq(proto)
end
it 'can succesfully convert a status struct into a google protobuf status '\
'when there are no rpcstatus details' do
proto = Google::Rpc::Status.new(code: 1, message: 'matching message')
encoded_proto = Google::Rpc::Status.encode(proto)
status = Struct::Status.new(1, 'matching message',
'grpc-status-details-bin' => encoded_proto)
out = GRPC::GoogleRpcStatusUtils.extract_google_rpc_status(status)
expect(out.code).to eq(1)
expect(out.message).to eq('matching message')
expect(out.details).to eq([])
end
it 'can succesfully convert a status struct into a google protobuf '\
'status when there are multiple rpcstatus details' do
simple_request_any = Google::Protobuf::Any.new
simple_request = Grpc::Testing::SimpleRequest.new(
payload: Grpc::Testing::Payload.new(body: 'request'))
simple_request_any.pack(simple_request)
simple_response_any = Google::Protobuf::Any.new
simple_response = Grpc::Testing::SimpleResponse.new(
payload: Grpc::Testing::Payload.new(body: 'response'))
simple_response_any.pack(simple_response)
payload_any = Google::Protobuf::Any.new
payload = Grpc::Testing::Payload.new(body: 'payload')
payload_any.pack(payload)
proto = Google::Rpc::Status.new(code: 1,
message: 'matching message',
details: [
simple_request_any,
simple_response_any,
payload_any
])
encoded_proto = Google::Rpc::Status.encode(proto)
status = Struct::Status.new(1, 'matching message',
'grpc-status-details-bin' => encoded_proto)
out = GRPC::GoogleRpcStatusUtils.extract_google_rpc_status(status)
expect(out.code).to eq(1)
expect(out.message).to eq('matching message')
expect(out.details[0].unpack(
Grpc::Testing::SimpleRequest)).to eq(simple_request)
expect(out.details[1].unpack(
Grpc::Testing::SimpleResponse)).to eq(simple_response)
expect(out.details[2].unpack(
Grpc::Testing::Payload)).to eq(payload)
end
end
# Test message
class EchoMsg
def self.marshal(_o)
''
end
def self.unmarshal(_o)
EchoMsg.new
end
end
# A test service that fills in the "reserved" grpc-status-details-bin trailer,
# for client-side testing of GoogleRpcStatus protobuf extraction from trailers.
class GoogleRpcStatusTestService
include GRPC::GenericService
rpc :an_rpc, EchoMsg, EchoMsg
def initialize(encoded_rpc_status)
@encoded_rpc_status = encoded_rpc_status
end
def an_rpc(_, _)
# TODO: create a server-side utility API for sending a google rpc status.
# Applications are not expected to set the grpc-status-details-bin
# ("grpc"-fixed and reserved for library use) manually.
# Doing so here is only for testing of the client-side api for extracting
# a google rpc status, which is useful
# when the interacting with a server that does fill in this trailer.
fail GRPC::Unknown.new('test message',
'grpc-status-details-bin' => @encoded_rpc_status)
end
end
GoogleRpcStatusTestStub = GoogleRpcStatusTestService.rpc_stub_class
describe 'receving a google rpc status from a remote endpoint' do
def start_server(encoded_rpc_status)
@srv = GRPC::RpcServer.new(pool_size: 1)
@server_port = @srv.add_http2_port('localhost:0',
:this_port_is_insecure)
@srv.handle(GoogleRpcStatusTestService.new(encoded_rpc_status))
@server_thd = Thread.new { @srv.run }
@srv.wait_till_running
end
def stop_server
expect(@srv.stopped?).to be(false)
@srv.stop
@server_thd.join
expect(@srv.stopped?).to be(true)
end
before(:each) do
simple_request_any = Google::Protobuf::Any.new
simple_request = Grpc::Testing::SimpleRequest.new(
payload: Grpc::Testing::Payload.new(body: 'request'))
simple_request_any.pack(simple_request)
simple_response_any = Google::Protobuf::Any.new
simple_response = Grpc::Testing::SimpleResponse.new(
payload: Grpc::Testing::Payload.new(body: 'response'))
simple_response_any.pack(simple_response)
payload_any = Google::Protobuf::Any.new
payload = Grpc::Testing::Payload.new(body: 'payload')
payload_any.pack(payload)
@expected_proto = Google::Rpc::Status.new(
code: StatusCodes::UNKNOWN,
message: 'test message',
details: [simple_request_any, simple_response_any, payload_any])
start_server(Google::Rpc::Status.encode(@expected_proto))
end
after(:each) do
stop_server
end
it 'should receive be able to extract a google rpc status from the '\
'status struct taken from a BadStatus exception' do
stub = GoogleRpcStatusTestStub.new("localhost:#{@server_port}",
:this_channel_is_insecure)
begin
stub.an_rpc(EchoMsg.new)
rescue GRPC::BadStatus => e
rpc_status = GRPC::GoogleRpcStatusUtils.extract_google_rpc_status(
e.to_status)
end
expect(rpc_status).to eq(@expected_proto)
end
it 'should receive be able to extract a google rpc status from the '\
'status struct taken from the op view of a call' do
stub = GoogleRpcStatusTestStub.new("localhost:#{@server_port}",
:this_channel_is_insecure)
op = stub.an_rpc(EchoMsg.new, return_op: true)
begin
op.execute
rescue GRPC::BadStatus => e
status_from_exception = e.to_status
end
rpc_status = GRPC::GoogleRpcStatusUtils.extract_google_rpc_status(
op.status)
expect(rpc_status).to eq(@expected_proto)
# "to_status" on the bad status should give the same result
# as "status" on the "op view".
expect(GRPC::GoogleRpcStatusUtils.extract_google_rpc_status(
status_from_exception)).to eq(rpc_status)
end
end

@ -14,7 +14,7 @@
LIBS="-lpthread $LIBS"
CFLAGS="-Wall -Werror -Wno-parentheses-equality -Wno-unused-value -std=c11"
CXXFLAGS="-std=c++11"
CXXFLAGS="-std=c++11 -fno-exceptions -fno-rtti"
GRPC_SHARED_LIBADD="-lpthread $GRPC_SHARED_LIBADD"
PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(pthread)

@ -31,6 +31,7 @@
s.add_dependency 'google-protobuf', '~> 3.1'
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_dependency 'googleapis-common-protos-types', '~> 1.0.0'
s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'facter', '~> 2.4'

@ -12,7 +12,7 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
<date>2017-05-22</date>
<date>2017-08-24</date>
<time>16:06:07</time>
<version>
<release>${settings.php_version.php()}</release>
@ -27,6 +27,9 @@
- Channel are now by default persistent #11878
- Some bug fixes from 1.4 branch #12109, #12123
- Fixed hang bug when fork() was used #11814
- License changed to Apache 2.0
- Added support for php_namespace option in codegen plugin #11886
- Updated gRPC C Core library version 1.6
</notes>
<contents>
<dir baseinstalldir="/" name="/">

@ -0,0 +1,19 @@
%YAML 1.2
--- |
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
VERSION='${settings.python_version.pep440()}'

@ -35,7 +35,7 @@ static void test_algorithm_mesh(void) {
gpr_log(GPR_DEBUG, "test_algorithm_mesh");
for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
char *name;
const char *name;
grpc_compression_algorithm parsed;
grpc_slice mdstr;
grpc_mdelem mdelem;

@ -57,7 +57,7 @@ static void test_compression_algorithm_parse(void) {
static void test_compression_algorithm_name(void) {
int success;
char *name;
const char *name;
size_t i;
const char *valid_names[] = {"identity", "gzip", "deflate"};
const grpc_compression_algorithm valid_algorithms[] = {

@ -49,7 +49,7 @@ static void assert_passthrough(grpc_slice value,
grpc_slice_buffer output;
grpc_slice final;
int was_compressed;
char *algorithm_name;
const char *algorithm_name;
GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algorithm_name) != 0);
gpr_log(

@ -228,7 +228,7 @@ static void request_for_disabled_algorithm(
/* with a certain error */
GPR_ASSERT(status == expected_error);
char *algo_name = NULL;
const char *algo_name = NULL;
GPR_ASSERT(grpc_compression_algorithm_name(algorithm_to_disable, &algo_name));
char *expected_details = NULL;
gpr_asprintf(&expected_details, "Compression algorithm '%s' is disabled.",

@ -228,7 +228,7 @@ static void request_for_disabled_algorithm(
/* with a certain error */
GPR_ASSERT(status == expected_error);
char *algo_name = NULL;
const char *algo_name = NULL;
GPR_ASSERT(
grpc_stream_compression_algorithm_name(algorithm_to_disable, &algo_name));
char *expected_details = NULL;

@ -23,7 +23,9 @@
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/transport/security_connector.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security.h"
#include "src/core/tsi/transport_security_adapter.h"
#include "src/core/tsi/transport_security_interface.h"
#include "test/core/tsi/transport_security_test_lib.h"
#include "test/core/util/test_config.h"
@ -312,10 +314,10 @@ static void ssl_test_destruct(tsi_test_fixture *fixture) {
key_cert_lib->bad_client_pem_key_cert_pair);
gpr_free(key_cert_lib->root_cert);
gpr_free(key_cert_lib);
/* Destroy others. */
tsi_ssl_server_handshaker_factory_destroy(
/* Unreference others. */
tsi_ssl_server_handshaker_factory_unref(
ssl_fixture->server_handshaker_factory);
tsi_ssl_client_handshaker_factory_destroy(
tsi_ssl_client_handshaker_factory_unref(
ssl_fixture->client_handshaker_factory);
}
@ -536,6 +538,118 @@ void ssl_tsi_test_do_round_trip_odd_buffer_size() {
}
}
static const tsi_ssl_handshaker_factory_vtable *original_vtable;
static bool handshaker_factory_destructor_called;
static void ssl_tsi_test_handshaker_factory_destructor(
tsi_ssl_handshaker_factory *factory) {
GPR_ASSERT(factory != NULL);
handshaker_factory_destructor_called = true;
if (original_vtable != NULL && original_vtable->destroy != NULL) {
original_vtable->destroy(factory);
}
}
static tsi_ssl_handshaker_factory_vtable test_handshaker_factory_vtable = {
ssl_tsi_test_handshaker_factory_destructor};
void test_tsi_ssl_client_handshaker_factory_refcounting() {
int i;
const char *cert_chain =
load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "client.pem");
tsi_ssl_client_handshaker_factory *client_handshaker_factory;
GPR_ASSERT(tsi_create_ssl_client_handshaker_factory(
NULL, cert_chain, NULL, NULL, 0, &client_handshaker_factory) ==
TSI_OK);
handshaker_factory_destructor_called = false;
original_vtable = tsi_ssl_handshaker_factory_swap_vtable(
(tsi_ssl_handshaker_factory *)client_handshaker_factory,
&test_handshaker_factory_vtable);
tsi_handshaker *handshaker[3];
for (i = 0; i < 3; ++i) {
GPR_ASSERT(tsi_ssl_client_handshaker_factory_create_handshaker(
client_handshaker_factory, "google.com", &handshaker[i]) ==
TSI_OK);
}
tsi_handshaker_destroy(handshaker[1]);
GPR_ASSERT(!handshaker_factory_destructor_called);
tsi_handshaker_destroy(handshaker[0]);
GPR_ASSERT(!handshaker_factory_destructor_called);
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory);
GPR_ASSERT(!handshaker_factory_destructor_called);
tsi_handshaker_destroy(handshaker[2]);
GPR_ASSERT(handshaker_factory_destructor_called);
gpr_free((void *)cert_chain);
}
void test_tsi_ssl_server_handshaker_factory_refcounting() {
int i;
tsi_ssl_server_handshaker_factory *server_handshaker_factory;
tsi_handshaker *handshaker[3];
const char *cert_chain =
load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server0.pem");
tsi_ssl_pem_key_cert_pair cert_pair;
cert_pair.cert_chain = cert_chain;
cert_pair.private_key =
load_file(SSL_TSI_TEST_CREDENTIALS_DIR, "server0.key");
GPR_ASSERT(tsi_create_ssl_server_handshaker_factory(
&cert_pair, 1, cert_chain, 0, NULL, NULL, 0,
&server_handshaker_factory) == TSI_OK);
handshaker_factory_destructor_called = false;
original_vtable = tsi_ssl_handshaker_factory_swap_vtable(
(tsi_ssl_handshaker_factory *)server_handshaker_factory,
&test_handshaker_factory_vtable);
for (i = 0; i < 3; ++i) {
GPR_ASSERT(tsi_ssl_server_handshaker_factory_create_handshaker(
server_handshaker_factory, &handshaker[i]) == TSI_OK);
}
tsi_handshaker_destroy(handshaker[1]);
GPR_ASSERT(!handshaker_factory_destructor_called);
tsi_handshaker_destroy(handshaker[0]);
GPR_ASSERT(!handshaker_factory_destructor_called);
tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory);
GPR_ASSERT(!handshaker_factory_destructor_called);
tsi_handshaker_destroy(handshaker[2]);
GPR_ASSERT(handshaker_factory_destructor_called);
ssl_test_pem_key_cert_pair_destroy(cert_pair);
}
/* Attempting to create a handshaker factory with invalid parameters should fail
* but not crash. */
void test_tsi_ssl_client_handshaker_factory_bad_params() {
const char *cert_chain = "This is not a valid PEM file.";
tsi_ssl_client_handshaker_factory *client_handshaker_factory;
GPR_ASSERT(tsi_create_ssl_client_handshaker_factory(
NULL, cert_chain, NULL, NULL, 0, &client_handshaker_factory) ==
TSI_INVALID_ARGUMENT);
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory);
}
void ssl_tsi_test_handshaker_factory_internals() {
test_tsi_ssl_client_handshaker_factory_refcounting();
test_tsi_ssl_server_handshaker_factory_refcounting();
test_tsi_ssl_client_handshaker_factory_bad_params();
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_init();
@ -553,6 +667,7 @@ int main(int argc, char **argv) {
ssl_tsi_test_do_handshake_alpn_client_server_ok();
ssl_tsi_test_do_round_trip_for_all_configs();
ssl_tsi_test_do_round_trip_odd_buffer_size();
ssl_tsi_test_handshaker_factory_internals();
grpc_shutdown();
return 0;
}

@ -47,7 +47,7 @@ CLASSIFIERS = [
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'License :: OSI Approved :: Apache Software License',
],
]
PY3 = sys.version_info.major == 3

@ -14,18 +14,15 @@
FROM debian:jessie
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget
nuget \
&& apt-get clean
# make sure we have nuget 2.12+ (in case there's an older cached docker image)
RUN apt-get update && apt-get install -y nuget
RUN apt-get update && apt-get install -y unzip
RUN apt-get update && apt-get install -y unzip && apt-get clean

@ -14,18 +14,15 @@
FROM 32bit/debian:jessie
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget
nuget \
&& apt-get clean
# make sure we have nuget 2.12+ (in case there's an older cached docker image)
RUN apt-get update && apt-get install -y nuget
RUN apt-get update && apt-get install -y unzip
RUN apt-get update && apt-get install -y unzip && apt-get clean

@ -17,11 +17,16 @@ FROM ubuntu:16.04
RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget
nuget \
&& apt-get clean
# make sure we have nuget 2.12+ (in case there's an older cached docker image)
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
RUN apt-get update && apt-get install -y nuget
RUN apt-get update && apt-get install -y nuget && apt-get clean
RUN apt-get update && apt-get install -y unzip
# Prevent "Error: SendFailure (Error writing headers)" when fetching nuget packages
# See https://github.com/tianon/docker-brew-ubuntu-core/issues/86
RUN apt-get update && apt-get install -y tzdata && apt-get clean
RUN apt-get update && apt-get install -y unzip && apt-get clean

@ -1,114 +0,0 @@
# Copyright 2015 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM debian:jessie
# Install Git and basic packages.
RUN apt-get update && apt-get install -y \
autoconf \
autotools-dev \
build-essential \
bzip2 \
ccache \
curl \
gcc \
gcc-multilib \
git \
golang \
gyp \
lcov \
libc6 \
libc6-dbg \
libc6-dev \
libgtest-dev \
libtool \
make \
perl \
strace \
python-dev \
python-setuptools \
python-yaml \
telnet \
unzip \
wget \
zip && apt-get clean
#================
# Build profiling
RUN apt-get update && apt-get install -y time && apt-get clean
#====================
# Python dependencies
# Install dependencies
RUN apt-get update && apt-get install -y \
python-all-dev \
python3-all-dev \
python-pip
# Install Python packages from PyPI
RUN pip install pip --upgrade
RUN pip install virtualenv
RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.2.0 six==1.10.0
#================
# C# dependencies
# Update to a newer version of mono
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
# Install dependencies
RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget \
&& apt-get clean
RUN nuget update -self
# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
RUN apt-get update && apt-get install -y curl libunwind8 gettext
# dotnet-dev-1.0.0-preview2-003131
RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
# dotnet-dev-1.0.1
RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
RUN ln -s /opt/dotnet/dotnet /usr/local/bin
# Trigger the population of the local package cache
ENV NUGET_XMLDOC_MODE skip
RUN mkdir warmup \
&& cd warmup \
&& dotnet new \
&& cd .. \
&& rm -rf warmup
# Prepare ccache
RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
RUN ln -s /usr/bin/ccache /usr/local/bin/g++
RUN ln -s /usr/bin/ccache /usr/local/bin/cc
RUN ln -s /usr/bin/ccache /usr/local/bin/c++
RUN ln -s /usr/bin/ccache /usr/local/bin/clang
RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
RUN mkdir /var/local/jenkins
# Define the default command.
CMD ["bash"]

@ -0,0 +1,30 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
timeout_mins: 240
action {
define_artifacts {
regex: "**/*sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
env_vars {
key: "RUN_TESTS_FLAGS"
value: "-f basictests linux c dbg --inner_jobs 16 -j 1 --internal_ci --max_time=3600"
}

@ -0,0 +1,30 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
timeout_mins: 240
action {
define_artifacts {
regex: "**/*sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
env_vars {
key: "RUN_TESTS_FLAGS"
value: "-f basictests linux c opt --inner_jobs 16 -j 1 --internal_ci --max_time=3600"
}

@ -0,0 +1,30 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
timeout_mins: 240
action {
define_artifacts {
regex: "**/*sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
env_vars {
key: "RUN_TESTS_FLAGS"
value: "-f basictests linux c++ dbg --inner_jobs 16 -j 1 --internal_ci --max_time=3600"
}

@ -0,0 +1,30 @@
# Copyright 2017 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Config file for the internal CI (in protobuf text format)
# Location of the continuous shell script in repository.
build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
timeout_mins: 240
action {
define_artifacts {
regex: "**/*sponge_log.xml"
regex: "github/grpc/reports/**"
}
}
env_vars {
key: "RUN_TESTS_FLAGS"
value: "-f basictests linux c++ opt --inner_jobs 16 -j 1 --internal_ci --max_time=3600"
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save