test/cpp/interop/client.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <memory>
20 #include <unordered_map>
21 
22 #include "absl/flags/flag.h"
23 
24 #include <grpc/grpc.h>
25 #include <grpc/support/alloc.h>
26 #include <grpc/support/log.h>
27 #include <grpcpp/channel.h>
28 #include <grpcpp/client_context.h>
29 
35 
36 ABSL_FLAG(bool, use_alts, false,
37  "Whether to use alts. Enable alts will disable tls.");
38 ABSL_FLAG(bool, use_tls, false, "Whether to use tls.");
40  "User provided credentials type.");
41 ABSL_FLAG(bool, use_test_ca, false, "False to use SSL roots for google");
42 ABSL_FLAG(int32_t, server_port, 0, "Server port.");
43 ABSL_FLAG(std::string, server_host, "localhost", "Server host to connect to");
44 ABSL_FLAG(std::string, server_host_override, "",
45  "Override the server host which is sent in HTTP header");
46 ABSL_FLAG(
47  std::string, test_case, "large_unary",
48  "Configure different test cases. Valid options are:\n\n"
49  "all : all test cases;\n"
50 
51  // TODO(veblush): Replace the help message with the following full message
52  // once Abseil fixes the flag-help compiler error on Windows. (b/171659833)
53  /*
54  "cancel_after_begin : cancel stream after starting it;\n"
55  "cancel_after_first_response: cancel on first response;\n"
56  "channel_soak: sends 'soak_iterations' rpcs, rebuilds channel each time;\n"
57  "client_compressed_streaming : compressed request streaming with "
58  "client_compressed_unary : single compressed request;\n"
59  "client_streaming : request streaming with single response;\n"
60  "compute_engine_creds: large_unary with compute engine auth;\n"
61  "custom_metadata: server will echo custom metadata;\n"
62  "empty_stream : bi-di stream with no request/response;\n"
63  "empty_unary : empty (zero bytes) request and response;\n"
64  "google_default_credentials: large unary using GDC;\n"
65  "half_duplex : half-duplex streaming;\n"
66  "jwt_token_creds: large_unary with JWT token auth;\n"
67  "large_unary : single request and (large) response;\n"
68  "long_lived_channel: sends large_unary rpcs over a long-lived channel;\n"
69  "oauth2_auth_token: raw oauth2 access token auth;\n"
70  "per_rpc_creds: raw oauth2 access token on a single rpc;\n"
71  "ping_pong : full-duplex streaming;\n"
72  "response streaming;\n"
73  "rpc_soak: 'sends soak_iterations' large_unary rpcs;\n"
74  "server_compressed_streaming : single request with compressed "
75  "server_compressed_unary : single compressed response;\n"
76  "server_streaming : single request with response streaming;\n"
77  "slow_consumer : single request with response streaming with "
78  "slow client consumer;\n"
79  "special_status_message: verify Unicode and whitespace in status message;\n"
80  "status_code_and_message: verify status code & message;\n"
81  "timeout_on_sleeping_server: deadline exceeds on stream;\n"
82  "unimplemented_method: client calls an unimplemented method;\n"
83  "unimplemented_service: client calls an unimplemented service;\n"
84  */
85 );
86 ABSL_FLAG(std::string, default_service_account, "",
87  "Email of GCE default service account");
88 ABSL_FLAG(std::string, service_account_key_file, "",
89  "Path to service account json key file.");
90 ABSL_FLAG(std::string, oauth_scope, "", "Scope for OAuth tokens.");
91 ABSL_FLAG(bool, do_not_abort_on_transient_failures, false,
92  "If set to 'true', abort() is not called in case of transient "
93  "failures (i.e failures that are temporary and will likely go away "
94  "on retrying; like a temporary connection failure) and an error "
95  "message is printed instead. Note that this flag just controls "
96  "whether abort() is called or not. It does not control whether the "
97  "test is retried in case of transient failures (and currently the "
98  "interop tests are not retried even if this flag is set to true)");
99 ABSL_FLAG(int32_t, soak_iterations, 1000,
100  "The number of iterations to use for the two soak tests; rpc_soak "
101  "and channel_soak.");
102 ABSL_FLAG(int32_t, soak_max_failures, 0,
103  "The number of iterations in soak tests that are allowed to fail "
104  "(either due to non-OK status code or exceeding the "
105  "per-iteration max acceptable latency).");
106 ABSL_FLAG(int32_t, soak_per_iteration_max_acceptable_latency_ms, 0,
107  "The number of milliseconds a single iteration in the two soak "
108  "tests (rpc_soak and channel_soak) should take.");
109 ABSL_FLAG(int32_t, soak_overall_timeout_seconds, 0,
110  "The overall number of seconds after which a soak test should "
111  "stop and fail, if the desired number of iterations have not yet "
112  "completed.");
113 ABSL_FLAG(int32_t, soak_min_time_ms_between_rpcs, 0,
114  "The minimum time in milliseconds between consecutive RPCs in a "
115  "soak test (rpc_soak or channel_soak), useful for limiting QPS");
116 ABSL_FLAG(int32_t, iteration_interval, 10,
117  "The interval in seconds between rpcs. This is used by "
118  "long_connection test");
119 ABSL_FLAG(std::string, additional_metadata, "",
120  "Additional metadata to send in each request, as a "
121  "semicolon-separated list of key:value pairs.");
122 ABSL_FLAG(
123  bool, log_metadata_and_status, false,
124  "If set to 'true', will print received initial and trailing metadata, "
125  "grpc-status and error message to the console, in a stable format.");
126 
130 
131 namespace {
132 
133 // Parse the contents of FLAGS_additional_metadata into a map. Allow
134 // alphanumeric characters and dashes in keys, and any character but semicolons
135 // in values. Convert keys to lowercase. On failure, log an error and return
136 // false.
137 bool ParseAdditionalMetadataFlag(
138  const std::string& flag,
139  std::multimap<std::string, std::string>* additional_metadata) {
140  size_t start_pos = 0;
141  while (start_pos < flag.length()) {
142  size_t colon_pos = flag.find(':', start_pos);
143  if (colon_pos == std::string::npos) {
145  "Couldn't parse metadata flag: extra characters at end of flag");
146  return false;
147  }
148  size_t semicolon_pos = flag.find(';', colon_pos);
149 
150  std::string key = flag.substr(start_pos, colon_pos - start_pos);
152  flag.substr(colon_pos + 1, semicolon_pos - colon_pos - 1);
153 
154  constexpr char alphanum_and_hyphen[] =
155  "-0123456789"
156  "abcdefghijklmnopqrstuvwxyz"
157  "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
158  if (key.find_first_not_of(alphanum_and_hyphen) != std::string::npos) {
160  "Couldn't parse metadata flag: key contains characters other "
161  "than alphanumeric and hyphens: %s",
162  key.c_str());
163  return false;
164  }
165 
166  // Convert to lowercase.
167  for (char& c : key) {
168  if (c >= 'A' && c <= 'Z') {
169  c += ('a' - 'A');
170  }
171  }
172 
173  gpr_log(GPR_INFO, "Adding additional metadata with key %s and value %s",
174  key.c_str(), value.c_str());
175  additional_metadata->insert({key, value});
176 
177  if (semicolon_pos == std::string::npos) {
178  break;
179  } else {
180  start_pos = semicolon_pos + 1;
181  }
182  }
183 
184  return true;
185 }
186 
187 } // namespace
188 
189 int main(int argc, char** argv) {
190  grpc::testing::TestEnvironment env(&argc, argv);
191  grpc::testing::InitTest(&argc, &argv, true);
192  gpr_log(GPR_INFO, "Testing these cases: %s",
193  absl::GetFlag(FLAGS_test_case).c_str());
194  int ret = 0;
195 
196  grpc::testing::ChannelCreationFunc channel_creation_func;
197  std::string test_case = absl::GetFlag(FLAGS_test_case);
198  if (absl::GetFlag(FLAGS_additional_metadata).empty()) {
199  channel_creation_func = [test_case]() {
200  std::vector<std::unique_ptr<
202  factories;
203  if (absl::GetFlag(FLAGS_log_metadata_and_status)) {
204  factories.emplace_back(
206  }
207  return CreateChannelForTestCase(test_case, std::move(factories));
208  };
209  } else {
210  std::multimap<std::string, std::string> additional_metadata;
211  if (!ParseAdditionalMetadataFlag(absl::GetFlag(FLAGS_additional_metadata),
212  &additional_metadata)) {
213  return 1;
214  }
215 
216  channel_creation_func = [test_case, additional_metadata]() {
217  std::vector<std::unique_ptr<
219  factories;
220  factories.emplace_back(
222  additional_metadata));
223  if (absl::GetFlag(FLAGS_log_metadata_and_status)) {
224  factories.emplace_back(
226  }
227  return CreateChannelForTestCase(test_case, std::move(factories));
228  };
229  }
230 
232  channel_creation_func, true,
233  absl::GetFlag(FLAGS_do_not_abort_on_transient_failures));
234 
235  std::unordered_map<std::string, std::function<bool()>> actions;
236  actions["empty_unary"] =
238  actions["large_unary"] =
240  actions["server_compressed_unary"] = std::bind(
242  actions["client_compressed_unary"] = std::bind(
244  actions["client_streaming"] =
246  actions["server_streaming"] =
248  actions["server_compressed_streaming"] = std::bind(
250  actions["client_compressed_streaming"] = std::bind(
252  actions["slow_consumer"] = std::bind(
254  &client);
255  actions["half_duplex"] =
257  actions["ping_pong"] =
259  actions["cancel_after_begin"] =
261  actions["cancel_after_first_response"] = std::bind(
263  actions["timeout_on_sleeping_server"] = std::bind(
265  actions["empty_stream"] =
267  actions["pick_first_unary"] =
269  if (absl::GetFlag(FLAGS_use_tls)) {
270  actions["compute_engine_creds"] =
272  absl::GetFlag(FLAGS_default_service_account),
273  absl::GetFlag(FLAGS_oauth_scope));
274  actions["jwt_token_creds"] =
277  actions["oauth2_auth_token"] =
279  absl::GetFlag(FLAGS_default_service_account),
280  absl::GetFlag(FLAGS_oauth_scope));
281  actions["per_rpc_creds"] =
284  }
285  if (absl::GetFlag(FLAGS_custom_credentials_type) ==
286  "google_default_credentials") {
287  actions["google_default_credentials"] =
289  &client, absl::GetFlag(FLAGS_default_service_account));
290  }
291  actions["status_code_and_message"] =
293  actions["special_status_message"] =
295  actions["custom_metadata"] =
297  actions["unimplemented_method"] =
299  actions["unimplemented_service"] =
301  actions["channel_soak"] = std::bind(
303  absl::GetFlag(FLAGS_soak_iterations),
304  absl::GetFlag(FLAGS_soak_max_failures),
305  absl::GetFlag(FLAGS_soak_per_iteration_max_acceptable_latency_ms),
306  absl::GetFlag(FLAGS_soak_min_time_ms_between_rpcs),
307  absl::GetFlag(FLAGS_soak_overall_timeout_seconds));
308  actions["rpc_soak"] = std::bind(
310  absl::GetFlag(FLAGS_soak_iterations),
311  absl::GetFlag(FLAGS_soak_max_failures),
312  absl::GetFlag(FLAGS_soak_per_iteration_max_acceptable_latency_ms),
313  absl::GetFlag(FLAGS_soak_min_time_ms_between_rpcs),
314  absl::GetFlag(FLAGS_soak_overall_timeout_seconds));
315  actions["long_lived_channel"] =
317  absl::GetFlag(FLAGS_soak_iterations),
318  absl::GetFlag(FLAGS_iteration_interval));
319 
320  UpdateActions(&actions);
321 
322  if (absl::GetFlag(FLAGS_test_case) == "all") {
323  for (const auto& action : actions) {
324  action.second();
325  }
326  } else if (actions.find(absl::GetFlag(FLAGS_test_case)) != actions.end()) {
327  actions.find(absl::GetFlag(FLAGS_test_case))->second();
328  } else {
330  for (const auto& action : actions) {
331  if (!test_cases.empty()) test_cases += "\n";
332  test_cases += action.first;
333  }
334  gpr_log(GPR_ERROR, "Unsupported test case %s. Valid options are\n%s",
335  absl::GetFlag(FLAGS_test_case).c_str(), test_cases.c_str());
336  ret = 1;
337  }
338 
339  return ret;
340 }
grpc::testing::InitTest
void InitTest(int *argc, char ***argv, bool remove_flags)
Definition: test_config_cc.cc:28
flag
uint32_t flag
Definition: ssl_versions.cc:162
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
grpc::testing::InteropClient::DoOauth2AuthToken
bool DoOauth2AuthToken(const std::string &username, const std::string &oauth_scope)
Definition: interop_client.cc:235
log.h
grpc::testing::InteropClient::DoEmpty
bool DoEmpty()
Definition: interop_client.cc:159
bool
bool
Definition: setup_once.h:312
client_helper.h
generate.env
env
Definition: generate.py:37
grpc::testing::InteropClient::DoCancelAfterFirstResponse
bool DoCancelAfterFirstResponse()
Definition: interop_client.cc:758
grpc::testing::InteropClient::DoServerCompressedUnary
bool DoServerCompressedUnary()
Definition: interop_client.cc:379
grpc::testing::InteropClient::DoResponseStreamingWithSlowConsumer
bool DoResponseStreamingWithSlowConsumer()
Definition: interop_client.cc:601
grpc::testing::InteropClient::DoLongLivedChannelTest
bool DoLongLivedChannelTest(int32_t soak_iterations, int32_t iteration_interval)
Definition: interop_client.cc:1176
client
Definition: examples/python/async_streaming/client.py:1
grpc::testing::InteropClient::DoUnimplementedMethod
bool DoUnimplementedMethod()
Definition: interop_client.cc:1224
string.h
server_port
static int server_port
Definition: bad_server_response_test.cc:86
grpc::experimental::ClientInterceptorFactoryInterface
Definition: impl/codegen/client_interceptor.h:48
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc::testing::InteropClient::DoUnimplementedService
bool DoUnimplementedService()
Definition: interop_client.cc:1204
grpc::testing::InteropClient::DoPingPong
bool DoPingPong()
Definition: interop_client.cc:691
grpc::testing::InteropClient::DoClientCompressedUnary
bool DoClientCompressedUnary()
Definition: interop_client.cc:333
grpc::testing::InteropClient::DoEmptyStream
bool DoEmptyStream()
Definition: interop_client.cc:817
grpc::testing::InteropClient::DoCustomMetadata
bool DoCustomMetadata()
Definition: interop_client.cc:933
grpc::testing::InteropClient::DoRpcSoakTest
bool DoRpcSoakTest(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)
Definition: interop_client.cc:1149
client
static uv_tcp_t client
Definition: test-callback-stack.c:33
grpc::testing::UpdateActions
void UpdateActions(std::unordered_map< std::string, std::function< bool()>> *)
Definition: client_helper.cc:82
grpc::testing::InteropClient::DoGoogleDefaultCredentials
bool DoGoogleDefaultCredentials(const std::string &default_service_account)
Definition: interop_client.cc:303
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
grpc::testing::InteropClient::DoResponseStreaming
bool DoResponseStreaming()
Definition: interop_client.cc:445
grpc::testing::InteropClient::DoLargeUnary
bool DoLargeUnary()
Definition: interop_client.cc:322
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
grpc::testing::InteropClient::DoHalfDuplex
bool DoHalfDuplex()
Definition: interop_client.cc:644
grpc::testing::InteropClient::DoPerRpcCreds
bool DoPerRpcCreds(const std::string &json_key)
Definition: interop_client.cc:261
grpc.h
grpc::testing::InteropClient::DoCancelAfterBegin
bool DoCancelAfterBegin()
Definition: interop_client.cc:735
custom_credentials_type
std::string custom_credentials_type("INSECURE_CREDENTIALS")
channel.h
interop_client.h
absl::GetFlag
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag< T > &flag)
Definition: abseil-cpp/absl/flags/flag.h:98
ABSL_FLAG
ABSL_FLAG(bool, use_alts, false, "Whether to use alts. Enable alts will disable tls.")
grpc::testing::GetServiceAccountJsonKey
std::string GetServiceAccountJsonKey()
Definition: client_helper.cc:57
grpc::testing::InteropClient
Definition: interop_client.h:40
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
grpc::testing::InteropClient::DoSpecialStatusMessage
bool DoSpecialStatusMessage()
Definition: interop_client.cc:883
grpc::testing::ChannelCreationFunc
std::function< std::shared_ptr< Channel >void)> ChannelCreationFunc
Definition: interop_client.h:38
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
grpc::testing::InteropClient::DoServerCompressedStreaming
bool DoServerCompressedStreaming()
Definition: interop_client.cc:544
test_config.h
value
const char * value
Definition: hpack_parser_table.cc:165
client_context.h
http2_server_health_check.server_host
server_host
Definition: http2_server_health_check.py:27
key
const char * key
Definition: hpack_parser_table.cc:164
client.action
action
Definition: examples/python/xds/client.py:49
grpc::testing::InteropClient::DoRequestStreaming
bool DoRequestStreaming()
Definition: interop_client.cc:414
grpc::testing::CreateChannelForTestCase
std::shared_ptr< Channel > CreateChannelForTestCase(const std::string &test_case, std::vector< std::unique_ptr< experimental::ClientInterceptorFactoryInterface >> interceptor_creators)
Definition: client_helper.cc:85
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
alloc.h
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
grpc::testing::InteropClient::DoJwtTokenCreds
bool DoJwtTokenCreds(const std::string &username)
Definition: interop_client.cc:286
grpc::testing::InteropClient::DoStatusWithMessage
bool DoStatusWithMessage()
Definition: interop_client.cc:837
test_config.h
python_utils.upload_rbe_results.test_cases
list test_cases
Definition: upload_rbe_results.py:197
grpc::testing::InteropClient::DoComputeEngineCreds
bool DoComputeEngineCreds(const std::string &default_service_account, const std::string &oauth_scope)
Definition: interop_client.cc:210
grpc::testing::InteropClient::DoTimeoutOnSleepingServer
bool DoTimeoutOnSleepingServer()
Definition: interop_client.cc:791
grpc::testing::InteropClient::DoChannelSoakTest
bool DoChannelSoakTest(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)
Definition: interop_client.cc:1162
function
std::function< bool(GrpcTool *, int, const char **, const CliCredentials &, GrpcToolOutputCallback)> function
Definition: grpc_tool.cc:250
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
grpc::testing::MetadataAndStatusLoggerInterceptorFactory
Definition: client_helper.h:113
grpc::testing::InteropClient::DoPickFirstUnary
bool DoPickFirstUnary()
Definition: interop_client.cc:907
grpc::testing::InteropClient::DoClientCompressedStreaming
bool DoClientCompressedStreaming()
Definition: interop_client.cc:484
grpc::testing::AdditionalMetadataInterceptorFactory
Definition: client_helper.h:91
main
int main(int argc, char **argv)
Definition: test/cpp/interop/client.cc:189


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:54