Merge branch 'master' of https://github.com/grpc/grpc into the-purge-2
Conflicts: test/cpp/end2end/async_end2end_test.cc test/cpp/end2end/end2end_test.cc test/cpp/interop/client.ccpull/1227/head
commit
b7c2035e83
88 changed files with 4427 additions and 1246 deletions
@ -0,0 +1,685 @@ |
|||||||
|
Interoperability Test Case Descriptions |
||||||
|
======================================= |
||||||
|
|
||||||
|
Client and server use |
||||||
|
[test.proto](https://github.com/grpc/grpc/blob/master/test/cpp/interop/test.proto) |
||||||
|
and the [gRPC over HTTP/2 v2 |
||||||
|
protocol](https://github.com/grpc/grpc-common/blob/master/PROTOCOL-HTTP2.md). |
||||||
|
|
||||||
|
Client |
||||||
|
------ |
||||||
|
|
||||||
|
Clients implement test cases that test certain functionally. Each client is |
||||||
|
provided the test case it is expected to run as a command-line parameter. Names |
||||||
|
should be lowercase and without spaces. |
||||||
|
|
||||||
|
Clients should accept these arguments: |
||||||
|
* --server_host=HOSTNAME |
||||||
|
* The server host to connect to. For example, "localhost" or "127.0.0.1" |
||||||
|
* --server_host_override=HOSTNAME |
||||||
|
* The server host to claim to be connecting to, for use in TLS and HTTP/2 |
||||||
|
:authority header. If unspecified, the value of --server_host will be |
||||||
|
used |
||||||
|
* --server_port=PORT |
||||||
|
* The server port to connect to. For example, "8080" |
||||||
|
* --test_case=TESTCASE |
||||||
|
* The name of the test case to execute. For example, "empty_unary" |
||||||
|
* --use_tls=BOOLEAN |
||||||
|
* Whether to use a plaintext or encrypted connection |
||||||
|
* --use_test_ca=BOOLEAN |
||||||
|
* Whether to replace platform root CAs with |
||||||
|
[ca.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/ca.pem) |
||||||
|
as the CA root |
||||||
|
|
||||||
|
Clients must support TLS with ALPN. Clients must not disable certificate |
||||||
|
checking. |
||||||
|
|
||||||
|
### empty_unary |
||||||
|
|
||||||
|
This test verifies that implementations support zero-size messages. Ideally, |
||||||
|
client implementations would verify that the request and response were zero |
||||||
|
bytes serialized, but this is generally prohibitive to perform, so is not |
||||||
|
required. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [EmptyCall][] |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client calls EmptyCall with the default Empty message |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* response is non-null |
||||||
|
|
||||||
|
*It may be possible to use UnaryCall instead of EmptyCall, but it is harder to |
||||||
|
ensure that the proto serialized to zero bytes.* |
||||||
|
|
||||||
|
### large_unary |
||||||
|
|
||||||
|
This test verifies unary calls succeed in sending messages, and touches on flow |
||||||
|
control (even if compression is enabled on the channel). |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [UnaryCall][] |
||||||
|
* [Compressable Payload][] |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client calls UnaryCall with: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_size: 314159 |
||||||
|
payload:{ |
||||||
|
body: 271828 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* response payload type is COMPRESSABLE |
||||||
|
* response payload body is 314159 bytes in size |
||||||
|
* clients are free to assert that the response payload body contents are zero |
||||||
|
and comparing the entire response message against a golden response |
||||||
|
|
||||||
|
### client_streaming |
||||||
|
|
||||||
|
This test verifies that client-only streaming succeeds. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [StreamingInputCall][] |
||||||
|
* [Compressable Payload][] |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client calls StreamingInputCall |
||||||
|
2. Client sends: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
payload:{ |
||||||
|
body: 27182 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
3. Client then sends: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
payload:{ |
||||||
|
body: 8 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
4. Client then sends: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
payload:{ |
||||||
|
body: 1828 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
5. Client then sends: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
payload:{ |
||||||
|
body: 45904 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
6. Client halfCloses |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* response aggregated_payload_size is 74922 |
||||||
|
|
||||||
|
### server_streaming |
||||||
|
|
||||||
|
This test verifies that server-only streaming succeeds. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [StreamingOutputCall][] |
||||||
|
* [Compressable Payload][] |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client calls StreamingOutputCall with: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type:COMPRESSABLE |
||||||
|
response_parameters:{ |
||||||
|
size: 31415 |
||||||
|
} |
||||||
|
response_parameters:{ |
||||||
|
size: 9 |
||||||
|
} |
||||||
|
response_parameters:{ |
||||||
|
size: 2653 |
||||||
|
} |
||||||
|
response_parameters:{ |
||||||
|
size: 58979 |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* exactly four responses |
||||||
|
* response payloads are COMPRESSABLE |
||||||
|
* response payload bodies are sized (in order): 31415, 9, 2653, 58979 |
||||||
|
* clients are free to assert that the response payload body contents are zero |
||||||
|
and comparing the entire response messages against golden responses |
||||||
|
|
||||||
|
### ping_pong |
||||||
|
|
||||||
|
This test verifies that full duplex bidi is supported. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [FullDuplexCall][] |
||||||
|
* [Compressable Payload][] |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client calls FullDuplexCall with: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_parameters:{ |
||||||
|
size: 31415 |
||||||
|
} |
||||||
|
payload:{ |
||||||
|
body: 27182 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
2. After getting a reply, it sends: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_parameters:{ |
||||||
|
size: 9 |
||||||
|
} |
||||||
|
payload:{ |
||||||
|
body: 8 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
3. After getting a reply, it sends: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_parameters:{ |
||||||
|
size: 2653 |
||||||
|
} |
||||||
|
payload:{ |
||||||
|
body: 1828 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
4. After getting a reply, it sends: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_parameters:{ |
||||||
|
size: 58979 |
||||||
|
} |
||||||
|
payload:{ |
||||||
|
body: 45904 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* exactly four responses |
||||||
|
* response payloads are COMPRESSABLE |
||||||
|
* response payload bodies are sized (in order): 31415, 9, 2653, 58979 |
||||||
|
* clients are free to assert that the response payload body contents are zero |
||||||
|
and comparing the entire response messages against golden responses |
||||||
|
|
||||||
|
### empty_stream |
||||||
|
|
||||||
|
This test verifies that streams support having zero-messages in both |
||||||
|
directions. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [FullDuplexCall][] |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client calls FullDuplexCall and then half-closes |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* exactly zero responses |
||||||
|
|
||||||
|
### compute_engine_creds |
||||||
|
|
||||||
|
Status: Not yet implementable |
||||||
|
|
||||||
|
This test is only for cloud-to-prod path. |
||||||
|
|
||||||
|
This test verifies unary calls succeed in sending messages while using Service |
||||||
|
Credentials from GCE metadata server. The client instance needs to be created |
||||||
|
with desired oauth scope. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [UnaryCall][] |
||||||
|
* [Compressable Payload][] |
||||||
|
* SimpeResponse.username |
||||||
|
* SimpleResponse.oauth_scope |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client sets flags default_service_account with GCE service account name and |
||||||
|
oauth_scope with the oauth scope to use. |
||||||
|
2. Client configures channel to use GCECredentials |
||||||
|
3. Client calls UnaryCall on the channel with: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_size: 314159 |
||||||
|
payload:{ |
||||||
|
body: 271828 bytes of zeros |
||||||
|
} |
||||||
|
fill_username: true |
||||||
|
fill_oauth_scope: true |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* received SimpleResponse.username equals FLAGS_default_service_account |
||||||
|
* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope |
||||||
|
* response payload body is 314159 bytes in size |
||||||
|
* clients are free to assert that the response payload body contents are zero |
||||||
|
and comparing the entire response message against a golden response |
||||||
|
|
||||||
|
### service_account_creds |
||||||
|
|
||||||
|
Status: Not yet implementable |
||||||
|
|
||||||
|
This test is only for cloud-to-prod path. |
||||||
|
|
||||||
|
This test verifies unary calls succeed in sending messages while using JWT |
||||||
|
signing keys (redeemed for OAuth2 access tokens by the auth implementation) |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [UnaryCall][] |
||||||
|
* [Compressable Payload][] |
||||||
|
* SimpleResponse.username |
||||||
|
* SimpleResponse.oauth_scope |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client sets flags service_account_key_file with the path to json key file, |
||||||
|
oauth_scope to the oauth scope. |
||||||
|
2. Client configures the channel to use ServiceAccountCredentials. |
||||||
|
3. Client calls UnaryCall with: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_size: 314159 |
||||||
|
payload:{ |
||||||
|
body: 271828 bytes of zeros |
||||||
|
} |
||||||
|
fill_username: true |
||||||
|
fill_oauth_scope: true |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* received SimpleResponse.username is in the json key file read from |
||||||
|
FLAGS_service_account_key_file |
||||||
|
* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope |
||||||
|
* response payload body is 314159 bytes in size |
||||||
|
* clients are free to assert that the response payload body contents are zero |
||||||
|
and comparing the entire response message against a golden response |
||||||
|
|
||||||
|
### jwt_token_creds |
||||||
|
|
||||||
|
Status: Not yet implementable |
||||||
|
|
||||||
|
This test is only for cloud-to-prod path. |
||||||
|
|
||||||
|
This test verifies unary calls succeed in sending messages while using JWT |
||||||
|
token (created by the project's key file) |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [UnaryCall][] |
||||||
|
* [Compressable Payload][] |
||||||
|
* SimpleResponse.username |
||||||
|
* SimpleResponse.oauth_scope |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client sets flags service_account_key_file with the path to json key file |
||||||
|
2. Client configures the channel to use JWTTokenCredentials. |
||||||
|
3. Client calls UnaryCall with: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_size: 314159 |
||||||
|
payload:{ |
||||||
|
body: 271828 bytes of zeros |
||||||
|
} |
||||||
|
fill_username: true |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* received SimpleResponse.username is in the json key file read from |
||||||
|
FLAGS_service_account_key_file |
||||||
|
* response payload body is 314159 bytes in size |
||||||
|
* clients are free to assert that the response payload body contents are zero |
||||||
|
and comparing the entire response message against a golden response |
||||||
|
|
||||||
|
### Metadata (TODO: fix name) |
||||||
|
|
||||||
|
Status: Not yet implementable |
||||||
|
|
||||||
|
This test verifies that custom metadata in either binary or ascii format can be |
||||||
|
sent in header and trailer. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [UnaryCall][] |
||||||
|
* [Compressable Payload][] |
||||||
|
* Ability to receive custom metadata from client in header and send custom data |
||||||
|
back to client in both header and trailer. (TODO: this is not defined) |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. While sending custom metadata (ascii + binary) in the header, client calls UnaryCall with: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_size: 314159 |
||||||
|
payload:{ |
||||||
|
body: 271828 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* call was successful |
||||||
|
* custom metadata is echoed back in the response header. |
||||||
|
* custom metadata is echoed back in the response trailer. |
||||||
|
|
||||||
|
### status_code_and_message |
||||||
|
|
||||||
|
Status: Not yet implementable |
||||||
|
|
||||||
|
This test verifies unary calls succeed in sending messages, and propagates back |
||||||
|
status code and message sent along with the messages. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [UnaryCall][] |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client calls UnaryCall with: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_status:{ |
||||||
|
code: 2 |
||||||
|
message: "test status message" |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* received status code is the same with sent code |
||||||
|
* received status message is the same with sent message |
||||||
|
|
||||||
|
### unimplemented_method |
||||||
|
|
||||||
|
Status: Not yet implementable |
||||||
|
|
||||||
|
This test verifies calling unimplemented RPC method returns unimplemented |
||||||
|
status. |
||||||
|
|
||||||
|
Procedure: |
||||||
|
* Client calls UnimplementedCall with: |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_size: 314159 |
||||||
|
payload:{ |
||||||
|
body: 271828 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* received status code is 12 (UNIMPLEMENTED) |
||||||
|
* received status message is empty or null/unset |
||||||
|
|
||||||
|
### cancel_after_begin |
||||||
|
|
||||||
|
This test verifies that a request can be cancelled after metadata has been sent |
||||||
|
but before payloads are sent. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [StreamingInputCall][] |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client starts StreamingInputCall |
||||||
|
2. Client immediately cancels request |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* Call completed with status CANCELLED |
||||||
|
|
||||||
|
### cancel_after_first_response |
||||||
|
|
||||||
|
This test verifies that a request can be cancelled after receiving a message |
||||||
|
from the server. |
||||||
|
|
||||||
|
Server features: |
||||||
|
* [FullDuplexCall][] |
||||||
|
* [Compressable Payload][] |
||||||
|
|
||||||
|
Procedure: |
||||||
|
1. Client starts FullDuplexCall with |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
response_type: COMPRESSABLE |
||||||
|
response_parameters:{ |
||||||
|
size: 31415 |
||||||
|
} |
||||||
|
payload:{ |
||||||
|
body: 27182 bytes of zeros |
||||||
|
} |
||||||
|
} |
||||||
|
``` |
||||||
|
2. After receiving a response, client cancels request |
||||||
|
|
||||||
|
Asserts: |
||||||
|
* Call completed with status CANCELLED |
||||||
|
|
||||||
|
### concurrent_large_unary |
||||||
|
|
||||||
|
Status: TODO |
||||||
|
|
||||||
|
Client performs 1000 large_unary tests in parallel on the same channel. |
||||||
|
|
||||||
|
### Flow control. Pushback at client for large messages (TODO: fix name) |
||||||
|
|
||||||
|
Status: TODO |
||||||
|
|
||||||
|
This test verifies that a client sending faster than a server can drain sees |
||||||
|
pushback (i.e., attempts to send succeed only after appropriate delays). |
||||||
|
|
||||||
|
### TODO Tests |
||||||
|
|
||||||
|
High priority: |
||||||
|
|
||||||
|
Propagation of status code and message (yangg) |
||||||
|
|
||||||
|
Cancel after sent headers (ctiller - done) |
||||||
|
|
||||||
|
Cancel after received first message (ctiller - done) |
||||||
|
|
||||||
|
Timeout after expire (zhaoq) |
||||||
|
|
||||||
|
Zero-message streams (ejona) |
||||||
|
|
||||||
|
Multiple thousand simultaneous calls on same Channel (ctiller - done) |
||||||
|
|
||||||
|
OAuth2 tokens + Service Credentials from GCE metadata server (GCE->prod only) |
||||||
|
(abhishek) |
||||||
|
|
||||||
|
OAuth2 tokens + JWT signing key (GCE->prod only) (abhishek) |
||||||
|
|
||||||
|
Metadata: client headers, server headers + trailers, binary+ascii (chenw) |
||||||
|
|
||||||
|
Normal priority: |
||||||
|
|
||||||
|
Cancel before start (ctiller) |
||||||
|
|
||||||
|
Cancel after sent first message (ctiller) |
||||||
|
|
||||||
|
Cancel after received headers (ctiller) |
||||||
|
|
||||||
|
Timeout but completed before expire (zhaoq) |
||||||
|
|
||||||
|
Multiple thousand simultaneous calls timeout on same Channel (ctiller) |
||||||
|
|
||||||
|
Lower priority: |
||||||
|
|
||||||
|
Flow control. Pushback at client for large messages (abhishek) |
||||||
|
|
||||||
|
Flow control. Pushback at server for large messages (abhishek) |
||||||
|
|
||||||
|
Going over max concurrent streams doesn't fail (client controls itself) |
||||||
|
(abhishek) |
||||||
|
|
||||||
|
RPC method not implemented (yangg) |
||||||
|
|
||||||
|
Multiple thousand simultaneous calls on different Channels (ctiller) |
||||||
|
|
||||||
|
Failed TLS hostname verification (ejona?) |
||||||
|
|
||||||
|
To priorize: |
||||||
|
|
||||||
|
Start streaming RPC but don't send any requests, server responds |
||||||
|
|
||||||
|
### Postponed Tests |
||||||
|
|
||||||
|
Resilience to buggy servers: These tests would verify that a client application |
||||||
|
isn't affected negatively by the responses put on the wire by a buggy server |
||||||
|
(e.g. the client library won't make the application crash). |
||||||
|
|
||||||
|
Reconnect after transport failure |
||||||
|
|
||||||
|
Reconnect backoff |
||||||
|
|
||||||
|
Fuzz testing |
||||||
|
|
||||||
|
|
||||||
|
Server |
||||||
|
------ |
||||||
|
|
||||||
|
Servers implement various named features for clients to test with. Server |
||||||
|
features are orthogonal. If a server implements a feature, it is always |
||||||
|
available for clients. Names are simple descriptions for developer |
||||||
|
communication and tracking. |
||||||
|
|
||||||
|
Servers should accept these arguments: |
||||||
|
|
||||||
|
* --port=PORT |
||||||
|
|
||||||
|
* The port to listen on. For example, "8080" |
||||||
|
|
||||||
|
* --use_tls=BOOLEAN |
||||||
|
|
||||||
|
* Whether to use a plaintext or encrypted connection |
||||||
|
|
||||||
|
Servers must support TLS with ALPN. They should use |
||||||
|
[server1.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/server1.pem) |
||||||
|
for their certificate. |
||||||
|
|
||||||
|
### EmptyCall |
||||||
|
[EmptyCall]: #emptycall |
||||||
|
|
||||||
|
Server implements EmptyCall which immediately returns the empty message. |
||||||
|
|
||||||
|
### UnaryCall |
||||||
|
[UnaryCall]: #unarycall |
||||||
|
|
||||||
|
Server implements UnaryCall which immediately returns a SimpleResponse with a |
||||||
|
payload body of size SimpleRequest.response_size bytes and type as appropriate |
||||||
|
for the SimpleRequest.response_type. If the server does not support the |
||||||
|
response_type, then it should fail the RPC with INVALID_ARGUMENT. |
||||||
|
|
||||||
|
If the request sets fill_username, the server should return the client username |
||||||
|
it sees in field SimpleResponse.username. If the request sets fill_oauth_scope, |
||||||
|
the server should return the oauth scope of the rpc in the form of "xapi_zoo" |
||||||
|
in field SimpleResponse.oauth_scope. |
||||||
|
|
||||||
|
### StreamingInputCall |
||||||
|
[StreamingInputCall]: #streaminginputcall |
||||||
|
|
||||||
|
Server implements StreamingInputCall which upon half close immediately returns |
||||||
|
a StreamingInputCallResponse where aggregated_payload_size is the sum of all |
||||||
|
request payload bodies received. |
||||||
|
|
||||||
|
### StreamingOutputCall |
||||||
|
[StreamingOutputCall]: #streamingoutputcall |
||||||
|
|
||||||
|
Server implements StreamingOutputCall by replying, in order, with one |
||||||
|
StreamingOutputCallResponses for each ResponseParameters in |
||||||
|
StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a |
||||||
|
payload body of size ResponseParameters.size bytes, as specified by its |
||||||
|
respective ResponseParameters. After sending all responses, it closes with OK. |
||||||
|
|
||||||
|
### FullDuplexCall |
||||||
|
[FullDuplexCall]: #fullduplexcall |
||||||
|
|
||||||
|
Server implements FullDuplexCall by replying, in order, with one |
||||||
|
StreamingOutputCallResponses for each ResponseParameters in each |
||||||
|
StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a |
||||||
|
payload body of size ResponseParameters.size bytes, as specified by its |
||||||
|
respective ResponseParameters. After receiving half close and sending all |
||||||
|
responses, it closes with OK. |
||||||
|
|
||||||
|
### Compressable Payload |
||||||
|
[Compressable Payload]: #compressable-payload |
||||||
|
|
||||||
|
When the client requests COMPRESSABLE payload, the response includes a payload |
||||||
|
of the size requested containing all zeros and the payload type is |
||||||
|
COMPRESSABLE. |
||||||
|
|
||||||
|
### Observe ResponseParameters.interval_us |
||||||
|
[Observe ResponseParameters.interval_us]: #observe-responseparametersinterval_us |
||||||
|
|
||||||
|
In StreamingOutputCall and FullDuplexCall, server delays sending a |
||||||
|
StreamingOutputCallResponse by the ResponseParameters's interval_us for that |
||||||
|
particular response, relative to the last response sent. That is, interval_us |
||||||
|
acts like a sleep *before* sending the response and accumulates from one |
||||||
|
response to the next. |
||||||
|
|
||||||
|
Interaction with flow control is unspecified. |
||||||
|
|
||||||
|
### Echo Auth Information |
||||||
|
|
||||||
|
Status: Pending |
||||||
|
|
||||||
|
If a SimpleRequest has fill_username=true and that request was successfully |
||||||
|
authenticated, then the SimpleResponse should have username filled with the |
||||||
|
canonical form of the authenticated source. The canonical form is dependent on |
||||||
|
the authentication method, but is likely to be a base 10 integer identifier or |
||||||
|
an email address. |
||||||
|
|
||||||
|
Discussion: |
||||||
|
|
||||||
|
Ideally, this would be communicated via metadata and not in the |
||||||
|
request/response, but we want to use this test in code paths that don't yet |
||||||
|
fully communicate metadata. |
@ -0,0 +1,236 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <map> |
||||||
|
|
||||||
|
#include "src/compiler/objective_c_generator.h" |
||||||
|
#include "src/compiler/objective_c_generator_helpers.h" |
||||||
|
|
||||||
|
#include "src/compiler/config.h" |
||||||
|
|
||||||
|
#include <sstream> |
||||||
|
|
||||||
|
namespace grpc_objective_c_generator { |
||||||
|
namespace { |
||||||
|
|
||||||
|
void PrintSimpleBlockSignature(grpc::protobuf::io::Printer *printer, |
||||||
|
const grpc::protobuf::MethodDescriptor *method, |
||||||
|
std::map<grpc::string, grpc::string> *vars) { |
||||||
|
(*vars)["method_name"] = method->name(); |
||||||
|
(*vars)["request_type"] = PrefixedName(method->input_type()->name()); |
||||||
|
(*vars)["response_type"] = PrefixedName(method->output_type()->name()); |
||||||
|
|
||||||
|
if (method->server_streaming()) { |
||||||
|
printer->Print("// When the response stream finishes, the handler is " |
||||||
|
"called with nil for both arguments.\n\n"); |
||||||
|
} else { |
||||||
|
printer->Print("// The handler is only called once.\n\n"); |
||||||
|
} |
||||||
|
printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:" |
||||||
|
"($request_type$)request completionHandler:(void(^)" |
||||||
|
"($response_type$ *, NSError *))handler"); |
||||||
|
} |
||||||
|
|
||||||
|
void PrintSimpleDelegateSignature(grpc::protobuf::io::Printer *printer, |
||||||
|
const grpc::protobuf::MethodDescriptor *method, |
||||||
|
std::map<grpc::string, grpc::string> *vars) { |
||||||
|
(*vars)["method_name"] = method->name(); |
||||||
|
(*vars)["request_type"] = PrefixedName(method->input_type()->name()); |
||||||
|
|
||||||
|
printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:" |
||||||
|
"($request_type$)request delegate:(id<GRXSink>)delegate"); |
||||||
|
} |
||||||
|
|
||||||
|
void PrintAdvancedSignature(grpc::protobuf::io::Printer *printer, |
||||||
|
const grpc::protobuf::MethodDescriptor *method, |
||||||
|
std::map<grpc::string, grpc::string> *vars) { |
||||||
|
(*vars)["method_name"] = method->name(); |
||||||
|
printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:" |
||||||
|
"(id<GRXSource>)request"); |
||||||
|
} |
||||||
|
|
||||||
|
void PrintSourceMethodSimpleBlock(grpc::protobuf::io::Printer *printer, |
||||||
|
const grpc::protobuf::MethodDescriptor *method, |
||||||
|
std::map<grpc::string, grpc::string> *vars) { |
||||||
|
PrintSimpleBlockSignature(printer, method, vars); |
||||||
|
|
||||||
|
(*vars)["method_name"] = method->name(); |
||||||
|
printer->Print(" {\n"); |
||||||
|
printer->Indent(); |
||||||
|
printer->Print(*vars, "return [[self $method_name$WithRequest:request] " |
||||||
|
"connectHandler:^(id value, NSError *error) {\n"); |
||||||
|
printer->Indent(); |
||||||
|
printer->Print("handler(value, error);\n"); |
||||||
|
printer->Outdent(); |
||||||
|
printer->Print("}];\n"); |
||||||
|
printer->Outdent(); |
||||||
|
printer->Print("}\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void PrintSourceMethodSimpleDelegate(grpc::protobuf::io::Printer *printer, |
||||||
|
const grpc::protobuf::MethodDescriptor *method, |
||||||
|
std::map<grpc::string, grpc::string> *vars) { |
||||||
|
PrintSimpleDelegateSignature(printer, method, vars); |
||||||
|
|
||||||
|
(*vars)["method_name"] = method->name(); |
||||||
|
printer->Print(" {\n"); |
||||||
|
printer->Indent(); |
||||||
|
printer->Print(*vars, "return [[self $method_name$WithRequest:request]" |
||||||
|
"connectToSink:delegate];\n"); |
||||||
|
printer->Outdent(); |
||||||
|
printer->Print("}\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void PrintSourceMethodAdvanced(grpc::protobuf::io::Printer *printer, |
||||||
|
const grpc::protobuf::MethodDescriptor *method, |
||||||
|
std::map<grpc::string, grpc::string> *vars) { |
||||||
|
PrintAdvancedSignature(printer, method, vars); |
||||||
|
|
||||||
|
(*vars)["method_name"] = method->name(); |
||||||
|
printer->Print(" {\n"); |
||||||
|
printer->Indent(); |
||||||
|
printer->Print(*vars, "return [self $method_name$WithRequest:request " |
||||||
|
"client:[self newClient]];\n"); |
||||||
|
printer->Outdent(); |
||||||
|
printer->Print("}\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void PrintSourceMethodHandler(grpc::protobuf::io::Printer *printer, |
||||||
|
const grpc::protobuf::MethodDescriptor *method, |
||||||
|
std::map<grpc::string, grpc::string> *vars) { |
||||||
|
(*vars)["method_name"] = method->name(); |
||||||
|
(*vars)["response_type"] = PrefixedName(method->output_type()->name()); |
||||||
|
(*vars)["caps_name"] = grpc_generator::CapitalizeFirstLetter(method->name()); |
||||||
|
|
||||||
|
printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:" |
||||||
|
"(id<GRXSource>)request client:(PBgRPCClient *)client {\n"); |
||||||
|
printer->Indent(); |
||||||
|
printer->Print(*vars, |
||||||
|
"return [self responseWithMethod:$@\"$caps_name\"\n"); |
||||||
|
printer->Print(*vars, |
||||||
|
" class:[$response_type$ class]\n"); |
||||||
|
printer->Print(" request:request\n"); |
||||||
|
printer->Print(" client:client];\n"); |
||||||
|
printer->Outdent(); |
||||||
|
printer->Print("}\n"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service, |
||||||
|
const grpc::string message_header) { |
||||||
|
grpc::string output; |
||||||
|
grpc::protobuf::io::StringOutputStream output_stream(&output); |
||||||
|
grpc::protobuf::io::Printer printer(&output_stream, '$'); |
||||||
|
std::map<grpc::string, grpc::string> vars; |
||||||
|
printer.Print("#import \"PBgRPCClient.h\"\n"); |
||||||
|
printer.Print("#import \"PBStub.h\"\n"); |
||||||
|
vars["message_header"] = message_header; |
||||||
|
printer.Print(vars, "#import \"$message_header$\"\n\n"); |
||||||
|
printer.Print("@protocol GRXSource\n"); |
||||||
|
printer.Print("@class GRXSource\n\n"); |
||||||
|
vars["service_name"] = service->name(); |
||||||
|
printer.Print("@protocol $service_name$Stub <NSObject>\n\n"); |
||||||
|
printer.Print("#pragma mark Simple block handlers\n\n"); |
||||||
|
for (int i = 0; i < service->method_count(); i++) { |
||||||
|
PrintSimpleBlockSignature(&printer, service->method(i), &vars); |
||||||
|
printer.Print(";\n"); |
||||||
|
} |
||||||
|
printer.Print("\n"); |
||||||
|
printer.Print("#pragma mark Simple delegate handlers.\n\n"); |
||||||
|
printer.Print("# TODO(jcanizales): Use high-level snippets to remove this duplication."); |
||||||
|
for (int i = 0; i < service->method_count(); i++) { |
||||||
|
PrintSimpleDelegateSignature(&printer, service->method(i), &vars); |
||||||
|
printer.Print(";\n"); |
||||||
|
} |
||||||
|
printer.Print("\n"); |
||||||
|
printer.Print("#pragma mark Advanced handlers.\n\n"); |
||||||
|
for (int i = 0; i < service->method_count(); i++) { |
||||||
|
PrintAdvancedSignature(&printer, service->method(i), &vars); |
||||||
|
printer.Print(";\n"); |
||||||
|
} |
||||||
|
printer.Print("\n"); |
||||||
|
printer.Print("@end\n\n"); |
||||||
|
printer.Print("// Basic stub that only does marshalling and parsing\n"); |
||||||
|
printer.Print(vars, "@interface $service_name$Stub :" |
||||||
|
" PBStub<$service_name$Stub>\n"); |
||||||
|
printer.Print("- (instancetype)initWithHost:(NSString *)host;\n"); |
||||||
|
printer.Print("@end\n"); |
||||||
|
return output; |
||||||
|
} |
||||||
|
|
||||||
|
grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service) { |
||||||
|
grpc::string output; |
||||||
|
grpc::protobuf::io::StringOutputStream output_stream(&output); |
||||||
|
grpc::protobuf::io::Printer printer(&output_stream, '$'); |
||||||
|
std::map<grpc::string, grpc::string> vars; |
||||||
|
vars["service_name"] = service->name(); |
||||||
|
printer.Print(vars, "#import \"$service_name$Stub.pb.h\"\n"); |
||||||
|
printer.Print("#import \"PBGeneratedMessage+GRXSource.h\"\n\n"); |
||||||
|
vars["full_name"] = service->full_name(); |
||||||
|
printer.Print(vars, |
||||||
|
"static NSString *const kInterface = @\"$full_name$\";\n"); |
||||||
|
printer.Print("@implementation $service_name$Stub\n\n"); |
||||||
|
printer.Print("- (instancetype)initWithHost:(NSString *)host {\n"); |
||||||
|
printer.Indent(); |
||||||
|
printer.Print("if ((self = [super initWithHost:host " |
||||||
|
"interface:kInterface])) {\n"); |
||||||
|
printer.Print("}\n"); |
||||||
|
printer.Print("return self;\n"); |
||||||
|
printer.Outdent(); |
||||||
|
printer.Print("}\n\n"); |
||||||
|
printer.Print("#pragma mark Simple block handlers.\n"); |
||||||
|
for (int i = 0; i < service->method_count(); i++) { |
||||||
|
PrintSourceMethodSimpleBlock(&printer, service->method(i), &vars); |
||||||
|
} |
||||||
|
printer.Print("\n"); |
||||||
|
printer.Print("#pragma mark Simple delegate handlers.\n"); |
||||||
|
for (int i = 0; i < service->method_count(); i++) { |
||||||
|
PrintSourceMethodSimpleDelegate(&printer, service->method(i), &vars); |
||||||
|
} |
||||||
|
printer.Print("\n"); |
||||||
|
printer.Print("#pragma mark Advanced handlers.\n"); |
||||||
|
for (int i = 0; i < service->method_count(); i++) { |
||||||
|
PrintSourceMethodAdvanced(&printer, service->method(i), &vars); |
||||||
|
} |
||||||
|
printer.Print("\n"); |
||||||
|
printer.Print("#pragma mark Handlers for subclasses " |
||||||
|
"(stub wrappers) to override.\n"); |
||||||
|
for (int i = 0; i < service->method_count(); i++) { |
||||||
|
PrintSourceMethodHandler(&printer, service->method(i), &vars); |
||||||
|
} |
||||||
|
printer.Print("@end\n"); |
||||||
|
return output; |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace grpc_objective_c_generator
|
@ -0,0 +1,48 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H |
||||||
|
#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H |
||||||
|
|
||||||
|
#include "src/compiler/config.h" |
||||||
|
|
||||||
|
namespace grpc_objective_c_generator { |
||||||
|
|
||||||
|
grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service, |
||||||
|
const grpc::string message_header); |
||||||
|
|
||||||
|
grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service); |
||||||
|
|
||||||
|
} // namespace grpc_objective_c_generator
|
||||||
|
|
||||||
|
#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H
|
@ -0,0 +1,58 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H |
||||||
|
#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H |
||||||
|
|
||||||
|
#include <map> |
||||||
|
#include "src/compiler/config.h" |
||||||
|
#include "src/compiler/generator_helpers.h" |
||||||
|
|
||||||
|
namespace grpc_objective_c_generator { |
||||||
|
|
||||||
|
const grpc::string prefix = "PBG"; |
||||||
|
|
||||||
|
inline grpc::string MessageHeaderName(const grpc::protobuf::FileDescriptor *file) { |
||||||
|
return grpc_generator::FileNameInUpperCamel(file) + ".pb.h"; |
||||||
|
} |
||||||
|
|
||||||
|
inline grpc::string StubFileName(grpc::string service_name) { |
||||||
|
return prefix + service_name + "Stub"; |
||||||
|
} |
||||||
|
|
||||||
|
inline grpc::string PrefixedName(grpc::string name) { |
||||||
|
return prefix + name; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
|
@ -0,0 +1,98 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
// Generates Objective C gRPC service interface out of Protobuf IDL.
|
||||||
|
|
||||||
|
#include <memory> |
||||||
|
|
||||||
|
#include "src/compiler/config.h" |
||||||
|
#include "src/compiler/objective_c_generator.h" |
||||||
|
#include "src/compiler/objective_c_generator_helpers.h" |
||||||
|
|
||||||
|
class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { |
||||||
|
public: |
||||||
|
ObjectiveCGrpcGenerator() {} |
||||||
|
virtual ~ObjectiveCGrpcGenerator() {} |
||||||
|
|
||||||
|
virtual bool Generate(const grpc::protobuf::FileDescriptor *file, |
||||||
|
const grpc::string ¶meter, |
||||||
|
grpc::protobuf::compiler::GeneratorContext *context, |
||||||
|
grpc::string *error) const { |
||||||
|
|
||||||
|
if (file->service_count() == 0) { |
||||||
|
// No services. Do nothing.
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < file->service_count(); i++) { |
||||||
|
const grpc::protobuf::ServiceDescriptor *service = file->service(i); |
||||||
|
grpc::string file_name = grpc_objective_c_generator::StubFileName( |
||||||
|
service->name()); |
||||||
|
|
||||||
|
// Generate .pb.h
|
||||||
|
grpc::string header_code = grpc_objective_c_generator::GetHeader( |
||||||
|
service, grpc_objective_c_generator::MessageHeaderName(file)); |
||||||
|
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output( |
||||||
|
context->Open(file_name + ".pb.h")); |
||||||
|
grpc::protobuf::io::CodedOutputStream header_coded_out( |
||||||
|
header_output.get()); |
||||||
|
header_coded_out.WriteRaw(header_code.data(), header_code.size()); |
||||||
|
|
||||||
|
// Generate .pb.m
|
||||||
|
grpc::string source_code = grpc_objective_c_generator::GetSource(service); |
||||||
|
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output( |
||||||
|
context->Open(file_name + ".pb.m")); |
||||||
|
grpc::protobuf::io::CodedOutputStream source_coded_out( |
||||||
|
source_output.get()); |
||||||
|
source_coded_out.WriteRaw(source_code.data(), source_code.size()); |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
// Insert the given code into the given file at the given insertion point.
|
||||||
|
void Insert(grpc::protobuf::compiler::GeneratorContext *context, |
||||||
|
const grpc::string &filename, const grpc::string &insertion_point, |
||||||
|
const grpc::string &code) const { |
||||||
|
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output( |
||||||
|
context->OpenForInsert(filename, insertion_point)); |
||||||
|
grpc::protobuf::io::CodedOutputStream coded_out(output.get()); |
||||||
|
coded_out.WriteRaw(code.data(), code.size()); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
int main(int argc, char *argv[]) { |
||||||
|
ObjectiveCGrpcGenerator generator; |
||||||
|
return grpc::protobuf::compiler::PluginMain(argc, argv, &generator); |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H |
||||||
|
#define GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H |
||||||
|
|
||||||
|
#include <grpc/grpc_security.h> |
||||||
|
|
||||||
|
#include <grpc++/config.h> |
||||||
|
#include <grpc++/credentials.h> |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
|
||||||
|
class SecureCredentials GRPC_FINAL : public Credentials { |
||||||
|
public: |
||||||
|
explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {} |
||||||
|
~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); } |
||||||
|
grpc_credentials* GetRawCreds() { return c_creds_; } |
||||||
|
|
||||||
|
std::shared_ptr<grpc::ChannelInterface> CreateChannel( |
||||||
|
const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE; |
||||||
|
SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; } |
||||||
|
|
||||||
|
private: |
||||||
|
grpc_credentials* const c_creds_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
#endif // GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H
|
||||||
|
|
@ -0,0 +1,60 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H |
||||||
|
#define GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H |
||||||
|
|
||||||
|
#include <grpc/grpc_security.h> |
||||||
|
|
||||||
|
#include <grpc++/server_credentials.h> |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
|
||||||
|
class SecureServerCredentials GRPC_FINAL : public ServerCredentials { |
||||||
|
public: |
||||||
|
explicit SecureServerCredentials(grpc_server_credentials* creds) |
||||||
|
: creds_(creds) {} |
||||||
|
~SecureServerCredentials() GRPC_OVERRIDE { |
||||||
|
grpc_server_credentials_release(creds_); |
||||||
|
} |
||||||
|
|
||||||
|
int AddPortToServer(const grpc::string& addr, |
||||||
|
grpc_server* server) GRPC_OVERRIDE; |
||||||
|
|
||||||
|
private: |
||||||
|
grpc_server_credentials* const creds_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
#endif // GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H
|
@ -0,0 +1,2 @@ |
|||||||
|
bin |
||||||
|
obj |
@ -0,0 +1,52 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||||
|
<PropertyGroup> |
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform> |
||||||
|
<ProductVersion>10.0.0</ProductVersion> |
||||||
|
<SchemaVersion>2.0</SchemaVersion> |
||||||
|
<ProjectGuid>{BF62FE08-373A-43D6-9D73-41CAA38B7011}</ProjectGuid> |
||||||
|
<OutputType>Exe</OutputType> |
||||||
|
<RootNamespace>Grpc.Examples.MathServer</RootNamespace> |
||||||
|
<AssemblyName>Grpc.Examples.MathServer</AssemblyName> |
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> |
||||||
|
<DebugSymbols>true</DebugSymbols> |
||||||
|
<DebugType>full</DebugType> |
||||||
|
<Optimize>false</Optimize> |
||||||
|
<OutputPath>bin\Debug</OutputPath> |
||||||
|
<DefineConstants>DEBUG;</DefineConstants> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<WarningLevel>4</WarningLevel> |
||||||
|
<Externalconsole>true</Externalconsole> |
||||||
|
<PlatformTarget>x86</PlatformTarget> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> |
||||||
|
<DebugType>full</DebugType> |
||||||
|
<Optimize>true</Optimize> |
||||||
|
<OutputPath>bin\Release</OutputPath> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<WarningLevel>4</WarningLevel> |
||||||
|
<Externalconsole>true</Externalconsole> |
||||||
|
<PlatformTarget>x86</PlatformTarget> |
||||||
|
</PropertyGroup> |
||||||
|
<ItemGroup> |
||||||
|
<Reference Include="System" /> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||||
|
<Compile Include="MathServer.cs" /> |
||||||
|
</ItemGroup> |
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |
||||||
|
<ItemGroup> |
||||||
|
<ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj"> |
||||||
|
<Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project> |
||||||
|
<Name>Grpc.Core</Name> |
||||||
|
</ProjectReference> |
||||||
|
<ProjectReference Include="..\Grpc.Examples\Grpc.Examples.csproj"> |
||||||
|
<Project>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</Project> |
||||||
|
<Name>Grpc.Examples</Name> |
||||||
|
</ProjectReference> |
||||||
|
</ItemGroup> |
||||||
|
</Project> |
@ -0,0 +1,61 @@ |
|||||||
|
#region Copyright notice and license |
||||||
|
// Copyright 2015, Google Inc. |
||||||
|
// All rights reserved. |
||||||
|
// |
||||||
|
// Redistribution and use in source and binary forms, with or without |
||||||
|
// modification, are permitted provided that the following conditions are |
||||||
|
// met: |
||||||
|
// |
||||||
|
// * Redistributions of source code must retain the above copyright |
||||||
|
// notice, this list of conditions and the following disclaimer. |
||||||
|
// * Redistributions in binary form must reproduce the above |
||||||
|
// copyright notice, this list of conditions and the following disclaimer |
||||||
|
// in the documentation and/or other materials provided with the |
||||||
|
// distribution. |
||||||
|
// * Neither the name of Google Inc. nor the names of its |
||||||
|
// contributors may be used to endorse or promote products derived from |
||||||
|
// this software without specific prior written permission. |
||||||
|
// |
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
#endregion |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
using System.Threading; |
||||||
|
using Grpc.Core; |
||||||
|
|
||||||
|
namespace math |
||||||
|
{ |
||||||
|
class MainClass |
||||||
|
{ |
||||||
|
public static void Main(string[] args) |
||||||
|
{ |
||||||
|
String host = "0.0.0.0"; |
||||||
|
|
||||||
|
GrpcEnvironment.Initialize(); |
||||||
|
|
||||||
|
Server server = new Server(); |
||||||
|
server.AddServiceDefinition(MathGrpc.BindService(new MathServiceImpl())); |
||||||
|
int port = server.AddListeningPort(host + ":0"); |
||||||
|
server.Start(); |
||||||
|
|
||||||
|
Console.WriteLine("MathServer listening on port " + port); |
||||||
|
|
||||||
|
Console.WriteLine("Press any key to stop the server..."); |
||||||
|
Console.ReadKey(); |
||||||
|
|
||||||
|
server.ShutdownAsync().Wait(); |
||||||
|
GrpcEnvironment.Shutdown(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
using System.Reflection; |
||||||
|
using System.Runtime.CompilerServices; |
||||||
|
|
||||||
|
[assembly: AssemblyTitle("Grpc.Examples.MathServer")] |
||||||
|
[assembly: AssemblyDescription("")] |
||||||
|
[assembly: AssemblyConfiguration("")] |
||||||
|
[assembly: AssemblyCompany("")] |
||||||
|
[assembly: AssemblyProduct("")] |
||||||
|
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")] |
||||||
|
[assembly: AssemblyTrademark("")] |
||||||
|
[assembly: AssemblyCulture("")] |
||||||
|
[assembly: AssemblyVersion("0.1.*")] |
@ -0,0 +1,40 @@ |
|||||||
|
#!/bin/sh |
||||||
|
# Copyright 2015, Google Inc. |
||||||
|
# All rights reserved. |
||||||
|
# |
||||||
|
# Redistribution and use in source and binary forms, with or without |
||||||
|
# modification, are permitted provided that the following conditions are |
||||||
|
# met: |
||||||
|
# |
||||||
|
# * Redistributions of source code must retain the above copyright |
||||||
|
# notice, this list of conditions and the following disclaimer. |
||||||
|
# * Redistributions in binary form must reproduce the above |
||||||
|
# copyright notice, this list of conditions and the following disclaimer |
||||||
|
# in the documentation and/or other materials provided with the |
||||||
|
# distribution. |
||||||
|
# * Neither the name of Google Inc. nor the names of its |
||||||
|
# contributors may be used to endorse or promote products derived from |
||||||
|
# this software without specific prior written permission. |
||||||
|
# |
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
|
||||||
|
|
||||||
|
set +e |
||||||
|
cd $(dirname $0) |
||||||
|
|
||||||
|
gen_code='../tests/generated_code' |
||||||
|
interop='../tests/interop' |
||||||
|
|
||||||
|
protoc-gen-php -i $gen_code -o $gen_code $gen_code/math.proto |
||||||
|
|
||||||
|
protoc-gen-php -i $interop -o $interop $interop/test.proto |
@ -0,0 +1,121 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/cpp/interop/client_helper.h" |
||||||
|
|
||||||
|
#include <fstream> |
||||||
|
#include <memory> |
||||||
|
#include <sstream> |
||||||
|
|
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <gflags/gflags.h> |
||||||
|
#include <grpc++/channel_arguments.h> |
||||||
|
#include <grpc++/channel_interface.h> |
||||||
|
#include <grpc++/create_channel.h> |
||||||
|
#include <grpc++/credentials.h> |
||||||
|
#include <grpc++/stream.h> |
||||||
|
#include "test/cpp/util/create_test_channel.h" |
||||||
|
|
||||||
|
DECLARE_bool(enable_ssl); |
||||||
|
DECLARE_bool(use_prod_roots); |
||||||
|
DECLARE_int32(server_port); |
||||||
|
DECLARE_string(server_host); |
||||||
|
DECLARE_string(server_host_override); |
||||||
|
DECLARE_string(test_case); |
||||||
|
DECLARE_string(default_service_account); |
||||||
|
DECLARE_string(service_account_key_file); |
||||||
|
DECLARE_string(oauth_scope); |
||||||
|
|
||||||
|
// In some distros, gflags is in the namespace google, and in some others,
|
||||||
|
// in gflags. This hack is enabling us to find both.
|
||||||
|
namespace google {} |
||||||
|
namespace gflags {} |
||||||
|
using namespace google; |
||||||
|
using namespace gflags; |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace testing { |
||||||
|
|
||||||
|
grpc::string GetServiceAccountJsonKey() { |
||||||
|
static grpc::string json_key; |
||||||
|
if (json_key.empty()) { |
||||||
|
std::ifstream json_key_file(FLAGS_service_account_key_file); |
||||||
|
std::stringstream key_stream; |
||||||
|
key_stream << json_key_file.rdbuf(); |
||||||
|
json_key = key_stream.str(); |
||||||
|
} |
||||||
|
return json_key; |
||||||
|
} |
||||||
|
|
||||||
|
std::shared_ptr<ChannelInterface> CreateChannelForTestCase( |
||||||
|
const grpc::string& test_case) { |
||||||
|
GPR_ASSERT(FLAGS_server_port); |
||||||
|
const int host_port_buf_size = 1024; |
||||||
|
char host_port[host_port_buf_size]; |
||||||
|
snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(), |
||||||
|
FLAGS_server_port); |
||||||
|
|
||||||
|
if (test_case == "service_account_creds") { |
||||||
|
std::unique_ptr<Credentials> creds; |
||||||
|
GPR_ASSERT(FLAGS_enable_ssl); |
||||||
|
grpc::string json_key = GetServiceAccountJsonKey(); |
||||||
|
std::chrono::seconds token_lifetime = std::chrono::hours(1); |
||||||
|
creds = ServiceAccountCredentials(json_key, FLAGS_oauth_scope, |
||||||
|
token_lifetime.count()); |
||||||
|
return CreateTestChannel(host_port, FLAGS_server_host_override, |
||||||
|
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds); |
||||||
|
} else if (test_case == "compute_engine_creds") { |
||||||
|
std::unique_ptr<Credentials> creds; |
||||||
|
GPR_ASSERT(FLAGS_enable_ssl); |
||||||
|
creds = ComputeEngineCredentials(); |
||||||
|
return CreateTestChannel(host_port, FLAGS_server_host_override, |
||||||
|
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds); |
||||||
|
} else if (test_case == "jwt_token_creds") { |
||||||
|
std::unique_ptr<Credentials> creds; |
||||||
|
GPR_ASSERT(FLAGS_enable_ssl); |
||||||
|
grpc::string json_key = GetServiceAccountJsonKey(); |
||||||
|
std::chrono::seconds token_lifetime = std::chrono::hours(1); |
||||||
|
creds = JWTCredentials(json_key, token_lifetime.count()); |
||||||
|
return CreateTestChannel(host_port, FLAGS_server_host_override, |
||||||
|
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds); |
||||||
|
} else { |
||||||
|
return CreateTestChannel(host_port, FLAGS_server_host_override, |
||||||
|
FLAGS_enable_ssl, FLAGS_use_prod_roots); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc
|
@ -0,0 +1,53 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H |
||||||
|
#define GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H |
||||||
|
|
||||||
|
#include <memory> |
||||||
|
|
||||||
|
#include <grpc++/config.h> |
||||||
|
#include <grpc++/channel_interface.h> |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace testing { |
||||||
|
|
||||||
|
grpc::string GetServiceAccountJsonKey(); |
||||||
|
|
||||||
|
std::shared_ptr<ChannelInterface> CreateChannelForTestCase( |
||||||
|
const grpc::string& test_case); |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
#endif // GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H
|
@ -0,0 +1,311 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/cpp/interop/interop_client.h" |
||||||
|
|
||||||
|
#include <memory> |
||||||
|
|
||||||
|
#include <unistd.h> |
||||||
|
|
||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc++/channel_interface.h> |
||||||
|
#include <grpc++/client_context.h> |
||||||
|
#include <grpc++/status.h> |
||||||
|
#include <grpc++/stream.h> |
||||||
|
#include "test/cpp/interop/test.grpc.pb.h" |
||||||
|
#include "test/cpp/interop/empty.grpc.pb.h" |
||||||
|
#include "test/cpp/interop/messages.grpc.pb.h" |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace testing { |
||||||
|
|
||||||
|
namespace { |
||||||
|
// The same value is defined by the Java client.
|
||||||
|
const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904}; |
||||||
|
const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979}; |
||||||
|
const int kNumResponseMessages = 2000; |
||||||
|
const int kResponseMessageSize = 1030; |
||||||
|
const int kReceiveDelayMilliSeconds = 20; |
||||||
|
const int kLargeRequestSize = 314159; |
||||||
|
const int kLargeResponseSize = 271812; |
||||||
|
} // namespace
|
||||||
|
|
||||||
|
InteropClient::InteropClient(std::shared_ptr<ChannelInterface> channel) |
||||||
|
: channel_(channel) {} |
||||||
|
|
||||||
|
void InteropClient::AssertOkOrPrintErrorStatus(const Status& s) { |
||||||
|
if (s.IsOk()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
gpr_log(GPR_INFO, "Error status code: %d, message: %s", s.code(), |
||||||
|
s.details().c_str()); |
||||||
|
GPR_ASSERT(0); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoEmpty() { |
||||||
|
gpr_log(GPR_INFO, "Sending an empty rpc..."); |
||||||
|
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_)); |
||||||
|
|
||||||
|
Empty request = Empty::default_instance(); |
||||||
|
Empty response = Empty::default_instance(); |
||||||
|
ClientContext context; |
||||||
|
|
||||||
|
Status s = stub->EmptyCall(&context, request, &response); |
||||||
|
AssertOkOrPrintErrorStatus(s); |
||||||
|
|
||||||
|
gpr_log(GPR_INFO, "Empty rpc done."); |
||||||
|
} |
||||||
|
|
||||||
|
// Shared code to set large payload, make rpc and check response payload.
|
||||||
|
void InteropClient::PerformLargeUnary(SimpleRequest* request, |
||||||
|
SimpleResponse* response) { |
||||||
|
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_)); |
||||||
|
|
||||||
|
ClientContext context; |
||||||
|
request->set_response_type(PayloadType::COMPRESSABLE); |
||||||
|
request->set_response_size(kLargeResponseSize); |
||||||
|
grpc::string payload(kLargeRequestSize, '\0'); |
||||||
|
request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize); |
||||||
|
|
||||||
|
Status s = stub->UnaryCall(&context, *request, response); |
||||||
|
|
||||||
|
AssertOkOrPrintErrorStatus(s); |
||||||
|
GPR_ASSERT(response->payload().type() == PayloadType::COMPRESSABLE); |
||||||
|
GPR_ASSERT(response->payload().body() == |
||||||
|
grpc::string(kLargeResponseSize, '\0')); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoComputeEngineCreds( |
||||||
|
const grpc::string& default_service_account, |
||||||
|
const grpc::string& oauth_scope) { |
||||||
|
gpr_log(GPR_INFO, |
||||||
|
"Sending a large unary rpc with compute engine credentials ..."); |
||||||
|
SimpleRequest request; |
||||||
|
SimpleResponse response; |
||||||
|
request.set_fill_username(true); |
||||||
|
request.set_fill_oauth_scope(true); |
||||||
|
PerformLargeUnary(&request, &response); |
||||||
|
gpr_log(GPR_INFO, "Got username %s", response.username().c_str()); |
||||||
|
gpr_log(GPR_INFO, "Got oauth_scope %s", response.oauth_scope().c_str()); |
||||||
|
GPR_ASSERT(!response.username().empty()); |
||||||
|
GPR_ASSERT(response.username().c_str() == default_service_account); |
||||||
|
GPR_ASSERT(!response.oauth_scope().empty()); |
||||||
|
const char* oauth_scope_str = response.oauth_scope().c_str(); |
||||||
|
GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos); |
||||||
|
gpr_log(GPR_INFO, "Large unary with compute engine creds done."); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoServiceAccountCreds(const grpc::string& username, |
||||||
|
const grpc::string& oauth_scope) { |
||||||
|
gpr_log(GPR_INFO, |
||||||
|
"Sending a large unary rpc with service account credentials ..."); |
||||||
|
SimpleRequest request; |
||||||
|
SimpleResponse response; |
||||||
|
request.set_fill_username(true); |
||||||
|
request.set_fill_oauth_scope(true); |
||||||
|
PerformLargeUnary(&request, &response); |
||||||
|
GPR_ASSERT(!response.username().empty()); |
||||||
|
GPR_ASSERT(!response.oauth_scope().empty()); |
||||||
|
GPR_ASSERT(username.find(response.username()) != grpc::string::npos); |
||||||
|
const char* oauth_scope_str = response.oauth_scope().c_str(); |
||||||
|
GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos); |
||||||
|
gpr_log(GPR_INFO, "Large unary with service account creds done."); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoJwtTokenCreds(const grpc::string& username) { |
||||||
|
gpr_log(GPR_INFO, "Sending a large unary rpc with JWT token credentials ..."); |
||||||
|
SimpleRequest request; |
||||||
|
SimpleResponse response; |
||||||
|
request.set_fill_username(true); |
||||||
|
PerformLargeUnary(&request, &response); |
||||||
|
GPR_ASSERT(!response.username().empty()); |
||||||
|
GPR_ASSERT(username.find(response.username()) != grpc::string::npos); |
||||||
|
gpr_log(GPR_INFO, "Large unary with JWT token creds done."); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoLargeUnary() { |
||||||
|
gpr_log(GPR_INFO, "Sending a large unary rpc..."); |
||||||
|
SimpleRequest request; |
||||||
|
SimpleResponse response; |
||||||
|
PerformLargeUnary(&request, &response); |
||||||
|
gpr_log(GPR_INFO, "Large unary done."); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoRequestStreaming() { |
||||||
|
gpr_log(GPR_INFO, "Sending request steaming rpc ..."); |
||||||
|
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_)); |
||||||
|
|
||||||
|
ClientContext context; |
||||||
|
StreamingInputCallRequest request; |
||||||
|
StreamingInputCallResponse response; |
||||||
|
|
||||||
|
std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream( |
||||||
|
stub->StreamingInputCall(&context, &response)); |
||||||
|
|
||||||
|
int aggregated_payload_size = 0; |
||||||
|
for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) { |
||||||
|
Payload* payload = request.mutable_payload(); |
||||||
|
payload->set_body(grpc::string(request_stream_sizes[i], '\0')); |
||||||
|
GPR_ASSERT(stream->Write(request)); |
||||||
|
aggregated_payload_size += request_stream_sizes[i]; |
||||||
|
} |
||||||
|
stream->WritesDone(); |
||||||
|
Status s = stream->Finish(); |
||||||
|
|
||||||
|
GPR_ASSERT(response.aggregated_payload_size() == aggregated_payload_size); |
||||||
|
AssertOkOrPrintErrorStatus(s); |
||||||
|
gpr_log(GPR_INFO, "Request streaming done."); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoResponseStreaming() { |
||||||
|
gpr_log(GPR_INFO, "Receiving response steaming rpc ..."); |
||||||
|
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_)); |
||||||
|
|
||||||
|
ClientContext context; |
||||||
|
StreamingOutputCallRequest request; |
||||||
|
for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) { |
||||||
|
ResponseParameters* response_parameter = request.add_response_parameters(); |
||||||
|
response_parameter->set_size(response_stream_sizes[i]); |
||||||
|
} |
||||||
|
StreamingOutputCallResponse response; |
||||||
|
std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream( |
||||||
|
stub->StreamingOutputCall(&context, request)); |
||||||
|
|
||||||
|
unsigned int i = 0; |
||||||
|
while (stream->Read(&response)) { |
||||||
|
GPR_ASSERT(response.payload().body() == |
||||||
|
grpc::string(response_stream_sizes[i], '\0')); |
||||||
|
++i; |
||||||
|
} |
||||||
|
GPR_ASSERT(response_stream_sizes.size() == i); |
||||||
|
Status s = stream->Finish(); |
||||||
|
|
||||||
|
AssertOkOrPrintErrorStatus(s); |
||||||
|
gpr_log(GPR_INFO, "Response streaming done."); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoResponseStreamingWithSlowConsumer() { |
||||||
|
gpr_log(GPR_INFO, "Receiving response steaming rpc with slow consumer ..."); |
||||||
|
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_)); |
||||||
|
|
||||||
|
ClientContext context; |
||||||
|
StreamingOutputCallRequest request; |
||||||
|
|
||||||
|
for (int i = 0; i < kNumResponseMessages; ++i) { |
||||||
|
ResponseParameters* response_parameter = request.add_response_parameters(); |
||||||
|
response_parameter->set_size(kResponseMessageSize); |
||||||
|
} |
||||||
|
StreamingOutputCallResponse response; |
||||||
|
std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream( |
||||||
|
stub->StreamingOutputCall(&context, request)); |
||||||
|
|
||||||
|
int i = 0; |
||||||
|
while (stream->Read(&response)) { |
||||||
|
GPR_ASSERT(response.payload().body() == |
||||||
|
grpc::string(kResponseMessageSize, '\0')); |
||||||
|
gpr_log(GPR_INFO, "received message %d", i); |
||||||
|
usleep(kReceiveDelayMilliSeconds * 1000); |
||||||
|
++i; |
||||||
|
} |
||||||
|
GPR_ASSERT(kNumResponseMessages == i); |
||||||
|
Status s = stream->Finish(); |
||||||
|
|
||||||
|
AssertOkOrPrintErrorStatus(s); |
||||||
|
gpr_log(GPR_INFO, "Response streaming done."); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoHalfDuplex() { |
||||||
|
gpr_log(GPR_INFO, "Sending half-duplex streaming rpc ..."); |
||||||
|
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_)); |
||||||
|
|
||||||
|
ClientContext context; |
||||||
|
std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest, |
||||||
|
StreamingOutputCallResponse>> |
||||||
|
stream(stub->HalfDuplexCall(&context)); |
||||||
|
|
||||||
|
StreamingOutputCallRequest request; |
||||||
|
ResponseParameters* response_parameter = request.add_response_parameters(); |
||||||
|
for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) { |
||||||
|
response_parameter->set_size(response_stream_sizes[i]); |
||||||
|
GPR_ASSERT(stream->Write(request)); |
||||||
|
} |
||||||
|
stream->WritesDone(); |
||||||
|
|
||||||
|
unsigned int i = 0; |
||||||
|
StreamingOutputCallResponse response; |
||||||
|
while (stream->Read(&response)) { |
||||||
|
GPR_ASSERT(response.payload().has_body()); |
||||||
|
GPR_ASSERT(response.payload().body() == |
||||||
|
grpc::string(response_stream_sizes[i], '\0')); |
||||||
|
++i; |
||||||
|
} |
||||||
|
GPR_ASSERT(response_stream_sizes.size() == i); |
||||||
|
Status s = stream->Finish(); |
||||||
|
AssertOkOrPrintErrorStatus(s); |
||||||
|
gpr_log(GPR_INFO, "Half-duplex streaming rpc done."); |
||||||
|
} |
||||||
|
|
||||||
|
void InteropClient::DoPingPong() { |
||||||
|
gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ..."); |
||||||
|
std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_)); |
||||||
|
|
||||||
|
ClientContext context; |
||||||
|
std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest, |
||||||
|
StreamingOutputCallResponse>> |
||||||
|
stream(stub->FullDuplexCall(&context)); |
||||||
|
|
||||||
|
StreamingOutputCallRequest request; |
||||||
|
request.set_response_type(PayloadType::COMPRESSABLE); |
||||||
|
ResponseParameters* response_parameter = request.add_response_parameters(); |
||||||
|
Payload* payload = request.mutable_payload(); |
||||||
|
StreamingOutputCallResponse response; |
||||||
|
for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) { |
||||||
|
response_parameter->set_size(response_stream_sizes[i]); |
||||||
|
payload->set_body(grpc::string(request_stream_sizes[i], '\0')); |
||||||
|
GPR_ASSERT(stream->Write(request)); |
||||||
|
GPR_ASSERT(stream->Read(&response)); |
||||||
|
GPR_ASSERT(response.payload().has_body()); |
||||||
|
GPR_ASSERT(response.payload().body() == |
||||||
|
grpc::string(response_stream_sizes[i], '\0')); |
||||||
|
} |
||||||
|
|
||||||
|
stream->WritesDone(); |
||||||
|
GPR_ASSERT(!stream->Read(&response)); |
||||||
|
Status s = stream->Finish(); |
||||||
|
AssertOkOrPrintErrorStatus(s); |
||||||
|
gpr_log(GPR_INFO, "Ping pong streaming done."); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc
|
@ -0,0 +1,79 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_TEST_CPP_INTEROP_INTEROP_CLIENT_H |
||||||
|
#define GRPC_TEST_CPP_INTEROP_INTEROP_CLIENT_H |
||||||
|
#include <memory> |
||||||
|
|
||||||
|
#include <grpc/grpc.h> |
||||||
|
#include <grpc++/channel_interface.h> |
||||||
|
#include <grpc++/status.h> |
||||||
|
#include "test/cpp/interop/messages.grpc.pb.h" |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace testing { |
||||||
|
|
||||||
|
class InteropClient { |
||||||
|
public: |
||||||
|
explicit InteropClient(std::shared_ptr<ChannelInterface> channel); |
||||||
|
~InteropClient() {} |
||||||
|
|
||||||
|
void Reset(std::shared_ptr<ChannelInterface> channel) { channel_ = channel; } |
||||||
|
|
||||||
|
void DoEmpty(); |
||||||
|
void DoLargeUnary(); |
||||||
|
void DoPingPong(); |
||||||
|
void DoHalfDuplex(); |
||||||
|
void DoRequestStreaming(); |
||||||
|
void DoResponseStreaming(); |
||||||
|
void DoResponseStreamingWithSlowConsumer(); |
||||||
|
// Auth tests.
|
||||||
|
// username is a string containing the user email
|
||||||
|
void DoJwtTokenCreds(const grpc::string& username); |
||||||
|
void DoComputeEngineCreds(const grpc::string& default_service_account, |
||||||
|
const grpc::string& oauth_scope); |
||||||
|
// username is a string containing the user email
|
||||||
|
void DoServiceAccountCreds(const grpc::string& username, |
||||||
|
const grpc::string& oauth_scope); |
||||||
|
|
||||||
|
private: |
||||||
|
void PerformLargeUnary(SimpleRequest* request, SimpleResponse* response); |
||||||
|
void AssertOkOrPrintErrorStatus(const Status& s); |
||||||
|
|
||||||
|
std::shared_ptr<ChannelInterface> channel_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
#endif // GRPC_TEST_CPP_INTEROP_INTEROP_CLIENT_H
|
@ -0,0 +1,69 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/cpp/interop/server_helper.h" |
||||||
|
|
||||||
|
#include <memory> |
||||||
|
|
||||||
|
#include <gflags/gflags.h> |
||||||
|
#include "test/core/end2end/data/ssl_test_data.h" |
||||||
|
#include <grpc++/config.h> |
||||||
|
#include <grpc++/server_credentials.h> |
||||||
|
|
||||||
|
DECLARE_bool(enable_ssl); |
||||||
|
|
||||||
|
// In some distros, gflags is in the namespace google, and in some others,
|
||||||
|
// in gflags. This hack is enabling us to find both.
|
||||||
|
namespace google {} |
||||||
|
namespace gflags {} |
||||||
|
using namespace google; |
||||||
|
using namespace gflags; |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace testing { |
||||||
|
|
||||||
|
std::shared_ptr<ServerCredentials> CreateInteropServerCredentials() { |
||||||
|
if (FLAGS_enable_ssl) { |
||||||
|
SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key, |
||||||
|
test_server1_cert}; |
||||||
|
SslServerCredentialsOptions ssl_opts; |
||||||
|
ssl_opts.pem_root_certs = ""; |
||||||
|
ssl_opts.pem_key_cert_pairs.push_back(pkcp); |
||||||
|
return SslServerCredentials(ssl_opts); |
||||||
|
} else { |
||||||
|
return InsecureServerCredentials(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc
|
@ -0,0 +1,49 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_TEST_CPP_INTEROP_SERVER_HELPER_H |
||||||
|
#define GRPC_TEST_CPP_INTEROP_SERVER_HELPER_H |
||||||
|
|
||||||
|
#include <memory> |
||||||
|
|
||||||
|
#include <grpc++/server_credentials.h> |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace testing { |
||||||
|
|
||||||
|
std::shared_ptr<ServerCredentials> CreateInteropServerCredentials(); |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
#endif // GRPC_TEST_CPP_INTEROP_SERVER_HELPER_H
|
@ -0,0 +1,94 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "test/cpp/qps/report.h" |
||||||
|
|
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include "test/cpp/qps/stats.h" |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace testing { |
||||||
|
|
||||||
|
// QPS: XXX
|
||||||
|
void ReportQPS(const ScenarioResult& result) { |
||||||
|
gpr_log(GPR_INFO, "QPS: %.1f", |
||||||
|
result.latencies.Count() / |
||||||
|
average(result.client_resources, |
||||||
|
[](ResourceUsage u) { return u.wall_time; })); |
||||||
|
} |
||||||
|
|
||||||
|
// QPS: XXX (YYY/server core)
|
||||||
|
void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& server_config) { |
||||||
|
auto qps =
|
||||||
|
result.latencies.Count() / |
||||||
|
average(result.client_resources, |
||||||
|
[](ResourceUsage u) { return u.wall_time; }); |
||||||
|
|
||||||
|
gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps, qps/server_config.threads()); |
||||||
|
} |
||||||
|
|
||||||
|
// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
|
||||||
|
void ReportLatency(const ScenarioResult& result) { |
||||||
|
gpr_log(GPR_INFO, "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us", |
||||||
|
result.latencies.Percentile(50) / 1000, |
||||||
|
result.latencies.Percentile(90) / 1000, |
||||||
|
result.latencies.Percentile(95) / 1000, |
||||||
|
result.latencies.Percentile(99) / 1000, |
||||||
|
result.latencies.Percentile(99.9) / 1000); |
||||||
|
} |
||||||
|
|
||||||
|
void ReportTimes(const ScenarioResult& result) { |
||||||
|
gpr_log(GPR_INFO, "Server system time: %.2f%%", |
||||||
|
100.0 * sum(result.server_resources, |
||||||
|
[](ResourceUsage u) { return u.system_time; }) / |
||||||
|
sum(result.server_resources, |
||||||
|
[](ResourceUsage u) { return u.wall_time; })); |
||||||
|
gpr_log(GPR_INFO, "Server user time: %.2f%%", |
||||||
|
100.0 * sum(result.server_resources, |
||||||
|
[](ResourceUsage u) { return u.user_time; }) / |
||||||
|
sum(result.server_resources, |
||||||
|
[](ResourceUsage u) { return u.wall_time; })); |
||||||
|
gpr_log(GPR_INFO, "Client system time: %.2f%%", |
||||||
|
100.0 * sum(result.client_resources, |
||||||
|
[](ResourceUsage u) { return u.system_time; }) / |
||||||
|
sum(result.client_resources, |
||||||
|
[](ResourceUsage u) { return u.wall_time; })); |
||||||
|
gpr_log(GPR_INFO, "Client user time: %.2f%%", |
||||||
|
100.0 * sum(result.client_resources, |
||||||
|
[](ResourceUsage u) { return u.user_time; }) / |
||||||
|
sum(result.client_resources, |
||||||
|
[](ResourceUsage u) { return u.wall_time; })); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc
|
@ -0,0 +1,57 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef TEST_QPS_REPORT_H |
||||||
|
#define TEST_QPS_REPORT_H |
||||||
|
|
||||||
|
#include "test/cpp/qps/driver.h" |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace testing { |
||||||
|
|
||||||
|
// QPS: XXX
|
||||||
|
void ReportQPS(const ScenarioResult& result); |
||||||
|
// QPS: XXX (YYY/server core)
|
||||||
|
void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& config); |
||||||
|
// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
|
||||||
|
void ReportLatency(const ScenarioResult& result); |
||||||
|
// Server system time: XX%
|
||||||
|
// Server user time: XX%
|
||||||
|
// Client system time: XX%
|
||||||
|
// Client user time: XX%
|
||||||
|
void ReportTimes(const ScenarioResult& result); |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,149 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <grpc/support/log.h> |
||||||
|
|
||||||
|
#include "test/cpp/qps/driver.h" |
||||||
|
#include "test/cpp/qps/report.h" |
||||||
|
|
||||||
|
namespace grpc { |
||||||
|
namespace testing { |
||||||
|
|
||||||
|
static const int WARMUP = 5; |
||||||
|
static const int BENCHMARK = 10; |
||||||
|
|
||||||
|
static void RunSynchronousUnaryPingPong() { |
||||||
|
gpr_log(GPR_INFO, "Running Synchronous Unary Ping Pong"); |
||||||
|
|
||||||
|
ClientConfig client_config; |
||||||
|
client_config.set_client_type(SYNCHRONOUS_CLIENT); |
||||||
|
client_config.set_enable_ssl(false); |
||||||
|
client_config.set_outstanding_rpcs_per_channel(1); |
||||||
|
client_config.set_client_channels(1); |
||||||
|
client_config.set_payload_size(1); |
||||||
|
client_config.set_rpc_type(UNARY); |
||||||
|
|
||||||
|
ServerConfig server_config; |
||||||
|
server_config.set_server_type(SYNCHRONOUS_SERVER); |
||||||
|
server_config.set_enable_ssl(false); |
||||||
|
server_config.set_threads(1); |
||||||
|
|
||||||
|
auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK); |
||||||
|
|
||||||
|
ReportQPS(result); |
||||||
|
ReportLatency(result); |
||||||
|
} |
||||||
|
|
||||||
|
static void RunSynchronousStreamingPingPong() { |
||||||
|
gpr_log(GPR_INFO, "Running Synchronous Streaming Ping Pong"); |
||||||
|
|
||||||
|
ClientConfig client_config; |
||||||
|
client_config.set_client_type(SYNCHRONOUS_CLIENT); |
||||||
|
client_config.set_enable_ssl(false); |
||||||
|
client_config.set_outstanding_rpcs_per_channel(1); |
||||||
|
client_config.set_client_channels(1); |
||||||
|
client_config.set_payload_size(1); |
||||||
|
client_config.set_rpc_type(STREAMING); |
||||||
|
|
||||||
|
ServerConfig server_config; |
||||||
|
server_config.set_server_type(SYNCHRONOUS_SERVER); |
||||||
|
server_config.set_enable_ssl(false); |
||||||
|
server_config.set_threads(1); |
||||||
|
|
||||||
|
auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK); |
||||||
|
|
||||||
|
ReportQPS(result); |
||||||
|
ReportLatency(result); |
||||||
|
} |
||||||
|
|
||||||
|
static void RunAsyncUnaryPingPong() { |
||||||
|
gpr_log(GPR_INFO, "Running Async Unary Ping Pong"); |
||||||
|
|
||||||
|
ClientConfig client_config; |
||||||
|
client_config.set_client_type(ASYNC_CLIENT); |
||||||
|
client_config.set_enable_ssl(false); |
||||||
|
client_config.set_outstanding_rpcs_per_channel(1); |
||||||
|
client_config.set_client_channels(1); |
||||||
|
client_config.set_payload_size(1); |
||||||
|
client_config.set_async_client_threads(1); |
||||||
|
client_config.set_rpc_type(UNARY); |
||||||
|
|
||||||
|
ServerConfig server_config; |
||||||
|
server_config.set_server_type(ASYNC_SERVER); |
||||||
|
server_config.set_enable_ssl(false); |
||||||
|
server_config.set_threads(1); |
||||||
|
|
||||||
|
auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK); |
||||||
|
|
||||||
|
ReportQPS(result); |
||||||
|
ReportLatency(result); |
||||||
|
} |
||||||
|
|
||||||
|
static void RunQPS() { |
||||||
|
gpr_log(GPR_INFO, "Running QPS test"); |
||||||
|
|
||||||
|
ClientConfig client_config; |
||||||
|
client_config.set_client_type(ASYNC_CLIENT); |
||||||
|
client_config.set_enable_ssl(false); |
||||||
|
client_config.set_outstanding_rpcs_per_channel(1000); |
||||||
|
client_config.set_client_channels(8); |
||||||
|
client_config.set_payload_size(1); |
||||||
|
client_config.set_async_client_threads(8); |
||||||
|
client_config.set_rpc_type(UNARY); |
||||||
|
|
||||||
|
ServerConfig server_config; |
||||||
|
server_config.set_server_type(ASYNC_SERVER); |
||||||
|
server_config.set_enable_ssl(false); |
||||||
|
server_config.set_threads(4); |
||||||
|
|
||||||
|
auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK); |
||||||
|
|
||||||
|
ReportQPSPerCore(result, server_config); |
||||||
|
ReportLatency(result); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace testing
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
int main(int argc, char** argv) { |
||||||
|
grpc_init(); |
||||||
|
|
||||||
|
using namespace grpc::testing; |
||||||
|
RunSynchronousStreamingPingPong(); |
||||||
|
RunSynchronousUnaryPingPong(); |
||||||
|
RunAsyncUnaryPingPong(); |
||||||
|
RunQPS(); |
||||||
|
|
||||||
|
grpc_shutdown(); |
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
#!/bin/sh |
||||||
|
|
||||||
|
# performs a single qps run with one client and one server |
||||||
|
|
||||||
|
set -ex |
||||||
|
|
||||||
|
cd $(dirname $0)/../../.. |
||||||
|
|
||||||
|
killall qps_worker || true |
||||||
|
|
||||||
|
config=opt |
||||||
|
|
||||||
|
NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'` |
||||||
|
|
||||||
|
make CONFIG=$config qps_worker qps_smoke_test -j$NUMCPUS |
||||||
|
|
||||||
|
bins/$config/qps_worker -driver_port 10000 -server_port 10001 & |
||||||
|
PID1=$! |
||||||
|
bins/$config/qps_worker -driver_port 10010 -server_port 10011 & |
||||||
|
PID2=$! |
||||||
|
|
||||||
|
export QPS_WORKERS="localhost:10000,localhost:10010" |
||||||
|
|
||||||
|
bins/$config/qps_smoke_test $* |
||||||
|
|
||||||
|
kill -2 $PID1 $PID2 |
||||||
|
wait |
||||||
|
|
@ -1 +1 @@ |
|||||||
0.5.1 |
0.6.0 |
||||||
|
@ -1 +1 @@ |
|||||||
0.5.0 |
0.6.0 |
||||||
|
Loading…
Reference in new issue