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 *is % allowed in string
17 */
18
19 #include "test/cpp/interop/stress_interop_client.h"
20
21 #include <memory>
22 #include <string>
23 #include <vector>
24
25 #include <grpc/support/log.h>
26 #include <grpcpp/create_channel.h>
27
28 #include "test/cpp/interop/interop_client.h"
29 #include "test/cpp/util/metrics_server.h"
30
31 namespace grpc {
32 namespace testing {
33
34 using std::pair;
35 using std::vector;
36
WeightedRandomTestSelector(const vector<pair<TestCaseType,int>> & tests)37 WeightedRandomTestSelector::WeightedRandomTestSelector(
38 const vector<pair<TestCaseType, int>>& tests)
39 : tests_(tests) {
40 total_weight_ = 0;
41 for (auto it = tests.begin(); it != tests.end(); it++) {
42 total_weight_ += it->second;
43 }
44 }
45
46 // Returns a weighted-randomly selected test case based on the test weights
47 // passed in the constructror
GetNextTest() const48 TestCaseType WeightedRandomTestSelector::GetNextTest() const {
49 int random = 0;
50 TestCaseType selected_test = UNKNOWN_TEST;
51
52 // Get a random number from [0 to the total_weight - 1]
53 random = rand() % total_weight_;
54
55 int weight_sofar = 0;
56 for (auto it = tests_.begin(); it != tests_.end(); it++) {
57 weight_sofar += it->second;
58 if (random < weight_sofar) {
59 selected_test = it->first;
60 break;
61 }
62 }
63
64 // It is a bug in the logic if no test is selected at this point
65 GPR_ASSERT(selected_test != UNKNOWN_TEST);
66 return selected_test;
67 }
68
StressTestInteropClient(int test_id,const grpc::string & server_address,ChannelCreationFunc channel_creation_func,const WeightedRandomTestSelector & test_selector,long test_duration_secs,long sleep_duration_ms,bool do_not_abort_on_transient_failures)69 StressTestInteropClient::StressTestInteropClient(
70 int test_id, const grpc::string& server_address,
71 ChannelCreationFunc channel_creation_func,
72 const WeightedRandomTestSelector& test_selector, long test_duration_secs,
73 long sleep_duration_ms, bool do_not_abort_on_transient_failures)
74 : test_id_(test_id),
75 server_address_(server_address),
76 channel_creation_func_(channel_creation_func),
77 interop_client_(new InteropClient(channel_creation_func_, false,
78 do_not_abort_on_transient_failures)),
79 test_selector_(test_selector),
80 test_duration_secs_(test_duration_secs),
81 sleep_duration_ms_(sleep_duration_ms) {}
82
MainLoop(const std::shared_ptr<QpsGauge> & qps_gauge)83 void StressTestInteropClient::MainLoop(
84 const std::shared_ptr<QpsGauge>& qps_gauge) {
85 gpr_log(GPR_INFO, "Running test %d. ServerAddr: %s", test_id_,
86 server_address_.c_str());
87
88 gpr_timespec test_end_time;
89 if (test_duration_secs_ < 0) {
90 test_end_time = gpr_inf_future(GPR_CLOCK_REALTIME);
91 } else {
92 test_end_time =
93 gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
94 gpr_time_from_seconds(test_duration_secs_, GPR_TIMESPAN));
95 }
96
97 qps_gauge->Reset();
98
99 while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), test_end_time) < 0) {
100 // Select the test case to execute based on the weights and execute it
101 TestCaseType test_case = test_selector_.GetNextTest();
102 gpr_log(GPR_DEBUG, "%d - Executing the test case %d", test_id_, test_case);
103 RunTest(test_case);
104
105 qps_gauge->Incr();
106
107 // Sleep between successive calls if needed
108 if (sleep_duration_ms_ > 0) {
109 gpr_timespec sleep_time =
110 gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
111 gpr_time_from_millis(sleep_duration_ms_, GPR_TIMESPAN));
112 gpr_sleep_until(sleep_time);
113 }
114 }
115 }
116
RunTest(TestCaseType test_case)117 bool StressTestInteropClient::RunTest(TestCaseType test_case) {
118 bool is_success = false;
119 switch (test_case) {
120 case EMPTY_UNARY: {
121 is_success = interop_client_->DoEmpty();
122 break;
123 }
124 case LARGE_UNARY: {
125 is_success = interop_client_->DoLargeUnary();
126 break;
127 }
128 case CLIENT_COMPRESSED_UNARY: {
129 is_success = interop_client_->DoClientCompressedUnary();
130 break;
131 }
132 case CLIENT_COMPRESSED_STREAMING: {
133 is_success = interop_client_->DoClientCompressedStreaming();
134 break;
135 }
136 case CLIENT_STREAMING: {
137 is_success = interop_client_->DoRequestStreaming();
138 break;
139 }
140 case SERVER_STREAMING: {
141 is_success = interop_client_->DoResponseStreaming();
142 break;
143 }
144 case SERVER_COMPRESSED_UNARY: {
145 is_success = interop_client_->DoServerCompressedUnary();
146 break;
147 }
148 case SERVER_COMPRESSED_STREAMING: {
149 is_success = interop_client_->DoServerCompressedStreaming();
150 break;
151 }
152 case SLOW_CONSUMER: {
153 is_success = interop_client_->DoResponseStreamingWithSlowConsumer();
154 break;
155 }
156 case HALF_DUPLEX: {
157 is_success = interop_client_->DoHalfDuplex();
158 break;
159 }
160 case PING_PONG: {
161 is_success = interop_client_->DoPingPong();
162 break;
163 }
164 case CANCEL_AFTER_BEGIN: {
165 is_success = interop_client_->DoCancelAfterBegin();
166 break;
167 }
168 case CANCEL_AFTER_FIRST_RESPONSE: {
169 is_success = interop_client_->DoCancelAfterFirstResponse();
170 break;
171 }
172 case TIMEOUT_ON_SLEEPING_SERVER: {
173 is_success = interop_client_->DoTimeoutOnSleepingServer();
174 break;
175 }
176 case EMPTY_STREAM: {
177 is_success = interop_client_->DoEmptyStream();
178 break;
179 }
180 case STATUS_CODE_AND_MESSAGE: {
181 is_success = interop_client_->DoStatusWithMessage();
182 break;
183 }
184 case CUSTOM_METADATA: {
185 is_success = interop_client_->DoCustomMetadata();
186 break;
187 }
188 default: {
189 gpr_log(GPR_ERROR, "Invalid test case (%d)", test_case);
190 GPR_ASSERT(false);
191 break;
192 }
193 }
194
195 return is_success;
196 }
197
198 } // namespace testing
199 } // namespace grpc
200