xref: /aosp_15_r20/external/angle/build/chromeos/test_runner_test.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/env vpython3
2*8975f5c5SAndroid Build Coastguard Worker# Copyright 2020 The Chromium Authors
3*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker
6*8975f5c5SAndroid Build Coastguard Workerimport json
7*8975f5c5SAndroid Build Coastguard Workerimport os
8*8975f5c5SAndroid Build Coastguard Workerimport shutil
9*8975f5c5SAndroid Build Coastguard Workerimport sys
10*8975f5c5SAndroid Build Coastguard Workerimport tempfile
11*8975f5c5SAndroid Build Coastguard Workerfrom textwrap import dedent
12*8975f5c5SAndroid Build Coastguard Workerimport unittest
13*8975f5c5SAndroid Build Coastguard Worker
14*8975f5c5SAndroid Build Coastguard Worker# The following non-std imports are fetched via vpython. See the list at
15*8975f5c5SAndroid Build Coastguard Worker# //.vpython3
16*8975f5c5SAndroid Build Coastguard Workerimport mock  # pylint: disable=import-error
17*8975f5c5SAndroid Build Coastguard Workerfrom parameterized import parameterized  # pylint: disable=import-error
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Workerimport test_runner
20*8975f5c5SAndroid Build Coastguard Worker
21*8975f5c5SAndroid Build Coastguard Worker_TAST_TEST_RESULTS_JSON = {
22*8975f5c5SAndroid Build Coastguard Worker    "name": "login.Chrome",
23*8975f5c5SAndroid Build Coastguard Worker    "errors": None,
24*8975f5c5SAndroid Build Coastguard Worker    "start": "2020-01-01T15:41:30.799228462-08:00",
25*8975f5c5SAndroid Build Coastguard Worker    "end": "2020-01-01T15:41:53.318914698-08:00",
26*8975f5c5SAndroid Build Coastguard Worker    "skipReason": ""
27*8975f5c5SAndroid Build Coastguard Worker}
28*8975f5c5SAndroid Build Coastguard Worker
29*8975f5c5SAndroid Build Coastguard Worker
30*8975f5c5SAndroid Build Coastguard Workerclass TestRunnerTest(unittest.TestCase):
31*8975f5c5SAndroid Build Coastguard Worker
32*8975f5c5SAndroid Build Coastguard Worker  def setUp(self):
33*8975f5c5SAndroid Build Coastguard Worker    self._tmp_dir = tempfile.mkdtemp()
34*8975f5c5SAndroid Build Coastguard Worker    self.mock_rdb = mock.patch.object(
35*8975f5c5SAndroid Build Coastguard Worker        test_runner.result_sink, 'TryInitClient', return_value=None)
36*8975f5c5SAndroid Build Coastguard Worker    self.mock_rdb.start()
37*8975f5c5SAndroid Build Coastguard Worker    self.mock_env = mock.patch.dict(
38*8975f5c5SAndroid Build Coastguard Worker        os.environ, {'SWARMING_BOT_ID': 'cros-chrome-chromeos8-row29'})
39*8975f5c5SAndroid Build Coastguard Worker    self.mock_env.start()
40*8975f5c5SAndroid Build Coastguard Worker
41*8975f5c5SAndroid Build Coastguard Worker  def tearDown(self):
42*8975f5c5SAndroid Build Coastguard Worker    shutil.rmtree(self._tmp_dir, ignore_errors=True)
43*8975f5c5SAndroid Build Coastguard Worker    self.mock_rdb.stop()
44*8975f5c5SAndroid Build Coastguard Worker    self.mock_env.stop()
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker  def safeAssertItemsEqual(self, list1, list2):
47*8975f5c5SAndroid Build Coastguard Worker    """A Py3 safe version of assertItemsEqual.
48*8975f5c5SAndroid Build Coastguard Worker
49*8975f5c5SAndroid Build Coastguard Worker    See https://bugs.python.org/issue17866.
50*8975f5c5SAndroid Build Coastguard Worker    """
51*8975f5c5SAndroid Build Coastguard Worker    self.assertSetEqual(set(list1), set(list2))
52*8975f5c5SAndroid Build Coastguard Worker
53*8975f5c5SAndroid Build Coastguard Worker
54*8975f5c5SAndroid Build Coastguard Workerclass TastTests(TestRunnerTest):
55*8975f5c5SAndroid Build Coastguard Worker
56*8975f5c5SAndroid Build Coastguard Worker  def get_common_tast_args(self, use_vm, fetch_cros_hostname):
57*8975f5c5SAndroid Build Coastguard Worker    return [
58*8975f5c5SAndroid Build Coastguard Worker        'script_name',
59*8975f5c5SAndroid Build Coastguard Worker        'tast',
60*8975f5c5SAndroid Build Coastguard Worker        '--suite-name=chrome_all_tast_tests',
61*8975f5c5SAndroid Build Coastguard Worker        '--board=eve',
62*8975f5c5SAndroid Build Coastguard Worker        '--flash',
63*8975f5c5SAndroid Build Coastguard Worker        '--path-to-outdir=out_eve/Release',
64*8975f5c5SAndroid Build Coastguard Worker        '--logs-dir=%s' % self._tmp_dir,
65*8975f5c5SAndroid Build Coastguard Worker        '--use-vm' if use_vm else
66*8975f5c5SAndroid Build Coastguard Worker        ('--fetch-cros-hostname'
67*8975f5c5SAndroid Build Coastguard Worker         if fetch_cros_hostname else '--device=localhost:2222'),
68*8975f5c5SAndroid Build Coastguard Worker    ]
69*8975f5c5SAndroid Build Coastguard Worker
70*8975f5c5SAndroid Build Coastguard Worker  def get_common_tast_expectations(self, use_vm, fetch_cros_hostname):
71*8975f5c5SAndroid Build Coastguard Worker    expectation = [
72*8975f5c5SAndroid Build Coastguard Worker        test_runner.CROS_RUN_TEST_PATH,
73*8975f5c5SAndroid Build Coastguard Worker        '--board',
74*8975f5c5SAndroid Build Coastguard Worker        'eve',
75*8975f5c5SAndroid Build Coastguard Worker        '--cache-dir',
76*8975f5c5SAndroid Build Coastguard Worker        test_runner.DEFAULT_CROS_CACHE,
77*8975f5c5SAndroid Build Coastguard Worker        '--results-dest-dir',
78*8975f5c5SAndroid Build Coastguard Worker        '%s/system_logs' % self._tmp_dir,
79*8975f5c5SAndroid Build Coastguard Worker        '--flash',
80*8975f5c5SAndroid Build Coastguard Worker        '--build-dir',
81*8975f5c5SAndroid Build Coastguard Worker        'out_eve/Release',
82*8975f5c5SAndroid Build Coastguard Worker        '--results-dir',
83*8975f5c5SAndroid Build Coastguard Worker        self._tmp_dir,
84*8975f5c5SAndroid Build Coastguard Worker        '--tast-total-shards=1',
85*8975f5c5SAndroid Build Coastguard Worker        '--tast-shard-index=0',
86*8975f5c5SAndroid Build Coastguard Worker    ]
87*8975f5c5SAndroid Build Coastguard Worker    expectation.extend(['--start', '--copy-on-write'] if use_vm else (
88*8975f5c5SAndroid Build Coastguard Worker        ['--device', 'chrome-chromeos8-row29']
89*8975f5c5SAndroid Build Coastguard Worker        if fetch_cros_hostname else ['--device', 'localhost:2222']))
90*8975f5c5SAndroid Build Coastguard Worker    for p in test_runner.SYSTEM_LOG_LOCATIONS:
91*8975f5c5SAndroid Build Coastguard Worker      expectation.extend(['--results-src', p])
92*8975f5c5SAndroid Build Coastguard Worker
93*8975f5c5SAndroid Build Coastguard Worker    expectation += [
94*8975f5c5SAndroid Build Coastguard Worker        '--mount',
95*8975f5c5SAndroid Build Coastguard Worker        '--deploy',
96*8975f5c5SAndroid Build Coastguard Worker        '--nostrip',
97*8975f5c5SAndroid Build Coastguard Worker    ]
98*8975f5c5SAndroid Build Coastguard Worker    return expectation
99*8975f5c5SAndroid Build Coastguard Worker
100*8975f5c5SAndroid Build Coastguard Worker  def test_tast_gtest_filter(self):
101*8975f5c5SAndroid Build Coastguard Worker    """Tests running tast tests with a gtest-style filter."""
102*8975f5c5SAndroid Build Coastguard Worker    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
103*8975f5c5SAndroid Build Coastguard Worker      json.dump(_TAST_TEST_RESULTS_JSON, f)
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker    args = self.get_common_tast_args(False, False) + [
106*8975f5c5SAndroid Build Coastguard Worker        '--attr-expr=( "group:mainline" && "dep:chrome" && !informational)',
107*8975f5c5SAndroid Build Coastguard Worker        '--gtest_filter=login.Chrome:ui.WindowControl',
108*8975f5c5SAndroid Build Coastguard Worker    ]
109*8975f5c5SAndroid Build Coastguard Worker    with mock.patch.object(sys, 'argv', args),\
110*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
111*8975f5c5SAndroid Build Coastguard Worker      mock_popen.return_value.returncode = 0
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker      test_runner.main()
114*8975f5c5SAndroid Build Coastguard Worker      # The gtest filter should cause the Tast expr to be replaced with a list
115*8975f5c5SAndroid Build Coastguard Worker      # of the tests in the filter.
116*8975f5c5SAndroid Build Coastguard Worker      expected_cmd = self.get_common_tast_expectations(False, False) + [
117*8975f5c5SAndroid Build Coastguard Worker          '--tast=("name:login.Chrome" || "name:ui.WindowControl")'
118*8975f5c5SAndroid Build Coastguard Worker      ]
119*8975f5c5SAndroid Build Coastguard Worker
120*8975f5c5SAndroid Build Coastguard Worker      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])
121*8975f5c5SAndroid Build Coastguard Worker
122*8975f5c5SAndroid Build Coastguard Worker  @parameterized.expand([
123*8975f5c5SAndroid Build Coastguard Worker      [True, False],
124*8975f5c5SAndroid Build Coastguard Worker      [False, True],
125*8975f5c5SAndroid Build Coastguard Worker      [False, False],
126*8975f5c5SAndroid Build Coastguard Worker  ])
127*8975f5c5SAndroid Build Coastguard Worker  def test_tast_attr_expr(self, use_vm, fetch_cros_hostname):
128*8975f5c5SAndroid Build Coastguard Worker    """Tests running a tast tests specified by an attribute expression."""
129*8975f5c5SAndroid Build Coastguard Worker    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
130*8975f5c5SAndroid Build Coastguard Worker      json.dump(_TAST_TEST_RESULTS_JSON, f)
131*8975f5c5SAndroid Build Coastguard Worker
132*8975f5c5SAndroid Build Coastguard Worker    args = self.get_common_tast_args(use_vm, fetch_cros_hostname) + [
133*8975f5c5SAndroid Build Coastguard Worker        '--attr-expr=( "group:mainline" && "dep:chrome" && !informational)',
134*8975f5c5SAndroid Build Coastguard Worker    ]
135*8975f5c5SAndroid Build Coastguard Worker    with mock.patch.object(sys, 'argv', args),\
136*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
137*8975f5c5SAndroid Build Coastguard Worker      mock_popen.return_value.returncode = 0
138*8975f5c5SAndroid Build Coastguard Worker
139*8975f5c5SAndroid Build Coastguard Worker      test_runner.main()
140*8975f5c5SAndroid Build Coastguard Worker      expected_cmd = self.get_common_tast_expectations(
141*8975f5c5SAndroid Build Coastguard Worker          use_vm, fetch_cros_hostname) + [
142*8975f5c5SAndroid Build Coastguard Worker              '--tast=( "group:mainline" && "dep:chrome" && !informational)',
143*8975f5c5SAndroid Build Coastguard Worker          ]
144*8975f5c5SAndroid Build Coastguard Worker
145*8975f5c5SAndroid Build Coastguard Worker      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])
146*8975f5c5SAndroid Build Coastguard Worker
147*8975f5c5SAndroid Build Coastguard Worker  @parameterized.expand([
148*8975f5c5SAndroid Build Coastguard Worker      [True, False],
149*8975f5c5SAndroid Build Coastguard Worker      [False, True],
150*8975f5c5SAndroid Build Coastguard Worker      [False, False],
151*8975f5c5SAndroid Build Coastguard Worker  ])
152*8975f5c5SAndroid Build Coastguard Worker  def test_tast_with_vars(self, use_vm, fetch_cros_hostname):
153*8975f5c5SAndroid Build Coastguard Worker    """Tests running a tast tests with runtime variables."""
154*8975f5c5SAndroid Build Coastguard Worker    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
155*8975f5c5SAndroid Build Coastguard Worker      json.dump(_TAST_TEST_RESULTS_JSON, f)
156*8975f5c5SAndroid Build Coastguard Worker
157*8975f5c5SAndroid Build Coastguard Worker    args = self.get_common_tast_args(use_vm, fetch_cros_hostname) + [
158*8975f5c5SAndroid Build Coastguard Worker        '-t=login.Chrome',
159*8975f5c5SAndroid Build Coastguard Worker        '--tast-var=key=value',
160*8975f5c5SAndroid Build Coastguard Worker    ]
161*8975f5c5SAndroid Build Coastguard Worker    with mock.patch.object(sys, 'argv', args),\
162*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
163*8975f5c5SAndroid Build Coastguard Worker      mock_popen.return_value.returncode = 0
164*8975f5c5SAndroid Build Coastguard Worker      test_runner.main()
165*8975f5c5SAndroid Build Coastguard Worker      expected_cmd = self.get_common_tast_expectations(
166*8975f5c5SAndroid Build Coastguard Worker          use_vm, fetch_cros_hostname) + [
167*8975f5c5SAndroid Build Coastguard Worker              '--tast', 'login.Chrome', '--tast-var', 'key=value'
168*8975f5c5SAndroid Build Coastguard Worker          ]
169*8975f5c5SAndroid Build Coastguard Worker
170*8975f5c5SAndroid Build Coastguard Worker      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])
171*8975f5c5SAndroid Build Coastguard Worker
172*8975f5c5SAndroid Build Coastguard Worker  @parameterized.expand([
173*8975f5c5SAndroid Build Coastguard Worker      [True, False],
174*8975f5c5SAndroid Build Coastguard Worker      [False, True],
175*8975f5c5SAndroid Build Coastguard Worker      [False, False],
176*8975f5c5SAndroid Build Coastguard Worker  ])
177*8975f5c5SAndroid Build Coastguard Worker  def test_tast_retries(self, use_vm, fetch_cros_hostname):
178*8975f5c5SAndroid Build Coastguard Worker    """Tests running a tast tests with retries."""
179*8975f5c5SAndroid Build Coastguard Worker    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
180*8975f5c5SAndroid Build Coastguard Worker      json.dump(_TAST_TEST_RESULTS_JSON, f)
181*8975f5c5SAndroid Build Coastguard Worker
182*8975f5c5SAndroid Build Coastguard Worker    args = self.get_common_tast_args(use_vm, fetch_cros_hostname) + [
183*8975f5c5SAndroid Build Coastguard Worker        '-t=login.Chrome',
184*8975f5c5SAndroid Build Coastguard Worker        '--tast-retries=1',
185*8975f5c5SAndroid Build Coastguard Worker    ]
186*8975f5c5SAndroid Build Coastguard Worker    with mock.patch.object(sys, 'argv', args),\
187*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
188*8975f5c5SAndroid Build Coastguard Worker      mock_popen.return_value.returncode = 0
189*8975f5c5SAndroid Build Coastguard Worker      test_runner.main()
190*8975f5c5SAndroid Build Coastguard Worker      expected_cmd = self.get_common_tast_expectations(
191*8975f5c5SAndroid Build Coastguard Worker          use_vm,
192*8975f5c5SAndroid Build Coastguard Worker          fetch_cros_hostname) + ['--tast', 'login.Chrome', '--tast-retries=1']
193*8975f5c5SAndroid Build Coastguard Worker
194*8975f5c5SAndroid Build Coastguard Worker      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])
195*8975f5c5SAndroid Build Coastguard Worker
196*8975f5c5SAndroid Build Coastguard Worker  @parameterized.expand([
197*8975f5c5SAndroid Build Coastguard Worker      [True, False],
198*8975f5c5SAndroid Build Coastguard Worker      [False, True],
199*8975f5c5SAndroid Build Coastguard Worker      [False, False],
200*8975f5c5SAndroid Build Coastguard Worker  ])
201*8975f5c5SAndroid Build Coastguard Worker  def test_tast(self, use_vm, fetch_cros_hostname):
202*8975f5c5SAndroid Build Coastguard Worker    """Tests running a tast tests."""
203*8975f5c5SAndroid Build Coastguard Worker    with open(os.path.join(self._tmp_dir, 'streamed_results.jsonl'), 'w') as f:
204*8975f5c5SAndroid Build Coastguard Worker      json.dump(_TAST_TEST_RESULTS_JSON, f)
205*8975f5c5SAndroid Build Coastguard Worker
206*8975f5c5SAndroid Build Coastguard Worker    args = self.get_common_tast_args(use_vm, fetch_cros_hostname) + [
207*8975f5c5SAndroid Build Coastguard Worker        '-t=login.Chrome',
208*8975f5c5SAndroid Build Coastguard Worker    ]
209*8975f5c5SAndroid Build Coastguard Worker    with mock.patch.object(sys, 'argv', args),\
210*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
211*8975f5c5SAndroid Build Coastguard Worker      mock_popen.return_value.returncode = 0
212*8975f5c5SAndroid Build Coastguard Worker
213*8975f5c5SAndroid Build Coastguard Worker      test_runner.main()
214*8975f5c5SAndroid Build Coastguard Worker      expected_cmd = self.get_common_tast_expectations(
215*8975f5c5SAndroid Build Coastguard Worker          use_vm, fetch_cros_hostname) + ['--tast', 'login.Chrome']
216*8975f5c5SAndroid Build Coastguard Worker
217*8975f5c5SAndroid Build Coastguard Worker      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])
218*8975f5c5SAndroid Build Coastguard Worker
219*8975f5c5SAndroid Build Coastguard Worker
220*8975f5c5SAndroid Build Coastguard Workerclass GTestTest(TestRunnerTest):
221*8975f5c5SAndroid Build Coastguard Worker
222*8975f5c5SAndroid Build Coastguard Worker  @parameterized.expand([
223*8975f5c5SAndroid Build Coastguard Worker      [True, True, True, False, True],
224*8975f5c5SAndroid Build Coastguard Worker      [True, False, False, False, False],
225*8975f5c5SAndroid Build Coastguard Worker      [False, True, True, True, True],
226*8975f5c5SAndroid Build Coastguard Worker      [False, False, False, True, False],
227*8975f5c5SAndroid Build Coastguard Worker      [False, True, True, False, True],
228*8975f5c5SAndroid Build Coastguard Worker      [False, False, False, False, False],
229*8975f5c5SAndroid Build Coastguard Worker  ])
230*8975f5c5SAndroid Build Coastguard Worker  def test_gtest(self, use_vm, stop_ui, use_test_sudo_helper,
231*8975f5c5SAndroid Build Coastguard Worker                 fetch_cros_hostname, use_deployed_dbus_configs):
232*8975f5c5SAndroid Build Coastguard Worker    """Tests running a gtest."""
233*8975f5c5SAndroid Build Coastguard Worker    fd_mock = mock.mock_open()
234*8975f5c5SAndroid Build Coastguard Worker
235*8975f5c5SAndroid Build Coastguard Worker    args = [
236*8975f5c5SAndroid Build Coastguard Worker        'script_name',
237*8975f5c5SAndroid Build Coastguard Worker        'gtest',
238*8975f5c5SAndroid Build Coastguard Worker        '--test-exe=out_eve/Release/base_unittests',
239*8975f5c5SAndroid Build Coastguard Worker        '--board=eve',
240*8975f5c5SAndroid Build Coastguard Worker        '--path-to-outdir=out_eve/Release',
241*8975f5c5SAndroid Build Coastguard Worker        '--use-vm' if use_vm else
242*8975f5c5SAndroid Build Coastguard Worker        ('--fetch-cros-hostname'
243*8975f5c5SAndroid Build Coastguard Worker         if fetch_cros_hostname else '--device=localhost:2222'),
244*8975f5c5SAndroid Build Coastguard Worker    ]
245*8975f5c5SAndroid Build Coastguard Worker    if stop_ui:
246*8975f5c5SAndroid Build Coastguard Worker      args.append('--stop-ui')
247*8975f5c5SAndroid Build Coastguard Worker    if use_test_sudo_helper:
248*8975f5c5SAndroid Build Coastguard Worker      args.append('--run-test-sudo-helper')
249*8975f5c5SAndroid Build Coastguard Worker    if use_deployed_dbus_configs:
250*8975f5c5SAndroid Build Coastguard Worker      args.append('--use-deployed-dbus-configs')
251*8975f5c5SAndroid Build Coastguard Worker
252*8975f5c5SAndroid Build Coastguard Worker    with mock.patch.object(sys, 'argv', args),\
253*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen,\
254*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(os, 'fdopen', fd_mock),\
255*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(os, 'remove') as mock_remove,\
256*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(tempfile, 'mkstemp',
257*8975f5c5SAndroid Build Coastguard Worker            side_effect=[(3, 'out_eve/Release/device_script.sh'),\
258*8975f5c5SAndroid Build Coastguard Worker                         (4, 'out_eve/Release/runtime_files.txt')]),\
259*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(os, 'fchmod'):
260*8975f5c5SAndroid Build Coastguard Worker      mock_popen.return_value.returncode = 0
261*8975f5c5SAndroid Build Coastguard Worker
262*8975f5c5SAndroid Build Coastguard Worker      test_runner.main()
263*8975f5c5SAndroid Build Coastguard Worker      self.assertEqual(1, mock_popen.call_count)
264*8975f5c5SAndroid Build Coastguard Worker      expected_cmd = [
265*8975f5c5SAndroid Build Coastguard Worker          'vpython3', test_runner.CROS_RUN_TEST_PATH, '--board', 'eve',
266*8975f5c5SAndroid Build Coastguard Worker          '--cache-dir', test_runner.DEFAULT_CROS_CACHE, '--remote-cmd',
267*8975f5c5SAndroid Build Coastguard Worker          '--cwd', 'out_eve/Release', '--files-from',
268*8975f5c5SAndroid Build Coastguard Worker          'out_eve/Release/runtime_files.txt'
269*8975f5c5SAndroid Build Coastguard Worker      ]
270*8975f5c5SAndroid Build Coastguard Worker      if not stop_ui:
271*8975f5c5SAndroid Build Coastguard Worker        expected_cmd.append('--as-chronos')
272*8975f5c5SAndroid Build Coastguard Worker      expected_cmd.extend(['--start', '--copy-on-write'] if use_vm else (
273*8975f5c5SAndroid Build Coastguard Worker          ['--device', 'chrome-chromeos8-row29']
274*8975f5c5SAndroid Build Coastguard Worker          if fetch_cros_hostname else ['--device', 'localhost:2222']))
275*8975f5c5SAndroid Build Coastguard Worker      expected_cmd.extend(['--', './device_script.sh'])
276*8975f5c5SAndroid Build Coastguard Worker      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])
277*8975f5c5SAndroid Build Coastguard Worker
278*8975f5c5SAndroid Build Coastguard Worker      expected_device_script = dedent("""\
279*8975f5c5SAndroid Build Coastguard Worker          #!/bin/sh
280*8975f5c5SAndroid Build Coastguard Worker          export HOME=/usr/local/tmp
281*8975f5c5SAndroid Build Coastguard Worker          export TMPDIR=/usr/local/tmp
282*8975f5c5SAndroid Build Coastguard Worker          """)
283*8975f5c5SAndroid Build Coastguard Worker
284*8975f5c5SAndroid Build Coastguard Worker      core_cmd = 'LD_LIBRARY_PATH=./ ./out_eve/Release/base_unittests'\
285*8975f5c5SAndroid Build Coastguard Worker          ' --test-launcher-shard-index=0 --test-launcher-total-shards=1'
286*8975f5c5SAndroid Build Coastguard Worker
287*8975f5c5SAndroid Build Coastguard Worker      if use_test_sudo_helper:
288*8975f5c5SAndroid Build Coastguard Worker        expected_device_script += dedent("""\
289*8975f5c5SAndroid Build Coastguard Worker            TEST_SUDO_HELPER_PATH=$(mktemp)
290*8975f5c5SAndroid Build Coastguard Worker            ./test_sudo_helper.py --socket-path=${TEST_SUDO_HELPER_PATH} &
291*8975f5c5SAndroid Build Coastguard Worker            TEST_SUDO_HELPER_PID=$!
292*8975f5c5SAndroid Build Coastguard Worker          """)
293*8975f5c5SAndroid Build Coastguard Worker        core_cmd += ' --test-sudo-helper-socket-path=${TEST_SUDO_HELPER_PATH}'
294*8975f5c5SAndroid Build Coastguard Worker
295*8975f5c5SAndroid Build Coastguard Worker      if use_deployed_dbus_configs:
296*8975f5c5SAndroid Build Coastguard Worker        expected_device_script += dedent("""\
297*8975f5c5SAndroid Build Coastguard Worker            mount --bind ./dbus /opt/google/chrome/dbus
298*8975f5c5SAndroid Build Coastguard Worker            kill -s HUP $(pgrep dbus)
299*8975f5c5SAndroid Build Coastguard Worker          """)
300*8975f5c5SAndroid Build Coastguard Worker
301*8975f5c5SAndroid Build Coastguard Worker      if stop_ui:
302*8975f5c5SAndroid Build Coastguard Worker        dbus_cmd = 'dbus-send --system --type=method_call'\
303*8975f5c5SAndroid Build Coastguard Worker          ' --dest=org.chromium.PowerManager'\
304*8975f5c5SAndroid Build Coastguard Worker          ' /org/chromium/PowerManager'\
305*8975f5c5SAndroid Build Coastguard Worker          ' org.chromium.PowerManager.HandleUserActivity int32:0'
306*8975f5c5SAndroid Build Coastguard Worker        expected_device_script += dedent("""\
307*8975f5c5SAndroid Build Coastguard Worker          stop ui
308*8975f5c5SAndroid Build Coastguard Worker          {0}
309*8975f5c5SAndroid Build Coastguard Worker          chown -R chronos: ../..
310*8975f5c5SAndroid Build Coastguard Worker          sudo -E -u chronos -- /bin/bash -c \"{1}\"
311*8975f5c5SAndroid Build Coastguard Worker          TEST_RETURN_CODE=$?
312*8975f5c5SAndroid Build Coastguard Worker          start ui
313*8975f5c5SAndroid Build Coastguard Worker          """).format(dbus_cmd, core_cmd)
314*8975f5c5SAndroid Build Coastguard Worker      else:
315*8975f5c5SAndroid Build Coastguard Worker        expected_device_script += dedent("""\
316*8975f5c5SAndroid Build Coastguard Worker          {0}
317*8975f5c5SAndroid Build Coastguard Worker          TEST_RETURN_CODE=$?
318*8975f5c5SAndroid Build Coastguard Worker          """).format(core_cmd)
319*8975f5c5SAndroid Build Coastguard Worker
320*8975f5c5SAndroid Build Coastguard Worker      if use_test_sudo_helper:
321*8975f5c5SAndroid Build Coastguard Worker        expected_device_script += dedent("""\
322*8975f5c5SAndroid Build Coastguard Worker            pkill -P $TEST_SUDO_HELPER_PID
323*8975f5c5SAndroid Build Coastguard Worker            kill $TEST_SUDO_HELPER_PID
324*8975f5c5SAndroid Build Coastguard Worker            unlink ${TEST_SUDO_HELPER_PATH}
325*8975f5c5SAndroid Build Coastguard Worker          """)
326*8975f5c5SAndroid Build Coastguard Worker
327*8975f5c5SAndroid Build Coastguard Worker      if use_deployed_dbus_configs:
328*8975f5c5SAndroid Build Coastguard Worker        expected_device_script += dedent("""\
329*8975f5c5SAndroid Build Coastguard Worker            umount /opt/google/chrome/dbus
330*8975f5c5SAndroid Build Coastguard Worker            kill -s HUP $(pgrep dbus)
331*8975f5c5SAndroid Build Coastguard Worker          """)
332*8975f5c5SAndroid Build Coastguard Worker
333*8975f5c5SAndroid Build Coastguard Worker      expected_device_script += dedent("""\
334*8975f5c5SAndroid Build Coastguard Worker          exit $TEST_RETURN_CODE
335*8975f5c5SAndroid Build Coastguard Worker        """)
336*8975f5c5SAndroid Build Coastguard Worker
337*8975f5c5SAndroid Build Coastguard Worker      self.assertEqual(2, fd_mock().write.call_count)
338*8975f5c5SAndroid Build Coastguard Worker      write_calls = fd_mock().write.call_args_list
339*8975f5c5SAndroid Build Coastguard Worker
340*8975f5c5SAndroid Build Coastguard Worker      # Split the strings to make failure messages easier to read.
341*8975f5c5SAndroid Build Coastguard Worker      # Verify the first write of device script.
342*8975f5c5SAndroid Build Coastguard Worker      self.assertListEqual(
343*8975f5c5SAndroid Build Coastguard Worker          expected_device_script.split('\n'),
344*8975f5c5SAndroid Build Coastguard Worker          str(write_calls[0][0][0]).split('\n'))
345*8975f5c5SAndroid Build Coastguard Worker
346*8975f5c5SAndroid Build Coastguard Worker      # Verify the 2nd write of runtime files.
347*8975f5c5SAndroid Build Coastguard Worker      expected_runtime_files = ['out_eve/Release/device_script.sh']
348*8975f5c5SAndroid Build Coastguard Worker      self.assertListEqual(expected_runtime_files,
349*8975f5c5SAndroid Build Coastguard Worker                           str(write_calls[1][0][0]).strip().split('\n'))
350*8975f5c5SAndroid Build Coastguard Worker
351*8975f5c5SAndroid Build Coastguard Worker      mock_remove.assert_called_once_with('out_eve/Release/device_script.sh')
352*8975f5c5SAndroid Build Coastguard Worker
353*8975f5c5SAndroid Build Coastguard Worker  def test_gtest_with_vpython(self):
354*8975f5c5SAndroid Build Coastguard Worker    """Tests building a gtest with --vpython-dir."""
355*8975f5c5SAndroid Build Coastguard Worker    args = mock.MagicMock()
356*8975f5c5SAndroid Build Coastguard Worker    args.test_exe = 'base_unittests'
357*8975f5c5SAndroid Build Coastguard Worker    args.test_launcher_summary_output = None
358*8975f5c5SAndroid Build Coastguard Worker    args.trace_dir = None
359*8975f5c5SAndroid Build Coastguard Worker    args.runtime_deps_path = None
360*8975f5c5SAndroid Build Coastguard Worker    args.path_to_outdir = self._tmp_dir
361*8975f5c5SAndroid Build Coastguard Worker    args.vpython_dir = self._tmp_dir
362*8975f5c5SAndroid Build Coastguard Worker    args.logs_dir = self._tmp_dir
363*8975f5c5SAndroid Build Coastguard Worker
364*8975f5c5SAndroid Build Coastguard Worker    # With vpython_dir initially empty, the test_runner should error out
365*8975f5c5SAndroid Build Coastguard Worker    # due to missing vpython binaries.
366*8975f5c5SAndroid Build Coastguard Worker    gtest = test_runner.GTestTest(args, None)
367*8975f5c5SAndroid Build Coastguard Worker    with self.assertRaises(test_runner.TestFormatError):
368*8975f5c5SAndroid Build Coastguard Worker      gtest.build_test_command()
369*8975f5c5SAndroid Build Coastguard Worker
370*8975f5c5SAndroid Build Coastguard Worker    # Create the two expected tools, and the test should be ready to run.
371*8975f5c5SAndroid Build Coastguard Worker    with open(os.path.join(args.vpython_dir, 'vpython3'), 'w'):
372*8975f5c5SAndroid Build Coastguard Worker      pass  # Just touch the file.
373*8975f5c5SAndroid Build Coastguard Worker    os.mkdir(os.path.join(args.vpython_dir, 'bin'))
374*8975f5c5SAndroid Build Coastguard Worker    with open(os.path.join(args.vpython_dir, 'bin', 'python3'), 'w'):
375*8975f5c5SAndroid Build Coastguard Worker      pass
376*8975f5c5SAndroid Build Coastguard Worker    gtest = test_runner.GTestTest(args, None)
377*8975f5c5SAndroid Build Coastguard Worker    gtest.build_test_command()
378*8975f5c5SAndroid Build Coastguard Worker
379*8975f5c5SAndroid Build Coastguard Worker
380*8975f5c5SAndroid Build Coastguard Workerclass HostCmdTests(TestRunnerTest):
381*8975f5c5SAndroid Build Coastguard Worker
382*8975f5c5SAndroid Build Coastguard Worker  @parameterized.expand([
383*8975f5c5SAndroid Build Coastguard Worker      [False, False],
384*8975f5c5SAndroid Build Coastguard Worker      [False, True],
385*8975f5c5SAndroid Build Coastguard Worker      [True, False],
386*8975f5c5SAndroid Build Coastguard Worker      [True, True],
387*8975f5c5SAndroid Build Coastguard Worker  ])
388*8975f5c5SAndroid Build Coastguard Worker  def test_host_cmd(self, deploy_chrome, strip_chrome):
389*8975f5c5SAndroid Build Coastguard Worker    args = [
390*8975f5c5SAndroid Build Coastguard Worker        'script_name',
391*8975f5c5SAndroid Build Coastguard Worker        'host-cmd',
392*8975f5c5SAndroid Build Coastguard Worker        '--board=eve',
393*8975f5c5SAndroid Build Coastguard Worker        '--flash',
394*8975f5c5SAndroid Build Coastguard Worker        '--path-to-outdir=out/Release',
395*8975f5c5SAndroid Build Coastguard Worker        '--device=localhost:2222',
396*8975f5c5SAndroid Build Coastguard Worker    ]
397*8975f5c5SAndroid Build Coastguard Worker    if deploy_chrome:
398*8975f5c5SAndroid Build Coastguard Worker      args += ['--deploy-chrome']
399*8975f5c5SAndroid Build Coastguard Worker    if strip_chrome:
400*8975f5c5SAndroid Build Coastguard Worker      args += ['--strip-chrome']
401*8975f5c5SAndroid Build Coastguard Worker    args += [
402*8975f5c5SAndroid Build Coastguard Worker        '--',
403*8975f5c5SAndroid Build Coastguard Worker        'fake_cmd',
404*8975f5c5SAndroid Build Coastguard Worker    ]
405*8975f5c5SAndroid Build Coastguard Worker    with mock.patch.object(sys, 'argv', args),\
406*8975f5c5SAndroid Build Coastguard Worker         mock.patch.object(test_runner.subprocess, 'Popen') as mock_popen:
407*8975f5c5SAndroid Build Coastguard Worker      mock_popen.return_value.returncode = 0
408*8975f5c5SAndroid Build Coastguard Worker
409*8975f5c5SAndroid Build Coastguard Worker      test_runner.main()
410*8975f5c5SAndroid Build Coastguard Worker      expected_cmd = [
411*8975f5c5SAndroid Build Coastguard Worker          test_runner.CROS_RUN_TEST_PATH,
412*8975f5c5SAndroid Build Coastguard Worker          '--board',
413*8975f5c5SAndroid Build Coastguard Worker          'eve',
414*8975f5c5SAndroid Build Coastguard Worker          '--cache-dir',
415*8975f5c5SAndroid Build Coastguard Worker          test_runner.DEFAULT_CROS_CACHE,
416*8975f5c5SAndroid Build Coastguard Worker          '--flash',
417*8975f5c5SAndroid Build Coastguard Worker          '--device',
418*8975f5c5SAndroid Build Coastguard Worker          'localhost:2222',
419*8975f5c5SAndroid Build Coastguard Worker          '--host-cmd',
420*8975f5c5SAndroid Build Coastguard Worker      ]
421*8975f5c5SAndroid Build Coastguard Worker      if deploy_chrome:
422*8975f5c5SAndroid Build Coastguard Worker        expected_cmd += [
423*8975f5c5SAndroid Build Coastguard Worker            '--mount',
424*8975f5c5SAndroid Build Coastguard Worker            '--deploy',
425*8975f5c5SAndroid Build Coastguard Worker            '--build-dir',
426*8975f5c5SAndroid Build Coastguard Worker            os.path.join(test_runner.CHROMIUM_SRC_PATH, 'out/Release'),
427*8975f5c5SAndroid Build Coastguard Worker        ]
428*8975f5c5SAndroid Build Coastguard Worker        if not strip_chrome:
429*8975f5c5SAndroid Build Coastguard Worker          expected_cmd += ['--nostrip']
430*8975f5c5SAndroid Build Coastguard Worker
431*8975f5c5SAndroid Build Coastguard Worker      expected_cmd += [
432*8975f5c5SAndroid Build Coastguard Worker          '--',
433*8975f5c5SAndroid Build Coastguard Worker          'fake_cmd',
434*8975f5c5SAndroid Build Coastguard Worker      ]
435*8975f5c5SAndroid Build Coastguard Worker
436*8975f5c5SAndroid Build Coastguard Worker      self.safeAssertItemsEqual(expected_cmd, mock_popen.call_args[0][0])
437*8975f5c5SAndroid Build Coastguard Worker
438*8975f5c5SAndroid Build Coastguard Worker
439*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__':
440*8975f5c5SAndroid Build Coastguard Worker  unittest.main()
441