blob: 93aa877424ec96165efd1c2ce67e3855796b4f09 [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.
Kuo-Hsin Yange0a2c062018-06-20 15:08:22 +080027ON_DUT_WHITE_LIST = ['cros_tab_switching.typical_24',
28 'cros_ui_smoothness',
Kuo-Hsin Yangc59ac8a2018-07-23 14:35:44 +080029 'dromaeo',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080030 'image_decoding.image_decoding_measurement',
31 'jetstream',
32 'kraken',
33 'memory.top_7_stress',
34 'octane',
35 'page_cycler.typical_25',
Chung-yih Wang80ba5812017-01-20 17:22:11 +080036 'page_cycler_v2.typical_25',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080037 'robohornet_pro',
Chung-yih Wang46672322018-03-30 16:28:57 +080038 'smoothness.top_25_smooth',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080039 'smoothness.tough_animation_cases',
40 'smoothness.tough_canvas_cases',
41 'smoothness.tough_filters_cases',
42 'smoothness.tough_pinch_zoom_cases',
43 'smoothness.tough_scrolling_cases',
44 'smoothness.tough_webgl_cases',
45 'speedometer',
Hsu-Cheng Tsaied1d6b32018-05-17 17:28:28 +080046 'speedometer2',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080047 'sunspider',
48 'tab_switching.top_10',
Chung-yih Wang80ba5812017-01-20 17:22:11 +080049 'tab_switching.typical_25',
Patrik Höglund2ef2e172016-11-16 10:07:29 +010050 'webrtc.peerconnection',
51 'webrtc.stress']
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080052
53# BLACK LIST
54# 'session_restore.cold.typical_25', # profile generator not implemented on
55 # CrOS.
Simran Basi833814b2013-01-29 13:13:43 -080056
57class TelemetryResult(object):
58 """Class to represent the results of a telemetry run.
59
60 This class represents the results of a telemetry run, whether it ran
61 successful, failed or had warnings.
62 """
63
64
65 def __init__(self, exit_code=0, stdout='', stderr=''):
66 """Initializes this TelemetryResultObject instance.
67
68 @param status: Status of the telemtry run.
69 @param stdout: Stdout of the telemetry run.
70 @param stderr: Stderr of the telemetry run.
71 """
72 if exit_code == 0:
73 self.status = SUCCESS_STATUS
74 else:
75 self.status = FAILED_STATUS
76
Simran Basi833814b2013-01-29 13:13:43 -080077 self._stdout = stdout
78 self._stderr = stderr
79 self.output = '\n'.join([stdout, stderr])
80
81
Simran Basi833814b2013-01-29 13:13:43 -080082class TelemetryRunner(object):
83 """Class responsible for telemetry for a given build.
84
85 This class will extract and install telemetry on the devserver and is
86 responsible for executing the telemetry benchmarks and returning their
87 output to the caller.
88 """
89
Ting-Yuan Huang85dcde82016-04-08 17:41:32 +080090 def __init__(self, host, local=False, telemetry_on_dut=True):
Simran Basi833814b2013-01-29 13:13:43 -080091 """Initializes this telemetry runner instance.
92
93 If telemetry is not installed for this build, it will be.
Luis Lozano23ae3192013-11-08 16:22:46 -080094
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080095 Basically, the following commands on the local pc on which test_that
96 will be executed, depending on the 4 possible combinations of
97 local x telemetry_on_dut:
98
99 local=True, telemetry_on_dut=False:
100 run_benchmark --browser=cros-chrome --remote=[dut] [test]
101
102 local=True, telemetry_on_dut=True:
103 ssh [dut] run_benchmark --browser=system [test]
104
105 local=False, telemetry_on_dut=False:
106 ssh [devserver] run_benchmark --browser=cros-chrome --remote=[dut] [test]
107
108 local=False, telemetry_on_dut=True:
109 ssh [devserver] ssh [dut] run_benchmark --browser=system [test]
110
Luis Lozano23ae3192013-11-08 16:22:46 -0800111 @param host: Host where the test will be run.
112 @param local: If set, no devserver will be used, test will be run
113 locally.
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800114 If not set, "ssh [devserver] " will be appended to test
115 commands.
116 @param telemetry_on_dut: If set, telemetry itself (the test harness)
117 will run on dut.
118 It decides browser=[system|cros-chrome]
Simran Basi833814b2013-01-29 13:13:43 -0800119 """
120 self._host = host
Ilja H. Friedelc7bf3102014-05-13 17:31:25 -0700121 self._devserver = None
122 self._telemetry_path = None
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800123 self._telemetry_on_dut = telemetry_on_dut
Luis Lozano23ae3192013-11-08 16:22:46 -0800124 # TODO (llozano crbug.com/324964). Remove conditional code.
125 # Use a class hierarchy instead.
126 if local:
127 self._setup_local_telemetry()
128 else:
129 self._setup_devserver_telemetry()
130
131 logging.debug('Telemetry Path: %s', self._telemetry_path)
132
133
134 def _setup_devserver_telemetry(self):
135 """Setup Telemetry to use the devserver."""
136 logging.debug('Setting up telemetry for devserver testing')
Simran Basi833814b2013-01-29 13:13:43 -0800137 logging.debug('Grabbing build from AFE.')
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800138 info = self._host.host_info_store.get()
139 if not info.build:
Simran Basi833814b2013-01-29 13:13:43 -0800140 logging.error('Unable to locate build label for host: %s.',
Dean Liaoe3e75f62017-11-14 10:36:43 +0800141 self._host.host_port)
Simran Basi833814b2013-01-29 13:13:43 -0800142 raise error.AutotestError('Failed to grab build for host %s.' %
Dean Liaoe3e75f62017-11-14 10:36:43 +0800143 self._host.host_port)
Simran Basi833814b2013-01-29 13:13:43 -0800144
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800145 logging.debug('Setting up telemetry for build: %s', info.build)
Simran Basi833814b2013-01-29 13:13:43 -0800146
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800147 self._devserver = dev_server.ImageServer.resolve(
148 info.build, hostname=self._host.hostname)
149 self._devserver.stage_artifacts(info.build, ['autotest_packages'])
150 self._telemetry_path = self._devserver.setup_telemetry(build=info.build)
Luis Lozano23ae3192013-11-08 16:22:46 -0800151
152
153 def _setup_local_telemetry(self):
154 """Setup Telemetry to use local path to its sources.
155
156 First look for chrome source root, either externally mounted, or inside
157 the chroot. Prefer chrome-src-internal source tree to chrome-src.
158 """
159 TELEMETRY_DIR = 'src'
160 CHROME_LOCAL_SRC = '/var/cache/chromeos-cache/distfiles/target/'
Josh Triplett05208c92014-07-17 13:21:29 -0700161 CHROME_EXTERNAL_SRC = os.path.expanduser('~/chrome_root/')
Luis Lozano23ae3192013-11-08 16:22:46 -0800162
163 logging.debug('Setting up telemetry for local testing')
164
165 sources_list = ('chrome-src-internal', 'chrome-src')
Josh Triplett05208c92014-07-17 13:21:29 -0700166 dir_list = [CHROME_EXTERNAL_SRC]
Luis Lozano23ae3192013-11-08 16:22:46 -0800167 dir_list.extend(
168 [os.path.join(CHROME_LOCAL_SRC, x) for x in sources_list])
169 if 'CHROME_ROOT' in os.environ:
170 dir_list.insert(0, os.environ['CHROME_ROOT'])
171
172 telemetry_src = ''
173 for dir in dir_list:
174 if os.path.exists(dir):
175 telemetry_src = os.path.join(dir, TELEMETRY_DIR)
176 break
177 else:
178 raise error.TestError('Telemetry source directory not found.')
179
180 self._devserver = None
181 self._telemetry_path = telemetry_src
182
183
Luis Lozano814c7182015-09-08 11:20:47 -0700184 def _get_telemetry_cmd(self, script, test_or_benchmark, *args):
Luis Lozano23ae3192013-11-08 16:22:46 -0800185 """Build command to execute telemetry based on script and benchmark.
186
187 @param script: Telemetry script we want to run. For example:
188 [path_to_telemetry_src]/src/tools/telemetry/run_tests.
189 @param test_or_benchmark: Name of the test or benchmark we want to run,
190 with the page_set (if required) as part of
191 the string.
Luis Lozano814c7182015-09-08 11:20:47 -0700192 @param args: additional list of arguments to pass to the script.
193
Luis Lozano23ae3192013-11-08 16:22:46 -0800194 @returns Full telemetry command to execute the script.
195 """
196 telemetry_cmd = []
197 if self._devserver:
Allen Lia5cfb972016-12-27 17:17:22 -0800198 devserver_hostname = self._devserver.hostname
Luis Lozano23ae3192013-11-08 16:22:46 -0800199 telemetry_cmd.extend(['ssh', devserver_hostname])
200
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800201 if self._telemetry_on_dut:
202 telemetry_cmd.extend(
Dean Liaoe3e75f62017-11-14 10:36:43 +0800203 [self._host.ssh_command(alive_interval=900,
204 connection_attempts=4),
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800205 'python',
206 script,
207 '--verbose',
208 '--output-format=chartjson',
209 '--output-dir=%s' % DUT_CHROME_ROOT,
210 '--browser=system'])
211 else:
212 telemetry_cmd.extend(
213 ['python',
214 script,
215 '--verbose',
216 '--browser=cros-chrome',
217 '--output-format=chartjson',
218 '--output-dir=%s' % self._telemetry_path,
Dean Liaoe3e75f62017-11-14 10:36:43 +0800219 '--remote=%s' % self._host.host_port])
Luis Lozano814c7182015-09-08 11:20:47 -0700220 telemetry_cmd.extend(args)
221 telemetry_cmd.append(test_or_benchmark)
222
Keith Haddow1e5c7012016-03-09 16:05:37 -0800223 return ' '.join(telemetry_cmd)
224
225
226 def _scp_telemetry_results_cmd(self, perf_results_dir):
227 """Build command to copy the telemetry results from the devserver.
228
229 @param perf_results_dir: directory path where test output is to be
230 collected.
231 @returns SCP command to copy the results json to the specified directory.
232 """
Dean Liaoe3e75f62017-11-14 10:36:43 +0800233 if not perf_results_dir:
234 return ''
235
236 scp_cmd = ['scp']
237 if self._telemetry_on_dut:
238 scp_cmd.append(self._host.make_ssh_options(alive_interval=900,
239 connection_attempts=4))
240 if not self._host.is_default_port:
241 scp_cmd.append('-P %d' % self._host.port)
242 src = 'root@%s:%s/results-chart.json' % (self._host.hostname,
243 DUT_CHROME_ROOT)
244 else:
245 devserver_hostname = ''
Ricky Liangd186f3e2016-03-15 16:50:55 +0800246 if self._devserver:
Allen Lia5cfb972016-12-27 17:17:22 -0800247 devserver_hostname = self._devserver.hostname + ':'
Dean Liaoe3e75f62017-11-14 10:36:43 +0800248 src = '%s%s/results-chart.json' % (devserver_hostname,
249 self._telemetry_path)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800250
Dean Liaoe3e75f62017-11-14 10:36:43 +0800251 scp_cmd.extend([src, perf_results_dir])
Keith Haddow1e5c7012016-03-09 16:05:37 -0800252 return ' '.join(scp_cmd)
253
254
255 def _run_cmd(self, cmd):
256 """Execute an command in a external shell and capture the output.
257
258 @param cmd: String of is a valid shell command.
259
260 @returns The standard out, standard error and the integer exit code of
261 the executed command.
262 """
263 logging.debug('Running: %s', cmd)
264
265 output = StringIO.StringIO()
266 error_output = StringIO.StringIO()
267 exit_code = 0
268 try:
269 result = utils.run(cmd, stdout_tee=output,
270 stderr_tee=error_output,
271 timeout=TELEMETRY_TIMEOUT_MINS*60)
272 exit_code = result.exit_status
273 except error.CmdError as e:
274 logging.debug('Error occurred executing.')
275 exit_code = e.result_obj.exit_status
276
277 stdout = output.getvalue()
278 stderr = error_output.getvalue()
279 logging.debug('Completed with exit code: %d.\nstdout:%s\n'
280 'stderr:%s', exit_code, stdout, stderr)
281 return stdout, stderr, exit_code
Simran Basi833814b2013-01-29 13:13:43 -0800282
283
Luis Lozano814c7182015-09-08 11:20:47 -0700284 def _run_telemetry(self, script, test_or_benchmark, *args):
Simran Basi833814b2013-01-29 13:13:43 -0800285 """Runs telemetry on a dut.
286
287 @param script: Telemetry script we want to run. For example:
Luis Lozano23ae3192013-11-08 16:22:46 -0800288 [path_to_telemetry_src]/src/tools/telemetry/run_tests.
Simran Basi833814b2013-01-29 13:13:43 -0800289 @param test_or_benchmark: Name of the test or benchmark we want to run,
290 with the page_set (if required) as part of the
291 string.
Luis Lozano814c7182015-09-08 11:20:47 -0700292 @param args: additional list of arguments to pass to the script.
Simran Basi833814b2013-01-29 13:13:43 -0800293
294 @returns A TelemetryResult Instance with the results of this telemetry
295 execution.
296 """
Simran Basi1dbfc132013-05-02 10:11:02 -0700297 # TODO (sbasi crbug.com/239933) add support for incognito mode.
Simran Basi833814b2013-01-29 13:13:43 -0800298
Luis Lozano814c7182015-09-08 11:20:47 -0700299 telemetry_cmd = self._get_telemetry_cmd(script,
300 test_or_benchmark,
301 *args)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800302 logging.debug('Running Telemetry: %s', telemetry_cmd)
Luis Lozano23ae3192013-11-08 16:22:46 -0800303
Keith Haddow1e5c7012016-03-09 16:05:37 -0800304 stdout, stderr, exit_code = self._run_cmd(telemetry_cmd)
Simran Basi833814b2013-01-29 13:13:43 -0800305
306 return TelemetryResult(exit_code=exit_code, stdout=stdout,
307 stderr=stderr)
308
309
Keith Haddow1e5c7012016-03-09 16:05:37 -0800310 def _run_scp(self, perf_results_dir):
311 """Runs telemetry on a dut.
312
313 @param perf_results_dir: The local directory that results are being
314 collected.
315 """
316 scp_cmd = self._scp_telemetry_results_cmd(perf_results_dir)
317 logging.debug('Retrieving Results: %s', scp_cmd)
Dean Liaoe4773c72017-11-09 16:15:38 +0800318 _, _, exit_code = self._run_cmd(scp_cmd)
319 if exit_code != 0:
320 raise error.TestFail('Unable to retrieve results.')
Keith Haddow1e5c7012016-03-09 16:05:37 -0800321
322
Luis Lozano814c7182015-09-08 11:20:47 -0700323 def _run_test(self, script, test, *args):
Simran Basi1dbfc132013-05-02 10:11:02 -0700324 """Runs a telemetry test on a dut.
325
326 @param script: Which telemetry test script we want to run. Can be
327 telemetry's base test script or the Chrome OS specific
328 test script.
329 @param test: Telemetry test we want to run.
Luis Lozano814c7182015-09-08 11:20:47 -0700330 @param args: additional list of arguments to pass to the script.
Simran Basi1dbfc132013-05-02 10:11:02 -0700331
332 @returns A TelemetryResult Instance with the results of this telemetry
333 execution.
334 """
335 logging.debug('Running telemetry test: %s', test)
336 telemetry_script = os.path.join(self._telemetry_path, script)
Luis Lozano814c7182015-09-08 11:20:47 -0700337 result = self._run_telemetry(telemetry_script, test, *args)
Simran Basi1dbfc132013-05-02 10:11:02 -0700338 if result.status is FAILED_STATUS:
Ilja H. Friedelc7bf3102014-05-13 17:31:25 -0700339 raise error.TestFail('Telemetry test %s failed.' % test)
Simran Basi1dbfc132013-05-02 10:11:02 -0700340 return result
341
342
Luis Lozano814c7182015-09-08 11:20:47 -0700343 def run_telemetry_test(self, test, *args):
Simran Basi833814b2013-01-29 13:13:43 -0800344 """Runs a telemetry test on a dut.
345
346 @param test: Telemetry test we want to run.
Luis Lozano814c7182015-09-08 11:20:47 -0700347 @param args: additional list of arguments to pass to the telemetry
348 execution script.
Simran Basi833814b2013-01-29 13:13:43 -0800349
350 @returns A TelemetryResult Instance with the results of this telemetry
351 execution.
352 """
Luis Lozano814c7182015-09-08 11:20:47 -0700353 return self._run_test(TELEMETRY_RUN_TESTS_SCRIPT, test, *args)
Simran Basi1dbfc132013-05-02 10:11:02 -0700354
355
Luis Lozano814c7182015-09-08 11:20:47 -0700356 def run_telemetry_benchmark(self, benchmark, perf_value_writer=None,
357 *args):
Simran Basi833814b2013-01-29 13:13:43 -0800358 """Runs a telemetry benchmark on a dut.
359
360 @param benchmark: Benchmark we want to run.
Fang Denge689e712013-11-13 18:27:06 -0800361 @param perf_value_writer: Should be an instance with the function
362 output_perf_value(), if None, no perf value
363 will be written. Typically this will be the
364 job object from an autotest test.
Luis Lozano814c7182015-09-08 11:20:47 -0700365 @param args: additional list of arguments to pass to the telemetry
366 execution script.
Simran Basi833814b2013-01-29 13:13:43 -0800367
368 @returns A TelemetryResult Instance with the results of this telemetry
369 execution.
370 """
Dave Tu6a404e62013-11-05 15:54:48 -0800371 logging.debug('Running telemetry benchmark: %s', benchmark)
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800372
373 if benchmark not in ON_DUT_WHITE_LIST:
374 self._telemetry_on_dut = False
375
376 if self._telemetry_on_dut:
377 telemetry_script = os.path.join(DUT_CHROME_ROOT,
378 TELEMETRY_RUN_BENCHMARKS_SCRIPT)
379 self._ensure_deps(self._host, benchmark)
380 else:
381 telemetry_script = os.path.join(self._telemetry_path,
382 TELEMETRY_RUN_BENCHMARKS_SCRIPT)
383
Luis Lozano814c7182015-09-08 11:20:47 -0700384 result = self._run_telemetry(telemetry_script, benchmark, *args)
Simran Basi833814b2013-01-29 13:13:43 -0800385
386 if result.status is WARNING_STATUS:
Dave Tu6a404e62013-11-05 15:54:48 -0800387 raise error.TestWarn('Telemetry Benchmark: %s'
388 ' exited with Warnings.' % benchmark)
Simran Basi833814b2013-01-29 13:13:43 -0800389 if result.status is FAILED_STATUS:
Dave Tu6a404e62013-11-05 15:54:48 -0800390 raise error.TestFail('Telemetry Benchmark: %s'
391 ' failed to run.' % benchmark)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800392 if perf_value_writer:
393 self._run_scp(perf_value_writer.resultsdir)
Simran Basi833814b2013-01-29 13:13:43 -0800394 return result
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800395
Gurchetan Singhfaf75e92017-04-17 18:09:44 -0700396
397 def run_gpu_integration_test(self, test, *args):
398 """Runs a gpu test on a dut.
399
400 @param test: Gpu test we want to run.
401 @param args: additional list of arguments to pass to the telemetry
402 execution script.
403
404 @returns A TelemetryResult instance with the results of this telemetry
405 execution.
406 """
407 script = os.path.join(DUT_CHROME_ROOT,
408 TELEMETRY_RUN_GPU_TESTS_SCRIPT)
409 cmd = []
410 if self._devserver:
411 devserver_hostname = self._devserver.hostname
412 cmd.extend(['ssh', devserver_hostname])
413
414 cmd.extend(
Dean Liaoe3e75f62017-11-14 10:36:43 +0800415 [self._host.ssh_command(alive_interval=900, connection_attempts=4),
416 'python', script])
Gurchetan Singhfaf75e92017-04-17 18:09:44 -0700417 cmd.extend(args)
418 cmd.append(test)
419 cmd = ' '.join(cmd)
420 stdout, stderr, exit_code = self._run_cmd(cmd)
421
422 return TelemetryResult(exit_code=exit_code, stdout=stdout,
423 stderr=stderr)
424
425
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800426 def _ensure_deps(self, dut, test_name):
427 """
428 Ensure the dependencies are locally available on DUT.
429
430 @param dut: The autotest host object representing DUT.
431 @param test_name: Name of the telemetry test.
432 """
433 # Get DEPs using host's telemetry.
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800434 # Example output, fetch_benchmark_deps.py --output-deps=deps octane:
435 # {'octane': ['tools/perf/page_sets/data/octane_002.wprgo']}
436 perf_path = os.path.join(self._telemetry_path, 'tools', 'perf')
437 deps_path = os.path.join(perf_path, 'fetch_benchmark_deps_result.json')
438 fetch_path = os.path.join(perf_path, 'fetch_benchmark_deps.py')
439 format_fetch = ('python %s --output-deps=%s %s')
440 command_fetch = format_fetch % (fetch_path, deps_path, test_name)
441 command_get = 'cat %s' % deps_path
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800442
443 if self._devserver:
444 devserver_hostname = self._devserver.url().split(
445 'http://')[1].split(':')[0]
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800446 command_fetch = 'ssh %s %s' % (devserver_hostname, command_fetch)
447 command_get = 'ssh %s %s' % (devserver_hostname, command_get)
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800448
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800449 logging.info('Getting DEPs: %s', command_fetch)
450 _, _, exit_code = self._run_cmd(command_fetch)
451 if exit_code != 0:
452 raise error.TestFail('Error occurred while fetching DEPs.')
453 stdout, _, exit_code = self._run_cmd(command_get)
454 if exit_code != 0:
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800455 raise error.TestFail('Error occurred while getting DEPs.')
456
457 # Download DEPs to DUT.
458 # send_file() relies on rsync over ssh. Couldn't be better.
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800459 deps = json.loads(stdout)
460 for dep in deps[test_name]:
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800461 src = os.path.join(self._telemetry_path, dep)
462 dst = os.path.join(DUT_CHROME_ROOT, dep)
Ting-Yuan Huang8a2c7f72016-03-28 22:01:07 +0800463 if self._devserver:
464 logging.info('Copying: %s -> %s', src, dst)
Chung-yih Wangfd8eb242017-12-09 19:23:04 +0800465 rsync_cmd = utils.sh_escape('rsync %s %s %s:%s' %
466 (self._host.rsync_options(), src,
467 self._host.hostname, dst))
468 utils.run('ssh %s "%s"' % (devserver_hostname, rsync_cmd))
Ting-Yuan Huang8a2c7f72016-03-28 22:01:07 +0800469 else:
470 if not os.path.isfile(src):
471 raise error.TestFail('Error occurred while saving DEPs.')
472 logging.info('Copying: %s -> %s', src, dst)
473 dut.send_file(src, dst)