blob: 671dd4b5e9f765d90d8e1723446a93195234e3dd [file] [log] [blame]
Simran Basi833814b2013-01-29 13:13:43 -08001# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +08005import json
Simran Basi833814b2013-01-29 13:13:43 -08006import logging
7import os
Simran Basi833814b2013-01-29 13:13:43 -08008import StringIO
9
Simran Basi833814b2013-01-29 13:13:43 -080010from autotest_lib.client.common_lib import error, utils
11from autotest_lib.client.common_lib.cros import dev_server
12
13
Dave Tu6a404e62013-11-05 15:54:48 -080014TELEMETRY_RUN_BENCHMARKS_SCRIPT = 'tools/perf/run_benchmark'
Ilja H. Friedel086bc3f2014-02-27 22:17:55 -080015TELEMETRY_RUN_TESTS_SCRIPT = 'tools/telemetry/run_tests'
Gurchetan Singhfaf75e92017-04-17 18:09:44 -070016TELEMETRY_RUN_GPU_TESTS_SCRIPT = 'content/test/gpu/run_gpu_integration_test.py'
Mao Huangc9642d72017-09-28 16:50:02 +080017TELEMETRY_TIMEOUT_MINS = 150
Simran Basi833814b2013-01-29 13:13:43 -080018
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080019DUT_CHROME_ROOT = '/usr/local/telemetry/src'
20
Simran Basi833814b2013-01-29 13:13:43 -080021# Result Statuses
22SUCCESS_STATUS = 'SUCCESS'
23WARNING_STATUS = 'WARNING'
24FAILED_STATUS = 'FAILED'
25
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080026# A list of benchmarks with that the telemetry test harness can run on dut.
wutao5a6dedd2018-03-01 18:15:31 -080027ON_DUT_WHITE_LIST = ['cros_ui_smoothness',
28 'dromaeo.domcoreattr',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080029 'dromaeo.domcoremodify',
30 'dromaeo.domcorequery',
31 'dromaeo.domcoretraverse',
32 'image_decoding.image_decoding_measurement',
33 'jetstream',
34 'kraken',
35 'memory.top_7_stress',
36 'octane',
37 'page_cycler.typical_25',
Chung-yih Wang80ba5812017-01-20 17:22:11 +080038 'page_cycler_v2.typical_25',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080039 'robohornet_pro',
Chung-yih Wang46672322018-03-30 16:28:57 +080040 'smoothness.top_25_smooth',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080041 'smoothness.tough_animation_cases',
42 'smoothness.tough_canvas_cases',
43 'smoothness.tough_filters_cases',
44 'smoothness.tough_pinch_zoom_cases',
45 'smoothness.tough_scrolling_cases',
46 'smoothness.tough_webgl_cases',
47 'speedometer',
Hsu-Cheng Tsaied1d6b32018-05-17 17:28:28 +080048 'speedometer2',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080049 'sunspider',
50 'tab_switching.top_10',
Chung-yih Wang80ba5812017-01-20 17:22:11 +080051 'tab_switching.typical_25',
Patrik Höglund2ef2e172016-11-16 10:07:29 +010052 'webrtc.peerconnection',
53 'webrtc.stress']
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080054
55# BLACK LIST
56# 'session_restore.cold.typical_25', # profile generator not implemented on
57 # CrOS.
Simran Basi833814b2013-01-29 13:13:43 -080058
59class TelemetryResult(object):
60 """Class to represent the results of a telemetry run.
61
62 This class represents the results of a telemetry run, whether it ran
63 successful, failed or had warnings.
64 """
65
66
67 def __init__(self, exit_code=0, stdout='', stderr=''):
68 """Initializes this TelemetryResultObject instance.
69
70 @param status: Status of the telemtry run.
71 @param stdout: Stdout of the telemetry run.
72 @param stderr: Stderr of the telemetry run.
73 """
74 if exit_code == 0:
75 self.status = SUCCESS_STATUS
76 else:
77 self.status = FAILED_STATUS
78
Simran Basi833814b2013-01-29 13:13:43 -080079 self._stdout = stdout
80 self._stderr = stderr
81 self.output = '\n'.join([stdout, stderr])
82
83
Simran Basi833814b2013-01-29 13:13:43 -080084class TelemetryRunner(object):
85 """Class responsible for telemetry for a given build.
86
87 This class will extract and install telemetry on the devserver and is
88 responsible for executing the telemetry benchmarks and returning their
89 output to the caller.
90 """
91
Ting-Yuan Huang85dcde82016-04-08 17:41:32 +080092 def __init__(self, host, local=False, telemetry_on_dut=True):
Simran Basi833814b2013-01-29 13:13:43 -080093 """Initializes this telemetry runner instance.
94
95 If telemetry is not installed for this build, it will be.
Luis Lozano23ae3192013-11-08 16:22:46 -080096
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080097 Basically, the following commands on the local pc on which test_that
98 will be executed, depending on the 4 possible combinations of
99 local x telemetry_on_dut:
100
101 local=True, telemetry_on_dut=False:
102 run_benchmark --browser=cros-chrome --remote=[dut] [test]
103
104 local=True, telemetry_on_dut=True:
105 ssh [dut] run_benchmark --browser=system [test]
106
107 local=False, telemetry_on_dut=False:
108 ssh [devserver] run_benchmark --browser=cros-chrome --remote=[dut] [test]
109
110 local=False, telemetry_on_dut=True:
111 ssh [devserver] ssh [dut] run_benchmark --browser=system [test]
112
Luis Lozano23ae3192013-11-08 16:22:46 -0800113 @param host: Host where the test will be run.
114 @param local: If set, no devserver will be used, test will be run
115 locally.
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800116 If not set, "ssh [devserver] " will be appended to test
117 commands.
118 @param telemetry_on_dut: If set, telemetry itself (the test harness)
119 will run on dut.
120 It decides browser=[system|cros-chrome]
Simran Basi833814b2013-01-29 13:13:43 -0800121 """
122 self._host = host
Ilja H. Friedelc7bf3102014-05-13 17:31:25 -0700123 self._devserver = None
124 self._telemetry_path = None
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800125 self._telemetry_on_dut = telemetry_on_dut
Luis Lozano23ae3192013-11-08 16:22:46 -0800126 # TODO (llozano crbug.com/324964). Remove conditional code.
127 # Use a class hierarchy instead.
128 if local:
129 self._setup_local_telemetry()
130 else:
131 self._setup_devserver_telemetry()
132
133 logging.debug('Telemetry Path: %s', self._telemetry_path)
134
135
136 def _setup_devserver_telemetry(self):
137 """Setup Telemetry to use the devserver."""
138 logging.debug('Setting up telemetry for devserver testing')
Simran Basi833814b2013-01-29 13:13:43 -0800139 logging.debug('Grabbing build from AFE.')
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800140 info = self._host.host_info_store.get()
141 if not info.build:
Simran Basi833814b2013-01-29 13:13:43 -0800142 logging.error('Unable to locate build label for host: %s.',
Dean Liaoe3e75f62017-11-14 10:36:43 +0800143 self._host.host_port)
Simran Basi833814b2013-01-29 13:13:43 -0800144 raise error.AutotestError('Failed to grab build for host %s.' %
Dean Liaoe3e75f62017-11-14 10:36:43 +0800145 self._host.host_port)
Simran Basi833814b2013-01-29 13:13:43 -0800146
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800147 logging.debug('Setting up telemetry for build: %s', info.build)
Simran Basi833814b2013-01-29 13:13:43 -0800148
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800149 self._devserver = dev_server.ImageServer.resolve(
150 info.build, hostname=self._host.hostname)
151 self._devserver.stage_artifacts(info.build, ['autotest_packages'])
152 self._telemetry_path = self._devserver.setup_telemetry(build=info.build)
Luis Lozano23ae3192013-11-08 16:22:46 -0800153
154
155 def _setup_local_telemetry(self):
156 """Setup Telemetry to use local path to its sources.
157
158 First look for chrome source root, either externally mounted, or inside
159 the chroot. Prefer chrome-src-internal source tree to chrome-src.
160 """
161 TELEMETRY_DIR = 'src'
162 CHROME_LOCAL_SRC = '/var/cache/chromeos-cache/distfiles/target/'
Josh Triplett05208c92014-07-17 13:21:29 -0700163 CHROME_EXTERNAL_SRC = os.path.expanduser('~/chrome_root/')
Luis Lozano23ae3192013-11-08 16:22:46 -0800164
165 logging.debug('Setting up telemetry for local testing')
166
167 sources_list = ('chrome-src-internal', 'chrome-src')
Josh Triplett05208c92014-07-17 13:21:29 -0700168 dir_list = [CHROME_EXTERNAL_SRC]
Luis Lozano23ae3192013-11-08 16:22:46 -0800169 dir_list.extend(
170 [os.path.join(CHROME_LOCAL_SRC, x) for x in sources_list])
171 if 'CHROME_ROOT' in os.environ:
172 dir_list.insert(0, os.environ['CHROME_ROOT'])
173
174 telemetry_src = ''
175 for dir in dir_list:
176 if os.path.exists(dir):
177 telemetry_src = os.path.join(dir, TELEMETRY_DIR)
178 break
179 else:
180 raise error.TestError('Telemetry source directory not found.')
181
182 self._devserver = None
183 self._telemetry_path = telemetry_src
184
185
Luis Lozano814c7182015-09-08 11:20:47 -0700186 def _get_telemetry_cmd(self, script, test_or_benchmark, *args):
Luis Lozano23ae3192013-11-08 16:22:46 -0800187 """Build command to execute telemetry based on script and benchmark.
188
189 @param script: Telemetry script we want to run. For example:
190 [path_to_telemetry_src]/src/tools/telemetry/run_tests.
191 @param test_or_benchmark: Name of the test or benchmark we want to run,
192 with the page_set (if required) as part of
193 the string.
Luis Lozano814c7182015-09-08 11:20:47 -0700194 @param args: additional list of arguments to pass to the script.
195
Luis Lozano23ae3192013-11-08 16:22:46 -0800196 @returns Full telemetry command to execute the script.
197 """
198 telemetry_cmd = []
199 if self._devserver:
Allen Lia5cfb972016-12-27 17:17:22 -0800200 devserver_hostname = self._devserver.hostname
Luis Lozano23ae3192013-11-08 16:22:46 -0800201 telemetry_cmd.extend(['ssh', devserver_hostname])
202
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800203 if self._telemetry_on_dut:
204 telemetry_cmd.extend(
Dean Liaoe3e75f62017-11-14 10:36:43 +0800205 [self._host.ssh_command(alive_interval=900,
206 connection_attempts=4),
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800207 'python',
208 script,
209 '--verbose',
210 '--output-format=chartjson',
211 '--output-dir=%s' % DUT_CHROME_ROOT,
212 '--browser=system'])
213 else:
214 telemetry_cmd.extend(
215 ['python',
216 script,
217 '--verbose',
218 '--browser=cros-chrome',
219 '--output-format=chartjson',
220 '--output-dir=%s' % self._telemetry_path,
Dean Liaoe3e75f62017-11-14 10:36:43 +0800221 '--remote=%s' % self._host.host_port])
Luis Lozano814c7182015-09-08 11:20:47 -0700222 telemetry_cmd.extend(args)
223 telemetry_cmd.append(test_or_benchmark)
224
Keith Haddow1e5c7012016-03-09 16:05:37 -0800225 return ' '.join(telemetry_cmd)
226
227
228 def _scp_telemetry_results_cmd(self, perf_results_dir):
229 """Build command to copy the telemetry results from the devserver.
230
231 @param perf_results_dir: directory path where test output is to be
232 collected.
233 @returns SCP command to copy the results json to the specified directory.
234 """
Dean Liaoe3e75f62017-11-14 10:36:43 +0800235 if not perf_results_dir:
236 return ''
237
238 scp_cmd = ['scp']
239 if self._telemetry_on_dut:
240 scp_cmd.append(self._host.make_ssh_options(alive_interval=900,
241 connection_attempts=4))
242 if not self._host.is_default_port:
243 scp_cmd.append('-P %d' % self._host.port)
244 src = 'root@%s:%s/results-chart.json' % (self._host.hostname,
245 DUT_CHROME_ROOT)
246 else:
247 devserver_hostname = ''
Ricky Liangd186f3e2016-03-15 16:50:55 +0800248 if self._devserver:
Allen Lia5cfb972016-12-27 17:17:22 -0800249 devserver_hostname = self._devserver.hostname + ':'
Dean Liaoe3e75f62017-11-14 10:36:43 +0800250 src = '%s%s/results-chart.json' % (devserver_hostname,
251 self._telemetry_path)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800252
Dean Liaoe3e75f62017-11-14 10:36:43 +0800253 scp_cmd.extend([src, perf_results_dir])
Keith Haddow1e5c7012016-03-09 16:05:37 -0800254 return ' '.join(scp_cmd)
255
256
257 def _run_cmd(self, cmd):
258 """Execute an command in a external shell and capture the output.
259
260 @param cmd: String of is a valid shell command.
261
262 @returns The standard out, standard error and the integer exit code of
263 the executed command.
264 """
265 logging.debug('Running: %s', cmd)
266
267 output = StringIO.StringIO()
268 error_output = StringIO.StringIO()
269 exit_code = 0
270 try:
271 result = utils.run(cmd, stdout_tee=output,
272 stderr_tee=error_output,
273 timeout=TELEMETRY_TIMEOUT_MINS*60)
274 exit_code = result.exit_status
275 except error.CmdError as e:
276 logging.debug('Error occurred executing.')
277 exit_code = e.result_obj.exit_status
278
279 stdout = output.getvalue()
280 stderr = error_output.getvalue()
281 logging.debug('Completed with exit code: %d.\nstdout:%s\n'
282 'stderr:%s', exit_code, stdout, stderr)
283 return stdout, stderr, exit_code
Simran Basi833814b2013-01-29 13:13:43 -0800284
285
Luis Lozano814c7182015-09-08 11:20:47 -0700286 def _run_telemetry(self, script, test_or_benchmark, *args):
Simran Basi833814b2013-01-29 13:13:43 -0800287 """Runs telemetry on a dut.
288
289 @param script: Telemetry script we want to run. For example:
Luis Lozano23ae3192013-11-08 16:22:46 -0800290 [path_to_telemetry_src]/src/tools/telemetry/run_tests.
Simran Basi833814b2013-01-29 13:13:43 -0800291 @param test_or_benchmark: Name of the test or benchmark we want to run,
292 with the page_set (if required) as part of the
293 string.
Luis Lozano814c7182015-09-08 11:20:47 -0700294 @param args: additional list of arguments to pass to the script.
Simran Basi833814b2013-01-29 13:13:43 -0800295
296 @returns A TelemetryResult Instance with the results of this telemetry
297 execution.
298 """
Simran Basi1dbfc132013-05-02 10:11:02 -0700299 # TODO (sbasi crbug.com/239933) add support for incognito mode.
Simran Basi833814b2013-01-29 13:13:43 -0800300
Luis Lozano814c7182015-09-08 11:20:47 -0700301 telemetry_cmd = self._get_telemetry_cmd(script,
302 test_or_benchmark,
303 *args)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800304 logging.debug('Running Telemetry: %s', telemetry_cmd)
Luis Lozano23ae3192013-11-08 16:22:46 -0800305
Keith Haddow1e5c7012016-03-09 16:05:37 -0800306 stdout, stderr, exit_code = self._run_cmd(telemetry_cmd)
Simran Basi833814b2013-01-29 13:13:43 -0800307
308 return TelemetryResult(exit_code=exit_code, stdout=stdout,
309 stderr=stderr)
310
311
Keith Haddow1e5c7012016-03-09 16:05:37 -0800312 def _run_scp(self, perf_results_dir):
313 """Runs telemetry on a dut.
314
315 @param perf_results_dir: The local directory that results are being
316 collected.
317 """
318 scp_cmd = self._scp_telemetry_results_cmd(perf_results_dir)
319 logging.debug('Retrieving Results: %s', scp_cmd)
Dean Liaoe4773c72017-11-09 16:15:38 +0800320 _, _, exit_code = self._run_cmd(scp_cmd)
321 if exit_code != 0:
322 raise error.TestFail('Unable to retrieve results.')
Keith Haddow1e5c7012016-03-09 16:05:37 -0800323
324
Luis Lozano814c7182015-09-08 11:20:47 -0700325 def _run_test(self, script, test, *args):
Simran Basi1dbfc132013-05-02 10:11:02 -0700326 """Runs a telemetry test on a dut.
327
328 @param script: Which telemetry test script we want to run. Can be
329 telemetry's base test script or the Chrome OS specific
330 test script.
331 @param test: Telemetry test we want to run.
Luis Lozano814c7182015-09-08 11:20:47 -0700332 @param args: additional list of arguments to pass to the script.
Simran Basi1dbfc132013-05-02 10:11:02 -0700333
334 @returns A TelemetryResult Instance with the results of this telemetry
335 execution.
336 """
337 logging.debug('Running telemetry test: %s', test)
338 telemetry_script = os.path.join(self._telemetry_path, script)
Luis Lozano814c7182015-09-08 11:20:47 -0700339 result = self._run_telemetry(telemetry_script, test, *args)
Simran Basi1dbfc132013-05-02 10:11:02 -0700340 if result.status is FAILED_STATUS:
Ilja H. Friedelc7bf3102014-05-13 17:31:25 -0700341 raise error.TestFail('Telemetry test %s failed.' % test)
Simran Basi1dbfc132013-05-02 10:11:02 -0700342 return result
343
344
Luis Lozano814c7182015-09-08 11:20:47 -0700345 def run_telemetry_test(self, test, *args):
Simran Basi833814b2013-01-29 13:13:43 -0800346 """Runs a telemetry test on a dut.
347
348 @param test: Telemetry test we want to run.
Luis Lozano814c7182015-09-08 11:20:47 -0700349 @param args: additional list of arguments to pass to the telemetry
350 execution script.
Simran Basi833814b2013-01-29 13:13:43 -0800351
352 @returns A TelemetryResult Instance with the results of this telemetry
353 execution.
354 """
Luis Lozano814c7182015-09-08 11:20:47 -0700355 return self._run_test(TELEMETRY_RUN_TESTS_SCRIPT, test, *args)
Simran Basi1dbfc132013-05-02 10:11:02 -0700356
357
Luis Lozano814c7182015-09-08 11:20:47 -0700358 def run_telemetry_benchmark(self, benchmark, perf_value_writer=None,
359 *args):
Simran Basi833814b2013-01-29 13:13:43 -0800360 """Runs a telemetry benchmark on a dut.
361
362 @param benchmark: Benchmark we want to run.
Fang Denge689e712013-11-13 18:27:06 -0800363 @param perf_value_writer: Should be an instance with the function
364 output_perf_value(), if None, no perf value
365 will be written. Typically this will be the
366 job object from an autotest test.
Luis Lozano814c7182015-09-08 11:20:47 -0700367 @param args: additional list of arguments to pass to the telemetry
368 execution script.
Simran Basi833814b2013-01-29 13:13:43 -0800369
370 @returns A TelemetryResult Instance with the results of this telemetry
371 execution.
372 """
Dave Tu6a404e62013-11-05 15:54:48 -0800373 logging.debug('Running telemetry benchmark: %s', benchmark)
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800374
375 if benchmark not in ON_DUT_WHITE_LIST:
376 self._telemetry_on_dut = False
377
378 if self._telemetry_on_dut:
379 telemetry_script = os.path.join(DUT_CHROME_ROOT,
380 TELEMETRY_RUN_BENCHMARKS_SCRIPT)
381 self._ensure_deps(self._host, benchmark)
382 else:
383 telemetry_script = os.path.join(self._telemetry_path,
384 TELEMETRY_RUN_BENCHMARKS_SCRIPT)
385
Luis Lozano814c7182015-09-08 11:20:47 -0700386 result = self._run_telemetry(telemetry_script, benchmark, *args)
Simran Basi833814b2013-01-29 13:13:43 -0800387
388 if result.status is WARNING_STATUS:
Dave Tu6a404e62013-11-05 15:54:48 -0800389 raise error.TestWarn('Telemetry Benchmark: %s'
390 ' exited with Warnings.' % benchmark)
Simran Basi833814b2013-01-29 13:13:43 -0800391 if result.status is FAILED_STATUS:
Dave Tu6a404e62013-11-05 15:54:48 -0800392 raise error.TestFail('Telemetry Benchmark: %s'
393 ' failed to run.' % benchmark)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800394 if perf_value_writer:
395 self._run_scp(perf_value_writer.resultsdir)
Simran Basi833814b2013-01-29 13:13:43 -0800396 return result
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800397
Gurchetan Singhfaf75e92017-04-17 18:09:44 -0700398
399 def run_gpu_integration_test(self, test, *args):
400 """Runs a gpu test on a dut.
401
402 @param test: Gpu test we want to run.
403 @param args: additional list of arguments to pass to the telemetry
404 execution script.
405
406 @returns A TelemetryResult instance with the results of this telemetry
407 execution.
408 """
409 script = os.path.join(DUT_CHROME_ROOT,
410 TELEMETRY_RUN_GPU_TESTS_SCRIPT)
411 cmd = []
412 if self._devserver:
413 devserver_hostname = self._devserver.hostname
414 cmd.extend(['ssh', devserver_hostname])
415
416 cmd.extend(
Dean Liaoe3e75f62017-11-14 10:36:43 +0800417 [self._host.ssh_command(alive_interval=900, connection_attempts=4),
418 'python', script])
Gurchetan Singhfaf75e92017-04-17 18:09:44 -0700419 cmd.extend(args)
420 cmd.append(test)
421 cmd = ' '.join(cmd)
422 stdout, stderr, exit_code = self._run_cmd(cmd)
423
424 return TelemetryResult(exit_code=exit_code, stdout=stdout,
425 stderr=stderr)
426
427
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800428 def _ensure_deps(self, dut, test_name):
429 """
430 Ensure the dependencies are locally available on DUT.
431
432 @param dut: The autotest host object representing DUT.
433 @param test_name: Name of the telemetry test.
434 """
435 # Get DEPs using host's telemetry.
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800436 # Example output, fetch_benchmark_deps.py --output-deps=deps octane:
437 # {'octane': ['tools/perf/page_sets/data/octane_002.wprgo']}
438 perf_path = os.path.join(self._telemetry_path, 'tools', 'perf')
439 deps_path = os.path.join(perf_path, 'fetch_benchmark_deps_result.json')
440 fetch_path = os.path.join(perf_path, 'fetch_benchmark_deps.py')
441 format_fetch = ('python %s --output-deps=%s %s')
442 command_fetch = format_fetch % (fetch_path, deps_path, test_name)
443 command_get = 'cat %s' % deps_path
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800444
445 if self._devserver:
446 devserver_hostname = self._devserver.url().split(
447 'http://')[1].split(':')[0]
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800448 command_fetch = 'ssh %s %s' % (devserver_hostname, command_fetch)
449 command_get = 'ssh %s %s' % (devserver_hostname, command_get)
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800450
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800451 logging.info('Getting DEPs: %s', command_fetch)
452 _, _, exit_code = self._run_cmd(command_fetch)
453 if exit_code != 0:
454 raise error.TestFail('Error occurred while fetching DEPs.')
455 stdout, _, exit_code = self._run_cmd(command_get)
456 if exit_code != 0:
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800457 raise error.TestFail('Error occurred while getting DEPs.')
458
459 # Download DEPs to DUT.
460 # send_file() relies on rsync over ssh. Couldn't be better.
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800461 deps = json.loads(stdout)
462 for dep in deps[test_name]:
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800463 src = os.path.join(self._telemetry_path, dep)
464 dst = os.path.join(DUT_CHROME_ROOT, dep)
Ting-Yuan Huang8a2c7f72016-03-28 22:01:07 +0800465 if self._devserver:
466 logging.info('Copying: %s -> %s', src, dst)
Chung-yih Wangfd8eb242017-12-09 19:23:04 +0800467 rsync_cmd = utils.sh_escape('rsync %s %s %s:%s' %
468 (self._host.rsync_options(), src,
469 self._host.hostname, dst))
470 utils.run('ssh %s "%s"' % (devserver_hostname, rsync_cmd))
Ting-Yuan Huang8a2c7f72016-03-28 22:01:07 +0800471 else:
472 if not os.path.isfile(src):
473 raise error.TestFail('Error occurred while saving DEPs.')
474 logging.info('Copying: %s -> %s', src, dst)
475 dut.send_file(src, dst)