Merge branch 'master' into epoll_changes

pull/6803/head
Sree Kuchibhotla 9 years ago
commit f325ee367a
  1. 5
      BUILD
  2. 2
      Makefile
  3. 4
      build.yaml
  4. 127
      doc/interop-test-descriptions.md
  5. 43
      include/grpc++/impl/codegen/async_stream.h
  6. 0
      include/grpc++/impl/codegen/core_codegen.h
  7. 43
      include/grpc++/impl/codegen/impl/async_stream.h
  8. 3
      include/grpc++/impl/grpc_library.h
  9. 2
      setup.py
  10. 4
      src/compiler/objective_c_generator.cc
  11. 20
      src/core/lib/channel/http_client_filter.c
  12. 2
      src/core/lib/channel/http_server_filter.c
  13. 39
      src/core/lib/transport/metadata.c
  14. 2
      src/cpp/common/core_codegen.cc
  15. 5
      src/csharp/Grpc.Core/Metadata.cs
  16. 2
      src/objective-c/GRPCClient/GRPCCall.h
  17. 9
      src/objective-c/ProtoRPC/ProtoMethod.h
  18. 4
      src/objective-c/ProtoRPC/ProtoMethod.m
  19. 15
      src/objective-c/ProtoRPC/ProtoRPC.h
  20. 6
      src/objective-c/ProtoRPC/ProtoRPC.m
  21. 15
      src/objective-c/ProtoRPC/ProtoService.h
  22. 4
      src/objective-c/ProtoRPC/ProtoService.m
  23. 19
      src/proto/grpc/testing/messages.proto
  24. 15
      src/python/grpcio/grpc/_auth.py
  25. 3
      src/python/grpcio/tests/interop/client.py
  26. 13
      src/python/grpcio/tests/interop/methods.py
  27. 88
      src/python/grpcio/tests/qps/benchmark_client.py
  28. 5
      src/python/grpcio/tests/qps/client_runner.py
  29. 4
      src/python/grpcio/tests/qps/qps_worker.py
  30. 5
      src/python/grpcio/tests/qps/worker_server.py
  31. 105
      test/cpp/interop/interop_client.cc
  32. 24
      test/cpp/interop/server_main.cc
  33. 1
      tools/doxygen/Doxyfile.c++
  34. 3
      tools/doxygen/Doxyfile.c++.internal
  35. 2505
      tools/doxygen/Doxyfile.c++.internal.orig
  36. 10
      tools/run_tests/performance/scenario_config.py
  37. 2
      tools/run_tests/run_interop_tests.py
  38. 8
      tools/run_tests/sources_and_headers.json
  39. 3
      vsprojects/vcxproj/grpc++/grpc++.vcxproj
  40. 9
      vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
  41. 2
      vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
  42. 6
      vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters

@ -1216,8 +1216,8 @@ cc_library(
cc_library( cc_library(
name = "grpc++", name = "grpc++",
srcs = [ srcs = [
"include/grpc++/impl/codegen/core_codegen.h",
"src/cpp/client/secure_credentials.h", "src/cpp/client/secure_credentials.h",
"src/cpp/common/core_codegen.h",
"src/cpp/common/secure_auth_context.h", "src/cpp/common/secure_auth_context.h",
"src/cpp/server/secure_server_credentials.h", "src/cpp/server/secure_server_credentials.h",
"src/cpp/client/create_channel_internal.h", "src/cpp/client/create_channel_internal.h",
@ -1266,6 +1266,7 @@ cc_library(
"include/grpc++/grpc++.h", "include/grpc++/grpc++.h",
"include/grpc++/impl/call.h", "include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h", "include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/codegen/core_codegen.h",
"include/grpc++/impl/grpc_library.h", "include/grpc++/impl/grpc_library.h",
"include/grpc++/impl/method_handler_impl.h", "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/rpc_method.h", "include/grpc++/impl/rpc_method.h",
@ -1369,7 +1370,6 @@ cc_library(
name = "grpc++_unsecure", name = "grpc++_unsecure",
srcs = [ srcs = [
"src/cpp/client/create_channel_internal.h", "src/cpp/client/create_channel_internal.h",
"src/cpp/common/core_codegen.h",
"src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/thread_pool_interface.h", "src/cpp/server/thread_pool_interface.h",
"src/cpp/common/insecure_create_auth_context.cc", "src/cpp/common/insecure_create_auth_context.cc",
@ -1410,6 +1410,7 @@ cc_library(
"include/grpc++/grpc++.h", "include/grpc++/grpc++.h",
"include/grpc++/impl/call.h", "include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h", "include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/codegen/core_codegen.h",
"include/grpc++/impl/grpc_library.h", "include/grpc++/impl/grpc_library.h",
"include/grpc++/impl/method_handler_impl.h", "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/rpc_method.h", "include/grpc++/impl/rpc_method.h",

@ -3455,6 +3455,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/grpc++.h \ include/grpc++/grpc++.h \
include/grpc++/impl/call.h \ include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \ include/grpc++/impl/grpc_library.h \
include/grpc++/impl/method_handler_impl.h \ include/grpc++/impl/method_handler_impl.h \
include/grpc++/impl/rpc_method.h \ include/grpc++/impl/rpc_method.h \
@ -3810,6 +3811,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/grpc++.h \ include/grpc++/grpc++.h \
include/grpc++/impl/call.h \ include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \ include/grpc++/impl/grpc_library.h \
include/grpc++/impl/method_handler_impl.h \ include/grpc++/impl/method_handler_impl.h \
include/grpc++/impl/rpc_method.h \ include/grpc++/impl/rpc_method.h \

@ -639,6 +639,7 @@ filegroups:
- include/grpc++/grpc++.h - include/grpc++/grpc++.h
- include/grpc++/impl/call.h - include/grpc++/impl/call.h
- include/grpc++/impl/client_unary_call.h - include/grpc++/impl/client_unary_call.h
- include/grpc++/impl/codegen/core_codegen.h
- include/grpc++/impl/grpc_library.h - include/grpc++/impl/grpc_library.h
- include/grpc++/impl/method_handler_impl.h - include/grpc++/impl/method_handler_impl.h
- include/grpc++/impl/rpc_method.h - include/grpc++/impl/rpc_method.h
@ -675,7 +676,6 @@ filegroups:
- include/grpc++/support/time.h - include/grpc++/support/time.h
headers: headers:
- src/cpp/client/create_channel_internal.h - src/cpp/client/create_channel_internal.h
- src/cpp/common/core_codegen.h
- src/cpp/server/dynamic_thread_pool.h - src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/thread_pool_interface.h - src/cpp/server/thread_pool_interface.h
src: src:
@ -934,8 +934,8 @@ libs:
build: all build: all
language: c++ language: c++
headers: headers:
- include/grpc++/impl/codegen/core_codegen.h
- src/cpp/client/secure_credentials.h - src/cpp/client/secure_credentials.h
- src/cpp/common/core_codegen.h
- src/cpp/common/secure_auth_context.h - src/cpp/common/secure_auth_context.h
- src/cpp/server/secure_server_credentials.h - src/cpp/server/secure_server_credentials.h
src: src:

@ -93,26 +93,24 @@ Client asserts:
### large_compressed_unary ### large_compressed_unary
This test verifies compressed unary calls succeed in sending messages. It This test verifies compressed unary calls succeed in sending messages. It
sends one unary request for every combination of compression algorithm and sends one unary request for every payload type, with and without requesting a
payload type. compressed response from the server.
In all scenarios, whether compression was actually performed is determined by In all scenarios, whether compression was actually performed is determined by
the compression bit in the response's message flags. The response's compression the compression bit in the response's message flags.
value indicates which algorithm was used if said compression bit is set.
Server features: Server features:
* [UnaryCall][] * [UnaryCall][]
* [Compressable Payload][] * [Compressable Payload][]
* [Uncompressable Payload][] * [Uncompressable Payload][]
* [Random Payload][]
Procedure: Procedure:
1. Client calls UnaryCall with: 1. Client calls UnaryCall with:
``` ```
{ {
response_compression: <one of {NONE, GZIP, DEFLATE}> request_compressed_response: bool
response_type: COMPRESSABLE response_type: COMPRESSABLE
response_size: 314159 response_size: 314159
payload:{ payload:{
@ -123,11 +121,10 @@ Procedure:
Client asserts: Client asserts:
* call was successful * call was successful
* response payload type is COMPRESSABLE * response payload type is COMPRESSABLE
* response compression is consistent with the requested one. * if `request_compressed_response` is false, the response MUST NOT have the
* if `response_compression == NONE`, the response MUST NOT have the compressed message flag set.
* if `request_compressed_response` is true, the response MUST have the
compressed message flag set. compressed message flag set.
* if `response_compression != NONE`, the response MUST have the compressed
message flag set.
* response payload body is 314159 bytes in size * response payload body is 314159 bytes in size
* clients are free to assert that the response payload body contents are * clients are free to assert that the response payload body contents are
zero and comparing the entire response message against a golden response zero and comparing the entire response message against a golden response
@ -136,7 +133,7 @@ Procedure:
2. Client calls UnaryCall with: 2. Client calls UnaryCall with:
``` ```
{ {
response_compression: <one of {NONE, GZIP, DEFLATE}> request_compressed_response: bool
response_type: UNCOMPRESSABLE response_type: UNCOMPRESSABLE
response_size: 314159 response_size: 314159
payload:{ payload:{
@ -147,29 +144,11 @@ Procedure:
Client asserts: Client asserts:
* call was successful * call was successful
* response payload type is UNCOMPRESSABLE * response payload type is UNCOMPRESSABLE
* response compression is consistent with the requested one. * the response MAY have the compressed message flag set. Some
* the response MUST NOT have the compressed message flag set. implementations will choose to compress the payload even when the output
size if larger than the input.
* response payload body is 314159 bytes in size * response payload body is 314159 bytes in size
* clients are free to assert that the response payload body contents are
identical to the golden uncompressable data at `test/cpp/interop/rnd.dat`.
3. Client calls UnaryCall with:
```
{
response_compression: <one of {NONE, GZIP, DEFLATE}>
response_type: RANDOM
response_size: 314159
payload:{
body: 271828 bytes of zeros
}
}
```
Client asserts:
* call was successful
* response payload type is either COMPRESSABLE or UNCOMPRESSABLE
* the behavior is consistent with the randomly chosen incoming payload type,
as described in their respective sections.
### client_streaming ### client_streaming
@ -245,7 +224,7 @@ Procedure:
size: 31415 size: 31415
} }
response_parameters:{ response_parameters:{
size: 9 size: 59
} }
response_parameters:{ response_parameters:{
size: 2653 size: 2653
@ -272,7 +251,6 @@ Server features:
* [StreamingOutputCall][] * [StreamingOutputCall][]
* [Compressable Payload][] * [Compressable Payload][]
* [Uncompressable Payload][] * [Uncompressable Payload][]
* [Random Payload][]
Procedure: Procedure:
@ -280,13 +258,13 @@ Procedure:
``` ```
{ {
response_compression: <one of {NONE, GZIP, DEFLATE}> request_compressed_response: bool
response_type:COMPRESSABLE response_type:COMPRESSABLE
response_parameters:{ response_parameters:{
size: 31415 size: 31415
} }
response_parameters:{ response_parameters:{
size: 9 size: 59
} }
response_parameters:{ response_parameters:{
size: 2653 size: 2653
@ -301,12 +279,11 @@ Procedure:
* call was successful * call was successful
* exactly four responses * exactly four responses
* response payloads are COMPRESSABLE * response payloads are COMPRESSABLE
* response compression is consistent with the requested one. * if `request_compressed_response` is false, the response's messages MUST
* if `response_compression == NONE`, the response MUST NOT have the NOT have the compressed message flag set.
compressed message flag set. * if `request_compressed_response` is true, the response's messages MUST
* if `response_compression != NONE`, the response MUST have the compressed have the compressed message flag set.
message flag set. * response payload bodies are sized (in order): 31415, 59, 2653, 58979
* response payload bodies are sized (in order): 31415, 9, 2653, 58979
* clients are free to assert that the response payload body contents are * clients are free to assert that the response payload body contents are
zero and comparing the entire response messages against golden responses zero and comparing the entire response messages against golden responses
@ -315,13 +292,13 @@ Procedure:
``` ```
{ {
response_compression: <one of {NONE, GZIP, DEFLATE}> request_compressed_response: bool
response_type:UNCOMPRESSABLE response_type:UNCOMPRESSABLE
response_parameters:{ response_parameters:{
size: 31415 size: 31415
} }
response_parameters:{ response_parameters:{
size: 9 size: 59
} }
response_parameters:{ response_parameters:{
size: 2653 size: 2653
@ -336,40 +313,14 @@ Procedure:
* call was successful * call was successful
* exactly four responses * exactly four responses
* response payloads are UNCOMPRESSABLE * response payloads are UNCOMPRESSABLE
* response compressions are consistent with the requested one. * the response MAY have the compressed message flag set. Some
* the responses MUST NOT have the compressed message flag set. implementations will choose to compress the payload even when the output
* response payload bodies are sized (in order): 31415, 9, 2653, 58979 size if larger than the input.
* response payload bodies are sized (in order): 31415, 59, 2653, 58979
* clients are free to assert that the body of the responses are identical to * clients are free to assert that the body of the responses are identical to
the golden uncompressable data at `test/cpp/interop/rnd.dat`. the golden uncompressable data at `test/cpp/interop/rnd.dat`.
3. Client calls StreamingOutputCall with:
```
{
response_compression: <one of {NONE, GZIP, DEFLATE}>
response_type:RANDOM
response_parameters:{
size: 31415
}
response_parameters:{
size: 9
}
response_parameters:{
size: 2653
}
response_parameters:{
size: 58979
}
}
```
Client asserts:
* call was successful
* response payload type is either COMPRESSABLE or UNCOMPRESSABLE
* the behavior is consistent with the randomly chosen incoming payload type,
as described in their respective sections.
### ping_pong ### ping_pong
This test verifies that full duplex bidi is supported. This test verifies that full duplex bidi is supported.
@ -399,7 +350,7 @@ Procedure:
{ {
response_type: COMPRESSABLE response_type: COMPRESSABLE
response_parameters:{ response_parameters:{
size: 9 size: 59
} }
payload:{ payload:{
body: 8 bytes of zeros body: 8 bytes of zeros
@ -932,9 +883,9 @@ Server implements EmptyCall which immediately returns the empty message.
[UnaryCall]: #unarycall [UnaryCall]: #unarycall
Server implements UnaryCall which immediately returns a SimpleResponse with a Server implements UnaryCall which immediately returns a SimpleResponse with a
payload body of size SimpleRequest.response_size bytes and type as appropriate payload body of size `SimpleRequest.response_size` bytes and type as appropriate
for the SimpleRequest.response_type. If the server does not support the for the `SimpleRequest.response_type`. If the server does not support the
response_type, then it should fail the RPC with INVALID_ARGUMENT. `response_type`, then it should fail the RPC with `INVALID_ARGUMENT`.
### StreamingInputCall ### StreamingInputCall
[StreamingInputCall]: #streaminginputcall [StreamingInputCall]: #streaminginputcall
@ -974,15 +925,7 @@ COMPRESSABLE.
When the client requests UNCOMPRESSABLE payload, the response includes a payload When the client requests UNCOMPRESSABLE payload, the response includes a payload
of the size requested containing uncompressable data and the payload type is of the size requested containing uncompressable data and the payload type is
UNCOMPRESSABLE. A 512 kB dump from /dev/urandom is the current golden data, UNCOMPRESSABLE.
stored at `test/cpp/interop/rnd.dat`
### Random Payload
[Random Payload]: #random-payload
When the client requests RANDOM payload, the response includes either a randomly
chosen COMPRESSABLE or UNCOMPRESSABLE payload. The data and the payload type
will be consistent with this choice.
### Echo Status ### Echo Status
[Echo Status]: #echo-status [Echo Status]: #echo-status
@ -1004,8 +947,8 @@ key and the corresponding value back to the client as trailing metadata.
[Observe ResponseParameters.interval_us]: #observe-responseparametersinterval_us [Observe ResponseParameters.interval_us]: #observe-responseparametersinterval_us
In StreamingOutputCall and FullDuplexCall, server delays sending a In StreamingOutputCall and FullDuplexCall, server delays sending a
StreamingOutputCallResponse by the ResponseParameters's interval_us for that StreamingOutputCallResponse by the ResponseParameters's `interval_us` for that
particular response, relative to the last response sent. That is, interval_us particular response, relative to the last response sent. That is, `interval_us`
acts like a sleep *before* sending the response and accumulates from one acts like a sleep *before* sending the response and accumulates from one
response to the next. response to the next.
@ -1027,13 +970,13 @@ an email address.
#### Echo OAuth scope #### Echo OAuth scope
[Echo OAuth Scope]: #echo-oauth-scope [Echo OAuth Scope]: #echo-oauth-scope
If a SimpleRequest has fill_oauth_scope=true and that request was successfully If a SimpleRequest has `fill_oauth_scope=true` and that request was successfully
authenticated via OAuth, then the SimpleResponse should have oauth_scope filled authenticated via OAuth, then the SimpleResponse should have oauth_scope filled
with the scope of the method being invoked. with the scope of the method being invoked.
Although a general server-side feature, most test servers won't implement this Although a general server-side feature, most test servers won't implement this
feature. The TLS server grpc-test.sandbox.googleapis.com:443 supports this feature. feature. The TLS server `grpc-test.sandbox.googleapis.com:443` supports this
It requires at least the OAuth scope feature. It requires at least the OAuth scope
`https://www.googleapis.com/auth/xapi.zoo` for authentication to succeed. `https://www.googleapis.com/auth/xapi.zoo` for authentication to succeed.
Discussion: Discussion:

@ -299,8 +299,16 @@ class ClientAsyncReaderWriter GRPC_FINAL
}; };
template <class W, class R> template <class W, class R>
class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface, class ServerAsyncReaderInterface : public ServerAsyncStreamingInterface,
public AsyncReaderInterface<R> { public AsyncReaderInterface<R> {
public:
virtual void Finish(const W& msg, const Status& status, void* tag) = 0;
virtual void FinishWithError(const Status& status, void* tag) = 0;
};
template <class W, class R>
class ServerAsyncReader GRPC_FINAL : public ServerAsyncReaderInterface<W, R> {
public: public:
explicit ServerAsyncReader(ServerContext* ctx) explicit ServerAsyncReader(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {} : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@ -321,7 +329,7 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
call_.PerformOps(&read_ops_); call_.PerformOps(&read_ops_);
} }
void Finish(const W& msg, const Status& status, void* tag) { void Finish(const W& msg, const Status& status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag); finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) { if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_, finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
@ -338,7 +346,7 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
call_.PerformOps(&finish_ops_); call_.PerformOps(&finish_ops_);
} }
void FinishWithError(const Status& status, void* tag) { void FinishWithError(const Status& status, void* tag) GRPC_OVERRIDE {
GPR_CODEGEN_ASSERT(!status.ok()); GPR_CODEGEN_ASSERT(!status.ok());
finish_ops_.set_output_tag(tag); finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) { if (!ctx_->sent_initial_metadata_) {
@ -363,8 +371,14 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
}; };
template <class W> template <class W>
class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface, class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface,
public AsyncWriterInterface<W> { public AsyncWriterInterface<W> {
public:
virtual void Finish(const Status& status, void* tag) = 0;
};
template <class W>
class ServerAsyncWriter GRPC_FINAL : public ServerAsyncWriterInterface<W> {
public: public:
explicit ServerAsyncWriter(ServerContext* ctx) explicit ServerAsyncWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {} : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@ -391,7 +405,7 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
call_.PerformOps(&write_ops_); call_.PerformOps(&write_ops_);
} }
void Finish(const Status& status, void* tag) { void Finish(const Status& status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag); finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) { if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_, finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
@ -414,9 +428,16 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
/// Server-side interface for asynchronous bi-directional streaming. /// Server-side interface for asynchronous bi-directional streaming.
template <class W, class R> template <class W, class R>
class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface, class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface,
public AsyncWriterInterface<W>, public AsyncWriterInterface<W>,
public AsyncReaderInterface<R> { public AsyncReaderInterface<R> {
public:
virtual void Finish(const Status& status, void* tag) = 0;
};
template <class W, class R>
class ServerAsyncReaderWriter GRPC_FINAL
: public ServerAsyncReaderWriterInterface<W, R> {
public: public:
explicit ServerAsyncReaderWriter(ServerContext* ctx) explicit ServerAsyncReaderWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {} : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@ -449,7 +470,7 @@ class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
call_.PerformOps(&write_ops_); call_.PerformOps(&write_ops_);
} }
void Finish(const Status& status, void* tag) { void Finish(const Status& status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag); finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) { if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_, finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,

@ -295,8 +295,16 @@ class ClientAsyncReaderWriter GRPC_FINAL
}; };
template <class W, class R> template <class W, class R>
class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface, class ServerAsyncReaderInterface : public ServerAsyncStreamingInterface,
public AsyncReaderInterface<R> { public AsyncReaderInterface<R> {
public:
virtual void Finish(const W& msg, const Status& status, void* tag) = 0;
virtual void FinishWithError(const Status& status, void* tag) = 0;
};
template <class W, class R>
class ServerAsyncReader GRPC_FINAL : public ServerAsyncReaderInterface<W, R> {
public: public:
explicit ServerAsyncReader(ServerContext* ctx) explicit ServerAsyncReader(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {} : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@ -316,7 +324,7 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
call_.PerformOps(&read_ops_); call_.PerformOps(&read_ops_);
} }
void Finish(const W& msg, const Status& status, void* tag) { void Finish(const W& msg, const Status& status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag); finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) { if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
@ -332,7 +340,7 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
call_.PerformOps(&finish_ops_); call_.PerformOps(&finish_ops_);
} }
void FinishWithError(const Status& status, void* tag) { void FinishWithError(const Status& status, void* tag) GRPC_OVERRIDE {
GPR_CODEGEN_ASSERT(!status.ok()); GPR_CODEGEN_ASSERT(!status.ok());
finish_ops_.set_output_tag(tag); finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) { if (!ctx_->sent_initial_metadata_) {
@ -356,8 +364,14 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
}; };
template <class W> template <class W>
class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface, class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface,
public AsyncWriterInterface<W> { public AsyncWriterInterface<W> {
public:
virtual void Finish(const Status& status, void* tag) = 0;
};
template <class W>
class ServerAsyncWriter GRPC_FINAL : public ServerAsyncWriterInterface<W> {
public: public:
explicit ServerAsyncWriter(ServerContext* ctx) explicit ServerAsyncWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {} : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@ -382,7 +396,7 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
call_.PerformOps(&write_ops_); call_.PerformOps(&write_ops_);
} }
void Finish(const Status& status, void* tag) { void Finish(const Status& status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag); finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) { if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
@ -404,9 +418,16 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
/// Server-side interface for asynchronous bi-directional streaming. /// Server-side interface for asynchronous bi-directional streaming.
template <class W, class R> template <class W, class R>
class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface, class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface,
public AsyncWriterInterface<W>, public AsyncWriterInterface<W>,
public AsyncReaderInterface<R> { public AsyncReaderInterface<R> {
public:
virtual void Finish(const Status& status, void* tag) = 0;
};
template <class W, class R>
class ServerAsyncReaderWriter GRPC_FINAL
: public ServerAsyncReaderWriterInterface<W, R> {
public: public:
explicit ServerAsyncReaderWriter(ServerContext* ctx) explicit ServerAsyncReaderWriter(ServerContext* ctx)
: call_(nullptr, nullptr, nullptr), ctx_(ctx) {} : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@ -437,7 +458,7 @@ class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
call_.PerformOps(&write_ops_); call_.PerformOps(&write_ops_);
} }
void Finish(const Status& status, void* tag) { void Finish(const Status& status, void* tag) GRPC_OVERRIDE {
finish_ops_.set_output_tag(tag); finish_ops_.set_output_tag(tag);
if (!ctx_->sent_initial_metadata_) { if (!ctx_->sent_initial_metadata_) {
finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);

@ -37,11 +37,10 @@
#include <iostream> #include <iostream>
#include <grpc++/impl/codegen/config.h> #include <grpc++/impl/codegen/config.h>
#include <grpc++/impl/codegen/core_codegen.h>
#include <grpc++/impl/codegen/grpc_library.h> #include <grpc++/impl/codegen/grpc_library.h>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include "src/cpp/common/core_codegen.h"
namespace grpc { namespace grpc {
namespace internal { namespace internal {

@ -202,7 +202,7 @@ TEST_PACKAGE_DATA = {
} }
TESTS_REQUIRE = ( TESTS_REQUIRE = (
'oauth2client>=1.4.7', 'oauth2client>=2.1.0',
'protobuf>=3.0.0a3', 'protobuf>=3.0.0a3',
'coverage>=4.0', 'coverage>=4.0',
) + INSTALL_REQUIRES ) + INSTALL_REQUIRES

@ -94,7 +94,7 @@ void PrintSimpleSignature(Printer *printer, const MethodDescriptor *method,
void PrintAdvancedSignature(Printer *printer, const MethodDescriptor *method, void PrintAdvancedSignature(Printer *printer, const MethodDescriptor *method,
map< ::grpc::string, ::grpc::string> vars) { map< ::grpc::string, ::grpc::string> vars) {
vars["method_name"] = "RPCTo" + vars["method_name"]; vars["method_name"] = "RPCTo" + vars["method_name"];
vars["return_type"] = "ProtoRPC *"; vars["return_type"] = "GRPCProtoCall *";
PrintMethodSignature(printer, method, vars); PrintMethodSignature(printer, method, vars);
} }
@ -199,7 +199,7 @@ void PrintMethodImplementations(Printer *printer,
" marshalling and parsing.\n"); " marshalling and parsing.\n");
printer.Print(vars, printer.Print(vars,
"@interface $service_class$ :" "@interface $service_class$ :"
" ProtoService<$service_class$>\n"); " GRPCProtoService<$service_class$>\n");
printer.Print( printer.Print(
"- (instancetype)initWithHost:(NSString *)host" "- (instancetype)initWithHost:(NSString *)host"
" NS_DESIGNATED_INITIALIZER;\n"); " NS_DESIGNATED_INITIALIZER;\n");

@ -39,6 +39,9 @@
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
#include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/static_metadata.h"
#define EXPECTED_CONTENT_TYPE "application/grpc"
#define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1
typedef struct call_data { typedef struct call_data {
grpc_linked_mdelem method; grpc_linked_mdelem method;
grpc_linked_mdelem scheme; grpc_linked_mdelem scheme;
@ -74,7 +77,24 @@ static grpc_mdelem *client_recv_filter(void *user_data, grpc_mdelem *md) {
} else if (md->key == GRPC_MDSTR_STATUS) { } else if (md->key == GRPC_MDSTR_STATUS) {
grpc_call_element_send_cancel(a->exec_ctx, a->elem); grpc_call_element_send_cancel(a->exec_ctx, a->elem);
return NULL; return NULL;
} else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
return NULL;
} else if (md->key == GRPC_MDSTR_CONTENT_TYPE) { } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
const char *value_str = grpc_mdstr_as_c_string(md->value);
if (strncmp(value_str, EXPECTED_CONTENT_TYPE,
EXPECTED_CONTENT_TYPE_LENGTH) == 0 &&
(value_str[EXPECTED_CONTENT_TYPE_LENGTH] == '+' ||
value_str[EXPECTED_CONTENT_TYPE_LENGTH] == ';')) {
/* Although the C implementation doesn't (currently) generate them,
any custom +-suffix is explicitly valid. */
/* TODO(klempner): We should consider preallocating common values such
as +proto or +json, or at least stashing them if we see them. */
/* TODO(klempner): Should we be surfacing this to application code? */
} else {
/* TODO(klempner): We're currently allowing this, but we shouldn't
see it without a proxy so log for now. */
gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str);
}
return NULL; return NULL;
} }
return md; return md;

@ -108,7 +108,7 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
} else { } else {
/* TODO(klempner): We're currently allowing this, but we shouldn't /* TODO(klempner): We're currently allowing this, but we shouldn't
see it without a proxy so log for now. */ see it without a proxy so log for now. */
gpr_log(GPR_INFO, "Unexpected content-type %s", value_str); gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str);
} }
return NULL; return NULL;
} else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD || } else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD ||

@ -129,7 +129,10 @@ typedef struct mdtab_shard {
internal_metadata **elems; internal_metadata **elems;
size_t count; size_t count;
size_t capacity; size_t capacity;
size_t free; /** Estimate of the number of unreferenced mdelems in the hash table.
This will eventually converge to the exact number, but it's instantaneous
accuracy is not guaranteed */
gpr_atm free_estimate;
} mdtab_shard; } mdtab_shard;
#define LOG2_STRTAB_SHARD_COUNT 5 #define LOG2_STRTAB_SHARD_COUNT 5
@ -217,7 +220,7 @@ void grpc_mdctx_global_init(void) {
mdtab_shard *shard = &g_mdtab_shard[i]; mdtab_shard *shard = &g_mdtab_shard[i];
gpr_mu_init(&shard->mu); gpr_mu_init(&shard->mu);
shard->count = 0; shard->count = 0;
shard->free = 0; gpr_atm_no_barrier_store(&shard->free_estimate, 0);
shard->capacity = INITIAL_MDTAB_CAPACITY; shard->capacity = INITIAL_MDTAB_CAPACITY;
shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity); shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity);
memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity); memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity);
@ -281,10 +284,8 @@ static void ref_md_locked(mdtab_shard *shard,
grpc_mdstr_as_c_string((grpc_mdstr *)md->key), grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
#endif #endif
if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 2)) { if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) {
shard->free--; gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1);
} else {
GPR_ASSERT(1 != gpr_atm_no_barrier_fetch_add(&md->refcnt, -1));
} }
} }
@ -447,6 +448,7 @@ static void gc_mdtab(mdtab_shard *shard) {
size_t i; size_t i;
internal_metadata **prev_next; internal_metadata **prev_next;
internal_metadata *md, *next; internal_metadata *md, *next;
gpr_atm num_freed = 0;
GPR_TIMER_BEGIN("gc_mdtab", 0); GPR_TIMER_BEGIN("gc_mdtab", 0);
for (i = 0; i < shard->capacity; i++) { for (i = 0; i < shard->capacity; i++) {
@ -463,13 +465,14 @@ static void gc_mdtab(mdtab_shard *shard) {
} }
gpr_free(md); gpr_free(md);
*prev_next = next; *prev_next = next;
shard->free--; num_freed++;
shard->count--; shard->count--;
} else { } else {
prev_next = &md->bucket_next; prev_next = &md->bucket_next;
} }
} }
} }
gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -num_freed);
GPR_TIMER_END("gc_mdtab", 0); GPR_TIMER_END("gc_mdtab", 0);
} }
@ -504,7 +507,8 @@ static void grow_mdtab(mdtab_shard *shard) {
} }
static void rehash_mdtab(mdtab_shard *shard) { static void rehash_mdtab(mdtab_shard *shard) {
if (shard->free > shard->capacity / 4) { if (gpr_atm_no_barrier_load(&shard->free_estimate) >
(gpr_atm)(shard->capacity / 4)) {
gc_mdtab(shard); gc_mdtab(shard);
} else { } else {
grow_mdtab(shard); grow_mdtab(shard);
@ -553,7 +557,7 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdstr *mkey,
/* not found: create a new pair */ /* not found: create a new pair */
md = gpr_malloc(sizeof(internal_metadata)); md = gpr_malloc(sizeof(internal_metadata));
gpr_atm_rel_store(&md->refcnt, 2); gpr_atm_rel_store(&md->refcnt, 1);
md->key = key; md->key = key;
md->value = value; md->value = value;
md->user_data = 0; md->user_data = 0;
@ -645,7 +649,7 @@ grpc_mdelem *grpc_mdelem_ref(grpc_mdelem *gmd DEBUG_ARGS) {
this function - meaning that no adjustment to mdtab_free is necessary, this function - meaning that no adjustment to mdtab_free is necessary,
simplifying the logic here to be just an atomic increment */ simplifying the logic here to be just an atomic increment */
/* use C assert to have this removed in opt builds */ /* use C assert to have this removed in opt builds */
assert(gpr_atm_no_barrier_load(&md->refcnt) >= 2); assert(gpr_atm_no_barrier_load(&md->refcnt) >= 1);
gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
return gmd; return gmd;
} }
@ -662,18 +666,13 @@ void grpc_mdelem_unref(grpc_mdelem *gmd DEBUG_ARGS) {
grpc_mdstr_as_c_string((grpc_mdstr *)md->key), grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
grpc_mdstr_as_c_string((grpc_mdstr *)md->value)); grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
#endif #endif
if (2 == gpr_atm_full_fetch_add(&md->refcnt, -1)) { uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash);
uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash); if (1 == gpr_atm_full_fetch_add(&md->refcnt, -1)) {
/* once the refcount hits zero, some other thread can come along and
free md at any time: it's unsafe from this point on to access it */
mdtab_shard *shard = mdtab_shard *shard =
&g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)]; &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)];
GPR_TIMER_BEGIN("grpc_mdelem_unref.to_zero", 0); gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1);
gpr_mu_lock(&shard->mu);
if (1 == gpr_atm_no_barrier_load(&md->refcnt)) {
shard->free++;
gpr_atm_no_barrier_store(&md->refcnt, 0);
}
gpr_mu_unlock(&shard->mu);
GPR_TIMER_END("grpc_mdelem_unref.to_zero", 0);
} }
} }

@ -31,7 +31,7 @@
* *
*/ */
#include "src/cpp/common/core_codegen.h" #include <grpc++/impl/codegen/core_codegen.h>
#include <stdlib.h> #include <stdlib.h>

@ -95,6 +95,7 @@ namespace Grpc.Core
public void Insert(int index, Metadata.Entry item) public void Insert(int index, Metadata.Entry item)
{ {
GrpcPreconditions.CheckNotNull(item);
CheckWriteable(); CheckWriteable();
entries.Insert(index, item); entries.Insert(index, item);
} }
@ -114,6 +115,7 @@ namespace Grpc.Core
set set
{ {
GrpcPreconditions.CheckNotNull(value);
CheckWriteable(); CheckWriteable();
entries[index] = value; entries[index] = value;
} }
@ -121,6 +123,7 @@ namespace Grpc.Core
public void Add(Metadata.Entry item) public void Add(Metadata.Entry item)
{ {
GrpcPreconditions.CheckNotNull(item);
CheckWriteable(); CheckWriteable();
entries.Add(item); entries.Add(item);
} }
@ -187,7 +190,7 @@ namespace Grpc.Core
/// <summary> /// <summary>
/// Metadata entry /// Metadata entry
/// </summary> /// </summary>
public struct Entry public class Entry
{ {
private static readonly Encoding Encoding = Encoding.ASCII; private static readonly Encoding Encoding = Encoding.ASCII;
private static readonly Regex ValidKeyRegex = new Regex("^[a-z0-9_-]+$"); private static readonly Regex ValidKeyRegex = new Regex("^[a-z0-9_-]+$");

@ -220,6 +220,8 @@ extern id const kGRPCTrailersKey;
* messages to the response side of the call indefinitely (depending on the semantics of the * messages to the response side of the call indefinitely (depending on the semantics of the
* specific remote method called). * specific remote method called).
* To finish a call right away, invoke cancel. * To finish a call right away, invoke cancel.
* host parameter should not contain the scheme (http:// or https://), only the name or IP addr
* and the port number, for example @"localhost:5050".
*/ */
- (instancetype)initWithHost:(NSString *)host - (instancetype)initWithHost:(NSString *)host
path:(NSString *)path path:(NSString *)path

@ -37,6 +37,7 @@
* A fully-qualified proto service method name. Full qualification is needed because a gRPC endpoint * A fully-qualified proto service method name. Full qualification is needed because a gRPC endpoint
* can implement multiple services. * can implement multiple services.
*/ */
__attribute__((deprecated("Please use GRPCProtoMethod.")))
@interface ProtoMethod : NSObject @interface ProtoMethod : NSObject
@property(nonatomic, readonly) NSString *package; @property(nonatomic, readonly) NSString *package;
@property(nonatomic, readonly) NSString *service; @property(nonatomic, readonly) NSString *service;
@ -48,3 +49,11 @@
service:(NSString *)service service:(NSString *)service
method:(NSString *)method; method:(NSString *)method;
@end @end
/**
* This subclass is empty now. Eventually we'll remove ProtoMethod class
* to avoid potential naming conflict
*/
@interface GRPCProtoMethod : ProtoMethod
@end

@ -53,3 +53,7 @@
} }
} }
@end @end
@implementation GRPCProtoMethod
@end

@ -36,13 +36,26 @@
#import "ProtoMethod.h" #import "ProtoMethod.h"
__attribute__((deprecated("Please use GRPCProtoCall.")))
@interface ProtoRPC : GRPCCall @interface ProtoRPC : GRPCCall
/**
* host parameter should not contain the scheme (http:// or https://), only the name or IP addr
* and the port number, for example @"localhost:5050".
*/
- (instancetype)initWithHost:(NSString *)host - (instancetype)initWithHost:(NSString *)host
method:(ProtoMethod *)method method:(GRPCProtoMethod *)method
requestsWriter:(GRXWriter *)requestsWriter requestsWriter:(GRXWriter *)requestsWriter
responseClass:(Class)responseClass responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable NS_DESIGNATED_INITIALIZER; responsesWriteable:(id<GRXWriteable>)responsesWriteable NS_DESIGNATED_INITIALIZER;
- (void)start; - (void)start;
@end @end
/**
* This subclass is empty now. Eventually we'll remove ProtoRPC class
* to avoid potential naming conflict
*/
@interface GRPCProtoCall : ProtoRPC
@end

@ -70,7 +70,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing
// Designated initializer // Designated initializer
- (instancetype)initWithHost:(NSString *)host - (instancetype)initWithHost:(NSString *)host
method:(ProtoMethod *)method method:(GRPCProtoMethod *)method
requestsWriter:(GRXWriter *)requestsWriter requestsWriter:(GRXWriter *)requestsWriter
responseClass:(Class)responseClass responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable { responsesWriteable:(id<GRXWriteable>)responsesWriteable {
@ -117,3 +117,7 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing
_responseWriteable = nil; _responseWriteable = nil;
} }
@end @end
@implementation GRPCProtoCall
@end

@ -33,17 +33,28 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class ProtoRPC; @class GRPCProtoCall;
@protocol GRXWriteable; @protocol GRXWriteable;
@class GRXWriter; @class GRXWriter;
__attribute__((deprecated("Please use GRPCProtoService.")))
@interface ProtoService : NSObject @interface ProtoService : NSObject
- (instancetype)initWithHost:(NSString *)host - (instancetype)initWithHost:(NSString *)host
packageName:(NSString *)packageName packageName:(NSString *)packageName
serviceName:(NSString *)serviceName NS_DESIGNATED_INITIALIZER; serviceName:(NSString *)serviceName NS_DESIGNATED_INITIALIZER;
- (ProtoRPC *)RPCToMethod:(NSString *)method - (GRPCProtoCall *)RPCToMethod:(NSString *)method
requestsWriter:(GRXWriter *)requestsWriter requestsWriter:(GRXWriter *)requestsWriter
responseClass:(Class)responseClass responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable; responsesWriteable:(id<GRXWriteable>)responsesWriteable;
@end @end
/**
* This subclass is empty now. Eventually we'll remove ProtoService class
* to avoid potential naming conflict
*/
@interface GRPCProtoService : ProtoService
@end

@ -79,3 +79,7 @@
responsesWriteable:responsesWriteable]; responsesWriteable:responsesWriteable];
} }
@end @end
@implementation GRPCProtoService
@end

@ -41,17 +41,6 @@ enum PayloadType {
// Uncompressable binary format. // Uncompressable binary format.
UNCOMPRESSABLE = 1; UNCOMPRESSABLE = 1;
// Randomly chosen from all other formats defined in this enum.
RANDOM = 2;
}
// Compression algorithms
enum CompressionType {
// No compression
NONE = 0;
GZIP = 1;
DEFLATE = 2;
} }
// A block of data, to simply increase gRPC message size. // A block of data, to simply increase gRPC message size.
@ -88,8 +77,8 @@ message SimpleRequest {
// Whether SimpleResponse should include OAuth scope. // Whether SimpleResponse should include OAuth scope.
bool fill_oauth_scope = 5; bool fill_oauth_scope = 5;
// Compression algorithm to be used by the server for the response (stream) // Whether to request the server to compress the response.
CompressionType response_compression = 6; bool request_compressed_response = 6;
// Whether server should return a given status // Whether server should return a given status
EchoStatus response_status = 7; EchoStatus response_status = 7;
@ -145,8 +134,8 @@ message StreamingOutputCallRequest {
// Optional input payload sent along with the request. // Optional input payload sent along with the request.
Payload payload = 3; Payload payload = 3;
// Compression algorithm to be used by the server for the response (stream) // Whether to request the server to compress the response.
CompressionType response_compression = 6; bool request_compressed_response = 6;
// Whether server should return a given status // Whether server should return a given status
EchoStatus response_status = 7; EchoStatus response_status = 7;

@ -29,6 +29,7 @@
"""GRPCAuthMetadataPlugins for standard authentication.""" """GRPCAuthMetadataPlugins for standard authentication."""
import inspect
from concurrent import futures from concurrent import futures
import grpc import grpc
@ -46,9 +47,21 @@ class GoogleCallCredentials(grpc.AuthMetadataPlugin):
self._credentials = credentials self._credentials = credentials
self._pool = futures.ThreadPoolExecutor(max_workers=1) self._pool = futures.ThreadPoolExecutor(max_workers=1)
# Hack to determine if these are JWT creds and we need to pass
# additional_claims when getting a token
if 'additional_claims' in inspect.getargspec(
credentials.get_access_token).args:
self._is_jwt = True
else:
self._is_jwt = False
def __call__(self, context, callback): def __call__(self, context, callback):
# MetadataPlugins cannot block (see grpc.beta.interfaces.py) # MetadataPlugins cannot block (see grpc.beta.interfaces.py)
future = self._pool.submit(self._credentials.get_access_token) if self._is_jwt:
future = self._pool.submit(self._credentials.get_access_token,
additional_claims={'aud': context.service_url})
else:
future = self._pool.submit(self._credentials.get_access_token)
future.add_done_callback(lambda x: self._get_token_callback(callback, x)) future.add_done_callback(lambda x: self._get_token_callback(callback, x))
def _get_token_callback(self, callback, future): def _get_token_callback(self, callback, future):

@ -76,6 +76,9 @@ def _stub(args):
creds = oauth2client_client.GoogleCredentials.get_application_default() creds = oauth2client_client.GoogleCredentials.get_application_default()
scoped_creds = creds.create_scoped([args.oauth_scope]) scoped_creds = creds.create_scoped([args.oauth_scope])
call_creds = implementations.google_call_credentials(scoped_creds) call_creds = implementations.google_call_credentials(scoped_creds)
elif args.test_case == 'jwt_token_creds':
creds = oauth2client_client.GoogleCredentials.get_application_default()
call_creds = implementations.google_call_credentials(creds)
else: else:
call_creds = None call_creds = None
if args.use_tls: if args.use_tls:

@ -310,6 +310,16 @@ def _oauth2_auth_token(stub, args):
(response.oauth_scope, args.oauth_scope)) (response.oauth_scope, args.oauth_scope))
def _jwt_token_creds(stub, args):
json_key_filename = os.environ[
oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
response = _large_unary_common_behavior(stub, True, False)
if wanted_email != response.username:
raise ValueError(
'expected username %s, got %s' % (wanted_email, response.username))
def _per_rpc_creds(stub, args): def _per_rpc_creds(stub, args):
json_key_filename = os.environ[ json_key_filename = os.environ[
oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS] oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
@ -338,6 +348,7 @@ class TestCase(enum.Enum):
EMPTY_STREAM = 'empty_stream' EMPTY_STREAM = 'empty_stream'
COMPUTE_ENGINE_CREDS = 'compute_engine_creds' COMPUTE_ENGINE_CREDS = 'compute_engine_creds'
OAUTH2_AUTH_TOKEN = 'oauth2_auth_token' OAUTH2_AUTH_TOKEN = 'oauth2_auth_token'
JWT_TOKEN_CREDS = 'jwt_token_creds'
PER_RPC_CREDS = 'per_rpc_creds' PER_RPC_CREDS = 'per_rpc_creds'
TIMEOUT_ON_SLEEPING_SERVER = 'timeout_on_sleeping_server' TIMEOUT_ON_SLEEPING_SERVER = 'timeout_on_sleeping_server'
@ -364,6 +375,8 @@ class TestCase(enum.Enum):
_compute_engine_creds(stub, args) _compute_engine_creds(stub, args)
elif self is TestCase.OAUTH2_AUTH_TOKEN: elif self is TestCase.OAUTH2_AUTH_TOKEN:
_oauth2_auth_token(stub, args) _oauth2_auth_token(stub, args)
elif self is TestCase.JWT_TOKEN_CREDS:
_jwt_token_creds(stub, args)
elif self is TestCase.PER_RPC_CREDS: elif self is TestCase.PER_RPC_CREDS:
_per_rpc_creds(stub, args) _per_rpc_creds(stub, args)
else: else:

@ -82,6 +82,7 @@ class BenchmarkClient:
self._response_callbacks = [] self._response_callbacks = []
def add_response_callback(self, callback): def add_response_callback(self, callback):
"""callback will be invoked as callback(client, query_time)"""
self._response_callbacks.append(callback) self._response_callbacks.append(callback)
@abc.abstractmethod @abc.abstractmethod
@ -95,10 +96,10 @@ class BenchmarkClient:
def stop(self): def stop(self):
pass pass
def _handle_response(self, query_time): def _handle_response(self, client, query_time):
self._hist.add(query_time * 1e9) # Report times in nanoseconds self._hist.add(query_time * 1e9) # Report times in nanoseconds
for callback in self._response_callbacks: for callback in self._response_callbacks:
callback(query_time) callback(client, query_time)
class UnarySyncBenchmarkClient(BenchmarkClient): class UnarySyncBenchmarkClient(BenchmarkClient):
@ -121,7 +122,7 @@ class UnarySyncBenchmarkClient(BenchmarkClient):
start_time = time.time() start_time = time.time()
self._stub.UnaryCall(self._request, _TIMEOUT) self._stub.UnaryCall(self._request, _TIMEOUT)
end_time = time.time() end_time = time.time()
self._handle_response(end_time - start_time) self._handle_response(self, end_time - start_time)
class UnaryAsyncBenchmarkClient(BenchmarkClient): class UnaryAsyncBenchmarkClient(BenchmarkClient):
@ -136,19 +137,20 @@ class UnaryAsyncBenchmarkClient(BenchmarkClient):
def _response_received(self, start_time, resp): def _response_received(self, start_time, resp):
resp.result() resp.result()
end_time = time.time() end_time = time.time()
self._handle_response(end_time - start_time) self._handle_response(self, end_time - start_time)
def stop(self): def stop(self):
self._stub = None self._stub = None
class StreamingSyncBenchmarkClient(BenchmarkClient): class _SyncStream(object):
def __init__(self, server, config, hist): def __init__(self, stub, generic, request, handle_response):
super(StreamingSyncBenchmarkClient, self).__init__(server, config, hist) self._stub = stub
self._generic = generic
self._request = request
self._handle_response = handle_response
self._is_streaming = False self._is_streaming = False
self._pool = futures.ThreadPoolExecutor(max_workers=1)
# Use a thread-safe queue to put requests on the stream
self._request_queue = queue.Queue() self._request_queue = queue.Queue()
self._send_time_queue = queue.Queue() self._send_time_queue = queue.Queue()
@ -157,15 +159,6 @@ class StreamingSyncBenchmarkClient(BenchmarkClient):
self._request_queue.put(self._request) self._request_queue.put(self._request)
def start(self): def start(self):
self._is_streaming = True
self._pool.submit(self._request_stream)
def stop(self):
self._is_streaming = False
self._pool.shutdown(wait=True)
self._stub = None
def _request_stream(self):
self._is_streaming = True self._is_streaming = True
if self._generic: if self._generic:
stream_callable = self._stub.stream_stream( stream_callable = self._stub.stream_stream(
@ -175,8 +168,11 @@ class StreamingSyncBenchmarkClient(BenchmarkClient):
response_stream = stream_callable(self._request_generator(), _TIMEOUT) response_stream = stream_callable(self._request_generator(), _TIMEOUT)
for _ in response_stream: for _ in response_stream:
end_time = time.time() self._handle_response(
self._handle_response(end_time - self._send_time_queue.get_nowait()) self, time.time() - self._send_time_queue.get_nowait())
def stop(self):
self._is_streaming = False
def _request_generator(self): def _request_generator(self):
while self._is_streaming: while self._is_streaming:
@ -187,46 +183,28 @@ class StreamingSyncBenchmarkClient(BenchmarkClient):
pass pass
class AsyncReceiver(face.ResponseReceiver): class StreamingSyncBenchmarkClient(BenchmarkClient):
"""Receiver for async stream responses."""
def __init__(self, send_time_queue, response_handler):
self._send_time_queue = send_time_queue
self._response_handler = response_handler
def initial_metadata(self, initial_mdetadata):
pass
def response(self, response):
end_time = time.time()
self._response_handler(end_time - self._send_time_queue.get_nowait())
def complete(self, terminal_metadata, code, details):
pass
class StreamingAsyncBenchmarkClient(BenchmarkClient):
def __init__(self, server, config, hist): def __init__(self, server, config, hist):
super(StreamingAsyncBenchmarkClient, self).__init__(server, config, hist) super(StreamingSyncBenchmarkClient, self).__init__(server, config, hist)
self._send_time_queue = queue.Queue() self._pool = futures.ThreadPoolExecutor(
self._receiver = AsyncReceiver(self._send_time_queue, self._handle_response) max_workers=config.outstanding_rpcs_per_channel)
self._rendezvous = None self._streams = [_SyncStream(self._stub, self._generic,
self._request, self._handle_response)
for _ in xrange(config.outstanding_rpcs_per_channel)]
self._curr_stream = 0
def send_request(self): def send_request(self):
if self._rendezvous is not None: # Use a round_robin scheduler to determine what stream to send on
self._send_time_queue.put(time.time()) self._streams[self._curr_stream].send_request()
self._rendezvous.consume(self._request) self._curr_stream = (self._curr_stream + 1) % len(self._streams)
def start(self): def start(self):
if self._generic: for stream in self._streams:
stream_callable = self._stub.stream_stream( self._pool.submit(stream.start)
'grpc.testing.BenchmarkService', 'StreamingCall')
else:
stream_callable = self._stub.StreamingCall
self._rendezvous = stream_callable.event(
self._receiver, lambda *args: None, _TIMEOUT)
def stop(self): def stop(self):
self._rendezvous.terminate() for stream in self._streams:
self._rendezvous = None stream.stop()
self._pool.shutdown(wait=True)
self._stub = None

@ -98,7 +98,6 @@ class ClosedLoopClientRunner(ClientRunner):
self._client.stop() self._client.stop()
self._client = None self._client = None
def _send_request(self, response_time): def _send_request(self, client, response_time):
if self._is_running: if self._is_running:
self._client.send_request() client.send_request()

@ -43,9 +43,7 @@ def run_worker_server(port):
server.add_insecure_port('[::]:{}'.format(port)) server.add_insecure_port('[::]:{}'.format(port))
server.start() server.start()
servicer.wait_for_quit() servicer.wait_for_quit()
# Drain outstanding requests for clean exit server.stop(2)
time.sleep(2)
server.stop(0)
if __name__ == '__main__': if __name__ == '__main__':

@ -153,9 +153,8 @@ class WorkerServer(services_pb2.BetaWorkerServiceServicer):
if config.rpc_type == control_pb2.UNARY: if config.rpc_type == control_pb2.UNARY:
client = benchmark_client.UnaryAsyncBenchmarkClient( client = benchmark_client.UnaryAsyncBenchmarkClient(
server, config, qps_data) server, config, qps_data)
elif config.rpc_type == control_pb2.STREAMING: else:
client = benchmark_client.StreamingAsyncBenchmarkClient( raise Exception('Async streaming client not supported')
server, config, qps_data)
else: else:
raise Exception('Unsupported client type {}'.format(config.client_type)) raise Exception('Unsupported client type {}'.format(config.client_type))

@ -55,8 +55,6 @@
namespace grpc { namespace grpc {
namespace testing { namespace testing {
static const char* kRandomFile = "test/cpp/interop/rnd.dat";
namespace { namespace {
// The same value is defined by the Java client. // The same value is defined by the Java client.
const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904}; const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
@ -67,30 +65,26 @@ const int kReceiveDelayMilliSeconds = 20;
const int kLargeRequestSize = 271828; const int kLargeRequestSize = 271828;
const int kLargeResponseSize = 314159; const int kLargeResponseSize = 314159;
CompressionType GetInteropCompressionTypeFromCompressionAlgorithm(
grpc_compression_algorithm algorithm) {
switch (algorithm) {
case GRPC_COMPRESS_NONE:
return CompressionType::NONE;
case GRPC_COMPRESS_GZIP:
return CompressionType::GZIP;
case GRPC_COMPRESS_DEFLATE:
return CompressionType::DEFLATE;
default:
GPR_ASSERT(false);
}
}
void NoopChecks(const InteropClientContextInspector& inspector, void NoopChecks(const InteropClientContextInspector& inspector,
const SimpleRequest* request, const SimpleResponse* response) {} const SimpleRequest* request, const SimpleResponse* response) {}
void CompressionChecks(const InteropClientContextInspector& inspector, void CompressionChecks(const InteropClientContextInspector& inspector,
const SimpleRequest* request, const SimpleRequest* request,
const SimpleResponse* response) { const SimpleResponse* response) {
GPR_ASSERT(request->response_compression() == const grpc_compression_algorithm received_compression =
GetInteropCompressionTypeFromCompressionAlgorithm( inspector.GetCallCompressionAlgorithm();
inspector.GetCallCompressionAlgorithm())); if (request->request_compressed_response() &&
if (request->response_compression() == NONE) { received_compression == GRPC_COMPRESS_NONE) {
if (request->request_compressed_response() &&
received_compression == GRPC_COMPRESS_NONE) {
// Requested some compression, got NONE. This is an error.
gpr_log(GPR_ERROR,
"Failure: Requested compression but got uncompressed response "
"from server.");
abort();
}
}
if (!request->request_compressed_response()) {
GPR_ASSERT(!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS)); GPR_ASSERT(!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS));
} else if (request->response_type() == PayloadType::COMPRESSABLE) { } else if (request->response_type() == PayloadType::COMPRESSABLE) {
// requested compression and compressable response => results should always // requested compression and compressable response => results should always
@ -211,20 +205,22 @@ bool InteropClient::PerformLargeUnary(SimpleRequest* request,
custom_checks_fn(inspector, request, response); custom_checks_fn(inspector, request, response);
// Payload related checks. // Payload related checks.
if (request->response_type() != PayloadType::RANDOM) { GPR_ASSERT(response->payload().type() == request->response_type());
GPR_ASSERT(response->payload().type() == request->response_type());
}
switch (response->payload().type()) { switch (response->payload().type()) {
case PayloadType::COMPRESSABLE: case PayloadType::COMPRESSABLE:
GPR_ASSERT(response->payload().body() == GPR_ASSERT(response->payload().body() ==
grpc::string(kLargeResponseSize, '\0')); grpc::string(kLargeResponseSize, '\0'));
break; break;
case PayloadType::UNCOMPRESSABLE: { case PayloadType::UNCOMPRESSABLE: {
std::ifstream rnd_file(kRandomFile); // We don't really check anything: We can't assert that the payload is
GPR_ASSERT(rnd_file.good()); // uncompressed because it's the server's prerogative to decide on that,
for (int i = 0; i < kLargeResponseSize; i++) { // and different implementations decide differently (ie, Java always
GPR_ASSERT(response->payload().body()[i] == (char)rnd_file.get()); // compresses when requested to do so, whereas C core throws away the
} // compressed payload if the output is larger than the input).
// In addition, we don't compare the actual random bytes received because
// asserting that data is sent/received properly isn't the purpose of this
// test. Moreover, different implementations are also free to use
// different sets of random bytes.
} break; } break;
default: default:
GPR_ASSERT(false); GPR_ASSERT(false);
@ -341,13 +337,13 @@ bool InteropClient::DoLargeUnary() {
} }
bool InteropClient::DoLargeCompressedUnary() { bool InteropClient::DoLargeCompressedUnary() {
const CompressionType compression_types[] = {NONE, GZIP, DEFLATE}; const bool request_compression[] = {false, true};
const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE, RANDOM}; const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE};
for (size_t i = 0; i < GPR_ARRAY_SIZE(payload_types); i++) { for (size_t i = 0; i < GPR_ARRAY_SIZE(payload_types); i++) {
for (size_t j = 0; j < GPR_ARRAY_SIZE(compression_types); j++) { for (size_t j = 0; j < GPR_ARRAY_SIZE(request_compression); j++) {
char* log_suffix; char* log_suffix;
gpr_asprintf(&log_suffix, "(compression=%s; payload=%s)", gpr_asprintf(&log_suffix, "(compression=%s; payload=%s)",
CompressionType_Name(compression_types[j]).c_str(), request_compression[j] ? "true" : "false",
PayloadType_Name(payload_types[i]).c_str()); PayloadType_Name(payload_types[i]).c_str());
gpr_log(GPR_DEBUG, "Sending a large compressed unary rpc %s.", gpr_log(GPR_DEBUG, "Sending a large compressed unary rpc %s.",
@ -355,7 +351,7 @@ bool InteropClient::DoLargeCompressedUnary() {
SimpleRequest request; SimpleRequest request;
SimpleResponse response; SimpleResponse response;
request.set_response_type(payload_types[i]); request.set_response_type(payload_types[i]);
request.set_response_compression(compression_types[j]); request.set_request_compressed_response(request_compression[j]);
if (!PerformLargeUnary(&request, &response, CompressionChecks)) { if (!PerformLargeUnary(&request, &response, CompressionChecks)) {
gpr_log(GPR_ERROR, "Large compressed unary failed %s", log_suffix); gpr_log(GPR_ERROR, "Large compressed unary failed %s", log_suffix);
@ -452,23 +448,23 @@ bool InteropClient::DoResponseStreaming() {
} }
bool InteropClient::DoResponseCompressedStreaming() { bool InteropClient::DoResponseCompressedStreaming() {
const CompressionType compression_types[] = {NONE, GZIP, DEFLATE}; const bool request_compression[] = {false, true};
const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE, RANDOM}; const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE};
for (size_t i = 0; i < GPR_ARRAY_SIZE(payload_types); i++) { for (size_t i = 0; i < GPR_ARRAY_SIZE(payload_types); i++) {
for (size_t j = 0; j < GPR_ARRAY_SIZE(compression_types); j++) { for (size_t j = 0; j < GPR_ARRAY_SIZE(request_compression); j++) {
ClientContext context; ClientContext context;
InteropClientContextInspector inspector(context); InteropClientContextInspector inspector(context);
StreamingOutputCallRequest request; StreamingOutputCallRequest request;
char* log_suffix; char* log_suffix;
gpr_asprintf(&log_suffix, "(compression=%s; payload=%s)", gpr_asprintf(&log_suffix, "(compression=%s; payload=%s)",
CompressionType_Name(compression_types[j]).c_str(), request_compression[j] ? "true" : "false",
PayloadType_Name(payload_types[i]).c_str()); PayloadType_Name(payload_types[i]).c_str());
gpr_log(GPR_DEBUG, "Receiving response streaming rpc %s.", log_suffix); gpr_log(GPR_DEBUG, "Receiving response streaming rpc %s.", log_suffix);
request.set_response_type(payload_types[i]); request.set_response_type(payload_types[i]);
request.set_response_compression(compression_types[j]); request.set_request_compressed_response(request_compression[j]);
for (size_t k = 0; k < response_stream_sizes.size(); ++k) { for (size_t k = 0; k < response_stream_sizes.size(); ++k) {
ResponseParameters* response_parameter = ResponseParameters* response_parameter =
@ -483,37 +479,32 @@ bool InteropClient::DoResponseCompressedStreaming() {
size_t k = 0; size_t k = 0;
while (stream->Read(&response)) { while (stream->Read(&response)) {
// Payload related checks. // Payload related checks.
if (request.response_type() != PayloadType::RANDOM) { GPR_ASSERT(response.payload().type() == request.response_type());
GPR_ASSERT(response.payload().type() == request.response_type());
}
switch (response.payload().type()) { switch (response.payload().type()) {
case PayloadType::COMPRESSABLE: case PayloadType::COMPRESSABLE:
GPR_ASSERT(response.payload().body() == GPR_ASSERT(response.payload().body() ==
grpc::string(response_stream_sizes[k], '\0')); grpc::string(response_stream_sizes[k], '\0'));
break; break;
case PayloadType::UNCOMPRESSABLE: { case PayloadType::UNCOMPRESSABLE:
std::ifstream rnd_file(kRandomFile); break;
GPR_ASSERT(rnd_file.good());
for (int n = 0; n < response_stream_sizes[k]; n++) {
GPR_ASSERT(response.payload().body()[n] == (char)rnd_file.get());
}
} break;
default: default:
GPR_ASSERT(false); GPR_ASSERT(false);
} }
// Compression related checks. // Compression related checks.
GPR_ASSERT(request.response_compression() == if (request.request_compressed_response()) {
GetInteropCompressionTypeFromCompressionAlgorithm( GPR_ASSERT(inspector.GetCallCompressionAlgorithm() >
inspector.GetCallCompressionAlgorithm())); GRPC_COMPRESS_NONE);
if (request.response_compression() == NONE) { if (request.response_type() == PayloadType::COMPRESSABLE) {
// requested compression and compressable response => results should
// always be compressed.
GPR_ASSERT(inspector.GetMessageFlags() &
GRPC_WRITE_INTERNAL_COMPRESS);
}
} else {
// requested *no* compression.
GPR_ASSERT( GPR_ASSERT(
!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS)); !(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS));
} else if (request.response_type() == PayloadType::COMPRESSABLE) {
// requested compression and compressable response => results should
// always be compressed.
GPR_ASSERT(inspector.GetMessageFlags() &
GRPC_WRITE_INTERNAL_COMPRESS);
} }
++k; ++k;

@ -110,14 +110,7 @@ void MaybeEchoMetadata(ServerContext* context) {
} }
} }
bool SetPayload(PayloadType type, int size, Payload* payload) { bool SetPayload(PayloadType response_type, int size, Payload* payload) {
PayloadType response_type;
if (type == PayloadType::RANDOM) {
response_type =
rand() & 0x1 ? PayloadType::COMPRESSABLE : PayloadType::UNCOMPRESSABLE;
} else {
response_type = type;
}
payload->set_type(response_type); payload->set_type(response_type);
switch (response_type) { switch (response_type) {
case PayloadType::COMPRESSABLE: { case PayloadType::COMPRESSABLE: {
@ -141,18 +134,9 @@ bool SetPayload(PayloadType type, int size, Payload* payload) {
template <typename RequestType> template <typename RequestType>
void SetResponseCompression(ServerContext* context, void SetResponseCompression(ServerContext* context,
const RequestType& request) { const RequestType& request) {
switch (request.response_compression()) { if (request.request_compressed_response()) {
case grpc::testing::NONE: // Any level would do, let's go for HIGH because we are overachievers.
context->set_compression_algorithm(GRPC_COMPRESS_NONE); context->set_compression_level(GRPC_COMPRESS_LEVEL_HIGH);
break;
case grpc::testing::GZIP:
context->set_compression_algorithm(GRPC_COMPRESS_GZIP);
break;
case grpc::testing::DEFLATE:
context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
break;
default:
abort();
} }
} }

@ -770,6 +770,7 @@ include/grpc++/generic/generic_stub.h \
include/grpc++/grpc++.h \ include/grpc++/grpc++.h \
include/grpc++/impl/call.h \ include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \ include/grpc++/impl/grpc_library.h \
include/grpc++/impl/method_handler_impl.h \ include/grpc++/impl/method_handler_impl.h \
include/grpc++/impl/rpc_method.h \ include/grpc++/impl/rpc_method.h \

@ -770,6 +770,7 @@ include/grpc++/generic/generic_stub.h \
include/grpc++/grpc++.h \ include/grpc++/grpc++.h \
include/grpc++/impl/call.h \ include/grpc++/impl/call.h \
include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/client_unary_call.h \
include/grpc++/impl/codegen/core_codegen.h \
include/grpc++/impl/grpc_library.h \ include/grpc++/impl/grpc_library.h \
include/grpc++/impl/method_handler_impl.h \ include/grpc++/impl/method_handler_impl.h \
include/grpc++/impl/rpc_method.h \ include/grpc++/impl/rpc_method.h \
@ -855,8 +856,8 @@ include/grpc/impl/codegen/sync_generic.h \
include/grpc/impl/codegen/sync_posix.h \ include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \ include/grpc/impl/codegen/sync_windows.h \
include/grpc/impl/codegen/time.h \ include/grpc/impl/codegen/time.h \
include/grpc++/impl/codegen/core_codegen.h \
src/cpp/client/secure_credentials.h \ src/cpp/client/secure_credentials.h \
src/cpp/common/core_codegen.h \
src/cpp/common/secure_auth_context.h \ src/cpp/common/secure_auth_context.h \
src/cpp/server/secure_server_credentials.h \ src/cpp/server/secure_server_credentials.h \
src/cpp/client/create_channel_internal.h \ src/cpp/client/create_channel_internal.h \

File diff suppressed because it is too large Load Diff

@ -395,8 +395,8 @@ class PythonLanguage:
# categories=[SMOKETEST]) # categories=[SMOKETEST])
yield _ping_pong_scenario( yield _ping_pong_scenario(
'python_protobuf_async_streaming_ping_pong', rpc_type='STREAMING', 'python_protobuf_sync_streaming_ping_pong', rpc_type='STREAMING',
client_type='ASYNC_CLIENT', server_type='SYNC_SERVER') client_type='SYNC_CLIENT', server_type='SYNC_SERVER')
yield _ping_pong_scenario( yield _ping_pong_scenario(
'python_protobuf_async_unary_ping_pong', rpc_type='UNARY', 'python_protobuf_async_unary_ping_pong', rpc_type='UNARY',
@ -413,9 +413,9 @@ class PythonLanguage:
unconstrained_client='sync') unconstrained_client='sync')
yield _ping_pong_scenario( yield _ping_pong_scenario(
'python_protobuf_async_streaming_qps_unconstrained', rpc_type='STREAMING', 'python_protobuf_sync_streaming_qps_unconstrained', rpc_type='STREAMING',
client_type='ASYNC_CLIENT', server_type='SYNC_SERVER', client_type='SYNC_CLIENT', server_type='SYNC_SERVER',
unconstrained_client='async') unconstrained_client='sync')
yield _ping_pong_scenario( yield _ping_pong_scenario(
'python_to_cpp_protobuf_sync_unary_ping_pong', rpc_type='UNARY', 'python_to_cpp_protobuf_sync_unary_ping_pong', rpc_type='UNARY',

@ -317,7 +317,7 @@ class PythonLanguage:
'PYTHONPATH': '{}/src/python/gens'.format(DOCKER_WORKDIR_ROOT)} 'PYTHONPATH': '{}/src/python/gens'.format(DOCKER_WORKDIR_ROOT)}
def unimplemented_test_cases(self): def unimplemented_test_cases(self):
return _SKIP_ADVANCED + _SKIP_COMPRESSION + ['jwt_token_creds'] return _SKIP_ADVANCED + _SKIP_COMPRESSION
def unimplemented_test_cases_server(self): def unimplemented_test_cases_server(self):
return _SKIP_ADVANCED + _SKIP_COMPRESSION return _SKIP_ADVANCED + _SKIP_COMPRESSION

@ -4261,18 +4261,18 @@
"grpc++_codegen_base_src" "grpc++_codegen_base_src"
], ],
"headers": [ "headers": [
"include/grpc++/impl/codegen/core_codegen.h",
"src/cpp/client/secure_credentials.h", "src/cpp/client/secure_credentials.h",
"src/cpp/common/core_codegen.h",
"src/cpp/common/secure_auth_context.h", "src/cpp/common/secure_auth_context.h",
"src/cpp/server/secure_server_credentials.h" "src/cpp/server/secure_server_credentials.h"
], ],
"language": "c++", "language": "c++",
"name": "grpc++", "name": "grpc++",
"src": [ "src": [
"include/grpc++/impl/codegen/core_codegen.h",
"src/cpp/client/secure_credentials.cc", "src/cpp/client/secure_credentials.cc",
"src/cpp/client/secure_credentials.h", "src/cpp/client/secure_credentials.h",
"src/cpp/common/auth_property_iterator.cc", "src/cpp/common/auth_property_iterator.cc",
"src/cpp/common/core_codegen.h",
"src/cpp/common/secure_auth_context.cc", "src/cpp/common/secure_auth_context.cc",
"src/cpp/common/secure_auth_context.h", "src/cpp/common/secure_auth_context.h",
"src/cpp/common/secure_channel_arguments.cc", "src/cpp/common/secure_channel_arguments.cc",
@ -6405,6 +6405,7 @@
"include/grpc++/grpc++.h", "include/grpc++/grpc++.h",
"include/grpc++/impl/call.h", "include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h", "include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/codegen/core_codegen.h",
"include/grpc++/impl/grpc_library.h", "include/grpc++/impl/grpc_library.h",
"include/grpc++/impl/method_handler_impl.h", "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/rpc_method.h", "include/grpc++/impl/rpc_method.h",
@ -6440,7 +6441,6 @@
"include/grpc++/support/sync_stream.h", "include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h", "include/grpc++/support/time.h",
"src/cpp/client/create_channel_internal.h", "src/cpp/client/create_channel_internal.h",
"src/cpp/common/core_codegen.h",
"src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/dynamic_thread_pool.h",
"src/cpp/server/thread_pool_interface.h" "src/cpp/server/thread_pool_interface.h"
], ],
@ -6457,6 +6457,7 @@
"include/grpc++/grpc++.h", "include/grpc++/grpc++.h",
"include/grpc++/impl/call.h", "include/grpc++/impl/call.h",
"include/grpc++/impl/client_unary_call.h", "include/grpc++/impl/client_unary_call.h",
"include/grpc++/impl/codegen/core_codegen.h",
"include/grpc++/impl/grpc_library.h", "include/grpc++/impl/grpc_library.h",
"include/grpc++/impl/method_handler_impl.h", "include/grpc++/impl/method_handler_impl.h",
"include/grpc++/impl/rpc_method.h", "include/grpc++/impl/rpc_method.h",
@ -6502,7 +6503,6 @@
"src/cpp/common/channel_arguments.cc", "src/cpp/common/channel_arguments.cc",
"src/cpp/common/completion_queue.cc", "src/cpp/common/completion_queue.cc",
"src/cpp/common/core_codegen.cc", "src/cpp/common/core_codegen.cc",
"src/cpp/common/core_codegen.h",
"src/cpp/common/rpc_method.cc", "src/cpp/common/rpc_method.cc",
"src/cpp/server/async_generic_service.cc", "src/cpp/server/async_generic_service.cc",
"src/cpp/server/create_default_thread_pool.cc", "src/cpp/server/create_default_thread_pool.cc",

@ -268,6 +268,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h" />
@ -355,8 +356,8 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h" /> <ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\secure_auth_context.h" /> <ClInclude Include="$(SolutionDir)\..\src\cpp\common\secure_auth_context.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\secure_server_credentials.h" /> <ClInclude Include="$(SolutionDir)\..\src\cpp\server\secure_server_credentials.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" /> <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />

@ -126,6 +126,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h"> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h">
<Filter>include\grpc++\impl</Filter> <Filter>include\grpc++\impl</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h">
<Filter>include\grpc++\impl\codegen</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h"> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h">
<Filter>include\grpc++\impl</Filter> <Filter>include\grpc++\impl</Filter>
</ClInclude> </ClInclude>
@ -383,12 +386,12 @@
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h">
<Filter>include\grpc++\impl\codegen</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h"> <ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h">
<Filter>src\cpp\client</Filter> <Filter>src\cpp\client</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h">
<Filter>src\cpp\common</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\secure_auth_context.h"> <ClInclude Include="$(SolutionDir)\..\src\cpp\common\secure_auth_context.h">
<Filter>src\cpp\common</Filter> <Filter>src\cpp\common</Filter>
</ClInclude> </ClInclude>

@ -268,6 +268,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h" />
@ -356,7 +357,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" /> <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" /> <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" /> <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
</ItemGroup> </ItemGroup>

@ -111,6 +111,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h"> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h">
<Filter>include\grpc++\impl</Filter> <Filter>include\grpc++\impl</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h">
<Filter>include\grpc++\impl\codegen</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h"> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h">
<Filter>include\grpc++\impl</Filter> <Filter>include\grpc++\impl</Filter>
</ClInclude> </ClInclude>
@ -371,9 +374,6 @@
<ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h"> <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h">
<Filter>src\cpp\client</Filter> <Filter>src\cpp\client</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h">
<Filter>src\cpp\common</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h"> <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h">
<Filter>src\cpp\server</Filter> <Filter>src\cpp\server</Filter>
</ClInclude> </ClInclude>

Loading…
Cancel
Save