blob: bc8780f74d58229f475b1de81d0894fa923c09d8 [file] [log] [blame]
Craig Tillere4860192015-02-23 17:10:41 -08001/*
2 *
David Garcia Quintas5a946232016-01-27 19:22:14 -08003 * Copyright 2015-2016, Google Inc.
Craig Tillere4860192015-02-23 17:10:41 -08004 * 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 *
32 */
33
Vijay Paid02dd302016-01-27 11:23:34 -080034#include <deque>
Craig Tiller2d0f36c2015-02-23 23:16:17 -080035#include <list>
36#include <thread>
Vijay Pai7d45cdb2016-02-01 13:00:19 -080037#include <unordered_map>
Craig Tiller2d0f36c2015-02-23 23:16:17 -080038#include <vector>
yang-g9e2f90c2015-08-21 15:35:03 -070039
David Garcia Quintas6a484052016-01-25 19:12:37 -080040#include <grpc++/channel.h>
yang-g9e2f90c2015-08-21 15:35:03 -070041#include <grpc++/client_context.h>
42#include <grpc++/create_channel.h>
Vijay Paid02dd302016-01-27 11:23:34 -080043#include <grpc/support/alloc.h>
44#include <grpc/support/host_port.h>
45#include <grpc/support/log.h>
yang-g9e2f90c2015-08-21 15:35:03 -070046
47#include "src/core/support/env.h"
Vijay Paid02dd302016-01-27 11:23:34 -080048#include "src/proto/grpc/testing/services.grpc.pb.h"
Craig Tillere9a6eb72015-04-09 15:51:41 -070049#include "test/core/util/port.h"
Craig Tiller882431f2015-05-19 09:25:37 -070050#include "test/core/util/test_config.h"
yang-g9e2f90c2015-08-21 15:35:03 -070051#include "test/cpp/qps/driver.h"
52#include "test/cpp/qps/histogram.h"
53#include "test/cpp/qps/qps_worker.h"
Craig Tillere4860192015-02-23 17:10:41 -080054
Craig Tiller2d0f36c2015-02-23 23:16:17 -080055using std::list;
56using std::thread;
57using std::unique_ptr;
Craig Tillere9a6eb72015-04-09 15:51:41 -070058using std::deque;
Craig Tiller4ef7a292015-02-23 17:29:01 -080059using std::vector;
Craig Tiller4ef7a292015-02-23 17:29:01 -080060
Craig Tiller6af9ed02015-03-02 22:42:10 -080061namespace grpc {
62namespace testing {
Vijay Pai59567422016-02-01 13:28:55 -080063static std::string get_host(const std::string& worker) {
64 char* host;
65 char* port;
Vijay Pai7d45cdb2016-02-01 13:00:19 -080066
67 gpr_split_host_port(worker.c_str(), &host, &port);
Vijay Pai33e51182016-02-01 16:40:06 -080068 const string s(host);
Vijay Pai7d45cdb2016-02-01 13:00:19 -080069
70 gpr_free(host);
71 gpr_free(port);
72 return s;
73}
74
Vijay Pai59567422016-02-01 13:28:55 -080075static std::unordered_map<string, std::deque<int>> get_hosts_and_cores(
76 const deque<string>& workers) {
77 std::unordered_map<string, std::deque<int>> hosts;
Vijay Pai7d45cdb2016-02-01 13:00:19 -080078 for (auto it = workers.begin(); it != workers.end(); it++) {
Vijay Pai33e51182016-02-01 16:40:06 -080079 const string host = get_host(*it);
Vijay Pai7d45cdb2016-02-01 13:00:19 -080080 if (hosts.find(host) == hosts.end()) {
81 auto stub = WorkerService::NewStub(
82 CreateChannel(*it, InsecureChannelCredentials()));
83 grpc::ClientContext ctx;
84 CoreRequest dummy;
85 CoreResponse cores;
86 grpc::Status s = stub->CoreCount(&ctx, dummy, &cores);
87 assert(s.ok());
88 std::deque<int> dq;
Vijay Pai59567422016-02-01 13:28:55 -080089 for (int i = 0; i < cores.cores(); i++) {
Vijay Pai7d45cdb2016-02-01 13:00:19 -080090 dq.push_back(i);
91 }
92 hosts[host] = dq;
93 }
94 }
95 return hosts;
96}
97
98static deque<string> get_workers(const string& name) {
Craig Tiller4ef7a292015-02-23 17:29:01 -080099 char* env = gpr_getenv(name.c_str());
Craig Tillere9a6eb72015-04-09 15:51:41 -0700100 if (!env) return deque<string>();
Craig Tiller4ef7a292015-02-23 17:29:01 -0800101
Craig Tillere9a6eb72015-04-09 15:51:41 -0700102 deque<string> out;
Craig Tiller4ef7a292015-02-23 17:29:01 -0800103 char* p = env;
104 for (;;) {
Craig Tiller6af9ed02015-03-02 22:42:10 -0800105 char* comma = strchr(p, ',');
106 if (comma) {
107 out.emplace_back(p, comma);
108 p = comma + 1;
109 } else {
110 out.emplace_back(p);
111 gpr_free(env);
112 return out;
113 }
Craig Tiller4ef7a292015-02-23 17:29:01 -0800114 }
115}
116
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700117// Namespace for classes and functions used only in RunScenario
118// Using this rather than local definitions to workaround gcc-4.4 limitations
Vijay Pai90e73692015-08-05 19:15:36 -0700119// regarding using templates without linkage
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700120namespace runsc {
121
122// ClientContext allocator
Craig Tillerb17b7f42015-10-07 08:48:51 -0700123template <class T>
124static ClientContext* AllocContext(list<ClientContext>* contexts, T deadline) {
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700125 contexts->emplace_back();
Craig Tillerb17b7f42015-10-07 08:48:51 -0700126 auto context = &contexts->back();
127 context->set_deadline(deadline);
128 return context;
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700129}
130
131struct ServerData {
vjpai119c1032015-10-29 01:21:04 -0700132 unique_ptr<WorkerService::Stub> stub;
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700133 unique_ptr<ClientReaderWriter<ServerArgs, ServerStatus>> stream;
134};
135
136struct ClientData {
vjpai119c1032015-10-29 01:21:04 -0700137 unique_ptr<WorkerService::Stub> stub;
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700138 unique_ptr<ClientReaderWriter<ClientArgs, ClientStatus>> stream;
139};
Vijay Pai3ae11042015-08-11 22:43:14 -0700140} // namespace runsc
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700141
David Garcia Quintas08116502015-05-20 17:27:23 -0700142std::unique_ptr<ScenarioResult> RunScenario(
143 const ClientConfig& initial_client_config, size_t num_clients,
Vijay Pai59567422016-02-01 13:28:55 -0800144 const ServerConfig& initial_server_config, size_t num_servers,
145 int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count) {
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700146 // ClientContext allocations (all are destroyed at scope exit)
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800147 list<ClientContext> contexts;
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800148
David Garcia Quintas6ba29ba2015-05-19 18:29:35 -0700149 // To be added to the result, containing the final configuration used for
Jan Tattermuschc5ebbd52015-11-18 16:50:47 -0800150 // client and config (including host, etc.)
David Garcia Quintas6ba29ba2015-05-19 18:29:35 -0700151 ClientConfig result_client_config;
Vijay Pai33e51182016-02-01 16:40:06 -0800152 const ServerConfig result_server_config = initial_server_config;
David Garcia Quintas6ba29ba2015-05-19 18:29:35 -0700153
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800154 // Get client, server lists
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800155 auto workers = get_workers("QPS_WORKERS");
Craig Tiller6af9ed02015-03-02 22:42:10 -0800156 ClientConfig client_config = initial_client_config;
Craig Tiller4ef7a292015-02-23 17:29:01 -0800157
Craig Tillere9a6eb72015-04-09 15:51:41 -0700158 // Spawn some local workers if desired
159 vector<unique_ptr<QpsWorker>> local_workers;
160 for (int i = 0; i < abs(spawn_local_worker_count); i++) {
Craig Tiller49c3b012015-05-19 08:18:02 -0700161 // act as if we're a new test -- gets a good rng seed
162 static bool called_init = false;
163 if (!called_init) {
Craig Tiller882431f2015-05-19 09:25:37 -0700164 char args_buf[100];
165 strcpy(args_buf, "some-benchmark");
Craig Tiller5c8737d2015-05-21 11:42:17 -0700166 char* args[] = {args_buf};
Craig Tiller49c3b012015-05-19 08:18:02 -0700167 grpc_test_init(1, args);
168 called_init = true;
169 }
170
Craig Tillere9a6eb72015-04-09 15:51:41 -0700171 int driver_port = grpc_pick_unused_port_or_die();
vjpai72a63322015-10-29 02:23:11 -0700172 local_workers.emplace_back(new QpsWorker(driver_port));
Craig Tillere9a6eb72015-04-09 15:51:41 -0700173 char addr[256];
174 sprintf(addr, "localhost:%d", driver_port);
175 if (spawn_local_worker_count < 0) {
176 workers.push_front(addr);
177 } else {
178 workers.push_back(addr);
179 }
180 }
181
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800182 // Setup the hosts and core counts
183 auto hosts_cores = get_hosts_and_cores(workers);
184
Vijay Paid02dd302016-01-27 11:23:34 -0800185 // if num_clients is set to <=0, do dynamic sizing: all workers
186 // except for servers are clients
187 if (num_clients <= 0) {
188 num_clients = workers.size() - num_servers;
189 }
190
Craig Tiller10923c22015-03-03 14:24:49 -0800191 // TODO(ctiller): support running multiple configurations, and binpack
192 // client/server pairs
Craig Tiller6af9ed02015-03-02 22:42:10 -0800193 // to available workers
194 GPR_ASSERT(workers.size() >= num_clients + num_servers);
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800195
196 // Trim to just what we need
Craig Tiller6af9ed02015-03-02 22:42:10 -0800197 workers.resize(num_clients + num_servers);
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800198
Vijay Paie40aefb2016-02-13 01:25:30 -0800199 gpr_timespec deadline =
200 GRPC_TIMEOUT_SECONDS_TO_DEADLINE(warmup_seconds + benchmark_seconds + 20);
Craig Tillerb17b7f42015-10-07 08:48:51 -0700201
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800202 // Start servers
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700203 using runsc::ServerData;
Vijay Pai90e73692015-08-05 19:15:36 -0700204 // servers is array rather than std::vector to avoid gcc-4.4 issues
205 // where class contained in std::vector must have a copy constructor
vjpaib1db8692015-08-11 22:41:02 -0700206 auto* servers = new ServerData[num_servers];
Craig Tiller6af9ed02015-03-02 22:42:10 -0800207 for (size_t i = 0; i < num_servers; i++) {
vjpai94aada92016-01-26 18:12:30 -0800208 gpr_log(GPR_INFO, "Starting server on %s (worker #%d)", workers[i].c_str(),
vjpai0c31b602016-01-27 09:03:18 -0800209 i);
Julien Boeuf6049ebd2015-11-17 16:53:52 -0800210 servers[i].stub = WorkerService::NewStub(
Julien Boeufe5adc0e2015-10-12 14:08:10 -0700211 CreateChannel(workers[i], InsecureChannelCredentials()));
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800212
213 ServerConfig server_config = initial_server_config;
214 char* host;
215 char* driver_port;
216 char* cli_target;
217 gpr_split_host_port(workers[i].c_str(), &host, &driver_port);
218 string host_str(host);
219 int server_core_limit = initial_server_config.core_limit();
220 int client_core_limit = initial_client_config.core_limit();
221
222 if (server_core_limit == 0 && client_core_limit > 0) {
223 // In this case, limit the server cores if it matches the
224 // same host as one or more clients
Vijay Pai33e51182016-02-01 16:40:06 -0800225 const auto& dq = hosts_cores.at(host_str);
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800226 bool match = false;
227 int limit = dq.size();
228 for (size_t cli = 0; cli < num_clients; cli++) {
Vijay Pai59567422016-02-01 13:28:55 -0800229 if (host_str == get_host(workers[cli + num_servers])) {
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800230 limit -= client_core_limit;
231 match = true;
232 }
233 }
234 if (match) {
235 GPR_ASSERT(limit > 0);
236 server_core_limit = limit;
237 }
238 }
239 if (server_core_limit > 0) {
Vijay Pai33e51182016-02-01 16:40:06 -0800240 auto& dq = hosts_cores.at(host_str);
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800241 GPR_ASSERT(dq.size() >= static_cast<size_t>(server_core_limit));
Vijay Pai59567422016-02-01 13:28:55 -0800242 for (int core = 0; core < server_core_limit; core++) {
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800243 server_config.add_core_list(dq.front());
244 dq.pop_front();
245 }
246 }
247
Craig Tiller6af9ed02015-03-02 22:42:10 -0800248 ServerArgs args;
249 *args.mutable_setup() = server_config;
Vijay Pai90e73692015-08-05 19:15:36 -0700250 servers[i].stream =
Craig Tillerb17b7f42015-10-07 08:48:51 -0700251 servers[i].stub->RunServer(runsc::AllocContext(&contexts, deadline));
Vijay Paieed63fa2015-08-05 23:08:34 +0000252 GPR_ASSERT(servers[i].stream->Write(args));
Craig Tiller6af9ed02015-03-02 22:42:10 -0800253 ServerStatus init_status;
Vijay Paieed63fa2015-08-05 23:08:34 +0000254 GPR_ASSERT(servers[i].stream->Read(&init_status));
Craig Tiller6af9ed02015-03-02 22:42:10 -0800255 gpr_join_host_port(&cli_target, host, init_status.port());
256 client_config.add_server_targets(cli_target);
257 gpr_free(host);
258 gpr_free(driver_port);
259 gpr_free(cli_target);
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800260 }
261
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800262 // Targets are all set by now
263 result_client_config = client_config;
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800264 // Start clients
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700265 using runsc::ClientData;
Vijay Pai90e73692015-08-05 19:15:36 -0700266 // clients is array rather than std::vector to avoid gcc-4.4 issues
267 // where class contained in std::vector must have a copy constructor
vjpaib1db8692015-08-11 22:41:02 -0700268 auto* clients = new ClientData[num_clients];
Craig Tiller6af9ed02015-03-02 22:42:10 -0800269 for (size_t i = 0; i < num_clients; i++) {
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800270 const auto& worker = workers[i + num_servers];
Vijay Pai59567422016-02-01 13:28:55 -0800271 gpr_log(GPR_INFO, "Starting client on %s (worker #%d)", worker.c_str(),
272 i + num_servers);
Julien Boeuf6049ebd2015-11-17 16:53:52 -0800273 clients[i].stub = WorkerService::NewStub(
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800274 CreateChannel(worker, InsecureChannelCredentials()));
275 ClientConfig per_client_config = client_config;
276
277 int server_core_limit = initial_server_config.core_limit();
278 int client_core_limit = initial_client_config.core_limit();
279 if ((server_core_limit > 0) || (client_core_limit > 0)) {
Vijay Paidaadcc82016-02-01 16:49:55 -0800280 auto& dq = hosts_cores.at(get_host(worker));
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800281 if (client_core_limit == 0) {
282 // limit client cores if it matches a server host
283 bool match = false;
284 int limit = dq.size();
285 for (size_t srv = 0; srv < num_servers; srv++) {
286 if (get_host(worker) == get_host(workers[srv])) {
287 match = true;
288 }
289 }
290 if (match) {
Vijay Pai6b056392016-02-01 13:01:34 -0800291 GPR_ASSERT(limit > 0);
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800292 client_core_limit = limit;
293 }
294 }
295 if (client_core_limit > 0) {
296 GPR_ASSERT(dq.size() >= static_cast<size_t>(client_core_limit));
Vijay Pai59567422016-02-01 13:28:55 -0800297 for (int core = 0; core < client_core_limit; core++) {
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800298 per_client_config.add_core_list(dq.front());
299 dq.pop_front();
300 }
301 }
302 }
303
Craig Tiller6af9ed02015-03-02 22:42:10 -0800304 ClientArgs args;
Vijay Pai7d45cdb2016-02-01 13:00:19 -0800305 *args.mutable_setup() = per_client_config;
Vijay Pai90e73692015-08-05 19:15:36 -0700306 clients[i].stream =
vjpai52bfb252015-10-21 07:50:49 -0700307 clients[i].stub->RunClient(runsc::AllocContext(&contexts, deadline));
Vijay Paieed63fa2015-08-05 23:08:34 +0000308 GPR_ASSERT(clients[i].stream->Write(args));
Craig Tiller6af9ed02015-03-02 22:42:10 -0800309 ClientStatus init_status;
Vijay Paieed63fa2015-08-05 23:08:34 +0000310 GPR_ASSERT(clients[i].stream->Read(&init_status));
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800311 }
312
Craig Tiller6af9ed02015-03-02 22:42:10 -0800313 // Let everything warmup
314 gpr_log(GPR_INFO, "Warming up");
Craig Tiller20b5fe92015-07-06 10:43:50 -0700315 gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
Craig Tiller677c50c2015-07-13 10:49:06 -0700316 gpr_sleep_until(
317 gpr_time_add(start, gpr_time_from_seconds(warmup_seconds, GPR_TIMESPAN)));
Craig Tiller6af9ed02015-03-02 22:42:10 -0800318
319 // Start a run
320 gpr_log(GPR_INFO, "Starting");
321 ServerArgs server_mark;
vjpai119c1032015-10-29 01:21:04 -0700322 server_mark.mutable_mark()->set_reset(true);
Craig Tiller6af9ed02015-03-02 22:42:10 -0800323 ClientArgs client_mark;
vjpai119c1032015-10-29 01:21:04 -0700324 client_mark.mutable_mark()->set_reset(true);
Vijay Paieed63fa2015-08-05 23:08:34 +0000325 for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
Vijay Pai82dd80a2015-03-24 10:36:08 -0700326 GPR_ASSERT(server->stream->Write(server_mark));
Craig Tiller6af9ed02015-03-02 22:42:10 -0800327 }
Vijay Paieed63fa2015-08-05 23:08:34 +0000328 for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
Vijay Pai82dd80a2015-03-24 10:36:08 -0700329 GPR_ASSERT(client->stream->Write(client_mark));
Craig Tiller6af9ed02015-03-02 22:42:10 -0800330 }
331 ServerStatus server_status;
332 ClientStatus client_status;
Vijay Paieed63fa2015-08-05 23:08:34 +0000333 for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
Vijay Pai82dd80a2015-03-24 10:36:08 -0700334 GPR_ASSERT(server->stream->Read(&server_status));
Craig Tiller6af9ed02015-03-02 22:42:10 -0800335 }
Vijay Paieed63fa2015-08-05 23:08:34 +0000336 for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
Vijay Pai82dd80a2015-03-24 10:36:08 -0700337 GPR_ASSERT(client->stream->Read(&client_status));
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800338 }
339
Craig Tiller6af9ed02015-03-02 22:42:10 -0800340 // Wait some time
341 gpr_log(GPR_INFO, "Running");
Vijay Pai90e73692015-08-05 19:15:36 -0700342 // Use gpr_sleep_until rather than this_thread::sleep_until to support
343 // compilers that don't work with this_thread
Craig Tiller677c50c2015-07-13 10:49:06 -0700344 gpr_sleep_until(gpr_time_add(
345 start, gpr_time_from_seconds(benchmark_seconds, GPR_TIMESPAN)));
Craig Tiller6af9ed02015-03-02 22:42:10 -0800346
347 // Finish a run
David Garcia Quintas08116502015-05-20 17:27:23 -0700348 std::unique_ptr<ScenarioResult> result(new ScenarioResult);
349 result->client_config = result_client_config;
350 result->server_config = result_server_config;
vjpai60a7e332016-02-26 10:30:17 -0800351 gpr_log(GPR_INFO, "Finishing clients");
Vijay Paieed63fa2015-08-05 23:08:34 +0000352 for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
Vijay Pai82dd80a2015-03-24 10:36:08 -0700353 GPR_ASSERT(client->stream->Write(client_mark));
Vijay Pai02eda412016-02-25 19:43:57 -0800354 GPR_ASSERT(client->stream->WritesDone());
Craig Tiller6af9ed02015-03-02 22:42:10 -0800355 }
Vijay Paieed63fa2015-08-05 23:08:34 +0000356 for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
Vijay Pai82dd80a2015-03-24 10:36:08 -0700357 GPR_ASSERT(client->stream->Read(&client_status));
Craig Tillerf2825142015-03-03 17:15:36 -0800358 const auto& stats = client_status.stats();
David Garcia Quintas08116502015-05-20 17:27:23 -0700359 result->latencies.MergeProto(stats.latencies());
Vijay Pai4d06e2e2015-07-31 10:20:42 -0700360 result->client_resources.emplace_back(
Vijay Paice846702015-11-04 00:30:12 -0800361 stats.time_elapsed(), stats.time_user(), stats.time_system(), -1);
Vijay Pai02eda412016-02-25 19:43:57 -0800362 GPR_ASSERT(!client->stream->Read(&client_status));
Craig Tiller6af9ed02015-03-02 22:42:10 -0800363 }
Vijay Paieed63fa2015-08-05 23:08:34 +0000364 for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
Yang Gaoc1a2c312015-06-16 10:59:46 -0700365 GPR_ASSERT(client->stream->Finish().ok());
Craig Tiller6af9ed02015-03-02 22:42:10 -0800366 }
vjpai60a7e332016-02-26 10:30:17 -0800367 delete[] clients;
368
369 gpr_log(GPR_INFO, "Finishing servers");
370 for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
371 GPR_ASSERT(server->stream->Write(server_mark));
372 GPR_ASSERT(server->stream->WritesDone());
373 }
374 for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
375 GPR_ASSERT(server->stream->Read(&server_status));
376 const auto& stats = server_status.stats();
377 result->server_resources.emplace_back(
378 stats.time_elapsed(), stats.time_user(), stats.time_system(),
379 server_status.cores());
380 GPR_ASSERT(!server->stream->Read(&server_status));
381 }
Vijay Paieed63fa2015-08-05 23:08:34 +0000382 for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
Yang Gaoc1a2c312015-06-16 10:59:46 -0700383 GPR_ASSERT(server->stream->Finish().ok());
Craig Tiller2d0f36c2015-02-23 23:16:17 -0800384 }
vjpai60a7e332016-02-26 10:30:17 -0800385
vjpaib1db8692015-08-11 22:41:02 -0700386 delete[] servers;
Craig Tillerf2825142015-03-03 17:15:36 -0800387 return result;
Craig Tiller4ef7a292015-02-23 17:29:01 -0800388}
vjpai21e5d2b2016-02-02 09:36:36 -0800389
390void RunQuit() {
391 // Get client, server lists
Vijay Pai20664432016-02-02 11:48:12 -0800392 auto workers = get_workers("QPS_WORKERS");
vjpai21e5d2b2016-02-02 09:36:36 -0800393 for (size_t i = 0; i < workers.size(); i++) {
394 auto stub = WorkerService::NewStub(
Vijay Pai2ed337a2016-02-02 09:43:35 -0800395 CreateChannel(workers[i], InsecureChannelCredentials()));
vjpai21e5d2b2016-02-02 09:36:36 -0800396 Void dummy;
397 grpc::ClientContext ctx;
398 GPR_ASSERT(stub->QuitWorker(&ctx, dummy, &dummy).ok());
399 }
400}
401
Craig Tillerf2825142015-03-03 17:15:36 -0800402} // namespace testing
403} // namespace grpc