OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * |
| 3 * Copyright 2015-2016, Google Inc. |
| 4 * All rights reserved. |
| 5 * |
| 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions are |
| 8 * met: |
| 9 * |
| 10 * * Redistributions of source code must retain the above copyright |
| 11 * notice, this list of conditions and the following disclaimer. |
| 12 * * Redistributions in binary form must reproduce the above |
| 13 * copyright notice, this list of conditions and the following disclaimer |
| 14 * in the documentation and/or other materials provided with the |
| 15 * distribution. |
| 16 * * Neither the name of Google Inc. nor the names of its |
| 17 * contributors may be used to endorse or promote products derived from |
| 18 * this software without specific prior written permission. |
| 19 * |
| 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 31 *is % allowed in string |
| 32 */ |
| 33 |
| 34 #include "test/cpp/interop/stress_interop_client.h" |
| 35 |
| 36 #include <memory> |
| 37 #include <string> |
| 38 #include <vector> |
| 39 |
| 40 #include <grpc++/create_channel.h> |
| 41 |
| 42 #include "test/cpp/interop/interop_client.h" |
| 43 #include "test/cpp/util/metrics_server.h" |
| 44 |
| 45 namespace grpc { |
| 46 namespace testing { |
| 47 |
| 48 using std::pair; |
| 49 using std::vector; |
| 50 |
| 51 WeightedRandomTestSelector::WeightedRandomTestSelector( |
| 52 const vector<pair<TestCaseType, int>>& tests) |
| 53 : tests_(tests) { |
| 54 total_weight_ = 0; |
| 55 for (auto it = tests.begin(); it != tests.end(); it++) { |
| 56 total_weight_ += it->second; |
| 57 } |
| 58 } |
| 59 |
| 60 // Returns a weighted-randomly selected test case based on the test weights |
| 61 // passed in the constructror |
| 62 TestCaseType WeightedRandomTestSelector::GetNextTest() const { |
| 63 int random = 0; |
| 64 TestCaseType selected_test = UNKNOWN_TEST; |
| 65 |
| 66 // Get a random number from [0 to the total_weight - 1] |
| 67 random = rand() % total_weight_; |
| 68 |
| 69 int weight_sofar = 0; |
| 70 for (auto it = tests_.begin(); it != tests_.end(); it++) { |
| 71 weight_sofar += it->second; |
| 72 if (random < weight_sofar) { |
| 73 selected_test = it->first; |
| 74 break; |
| 75 } |
| 76 } |
| 77 |
| 78 // It is a bug in the logic if no test is selected at this point |
| 79 GPR_ASSERT(selected_test != UNKNOWN_TEST); |
| 80 return selected_test; |
| 81 } |
| 82 |
| 83 StressTestInteropClient::StressTestInteropClient( |
| 84 int test_id, const grpc::string& server_address, |
| 85 std::shared_ptr<Channel> channel, |
| 86 const WeightedRandomTestSelector& test_selector, long test_duration_secs, |
| 87 long sleep_duration_ms, long metrics_collection_interval_secs) |
| 88 : test_id_(test_id), |
| 89 server_address_(server_address), |
| 90 channel_(channel), |
| 91 interop_client_(new InteropClient(channel, false)), |
| 92 test_selector_(test_selector), |
| 93 test_duration_secs_(test_duration_secs), |
| 94 sleep_duration_ms_(sleep_duration_ms), |
| 95 metrics_collection_interval_secs_(metrics_collection_interval_secs) {} |
| 96 |
| 97 void StressTestInteropClient::MainLoop(std::shared_ptr<Gauge> qps_gauge) { |
| 98 gpr_log(GPR_INFO, "Running test %d. ServerAddr: %s", test_id_, |
| 99 server_address_.c_str()); |
| 100 |
| 101 gpr_timespec test_end_time = |
| 102 gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), |
| 103 gpr_time_from_seconds(test_duration_secs_, GPR_TIMESPAN)); |
| 104 |
| 105 gpr_timespec current_time = gpr_now(GPR_CLOCK_REALTIME); |
| 106 gpr_timespec next_stat_collection_time = current_time; |
| 107 gpr_timespec collection_interval = |
| 108 gpr_time_from_seconds(metrics_collection_interval_secs_, GPR_TIMESPAN); |
| 109 long num_calls_per_interval = 0; |
| 110 |
| 111 while (test_duration_secs_ < 0 || |
| 112 gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), test_end_time) < 0) { |
| 113 // Select the test case to execute based on the weights and execute it |
| 114 TestCaseType test_case = test_selector_.GetNextTest(); |
| 115 gpr_log(GPR_DEBUG, "%d - Executing the test case %d", test_id_, test_case); |
| 116 RunTest(test_case); |
| 117 |
| 118 num_calls_per_interval++; |
| 119 |
| 120 // See if its time to collect stats yet |
| 121 current_time = gpr_now(GPR_CLOCK_REALTIME); |
| 122 if (gpr_time_cmp(next_stat_collection_time, current_time) < 0) { |
| 123 qps_gauge->Set(num_calls_per_interval / |
| 124 metrics_collection_interval_secs_); |
| 125 |
| 126 num_calls_per_interval = 0; |
| 127 next_stat_collection_time = |
| 128 gpr_time_add(current_time, collection_interval); |
| 129 } |
| 130 |
| 131 // Sleep between successive calls if needed |
| 132 if (sleep_duration_ms_ > 0) { |
| 133 gpr_timespec sleep_time = |
| 134 gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), |
| 135 gpr_time_from_millis(sleep_duration_ms_, GPR_TIMESPAN)); |
| 136 gpr_sleep_until(sleep_time); |
| 137 } |
| 138 } |
| 139 } |
| 140 |
| 141 // TODO(sree): Add all interop tests |
| 142 void StressTestInteropClient::RunTest(TestCaseType test_case) { |
| 143 switch (test_case) { |
| 144 case EMPTY_UNARY: { |
| 145 interop_client_->DoEmpty(); |
| 146 break; |
| 147 } |
| 148 case LARGE_UNARY: { |
| 149 interop_client_->DoLargeUnary(); |
| 150 break; |
| 151 } |
| 152 case LARGE_COMPRESSED_UNARY: { |
| 153 interop_client_->DoLargeCompressedUnary(); |
| 154 break; |
| 155 } |
| 156 case CLIENT_STREAMING: { |
| 157 interop_client_->DoRequestStreaming(); |
| 158 break; |
| 159 } |
| 160 case SERVER_STREAMING: { |
| 161 interop_client_->DoResponseStreaming(); |
| 162 break; |
| 163 } |
| 164 case EMPTY_STREAM: { |
| 165 interop_client_->DoEmptyStream(); |
| 166 break; |
| 167 } |
| 168 default: { |
| 169 gpr_log(GPR_ERROR, "Invalid test case (%d)", test_case); |
| 170 GPR_ASSERT(false); |
| 171 break; |
| 172 } |
| 173 } |
| 174 } |
| 175 |
| 176 } // namespace testing |
| 177 } // namespace grpc |
OLD | NEW |