xref: /aosp_15_r20/external/grpc-grpc/test/cpp/interop/interop_client.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2015-2016 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker 
19*cc02d7e2SAndroid Build Coastguard Worker #include "test/cpp/interop/interop_client.h"
20*cc02d7e2SAndroid Build Coastguard Worker 
21*cc02d7e2SAndroid Build Coastguard Worker #include <cinttypes>
22*cc02d7e2SAndroid Build Coastguard Worker #include <fstream>
23*cc02d7e2SAndroid Build Coastguard Worker #include <memory>
24*cc02d7e2SAndroid Build Coastguard Worker #include <string>
25*cc02d7e2SAndroid Build Coastguard Worker #include <type_traits>
26*cc02d7e2SAndroid Build Coastguard Worker #include <utility>
27*cc02d7e2SAndroid Build Coastguard Worker 
28*cc02d7e2SAndroid Build Coastguard Worker #include "absl/cleanup/cleanup.h"
29*cc02d7e2SAndroid Build Coastguard Worker #include "absl/strings/match.h"
30*cc02d7e2SAndroid Build Coastguard Worker #include "absl/strings/str_format.h"
31*cc02d7e2SAndroid Build Coastguard Worker #include "absl/strings/str_join.h"
32*cc02d7e2SAndroid Build Coastguard Worker #include "absl/types/optional.h"
33*cc02d7e2SAndroid Build Coastguard Worker 
34*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/grpc.h>
35*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/alloc.h>
36*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/log.h>
37*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/string_util.h>
38*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/time.h>
39*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/channel.h>
40*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/client_context.h>
41*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/security/credentials.h>
42*cc02d7e2SAndroid Build Coastguard Worker 
43*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/config/config_vars.h"
44*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/config/core_configuration.h"
45*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/gprpp/crash.h"
46*cc02d7e2SAndroid Build Coastguard Worker #include "src/proto/grpc/testing/empty.pb.h"
47*cc02d7e2SAndroid Build Coastguard Worker #include "src/proto/grpc/testing/messages.pb.h"
48*cc02d7e2SAndroid Build Coastguard Worker #include "src/proto/grpc/testing/test.grpc.pb.h"
49*cc02d7e2SAndroid Build Coastguard Worker #include "test/core/util/histogram.h"
50*cc02d7e2SAndroid Build Coastguard Worker #include "test/cpp/interop/backend_metrics_lb_policy.h"
51*cc02d7e2SAndroid Build Coastguard Worker #include "test/cpp/interop/client_helper.h"
52*cc02d7e2SAndroid Build Coastguard Worker 
53*cc02d7e2SAndroid Build Coastguard Worker namespace grpc {
54*cc02d7e2SAndroid Build Coastguard Worker namespace testing {
55*cc02d7e2SAndroid Build Coastguard Worker 
56*cc02d7e2SAndroid Build Coastguard Worker namespace {
57*cc02d7e2SAndroid Build Coastguard Worker // The same value is defined by the Java client.
58*cc02d7e2SAndroid Build Coastguard Worker const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
59*cc02d7e2SAndroid Build Coastguard Worker const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979};
60*cc02d7e2SAndroid Build Coastguard Worker const int kNumResponseMessages = 2000;
61*cc02d7e2SAndroid Build Coastguard Worker const int kResponseMessageSize = 1030;
62*cc02d7e2SAndroid Build Coastguard Worker const int kReceiveDelayMilliSeconds = 20;
63*cc02d7e2SAndroid Build Coastguard Worker const int kLargeRequestSize = 271828;
64*cc02d7e2SAndroid Build Coastguard Worker const int kLargeResponseSize = 314159;
65*cc02d7e2SAndroid Build Coastguard Worker 
NoopChecks(const InteropClientContextInspector &,const SimpleRequest *,const SimpleResponse *)66*cc02d7e2SAndroid Build Coastguard Worker void NoopChecks(const InteropClientContextInspector& /*inspector*/,
67*cc02d7e2SAndroid Build Coastguard Worker                 const SimpleRequest* /*request*/,
68*cc02d7e2SAndroid Build Coastguard Worker                 const SimpleResponse* /*response*/) {}
69*cc02d7e2SAndroid Build Coastguard Worker 
UnaryCompressionChecks(const InteropClientContextInspector & inspector,const SimpleRequest * request,const SimpleResponse *)70*cc02d7e2SAndroid Build Coastguard Worker void UnaryCompressionChecks(const InteropClientContextInspector& inspector,
71*cc02d7e2SAndroid Build Coastguard Worker                             const SimpleRequest* request,
72*cc02d7e2SAndroid Build Coastguard Worker                             const SimpleResponse* /*response*/) {
73*cc02d7e2SAndroid Build Coastguard Worker   const grpc_compression_algorithm received_compression =
74*cc02d7e2SAndroid Build Coastguard Worker       inspector.GetCallCompressionAlgorithm();
75*cc02d7e2SAndroid Build Coastguard Worker   if (request->response_compressed().value()) {
76*cc02d7e2SAndroid Build Coastguard Worker     if (received_compression == GRPC_COMPRESS_NONE) {
77*cc02d7e2SAndroid Build Coastguard Worker       // Requested some compression, got NONE. This is an error.
78*cc02d7e2SAndroid Build Coastguard Worker       grpc_core::Crash(
79*cc02d7e2SAndroid Build Coastguard Worker           "Failure: Requested compression but got uncompressed response "
80*cc02d7e2SAndroid Build Coastguard Worker           "from server.");
81*cc02d7e2SAndroid Build Coastguard Worker     }
82*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(inspector.WasCompressed());
83*cc02d7e2SAndroid Build Coastguard Worker   } else {
84*cc02d7e2SAndroid Build Coastguard Worker     // Didn't request compression -> make sure the response is uncompressed
85*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(!(inspector.WasCompressed()));
86*cc02d7e2SAndroid Build Coastguard Worker   }
87*cc02d7e2SAndroid Build Coastguard Worker }
88*cc02d7e2SAndroid Build Coastguard Worker 
ValuesDiff(absl::string_view field,double expected,double actual)89*cc02d7e2SAndroid Build Coastguard Worker absl::optional<std::string> ValuesDiff(absl::string_view field, double expected,
90*cc02d7e2SAndroid Build Coastguard Worker                                        double actual) {
91*cc02d7e2SAndroid Build Coastguard Worker   if (expected != actual) {
92*cc02d7e2SAndroid Build Coastguard Worker     return absl::StrFormat("%s: expected: %f, actual: %f", field, expected,
93*cc02d7e2SAndroid Build Coastguard Worker                            actual);
94*cc02d7e2SAndroid Build Coastguard Worker   }
95*cc02d7e2SAndroid Build Coastguard Worker   return absl::nullopt;
96*cc02d7e2SAndroid Build Coastguard Worker }
97*cc02d7e2SAndroid Build Coastguard Worker 
98*cc02d7e2SAndroid Build Coastguard Worker template <typename Map>
MapsDiff(absl::string_view path,const Map & expected,const Map & actual)99*cc02d7e2SAndroid Build Coastguard Worker absl::optional<std::string> MapsDiff(absl::string_view path,
100*cc02d7e2SAndroid Build Coastguard Worker                                      const Map& expected, const Map& actual) {
101*cc02d7e2SAndroid Build Coastguard Worker   auto result = ValuesDiff(absl::StrFormat("%s size", path), expected.size(),
102*cc02d7e2SAndroid Build Coastguard Worker                            actual.size());
103*cc02d7e2SAndroid Build Coastguard Worker   if (result.has_value()) {
104*cc02d7e2SAndroid Build Coastguard Worker     return result;
105*cc02d7e2SAndroid Build Coastguard Worker   }
106*cc02d7e2SAndroid Build Coastguard Worker   for (const auto& key_value : expected) {
107*cc02d7e2SAndroid Build Coastguard Worker     auto it = actual.find(key_value.first);
108*cc02d7e2SAndroid Build Coastguard Worker     if (it == actual.end()) {
109*cc02d7e2SAndroid Build Coastguard Worker       return absl::StrFormat("In field %s, key %s was not found", path,
110*cc02d7e2SAndroid Build Coastguard Worker                              key_value.first);
111*cc02d7e2SAndroid Build Coastguard Worker     }
112*cc02d7e2SAndroid Build Coastguard Worker     result = ValuesDiff(absl::StrFormat("%s/%s", path, key_value.first),
113*cc02d7e2SAndroid Build Coastguard Worker                         key_value.second, it->second);
114*cc02d7e2SAndroid Build Coastguard Worker     if (result.has_value()) {
115*cc02d7e2SAndroid Build Coastguard Worker       return result;
116*cc02d7e2SAndroid Build Coastguard Worker     }
117*cc02d7e2SAndroid Build Coastguard Worker   }
118*cc02d7e2SAndroid Build Coastguard Worker   return absl::nullopt;
119*cc02d7e2SAndroid Build Coastguard Worker }
120*cc02d7e2SAndroid Build Coastguard Worker 
OrcaLoadReportsDiff(const TestOrcaReport & expected,const TestOrcaReport & actual)121*cc02d7e2SAndroid Build Coastguard Worker absl::optional<std::string> OrcaLoadReportsDiff(const TestOrcaReport& expected,
122*cc02d7e2SAndroid Build Coastguard Worker                                                 const TestOrcaReport& actual) {
123*cc02d7e2SAndroid Build Coastguard Worker   auto error = ValuesDiff("cpu_utilization", expected.cpu_utilization(),
124*cc02d7e2SAndroid Build Coastguard Worker                           actual.cpu_utilization());
125*cc02d7e2SAndroid Build Coastguard Worker   if (error.has_value()) {
126*cc02d7e2SAndroid Build Coastguard Worker     return error;
127*cc02d7e2SAndroid Build Coastguard Worker   }
128*cc02d7e2SAndroid Build Coastguard Worker   error = ValuesDiff("mem_utilization", expected.memory_utilization(),
129*cc02d7e2SAndroid Build Coastguard Worker                      actual.memory_utilization());
130*cc02d7e2SAndroid Build Coastguard Worker   if (error.has_value()) {
131*cc02d7e2SAndroid Build Coastguard Worker     return error;
132*cc02d7e2SAndroid Build Coastguard Worker   }
133*cc02d7e2SAndroid Build Coastguard Worker   error =
134*cc02d7e2SAndroid Build Coastguard Worker       MapsDiff("request_cost", expected.request_cost(), actual.request_cost());
135*cc02d7e2SAndroid Build Coastguard Worker   if (error.has_value()) {
136*cc02d7e2SAndroid Build Coastguard Worker     return error;
137*cc02d7e2SAndroid Build Coastguard Worker   }
138*cc02d7e2SAndroid Build Coastguard Worker   error = MapsDiff("utilization", expected.utilization(), actual.utilization());
139*cc02d7e2SAndroid Build Coastguard Worker   if (error.has_value()) {
140*cc02d7e2SAndroid Build Coastguard Worker     return error;
141*cc02d7e2SAndroid Build Coastguard Worker   }
142*cc02d7e2SAndroid Build Coastguard Worker   return absl::nullopt;
143*cc02d7e2SAndroid Build Coastguard Worker }
144*cc02d7e2SAndroid Build Coastguard Worker }  // namespace
145*cc02d7e2SAndroid Build Coastguard Worker 
ServiceStub(ChannelCreationFunc channel_creation_func,bool new_stub_every_call)146*cc02d7e2SAndroid Build Coastguard Worker InteropClient::ServiceStub::ServiceStub(
147*cc02d7e2SAndroid Build Coastguard Worker     ChannelCreationFunc channel_creation_func, bool new_stub_every_call)
148*cc02d7e2SAndroid Build Coastguard Worker     : channel_creation_func_(std::move(channel_creation_func)),
149*cc02d7e2SAndroid Build Coastguard Worker       new_stub_every_call_(new_stub_every_call) {}
150*cc02d7e2SAndroid Build Coastguard Worker 
Get()151*cc02d7e2SAndroid Build Coastguard Worker TestService::Stub* InteropClient::ServiceStub::Get() {
152*cc02d7e2SAndroid Build Coastguard Worker   if (new_stub_every_call_ || stub_ == nullptr) {
153*cc02d7e2SAndroid Build Coastguard Worker     if (channel_ == nullptr) {
154*cc02d7e2SAndroid Build Coastguard Worker       channel_ = channel_creation_func_();
155*cc02d7e2SAndroid Build Coastguard Worker     }
156*cc02d7e2SAndroid Build Coastguard Worker     stub_ = TestService::NewStub(channel_);
157*cc02d7e2SAndroid Build Coastguard Worker   }
158*cc02d7e2SAndroid Build Coastguard Worker   return stub_.get();
159*cc02d7e2SAndroid Build Coastguard Worker }
160*cc02d7e2SAndroid Build Coastguard Worker 
161*cc02d7e2SAndroid Build Coastguard Worker UnimplementedService::Stub*
GetUnimplementedServiceStub()162*cc02d7e2SAndroid Build Coastguard Worker InteropClient::ServiceStub::GetUnimplementedServiceStub() {
163*cc02d7e2SAndroid Build Coastguard Worker   if (unimplemented_service_stub_ == nullptr) {
164*cc02d7e2SAndroid Build Coastguard Worker     if (channel_ == nullptr) {
165*cc02d7e2SAndroid Build Coastguard Worker       channel_ = channel_creation_func_();
166*cc02d7e2SAndroid Build Coastguard Worker     }
167*cc02d7e2SAndroid Build Coastguard Worker     unimplemented_service_stub_ = UnimplementedService::NewStub(channel_);
168*cc02d7e2SAndroid Build Coastguard Worker   }
169*cc02d7e2SAndroid Build Coastguard Worker   return unimplemented_service_stub_.get();
170*cc02d7e2SAndroid Build Coastguard Worker }
171*cc02d7e2SAndroid Build Coastguard Worker 
ResetChannel()172*cc02d7e2SAndroid Build Coastguard Worker void InteropClient::ServiceStub::ResetChannel() {
173*cc02d7e2SAndroid Build Coastguard Worker   channel_.reset();
174*cc02d7e2SAndroid Build Coastguard Worker   stub_.reset();
175*cc02d7e2SAndroid Build Coastguard Worker }
176*cc02d7e2SAndroid Build Coastguard Worker 
InteropClient(ChannelCreationFunc channel_creation_func,bool new_stub_every_test_case,bool do_not_abort_on_transient_failures)177*cc02d7e2SAndroid Build Coastguard Worker InteropClient::InteropClient(ChannelCreationFunc channel_creation_func,
178*cc02d7e2SAndroid Build Coastguard Worker                              bool new_stub_every_test_case,
179*cc02d7e2SAndroid Build Coastguard Worker                              bool do_not_abort_on_transient_failures)
180*cc02d7e2SAndroid Build Coastguard Worker     : serviceStub_(
181*cc02d7e2SAndroid Build Coastguard Worker           [channel_creation_func = std::move(channel_creation_func), this]() {
182*cc02d7e2SAndroid Build Coastguard Worker             return channel_creation_func(
183*cc02d7e2SAndroid Build Coastguard Worker                 load_report_tracker_.GetChannelArguments());
184*cc02d7e2SAndroid Build Coastguard Worker           },
185*cc02d7e2SAndroid Build Coastguard Worker           new_stub_every_test_case),
186*cc02d7e2SAndroid Build Coastguard Worker       do_not_abort_on_transient_failures_(do_not_abort_on_transient_failures) {}
187*cc02d7e2SAndroid Build Coastguard Worker 
AssertStatusOk(const Status & s,const std::string & optional_debug_string)188*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::AssertStatusOk(const Status& s,
189*cc02d7e2SAndroid Build Coastguard Worker                                    const std::string& optional_debug_string) {
190*cc02d7e2SAndroid Build Coastguard Worker   if (s.ok()) {
191*cc02d7e2SAndroid Build Coastguard Worker     return true;
192*cc02d7e2SAndroid Build Coastguard Worker   }
193*cc02d7e2SAndroid Build Coastguard Worker 
194*cc02d7e2SAndroid Build Coastguard Worker   // Note: At this point, s.error_code is definitely not StatusCode::OK (we
195*cc02d7e2SAndroid Build Coastguard Worker   // already checked for s.ok() above). So, the following will call abort()
196*cc02d7e2SAndroid Build Coastguard Worker   // (unless s.error_code() corresponds to a transient failure and
197*cc02d7e2SAndroid Build Coastguard Worker   // 'do_not_abort_on_transient_failures' is true)
198*cc02d7e2SAndroid Build Coastguard Worker   return AssertStatusCode(s, StatusCode::OK, optional_debug_string);
199*cc02d7e2SAndroid Build Coastguard Worker }
200*cc02d7e2SAndroid Build Coastguard Worker 
AssertStatusCode(const Status & s,StatusCode expected_code,const std::string & optional_debug_string)201*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::AssertStatusCode(const Status& s, StatusCode expected_code,
202*cc02d7e2SAndroid Build Coastguard Worker                                      const std::string& optional_debug_string) {
203*cc02d7e2SAndroid Build Coastguard Worker   if (s.error_code() == expected_code) {
204*cc02d7e2SAndroid Build Coastguard Worker     return true;
205*cc02d7e2SAndroid Build Coastguard Worker   }
206*cc02d7e2SAndroid Build Coastguard Worker 
207*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_ERROR,
208*cc02d7e2SAndroid Build Coastguard Worker           "Error status code: %d (expected: %d), message: %s,"
209*cc02d7e2SAndroid Build Coastguard Worker           " debug string: %s",
210*cc02d7e2SAndroid Build Coastguard Worker           s.error_code(), expected_code, s.error_message().c_str(),
211*cc02d7e2SAndroid Build Coastguard Worker           optional_debug_string.c_str());
212*cc02d7e2SAndroid Build Coastguard Worker 
213*cc02d7e2SAndroid Build Coastguard Worker   // In case of transient transient/retryable failures (like a broken
214*cc02d7e2SAndroid Build Coastguard Worker   // connection) we may or may not abort (see TransientFailureOrAbort())
215*cc02d7e2SAndroid Build Coastguard Worker   if (s.error_code() == grpc::StatusCode::UNAVAILABLE) {
216*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
217*cc02d7e2SAndroid Build Coastguard Worker   }
218*cc02d7e2SAndroid Build Coastguard Worker 
219*cc02d7e2SAndroid Build Coastguard Worker   abort();
220*cc02d7e2SAndroid Build Coastguard Worker }
221*cc02d7e2SAndroid Build Coastguard Worker 
DoEmpty()222*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoEmpty() {
223*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending an empty rpc...");
224*cc02d7e2SAndroid Build Coastguard Worker 
225*cc02d7e2SAndroid Build Coastguard Worker   Empty request;
226*cc02d7e2SAndroid Build Coastguard Worker   Empty response;
227*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
228*cc02d7e2SAndroid Build Coastguard Worker 
229*cc02d7e2SAndroid Build Coastguard Worker   Status s = serviceStub_.Get()->EmptyCall(&context, request, &response);
230*cc02d7e2SAndroid Build Coastguard Worker 
231*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
232*cc02d7e2SAndroid Build Coastguard Worker     return false;
233*cc02d7e2SAndroid Build Coastguard Worker   }
234*cc02d7e2SAndroid Build Coastguard Worker 
235*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Empty rpc done.");
236*cc02d7e2SAndroid Build Coastguard Worker   return true;
237*cc02d7e2SAndroid Build Coastguard Worker }
238*cc02d7e2SAndroid Build Coastguard Worker 
PerformLargeUnary(SimpleRequest * request,SimpleResponse * response)239*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::PerformLargeUnary(SimpleRequest* request,
240*cc02d7e2SAndroid Build Coastguard Worker                                       SimpleResponse* response) {
241*cc02d7e2SAndroid Build Coastguard Worker   return PerformLargeUnary(request, response, NoopChecks);
242*cc02d7e2SAndroid Build Coastguard Worker }
243*cc02d7e2SAndroid Build Coastguard Worker 
PerformLargeUnary(SimpleRequest * request,SimpleResponse * response,const CheckerFn & custom_checks_fn)244*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::PerformLargeUnary(SimpleRequest* request,
245*cc02d7e2SAndroid Build Coastguard Worker                                       SimpleResponse* response,
246*cc02d7e2SAndroid Build Coastguard Worker                                       const CheckerFn& custom_checks_fn) {
247*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
248*cc02d7e2SAndroid Build Coastguard Worker   InteropClientContextInspector inspector(context);
249*cc02d7e2SAndroid Build Coastguard Worker   request->set_response_size(kLargeResponseSize);
250*cc02d7e2SAndroid Build Coastguard Worker   std::string payload(kLargeRequestSize, '\0');
251*cc02d7e2SAndroid Build Coastguard Worker   request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
252*cc02d7e2SAndroid Build Coastguard Worker   if (request->has_expect_compressed()) {
253*cc02d7e2SAndroid Build Coastguard Worker     if (request->expect_compressed().value()) {
254*cc02d7e2SAndroid Build Coastguard Worker       context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
255*cc02d7e2SAndroid Build Coastguard Worker     } else {
256*cc02d7e2SAndroid Build Coastguard Worker       context.set_compression_algorithm(GRPC_COMPRESS_NONE);
257*cc02d7e2SAndroid Build Coastguard Worker     }
258*cc02d7e2SAndroid Build Coastguard Worker   }
259*cc02d7e2SAndroid Build Coastguard Worker 
260*cc02d7e2SAndroid Build Coastguard Worker   Status s = serviceStub_.Get()->UnaryCall(&context, *request, response);
261*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
262*cc02d7e2SAndroid Build Coastguard Worker     return false;
263*cc02d7e2SAndroid Build Coastguard Worker   }
264*cc02d7e2SAndroid Build Coastguard Worker 
265*cc02d7e2SAndroid Build Coastguard Worker   custom_checks_fn(inspector, request, response);
266*cc02d7e2SAndroid Build Coastguard Worker 
267*cc02d7e2SAndroid Build Coastguard Worker   // Payload related checks.
268*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(response->payload().body() ==
269*cc02d7e2SAndroid Build Coastguard Worker              std::string(kLargeResponseSize, '\0'));
270*cc02d7e2SAndroid Build Coastguard Worker   return true;
271*cc02d7e2SAndroid Build Coastguard Worker }
272*cc02d7e2SAndroid Build Coastguard Worker 
DoComputeEngineCreds(const std::string & default_service_account,const std::string & oauth_scope)273*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoComputeEngineCreds(
274*cc02d7e2SAndroid Build Coastguard Worker     const std::string& default_service_account,
275*cc02d7e2SAndroid Build Coastguard Worker     const std::string& oauth_scope) {
276*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG,
277*cc02d7e2SAndroid Build Coastguard Worker           "Sending a large unary rpc with compute engine credentials ...");
278*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
279*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
280*cc02d7e2SAndroid Build Coastguard Worker   request.set_fill_username(true);
281*cc02d7e2SAndroid Build Coastguard Worker   request.set_fill_oauth_scope(true);
282*cc02d7e2SAndroid Build Coastguard Worker 
283*cc02d7e2SAndroid Build Coastguard Worker   if (!PerformLargeUnary(&request, &response)) {
284*cc02d7e2SAndroid Build Coastguard Worker     return false;
285*cc02d7e2SAndroid Build Coastguard Worker   }
286*cc02d7e2SAndroid Build Coastguard Worker 
287*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Got username %s", response.username().c_str());
288*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Got oauth_scope %s", response.oauth_scope().c_str());
289*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!response.username().empty());
290*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(response.username() == default_service_account);
291*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!response.oauth_scope().empty());
292*cc02d7e2SAndroid Build Coastguard Worker   const char* oauth_scope_str = response.oauth_scope().c_str();
293*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(absl::StrContains(oauth_scope, oauth_scope_str));
294*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Large unary with compute engine creds done.");
295*cc02d7e2SAndroid Build Coastguard Worker   return true;
296*cc02d7e2SAndroid Build Coastguard Worker }
297*cc02d7e2SAndroid Build Coastguard Worker 
DoOauth2AuthToken(const std::string & username,const std::string & oauth_scope)298*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoOauth2AuthToken(const std::string& username,
299*cc02d7e2SAndroid Build Coastguard Worker                                       const std::string& oauth_scope) {
300*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG,
301*cc02d7e2SAndroid Build Coastguard Worker           "Sending a unary rpc with raw oauth2 access token credentials ...");
302*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
303*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
304*cc02d7e2SAndroid Build Coastguard Worker   request.set_fill_username(true);
305*cc02d7e2SAndroid Build Coastguard Worker   request.set_fill_oauth_scope(true);
306*cc02d7e2SAndroid Build Coastguard Worker 
307*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
308*cc02d7e2SAndroid Build Coastguard Worker 
309*cc02d7e2SAndroid Build Coastguard Worker   Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
310*cc02d7e2SAndroid Build Coastguard Worker 
311*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
312*cc02d7e2SAndroid Build Coastguard Worker     return false;
313*cc02d7e2SAndroid Build Coastguard Worker   }
314*cc02d7e2SAndroid Build Coastguard Worker 
315*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!response.username().empty());
316*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!response.oauth_scope().empty());
317*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(username == response.username());
318*cc02d7e2SAndroid Build Coastguard Worker   const char* oauth_scope_str = response.oauth_scope().c_str();
319*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(absl::StrContains(oauth_scope, oauth_scope_str));
320*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Unary with oauth2 access token credentials done.");
321*cc02d7e2SAndroid Build Coastguard Worker   return true;
322*cc02d7e2SAndroid Build Coastguard Worker }
323*cc02d7e2SAndroid Build Coastguard Worker 
DoPerRpcCreds(const std::string & json_key)324*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoPerRpcCreds(const std::string& json_key) {
325*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending a unary rpc with per-rpc JWT access token ...");
326*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
327*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
328*cc02d7e2SAndroid Build Coastguard Worker   request.set_fill_username(true);
329*cc02d7e2SAndroid Build Coastguard Worker 
330*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
331*cc02d7e2SAndroid Build Coastguard Worker   std::chrono::seconds token_lifetime = std::chrono::hours(1);
332*cc02d7e2SAndroid Build Coastguard Worker   std::shared_ptr<CallCredentials> creds =
333*cc02d7e2SAndroid Build Coastguard Worker       ServiceAccountJWTAccessCredentials(json_key, token_lifetime.count());
334*cc02d7e2SAndroid Build Coastguard Worker 
335*cc02d7e2SAndroid Build Coastguard Worker   context.set_credentials(creds);
336*cc02d7e2SAndroid Build Coastguard Worker 
337*cc02d7e2SAndroid Build Coastguard Worker   Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
338*cc02d7e2SAndroid Build Coastguard Worker 
339*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
340*cc02d7e2SAndroid Build Coastguard Worker     return false;
341*cc02d7e2SAndroid Build Coastguard Worker   }
342*cc02d7e2SAndroid Build Coastguard Worker 
343*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!response.username().empty());
344*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(json_key.find(response.username()) != std::string::npos);
345*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Unary with per-rpc JWT access token done.");
346*cc02d7e2SAndroid Build Coastguard Worker   return true;
347*cc02d7e2SAndroid Build Coastguard Worker }
348*cc02d7e2SAndroid Build Coastguard Worker 
DoJwtTokenCreds(const std::string & username)349*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoJwtTokenCreds(const std::string& username) {
350*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG,
351*cc02d7e2SAndroid Build Coastguard Worker           "Sending a large unary rpc with JWT token credentials ...");
352*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
353*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
354*cc02d7e2SAndroid Build Coastguard Worker   request.set_fill_username(true);
355*cc02d7e2SAndroid Build Coastguard Worker 
356*cc02d7e2SAndroid Build Coastguard Worker   if (!PerformLargeUnary(&request, &response)) {
357*cc02d7e2SAndroid Build Coastguard Worker     return false;
358*cc02d7e2SAndroid Build Coastguard Worker   }
359*cc02d7e2SAndroid Build Coastguard Worker 
360*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!response.username().empty());
361*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(username.find(response.username()) != std::string::npos);
362*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Large unary with JWT token creds done.");
363*cc02d7e2SAndroid Build Coastguard Worker   return true;
364*cc02d7e2SAndroid Build Coastguard Worker }
365*cc02d7e2SAndroid Build Coastguard Worker 
DoGoogleDefaultCredentials(const std::string & default_service_account)366*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoGoogleDefaultCredentials(
367*cc02d7e2SAndroid Build Coastguard Worker     const std::string& default_service_account) {
368*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG,
369*cc02d7e2SAndroid Build Coastguard Worker           "Sending a large unary rpc with GoogleDefaultCredentials...");
370*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
371*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
372*cc02d7e2SAndroid Build Coastguard Worker   request.set_fill_username(true);
373*cc02d7e2SAndroid Build Coastguard Worker 
374*cc02d7e2SAndroid Build Coastguard Worker   if (!PerformLargeUnary(&request, &response)) {
375*cc02d7e2SAndroid Build Coastguard Worker     return false;
376*cc02d7e2SAndroid Build Coastguard Worker   }
377*cc02d7e2SAndroid Build Coastguard Worker 
378*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Got username %s", response.username().c_str());
379*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!response.username().empty());
380*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(response.username() == default_service_account);
381*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Large unary rpc with GoogleDefaultCredentials done.");
382*cc02d7e2SAndroid Build Coastguard Worker   return true;
383*cc02d7e2SAndroid Build Coastguard Worker }
384*cc02d7e2SAndroid Build Coastguard Worker 
DoLargeUnary()385*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoLargeUnary() {
386*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending a large unary rpc...");
387*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
388*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
389*cc02d7e2SAndroid Build Coastguard Worker   if (!PerformLargeUnary(&request, &response)) {
390*cc02d7e2SAndroid Build Coastguard Worker     return false;
391*cc02d7e2SAndroid Build Coastguard Worker   }
392*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Large unary done.");
393*cc02d7e2SAndroid Build Coastguard Worker   return true;
394*cc02d7e2SAndroid Build Coastguard Worker }
395*cc02d7e2SAndroid Build Coastguard Worker 
DoClientCompressedUnary()396*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoClientCompressedUnary() {
397*cc02d7e2SAndroid Build Coastguard Worker   // Probing for compression-checks support.
398*cc02d7e2SAndroid Build Coastguard Worker   ClientContext probe_context;
399*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest probe_req;
400*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse probe_res;
401*cc02d7e2SAndroid Build Coastguard Worker 
402*cc02d7e2SAndroid Build Coastguard Worker   probe_context.set_compression_algorithm(GRPC_COMPRESS_NONE);
403*cc02d7e2SAndroid Build Coastguard Worker   probe_req.mutable_expect_compressed()->set_value(true);  // lies!
404*cc02d7e2SAndroid Build Coastguard Worker 
405*cc02d7e2SAndroid Build Coastguard Worker   probe_req.set_response_size(kLargeResponseSize);
406*cc02d7e2SAndroid Build Coastguard Worker   probe_req.mutable_payload()->set_body(std::string(kLargeRequestSize, '\0'));
407*cc02d7e2SAndroid Build Coastguard Worker 
408*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending probe for compressed unary request.");
409*cc02d7e2SAndroid Build Coastguard Worker   const Status s =
410*cc02d7e2SAndroid Build Coastguard Worker       serviceStub_.Get()->UnaryCall(&probe_context, probe_req, &probe_res);
411*cc02d7e2SAndroid Build Coastguard Worker   if (s.error_code() != grpc::StatusCode::INVALID_ARGUMENT) {
412*cc02d7e2SAndroid Build Coastguard Worker     // The server isn't able to evaluate incoming compression, making the rest
413*cc02d7e2SAndroid Build Coastguard Worker     // of this test moot.
414*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Compressed unary request probe failed");
415*cc02d7e2SAndroid Build Coastguard Worker     return false;
416*cc02d7e2SAndroid Build Coastguard Worker   }
417*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Compressed unary request probe succeeded. Proceeding.");
418*cc02d7e2SAndroid Build Coastguard Worker 
419*cc02d7e2SAndroid Build Coastguard Worker   const std::vector<bool> compressions = {true, false};
420*cc02d7e2SAndroid Build Coastguard Worker   for (size_t i = 0; i < compressions.size(); i++) {
421*cc02d7e2SAndroid Build Coastguard Worker     std::string log_suffix =
422*cc02d7e2SAndroid Build Coastguard Worker         absl::StrFormat("(compression=%s)", compressions[i] ? "true" : "false");
423*cc02d7e2SAndroid Build Coastguard Worker 
424*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Sending compressed unary request %s.",
425*cc02d7e2SAndroid Build Coastguard Worker             log_suffix.c_str());
426*cc02d7e2SAndroid Build Coastguard Worker     SimpleRequest request;
427*cc02d7e2SAndroid Build Coastguard Worker     SimpleResponse response;
428*cc02d7e2SAndroid Build Coastguard Worker     request.mutable_expect_compressed()->set_value(compressions[i]);
429*cc02d7e2SAndroid Build Coastguard Worker     if (!PerformLargeUnary(&request, &response, UnaryCompressionChecks)) {
430*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "Compressed unary request failed %s",
431*cc02d7e2SAndroid Build Coastguard Worker               log_suffix.c_str());
432*cc02d7e2SAndroid Build Coastguard Worker       return false;
433*cc02d7e2SAndroid Build Coastguard Worker     }
434*cc02d7e2SAndroid Build Coastguard Worker 
435*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Compressed unary request failed %s",
436*cc02d7e2SAndroid Build Coastguard Worker             log_suffix.c_str());
437*cc02d7e2SAndroid Build Coastguard Worker   }
438*cc02d7e2SAndroid Build Coastguard Worker 
439*cc02d7e2SAndroid Build Coastguard Worker   return true;
440*cc02d7e2SAndroid Build Coastguard Worker }
441*cc02d7e2SAndroid Build Coastguard Worker 
DoServerCompressedUnary()442*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoServerCompressedUnary() {
443*cc02d7e2SAndroid Build Coastguard Worker   const std::vector<bool> compressions = {true, false};
444*cc02d7e2SAndroid Build Coastguard Worker   for (size_t i = 0; i < compressions.size(); i++) {
445*cc02d7e2SAndroid Build Coastguard Worker     std::string log_suffix =
446*cc02d7e2SAndroid Build Coastguard Worker         absl::StrFormat("(compression=%s)", compressions[i] ? "true" : "false");
447*cc02d7e2SAndroid Build Coastguard Worker 
448*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Sending unary request for compressed response %s.",
449*cc02d7e2SAndroid Build Coastguard Worker             log_suffix.c_str());
450*cc02d7e2SAndroid Build Coastguard Worker     SimpleRequest request;
451*cc02d7e2SAndroid Build Coastguard Worker     SimpleResponse response;
452*cc02d7e2SAndroid Build Coastguard Worker     request.mutable_response_compressed()->set_value(compressions[i]);
453*cc02d7e2SAndroid Build Coastguard Worker 
454*cc02d7e2SAndroid Build Coastguard Worker     if (!PerformLargeUnary(&request, &response, UnaryCompressionChecks)) {
455*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "Request for compressed unary failed %s",
456*cc02d7e2SAndroid Build Coastguard Worker               log_suffix.c_str());
457*cc02d7e2SAndroid Build Coastguard Worker       return false;
458*cc02d7e2SAndroid Build Coastguard Worker     }
459*cc02d7e2SAndroid Build Coastguard Worker 
460*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Request for compressed unary failed %s",
461*cc02d7e2SAndroid Build Coastguard Worker             log_suffix.c_str());
462*cc02d7e2SAndroid Build Coastguard Worker   }
463*cc02d7e2SAndroid Build Coastguard Worker 
464*cc02d7e2SAndroid Build Coastguard Worker   return true;
465*cc02d7e2SAndroid Build Coastguard Worker }
466*cc02d7e2SAndroid Build Coastguard Worker 
467*cc02d7e2SAndroid Build Coastguard Worker // Either abort() (unless do_not_abort_on_transient_failures_ is true) or return
468*cc02d7e2SAndroid Build Coastguard Worker // false
TransientFailureOrAbort()469*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::TransientFailureOrAbort() {
470*cc02d7e2SAndroid Build Coastguard Worker   if (do_not_abort_on_transient_failures_) {
471*cc02d7e2SAndroid Build Coastguard Worker     return false;
472*cc02d7e2SAndroid Build Coastguard Worker   }
473*cc02d7e2SAndroid Build Coastguard Worker 
474*cc02d7e2SAndroid Build Coastguard Worker   abort();
475*cc02d7e2SAndroid Build Coastguard Worker }
476*cc02d7e2SAndroid Build Coastguard Worker 
DoRequestStreaming()477*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoRequestStreaming() {
478*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending request steaming rpc ...");
479*cc02d7e2SAndroid Build Coastguard Worker 
480*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
481*cc02d7e2SAndroid Build Coastguard Worker   StreamingInputCallRequest request;
482*cc02d7e2SAndroid Build Coastguard Worker   StreamingInputCallResponse response;
483*cc02d7e2SAndroid Build Coastguard Worker 
484*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
485*cc02d7e2SAndroid Build Coastguard Worker       serviceStub_.Get()->StreamingInputCall(&context, &response));
486*cc02d7e2SAndroid Build Coastguard Worker 
487*cc02d7e2SAndroid Build Coastguard Worker   int aggregated_payload_size = 0;
488*cc02d7e2SAndroid Build Coastguard Worker   for (size_t i = 0; i < request_stream_sizes.size(); ++i) {
489*cc02d7e2SAndroid Build Coastguard Worker     Payload* payload = request.mutable_payload();
490*cc02d7e2SAndroid Build Coastguard Worker     payload->set_body(std::string(request_stream_sizes[i], '\0'));
491*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Write(request)) {
492*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoRequestStreaming(): stream->Write() failed");
493*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
494*cc02d7e2SAndroid Build Coastguard Worker     }
495*cc02d7e2SAndroid Build Coastguard Worker     aggregated_payload_size += request_stream_sizes[i];
496*cc02d7e2SAndroid Build Coastguard Worker   }
497*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(stream->WritesDone());
498*cc02d7e2SAndroid Build Coastguard Worker 
499*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
500*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
501*cc02d7e2SAndroid Build Coastguard Worker     return false;
502*cc02d7e2SAndroid Build Coastguard Worker   }
503*cc02d7e2SAndroid Build Coastguard Worker 
504*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(response.aggregated_payload_size() == aggregated_payload_size);
505*cc02d7e2SAndroid Build Coastguard Worker   return true;
506*cc02d7e2SAndroid Build Coastguard Worker }
507*cc02d7e2SAndroid Build Coastguard Worker 
DoResponseStreaming()508*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoResponseStreaming() {
509*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Receiving response streaming rpc ...");
510*cc02d7e2SAndroid Build Coastguard Worker 
511*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
512*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallRequest request;
513*cc02d7e2SAndroid Build Coastguard Worker   for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
514*cc02d7e2SAndroid Build Coastguard Worker     ResponseParameters* response_parameter = request.add_response_parameters();
515*cc02d7e2SAndroid Build Coastguard Worker     response_parameter->set_size(response_stream_sizes[i]);
516*cc02d7e2SAndroid Build Coastguard Worker   }
517*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallResponse response;
518*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
519*cc02d7e2SAndroid Build Coastguard Worker       serviceStub_.Get()->StreamingOutputCall(&context, request));
520*cc02d7e2SAndroid Build Coastguard Worker 
521*cc02d7e2SAndroid Build Coastguard Worker   unsigned int i = 0;
522*cc02d7e2SAndroid Build Coastguard Worker   while (stream->Read(&response)) {
523*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(response.payload().body() ==
524*cc02d7e2SAndroid Build Coastguard Worker                std::string(response_stream_sizes[i], '\0'));
525*cc02d7e2SAndroid Build Coastguard Worker     ++i;
526*cc02d7e2SAndroid Build Coastguard Worker   }
527*cc02d7e2SAndroid Build Coastguard Worker 
528*cc02d7e2SAndroid Build Coastguard Worker   if (i < response_stream_sizes.size()) {
529*cc02d7e2SAndroid Build Coastguard Worker     // stream->Read() failed before reading all the expected messages. This is
530*cc02d7e2SAndroid Build Coastguard Worker     // most likely due to connection failure.
531*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR,
532*cc02d7e2SAndroid Build Coastguard Worker             "DoResponseStreaming(): Read fewer streams (%d) than "
533*cc02d7e2SAndroid Build Coastguard Worker             "response_stream_sizes.size() (%" PRIuPTR ")",
534*cc02d7e2SAndroid Build Coastguard Worker             i, response_stream_sizes.size());
535*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
536*cc02d7e2SAndroid Build Coastguard Worker   }
537*cc02d7e2SAndroid Build Coastguard Worker 
538*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
539*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
540*cc02d7e2SAndroid Build Coastguard Worker     return false;
541*cc02d7e2SAndroid Build Coastguard Worker   }
542*cc02d7e2SAndroid Build Coastguard Worker 
543*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Response streaming done.");
544*cc02d7e2SAndroid Build Coastguard Worker   return true;
545*cc02d7e2SAndroid Build Coastguard Worker }
546*cc02d7e2SAndroid Build Coastguard Worker 
DoClientCompressedStreaming()547*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoClientCompressedStreaming() {
548*cc02d7e2SAndroid Build Coastguard Worker   // Probing for compression-checks support.
549*cc02d7e2SAndroid Build Coastguard Worker   ClientContext probe_context;
550*cc02d7e2SAndroid Build Coastguard Worker   StreamingInputCallRequest probe_req;
551*cc02d7e2SAndroid Build Coastguard Worker   StreamingInputCallResponse probe_res;
552*cc02d7e2SAndroid Build Coastguard Worker 
553*cc02d7e2SAndroid Build Coastguard Worker   probe_context.set_compression_algorithm(GRPC_COMPRESS_NONE);
554*cc02d7e2SAndroid Build Coastguard Worker   probe_req.mutable_expect_compressed()->set_value(true);  // lies!
555*cc02d7e2SAndroid Build Coastguard Worker   probe_req.mutable_payload()->set_body(std::string(27182, '\0'));
556*cc02d7e2SAndroid Build Coastguard Worker 
557*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending probe for compressed streaming request.");
558*cc02d7e2SAndroid Build Coastguard Worker 
559*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientWriter<StreamingInputCallRequest>> probe_stream(
560*cc02d7e2SAndroid Build Coastguard Worker       serviceStub_.Get()->StreamingInputCall(&probe_context, &probe_res));
561*cc02d7e2SAndroid Build Coastguard Worker 
562*cc02d7e2SAndroid Build Coastguard Worker   if (!probe_stream->Write(probe_req)) {
563*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR, "%s(): stream->Write() failed", __func__);
564*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
565*cc02d7e2SAndroid Build Coastguard Worker   }
566*cc02d7e2SAndroid Build Coastguard Worker   Status s = probe_stream->Finish();
567*cc02d7e2SAndroid Build Coastguard Worker   if (s.error_code() != grpc::StatusCode::INVALID_ARGUMENT) {
568*cc02d7e2SAndroid Build Coastguard Worker     // The server isn't able to evaluate incoming compression, making the rest
569*cc02d7e2SAndroid Build Coastguard Worker     // of this test moot.
570*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Compressed streaming request probe failed");
571*cc02d7e2SAndroid Build Coastguard Worker     return false;
572*cc02d7e2SAndroid Build Coastguard Worker   }
573*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG,
574*cc02d7e2SAndroid Build Coastguard Worker           "Compressed streaming request probe succeeded. Proceeding.");
575*cc02d7e2SAndroid Build Coastguard Worker 
576*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
577*cc02d7e2SAndroid Build Coastguard Worker   StreamingInputCallRequest request;
578*cc02d7e2SAndroid Build Coastguard Worker   StreamingInputCallResponse response;
579*cc02d7e2SAndroid Build Coastguard Worker 
580*cc02d7e2SAndroid Build Coastguard Worker   context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
581*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
582*cc02d7e2SAndroid Build Coastguard Worker       serviceStub_.Get()->StreamingInputCall(&context, &response));
583*cc02d7e2SAndroid Build Coastguard Worker 
584*cc02d7e2SAndroid Build Coastguard Worker   request.mutable_payload()->set_body(std::string(27182, '\0'));
585*cc02d7e2SAndroid Build Coastguard Worker   request.mutable_expect_compressed()->set_value(true);
586*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending streaming request with compression enabled");
587*cc02d7e2SAndroid Build Coastguard Worker   if (!stream->Write(request)) {
588*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR, "%s(): stream->Write() failed", __func__);
589*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
590*cc02d7e2SAndroid Build Coastguard Worker   }
591*cc02d7e2SAndroid Build Coastguard Worker 
592*cc02d7e2SAndroid Build Coastguard Worker   WriteOptions wopts;
593*cc02d7e2SAndroid Build Coastguard Worker   wopts.set_no_compression();
594*cc02d7e2SAndroid Build Coastguard Worker   request.mutable_payload()->set_body(std::string(45904, '\0'));
595*cc02d7e2SAndroid Build Coastguard Worker   request.mutable_expect_compressed()->set_value(false);
596*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending streaming request with compression disabled");
597*cc02d7e2SAndroid Build Coastguard Worker   if (!stream->Write(request, wopts)) {
598*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR, "%s(): stream->Write() failed", __func__);
599*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
600*cc02d7e2SAndroid Build Coastguard Worker   }
601*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(stream->WritesDone());
602*cc02d7e2SAndroid Build Coastguard Worker 
603*cc02d7e2SAndroid Build Coastguard Worker   s = stream->Finish();
604*cc02d7e2SAndroid Build Coastguard Worker   return AssertStatusOk(s, context.debug_error_string());
605*cc02d7e2SAndroid Build Coastguard Worker }
606*cc02d7e2SAndroid Build Coastguard Worker 
DoServerCompressedStreaming()607*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoServerCompressedStreaming() {
608*cc02d7e2SAndroid Build Coastguard Worker   const std::vector<bool> compressions = {true, false};
609*cc02d7e2SAndroid Build Coastguard Worker   const std::vector<int> sizes = {31415, 92653};
610*cc02d7e2SAndroid Build Coastguard Worker 
611*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
612*cc02d7e2SAndroid Build Coastguard Worker   InteropClientContextInspector inspector(context);
613*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallRequest request;
614*cc02d7e2SAndroid Build Coastguard Worker 
615*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(compressions.size() == sizes.size());
616*cc02d7e2SAndroid Build Coastguard Worker   for (size_t i = 0; i < sizes.size(); i++) {
617*cc02d7e2SAndroid Build Coastguard Worker     std::string log_suffix =
618*cc02d7e2SAndroid Build Coastguard Worker         absl::StrFormat("(compression=%s; size=%d)",
619*cc02d7e2SAndroid Build Coastguard Worker                         compressions[i] ? "true" : "false", sizes[i]);
620*cc02d7e2SAndroid Build Coastguard Worker 
621*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Sending request streaming rpc %s.", log_suffix.c_str());
622*cc02d7e2SAndroid Build Coastguard Worker 
623*cc02d7e2SAndroid Build Coastguard Worker     ResponseParameters* const response_parameter =
624*cc02d7e2SAndroid Build Coastguard Worker         request.add_response_parameters();
625*cc02d7e2SAndroid Build Coastguard Worker     response_parameter->mutable_compressed()->set_value(compressions[i]);
626*cc02d7e2SAndroid Build Coastguard Worker     response_parameter->set_size(sizes[i]);
627*cc02d7e2SAndroid Build Coastguard Worker   }
628*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
629*cc02d7e2SAndroid Build Coastguard Worker       serviceStub_.Get()->StreamingOutputCall(&context, request));
630*cc02d7e2SAndroid Build Coastguard Worker 
631*cc02d7e2SAndroid Build Coastguard Worker   size_t k = 0;
632*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallResponse response;
633*cc02d7e2SAndroid Build Coastguard Worker   while (stream->Read(&response)) {
634*cc02d7e2SAndroid Build Coastguard Worker     // Payload size checks.
635*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(response.payload().body() ==
636*cc02d7e2SAndroid Build Coastguard Worker                std::string(request.response_parameters(k).size(), '\0'));
637*cc02d7e2SAndroid Build Coastguard Worker 
638*cc02d7e2SAndroid Build Coastguard Worker     // Compression checks.
639*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(request.response_parameters(k).has_compressed());
640*cc02d7e2SAndroid Build Coastguard Worker     if (request.response_parameters(k).compressed().value()) {
641*cc02d7e2SAndroid Build Coastguard Worker       GPR_ASSERT(inspector.GetCallCompressionAlgorithm() > GRPC_COMPRESS_NONE);
642*cc02d7e2SAndroid Build Coastguard Worker       GPR_ASSERT(inspector.WasCompressed());
643*cc02d7e2SAndroid Build Coastguard Worker     } else {
644*cc02d7e2SAndroid Build Coastguard Worker       // requested *no* compression.
645*cc02d7e2SAndroid Build Coastguard Worker       GPR_ASSERT(!(inspector.WasCompressed()));
646*cc02d7e2SAndroid Build Coastguard Worker     }
647*cc02d7e2SAndroid Build Coastguard Worker     ++k;
648*cc02d7e2SAndroid Build Coastguard Worker   }
649*cc02d7e2SAndroid Build Coastguard Worker 
650*cc02d7e2SAndroid Build Coastguard Worker   if (k < sizes.size()) {
651*cc02d7e2SAndroid Build Coastguard Worker     // stream->Read() failed before reading all the expected messages. This
652*cc02d7e2SAndroid Build Coastguard Worker     // is most likely due to a connection failure.
653*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR,
654*cc02d7e2SAndroid Build Coastguard Worker             "%s(): Responses read (k=%" PRIuPTR
655*cc02d7e2SAndroid Build Coastguard Worker             ") is less than the expected number of  messages (%" PRIuPTR ").",
656*cc02d7e2SAndroid Build Coastguard Worker             __func__, k, sizes.size());
657*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
658*cc02d7e2SAndroid Build Coastguard Worker   }
659*cc02d7e2SAndroid Build Coastguard Worker 
660*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
661*cc02d7e2SAndroid Build Coastguard Worker   return AssertStatusOk(s, context.debug_error_string());
662*cc02d7e2SAndroid Build Coastguard Worker }
663*cc02d7e2SAndroid Build Coastguard Worker 
DoResponseStreamingWithSlowConsumer()664*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoResponseStreamingWithSlowConsumer() {
665*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Receiving response streaming rpc with slow consumer ...");
666*cc02d7e2SAndroid Build Coastguard Worker 
667*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
668*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallRequest request;
669*cc02d7e2SAndroid Build Coastguard Worker 
670*cc02d7e2SAndroid Build Coastguard Worker   for (int i = 0; i < kNumResponseMessages; ++i) {
671*cc02d7e2SAndroid Build Coastguard Worker     ResponseParameters* response_parameter = request.add_response_parameters();
672*cc02d7e2SAndroid Build Coastguard Worker     response_parameter->set_size(kResponseMessageSize);
673*cc02d7e2SAndroid Build Coastguard Worker   }
674*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallResponse response;
675*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
676*cc02d7e2SAndroid Build Coastguard Worker       serviceStub_.Get()->StreamingOutputCall(&context, request));
677*cc02d7e2SAndroid Build Coastguard Worker 
678*cc02d7e2SAndroid Build Coastguard Worker   int i = 0;
679*cc02d7e2SAndroid Build Coastguard Worker   while (stream->Read(&response)) {
680*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(response.payload().body() ==
681*cc02d7e2SAndroid Build Coastguard Worker                std::string(kResponseMessageSize, '\0'));
682*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "received message %d", i);
683*cc02d7e2SAndroid Build Coastguard Worker     gpr_sleep_until(gpr_time_add(
684*cc02d7e2SAndroid Build Coastguard Worker         gpr_now(GPR_CLOCK_REALTIME),
685*cc02d7e2SAndroid Build Coastguard Worker         gpr_time_from_millis(kReceiveDelayMilliSeconds, GPR_TIMESPAN)));
686*cc02d7e2SAndroid Build Coastguard Worker     ++i;
687*cc02d7e2SAndroid Build Coastguard Worker   }
688*cc02d7e2SAndroid Build Coastguard Worker 
689*cc02d7e2SAndroid Build Coastguard Worker   if (i < kNumResponseMessages) {
690*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR,
691*cc02d7e2SAndroid Build Coastguard Worker             "DoResponseStreamingWithSlowConsumer(): Responses read (i=%d) is "
692*cc02d7e2SAndroid Build Coastguard Worker             "less than the expected messages (i.e kNumResponseMessages = %d)",
693*cc02d7e2SAndroid Build Coastguard Worker             i, kNumResponseMessages);
694*cc02d7e2SAndroid Build Coastguard Worker 
695*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
696*cc02d7e2SAndroid Build Coastguard Worker   }
697*cc02d7e2SAndroid Build Coastguard Worker 
698*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
699*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
700*cc02d7e2SAndroid Build Coastguard Worker     return false;
701*cc02d7e2SAndroid Build Coastguard Worker   }
702*cc02d7e2SAndroid Build Coastguard Worker 
703*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Response streaming done.");
704*cc02d7e2SAndroid Build Coastguard Worker   return true;
705*cc02d7e2SAndroid Build Coastguard Worker }
706*cc02d7e2SAndroid Build Coastguard Worker 
DoHalfDuplex()707*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoHalfDuplex() {
708*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending half-duplex streaming rpc ...");
709*cc02d7e2SAndroid Build Coastguard Worker 
710*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
711*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
712*cc02d7e2SAndroid Build Coastguard Worker                                      StreamingOutputCallResponse>>
713*cc02d7e2SAndroid Build Coastguard Worker       stream(serviceStub_.Get()->HalfDuplexCall(&context));
714*cc02d7e2SAndroid Build Coastguard Worker 
715*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallRequest request;
716*cc02d7e2SAndroid Build Coastguard Worker   ResponseParameters* response_parameter = request.add_response_parameters();
717*cc02d7e2SAndroid Build Coastguard Worker   for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
718*cc02d7e2SAndroid Build Coastguard Worker     response_parameter->set_size(response_stream_sizes[i]);
719*cc02d7e2SAndroid Build Coastguard Worker 
720*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Write(request)) {
721*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoHalfDuplex(): stream->Write() failed. i=%d", i);
722*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
723*cc02d7e2SAndroid Build Coastguard Worker     }
724*cc02d7e2SAndroid Build Coastguard Worker   }
725*cc02d7e2SAndroid Build Coastguard Worker   stream->WritesDone();
726*cc02d7e2SAndroid Build Coastguard Worker 
727*cc02d7e2SAndroid Build Coastguard Worker   unsigned int i = 0;
728*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallResponse response;
729*cc02d7e2SAndroid Build Coastguard Worker   while (stream->Read(&response)) {
730*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(response.payload().body() ==
731*cc02d7e2SAndroid Build Coastguard Worker                std::string(response_stream_sizes[i], '\0'));
732*cc02d7e2SAndroid Build Coastguard Worker     ++i;
733*cc02d7e2SAndroid Build Coastguard Worker   }
734*cc02d7e2SAndroid Build Coastguard Worker 
735*cc02d7e2SAndroid Build Coastguard Worker   if (i < response_stream_sizes.size()) {
736*cc02d7e2SAndroid Build Coastguard Worker     // stream->Read() failed before reading all the expected messages. This is
737*cc02d7e2SAndroid Build Coastguard Worker     // most likely due to a connection failure
738*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR,
739*cc02d7e2SAndroid Build Coastguard Worker             "DoHalfDuplex(): Responses read (i=%d) are less than the expected "
740*cc02d7e2SAndroid Build Coastguard Worker             "number of messages response_stream_sizes.size() (%" PRIuPTR ")",
741*cc02d7e2SAndroid Build Coastguard Worker             i, response_stream_sizes.size());
742*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
743*cc02d7e2SAndroid Build Coastguard Worker   }
744*cc02d7e2SAndroid Build Coastguard Worker 
745*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
746*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
747*cc02d7e2SAndroid Build Coastguard Worker     return false;
748*cc02d7e2SAndroid Build Coastguard Worker   }
749*cc02d7e2SAndroid Build Coastguard Worker 
750*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Half-duplex streaming rpc done.");
751*cc02d7e2SAndroid Build Coastguard Worker   return true;
752*cc02d7e2SAndroid Build Coastguard Worker }
753*cc02d7e2SAndroid Build Coastguard Worker 
DoPingPong()754*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoPingPong() {
755*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending Ping Pong streaming rpc ...");
756*cc02d7e2SAndroid Build Coastguard Worker 
757*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
758*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
759*cc02d7e2SAndroid Build Coastguard Worker                                      StreamingOutputCallResponse>>
760*cc02d7e2SAndroid Build Coastguard Worker       stream(serviceStub_.Get()->FullDuplexCall(&context));
761*cc02d7e2SAndroid Build Coastguard Worker 
762*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallRequest request;
763*cc02d7e2SAndroid Build Coastguard Worker   ResponseParameters* response_parameter = request.add_response_parameters();
764*cc02d7e2SAndroid Build Coastguard Worker   Payload* payload = request.mutable_payload();
765*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallResponse response;
766*cc02d7e2SAndroid Build Coastguard Worker 
767*cc02d7e2SAndroid Build Coastguard Worker   for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
768*cc02d7e2SAndroid Build Coastguard Worker     response_parameter->set_size(response_stream_sizes[i]);
769*cc02d7e2SAndroid Build Coastguard Worker     payload->set_body(std::string(request_stream_sizes[i], '\0'));
770*cc02d7e2SAndroid Build Coastguard Worker 
771*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Write(request)) {
772*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoPingPong(): stream->Write() failed. i: %d", i);
773*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
774*cc02d7e2SAndroid Build Coastguard Worker     }
775*cc02d7e2SAndroid Build Coastguard Worker 
776*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Read(&response)) {
777*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoPingPong(): stream->Read() failed. i:%d", i);
778*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
779*cc02d7e2SAndroid Build Coastguard Worker     }
780*cc02d7e2SAndroid Build Coastguard Worker 
781*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(response.payload().body() ==
782*cc02d7e2SAndroid Build Coastguard Worker                std::string(response_stream_sizes[i], '\0'));
783*cc02d7e2SAndroid Build Coastguard Worker   }
784*cc02d7e2SAndroid Build Coastguard Worker 
785*cc02d7e2SAndroid Build Coastguard Worker   stream->WritesDone();
786*cc02d7e2SAndroid Build Coastguard Worker 
787*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!stream->Read(&response));
788*cc02d7e2SAndroid Build Coastguard Worker 
789*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
790*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
791*cc02d7e2SAndroid Build Coastguard Worker     return false;
792*cc02d7e2SAndroid Build Coastguard Worker   }
793*cc02d7e2SAndroid Build Coastguard Worker 
794*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Ping pong streaming done.");
795*cc02d7e2SAndroid Build Coastguard Worker   return true;
796*cc02d7e2SAndroid Build Coastguard Worker }
797*cc02d7e2SAndroid Build Coastguard Worker 
DoCancelAfterBegin()798*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoCancelAfterBegin() {
799*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending request streaming rpc ...");
800*cc02d7e2SAndroid Build Coastguard Worker 
801*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
802*cc02d7e2SAndroid Build Coastguard Worker   StreamingInputCallRequest request;
803*cc02d7e2SAndroid Build Coastguard Worker   StreamingInputCallResponse response;
804*cc02d7e2SAndroid Build Coastguard Worker 
805*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
806*cc02d7e2SAndroid Build Coastguard Worker       serviceStub_.Get()->StreamingInputCall(&context, &response));
807*cc02d7e2SAndroid Build Coastguard Worker 
808*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Trying to cancel...");
809*cc02d7e2SAndroid Build Coastguard Worker   context.TryCancel();
810*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
811*cc02d7e2SAndroid Build Coastguard Worker 
812*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusCode(s, StatusCode::CANCELLED,
813*cc02d7e2SAndroid Build Coastguard Worker                         context.debug_error_string())) {
814*cc02d7e2SAndroid Build Coastguard Worker     return false;
815*cc02d7e2SAndroid Build Coastguard Worker   }
816*cc02d7e2SAndroid Build Coastguard Worker 
817*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Canceling streaming done.");
818*cc02d7e2SAndroid Build Coastguard Worker   return true;
819*cc02d7e2SAndroid Build Coastguard Worker }
820*cc02d7e2SAndroid Build Coastguard Worker 
DoCancelAfterFirstResponse()821*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoCancelAfterFirstResponse() {
822*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending Ping Pong streaming rpc ...");
823*cc02d7e2SAndroid Build Coastguard Worker 
824*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
825*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
826*cc02d7e2SAndroid Build Coastguard Worker                                      StreamingOutputCallResponse>>
827*cc02d7e2SAndroid Build Coastguard Worker       stream(serviceStub_.Get()->FullDuplexCall(&context));
828*cc02d7e2SAndroid Build Coastguard Worker 
829*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallRequest request;
830*cc02d7e2SAndroid Build Coastguard Worker   ResponseParameters* response_parameter = request.add_response_parameters();
831*cc02d7e2SAndroid Build Coastguard Worker   response_parameter->set_size(31415);
832*cc02d7e2SAndroid Build Coastguard Worker   request.mutable_payload()->set_body(std::string(27182, '\0'));
833*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallResponse response;
834*cc02d7e2SAndroid Build Coastguard Worker 
835*cc02d7e2SAndroid Build Coastguard Worker   if (!stream->Write(request)) {
836*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR, "DoCancelAfterFirstResponse(): stream->Write() failed");
837*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
838*cc02d7e2SAndroid Build Coastguard Worker   }
839*cc02d7e2SAndroid Build Coastguard Worker 
840*cc02d7e2SAndroid Build Coastguard Worker   if (!stream->Read(&response)) {
841*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR, "DoCancelAfterFirstResponse(): stream->Read failed");
842*cc02d7e2SAndroid Build Coastguard Worker     return TransientFailureOrAbort();
843*cc02d7e2SAndroid Build Coastguard Worker   }
844*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(response.payload().body() == std::string(31415, '\0'));
845*cc02d7e2SAndroid Build Coastguard Worker 
846*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Trying to cancel...");
847*cc02d7e2SAndroid Build Coastguard Worker   context.TryCancel();
848*cc02d7e2SAndroid Build Coastguard Worker 
849*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
850*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Canceling pingpong streaming done.");
851*cc02d7e2SAndroid Build Coastguard Worker   return true;
852*cc02d7e2SAndroid Build Coastguard Worker }
853*cc02d7e2SAndroid Build Coastguard Worker 
DoTimeoutOnSleepingServer()854*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoTimeoutOnSleepingServer() {
855*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG,
856*cc02d7e2SAndroid Build Coastguard Worker           "Sending Ping Pong streaming rpc with a short deadline...");
857*cc02d7e2SAndroid Build Coastguard Worker 
858*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
859*cc02d7e2SAndroid Build Coastguard Worker   std::chrono::system_clock::time_point deadline =
860*cc02d7e2SAndroid Build Coastguard Worker       std::chrono::system_clock::now() + std::chrono::milliseconds(1);
861*cc02d7e2SAndroid Build Coastguard Worker   context.set_deadline(deadline);
862*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
863*cc02d7e2SAndroid Build Coastguard Worker                                      StreamingOutputCallResponse>>
864*cc02d7e2SAndroid Build Coastguard Worker       stream(serviceStub_.Get()->FullDuplexCall(&context));
865*cc02d7e2SAndroid Build Coastguard Worker 
866*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallRequest request;
867*cc02d7e2SAndroid Build Coastguard Worker   request.mutable_payload()->set_body(std::string(27182, '\0'));
868*cc02d7e2SAndroid Build Coastguard Worker   stream->Write(request);
869*cc02d7e2SAndroid Build Coastguard Worker 
870*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
871*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusCode(s, StatusCode::DEADLINE_EXCEEDED,
872*cc02d7e2SAndroid Build Coastguard Worker                         context.debug_error_string())) {
873*cc02d7e2SAndroid Build Coastguard Worker     return false;
874*cc02d7e2SAndroid Build Coastguard Worker   }
875*cc02d7e2SAndroid Build Coastguard Worker 
876*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Pingpong streaming timeout done.");
877*cc02d7e2SAndroid Build Coastguard Worker   return true;
878*cc02d7e2SAndroid Build Coastguard Worker }
879*cc02d7e2SAndroid Build Coastguard Worker 
DoEmptyStream()880*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoEmptyStream() {
881*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Starting empty_stream.");
882*cc02d7e2SAndroid Build Coastguard Worker 
883*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
884*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
885*cc02d7e2SAndroid Build Coastguard Worker                                      StreamingOutputCallResponse>>
886*cc02d7e2SAndroid Build Coastguard Worker       stream(serviceStub_.Get()->FullDuplexCall(&context));
887*cc02d7e2SAndroid Build Coastguard Worker   stream->WritesDone();
888*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallResponse response;
889*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(stream->Read(&response) == false);
890*cc02d7e2SAndroid Build Coastguard Worker 
891*cc02d7e2SAndroid Build Coastguard Worker   Status s = stream->Finish();
892*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(s, context.debug_error_string())) {
893*cc02d7e2SAndroid Build Coastguard Worker     return false;
894*cc02d7e2SAndroid Build Coastguard Worker   }
895*cc02d7e2SAndroid Build Coastguard Worker 
896*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "empty_stream done.");
897*cc02d7e2SAndroid Build Coastguard Worker   return true;
898*cc02d7e2SAndroid Build Coastguard Worker }
899*cc02d7e2SAndroid Build Coastguard Worker 
DoStatusWithMessage()900*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoStatusWithMessage() {
901*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG,
902*cc02d7e2SAndroid Build Coastguard Worker           "Sending RPC with a request for status code 2 and message");
903*cc02d7e2SAndroid Build Coastguard Worker 
904*cc02d7e2SAndroid Build Coastguard Worker   const grpc::StatusCode test_code = grpc::StatusCode::UNKNOWN;
905*cc02d7e2SAndroid Build Coastguard Worker   const std::string test_msg = "This is a test message";
906*cc02d7e2SAndroid Build Coastguard Worker 
907*cc02d7e2SAndroid Build Coastguard Worker   // Test UnaryCall.
908*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
909*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
910*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
911*cc02d7e2SAndroid Build Coastguard Worker   EchoStatus* requested_status = request.mutable_response_status();
912*cc02d7e2SAndroid Build Coastguard Worker   requested_status->set_code(test_code);
913*cc02d7e2SAndroid Build Coastguard Worker   requested_status->set_message(test_msg);
914*cc02d7e2SAndroid Build Coastguard Worker   Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
915*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusCode(s, grpc::StatusCode::UNKNOWN,
916*cc02d7e2SAndroid Build Coastguard Worker                         context.debug_error_string())) {
917*cc02d7e2SAndroid Build Coastguard Worker     return false;
918*cc02d7e2SAndroid Build Coastguard Worker   }
919*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(s.error_message() == test_msg);
920*cc02d7e2SAndroid Build Coastguard Worker 
921*cc02d7e2SAndroid Build Coastguard Worker   // Test FullDuplexCall.
922*cc02d7e2SAndroid Build Coastguard Worker   ClientContext stream_context;
923*cc02d7e2SAndroid Build Coastguard Worker   std::shared_ptr<ClientReaderWriter<StreamingOutputCallRequest,
924*cc02d7e2SAndroid Build Coastguard Worker                                      StreamingOutputCallResponse>>
925*cc02d7e2SAndroid Build Coastguard Worker       stream(serviceStub_.Get()->FullDuplexCall(&stream_context));
926*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallRequest streaming_request;
927*cc02d7e2SAndroid Build Coastguard Worker   requested_status = streaming_request.mutable_response_status();
928*cc02d7e2SAndroid Build Coastguard Worker   requested_status->set_code(test_code);
929*cc02d7e2SAndroid Build Coastguard Worker   requested_status->set_message(test_msg);
930*cc02d7e2SAndroid Build Coastguard Worker   stream->Write(streaming_request);
931*cc02d7e2SAndroid Build Coastguard Worker   stream->WritesDone();
932*cc02d7e2SAndroid Build Coastguard Worker   StreamingOutputCallResponse streaming_response;
933*cc02d7e2SAndroid Build Coastguard Worker   while (stream->Read(&streaming_response)) {
934*cc02d7e2SAndroid Build Coastguard Worker   }
935*cc02d7e2SAndroid Build Coastguard Worker   s = stream->Finish();
936*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusCode(s, grpc::StatusCode::UNKNOWN,
937*cc02d7e2SAndroid Build Coastguard Worker                         context.debug_error_string())) {
938*cc02d7e2SAndroid Build Coastguard Worker     return false;
939*cc02d7e2SAndroid Build Coastguard Worker   }
940*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(s.error_message() == test_msg);
941*cc02d7e2SAndroid Build Coastguard Worker 
942*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Done testing Status and Message");
943*cc02d7e2SAndroid Build Coastguard Worker   return true;
944*cc02d7e2SAndroid Build Coastguard Worker }
945*cc02d7e2SAndroid Build Coastguard Worker 
DoSpecialStatusMessage()946*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoSpecialStatusMessage() {
947*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(
948*cc02d7e2SAndroid Build Coastguard Worker       GPR_DEBUG,
949*cc02d7e2SAndroid Build Coastguard Worker       "Sending RPC with a request for status code 2 and message - \\t\\ntest "
950*cc02d7e2SAndroid Build Coastguard Worker       "with whitespace\\r\\nand Unicode BMP ☺ and non-BMP ��\\t\\n");
951*cc02d7e2SAndroid Build Coastguard Worker   const grpc::StatusCode test_code = grpc::StatusCode::UNKNOWN;
952*cc02d7e2SAndroid Build Coastguard Worker   const std::string test_msg =
953*cc02d7e2SAndroid Build Coastguard Worker       "\t\ntest with whitespace\r\nand Unicode BMP ☺ and non-BMP ��\t\n";
954*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
955*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
956*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
957*cc02d7e2SAndroid Build Coastguard Worker   EchoStatus* requested_status = request.mutable_response_status();
958*cc02d7e2SAndroid Build Coastguard Worker   requested_status->set_code(test_code);
959*cc02d7e2SAndroid Build Coastguard Worker   requested_status->set_message(test_msg);
960*cc02d7e2SAndroid Build Coastguard Worker   Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
961*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusCode(s, grpc::StatusCode::UNKNOWN,
962*cc02d7e2SAndroid Build Coastguard Worker                         context.debug_error_string())) {
963*cc02d7e2SAndroid Build Coastguard Worker     return false;
964*cc02d7e2SAndroid Build Coastguard Worker   }
965*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(s.error_message() == test_msg);
966*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Done testing Special Status Message");
967*cc02d7e2SAndroid Build Coastguard Worker   return true;
968*cc02d7e2SAndroid Build Coastguard Worker }
969*cc02d7e2SAndroid Build Coastguard Worker 
DoPickFirstUnary()970*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoPickFirstUnary() {
971*cc02d7e2SAndroid Build Coastguard Worker   const int rpcCount = 100;
972*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
973*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
974*cc02d7e2SAndroid Build Coastguard Worker   std::string server_id;
975*cc02d7e2SAndroid Build Coastguard Worker   request.set_fill_server_id(true);
976*cc02d7e2SAndroid Build Coastguard Worker   for (int i = 0; i < rpcCount; i++) {
977*cc02d7e2SAndroid Build Coastguard Worker     ClientContext context;
978*cc02d7e2SAndroid Build Coastguard Worker     Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
979*cc02d7e2SAndroid Build Coastguard Worker     if (!AssertStatusOk(s, context.debug_error_string())) {
980*cc02d7e2SAndroid Build Coastguard Worker       return false;
981*cc02d7e2SAndroid Build Coastguard Worker     }
982*cc02d7e2SAndroid Build Coastguard Worker     if (i == 0) {
983*cc02d7e2SAndroid Build Coastguard Worker       server_id = response.server_id();
984*cc02d7e2SAndroid Build Coastguard Worker       continue;
985*cc02d7e2SAndroid Build Coastguard Worker     }
986*cc02d7e2SAndroid Build Coastguard Worker     if (response.server_id() != server_id) {
987*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "#%d rpc hits server_id %s, expect server_id %s", i,
988*cc02d7e2SAndroid Build Coastguard Worker               response.server_id().c_str(), server_id.c_str());
989*cc02d7e2SAndroid Build Coastguard Worker       return false;
990*cc02d7e2SAndroid Build Coastguard Worker     }
991*cc02d7e2SAndroid Build Coastguard Worker   }
992*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "pick first unary successfully finished");
993*cc02d7e2SAndroid Build Coastguard Worker   return true;
994*cc02d7e2SAndroid Build Coastguard Worker }
995*cc02d7e2SAndroid Build Coastguard Worker 
DoOrcaPerRpc()996*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoOrcaPerRpc() {
997*cc02d7e2SAndroid Build Coastguard Worker   load_report_tracker_.ResetCollectedLoadReports();
998*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::CoreConfiguration::RegisterBuilder(RegisterBackendMetricsLbPolicy);
999*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "testing orca per rpc");
1000*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
1001*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
1002*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
1003*cc02d7e2SAndroid Build Coastguard Worker   auto orca_report = request.mutable_orca_per_query_report();
1004*cc02d7e2SAndroid Build Coastguard Worker   orca_report->set_cpu_utilization(0.8210);
1005*cc02d7e2SAndroid Build Coastguard Worker   orca_report->set_memory_utilization(0.5847);
1006*cc02d7e2SAndroid Build Coastguard Worker   orca_report->mutable_request_cost()->emplace("cost", 3456.32);
1007*cc02d7e2SAndroid Build Coastguard Worker   orca_report->mutable_utilization()->emplace("util", 0.30499);
1008*cc02d7e2SAndroid Build Coastguard Worker   auto status = serviceStub_.Get()->UnaryCall(&context, request, &response);
1009*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusOk(status, context.debug_error_string())) {
1010*cc02d7e2SAndroid Build Coastguard Worker     return false;
1011*cc02d7e2SAndroid Build Coastguard Worker   }
1012*cc02d7e2SAndroid Build Coastguard Worker   auto report = load_report_tracker_.GetNextLoadReport();
1013*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(report.has_value());
1014*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(report->has_value());
1015*cc02d7e2SAndroid Build Coastguard Worker   auto comparison_result = OrcaLoadReportsDiff(report->value(), *orca_report);
1016*cc02d7e2SAndroid Build Coastguard Worker   if (comparison_result.has_value()) {
1017*cc02d7e2SAndroid Build Coastguard Worker     gpr_assertion_failed(__FILE__, __LINE__, comparison_result->c_str());
1018*cc02d7e2SAndroid Build Coastguard Worker   }
1019*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!load_report_tracker_.GetNextLoadReport().has_value());
1020*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "orca per rpc successfully finished");
1021*cc02d7e2SAndroid Build Coastguard Worker   return true;
1022*cc02d7e2SAndroid Build Coastguard Worker }
1023*cc02d7e2SAndroid Build Coastguard Worker 
DoOrcaOob()1024*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoOrcaOob() {
1025*cc02d7e2SAndroid Build Coastguard Worker   static constexpr auto kTimeout = absl::Seconds(10);
1026*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_INFO, "testing orca oob");
1027*cc02d7e2SAndroid Build Coastguard Worker   load_report_tracker_.ResetCollectedLoadReports();
1028*cc02d7e2SAndroid Build Coastguard Worker   // Make the backup poller poll very frequently in order to pick up
1029*cc02d7e2SAndroid Build Coastguard Worker   // updates from all the subchannels's FDs.
1030*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ConfigVars::Overrides overrides;
1031*cc02d7e2SAndroid Build Coastguard Worker   overrides.client_channel_backup_poll_interval_ms = 250;
1032*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ConfigVars::SetOverrides(overrides);
1033*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::CoreConfiguration::RegisterBuilder(RegisterBackendMetricsLbPolicy);
1034*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
1035*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
1036*cc02d7e2SAndroid Build Coastguard Worker                                      StreamingOutputCallResponse>>
1037*cc02d7e2SAndroid Build Coastguard Worker       stream(serviceStub_.Get()->FullDuplexCall(&context));
1038*cc02d7e2SAndroid Build Coastguard Worker   auto stream_cleanup = absl::MakeCleanup([&]() {
1039*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(stream->WritesDone());
1040*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(stream->Finish().ok());
1041*cc02d7e2SAndroid Build Coastguard Worker   });
1042*cc02d7e2SAndroid Build Coastguard Worker   {
1043*cc02d7e2SAndroid Build Coastguard Worker     StreamingOutputCallRequest request;
1044*cc02d7e2SAndroid Build Coastguard Worker     request.add_response_parameters()->set_size(1);
1045*cc02d7e2SAndroid Build Coastguard Worker     TestOrcaReport* orca_report = request.mutable_orca_oob_report();
1046*cc02d7e2SAndroid Build Coastguard Worker     orca_report->set_cpu_utilization(0.8210);
1047*cc02d7e2SAndroid Build Coastguard Worker     orca_report->set_memory_utilization(0.5847);
1048*cc02d7e2SAndroid Build Coastguard Worker     orca_report->mutable_utilization()->emplace("util", 0.30499);
1049*cc02d7e2SAndroid Build Coastguard Worker     StreamingOutputCallResponse response;
1050*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Write(request)) {
1051*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoOrcaOob(): stream->Write() failed");
1052*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
1053*cc02d7e2SAndroid Build Coastguard Worker     }
1054*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Read(&response)) {
1055*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoOrcaOob(): stream->Read failed");
1056*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
1057*cc02d7e2SAndroid Build Coastguard Worker     }
1058*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(load_report_tracker_
1059*cc02d7e2SAndroid Build Coastguard Worker                    .WaitForOobLoadReport(
1060*cc02d7e2SAndroid Build Coastguard Worker                        [orca_report](const auto& actual) {
1061*cc02d7e2SAndroid Build Coastguard Worker                          auto value = OrcaLoadReportsDiff(*orca_report, actual);
1062*cc02d7e2SAndroid Build Coastguard Worker                          if (value.has_value()) {
1063*cc02d7e2SAndroid Build Coastguard Worker                            gpr_log(GPR_DEBUG, "Reports mismatch: %s",
1064*cc02d7e2SAndroid Build Coastguard Worker                                    value->c_str());
1065*cc02d7e2SAndroid Build Coastguard Worker                            return false;
1066*cc02d7e2SAndroid Build Coastguard Worker                          }
1067*cc02d7e2SAndroid Build Coastguard Worker                          return true;
1068*cc02d7e2SAndroid Build Coastguard Worker                        },
1069*cc02d7e2SAndroid Build Coastguard Worker                        kTimeout, 10)
1070*cc02d7e2SAndroid Build Coastguard Worker                    .has_value());
1071*cc02d7e2SAndroid Build Coastguard Worker   }
1072*cc02d7e2SAndroid Build Coastguard Worker   {
1073*cc02d7e2SAndroid Build Coastguard Worker     StreamingOutputCallRequest request;
1074*cc02d7e2SAndroid Build Coastguard Worker     request.add_response_parameters()->set_size(1);
1075*cc02d7e2SAndroid Build Coastguard Worker     TestOrcaReport* orca_report = request.mutable_orca_oob_report();
1076*cc02d7e2SAndroid Build Coastguard Worker     orca_report->set_cpu_utilization(0.29309);
1077*cc02d7e2SAndroid Build Coastguard Worker     orca_report->set_memory_utilization(0.2);
1078*cc02d7e2SAndroid Build Coastguard Worker     orca_report->mutable_utilization()->emplace("util", 0.2039);
1079*cc02d7e2SAndroid Build Coastguard Worker     StreamingOutputCallResponse response;
1080*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Write(request)) {
1081*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoOrcaOob(): stream->Write() failed");
1082*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
1083*cc02d7e2SAndroid Build Coastguard Worker     }
1084*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Read(&response)) {
1085*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoOrcaOob(): stream->Read failed");
1086*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
1087*cc02d7e2SAndroid Build Coastguard Worker     }
1088*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(
1089*cc02d7e2SAndroid Build Coastguard Worker         load_report_tracker_
1090*cc02d7e2SAndroid Build Coastguard Worker             .WaitForOobLoadReport(
1091*cc02d7e2SAndroid Build Coastguard Worker                 [orca_report](const auto& report) {
1092*cc02d7e2SAndroid Build Coastguard Worker                   return !OrcaLoadReportsDiff(*orca_report, report).has_value();
1093*cc02d7e2SAndroid Build Coastguard Worker                 },
1094*cc02d7e2SAndroid Build Coastguard Worker                 kTimeout, 10)
1095*cc02d7e2SAndroid Build Coastguard Worker             .has_value());
1096*cc02d7e2SAndroid Build Coastguard Worker   }
1097*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_INFO, "orca oob successfully finished");
1098*cc02d7e2SAndroid Build Coastguard Worker   return true;
1099*cc02d7e2SAndroid Build Coastguard Worker }
1100*cc02d7e2SAndroid Build Coastguard Worker 
DoCustomMetadata()1101*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoCustomMetadata() {
1102*cc02d7e2SAndroid Build Coastguard Worker   const std::string kEchoInitialMetadataKey("x-grpc-test-echo-initial");
1103*cc02d7e2SAndroid Build Coastguard Worker   const std::string kInitialMetadataValue("test_initial_metadata_value");
1104*cc02d7e2SAndroid Build Coastguard Worker   const std::string kEchoTrailingBinMetadataKey(
1105*cc02d7e2SAndroid Build Coastguard Worker       "x-grpc-test-echo-trailing-bin");
1106*cc02d7e2SAndroid Build Coastguard Worker   const std::string kTrailingBinValue("\x0a\x0b\x0a\x0b\x0a\x0b");
1107*cc02d7e2SAndroid Build Coastguard Worker 
1108*cc02d7e2SAndroid Build Coastguard Worker   {
1109*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Sending RPC with custom metadata");
1110*cc02d7e2SAndroid Build Coastguard Worker     ClientContext context;
1111*cc02d7e2SAndroid Build Coastguard Worker     context.AddMetadata(kEchoInitialMetadataKey, kInitialMetadataValue);
1112*cc02d7e2SAndroid Build Coastguard Worker     context.AddMetadata(kEchoTrailingBinMetadataKey, kTrailingBinValue);
1113*cc02d7e2SAndroid Build Coastguard Worker     SimpleRequest request;
1114*cc02d7e2SAndroid Build Coastguard Worker     SimpleResponse response;
1115*cc02d7e2SAndroid Build Coastguard Worker     request.set_response_size(kLargeResponseSize);
1116*cc02d7e2SAndroid Build Coastguard Worker     std::string payload(kLargeRequestSize, '\0');
1117*cc02d7e2SAndroid Build Coastguard Worker     request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
1118*cc02d7e2SAndroid Build Coastguard Worker 
1119*cc02d7e2SAndroid Build Coastguard Worker     Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
1120*cc02d7e2SAndroid Build Coastguard Worker     if (!AssertStatusOk(s, context.debug_error_string())) {
1121*cc02d7e2SAndroid Build Coastguard Worker       return false;
1122*cc02d7e2SAndroid Build Coastguard Worker     }
1123*cc02d7e2SAndroid Build Coastguard Worker 
1124*cc02d7e2SAndroid Build Coastguard Worker     const auto& server_initial_metadata = context.GetServerInitialMetadata();
1125*cc02d7e2SAndroid Build Coastguard Worker     auto iter = server_initial_metadata.find(kEchoInitialMetadataKey);
1126*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(iter != server_initial_metadata.end());
1127*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(iter->second == kInitialMetadataValue);
1128*cc02d7e2SAndroid Build Coastguard Worker     const auto& server_trailing_metadata = context.GetServerTrailingMetadata();
1129*cc02d7e2SAndroid Build Coastguard Worker     iter = server_trailing_metadata.find(kEchoTrailingBinMetadataKey);
1130*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(iter != server_trailing_metadata.end());
1131*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(std::string(iter->second.begin(), iter->second.end()) ==
1132*cc02d7e2SAndroid Build Coastguard Worker                kTrailingBinValue);
1133*cc02d7e2SAndroid Build Coastguard Worker 
1134*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Done testing RPC with custom metadata");
1135*cc02d7e2SAndroid Build Coastguard Worker   }
1136*cc02d7e2SAndroid Build Coastguard Worker 
1137*cc02d7e2SAndroid Build Coastguard Worker   {
1138*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Sending stream with custom metadata");
1139*cc02d7e2SAndroid Build Coastguard Worker     ClientContext context;
1140*cc02d7e2SAndroid Build Coastguard Worker     context.AddMetadata(kEchoInitialMetadataKey, kInitialMetadataValue);
1141*cc02d7e2SAndroid Build Coastguard Worker     context.AddMetadata(kEchoTrailingBinMetadataKey, kTrailingBinValue);
1142*cc02d7e2SAndroid Build Coastguard Worker     std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
1143*cc02d7e2SAndroid Build Coastguard Worker                                        StreamingOutputCallResponse>>
1144*cc02d7e2SAndroid Build Coastguard Worker         stream(serviceStub_.Get()->FullDuplexCall(&context));
1145*cc02d7e2SAndroid Build Coastguard Worker 
1146*cc02d7e2SAndroid Build Coastguard Worker     StreamingOutputCallRequest request;
1147*cc02d7e2SAndroid Build Coastguard Worker     ResponseParameters* response_parameter = request.add_response_parameters();
1148*cc02d7e2SAndroid Build Coastguard Worker     response_parameter->set_size(kLargeResponseSize);
1149*cc02d7e2SAndroid Build Coastguard Worker     std::string payload(kLargeRequestSize, '\0');
1150*cc02d7e2SAndroid Build Coastguard Worker     request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
1151*cc02d7e2SAndroid Build Coastguard Worker     StreamingOutputCallResponse response;
1152*cc02d7e2SAndroid Build Coastguard Worker 
1153*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Write(request)) {
1154*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoCustomMetadata(): stream->Write() failed");
1155*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
1156*cc02d7e2SAndroid Build Coastguard Worker     }
1157*cc02d7e2SAndroid Build Coastguard Worker 
1158*cc02d7e2SAndroid Build Coastguard Worker     stream->WritesDone();
1159*cc02d7e2SAndroid Build Coastguard Worker 
1160*cc02d7e2SAndroid Build Coastguard Worker     if (!stream->Read(&response)) {
1161*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "DoCustomMetadata(): stream->Read() failed");
1162*cc02d7e2SAndroid Build Coastguard Worker       return TransientFailureOrAbort();
1163*cc02d7e2SAndroid Build Coastguard Worker     }
1164*cc02d7e2SAndroid Build Coastguard Worker 
1165*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(response.payload().body() ==
1166*cc02d7e2SAndroid Build Coastguard Worker                std::string(kLargeResponseSize, '\0'));
1167*cc02d7e2SAndroid Build Coastguard Worker 
1168*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(!stream->Read(&response));
1169*cc02d7e2SAndroid Build Coastguard Worker 
1170*cc02d7e2SAndroid Build Coastguard Worker     Status s = stream->Finish();
1171*cc02d7e2SAndroid Build Coastguard Worker     if (!AssertStatusOk(s, context.debug_error_string())) {
1172*cc02d7e2SAndroid Build Coastguard Worker       return false;
1173*cc02d7e2SAndroid Build Coastguard Worker     }
1174*cc02d7e2SAndroid Build Coastguard Worker 
1175*cc02d7e2SAndroid Build Coastguard Worker     const auto& server_initial_metadata = context.GetServerInitialMetadata();
1176*cc02d7e2SAndroid Build Coastguard Worker     auto iter = server_initial_metadata.find(kEchoInitialMetadataKey);
1177*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(iter != server_initial_metadata.end());
1178*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(iter->second == kInitialMetadataValue);
1179*cc02d7e2SAndroid Build Coastguard Worker     const auto& server_trailing_metadata = context.GetServerTrailingMetadata();
1180*cc02d7e2SAndroid Build Coastguard Worker     iter = server_trailing_metadata.find(kEchoTrailingBinMetadataKey);
1181*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(iter != server_trailing_metadata.end());
1182*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(std::string(iter->second.begin(), iter->second.end()) ==
1183*cc02d7e2SAndroid Build Coastguard Worker                kTrailingBinValue);
1184*cc02d7e2SAndroid Build Coastguard Worker 
1185*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Done testing stream with custom metadata");
1186*cc02d7e2SAndroid Build Coastguard Worker   }
1187*cc02d7e2SAndroid Build Coastguard Worker 
1188*cc02d7e2SAndroid Build Coastguard Worker   return true;
1189*cc02d7e2SAndroid Build Coastguard Worker }
1190*cc02d7e2SAndroid Build Coastguard Worker 
1191*cc02d7e2SAndroid Build Coastguard Worker std::tuple<bool, int32_t, std::string, std::string>
PerformOneSoakTestIteration(const bool reset_channel,const int32_t max_acceptable_per_iteration_latency_ms,const int32_t request_size,const int32_t response_size)1192*cc02d7e2SAndroid Build Coastguard Worker InteropClient::PerformOneSoakTestIteration(
1193*cc02d7e2SAndroid Build Coastguard Worker     const bool reset_channel,
1194*cc02d7e2SAndroid Build Coastguard Worker     const int32_t max_acceptable_per_iteration_latency_ms,
1195*cc02d7e2SAndroid Build Coastguard Worker     const int32_t request_size, const int32_t response_size) {
1196*cc02d7e2SAndroid Build Coastguard Worker   gpr_timespec start = gpr_now(GPR_CLOCK_MONOTONIC);
1197*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
1198*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
1199*cc02d7e2SAndroid Build Coastguard Worker   // Don't set the deadline on the RPC, and instead just
1200*cc02d7e2SAndroid Build Coastguard Worker   // record how long the RPC took and compare. This makes
1201*cc02d7e2SAndroid Build Coastguard Worker   // debugging easier when looking at failure results.
1202*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
1203*cc02d7e2SAndroid Build Coastguard Worker   InteropClientContextInspector inspector(context);
1204*cc02d7e2SAndroid Build Coastguard Worker   request.set_response_size(response_size);
1205*cc02d7e2SAndroid Build Coastguard Worker   std::string payload(request_size, '\0');
1206*cc02d7e2SAndroid Build Coastguard Worker   request.mutable_payload()->set_body(payload.c_str(), request_size);
1207*cc02d7e2SAndroid Build Coastguard Worker   if (reset_channel) {
1208*cc02d7e2SAndroid Build Coastguard Worker     serviceStub_.ResetChannel();
1209*cc02d7e2SAndroid Build Coastguard Worker   }
1210*cc02d7e2SAndroid Build Coastguard Worker   Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
1211*cc02d7e2SAndroid Build Coastguard Worker   gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
1212*cc02d7e2SAndroid Build Coastguard Worker   int32_t elapsed_ms = gpr_time_to_millis(gpr_time_sub(now, start));
1213*cc02d7e2SAndroid Build Coastguard Worker   if (!s.ok()) {
1214*cc02d7e2SAndroid Build Coastguard Worker     return std::make_tuple(false, elapsed_ms, context.debug_error_string(),
1215*cc02d7e2SAndroid Build Coastguard Worker                            context.peer());
1216*cc02d7e2SAndroid Build Coastguard Worker   } else if (elapsed_ms > max_acceptable_per_iteration_latency_ms) {
1217*cc02d7e2SAndroid Build Coastguard Worker     std::string debug_string = absl::StrFormat(
1218*cc02d7e2SAndroid Build Coastguard Worker         "%d ms exceeds max acceptable latency: %d ms, peer: %s", elapsed_ms,
1219*cc02d7e2SAndroid Build Coastguard Worker         max_acceptable_per_iteration_latency_ms, context.peer());
1220*cc02d7e2SAndroid Build Coastguard Worker     return std::make_tuple(false, elapsed_ms, std::move(debug_string),
1221*cc02d7e2SAndroid Build Coastguard Worker                            context.peer());
1222*cc02d7e2SAndroid Build Coastguard Worker   } else {
1223*cc02d7e2SAndroid Build Coastguard Worker     return std::make_tuple(true, elapsed_ms, "", context.peer());
1224*cc02d7e2SAndroid Build Coastguard Worker   }
1225*cc02d7e2SAndroid Build Coastguard Worker }
1226*cc02d7e2SAndroid Build Coastguard Worker 
PerformSoakTest(const std::string & server_uri,const bool reset_channel_per_iteration,const int32_t soak_iterations,const int32_t max_failures,const int32_t max_acceptable_per_iteration_latency_ms,const int32_t min_time_ms_between_rpcs,const int32_t overall_timeout_seconds,const int32_t request_size,const int32_t response_size)1227*cc02d7e2SAndroid Build Coastguard Worker void InteropClient::PerformSoakTest(
1228*cc02d7e2SAndroid Build Coastguard Worker     const std::string& server_uri, const bool reset_channel_per_iteration,
1229*cc02d7e2SAndroid Build Coastguard Worker     const int32_t soak_iterations, const int32_t max_failures,
1230*cc02d7e2SAndroid Build Coastguard Worker     const int32_t max_acceptable_per_iteration_latency_ms,
1231*cc02d7e2SAndroid Build Coastguard Worker     const int32_t min_time_ms_between_rpcs,
1232*cc02d7e2SAndroid Build Coastguard Worker     const int32_t overall_timeout_seconds, const int32_t request_size,
1233*cc02d7e2SAndroid Build Coastguard Worker     const int32_t response_size) {
1234*cc02d7e2SAndroid Build Coastguard Worker   std::vector<std::tuple<bool, int32_t, std::string, std::string>> results;
1235*cc02d7e2SAndroid Build Coastguard Worker   grpc_histogram* latencies_ms_histogram = grpc_histogram_create(
1236*cc02d7e2SAndroid Build Coastguard Worker       1 /* resolution */,
1237*cc02d7e2SAndroid Build Coastguard Worker       500 * 1e3 /* largest bucket; 500 seconds is unlikely */);
1238*cc02d7e2SAndroid Build Coastguard Worker   gpr_timespec overall_deadline = gpr_time_add(
1239*cc02d7e2SAndroid Build Coastguard Worker       gpr_now(GPR_CLOCK_MONOTONIC),
1240*cc02d7e2SAndroid Build Coastguard Worker       gpr_time_from_seconds(overall_timeout_seconds, GPR_TIMESPAN));
1241*cc02d7e2SAndroid Build Coastguard Worker   int32_t iterations_ran = 0;
1242*cc02d7e2SAndroid Build Coastguard Worker   int total_failures = 0;
1243*cc02d7e2SAndroid Build Coastguard Worker   for (int i = 0;
1244*cc02d7e2SAndroid Build Coastguard Worker        i < soak_iterations &&
1245*cc02d7e2SAndroid Build Coastguard Worker        gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), overall_deadline) < 0;
1246*cc02d7e2SAndroid Build Coastguard Worker        ++i) {
1247*cc02d7e2SAndroid Build Coastguard Worker     gpr_timespec earliest_next_start = gpr_time_add(
1248*cc02d7e2SAndroid Build Coastguard Worker         gpr_now(GPR_CLOCK_MONOTONIC),
1249*cc02d7e2SAndroid Build Coastguard Worker         gpr_time_from_millis(min_time_ms_between_rpcs, GPR_TIMESPAN));
1250*cc02d7e2SAndroid Build Coastguard Worker     auto result = PerformOneSoakTestIteration(
1251*cc02d7e2SAndroid Build Coastguard Worker         reset_channel_per_iteration, max_acceptable_per_iteration_latency_ms,
1252*cc02d7e2SAndroid Build Coastguard Worker         request_size, response_size);
1253*cc02d7e2SAndroid Build Coastguard Worker     bool success = std::get<0>(result);
1254*cc02d7e2SAndroid Build Coastguard Worker     int32_t elapsed_ms = std::get<1>(result);
1255*cc02d7e2SAndroid Build Coastguard Worker     std::string debug_string = std::get<2>(result);
1256*cc02d7e2SAndroid Build Coastguard Worker     std::string peer = std::get<3>(result);
1257*cc02d7e2SAndroid Build Coastguard Worker     results.push_back(result);
1258*cc02d7e2SAndroid Build Coastguard Worker     if (!success) {
1259*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_INFO,
1260*cc02d7e2SAndroid Build Coastguard Worker               "soak iteration: %d elapsed_ms: %d peer: %s server_uri: %s "
1261*cc02d7e2SAndroid Build Coastguard Worker               "failed: %s",
1262*cc02d7e2SAndroid Build Coastguard Worker               i, elapsed_ms, peer.c_str(), server_uri.c_str(),
1263*cc02d7e2SAndroid Build Coastguard Worker               debug_string.c_str());
1264*cc02d7e2SAndroid Build Coastguard Worker       total_failures++;
1265*cc02d7e2SAndroid Build Coastguard Worker     } else {
1266*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(
1267*cc02d7e2SAndroid Build Coastguard Worker           GPR_INFO,
1268*cc02d7e2SAndroid Build Coastguard Worker           "soak iteration: %d elapsed_ms: %d peer: %s server_uri: %s succeeded",
1269*cc02d7e2SAndroid Build Coastguard Worker           i, elapsed_ms, peer.c_str(), server_uri.c_str());
1270*cc02d7e2SAndroid Build Coastguard Worker     }
1271*cc02d7e2SAndroid Build Coastguard Worker     grpc_histogram_add(latencies_ms_histogram, std::get<1>(result));
1272*cc02d7e2SAndroid Build Coastguard Worker     iterations_ran++;
1273*cc02d7e2SAndroid Build Coastguard Worker     gpr_sleep_until(earliest_next_start);
1274*cc02d7e2SAndroid Build Coastguard Worker   }
1275*cc02d7e2SAndroid Build Coastguard Worker   double latency_ms_median =
1276*cc02d7e2SAndroid Build Coastguard Worker       grpc_histogram_percentile(latencies_ms_histogram, 50);
1277*cc02d7e2SAndroid Build Coastguard Worker   double latency_ms_90th =
1278*cc02d7e2SAndroid Build Coastguard Worker       grpc_histogram_percentile(latencies_ms_histogram, 90);
1279*cc02d7e2SAndroid Build Coastguard Worker   double latency_ms_worst = grpc_histogram_maximum(latencies_ms_histogram);
1280*cc02d7e2SAndroid Build Coastguard Worker   grpc_histogram_destroy(latencies_ms_histogram);
1281*cc02d7e2SAndroid Build Coastguard Worker   if (iterations_ran < soak_iterations) {
1282*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(
1283*cc02d7e2SAndroid Build Coastguard Worker         GPR_ERROR,
1284*cc02d7e2SAndroid Build Coastguard Worker         "(server_uri: %s) soak test consumed all %d seconds of time and quit "
1285*cc02d7e2SAndroid Build Coastguard Worker         "early, only "
1286*cc02d7e2SAndroid Build Coastguard Worker         "having ran %d out of desired %d iterations. "
1287*cc02d7e2SAndroid Build Coastguard Worker         "total_failures: %d. "
1288*cc02d7e2SAndroid Build Coastguard Worker         "max_failures_threshold: %d. "
1289*cc02d7e2SAndroid Build Coastguard Worker         "median_soak_iteration_latency: %lf ms. "
1290*cc02d7e2SAndroid Build Coastguard Worker         "90th_soak_iteration_latency: %lf ms. "
1291*cc02d7e2SAndroid Build Coastguard Worker         "worst_soak_iteration_latency: %lf ms. "
1292*cc02d7e2SAndroid Build Coastguard Worker         "Some or all of the iterations that did run were unexpectedly slow. "
1293*cc02d7e2SAndroid Build Coastguard Worker         "See breakdown above for which iterations succeeded, failed, and "
1294*cc02d7e2SAndroid Build Coastguard Worker         "why for more info.",
1295*cc02d7e2SAndroid Build Coastguard Worker         server_uri.c_str(), overall_timeout_seconds, iterations_ran,
1296*cc02d7e2SAndroid Build Coastguard Worker         soak_iterations, total_failures, max_failures, latency_ms_median,
1297*cc02d7e2SAndroid Build Coastguard Worker         latency_ms_90th, latency_ms_worst);
1298*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(0);
1299*cc02d7e2SAndroid Build Coastguard Worker   } else if (total_failures > max_failures) {
1300*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_ERROR,
1301*cc02d7e2SAndroid Build Coastguard Worker             "(server_uri: %s) soak test ran: %d iterations. total_failures: %d "
1302*cc02d7e2SAndroid Build Coastguard Worker             "exceeds "
1303*cc02d7e2SAndroid Build Coastguard Worker             "max_failures_threshold: %d. "
1304*cc02d7e2SAndroid Build Coastguard Worker             "median_soak_iteration_latency: %lf ms. "
1305*cc02d7e2SAndroid Build Coastguard Worker             "90th_soak_iteration_latency: %lf ms. "
1306*cc02d7e2SAndroid Build Coastguard Worker             "worst_soak_iteration_latency: %lf ms. "
1307*cc02d7e2SAndroid Build Coastguard Worker             "See breakdown above for which iterations succeeded, failed, and "
1308*cc02d7e2SAndroid Build Coastguard Worker             "why for more info.",
1309*cc02d7e2SAndroid Build Coastguard Worker             server_uri.c_str(), soak_iterations, total_failures, max_failures,
1310*cc02d7e2SAndroid Build Coastguard Worker             latency_ms_median, latency_ms_90th, latency_ms_worst);
1311*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(0);
1312*cc02d7e2SAndroid Build Coastguard Worker   } else {
1313*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_INFO,
1314*cc02d7e2SAndroid Build Coastguard Worker             "(server_uri: %s) soak test ran: %d iterations. total_failures: %d "
1315*cc02d7e2SAndroid Build Coastguard Worker             "is within "
1316*cc02d7e2SAndroid Build Coastguard Worker             "max_failures_threshold: %d. "
1317*cc02d7e2SAndroid Build Coastguard Worker             "median_soak_iteration_latency: %lf ms. "
1318*cc02d7e2SAndroid Build Coastguard Worker             "90th_soak_iteration_latency: %lf ms. "
1319*cc02d7e2SAndroid Build Coastguard Worker             "worst_soak_iteration_latency: %lf ms. "
1320*cc02d7e2SAndroid Build Coastguard Worker             "See breakdown above for which iterations succeeded, failed, and "
1321*cc02d7e2SAndroid Build Coastguard Worker             "why for more info.",
1322*cc02d7e2SAndroid Build Coastguard Worker             server_uri.c_str(), soak_iterations, total_failures, max_failures,
1323*cc02d7e2SAndroid Build Coastguard Worker             latency_ms_median, latency_ms_90th, latency_ms_worst);
1324*cc02d7e2SAndroid Build Coastguard Worker   }
1325*cc02d7e2SAndroid Build Coastguard Worker }
1326*cc02d7e2SAndroid Build Coastguard Worker 
DoRpcSoakTest(const std::string & server_uri,int32_t soak_iterations,int32_t max_failures,int64_t max_acceptable_per_iteration_latency_ms,int32_t soak_min_time_ms_between_rpcs,int32_t overall_timeout_seconds,int32_t request_size,int32_t response_size)1327*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoRpcSoakTest(
1328*cc02d7e2SAndroid Build Coastguard Worker     const std::string& server_uri, int32_t soak_iterations,
1329*cc02d7e2SAndroid Build Coastguard Worker     int32_t max_failures, int64_t max_acceptable_per_iteration_latency_ms,
1330*cc02d7e2SAndroid Build Coastguard Worker     int32_t soak_min_time_ms_between_rpcs, int32_t overall_timeout_seconds,
1331*cc02d7e2SAndroid Build Coastguard Worker     int32_t request_size, int32_t response_size) {
1332*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending %d RPCs...", soak_iterations);
1333*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(soak_iterations > 0);
1334*cc02d7e2SAndroid Build Coastguard Worker   PerformSoakTest(server_uri, false /* reset channel per iteration */,
1335*cc02d7e2SAndroid Build Coastguard Worker                   soak_iterations, max_failures,
1336*cc02d7e2SAndroid Build Coastguard Worker                   max_acceptable_per_iteration_latency_ms,
1337*cc02d7e2SAndroid Build Coastguard Worker                   soak_min_time_ms_between_rpcs, overall_timeout_seconds,
1338*cc02d7e2SAndroid Build Coastguard Worker                   request_size, response_size);
1339*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "rpc_soak test done.");
1340*cc02d7e2SAndroid Build Coastguard Worker   return true;
1341*cc02d7e2SAndroid Build Coastguard Worker }
1342*cc02d7e2SAndroid Build Coastguard Worker 
DoChannelSoakTest(const std::string & server_uri,int32_t soak_iterations,int32_t max_failures,int64_t max_acceptable_per_iteration_latency_ms,int32_t soak_min_time_ms_between_rpcs,int32_t overall_timeout_seconds,int32_t request_size,int32_t response_size)1343*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoChannelSoakTest(
1344*cc02d7e2SAndroid Build Coastguard Worker     const std::string& server_uri, int32_t soak_iterations,
1345*cc02d7e2SAndroid Build Coastguard Worker     int32_t max_failures, int64_t max_acceptable_per_iteration_latency_ms,
1346*cc02d7e2SAndroid Build Coastguard Worker     int32_t soak_min_time_ms_between_rpcs, int32_t overall_timeout_seconds,
1347*cc02d7e2SAndroid Build Coastguard Worker     int32_t request_size, int32_t response_size) {
1348*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending %d RPCs, tearing down the channel each time...",
1349*cc02d7e2SAndroid Build Coastguard Worker           soak_iterations);
1350*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(soak_iterations > 0);
1351*cc02d7e2SAndroid Build Coastguard Worker   PerformSoakTest(server_uri, true /* reset channel per iteration */,
1352*cc02d7e2SAndroid Build Coastguard Worker                   soak_iterations, max_failures,
1353*cc02d7e2SAndroid Build Coastguard Worker                   max_acceptable_per_iteration_latency_ms,
1354*cc02d7e2SAndroid Build Coastguard Worker                   soak_min_time_ms_between_rpcs, overall_timeout_seconds,
1355*cc02d7e2SAndroid Build Coastguard Worker                   request_size, response_size);
1356*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "channel_soak test done.");
1357*cc02d7e2SAndroid Build Coastguard Worker   return true;
1358*cc02d7e2SAndroid Build Coastguard Worker }
1359*cc02d7e2SAndroid Build Coastguard Worker 
DoLongLivedChannelTest(int32_t soak_iterations,int32_t iteration_interval)1360*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoLongLivedChannelTest(int32_t soak_iterations,
1361*cc02d7e2SAndroid Build Coastguard Worker                                            int32_t iteration_interval) {
1362*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending %d RPCs...", soak_iterations);
1363*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(soak_iterations > 0);
1364*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(iteration_interval > 0);
1365*cc02d7e2SAndroid Build Coastguard Worker   SimpleRequest request;
1366*cc02d7e2SAndroid Build Coastguard Worker   SimpleResponse response;
1367*cc02d7e2SAndroid Build Coastguard Worker   int num_failures = 0;
1368*cc02d7e2SAndroid Build Coastguard Worker   for (int i = 0; i < soak_iterations; ++i) {
1369*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "Sending RPC number %d...", i);
1370*cc02d7e2SAndroid Build Coastguard Worker     if (!PerformLargeUnary(&request, &response)) {
1371*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_ERROR, "Iteration %d failed.", i);
1372*cc02d7e2SAndroid Build Coastguard Worker       num_failures++;
1373*cc02d7e2SAndroid Build Coastguard Worker     }
1374*cc02d7e2SAndroid Build Coastguard Worker     gpr_sleep_until(
1375*cc02d7e2SAndroid Build Coastguard Worker         gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
1376*cc02d7e2SAndroid Build Coastguard Worker                      gpr_time_from_seconds(iteration_interval, GPR_TIMESPAN)));
1377*cc02d7e2SAndroid Build Coastguard Worker   }
1378*cc02d7e2SAndroid Build Coastguard Worker   if (num_failures == 0) {
1379*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "long_lived_channel test done.");
1380*cc02d7e2SAndroid Build Coastguard Worker     return true;
1381*cc02d7e2SAndroid Build Coastguard Worker   } else {
1382*cc02d7e2SAndroid Build Coastguard Worker     gpr_log(GPR_DEBUG, "long_lived_channel test failed with %d rpc failures.",
1383*cc02d7e2SAndroid Build Coastguard Worker             num_failures);
1384*cc02d7e2SAndroid Build Coastguard Worker     return false;
1385*cc02d7e2SAndroid Build Coastguard Worker   }
1386*cc02d7e2SAndroid Build Coastguard Worker }
1387*cc02d7e2SAndroid Build Coastguard Worker 
DoUnimplementedService()1388*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoUnimplementedService() {
1389*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending a request for an unimplemented service...");
1390*cc02d7e2SAndroid Build Coastguard Worker 
1391*cc02d7e2SAndroid Build Coastguard Worker   Empty request;
1392*cc02d7e2SAndroid Build Coastguard Worker   Empty response;
1393*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
1394*cc02d7e2SAndroid Build Coastguard Worker 
1395*cc02d7e2SAndroid Build Coastguard Worker   UnimplementedService::Stub* stub = serviceStub_.GetUnimplementedServiceStub();
1396*cc02d7e2SAndroid Build Coastguard Worker 
1397*cc02d7e2SAndroid Build Coastguard Worker   Status s = stub->UnimplementedCall(&context, request, &response);
1398*cc02d7e2SAndroid Build Coastguard Worker 
1399*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED,
1400*cc02d7e2SAndroid Build Coastguard Worker                         context.debug_error_string())) {
1401*cc02d7e2SAndroid Build Coastguard Worker     return false;
1402*cc02d7e2SAndroid Build Coastguard Worker   }
1403*cc02d7e2SAndroid Build Coastguard Worker 
1404*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "unimplemented service done.");
1405*cc02d7e2SAndroid Build Coastguard Worker   return true;
1406*cc02d7e2SAndroid Build Coastguard Worker }
1407*cc02d7e2SAndroid Build Coastguard Worker 
DoUnimplementedMethod()1408*cc02d7e2SAndroid Build Coastguard Worker bool InteropClient::DoUnimplementedMethod() {
1409*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "Sending a request for an unimplemented rpc...");
1410*cc02d7e2SAndroid Build Coastguard Worker 
1411*cc02d7e2SAndroid Build Coastguard Worker   Empty request;
1412*cc02d7e2SAndroid Build Coastguard Worker   Empty response;
1413*cc02d7e2SAndroid Build Coastguard Worker   ClientContext context;
1414*cc02d7e2SAndroid Build Coastguard Worker 
1415*cc02d7e2SAndroid Build Coastguard Worker   Status s =
1416*cc02d7e2SAndroid Build Coastguard Worker       serviceStub_.Get()->UnimplementedCall(&context, request, &response);
1417*cc02d7e2SAndroid Build Coastguard Worker 
1418*cc02d7e2SAndroid Build Coastguard Worker   if (!AssertStatusCode(s, StatusCode::UNIMPLEMENTED,
1419*cc02d7e2SAndroid Build Coastguard Worker                         context.debug_error_string())) {
1420*cc02d7e2SAndroid Build Coastguard Worker     return false;
1421*cc02d7e2SAndroid Build Coastguard Worker   }
1422*cc02d7e2SAndroid Build Coastguard Worker 
1423*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_DEBUG, "unimplemented rpc done.");
1424*cc02d7e2SAndroid Build Coastguard Worker   return true;
1425*cc02d7e2SAndroid Build Coastguard Worker }
1426*cc02d7e2SAndroid Build Coastguard Worker 
1427*cc02d7e2SAndroid Build Coastguard Worker }  // namespace testing
1428*cc02d7e2SAndroid Build Coastguard Worker }  // namespace grpc
1429