• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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