blob: 7c8834e9b8ca9375f85073907063c23adef30cc2 [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',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080048 'sunspider',
49 'tab_switching.top_10',
Chung-yih Wang80ba5812017-01-20 17:22:11 +080050 'tab_switching.typical_25',
Patrik Höglund2ef2e172016-11-16 10:07:29 +010051 'webrtc.peerconnection',
52 'webrtc.stress']
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080053
54# BLACK LIST
55# 'session_restore.cold.typical_25', # profile generator not implemented on
56 # CrOS.
Simran Basi833814b2013-01-29 13:13:43 -080057
58class TelemetryResult(object):
59 """Class to represent the results of a telemetry run.
60
61 This class represents the results of a telemetry run, whether it ran
62 successful, failed or had warnings.
63 """
64
65
66 def __init__(self, exit_code=0, stdout='', stderr=''):
67 """Initializes this TelemetryResultObject instance.
68
69 @param status: Status of the telemtry run.
70 @param stdout: Stdout of the telemetry run.
71 @param stderr: Stderr of the telemetry run.
72 """
73 if exit_code == 0:
74 self.status = SUCCESS_STATUS
75 else:
76 self.status = FAILED_STATUS
77
Simran Basi833814b2013-01-29 13:13:43 -080078 self._stdout = stdout
79 self._stderr = stderr
80 self.output = '\n'.join([stdout, stderr])
81
82
Simran Basi833814b2013-01-29 13:13:43 -080083class TelemetryRunner(object):
84 """Class responsible for telemetry for a given build.
85
86 This class will extract and install telemetry on the devserver and is
87 responsible for executing the telemetry benchmarks and returning their
88 output to the caller.
89 """
90
Ting-Yuan Huang85dcde82016-04-08 17:41:32 +080091 def __init__(self, host, local=False, telemetry_on_dut=True):
Simran Basi833814b2013-01-29 13:13:43 -080092 """Initializes this telemetry runner instance.
93
94 If telemetry is not installed for this build, it will be.
Luis Lozano23ae3192013-11-08 16:22:46 -080095
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080096 Basically, the following commands on the local pc on which test_that
97 will be executed, depending on the 4 possible combinations of
98 local x telemetry_on_dut:
99
100 local=True, telemetry_on_dut=False:
101 run_benchmark --browser=cros-chrome --remote=[dut] [test]
102
103 local=True, telemetry_on_dut=True:
104 ssh [dut] run_benchmark --browser=system [test]
105
106 local=False, telemetry_on_dut=False:
107 ssh [devserver] run_benchmark --browser=cros-chrome --remote=[dut] [test]
108
109 local=False, telemetry_on_dut=True:
110 ssh [devserver] ssh [dut] run_benchmark --browser=system [test]
111
Luis Lozano23ae3192013-11-08 16:22:46 -0800112 @param host: Host where the test will be run.
113 @param local: If set, no devserver will be used, test will be run
114 locally.
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800115 If not set, "ssh [devserver] " will be appended to test
116 commands.
117 @param telemetry_on_dut: If set, telemetry itself (the test harness)
118 will run on dut.
119 It decides browser=[system|cros-chrome]
Simran Basi833814b2013-01-29 13:13:43 -0800120 """
121 self._host = host
Ilja H. Friedelc7bf3102014-05-13 17:31:25 -0700122 self._devserver = None
123 self._telemetry_path = None
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800124 self._telemetry_on_dut = telemetry_on_dut
Luis Lozano23ae3192013-11-08 16:22:46 -0800125 # TODO (llozano crbug.com/324964). Remove conditional code.
126 # Use a class hierarchy instead.
127 if local:
128 self._setup_local_telemetry()
129 else:
130 self._setup_devserver_telemetry()
131
132 logging.debug('Telemetry Path: %s', self._telemetry_path)
133
134
135 def _setup_devserver_telemetry(self):
136 """Setup Telemetry to use the devserver."""
137 logging.debug('Setting up telemetry for devserver testing')
Simran Basi833814b2013-01-29 13:13:43 -0800138 logging.debug('Grabbing build from AFE.')
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800139 info = self._host.host_info_store.get()
140 if not info.build:
Simran Basi833814b2013-01-29 13:13:43 -0800141 logging.error('Unable to locate build label for host: %s.',
Dean Liaoe3e75f62017-11-14 10:36:43 +0800142 self._host.host_port)
Simran Basi833814b2013-01-29 13:13:43 -0800143 raise error.AutotestError('Failed to grab build for host %s.' %
Dean Liaoe3e75f62017-11-14 10:36:43 +0800144 self._host.host_port)
Simran Basi833814b2013-01-29 13:13:43 -0800145
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800146 logging.debug('Setting up telemetry for build: %s', info.build)
Simran Basi833814b2013-01-29 13:13:43 -0800147
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800148 self._devserver = dev_server.ImageServer.resolve(
149 info.build, hostname=self._host.hostname)
150 self._devserver.stage_artifacts(info.build, ['autotest_packages'])
151 self._telemetry_path = self._devserver.setup_telemetry(build=info.build)
Luis Lozano23ae3192013-11-08 16:22:46 -0800152
153
154 def _setup_local_telemetry(self):
155 """Setup Telemetry to use local path to its sources.
156
157 First look for chrome source root, either externally mounted, or inside
158 the chroot. Prefer chrome-src-internal source tree to chrome-src.
159 """
160 TELEMETRY_DIR = 'src'
161 CHROME_LOCAL_SRC = '/var/cache/chromeos-cache/distfiles/target/'
Josh Triplett05208c92014-07-17 13:21:29 -0700162 CHROME_EXTERNAL_SRC = os.path.expanduser('~/chrome_root/')
Luis Lozano23ae3192013-11-08 16:22:46 -0800163
164 logging.debug('Setting up telemetry for local testing')
165
166 sources_list = ('chrome-src-internal', 'chrome-src')
Josh Triplett05208c92014-07-17 13:21:29 -0700167 dir_list = [CHROME_EXTERNAL_SRC]
Luis Lozano23ae3192013-11-08 16:22:46 -0800168 dir_list.extend(
169 [os.path.join(CHROME_LOCAL_SRC, x) for x in sources_list])
170 if 'CHROME_ROOT' in os.environ:
171 dir_list.insert(0, os.environ['CHROME_ROOT'])
172
173 telemetry_src = ''
174 for dir in dir_list:
175 if os.path.exists(dir):
176 telemetry_src = os.path.join(dir, TELEMETRY_DIR)
177 break
178 else:
179 raise error.TestError('Telemetry source directory not found.')
180
181 self._devserver = None
182 self._telemetry_path = telemetry_src
183
184
Luis Lozano814c7182015-09-08 11:20:47 -0700185 def _get_telemetry_cmd(self, script, test_or_benchmark, *args):
Luis Lozano23ae3192013-11-08 16:22:46 -0800186 """Build command to execute telemetry based on script and benchmark.
187
188 @param script: Telemetry script we want to run. For example:
189 [path_to_telemetry_src]/src/tools/telemetry/run_tests.
190 @param test_or_benchmark: Name of the test or benchmark we want to run,
191 with the page_set (if required) as part of
192 the string.
Luis Lozano814c7182015-09-08 11:20:47 -0700193 @param args: additional list of arguments to pass to the script.
194
Luis Lozano23ae3192013-11-08 16:22:46 -0800195 @returns Full telemetry command to execute the script.
196 """
197 telemetry_cmd = []
198 if self._devserver:
Allen Lia5cfb972016-12-27 17:17:22 -0800199 devserver_hostname = self._devserver.hostname
Luis Lozano23ae3192013-11-08 16:22:46 -0800200 telemetry_cmd.extend(['ssh', devserver_hostname])
201
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800202 if self._telemetry_on_dut:
203 telemetry_cmd.extend(
Dean Liaoe3e75f62017-11-14 10:36:43 +0800204 [self._host.ssh_command(alive_interval=900,
205 connection_attempts=4),
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800206 'python',
207 script,
208 '--verbose',
209 '--output-format=chartjson',
210 '--output-dir=%s' % DUT_CHROME_ROOT,
211 '--browser=system'])
212 else:
213 telemetry_cmd.extend(
214 ['python',
215 script,
216 '--verbose',
217 '--browser=cros-chrome',
218 '--output-format=chartjson',
219 '--output-dir=%s' % self._telemetry_path,
Dean Liaoe3e75f62017-11-14 10:36:43 +0800220 '--remote=%s' % self._host.host_port])
Luis Lozano814c7182015-09-08 11:20:47 -0700221 telemetry_cmd.extend(args)
222 telemetry_cmd.append(test_or_benchmark)
223
Keith Haddow1e5c7012016-03-09 16:05:37 -0800224 return ' '.join(telemetry_cmd)
225
226
227 def _scp_telemetry_results_cmd(self, perf_results_dir):
228 """Build command to copy the telemetry results from the devserver.
229
230 @param perf_results_dir: directory path where test output is to be
231 collected.
232 @returns SCP command to copy the results json to the specified directory.
233 """
Dean Liaoe3e75f62017-11-14 10:36:43 +0800234 if not perf_results_dir:
235 return ''
236
237 scp_cmd = ['scp']
238 if self._telemetry_on_dut:
239 scp_cmd.append(self._host.make_ssh_options(alive_interval=900,
240 connection_attempts=4))
241 if not self._host.is_default_port:
242 scp_cmd.append('-P %d' % self._host.port)
243 src = 'root@%s:%s/results-chart.json' % (self._host.hostname,
244 DUT_CHROME_ROOT)
245 else:
246 devserver_hostname = ''
Ricky Liangd186f3e2016-03-15 16:50:55 +0800247 if self._devserver:
Allen Lia5cfb972016-12-27 17:17:22 -0800248 devserver_hostname = self._devserver.hostname + ':'
Dean Liaoe3e75f62017-11-14 10:36:43 +0800249 src = '%s%s/results-chart.json' % (devserver_hostname,
250 self._telemetry_path)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800251
Dean Liaoe3e75f62017-11-14 10:36:43 +0800252 scp_cmd.extend([src, perf_results_dir])
Keith Haddow1e5c7012016-03-09 16:05:37 -0800253 return ' '.join(scp_cmd)
254
255
256 def _run_cmd(self, cmd):
257 """Execute an command in a external shell and capture the output.
258
259 @param cmd: String of is a valid shell command.
260
261 @returns The standard out, standard error and the integer exit code of
262 the executed command.
263 """
264 logging.debug('Running: %s', cmd)
265
266 output = StringIO.StringIO()
267 error_output = StringIO.StringIO()
268 exit_code = 0
269 try:
270 result = utils.run(cmd, stdout_tee=output,
271 stderr_tee=error_output,
272 timeout=TELEMETRY_TIMEOUT_MINS*60)
273 exit_code = result.exit_status
274 except error.CmdError as e:
275 logging.debug('Error occurred executing.')
276 exit_code = e.result_obj.exit_status
277
278 stdout = output.getvalue()
279 stderr = error_output.getvalue()
280 logging.debug('Completed with exit code: %d.\nstdout:%s\n'
281 'stderr:%s', exit_code, stdout, stderr)
282 return stdout, stderr, exit_code
Simran Basi833814b2013-01-29 13:13:43 -0800283
284
Luis Lozano814c7182015-09-08 11:20:47 -0700285 def _run_telemetry(self, script, test_or_benchmark, *args):
Simran Basi833814b2013-01-29 13:13:43 -0800286 """Runs telemetry on a dut.
287
288 @param script: Telemetry script we want to run. For example:
Luis Lozano23ae3192013-11-08 16:22:46 -0800289 [path_to_telemetry_src]/src/tools/telemetry/run_tests.
Simran Basi833814b2013-01-29 13:13:43 -0800290 @param test_or_benchmark: Name of the test or benchmark we want to run,
291 with the page_set (if required) as part of the
292 string.
Luis Lozano814c7182015-09-08 11:20:47 -0700293 @param args: additional list of arguments to pass to the script.
Simran Basi833814b2013-01-29 13:13:43 -0800294
295 @returns A TelemetryResult Instance with the results of this telemetry
296 execution.
297 """
Simran Basi1dbfc132013-05-02 10:11:02 -0700298 # TODO (sbasi crbug.com/239933) add support for incognito mode.
Simran Basi833814b2013-01-29 13:13:43 -0800299
Luis Lozano814c7182015-09-08 11:20:47 -0700300 telemetry_cmd = self._get_telemetry_cmd(script,
301 test_or_benchmark,
302 *args)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800303 logging.debug('Running Telemetry: %s', telemetry_cmd)
Luis Lozano23ae3192013-11-08 16:22:46 -0800304
Keith Haddow1e5c7012016-03-09 16:05:37 -0800305 stdout, stderr, exit_code = self._run_cmd(telemetry_cmd)
Simran Basi833814b2013-01-29 13:13:43 -0800306
307 return TelemetryResult(exit_code=exit_code, stdout=stdout,
308 stderr=stderr)
309
310
Keith Haddow1e5c7012016-03-09 16:05:37 -0800311 def _run_scp(self, perf_results_dir):
312 """Runs telemetry on a dut.
313
314 @param perf_results_dir: The local directory that results are being
315 collected.
316 """
317 scp_cmd = self._scp_telemetry_results_cmd(perf_results_dir)
318 logging.debug('Retrieving Results: %s', scp_cmd)
Dean Liaoe4773c72017-11-09 16:15:38 +0800319 _, _, exit_code = self._run_cmd(scp_cmd)
320 if exit_code != 0:
321 raise error.TestFail('Unable to retrieve results.')
Keith Haddow1e5c7012016-03-09 16:05:37 -0800322
323
Luis Lozano814c7182015-09-08 11:20:47 -0700324 def _run_test(self, script, test, *args):
Simran Basi1dbfc132013-05-02 10:11:02 -0700325 """Runs a telemetry test on a dut.
326
327 @param script: Which telemetry test script we want to run. Can be
328 telemetry's base test script or the Chrome OS specific
329 test script.
330 @param test: Telemetry test we want to run.
Luis Lozano814c7182015-09-08 11:20:47 -0700331 @param args: additional list of arguments to pass to the script.
Simran Basi1dbfc132013-05-02 10:11:02 -0700332
333 @returns A TelemetryResult Instance with the results of this telemetry
334 execution.
335 """
336 logging.debug('Running telemetry test: %s', test)
337 telemetry_script = os.path.join(self._telemetry_path, script)
Luis Lozano814c7182015-09-08 11:20:47 -0700338 result = self._run_telemetry(telemetry_script, test, *args)
Simran Basi1dbfc132013-05-02 10:11:02 -0700339 if result.status is FAILED_STATUS:
Ilja H. Friedelc7bf3102014-05-13 17:31:25 -0700340 raise error.TestFail('Telemetry test %s failed.' % test)
Simran Basi1dbfc132013-05-02 10:11:02 -0700341 return result
342
343
Luis Lozano814c7182015-09-08 11:20:47 -0700344 def run_telemetry_test(self, test, *args):
Simran Basi833814b2013-01-29 13:13:43 -0800345 """Runs a telemetry test on a dut.
346
347 @param test: Telemetry test we want to run.
Luis Lozano814c7182015-09-08 11:20:47 -0700348 @param args: additional list of arguments to pass to the telemetry
349 execution script.
Simran Basi833814b2013-01-29 13:13:43 -0800350
351 @returns A TelemetryResult Instance with the results of this telemetry
352 execution.
353 """
Luis Lozano814c7182015-09-08 11:20:47 -0700354 return self._run_test(TELEMETRY_RUN_TESTS_SCRIPT, test, *args)
Simran Basi1dbfc132013-05-02 10:11:02 -0700355
356
Luis Lozano814c7182015-09-08 11:20:47 -0700357 def run_telemetry_benchmark(self, benchmark, perf_value_writer=None,
358 *args):
Simran Basi833814b2013-01-29 13:13:43 -0800359 """Runs a telemetry benchmark on a dut.
360
361 @param benchmark: Benchmark we want to run.
Fang Denge689e712013-11-13 18:27:06 -0800362 @param perf_value_writer: Should be an instance with the function
363 output_perf_value(), if None, no perf value
364 will be written. Typically this will be the
365 job object from an autotest test.
Luis Lozano814c7182015-09-08 11:20:47 -0700366 @param args: additional list of arguments to pass to the telemetry
367 execution script.
Simran Basi833814b2013-01-29 13:13:43 -0800368
369 @returns A TelemetryResult Instance with the results of this telemetry
370 execution.
371 """
Dave Tu6a404e62013-11-05 15:54:48 -0800372 logging.debug('Running telemetry benchmark: %s', benchmark)
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800373
374 if benchmark not in ON_DUT_WHITE_LIST:
375 self._telemetry_on_dut = False
376
377 if self._telemetry_on_dut:
378 telemetry_script = os.path.join(DUT_CHROME_ROOT,
379 TELEMETRY_RUN_BENCHMARKS_SCRIPT)
380 self._ensure_deps(self._host, benchmark)
381 else:
382 telemetry_script = os.path.join(self._telemetry_path,
383 TELEMETRY_RUN_BENCHMARKS_SCRIPT)
384
Luis Lozano814c7182015-09-08 11:20:47 -0700385 result = self._run_telemetry(telemetry_script, benchmark, *args)
Simran Basi833814b2013-01-29 13:13:43 -0800386
387 if result.status is WARNING_STATUS:
Dave Tu6a404e62013-11-05 15:54:48 -0800388 raise error.TestWarn('Telemetry Benchmark: %s'
389 ' exited with Warnings.' % benchmark)
Simran Basi833814b2013-01-29 13:13:43 -0800390 if result.status is FAILED_STATUS:
Dave Tu6a404e62013-11-05 15:54:48 -0800391 raise error.TestFail('Telemetry Benchmark: %s'
392 ' failed to run.' % benchmark)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800393 if perf_value_writer:
394 self._run_scp(perf_value_writer.resultsdir)
Simran Basi833814b2013-01-29 13:13:43 -0800395 return result
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800396
Gurchetan Singhfaf75e92017-04-17 18:09:44 -0700397
398 def run_gpu_integration_test(self, test, *args):
399 """Runs a gpu test on a dut.
400
401 @param test: Gpu test we want to run.
402 @param args: additional list of arguments to pass to the telemetry
403 execution script.
404
405 @returns A TelemetryResult instance with the results of this telemetry
406 execution.
407 """
408 script = os.path.join(DUT_CHROME_ROOT,
409 TELEMETRY_RUN_GPU_TESTS_SCRIPT)
410 cmd = []
411 if self._devserver:
412 devserver_hostname = self._devserver.hostname
413 cmd.extend(['ssh', devserver_hostname])
414
415 cmd.extend(
Dean Liaoe3e75f62017-11-14 10:36:43 +0800416 [self._host.ssh_command(alive_interval=900, connection_attempts=4),
417 'python', script])
Gurchetan Singhfaf75e92017-04-17 18:09:44 -0700418 cmd.extend(args)
419 cmd.append(test)
420 cmd = ' '.join(cmd)
421 stdout, stderr, exit_code = self._run_cmd(cmd)
422
423 return TelemetryResult(exit_code=exit_code, stdout=stdout,
424 stderr=stderr)
425
426
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800427 def _ensure_deps(self, dut, test_name):
428 """
429 Ensure the dependencies are locally available on DUT.
430
431 @param dut: The autotest host object representing DUT.
432 @param test_name: Name of the telemetry test.
433 """
434 # Get DEPs using host's telemetry.
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800435 # Example output, fetch_benchmark_deps.py --output-deps=deps octane:
436 # {'octane': ['tools/perf/page_sets/data/octane_002.wprgo']}
437 perf_path = os.path.join(self._telemetry_path, 'tools', 'perf')
438 deps_path = os.path.join(perf_path, 'fetch_benchmark_deps_result.json')
439 fetch_path = os.path.join(perf_path, 'fetch_benchmark_deps.py')
440 format_fetch = ('python %s --output-deps=%s %s')
441 command_fetch = format_fetch % (fetch_path, deps_path, test_name)
442 command_get = 'cat %s' % deps_path
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800443
444 if self._devserver:
445 devserver_hostname = self._devserver.url().split(
446 'http://')[1].split(':')[0]
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800447 command_fetch = 'ssh %s %s' % (devserver_hostname, command_fetch)
448 command_get = 'ssh %s %s' % (devserver_hostname, command_get)
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800449
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800450 logging.info('Getting DEPs: %s', command_fetch)
451 _, _, exit_code = self._run_cmd(command_fetch)
452 if exit_code != 0:
453 raise error.TestFail('Error occurred while fetching DEPs.')
454 stdout, _, exit_code = self._run_cmd(command_get)
455 if exit_code != 0:
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800456 raise error.TestFail('Error occurred while getting DEPs.')
457
458 # Download DEPs to DUT.
459 # send_file() relies on rsync over ssh. Couldn't be better.
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800460 deps = json.loads(stdout)
461 for dep in deps[test_name]:
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800462 src = os.path.join(self._telemetry_path, dep)
463 dst = os.path.join(DUT_CHROME_ROOT, dep)
Ting-Yuan Huang8a2c7f72016-03-28 22:01:07 +0800464 if self._devserver:
465 logging.info('Copying: %s -> %s', src, dst)
Chung-yih Wangfd8eb242017-12-09 19:23:04 +0800466 rsync_cmd = utils.sh_escape('rsync %s %s %s:%s' %
467 (self._host.rsync_options(), src,
468 self._host.hostname, dst))
469 utils.run('ssh %s "%s"' % (devserver_hostname, rsync_cmd))
Ting-Yuan Huang8a2c7f72016-03-28 22:01:07 +0800470 else:
471 if not os.path.isfile(src):
472 raise error.TestFail('Error occurred while saving DEPs.')
473 logging.info('Copying: %s -> %s', src, dst)
474 dut.send_file(src, dst)