blob: 5fdf7a407d90102128a69bb9ba7ffd36da69009b [file] [log] [blame]
Jan Tattermuschb2758442016-03-28 09:32:20 -07001#!/usr/bin/env python2.7
2# Copyright 2016, Google Inc.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9# * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15# * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31"""Run performance tests locally or remotely."""
32
siddharthshukla0589e532016-07-07 16:08:01 +020033from __future__ import print_function
34
Jan Tattermuschb2758442016-03-28 09:32:20 -070035import argparse
Jan Tattermuschbb1a4532016-03-30 18:04:01 -070036import itertools
Jan Tattermuschb2758442016-03-28 09:32:20 -070037import jobset
Craig Tiller0bda0b32016-03-03 12:51:53 -080038import json
Jan Tattermuschb2758442016-03-28 09:32:20 -070039import multiprocessing
40import os
Craig Tiller0bda0b32016-03-03 12:51:53 -080041import pipes
Jan Tattermusch38becc22016-04-14 08:00:35 -070042import re
Jan Tattermuschb2758442016-03-28 09:32:20 -070043import subprocess
44import sys
45import tempfile
46import time
Jan Tattermuschee9032c2016-04-14 08:35:51 -070047import traceback
Jan Tattermuschb2758442016-03-28 09:32:20 -070048import uuid
Craig Tillerd92d5c52016-04-04 13:49:29 -070049import performance.scenario_config as scenario_config
Jan Tattermuschb2758442016-03-28 09:32:20 -070050
51
52_ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
53os.chdir(_ROOT)
54
55
56_REMOTE_HOST_USERNAME = 'jenkins'
57
58
Jan Tattermuschb2758442016-03-28 09:32:20 -070059class QpsWorkerJob:
60 """Encapsulates a qps worker server job."""
61
Jan Tattermuschbb1a4532016-03-30 18:04:01 -070062 def __init__(self, spec, language, host_and_port):
Jan Tattermuschb2758442016-03-28 09:32:20 -070063 self._spec = spec
Jan Tattermuschbb1a4532016-03-30 18:04:01 -070064 self.language = language
Jan Tattermuschb2758442016-03-28 09:32:20 -070065 self.host_and_port = host_and_port
Craig Tiller2e1a1fe2016-06-23 16:18:31 -070066 self._job = jobset.Job(spec, newline_on_success=True, travis=True, add_env={})
Jan Tattermuschb2758442016-03-28 09:32:20 -070067
68 def is_running(self):
69 """Polls a job and returns True if given job is still running."""
Craig Tiller2e1a1fe2016-06-23 16:18:31 -070070 return self._job.state() == jobset._RUNNING
Jan Tattermuschb2758442016-03-28 09:32:20 -070071
72 def kill(self):
73 return self._job.kill()
74
75
Jan Tattermuschbb1a4532016-03-30 18:04:01 -070076def create_qpsworker_job(language, shortname=None,
77 port=10000, remote_host=None):
Jan Tattermuschbb1a4532016-03-30 18:04:01 -070078 cmdline = language.worker_cmdline() + ['--driver_port=%s' % port]
Jan Tattermuschb2758442016-03-28 09:32:20 -070079 if remote_host:
80 user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
Jan Tattermuschbb1a4532016-03-30 18:04:01 -070081 cmdline = ['ssh',
82 str(user_at_host),
83 'cd ~/performance_workspace/grpc/ && %s' % ' '.join(cmdline)]
Jan Tattermuschb2758442016-03-28 09:32:20 -070084 host_and_port='%s:%s' % (remote_host, port)
85 else:
86 host_and_port='localhost:%s' % port
87
Jan Tattermusch38becc22016-04-14 08:00:35 -070088 # TODO(jtattermusch): with some care, we can calculate the right timeout
89 # of a worker from the sum of warmup + benchmark times for all the scenarios
Jan Tattermuschb2758442016-03-28 09:32:20 -070090 jobspec = jobset.JobSpec(
Jan Tattermuschbb1a4532016-03-30 18:04:01 -070091 cmdline=cmdline,
92 shortname=shortname,
Jan Tattermusch541d5d72016-05-05 16:08:49 -070093 timeout_seconds=2*60*60)
Jan Tattermuschbb1a4532016-03-30 18:04:01 -070094 return QpsWorkerJob(jobspec, language, host_and_port)
Jan Tattermuschb2758442016-03-28 09:32:20 -070095
96
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070097def create_scenario_jobspec(scenario_json, workers, remote_host=None,
98 bq_result_table=None):
Jan Tattermuschb2758442016-03-28 09:32:20 -070099 """Runs one scenario using QPS driver."""
100 # setting QPS_WORKERS env variable here makes sure it works with SSH too.
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700101 cmd = 'QPS_WORKERS="%s" ' % ','.join(workers)
102 if bq_result_table:
103 cmd += 'BQ_RESULT_TABLE="%s" ' % bq_result_table
104 cmd += 'tools/run_tests/performance/run_qps_driver.sh '
105 cmd += '--scenarios_json=%s ' % pipes.quote(json.dumps({'scenarios': [scenario_json]}))
106 cmd += '--scenario_result_file=scenario_result.json'
Jan Tattermuschb2758442016-03-28 09:32:20 -0700107 if remote_host:
108 user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700109 cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && "%s' % (user_at_host, pipes.quote(cmd))
Jan Tattermuschb2758442016-03-28 09:32:20 -0700110
111 return jobset.JobSpec(
112 cmdline=[cmd],
Craig Tiller0bda0b32016-03-03 12:51:53 -0800113 shortname='qps_json_driver.%s' % scenario_json['name'],
114 timeout_seconds=3*60,
115 shell=True,
116 verbose_success=True)
117
118
119def create_quit_jobspec(workers, remote_host=None):
120 """Runs quit using QPS driver."""
121 # setting QPS_WORKERS env variable here makes sure it works with SSH too.
vjpai29089c72016-04-20 12:38:16 -0700122 cmd = 'QPS_WORKERS="%s" bins/opt/qps_json_driver --quit' % ','.join(workers)
Craig Tiller0bda0b32016-03-03 12:51:53 -0800123 if remote_host:
124 user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700125 cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && "%s' % (user_at_host, pipes.quote(cmd))
Craig Tiller0bda0b32016-03-03 12:51:53 -0800126
127 return jobset.JobSpec(
128 cmdline=[cmd],
vjpai29089c72016-04-20 12:38:16 -0700129 shortname='qps_json_driver.quit',
Jan Tattermuschb2758442016-03-28 09:32:20 -0700130 timeout_seconds=3*60,
131 shell=True,
132 verbose_success=True)
133
134
Jan Tattermusch4de2c322016-05-10 14:33:07 -0700135def create_netperf_jobspec(server_host='localhost', client_host=None,
136 bq_result_table=None):
137 """Runs netperf benchmark."""
138 cmd = 'NETPERF_SERVER_HOST="%s" ' % server_host
139 if bq_result_table:
140 cmd += 'BQ_RESULT_TABLE="%s" ' % bq_result_table
Jan Tattermuschad17bf72016-05-11 12:41:37 -0700141 if client_host:
142 # If netperf is running remotely, the env variables populated by Jenkins
143 # won't be available on the client, but we need them for uploading results
144 # to BigQuery.
145 jenkins_job_name = os.getenv('JOB_NAME')
146 if jenkins_job_name:
147 cmd += 'JOB_NAME="%s" ' % jenkins_job_name
148 jenkins_build_number = os.getenv('BUILD_NUMBER')
149 if jenkins_build_number:
150 cmd += 'BUILD_NUMBER="%s" ' % jenkins_build_number
151
Jan Tattermusch4de2c322016-05-10 14:33:07 -0700152 cmd += 'tools/run_tests/performance/run_netperf.sh'
153 if client_host:
154 user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, client_host)
155 cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && "%s' % (user_at_host, pipes.quote(cmd))
156
157 return jobset.JobSpec(
158 cmdline=[cmd],
159 shortname='netperf',
160 timeout_seconds=60,
161 shell=True,
162 verbose_success=True)
163
164
Jan Tattermuschde874a12016-04-18 09:21:37 -0700165def archive_repo(languages):
Jan Tattermuschb2758442016-03-28 09:32:20 -0700166 """Archives local version of repo including submodules."""
Jan Tattermuschde874a12016-04-18 09:21:37 -0700167 cmdline=['tar', '-cf', '../grpc.tar', '../grpc/']
168 if 'java' in languages:
169 cmdline.append('../grpc-java')
170 if 'go' in languages:
171 cmdline.append('../grpc-go')
172
Jan Tattermuschb2758442016-03-28 09:32:20 -0700173 archive_job = jobset.JobSpec(
Jan Tattermuschde874a12016-04-18 09:21:37 -0700174 cmdline=cmdline,
Jan Tattermuschb2758442016-03-28 09:32:20 -0700175 shortname='archive_repo',
176 timeout_seconds=3*60)
177
178 jobset.message('START', 'Archiving local repository.', do_newline=True)
179 num_failures, _ = jobset.run(
180 [archive_job], newline_on_success=True, maxjobs=1)
181 if num_failures == 0:
182 jobset.message('SUCCESS',
Jan Tattermuschde874a12016-04-18 09:21:37 -0700183 'Archive with local repository created successfully.',
Jan Tattermuschb2758442016-03-28 09:32:20 -0700184 do_newline=True)
185 else:
186 jobset.message('FAILED', 'Failed to archive local repository.',
187 do_newline=True)
188 sys.exit(1)
189
190
Jan Tattermusch14089202016-04-27 17:55:27 -0700191def prepare_remote_hosts(hosts, prepare_local=False):
192 """Prepares remote hosts (and maybe prepare localhost as well)."""
193 prepare_timeout = 5*60
Jan Tattermuschb2758442016-03-28 09:32:20 -0700194 prepare_jobs = []
195 for host in hosts:
196 user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, host)
197 prepare_jobs.append(
198 jobset.JobSpec(
199 cmdline=['tools/run_tests/performance/remote_host_prepare.sh'],
200 shortname='remote_host_prepare.%s' % host,
201 environ = {'USER_AT_HOST': user_at_host},
Jan Tattermusch14089202016-04-27 17:55:27 -0700202 timeout_seconds=prepare_timeout))
203 if prepare_local:
204 # Prepare localhost as well
205 prepare_jobs.append(
206 jobset.JobSpec(
207 cmdline=['tools/run_tests/performance/kill_workers.sh'],
208 shortname='local_prepare',
209 timeout_seconds=prepare_timeout))
210 jobset.message('START', 'Preparing hosts.', do_newline=True)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700211 num_failures, _ = jobset.run(
212 prepare_jobs, newline_on_success=True, maxjobs=10)
213 if num_failures == 0:
214 jobset.message('SUCCESS',
Jan Tattermusch14089202016-04-27 17:55:27 -0700215 'Prepare step completed successfully.',
Jan Tattermuschb2758442016-03-28 09:32:20 -0700216 do_newline=True)
217 else:
218 jobset.message('FAILED', 'Failed to prepare remote hosts.',
219 do_newline=True)
220 sys.exit(1)
221
222
Craig Tillerd92d5c52016-04-04 13:49:29 -0700223def build_on_remote_hosts(hosts, languages=scenario_config.LANGUAGES.keys(), build_local=False):
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700224 """Builds performance worker on remote hosts (and maybe also locally)."""
Jan Tattermuschb2758442016-03-28 09:32:20 -0700225 build_timeout = 15*60
226 build_jobs = []
227 for host in hosts:
228 user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, host)
229 build_jobs.append(
230 jobset.JobSpec(
Craig Tiller7797e3f2016-04-01 07:41:05 -0700231 cmdline=['tools/run_tests/performance/remote_host_build.sh'] + languages,
Jan Tattermuschb2758442016-03-28 09:32:20 -0700232 shortname='remote_host_build.%s' % host,
233 environ = {'USER_AT_HOST': user_at_host, 'CONFIG': 'opt'},
234 timeout_seconds=build_timeout))
235 if build_local:
236 # Build locally as well
237 build_jobs.append(
238 jobset.JobSpec(
Craig Tiller7797e3f2016-04-01 07:41:05 -0700239 cmdline=['tools/run_tests/performance/build_performance.sh'] + languages,
Jan Tattermuschb2758442016-03-28 09:32:20 -0700240 shortname='local_build',
241 environ = {'CONFIG': 'opt'},
242 timeout_seconds=build_timeout))
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700243 jobset.message('START', 'Building.', do_newline=True)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700244 num_failures, _ = jobset.run(
245 build_jobs, newline_on_success=True, maxjobs=10)
246 if num_failures == 0:
247 jobset.message('SUCCESS',
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700248 'Built successfully.',
Jan Tattermuschb2758442016-03-28 09:32:20 -0700249 do_newline=True)
250 else:
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700251 jobset.message('FAILED', 'Build failed.',
Jan Tattermuschb2758442016-03-28 09:32:20 -0700252 do_newline=True)
253 sys.exit(1)
254
255
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700256def start_qpsworkers(languages, worker_hosts):
Jan Tattermuschb2758442016-03-28 09:32:20 -0700257 """Starts QPS workers as background jobs."""
258 if not worker_hosts:
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700259 # run two workers locally (for each language)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700260 workers=[(None, 10000), (None, 10010)]
261 elif len(worker_hosts) == 1:
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700262 # run two workers on the remote host (for each language)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700263 workers=[(worker_hosts[0], 10000), (worker_hosts[0], 10010)]
264 else:
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700265 # run one worker per each remote host (for each language)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700266 workers=[(worker_host, 10000) for worker_host in worker_hosts]
267
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700268 return [create_qpsworker_job(language,
269 shortname= 'qps_worker_%s_%s' % (language,
270 worker_idx),
271 port=worker[1] + language.worker_port_offset(),
Jan Tattermuschb2758442016-03-28 09:32:20 -0700272 remote_host=worker[0])
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700273 for language in languages
274 for worker_idx, worker in enumerate(workers)]
Jan Tattermuschb2758442016-03-28 09:32:20 -0700275
276
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700277def create_scenarios(languages, workers_by_lang, remote_host=None, regex='.*',
Jan Tattermusch4de2c322016-05-10 14:33:07 -0700278 category='all', bq_result_table=None,
279 netperf=False, netperf_hosts=[]):
Jan Tattermuschb2758442016-03-28 09:32:20 -0700280 """Create jobspecs for scenarios to run."""
Ken Payson0482c102016-04-19 12:08:34 -0700281 all_workers = [worker
282 for workers in workers_by_lang.values()
283 for worker in workers]
Jan Tattermuschb2758442016-03-28 09:32:20 -0700284 scenarios = []
Jan Tattermusch4de2c322016-05-10 14:33:07 -0700285
286 if netperf:
287 if not netperf_hosts:
288 netperf_server='localhost'
289 netperf_client=None
290 elif len(netperf_hosts) == 1:
291 netperf_server=netperf_hosts[0]
292 netperf_client=netperf_hosts[0]
293 else:
294 netperf_server=netperf_hosts[0]
295 netperf_client=netperf_hosts[1]
296 scenarios.append(create_netperf_jobspec(server_host=netperf_server,
297 client_host=netperf_client,
298 bq_result_table=bq_result_table))
299
Jan Tattermuschb2758442016-03-28 09:32:20 -0700300 for language in languages:
Craig Tiller0bda0b32016-03-03 12:51:53 -0800301 for scenario_json in language.scenarios():
Jan Tattermusch38becc22016-04-14 08:00:35 -0700302 if re.search(args.regex, scenario_json['name']):
Jan Tattermusch427699b2016-05-05 18:10:14 -0700303 if category in scenario_json.get('CATEGORIES', []) or category == 'all':
304 workers = workers_by_lang[str(language)]
305 # 'SERVER_LANGUAGE' is an indicator for this script to pick
306 # a server in different language.
307 custom_server_lang = scenario_json.get('SERVER_LANGUAGE', None)
Jan Tattermusch37a907e2016-05-13 13:49:43 -0700308 custom_client_lang = scenario_json.get('CLIENT_LANGUAGE', None)
Jan Tattermusch427699b2016-05-05 18:10:14 -0700309 scenario_json = scenario_config.remove_nonproto_fields(scenario_json)
Jan Tattermusch37a907e2016-05-13 13:49:43 -0700310 if custom_server_lang and custom_client_lang:
311 raise Exception('Cannot set both custom CLIENT_LANGUAGE and SERVER_LANGUAGE'
312 'in the same scenario')
Jan Tattermusch427699b2016-05-05 18:10:14 -0700313 if custom_server_lang:
314 if not workers_by_lang.get(custom_server_lang, []):
siddharthshukla0589e532016-07-07 16:08:01 +0200315 print('Warning: Skipping scenario %s as' % scenario_json['name'])
Jan Tattermusch427699b2016-05-05 18:10:14 -0700316 print('SERVER_LANGUAGE is set to %s yet the language has '
317 'not been selected with -l' % custom_server_lang)
318 continue
319 for idx in range(0, scenario_json['num_servers']):
320 # replace first X workers by workers of a different language
321 workers[idx] = workers_by_lang[custom_server_lang][idx]
Jan Tattermusch37a907e2016-05-13 13:49:43 -0700322 if custom_client_lang:
323 if not workers_by_lang.get(custom_client_lang, []):
siddharthshukla0589e532016-07-07 16:08:01 +0200324 print('Warning: Skipping scenario %s as' % scenario_json['name'])
Jan Tattermusch37a907e2016-05-13 13:49:43 -0700325 print('CLIENT_LANGUAGE is set to %s yet the language has '
326 'not been selected with -l' % custom_client_lang)
327 continue
328 for idx in range(scenario_json['num_servers'], len(workers)):
329 # replace all client workers by workers of a different language,
330 # leave num_server workers as they are server workers.
331 workers[idx] = workers_by_lang[custom_client_lang][idx]
Jan Tattermusch427699b2016-05-05 18:10:14 -0700332 scenario = create_scenario_jobspec(scenario_json,
333 workers,
334 remote_host=remote_host,
335 bq_result_table=bq_result_table)
336 scenarios.append(scenario)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700337
338 # the very last scenario requests shutting down the workers.
Craig Tiller0bda0b32016-03-03 12:51:53 -0800339 scenarios.append(create_quit_jobspec(all_workers, remote_host=remote_host))
Jan Tattermuschb2758442016-03-28 09:32:20 -0700340 return scenarios
341
342
343def finish_qps_workers(jobs):
344 """Waits for given jobs to finish and eventually kills them."""
345 retries = 0
346 while any(job.is_running() for job in jobs):
347 for job in qpsworker_jobs:
348 if job.is_running():
siddharthshukla0589e532016-07-07 16:08:01 +0200349 print('QPS worker "%s" is still running.' % job.host_and_port)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700350 if retries > 10:
siddharthshukla0589e532016-07-07 16:08:01 +0200351 print('Killing all QPS workers.')
Jan Tattermuschb2758442016-03-28 09:32:20 -0700352 for job in jobs:
353 job.kill()
354 retries += 1
355 time.sleep(3)
siddharthshukla0589e532016-07-07 16:08:01 +0200356 print('All QPS workers finished.')
Jan Tattermuschb2758442016-03-28 09:32:20 -0700357
358
359argp = argparse.ArgumentParser(description='Run performance tests.')
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700360argp.add_argument('-l', '--language',
Craig Tillerd92d5c52016-04-04 13:49:29 -0700361 choices=['all'] + sorted(scenario_config.LANGUAGES.keys()),
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700362 nargs='+',
Jan Tattermusch427699b2016-05-05 18:10:14 -0700363 required=True,
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700364 help='Languages to benchmark.')
Jan Tattermuschb2758442016-03-28 09:32:20 -0700365argp.add_argument('--remote_driver_host',
366 default=None,
367 help='Run QPS driver on given host. By default, QPS driver is run locally.')
368argp.add_argument('--remote_worker_host',
369 nargs='+',
370 default=[],
371 help='Worker hosts where to start QPS workers.')
Jan Tattermusch38becc22016-04-14 08:00:35 -0700372argp.add_argument('-r', '--regex', default='.*', type=str,
373 help='Regex to select scenarios to run.')
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700374argp.add_argument('--bq_result_table', default=None, type=str,
375 help='Bigquery "dataset.table" to upload results to.')
Jan Tattermusch427699b2016-05-05 18:10:14 -0700376argp.add_argument('--category',
Jan Tattermuschd27888b2016-05-19 16:11:11 -0700377 choices=['smoketest','all','scalable'],
Jan Tattermusch37a907e2016-05-13 13:49:43 -0700378 default='all',
379 help='Select a category of tests to run.')
Jan Tattermusch4de2c322016-05-10 14:33:07 -0700380argp.add_argument('--netperf',
381 default=False,
382 action='store_const',
383 const=True,
384 help='Run netperf benchmark as one of the scenarios.')
Jan Tattermuschb2758442016-03-28 09:32:20 -0700385
386args = argp.parse_args()
387
Craig Tillerd92d5c52016-04-04 13:49:29 -0700388languages = set(scenario_config.LANGUAGES[l]
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700389 for l in itertools.chain.from_iterable(
Craig Tillerd92d5c52016-04-04 13:49:29 -0700390 scenario_config.LANGUAGES.iterkeys() if x == 'all' else [x]
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700391 for x in args.language))
392
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700393
Jan Tattermuschb2758442016-03-28 09:32:20 -0700394# Put together set of remote hosts where to run and build
395remote_hosts = set()
396if args.remote_worker_host:
397 for host in args.remote_worker_host:
398 remote_hosts.add(host)
399if args.remote_driver_host:
400 remote_hosts.add(args.remote_driver_host)
401
402if remote_hosts:
Jan Tattermuschde874a12016-04-18 09:21:37 -0700403 archive_repo(languages=[str(l) for l in languages])
Jan Tattermusch14089202016-04-27 17:55:27 -0700404 prepare_remote_hosts(remote_hosts, prepare_local=True)
405else:
406 prepare_remote_hosts([], prepare_local=True)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700407
408build_local = False
409if not args.remote_driver_host:
410 build_local = True
Craig Tiller7797e3f2016-04-01 07:41:05 -0700411build_on_remote_hosts(remote_hosts, languages=[str(l) for l in languages], build_local=build_local)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700412
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700413qpsworker_jobs = start_qpsworkers(languages, args.remote_worker_host)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700414
Jan Tattermusch38becc22016-04-14 08:00:35 -0700415# TODO(jtattermusch): see https://github.com/grpc/grpc/issues/6174
416time.sleep(5)
417
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700418# get list of worker addresses for each language.
419worker_addresses = dict([(str(language), []) for language in languages])
420for job in qpsworker_jobs:
421 worker_addresses[str(job.language)].append(job.host_and_port)
Jan Tattermuschb2758442016-03-28 09:32:20 -0700422
423try:
Jan Tattermuschbb1a4532016-03-30 18:04:01 -0700424 scenarios = create_scenarios(languages,
425 workers_by_lang=worker_addresses,
Jan Tattermusch38becc22016-04-14 08:00:35 -0700426 remote_host=args.remote_driver_host,
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700427 regex=args.regex,
Jan Tattermusch427699b2016-05-05 18:10:14 -0700428 category=args.category,
Jan Tattermusch4de2c322016-05-10 14:33:07 -0700429 bq_result_table=args.bq_result_table,
430 netperf=args.netperf,
431 netperf_hosts=args.remote_worker_host)
432
Jan Tattermuschb2758442016-03-28 09:32:20 -0700433 if not scenarios:
434 raise Exception('No scenarios to run')
435
436 jobset.message('START', 'Running scenarios.', do_newline=True)
437 num_failures, _ = jobset.run(
438 scenarios, newline_on_success=True, maxjobs=1)
439 if num_failures == 0:
440 jobset.message('SUCCESS',
441 'All scenarios finished successfully.',
442 do_newline=True)
443 else:
444 jobset.message('FAILED', 'Some of the scenarios failed.',
445 do_newline=True)
446 sys.exit(1)
Jan Tattermuschee9032c2016-04-14 08:35:51 -0700447except:
448 traceback.print_exc()
Jan Tattermuschb688db02016-04-21 08:53:45 -0700449 raise
Jan Tattermuschb2758442016-03-28 09:32:20 -0700450finally:
451 finish_qps_workers(qpsworker_jobs)