mirror of https://github.com/grpc/grpc.git
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