blob: f93329ba4a886645931eb320d8043536bb47c181 [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',
Chung-yih Wang46672322018-03-30 16:28:57 +080037 'smoothness.top_25_smooth',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080038 'smoothness.tough_animation_cases',
39 'smoothness.tough_canvas_cases',
40 'smoothness.tough_filters_cases',
41 'smoothness.tough_pinch_zoom_cases',
42 'smoothness.tough_scrolling_cases',
43 'smoothness.tough_webgl_cases',
44 'speedometer',
Hsu-Cheng Tsaied1d6b32018-05-17 17:28:28 +080045 'speedometer2',
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080046 'tab_switching.top_10',
Chung-yih Wang80ba5812017-01-20 17:22:11 +080047 'tab_switching.typical_25',
Patrik Höglund2ef2e172016-11-16 10:07:29 +010048 'webrtc.peerconnection',
49 'webrtc.stress']
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080050
51# BLACK LIST
52# 'session_restore.cold.typical_25', # profile generator not implemented on
53 # CrOS.
Simran Basi833814b2013-01-29 13:13:43 -080054
55class TelemetryResult(object):
56 """Class to represent the results of a telemetry run.
57
58 This class represents the results of a telemetry run, whether it ran
59 successful, failed or had warnings.
60 """
61
62
63 def __init__(self, exit_code=0, stdout='', stderr=''):
64 """Initializes this TelemetryResultObject instance.
65
66 @param status: Status of the telemtry run.
67 @param stdout: Stdout of the telemetry run.
68 @param stderr: Stderr of the telemetry run.
69 """
70 if exit_code == 0:
71 self.status = SUCCESS_STATUS
72 else:
73 self.status = FAILED_STATUS
74
Simran Basi833814b2013-01-29 13:13:43 -080075 self._stdout = stdout
76 self._stderr = stderr
77 self.output = '\n'.join([stdout, stderr])
78
79
Simran Basi833814b2013-01-29 13:13:43 -080080class TelemetryRunner(object):
81 """Class responsible for telemetry for a given build.
82
83 This class will extract and install telemetry on the devserver and is
84 responsible for executing the telemetry benchmarks and returning their
85 output to the caller.
86 """
87
Ting-Yuan Huang85dcde82016-04-08 17:41:32 +080088 def __init__(self, host, local=False, telemetry_on_dut=True):
Simran Basi833814b2013-01-29 13:13:43 -080089 """Initializes this telemetry runner instance.
90
91 If telemetry is not installed for this build, it will be.
Luis Lozano23ae3192013-11-08 16:22:46 -080092
Ting-Yuan Huange5b19132016-03-22 13:02:41 +080093 Basically, the following commands on the local pc on which test_that
94 will be executed, depending on the 4 possible combinations of
95 local x telemetry_on_dut:
96
97 local=True, telemetry_on_dut=False:
98 run_benchmark --browser=cros-chrome --remote=[dut] [test]
99
100 local=True, telemetry_on_dut=True:
101 ssh [dut] run_benchmark --browser=system [test]
102
103 local=False, telemetry_on_dut=False:
104 ssh [devserver] run_benchmark --browser=cros-chrome --remote=[dut] [test]
105
106 local=False, telemetry_on_dut=True:
107 ssh [devserver] ssh [dut] run_benchmark --browser=system [test]
108
Luis Lozano23ae3192013-11-08 16:22:46 -0800109 @param host: Host where the test will be run.
110 @param local: If set, no devserver will be used, test will be run
111 locally.
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800112 If not set, "ssh [devserver] " will be appended to test
113 commands.
114 @param telemetry_on_dut: If set, telemetry itself (the test harness)
115 will run on dut.
116 It decides browser=[system|cros-chrome]
Simran Basi833814b2013-01-29 13:13:43 -0800117 """
118 self._host = host
Ilja H. Friedelc7bf3102014-05-13 17:31:25 -0700119 self._devserver = None
120 self._telemetry_path = None
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800121 self._telemetry_on_dut = telemetry_on_dut
Luis Lozano23ae3192013-11-08 16:22:46 -0800122 # TODO (llozano crbug.com/324964). Remove conditional code.
123 # Use a class hierarchy instead.
124 if local:
125 self._setup_local_telemetry()
126 else:
127 self._setup_devserver_telemetry()
128
129 logging.debug('Telemetry Path: %s', self._telemetry_path)
130
131
132 def _setup_devserver_telemetry(self):
133 """Setup Telemetry to use the devserver."""
134 logging.debug('Setting up telemetry for devserver testing')
Simran Basi833814b2013-01-29 13:13:43 -0800135 logging.debug('Grabbing build from AFE.')
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800136 info = self._host.host_info_store.get()
137 if not info.build:
Simran Basi833814b2013-01-29 13:13:43 -0800138 logging.error('Unable to locate build label for host: %s.',
Dean Liaoe3e75f62017-11-14 10:36:43 +0800139 self._host.host_port)
Simran Basi833814b2013-01-29 13:13:43 -0800140 raise error.AutotestError('Failed to grab build for host %s.' %
Dean Liaoe3e75f62017-11-14 10:36:43 +0800141 self._host.host_port)
Simran Basi833814b2013-01-29 13:13:43 -0800142
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800143 logging.debug('Setting up telemetry for build: %s', info.build)
Simran Basi833814b2013-01-29 13:13:43 -0800144
Prathmesh Prabhucfff58a2017-02-06 10:07:43 -0800145 self._devserver = dev_server.ImageServer.resolve(
146 info.build, hostname=self._host.hostname)
147 self._devserver.stage_artifacts(info.build, ['autotest_packages'])
148 self._telemetry_path = self._devserver.setup_telemetry(build=info.build)
Luis Lozano23ae3192013-11-08 16:22:46 -0800149
150
151 def _setup_local_telemetry(self):
152 """Setup Telemetry to use local path to its sources.
153
154 First look for chrome source root, either externally mounted, or inside
155 the chroot. Prefer chrome-src-internal source tree to chrome-src.
156 """
157 TELEMETRY_DIR = 'src'
158 CHROME_LOCAL_SRC = '/var/cache/chromeos-cache/distfiles/target/'
Josh Triplett05208c92014-07-17 13:21:29 -0700159 CHROME_EXTERNAL_SRC = os.path.expanduser('~/chrome_root/')
Luis Lozano23ae3192013-11-08 16:22:46 -0800160
161 logging.debug('Setting up telemetry for local testing')
162
163 sources_list = ('chrome-src-internal', 'chrome-src')
Josh Triplett05208c92014-07-17 13:21:29 -0700164 dir_list = [CHROME_EXTERNAL_SRC]
Luis Lozano23ae3192013-11-08 16:22:46 -0800165 dir_list.extend(
166 [os.path.join(CHROME_LOCAL_SRC, x) for x in sources_list])
167 if 'CHROME_ROOT' in os.environ:
168 dir_list.insert(0, os.environ['CHROME_ROOT'])
169
170 telemetry_src = ''
171 for dir in dir_list:
172 if os.path.exists(dir):
173 telemetry_src = os.path.join(dir, TELEMETRY_DIR)
174 break
175 else:
176 raise error.TestError('Telemetry source directory not found.')
177
178 self._devserver = None
179 self._telemetry_path = telemetry_src
180
181
Luis Lozano814c7182015-09-08 11:20:47 -0700182 def _get_telemetry_cmd(self, script, test_or_benchmark, *args):
Luis Lozano23ae3192013-11-08 16:22:46 -0800183 """Build command to execute telemetry based on script and benchmark.
184
185 @param script: Telemetry script we want to run. For example:
186 [path_to_telemetry_src]/src/tools/telemetry/run_tests.
187 @param test_or_benchmark: Name of the test or benchmark we want to run,
188 with the page_set (if required) as part of
189 the string.
Luis Lozano814c7182015-09-08 11:20:47 -0700190 @param args: additional list of arguments to pass to the script.
191
Luis Lozano23ae3192013-11-08 16:22:46 -0800192 @returns Full telemetry command to execute the script.
193 """
194 telemetry_cmd = []
195 if self._devserver:
Allen Lia5cfb972016-12-27 17:17:22 -0800196 devserver_hostname = self._devserver.hostname
Luis Lozano23ae3192013-11-08 16:22:46 -0800197 telemetry_cmd.extend(['ssh', devserver_hostname])
198
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800199 if self._telemetry_on_dut:
200 telemetry_cmd.extend(
Dean Liaoe3e75f62017-11-14 10:36:43 +0800201 [self._host.ssh_command(alive_interval=900,
202 connection_attempts=4),
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800203 'python',
204 script,
205 '--verbose',
206 '--output-format=chartjson',
207 '--output-dir=%s' % DUT_CHROME_ROOT,
208 '--browser=system'])
209 else:
210 telemetry_cmd.extend(
211 ['python',
212 script,
213 '--verbose',
214 '--browser=cros-chrome',
215 '--output-format=chartjson',
216 '--output-dir=%s' % self._telemetry_path,
Dean Liaoe3e75f62017-11-14 10:36:43 +0800217 '--remote=%s' % self._host.host_port])
Luis Lozano814c7182015-09-08 11:20:47 -0700218 telemetry_cmd.extend(args)
219 telemetry_cmd.append(test_or_benchmark)
220
Keith Haddow1e5c7012016-03-09 16:05:37 -0800221 return ' '.join(telemetry_cmd)
222
223
224 def _scp_telemetry_results_cmd(self, perf_results_dir):
225 """Build command to copy the telemetry results from the devserver.
226
227 @param perf_results_dir: directory path where test output is to be
228 collected.
229 @returns SCP command to copy the results json to the specified directory.
230 """
Dean Liaoe3e75f62017-11-14 10:36:43 +0800231 if not perf_results_dir:
232 return ''
233
234 scp_cmd = ['scp']
235 if self._telemetry_on_dut:
236 scp_cmd.append(self._host.make_ssh_options(alive_interval=900,
237 connection_attempts=4))
238 if not self._host.is_default_port:
239 scp_cmd.append('-P %d' % self._host.port)
240 src = 'root@%s:%s/results-chart.json' % (self._host.hostname,
241 DUT_CHROME_ROOT)
242 else:
243 devserver_hostname = ''
Ricky Liangd186f3e2016-03-15 16:50:55 +0800244 if self._devserver:
Allen Lia5cfb972016-12-27 17:17:22 -0800245 devserver_hostname = self._devserver.hostname + ':'
Dean Liaoe3e75f62017-11-14 10:36:43 +0800246 src = '%s%s/results-chart.json' % (devserver_hostname,
247 self._telemetry_path)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800248
Dean Liaoe3e75f62017-11-14 10:36:43 +0800249 scp_cmd.extend([src, perf_results_dir])
Keith Haddow1e5c7012016-03-09 16:05:37 -0800250 return ' '.join(scp_cmd)
251
252
253 def _run_cmd(self, cmd):
254 """Execute an command in a external shell and capture the output.
255
256 @param cmd: String of is a valid shell command.
257
258 @returns The standard out, standard error and the integer exit code of
259 the executed command.
260 """
261 logging.debug('Running: %s', cmd)
262
263 output = StringIO.StringIO()
264 error_output = StringIO.StringIO()
265 exit_code = 0
266 try:
267 result = utils.run(cmd, stdout_tee=output,
268 stderr_tee=error_output,
269 timeout=TELEMETRY_TIMEOUT_MINS*60)
270 exit_code = result.exit_status
271 except error.CmdError as e:
272 logging.debug('Error occurred executing.')
273 exit_code = e.result_obj.exit_status
274
275 stdout = output.getvalue()
276 stderr = error_output.getvalue()
277 logging.debug('Completed with exit code: %d.\nstdout:%s\n'
278 'stderr:%s', exit_code, stdout, stderr)
279 return stdout, stderr, exit_code
Simran Basi833814b2013-01-29 13:13:43 -0800280
281
Luis Lozano814c7182015-09-08 11:20:47 -0700282 def _run_telemetry(self, script, test_or_benchmark, *args):
Simran Basi833814b2013-01-29 13:13:43 -0800283 """Runs telemetry on a dut.
284
285 @param script: Telemetry script we want to run. For example:
Luis Lozano23ae3192013-11-08 16:22:46 -0800286 [path_to_telemetry_src]/src/tools/telemetry/run_tests.
Simran Basi833814b2013-01-29 13:13:43 -0800287 @param test_or_benchmark: Name of the test or benchmark we want to run,
288 with the page_set (if required) as part of the
289 string.
Luis Lozano814c7182015-09-08 11:20:47 -0700290 @param args: additional list of arguments to pass to the script.
Simran Basi833814b2013-01-29 13:13:43 -0800291
292 @returns A TelemetryResult Instance with the results of this telemetry
293 execution.
294 """
Simran Basi1dbfc132013-05-02 10:11:02 -0700295 # TODO (sbasi crbug.com/239933) add support for incognito mode.
Simran Basi833814b2013-01-29 13:13:43 -0800296
Luis Lozano814c7182015-09-08 11:20:47 -0700297 telemetry_cmd = self._get_telemetry_cmd(script,
298 test_or_benchmark,
299 *args)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800300 logging.debug('Running Telemetry: %s', telemetry_cmd)
Luis Lozano23ae3192013-11-08 16:22:46 -0800301
Keith Haddow1e5c7012016-03-09 16:05:37 -0800302 stdout, stderr, exit_code = self._run_cmd(telemetry_cmd)
Simran Basi833814b2013-01-29 13:13:43 -0800303
304 return TelemetryResult(exit_code=exit_code, stdout=stdout,
305 stderr=stderr)
306
307
Keith Haddow1e5c7012016-03-09 16:05:37 -0800308 def _run_scp(self, perf_results_dir):
309 """Runs telemetry on a dut.
310
311 @param perf_results_dir: The local directory that results are being
312 collected.
313 """
314 scp_cmd = self._scp_telemetry_results_cmd(perf_results_dir)
315 logging.debug('Retrieving Results: %s', scp_cmd)
Dean Liaoe4773c72017-11-09 16:15:38 +0800316 _, _, exit_code = self._run_cmd(scp_cmd)
317 if exit_code != 0:
318 raise error.TestFail('Unable to retrieve results.')
Keith Haddow1e5c7012016-03-09 16:05:37 -0800319
320
Luis Lozano814c7182015-09-08 11:20:47 -0700321 def _run_test(self, script, test, *args):
Simran Basi1dbfc132013-05-02 10:11:02 -0700322 """Runs a telemetry test on a dut.
323
324 @param script: Which telemetry test script we want to run. Can be
325 telemetry's base test script or the Chrome OS specific
326 test script.
327 @param test: Telemetry test we want to run.
Luis Lozano814c7182015-09-08 11:20:47 -0700328 @param args: additional list of arguments to pass to the script.
Simran Basi1dbfc132013-05-02 10:11:02 -0700329
330 @returns A TelemetryResult Instance with the results of this telemetry
331 execution.
332 """
333 logging.debug('Running telemetry test: %s', test)
334 telemetry_script = os.path.join(self._telemetry_path, script)
Luis Lozano814c7182015-09-08 11:20:47 -0700335 result = self._run_telemetry(telemetry_script, test, *args)
Simran Basi1dbfc132013-05-02 10:11:02 -0700336 if result.status is FAILED_STATUS:
Ilja H. Friedelc7bf3102014-05-13 17:31:25 -0700337 raise error.TestFail('Telemetry test %s failed.' % test)
Simran Basi1dbfc132013-05-02 10:11:02 -0700338 return result
339
340
Luis Lozano814c7182015-09-08 11:20:47 -0700341 def run_telemetry_test(self, test, *args):
Simran Basi833814b2013-01-29 13:13:43 -0800342 """Runs a telemetry test on a dut.
343
344 @param test: Telemetry test we want to run.
Luis Lozano814c7182015-09-08 11:20:47 -0700345 @param args: additional list of arguments to pass to the telemetry
346 execution script.
Simran Basi833814b2013-01-29 13:13:43 -0800347
348 @returns A TelemetryResult Instance with the results of this telemetry
349 execution.
350 """
Luis Lozano814c7182015-09-08 11:20:47 -0700351 return self._run_test(TELEMETRY_RUN_TESTS_SCRIPT, test, *args)
Simran Basi1dbfc132013-05-02 10:11:02 -0700352
353
Luis Lozano814c7182015-09-08 11:20:47 -0700354 def run_telemetry_benchmark(self, benchmark, perf_value_writer=None,
355 *args):
Simran Basi833814b2013-01-29 13:13:43 -0800356 """Runs a telemetry benchmark on a dut.
357
358 @param benchmark: Benchmark we want to run.
Fang Denge689e712013-11-13 18:27:06 -0800359 @param perf_value_writer: Should be an instance with the function
360 output_perf_value(), if None, no perf value
361 will be written. Typically this will be the
362 job object from an autotest test.
Luis Lozano814c7182015-09-08 11:20:47 -0700363 @param args: additional list of arguments to pass to the telemetry
364 execution script.
Simran Basi833814b2013-01-29 13:13:43 -0800365
366 @returns A TelemetryResult Instance with the results of this telemetry
367 execution.
368 """
Dave Tu6a404e62013-11-05 15:54:48 -0800369 logging.debug('Running telemetry benchmark: %s', benchmark)
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800370
371 if benchmark not in ON_DUT_WHITE_LIST:
372 self._telemetry_on_dut = False
373
374 if self._telemetry_on_dut:
375 telemetry_script = os.path.join(DUT_CHROME_ROOT,
376 TELEMETRY_RUN_BENCHMARKS_SCRIPT)
377 self._ensure_deps(self._host, benchmark)
378 else:
379 telemetry_script = os.path.join(self._telemetry_path,
380 TELEMETRY_RUN_BENCHMARKS_SCRIPT)
381
Luis Lozano814c7182015-09-08 11:20:47 -0700382 result = self._run_telemetry(telemetry_script, benchmark, *args)
Simran Basi833814b2013-01-29 13:13:43 -0800383
384 if result.status is WARNING_STATUS:
Dave Tu6a404e62013-11-05 15:54:48 -0800385 raise error.TestWarn('Telemetry Benchmark: %s'
386 ' exited with Warnings.' % benchmark)
Simran Basi833814b2013-01-29 13:13:43 -0800387 if result.status is FAILED_STATUS:
Dave Tu6a404e62013-11-05 15:54:48 -0800388 raise error.TestFail('Telemetry Benchmark: %s'
389 ' failed to run.' % benchmark)
Keith Haddow1e5c7012016-03-09 16:05:37 -0800390 if perf_value_writer:
391 self._run_scp(perf_value_writer.resultsdir)
Simran Basi833814b2013-01-29 13:13:43 -0800392 return result
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800393
Gurchetan Singhfaf75e92017-04-17 18:09:44 -0700394
395 def run_gpu_integration_test(self, test, *args):
396 """Runs a gpu test on a dut.
397
398 @param test: Gpu test we want to run.
399 @param args: additional list of arguments to pass to the telemetry
400 execution script.
401
402 @returns A TelemetryResult instance with the results of this telemetry
403 execution.
404 """
405 script = os.path.join(DUT_CHROME_ROOT,
406 TELEMETRY_RUN_GPU_TESTS_SCRIPT)
407 cmd = []
408 if self._devserver:
409 devserver_hostname = self._devserver.hostname
410 cmd.extend(['ssh', devserver_hostname])
411
412 cmd.extend(
Dean Liaoe3e75f62017-11-14 10:36:43 +0800413 [self._host.ssh_command(alive_interval=900, connection_attempts=4),
414 'python', script])
Gurchetan Singhfaf75e92017-04-17 18:09:44 -0700415 cmd.extend(args)
416 cmd.append(test)
417 cmd = ' '.join(cmd)
418 stdout, stderr, exit_code = self._run_cmd(cmd)
419
420 return TelemetryResult(exit_code=exit_code, stdout=stdout,
421 stderr=stderr)
422
423
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800424 def _ensure_deps(self, dut, test_name):
425 """
426 Ensure the dependencies are locally available on DUT.
427
428 @param dut: The autotest host object representing DUT.
429 @param test_name: Name of the telemetry test.
430 """
431 # Get DEPs using host's telemetry.
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800432 # Example output, fetch_benchmark_deps.py --output-deps=deps octane:
433 # {'octane': ['tools/perf/page_sets/data/octane_002.wprgo']}
434 perf_path = os.path.join(self._telemetry_path, 'tools', 'perf')
435 deps_path = os.path.join(perf_path, 'fetch_benchmark_deps_result.json')
436 fetch_path = os.path.join(perf_path, 'fetch_benchmark_deps.py')
437 format_fetch = ('python %s --output-deps=%s %s')
438 command_fetch = format_fetch % (fetch_path, deps_path, test_name)
439 command_get = 'cat %s' % deps_path
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800440
441 if self._devserver:
442 devserver_hostname = self._devserver.url().split(
443 'http://')[1].split(':')[0]
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800444 command_fetch = 'ssh %s %s' % (devserver_hostname, command_fetch)
445 command_get = 'ssh %s %s' % (devserver_hostname, command_get)
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800446
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800447 logging.info('Getting DEPs: %s', command_fetch)
448 _, _, exit_code = self._run_cmd(command_fetch)
449 if exit_code != 0:
450 raise error.TestFail('Error occurred while fetching DEPs.')
451 stdout, _, exit_code = self._run_cmd(command_get)
452 if exit_code != 0:
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800453 raise error.TestFail('Error occurred while getting DEPs.')
454
455 # Download DEPs to DUT.
456 # send_file() relies on rsync over ssh. Couldn't be better.
Kuo-Hsin Yang4a006172018-04-25 14:44:55 +0800457 deps = json.loads(stdout)
458 for dep in deps[test_name]:
Ting-Yuan Huange5b19132016-03-22 13:02:41 +0800459 src = os.path.join(self._telemetry_path, dep)
460 dst = os.path.join(DUT_CHROME_ROOT, dep)
Ting-Yuan Huang8a2c7f72016-03-28 22:01:07 +0800461 if self._devserver:
462 logging.info('Copying: %s -> %s', src, dst)
Chung-yih Wangfd8eb242017-12-09 19:23:04 +0800463 rsync_cmd = utils.sh_escape('rsync %s %s %s:%s' %
464 (self._host.rsync_options(), src,
465 self._host.hostname, dst))
466 utils.run('ssh %s "%s"' % (devserver_hostname, rsync_cmd))
Ting-Yuan Huang8a2c7f72016-03-28 22:01:07 +0800467 else:
468 if not os.path.isfile(src):
469 raise error.TestFail('Error occurred while saving DEPs.')
470 logging.info('Copying: %s -> %s', src, dst)
471 dut.send_file(src, dst)