diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | build.yaml | 2 | ||||
-rw-r--r-- | doc/interop-test-descriptions.md | 161 | ||||
-rw-r--r-- | src/proto/grpc/testing/messages.proto | 17 | ||||
-rw-r--r-- | test/cpp/interop/client.cc | 63 | ||||
-rw-r--r-- | test/cpp/interop/interop_client.cc | 99 | ||||
-rw-r--r-- | test/cpp/interop/interop_client.h | 6 | ||||
-rw-r--r-- | test/cpp/interop/interop_server.cc (renamed from test/cpp/interop/server_main.cc) | 61 | ||||
-rw-r--r-- | test/cpp/interop/rnd.dat | bin | 524288 -> 0 bytes | |||
-rw-r--r-- | test/cpp/interop/server_helper.cc | 4 | ||||
-rw-r--r-- | test/cpp/interop/server_helper.h | 1 | ||||
-rw-r--r-- | tools/run_tests/sources_and_headers.json | 2 | ||||
-rw-r--r-- | vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj | 2 | ||||
-rw-r--r-- | vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters | 2 |
14 files changed, 325 insertions, 101 deletions
@@ -4194,7 +4194,7 @@ LIBINTEROP_SERVER_MAIN_SRC = \ $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \ $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \ - test/cpp/interop/server_main.cc \ + test/cpp/interop/interop_server.cc \ PUBLIC_HEADERS_CXX += \ @@ -4240,7 +4240,7 @@ ifneq ($(NO_DEPS),true) -include $(LIBINTEROP_SERVER_MAIN_OBJS:.o=.dep) endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/interop/server_main.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc LIBQPS_SRC = \ @@ -14569,8 +14569,8 @@ test/cpp/end2end/test_service_impl.cc: $(OPENSSL_DEP) test/cpp/interop/client.cc: $(OPENSSL_DEP) test/cpp/interop/client_helper.cc: $(OPENSSL_DEP) test/cpp/interop/interop_client.cc: $(OPENSSL_DEP) +test/cpp/interop/interop_server.cc: $(OPENSSL_DEP) test/cpp/interop/server_helper.cc: $(OPENSSL_DEP) -test/cpp/interop/server_main.cc: $(OPENSSL_DEP) test/cpp/qps/client_async.cc: $(OPENSSL_DEP) test/cpp/qps/client_sync.cc: $(OPENSSL_DEP) test/cpp/qps/driver.cc: $(OPENSSL_DEP) diff --git a/build.yaml b/build.yaml index 302e3f99e0..335e68409f 100644 --- a/build.yaml +++ b/build.yaml @@ -1101,7 +1101,7 @@ libs: - src/proto/grpc/testing/empty.proto - src/proto/grpc/testing/messages.proto - src/proto/grpc/testing/test.proto - - test/cpp/interop/server_main.cc + - test/cpp/interop/interop_server.cc deps: - interop_server_helper - grpc++_test_util diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md index 63b0022c3f..a023d80c50 100644 --- a/doc/interop-test-descriptions.md +++ b/doc/interop-test-descriptions.md @@ -90,26 +90,84 @@ Client asserts: * clients are free to assert that the response payload body contents are zero and comparing the entire response message against a golden response +### client_compressed_unary + +This test verifies the client can compress unary messages. It sends one +unary request for a compressable payload type, with and without compression. + +Server features: +* [UnaryCall][] +* [Compressed Request][] + +Procedure: + 1. Client calls UnaryCall with: + + ``` + { + expect_compressed_request: true + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + } + ``` + + ``` + { + expect_compressed_request: false + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + } + ``` + + Client asserts: + * call was successful + * response payload type is COMPRESSABLE + * if `request_compressed_response` is false, the response MUST NOT have the + compressed message flag set. + * if `request_compressed_response` is true, the response MUST have the + compressed message flag set. + * 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 + + ### server_compressed_unary -This test verifies compressed server-only unary calls succeed in sending -messages. It sends one unary request for every payload type, with and without -requesting a compressed response from the server. +This test verifies the server can compress unary messages. It sends one unary +request for a COMPRESSABLE payload type, with and without requesting a +compressed response from the server. -In all scenarios, whether compression was actually performed is determined by -the compression bit in the response's message flags. +Whether compression was actually performed is determined by the compression bit +in the response's message flags. Server features: * [UnaryCall][] * [Compressable Payload][] +* [Compressed Response][] Procedure: 1. Client calls UnaryCall with: ``` { - request_compressed_response: bool + request_compressed_response: true + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + } + ``` + + ``` + { + request_compressed_response: false response_type: COMPRESSABLE response_size: 314159 payload:{ @@ -120,10 +178,10 @@ Procedure: Client asserts: * call was successful * response payload type is COMPRESSABLE - * if `request_compressed_response` is false, the response MUST NOT have the - compressed message flag set. - * if `request_compressed_response` is true, the response MUST have the + * when `request_compressed_response` is true, the response MUST have the compressed message flag set. + * when `request_compressed_response` is false, the response MUST NOT have + the compressed message flag set. * 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 @@ -224,11 +282,12 @@ Client asserts: ### server_compressed_streaming -This test verifies that server-only compressed streaming succeeds. +This test verifies that the server can compress streaming messages. Server features: * [StreamingOutputCall][] * [Compressable Payload][] +* [Compressed Response][] Procedure: @@ -262,17 +321,56 @@ Procedure: Client asserts: * call was successful - * exactly four responses + * exactly two responses * response payloads are COMPRESSABLE - * if `request_compressed_response` is false, the response's messages MUST + * when `request_compressed_response` is false, the response's messages MUST NOT have the compressed message flag set. - * if `request_compressed_response` is true, the response's messages MUST + * when `request_compressed_response` is true, the response's messages MUST have the compressed message flag set. * response payload bodies are sized (in order): 31415, 58979 * clients are free to assert that the response payload body contents are zero and comparing the entire response messages against golden responses +### client_compressed_streaming + +This test verifies that the client can compress streaming messages. + +Server features: +* [StreamingInputCall][] +* [Compressed Request][] + +Procedure: + 1. Client calls StreamingInputCall + 1. Client sends: + + ``` + { + expect_compressed_request: true + payload:{ + body: 27182 bytes of zeros + } + } + ``` + + 1. Client then sends: + + ``` + { + expect_compressed_request: false + payload:{ + body: 45904 bytes of zeros + } + } + ``` + + 6. Client half-closes + + Client asserts: + * call was successful + * response aggregated_payload_size is 73086 + + ### ping_pong This test verifies that full duplex bidi is supported. @@ -373,7 +471,8 @@ with desired oauth scope. The test uses `--default_service_account` with GCE service account email and `--oauth_scope` with the OAuth scope to use. For testing against -grpc-test.sandbox.googleapis.com, "https://www.googleapis.com/auth/xapi.zoo" should +grpc-test.sandbox.googleapis.com, "https://www.googleapis.com/auth/xapi.zoo" +should be passed in as `--oauth_scope`. Server features: @@ -400,7 +499,8 @@ Procedure: Client asserts: * call was successful -* received SimpleResponse.username equals the value of `--default_service_account` flag +* received SimpleResponse.username equals the value of + `--default_service_account` flag * received SimpleResponse.oauth_scope is in `--oauth_scope` * response payload body is 314159 bytes in size * clients are free to assert that the response payload body contents are zero @@ -444,7 +544,8 @@ Client asserts: * call was successful * received SimpleResponse.username is not empty and is in the json key file used by the auth library. The client can optionally check the username matches the -email address in the key file or equals the value of `--default_service_account` flag. +email address in the key file or equals the value of `--default_service_account` +flag. * 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 @@ -470,8 +571,8 @@ variable GOOGLE_APPLICATION_CREDENTIALS, *OR* if GCE credentials is used to fetch the token, `--default_service_account` can be used to pass in GCE service account email. - uses the flag `--oauth_scope` for the oauth scope. For testing against -grpc-test.sandbox.googleapis.com, "https://www.googleapis.com/auth/xapi.zoo" should -be passed as the `--oauth_scope`. +grpc-test.sandbox.googleapis.com, "https://www.googleapis.com/auth/xapi.zoo" +should be passed as the `--oauth_scope`. Server features: * [UnaryCall][] @@ -481,7 +582,8 @@ Server features: Procedure: 1. Client uses the auth library to obtain an authorization token - 2. Client configures the channel to use AccessTokenCredentials with the access token obtained in step 1 + 2. Client configures the channel to use AccessTokenCredentials with the access + token obtained in step 1 3. Client calls UnaryCall with the following message ``` @@ -502,17 +604,17 @@ json key file or GCE default service account email. Similar to the other auth tests, this test is only for cloud-to-prod path. -This test verifies unary calls succeed in sending messages using a JWT or a service account -credentials set on the RPC. +This test verifies unary calls succeed in sending messages using a JWT or a +service account credentials set on the RPC. The test - uses the flag `--service_account_key_file` with the path to a json key file downloaded from https://console.developers.google.com. Alternately, if using a usable auth implementation, it may specify the file location in the environment variable GOOGLE_APPLICATION_CREDENTIALS -- optionally uses the flag `--oauth_scope` for the oauth scope if implementator +- optionally uses the flag `--oauth_scope` for the oauth scope if implementator wishes to use service account credential instead of JWT credential. For testing -against grpc-test.sandbox.googleapis.com, oauth scope +against grpc-test.sandbox.googleapis.com, oauth scope "https://www.googleapis.com/auth/xapi.zoo" should be used. Server features: @@ -839,6 +941,19 @@ 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`. +### CompressedResponse +[CompressedResponse]: #compressedresponse + +When the client sets `SimpleRequest.request_compressed_response` to true, the +response is sent back compressed. + +### CompressedRequest +[CompressedRequest]: #compressedrequest + +When the client sets `SimpleRequest.expect_compressed_request ` to true, the +server expects the client request to be compressed. If it's not, it fails +the RPC with `INVALID_ARGUMENT`. + ### StreamingInputCall [StreamingInputCall]: #streaminginputcall diff --git a/src/proto/grpc/testing/messages.proto b/src/proto/grpc/testing/messages.proto index e1090156ab..99b75dea3d 100644 --- a/src/proto/grpc/testing/messages.proto +++ b/src/proto/grpc/testing/messages.proto @@ -38,9 +38,6 @@ package grpc.testing; enum PayloadType { // Compressable text format. COMPRESSABLE = 0; - - // Uncompressable binary format. - UNCOMPRESSABLE = 1; } // A block of data, to simply increase gRPC message size. @@ -82,6 +79,12 @@ message SimpleRequest { // Whether server should return a given status EchoStatus response_status = 7; + + // Whether the server should expect this request to be compressed. + bool expect_compressed_request = 8; + + // The type of payload. + PayloadType payload_type = 9; } // Unary response, as configured by the request. @@ -100,6 +103,12 @@ message StreamingInputCallRequest { // Optional input payload sent along with the request. Payload payload = 1; + // The type of payload. + PayloadType payload_type = 2; + + // Whether the server should expect this request to be compressed. + bool expect_compressed_request = 3; + // Not expecting any payload from the response. } @@ -135,7 +144,7 @@ message StreamingOutputCallRequest { Payload payload = 3; // Whether to request the server to compress the response. - bool request_compressed_response = 6; + bool request_compressed_response = 4; // Whether server should return a given status EchoStatus response_status = 7; diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index 7727824979..c7d081100e 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -40,7 +40,9 @@ #include <grpc++/client_context.h> #include <grpc/grpc.h> #include <grpc/support/log.h> +#include <grpc/support/useful.h> +#include "src/core/lib/support/string.h" #include "test/cpp/interop/client_helper.h" #include "test/cpp/interop/interop_client.h" #include "test/cpp/util/test_config.h" @@ -55,10 +57,14 @@ DEFINE_string(test_case, "large_unary", "Configure different test cases. Valid options are: " "empty_unary : empty (zero bytes) request and response; " "large_unary : single request and (large) response; " - "large_compressed_unary : single request and compressed (large) " - "response; " + + "client_compressed_unary : single compressed request; " + "server_compressed_unary : single compressed response; " + "client_streaming : request streaming with single response; " "server_streaming : single request with response streaming; " + "client_compressed_streaming : compressed request streaming with " + "single response; " "server_compressed_streaming : single request with compressed " "response streaming; " "slow_consumer : single request with response; " @@ -104,14 +110,18 @@ int main(int argc, char** argv) { client.DoEmpty(); } else if (FLAGS_test_case == "large_unary") { client.DoLargeUnary(); - } else if (FLAGS_test_case == "large_compressed_unary") { - client.DoLargeCompressedUnary(); + } else if (FLAGS_test_case == "server_compressed_unary") { + client.DoServerCompressedUnary(); + } else if (FLAGS_test_case == "client_compressed_unary") { + client.DoClientCompressedUnary(); } else if (FLAGS_test_case == "client_streaming") { client.DoRequestStreaming(); } else if (FLAGS_test_case == "server_streaming") { client.DoResponseStreaming(); } else if (FLAGS_test_case == "server_compressed_streaming") { - client.DoResponseCompressedStreaming(); + client.DoServerCompressedStreaming(); + } else if (FLAGS_test_case == "client_compressed_streaming") { + client.DoClientCompressedStreaming(); } else if (FLAGS_test_case == "slow_consumer") { client.DoResponseStreamingWithSlowConsumer(); } else if (FLAGS_test_case == "half_duplex") { @@ -144,9 +154,12 @@ int main(int argc, char** argv) { } else if (FLAGS_test_case == "all") { client.DoEmpty(); client.DoLargeUnary(); + client.DoClientCompressedUnary(); + client.DoServerCompressedUnary(); client.DoRequestStreaming(); client.DoResponseStreaming(); - client.DoResponseCompressedStreaming(); + client.DoClientCompressedStreaming(); + client.DoServerCompressedStreaming(); client.DoHalfDuplex(); client.DoPingPong(); client.DoCancelAfterBegin(); @@ -165,14 +178,36 @@ int main(int argc, char** argv) { } // compute_engine_creds only runs in GCE. } else { - gpr_log( - GPR_ERROR, - "Unsupported test case %s. Valid options are all|empty_unary|" - "large_unary|large_compressed_unary|client_streaming|server_streaming|" - "server_compressed_streaming|half_duplex|ping_pong|cancel_after_begin|" - "cancel_after_first_response|timeout_on_sleeping_server|empty_stream|" - "compute_engine_creds|jwt_token_creds|oauth2_auth_token|per_rpc_creds", - "status_code_and_message|custom_metadata", FLAGS_test_case.c_str()); + const char* testcases[] = + { "all", + "cancel_after_begin", + "cancel_after_first_response", + "client_compressed_streaming", + "client_compressed_unary", + "client_streaming", + "compute_engine_creds", + "custom_metadata", + "empty_stream", + "empty_unary", + "half_duplex", + "jwt_token_creds", + "large_unary", + "oauth2_auth_token", + "oauth2_auth_token", + "per_rpc_creds", + "per_rpc_creds", + "ping_pong", + "server_compressed_streaming", + "server_compressed_unary", + "server_streaming", + "status_code_and_message", + "timeout_on_sleeping_server"}; + char* joined_testcases = + gpr_strjoin_sep(testcases, GPR_ARRAY_SIZE(testcases), "\n", NULL); + + gpr_log(GPR_ERROR, "Unsupported test case %s. Valid options are\n%s", + FLAGS_test_case.c_str(), joined_testcases); + gpr_free(joined_testcases); ret = 1; } diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 7705bb1592..e5d3751402 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -73,23 +73,22 @@ void CompressionChecks(const InteropClientContextInspector& inspector, const SimpleResponse* response) { const grpc_compression_algorithm received_compression = inspector.GetCallCompressionAlgorithm(); - if (request->request_compressed_response() && - received_compression == GRPC_COMPRESS_NONE) { - if (request->request_compressed_response() && - received_compression == GRPC_COMPRESS_NONE) { + if (request->request_compressed_response()) { + if (received_compression == GRPC_COMPRESS_NONE) { // Requested some compression, got NONE. This is an error. gpr_log(GPR_ERROR, "Failure: Requested compression but got uncompressed response " "from server."); abort(); } - } - if (!request->request_compressed_response()) { + if (request->response_type() == PayloadType::COMPRESSABLE) { + // requested compression and compressable response => results should + // always be compressed. + GPR_ASSERT(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS); + } + } else { + // Didn't request compression -> make sure the response is uncompressed GPR_ASSERT(!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS)); - } else if (request->response_type() == PayloadType::COMPRESSABLE) { - // requested compression and compressable response => results should always - // be compressed. - GPR_ASSERT(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS); } } } // namespace @@ -211,17 +210,6 @@ bool InteropClient::PerformLargeUnary(SimpleRequest* request, GPR_ASSERT(response->payload().body() == grpc::string(kLargeResponseSize, '\0')); break; - case PayloadType::UNCOMPRESSABLE: { - // We don't really check anything: We can't assert that the payload is - // uncompressed because it's the server's prerogative to decide on that, - // and different implementations decide differently (ie, Java always - // compresses when requested to do so, whereas C core throws away the - // compressed payload if the output is larger than the input). - // In addition, we don't compare the actual random bytes received because - // asserting that data is sent/received properly isn't the purpose of this - // test. Moreover, different implementations are also free to use - // different sets of random bytes. - } break; default: GPR_ASSERT(false); } @@ -336,9 +324,39 @@ bool InteropClient::DoLargeUnary() { return true; } -bool InteropClient::DoLargeCompressedUnary() { +bool InteropClient::DoClientCompressedUnary() { + const bool expect_compression[] = {false, true}; + const PayloadType payload_types[] = {COMPRESSABLE}; + for (size_t i = 0; i < GPR_ARRAY_SIZE(payload_types); i++) { + for (size_t j = 0; j < GPR_ARRAY_SIZE(expect_compression); j++) { + char* log_suffix; + gpr_asprintf(&log_suffix, "(compression=%s; payload=%s)", + expect_compression[j] ? "true" : "false", + PayloadType_Name(payload_types[i]).c_str()); + + gpr_log(GPR_DEBUG, "Sending compressed unary request %s.", log_suffix); + SimpleRequest request; + SimpleResponse response; + request.set_response_type(payload_types[i]); + request.set_expect_compressed_request(expect_compression[j]); + + if (!PerformLargeUnary(&request, &response, CompressionChecks)) { + gpr_log(GPR_ERROR, "Compressed unary request failed %s", log_suffix); + gpr_free(log_suffix); + return false; + } + + gpr_log(GPR_DEBUG, "Compressed unary request failed %s", log_suffix); + gpr_free(log_suffix); + } + } + + return true; +} + +bool InteropClient::DoServerCompressedUnary() { const bool request_compression[] = {false, true}; - const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE}; + const PayloadType payload_types[] = {COMPRESSABLE}; for (size_t i = 0; i < GPR_ARRAY_SIZE(payload_types); i++) { for (size_t j = 0; j < GPR_ARRAY_SIZE(request_compression); j++) { char* log_suffix; @@ -346,7 +364,7 @@ bool InteropClient::DoLargeCompressedUnary() { request_compression[j] ? "true" : "false", PayloadType_Name(payload_types[i]).c_str()); - gpr_log(GPR_DEBUG, "Sending a large compressed unary rpc %s.", + gpr_log(GPR_DEBUG, "Sending unary request for compressed response %s.", log_suffix); SimpleRequest request; SimpleResponse response; @@ -354,12 +372,13 @@ bool InteropClient::DoLargeCompressedUnary() { request.set_request_compressed_response(request_compression[j]); if (!PerformLargeUnary(&request, &response, CompressionChecks)) { - gpr_log(GPR_ERROR, "Large compressed unary failed %s", log_suffix); + gpr_log(GPR_ERROR, "Request for compressed unary failed %s", + log_suffix); gpr_free(log_suffix); return false; } - gpr_log(GPR_DEBUG, "Large compressed unary done %s.", log_suffix); + gpr_log(GPR_DEBUG, "Request for compressed unary failed %s", log_suffix); gpr_free(log_suffix); } } @@ -447,9 +466,16 @@ bool InteropClient::DoResponseStreaming() { return true; } -bool InteropClient::DoResponseCompressedStreaming() { +bool InteropClient::DoClientCompressedStreaming() { + // XXX + return false; +} + +bool InteropClient::DoServerCompressedStreaming() { const bool request_compression[] = {false, true}; - const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE}; + const PayloadType payload_types[] = {COMPRESSABLE}; + const std::vector<int> response_stream_sizes = {31415, 58979}; + for (size_t i = 0; i < GPR_ARRAY_SIZE(payload_types); i++) { for (size_t j = 0; j < GPR_ARRAY_SIZE(request_compression); j++) { ClientContext context; @@ -466,11 +492,10 @@ bool InteropClient::DoResponseCompressedStreaming() { request.set_response_type(payload_types[i]); request.set_request_compressed_response(request_compression[j]); - for (size_t k = 0; k < response_stream_sizes.size() / 2; ++k) { + for (size_t k = 0; k < response_stream_sizes.size(); ++k) { ResponseParameters* response_parameter = request.add_response_parameters(); - response_parameter->set_size(response_stream_sizes[k] + - response_stream_sizes[k + 1]); + response_parameter->set_size(response_stream_sizes[k]); } StreamingOutputCallResponse response; @@ -484,11 +509,7 @@ bool InteropClient::DoResponseCompressedStreaming() { switch (response.payload().type()) { case PayloadType::COMPRESSABLE: GPR_ASSERT(response.payload().body() == - grpc::string(response_stream_sizes[k] + - response_stream_sizes[k + 1], - '\0')); - break; - case PayloadType::UNCOMPRESSABLE: + grpc::string(response_stream_sizes[k], '\0')); break; default: GPR_ASSERT(false); @@ -516,14 +537,14 @@ bool InteropClient::DoResponseCompressedStreaming() { gpr_log(GPR_DEBUG, "Response streaming done %s.", log_suffix); gpr_free(log_suffix); - if (k < response_stream_sizes.size() / 2) { + if (k < response_stream_sizes.size()) { // stream->Read() failed before reading all the expected messages. This // is most likely due to a connection failure. gpr_log(GPR_ERROR, - "DoResponseCompressedStreaming(): Responses read (k=%d) is " + "DoServerCompressedStreaming(): Responses read (k=%d) is " "less than the expected messages (i.e " "response_stream_sizes.size()/2 (%d)). (i=%d, j=%d)", - k, response_stream_sizes.size() / 2, i, j); + k, response_stream_sizes.size(), i, j); return TransientFailureOrAbort(); } diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h index ae75762bb8..ea44986fbc 100644 --- a/test/cpp/interop/interop_client.h +++ b/test/cpp/interop/interop_client.h @@ -64,12 +64,14 @@ class InteropClient { bool DoEmpty(); bool DoLargeUnary(); - bool DoLargeCompressedUnary(); + bool DoServerCompressedUnary(); + bool DoClientCompressedUnary(); bool DoPingPong(); bool DoHalfDuplex(); bool DoRequestStreaming(); bool DoResponseStreaming(); - bool DoResponseCompressedStreaming(); + bool DoServerCompressedStreaming(); + bool DoClientCompressedStreaming(); bool DoResponseStreamingWithSlowConsumer(); bool DoCancelAfterBegin(); bool DoCancelAfterFirstResponse(); diff --git a/test/cpp/interop/server_main.cc b/test/cpp/interop/interop_server.cc index bbedda14d2..b328f478fa 100644 --- a/test/cpp/interop/server_main.cc +++ b/test/cpp/interop/interop_server.cc @@ -48,6 +48,7 @@ #include <grpc/support/log.h> #include <grpc/support/useful.h> +#include "src/core/lib/transport/byte_stream.h" #include "src/proto/grpc/testing/empty.grpc.pb.h" #include "src/proto/grpc/testing/messages.grpc.pb.h" #include "src/proto/grpc/testing/test.grpc.pb.h" @@ -78,7 +79,6 @@ using grpc::testing::TestService; using grpc::Status; static bool got_sigint = false; -static const char* kRandomFile = "test/cpp/interop/rnd.dat"; const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial"; const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin"; @@ -117,16 +117,8 @@ bool SetPayload(PayloadType response_type, int size, Payload* payload) { std::unique_ptr<char[]> body(new char[size]()); payload->set_body(body.get(), size); } break; - case PayloadType::UNCOMPRESSABLE: { - std::unique_ptr<char[]> body(new char[size]()); - std::ifstream rnd_file(kRandomFile); - GPR_ASSERT(rnd_file.good()); - rnd_file.read(body.get(), size); - GPR_ASSERT(!rnd_file.eof()); // Requested more rnd bytes than available - payload->set_body(body.get(), size); - } break; default: - GPR_ASSERT(false); + return false; } return true; } @@ -140,6 +132,41 @@ void SetResponseCompression(ServerContext* context, } } +template <typename RequestType> +bool CheckExpectedCompression(const ServerContext& context, + const RequestType& request) { + const InteropServerContextInspector inspector(context); + const grpc_compression_algorithm received_compression = + inspector.GetCallCompressionAlgorithm(); + + if (request.expect_compressed_request()) { + if (received_compression == GRPC_COMPRESS_NONE) { + // Expected some compression, got NONE. This is an error. + gpr_log(GPR_ERROR, + "Failure: Expected compression but got uncompressed request " + "from client."); + return false; + } + if (request.payload_type() == PayloadType::COMPRESSABLE) { + if (!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS)) { + gpr_log(GPR_ERROR, + "Failure: Requested compression in a compressable request, but " + "compression bit in message flags not set."); + return false; + } + } + } else { + // Didn't expect compression -> make sure the request is uncompressed + if (inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS) { + gpr_log(GPR_ERROR, + "Failure: Didn't requested compression, but compression bit in " + "message flags set."); + return false; + } + } + return true; +} + class TestServiceImpl : public TestService::Service { public: Status EmptyCall(ServerContext* context, const grpc::testing::Empty* request, @@ -152,10 +179,15 @@ class TestServiceImpl : public TestService::Service { SimpleResponse* response) { MaybeEchoMetadata(context); SetResponseCompression(context, *request); + if (!CheckExpectedCompression(*context, *request)) { + return Status(grpc::StatusCode::INVALID_ARGUMENT, + "Compressed request expectation not met."); + } if (request->response_size() > 0) { if (!SetPayload(request->response_type(), request->response_size(), response->mutable_payload())) { - return Status(grpc::StatusCode::INTERNAL, "Error creating payload."); + return Status(grpc::StatusCode::INVALID_ARGUMENT, + "Error creating payload."); } } @@ -179,7 +211,8 @@ class TestServiceImpl : public TestService::Service { if (!SetPayload(request->response_type(), request->response_parameters(i).size(), response.mutable_payload())) { - return Status(grpc::StatusCode::INTERNAL, "Error creating payload."); + return Status(grpc::StatusCode::INVALID_ARGUMENT, + "Error creating payload."); } write_success = writer->Write(response); } @@ -196,6 +229,10 @@ class TestServiceImpl : public TestService::Service { StreamingInputCallRequest request; int aggregated_payload_size = 0; while (reader->Read(&request)) { + if (!CheckExpectedCompression(*context, request)) { + return Status(grpc::StatusCode::INVALID_ARGUMENT, + "Compressed request expectation not met."); + } if (request.has_payload()) { aggregated_payload_size += request.payload().body().size(); } diff --git a/test/cpp/interop/rnd.dat b/test/cpp/interop/rnd.dat Binary files differdeleted file mode 100644 index 8c7f38f9e0..0000000000 --- a/test/cpp/interop/rnd.dat +++ /dev/null diff --git a/test/cpp/interop/server_helper.cc b/test/cpp/interop/server_helper.cc index c6d891ad71..8b0b511bcb 100644 --- a/test/cpp/interop/server_helper.cc +++ b/test/cpp/interop/server_helper.cc @@ -72,6 +72,10 @@ uint32_t InteropServerContextInspector::GetEncodingsAcceptedByClient() const { return grpc_call_test_only_get_encodings_accepted_by_peer(context_.call_); } +uint32_t InteropServerContextInspector::GetMessageFlags() const { + return grpc_call_test_only_get_message_flags(context_.call_); +} + std::shared_ptr<const AuthContext> InteropServerContextInspector::GetAuthContext() const { return context_.auth_context(); diff --git a/test/cpp/interop/server_helper.h b/test/cpp/interop/server_helper.h index 12865e4032..a1da14a4c8 100644 --- a/test/cpp/interop/server_helper.h +++ b/test/cpp/interop/server_helper.h @@ -54,6 +54,7 @@ class InteropServerContextInspector { bool IsCancelled() const; grpc_compression_algorithm GetCallCompressionAlgorithm() const; uint32_t GetEncodingsAcceptedByClient() const; + uint32_t GetMessageFlags() const; private: const ::grpc::ServerContext& context_; diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index e23c1cb600..5aea0af0a2 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4519,7 +4519,7 @@ "language": "c++", "name": "interop_server_main", "src": [ - "test/cpp/interop/server_main.cc" + "test/cpp/interop/interop_server.cc" ], "third_party": false, "type": "lib" diff --git a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj index 075750afc6..18971d6a34 100644 --- a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj +++ b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj @@ -171,7 +171,7 @@ </ClCompile> <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\test.grpc.pb.h"> </ClInclude> - <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\server_main.cc"> + <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\interop_server.cc"> </ClCompile> </ItemGroup> <ItemGroup> diff --git a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters index 51a6b9e73c..4ee8135c04 100644 --- a/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters +++ b/vsprojects/vcxproj/interop_server_main/interop_server_main.vcxproj.filters @@ -10,7 +10,7 @@ <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\test.proto"> <Filter>src\proto\grpc\testing</Filter> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\server_main.cc"> + <ClCompile Include="$(SolutionDir)\..\test\cpp\interop\interop_server.cc"> <Filter>test\cpp\interop</Filter> </ClCompile> </ItemGroup> |