blob: 23c413ba9cfb529b3acb72784bef98c3a5668e70 [file] [log] [blame]
Alex Kleina2e42c42019-04-17 16:13:19 -06001# Copyright 2019 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
5"""The test controller tests."""
6
Alex Klein9f915782020-02-14 23:15:09 +00007import contextlib
Lizzy Presland4feb2372022-01-20 05:16:30 +00008import datetime
Mike Frysingeref94e4c2020-02-10 23:59:54 -05009import os
Mike Frysinger3bb61cb2022-04-14 16:07:44 -040010from pathlib import Path
Mike Frysinger166fea02021-02-12 05:30:33 -050011from unittest import mock
Mike Frysingeref94e4c2020-02-10 23:59:54 -050012
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040013from chromite.third_party.google.protobuf import json_format
14
Alex Klein231d2da2019-07-22 16:44:45 -060015from chromite.api import api_config
Alex Klein8cb365a2019-05-15 16:24:53 -060016from chromite.api import controller
Lizzy Presland4feb2372022-01-20 05:16:30 +000017from chromite.api.controller import controller_util
Alex Kleina2e42c42019-04-17 16:13:19 -060018from chromite.api.controller import test as test_controller
19from chromite.api.gen.chromite.api import test_pb2
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040020from chromite.api.gen.chromiumos import common_pb2
Sean McAllister3834fef2021-10-08 15:45:18 -060021from chromite.api.gen.chromiumos.build.api import container_metadata_pb2
Jack Neusc9707c32021-07-23 21:48:54 +000022from chromite.lib import build_target_lib
Evan Hernandeze1e05d32019-07-19 12:32:18 -060023from chromite.lib import chroot_lib
Alex Kleina2e42c42019-04-17 16:13:19 -060024from chromite.lib import cros_build_lib
25from chromite.lib import cros_test_lib
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -060026from chromite.lib import image_lib
Alex Kleina2e42c42019-04-17 16:13:19 -060027from chromite.lib import osutils
David Wellingc1433c22021-06-25 16:29:48 +000028from chromite.lib import sysroot_lib
Alex Klein18a60af2020-06-11 12:08:47 -060029from chromite.lib.parser import package_info
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -060030from chromite.scripts import cros_set_lsb_release
31from chromite.service import test as test_service
Mike Frysingere652ba12019-09-08 00:57:43 -040032from chromite.utils import key_value_store
Alex Kleina2e42c42019-04-17 16:13:19 -060033
34
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070035class DebugInfoTestTest(cros_test_lib.MockTempDirTestCase,
36 api_config.ApiConfigMixin):
37 """Tests for the DebugInfoTest function."""
38
39 def setUp(self):
40 self.board = 'board'
41 self.chroot_path = os.path.join(self.tempdir, 'chroot')
42 self.sysroot_path = '/build/board'
43 self.full_sysroot_path = os.path.join(self.chroot_path,
44 self.sysroot_path.lstrip(os.sep))
45 osutils.SafeMakedirs(self.full_sysroot_path)
46
47 def _GetInput(self, sysroot_path=None, build_target=None):
48 """Helper to build an input message instance."""
49 proto = test_pb2.DebugInfoTestRequest()
50 if sysroot_path:
51 proto.sysroot.path = sysroot_path
52 if build_target:
53 proto.sysroot.build_target.name = build_target
54 return proto
55
56 def _GetOutput(self):
57 """Helper to get an empty output message instance."""
58 return test_pb2.DebugInfoTestResponse()
59
60 def testValidateOnly(self):
61 """Sanity check that a validate only call does not execute any logic."""
62 patch = self.PatchObject(test_service, 'DebugInfoTest')
63 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
64 test_controller.DebugInfoTest(input_msg, self._GetOutput(),
65 self.validate_only_config)
66 patch.assert_not_called()
67
Michael Mortensen85d38402019-12-12 09:50:29 -070068 def testMockError(self):
69 """Test mock error call does not execute any logic, returns error."""
70 patch = self.PatchObject(test_service, 'DebugInfoTest')
71
72 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
73 rc = test_controller.DebugInfoTest(input_msg, self._GetOutput(),
74 self.mock_error_config)
75 patch.assert_not_called()
76 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
77
78 def testMockCall(self):
79 """Test mock call does not execute any logic, returns success."""
80 patch = self.PatchObject(test_service, 'DebugInfoTest')
81
82 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
83 rc = test_controller.DebugInfoTest(input_msg, self._GetOutput(),
84 self.mock_call_config)
85 patch.assert_not_called()
86 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
87
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070088 def testNoBuildTargetNoSysrootFails(self):
89 """Test missing build target name and sysroot path fails."""
90 input_msg = self._GetInput()
91 output_msg = self._GetOutput()
92 with self.assertRaises(cros_build_lib.DieSystemExit):
93 test_controller.DebugInfoTest(input_msg, output_msg, self.api_config)
94
95 def testDebugInfoTest(self):
96 """Call DebugInfoTest with valid sysroot_path."""
97 request = self._GetInput(sysroot_path=self.full_sysroot_path)
98
99 test_controller.DebugInfoTest(request, self._GetOutput(), self.api_config)
100
101
Alex Klein231d2da2019-07-22 16:44:45 -0600102class BuildTargetUnitTestTest(cros_test_lib.MockTempDirTestCase,
103 api_config.ApiConfigMixin):
Alex Kleina2e42c42019-04-17 16:13:19 -0600104 """Tests for the UnitTest function."""
105
Lizzy Presland4feb2372022-01-20 05:16:30 +0000106 def setUp(self):
107 # Set up portage log directory.
108 self.sysroot = os.path.join(self.tempdir, 'build', 'board')
109 osutils.SafeMakedirs(self.sysroot)
110 self.target_sysroot = sysroot_lib.Sysroot(self.sysroot)
111 self.portage_dir = os.path.join(self.tempdir, 'portage_logdir')
112 self.PatchObject(
113 sysroot_lib.Sysroot, 'portage_logdir', new=self.portage_dir)
114 osutils.SafeMakedirs(self.portage_dir)
115
Navil Perezc0b29a82020-07-07 14:17:48 +0000116 def _GetInput(self,
117 board=None,
118 result_path=None,
119 chroot_path=None,
120 cache_dir=None,
121 empty_sysroot=None,
122 packages=None,
Alex Kleinb64e5f82020-09-23 10:55:31 -0600123 blocklist=None):
Alex Kleina2e42c42019-04-17 16:13:19 -0600124 """Helper to build an input message instance."""
Navil Perezc0b29a82020-07-07 14:17:48 +0000125 formatted_packages = []
126 for pkg in packages or []:
127 formatted_packages.append({
128 'category': pkg.category,
129 'package_name': pkg.package
130 })
Alex Kleinb64e5f82020-09-23 10:55:31 -0600131 formatted_blocklist = []
132 for pkg in blocklist or []:
133 formatted_blocklist.append({'category': pkg.category,
Alex Kleinf2674462019-05-16 16:47:24 -0600134 'package_name': pkg.package})
135
Mike Frysinger3bb61cb2022-04-14 16:07:44 -0400136 # Protobufs can't handle Path objects.
137 if isinstance(result_path, Path):
138 result_path = str(result_path)
139
Alex Kleina2e42c42019-04-17 16:13:19 -0600140 return test_pb2.BuildTargetUnitTestRequest(
141 build_target={'name': board}, result_path=result_path,
Alex Kleinfa6ebdc2019-05-10 10:57:31 -0600142 chroot={'path': chroot_path, 'cache_dir': cache_dir},
Alex Kleinf2674462019-05-16 16:47:24 -0600143 flags={'empty_sysroot': empty_sysroot},
Alex Klein64ac34c2020-09-23 10:21:33 -0600144 packages=formatted_packages,
Alex Klein157caf42021-07-01 14:36:43 -0600145 package_blocklist=formatted_blocklist,
Alex Kleina2e42c42019-04-17 16:13:19 -0600146 )
147
148 def _GetOutput(self):
149 """Helper to get an empty output message instance."""
150 return test_pb2.BuildTargetUnitTestResponse()
151
Lizzy Presland4feb2372022-01-20 05:16:30 +0000152 def _CreatePortageLogFile(self, log_path, pkg_info, timestamp):
153 """Creates a log file for testing for individual packages built by Portage.
154
155 Args:
156 log_path (pathlike): the PORTAGE_LOGDIR path
157 pkg_info (PackageInfo): name components for log file.
158 timestamp (datetime): timestamp used to name the file.
159 """
160 path = os.path.join(log_path,
161 f'{pkg_info.category}:{pkg_info.pvr}:' \
162 f'{timestamp.strftime("%Y%m%d-%H%M%S")}.log')
163 osutils.WriteFile(path,
164 f'Test log file for package {pkg_info.category}/'
165 f'{pkg_info.package} written to {path}')
166 return path
167
Alex Klein231d2da2019-07-22 16:44:45 -0600168 def testValidateOnly(self):
169 """Sanity check that a validate only call does not execute any logic."""
170 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
171
172 input_msg = self._GetInput(board='board', result_path=self.tempdir)
173 test_controller.BuildTargetUnitTest(input_msg, self._GetOutput(),
174 self.validate_only_config)
175 patch.assert_not_called()
176
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700177 def testMockCall(self):
178 """Test that a mock call does not execute logic, returns mocked value."""
179 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
180
181 input_msg = self._GetInput(board='board', result_path=self.tempdir)
182 response = self._GetOutput()
183 test_controller.BuildTargetUnitTest(input_msg, response,
184 self.mock_call_config)
185 patch.assert_not_called()
186 self.assertEqual(response.tarball_path,
187 os.path.join(input_msg.result_path, 'unit_tests.tar'))
188
189 def testMockError(self):
Michael Mortensen85d38402019-12-12 09:50:29 -0700190 """Test that a mock error does not execute logic, returns error."""
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700191 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
192
193 input_msg = self._GetInput(board='board', result_path=self.tempdir)
194 response = self._GetOutput()
195 rc = test_controller.BuildTargetUnitTest(input_msg, response,
196 self.mock_error_config)
197 patch.assert_not_called()
198 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
199 self.assertTrue(response.failed_packages)
200 self.assertEqual(response.failed_packages[0].category, 'foo')
201 self.assertEqual(response.failed_packages[0].package_name, 'bar')
202 self.assertEqual(response.failed_packages[1].category, 'cat')
203 self.assertEqual(response.failed_packages[1].package_name, 'pkg')
204
Alex Klein64ac34c2020-09-23 10:21:33 -0600205 def testInvalidPackageFails(self):
206 """Test missing result path fails."""
207 # Missing result_path.
208 pkg = package_info.PackageInfo(package='bar')
209 input_msg = self._GetInput(board='board', result_path=self.tempdir,
210 packages=[pkg])
211 output_msg = self._GetOutput()
212 with self.assertRaises(cros_build_lib.DieSystemExit):
213 test_controller.BuildTargetUnitTest(input_msg, output_msg,
214 self.api_config)
215
Alex Kleina2e42c42019-04-17 16:13:19 -0600216 def testPackageBuildFailure(self):
217 """Test handling of raised BuildPackageFailure."""
218 tempdir = osutils.TempDir(base_dir=self.tempdir)
219 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
220
Lizzy Presland4feb2372022-01-20 05:16:30 +0000221 pkgs = ['cat/pkg-1.0-r1', 'foo/bar-2.0-r1']
222 cpvrs = [package_info.parse(pkg) for pkg in pkgs]
Alex Kleina2e42c42019-04-17 16:13:19 -0600223 expected = [('cat', 'pkg'), ('foo', 'bar')]
Lizzy Presland4feb2372022-01-20 05:16:30 +0000224 new_logs = {}
225 for i, pkg in enumerate(pkgs):
226 self._CreatePortageLogFile(self.portage_dir, cpvrs[i],
227 datetime.datetime(2021, 6, 9, 13, 37, 0))
228 new_logs[pkg] = self._CreatePortageLogFile(self.portage_dir, cpvrs[i],
229 datetime.datetime(2021, 6, 9,
230 16, 20, 0))
Alex Kleina2e42c42019-04-17 16:13:19 -0600231
Alex Klein38c7d9e2019-05-08 09:31:19 -0600232 result = test_service.BuildTargetUnitTestResult(1, None)
Alex Kleinea0c89e2021-09-09 15:17:35 -0600233 result.failed_pkgs = [package_info.parse(p) for p in pkgs]
Alex Klein38c7d9e2019-05-08 09:31:19 -0600234 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
Alex Kleina2e42c42019-04-17 16:13:19 -0600235
236 input_msg = self._GetInput(board='board', result_path=self.tempdir)
237 output_msg = self._GetOutput()
238
Alex Klein231d2da2019-07-22 16:44:45 -0600239 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg,
240 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600241
Alex Klein8cb365a2019-05-15 16:24:53 -0600242 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -0600243 self.assertTrue(output_msg.failed_packages)
Lizzy Presland4feb2372022-01-20 05:16:30 +0000244 self.assertTrue(output_msg.failed_package_data)
245 # TODO(b/206514844): remove when field is deleted
Alex Kleina2e42c42019-04-17 16:13:19 -0600246 failed = []
247 for pi in output_msg.failed_packages:
248 failed.append((pi.category, pi.package_name))
Mike Frysinger678735c2019-09-28 18:23:28 -0400249 self.assertCountEqual(expected, failed)
Alex Kleina2e42c42019-04-17 16:13:19 -0600250
Lizzy Presland4feb2372022-01-20 05:16:30 +0000251 failed_with_logs = []
252 for data in output_msg.failed_package_data:
253 failed_with_logs.append((data.name.category, data.name.package_name))
254 package = controller_util.deserialize_package_info(data.name)
255 self.assertEqual(data.log_path.path, new_logs[package.cpvr])
256 self.assertCountEqual(expected, failed_with_logs)
257
258
Alex Kleina2e42c42019-04-17 16:13:19 -0600259 def testOtherBuildScriptFailure(self):
260 """Test build script failure due to non-package emerge error."""
261 tempdir = osutils.TempDir(base_dir=self.tempdir)
262 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
263
Alex Klein38c7d9e2019-05-08 09:31:19 -0600264 result = test_service.BuildTargetUnitTestResult(1, None)
265 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
Alex Kleina2e42c42019-04-17 16:13:19 -0600266
Alex Kleinf2674462019-05-16 16:47:24 -0600267 pkgs = ['foo/bar', 'cat/pkg']
Alex Kleinb64e5f82020-09-23 10:55:31 -0600268 blocklist = [package_info.SplitCPV(p, strict=False) for p in pkgs]
Alex Klein2e91e522022-01-14 09:22:03 -0700269 input_msg = self._GetInput(board='board', empty_sysroot=True,
270 blocklist=blocklist)
Alex Kleina2e42c42019-04-17 16:13:19 -0600271 output_msg = self._GetOutput()
272
Alex Klein231d2da2019-07-22 16:44:45 -0600273 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg,
274 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600275
Alex Klein8cb365a2019-05-15 16:24:53 -0600276 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
Alex Kleina2e42c42019-04-17 16:13:19 -0600277 self.assertFalse(output_msg.failed_packages)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600278
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700279 def testBuildTargetUnitTest(self):
280 """Test BuildTargetUnitTest successful call."""
Navil Perezc0b29a82020-07-07 14:17:48 +0000281 pkgs = ['foo/bar', 'cat/pkg']
Alex Klein18a60af2020-06-11 12:08:47 -0600282 packages = [package_info.SplitCPV(p, strict=False) for p in pkgs]
Alex Klein2e91e522022-01-14 09:22:03 -0700283 input_msg = self._GetInput(board='board', packages=packages)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700284
285 result = test_service.BuildTargetUnitTestResult(0, None)
286 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
287
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700288 response = self._GetOutput()
289 test_controller.BuildTargetUnitTest(input_msg, response,
290 self.api_config)
Alex Klein2e91e522022-01-14 09:22:03 -0700291 self.assertFalse(response.failed_packages)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700292
Evan Hernandez4e388a52019-05-01 12:16:33 -0600293
Sean McAllister17eed8d2021-09-21 10:41:16 -0600294class DockerConstraintsTest(cros_test_lib.MockTestCase):
295 """Tests for Docker argument constraints."""
296
297 def assertValid(self, output):
298 return output is None
299
300 def assertInvalid(self, output):
301 return not self.assertValid(output)
302
303 def testValidDockerTag(self):
304 """Check logic for validating docker tag format."""
305 # pylint: disable=protected-access
306
307 invalid_tags = [
308 '.invalid-tag',
309 '-invalid-tag',
310 'invalid-tag;',
311 'invalid'*100,
312 ]
313
314 for tag in invalid_tags:
315 self.assertInvalid(test_controller._ValidDockerTag(tag))
316
317 valid_tags = [
318 'valid-tag',
319 'valid-tag-',
320 'valid.tag.',
321 ]
322
323 for tag in valid_tags:
324 self.assertValid(test_controller._ValidDockerTag(tag))
325
326
327 def testValidDockerLabelKey(self):
328 """Check logic for validating docker label key format."""
329 # pylint: disable=protected-access
330
331 invalid_keys = [
332 'Invalid-keY',
333 'Invalid-key',
334 'invalid-keY',
335 'iNVALID-KEy',
336 'invalid_key',
337 'invalid-key;',
338 ]
339
340 for key in invalid_keys:
341 self.assertInvalid(test_controller._ValidDockerLabelKey(key))
342
343 valid_keys = [
344 'chromeos.valid-key',
345 'chromeos.valid-key-2',
346 ]
347
348 for key in valid_keys:
349 self.assertValid(test_controller._ValidDockerLabelKey(key))
350
351
Sean McAllister3834fef2021-10-08 15:45:18 -0600352class BuildTestServiceContainers(cros_test_lib.RunCommandTempDirTestCase,
David Wellingc1433c22021-06-25 16:29:48 +0000353 api_config.ApiConfigMixin):
C Shapiro91af1ce2021-06-17 12:42:09 -0500354 """Tests for the BuildTestServiceContainers function."""
355
356 def setUp(self):
357 self.request = test_pb2.BuildTestServiceContainersRequest(
358 chroot={'path': '/path/to/chroot'},
359 build_target={'name': 'build_target'},
David Wellingc1433c22021-06-25 16:29:48 +0000360 version='R93-14033.0.0',
C Shapiro91af1ce2021-06-17 12:42:09 -0500361 )
362
C Shapiro91af1ce2021-06-17 12:42:09 -0500363 def testSuccess(self):
364 """Check passing case with mocked cros_build_lib.run."""
Sean McAllister3834fef2021-10-08 15:45:18 -0600365
366 def ContainerMetadata():
367 """Return mocked ContainerImageInfo proto"""
368 metadata = container_metadata_pb2.ContainerImageInfo()
369 metadata.repository.hostname = 'gcr.io'
370 metadata.repository.project = 'chromeos-bot'
371 metadata.name = 'random-container-name'
372 metadata.digest = (
373 '09b730f8b6a862f9c2705cb3acf3554563325f5fca5c784bf5c98beb2e56f6db')
374 metadata.tags[:] = [
375 'staging-cq-amd64-generic.R96-1.2.3',
376 '8834106026340379089',
377 ]
378 return metadata
379
380 def WriteContainerMetadata(path):
381 """Write json formatted metadata to the given file."""
382 osutils.WriteFile(
383 path,
384 json_format.MessageToJson(ContainerMetadata()),
385 )
386
387 # Write out mocked container metadata to a temporary file.
388 output_path = os.path.join(self.tempdir, 'metadata.jsonpb')
389 self.rc.SetDefaultCmdResult(
390 returncode=0,
391 side_effect=lambda *_, **__: WriteContainerMetadata(output_path)
392 )
393
394 # Patch TempDir so that we always use this test's directory.
395 self.PatchObject(osutils.TempDir, '__enter__', return_value=self.tempdir)
C Shapiro91af1ce2021-06-17 12:42:09 -0500396
397 response = test_pb2.BuildTestServiceContainersResponse()
398 test_controller.BuildTestServiceContainers(
399 self.request,
400 response,
401 self.api_config)
Sean McAllister3834fef2021-10-08 15:45:18 -0600402
403 self.assertTrue(self.rc.called)
C Shapiro91af1ce2021-06-17 12:42:09 -0500404 for result in response.results:
405 self.assertEqual(result.WhichOneof('result'), 'success')
Sean McAllister3834fef2021-10-08 15:45:18 -0600406 self.assertEqual(result.success.image_info, ContainerMetadata())
C Shapiro91af1ce2021-06-17 12:42:09 -0500407
C Shapiro91af1ce2021-06-17 12:42:09 -0500408 def testFailure(self):
409 """Check failure case with mocked cros_build_lib.run."""
410 patch = self.PatchObject(
411 cros_build_lib, 'run',
412 return_value=cros_build_lib.CommandResult(returncode=1))
413
414 response = test_pb2.BuildTestServiceContainersResponse()
415 test_controller.BuildTestServiceContainers(
416 self.request,
417 response,
418 self.api_config)
419 patch.assert_called()
420 for result in response.results:
Derek Beckett2b89c6f2022-05-02 15:21:16 -0700421 if result.name == 'cros-test':
422 self.assertEqual(result.WhichOneof('result'), 'success')
423 else:
424 self.assertEqual(result.WhichOneof('result'), 'failure')
C Shapiro91af1ce2021-06-17 12:42:09 -0500425
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700426class ChromiteUnitTestTest(cros_test_lib.MockTestCase,
427 api_config.ApiConfigMixin):
428 """Tests for the ChromiteInfoTest function."""
429
430 def setUp(self):
431 self.board = 'board'
432 self.chroot_path = '/path/to/chroot'
433
434 def _GetInput(self, chroot_path=None):
435 """Helper to build an input message instance."""
436 proto = test_pb2.ChromiteUnitTestRequest(
437 chroot={'path': chroot_path},
438 )
439 return proto
440
441 def _GetOutput(self):
442 """Helper to get an empty output message instance."""
443 return test_pb2.ChromiteUnitTestResponse()
444
445 def testValidateOnly(self):
446 """Sanity check that a validate only call does not execute any logic."""
447 patch = self.PatchObject(cros_build_lib, 'run')
448
449 input_msg = self._GetInput(chroot_path=self.chroot_path)
450 test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
451 self.validate_only_config)
452 patch.assert_not_called()
453
Michael Mortensen7a860eb2019-12-03 20:25:15 -0700454 def testMockError(self):
455 """Test mock error call does not execute any logic, returns error."""
456 patch = self.PatchObject(cros_build_lib, 'run')
457
458 input_msg = self._GetInput(chroot_path=self.chroot_path)
459 rc = test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
460 self.mock_error_config)
461 patch.assert_not_called()
462 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
463
464 def testMockCall(self):
465 """Test mock call does not execute any logic, returns success."""
466 patch = self.PatchObject(cros_build_lib, 'run')
467
468 input_msg = self._GetInput(chroot_path=self.chroot_path)
469 rc = test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
470 self.mock_call_config)
471 patch.assert_not_called()
472 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
473
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700474 def testChromiteUnitTest(self):
475 """Call ChromiteUnitTest with mocked cros_build_lib.run."""
476 request = self._GetInput(chroot_path=self.chroot_path)
477 patch = self.PatchObject(
478 cros_build_lib, 'run',
479 return_value=cros_build_lib.CommandResult(returncode=0))
480
481 test_controller.ChromiteUnitTest(request, self._GetOutput(),
482 self.api_config)
483 patch.assert_called_once()
484
485
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600486class CrosSigningTestTest(cros_test_lib.RunCommandTestCase,
487 api_config.ApiConfigMixin):
488 """CrosSigningTest tests."""
489
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700490 def setUp(self):
491 self.chroot_path = '/path/to/chroot'
492
493 def _GetInput(self, chroot_path=None):
494 """Helper to build an input message instance."""
495 proto = test_pb2.CrosSigningTestRequest(
496 chroot={'path': chroot_path},
497 )
498 return proto
499
500 def _GetOutput(self):
501 """Helper to get an empty output message instance."""
502 return test_pb2.CrosSigningTestResponse()
503
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600504 def testValidateOnly(self):
505 """Sanity check that a validate only call does not execute any logic."""
506 test_controller.CrosSigningTest(None, None, self.validate_only_config)
507 self.assertFalse(self.rc.call_count)
508
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700509 def testMockCall(self):
510 """Test mock call does not execute any logic, returns success."""
511 rc = test_controller.CrosSigningTest(None, None, self.mock_call_config)
512 self.assertFalse(self.rc.call_count)
513 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
514
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700515 def testCrosSigningTest(self):
516 """Call CrosSigningTest with mocked cros_build_lib.run."""
517 request = self._GetInput(chroot_path=self.chroot_path)
518 patch = self.PatchObject(
519 cros_build_lib, 'run',
520 return_value=cros_build_lib.CommandResult(returncode=0))
521
522 test_controller.CrosSigningTest(request, self._GetOutput(),
523 self.api_config)
524 patch.assert_called_once()
525
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600526
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600527class SimpleChromeWorkflowTestTest(cros_test_lib.MockTestCase,
528 api_config.ApiConfigMixin):
529 """Test the SimpleChromeWorkflowTest endpoint."""
530
531 @staticmethod
532 def _Output():
533 return test_pb2.SimpleChromeWorkflowTestResponse()
534
David Wellingc1433c22021-06-25 16:29:48 +0000535 def _Input(self,
536 sysroot_path=None,
537 build_target=None,
538 chrome_root=None,
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600539 goma_config=None):
540 proto = test_pb2.SimpleChromeWorkflowTestRequest()
541 if sysroot_path:
542 proto.sysroot.path = sysroot_path
543 if build_target:
544 proto.sysroot.build_target.name = build_target
545 if chrome_root:
546 proto.chrome_root = chrome_root
547 if goma_config:
548 proto.goma_config = goma_config
549 return proto
550
551 def setUp(self):
552 self.chrome_path = 'path/to/chrome'
553 self.sysroot_dir = 'build/board'
554 self.build_target = 'amd64'
555 self.mock_simple_chrome_workflow_test = self.PatchObject(
556 test_service, 'SimpleChromeWorkflowTest')
557
558 def testMissingBuildTarget(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700559 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600560 input_proto = self._Input(build_target=None, sysroot_path='/sysroot/dir',
561 chrome_root='/chrome/path')
562 with self.assertRaises(cros_build_lib.DieSystemExit):
563 test_controller.SimpleChromeWorkflowTest(input_proto, None,
564 self.api_config)
565
566 def testMissingSysrootPath(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700567 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600568 input_proto = self._Input(build_target='board', sysroot_path=None,
569 chrome_root='/chrome/path')
570 with self.assertRaises(cros_build_lib.DieSystemExit):
571 test_controller.SimpleChromeWorkflowTest(input_proto, None,
572 self.api_config)
573
574 def testMissingChromeRoot(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700575 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600576 input_proto = self._Input(build_target='board', sysroot_path='/sysroot/dir',
577 chrome_root=None)
578 with self.assertRaises(cros_build_lib.DieSystemExit):
579 test_controller.SimpleChromeWorkflowTest(input_proto, None,
580 self.api_config)
581
582 def testSimpleChromeWorkflowTest(self):
583 """Call SimpleChromeWorkflowTest with valid args and temp dir."""
584 request = self._Input(sysroot_path='sysroot_path', build_target='board',
585 chrome_root='/path/to/chrome')
586 response = self._Output()
587
588 test_controller.SimpleChromeWorkflowTest(request, response, self.api_config)
589 self.mock_simple_chrome_workflow_test.assert_called()
590
591 def testValidateOnly(self):
592 request = self._Input(sysroot_path='sysroot_path', build_target='board',
593 chrome_root='/path/to/chrome')
594 test_controller.SimpleChromeWorkflowTest(request, self._Output(),
595 self.validate_only_config)
596 self.mock_simple_chrome_workflow_test.assert_not_called()
597
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700598 def testMockCall(self):
599 """Test mock call does not execute any logic, returns success."""
600 patch = self.mock_simple_chrome_workflow_test = self.PatchObject(
601 test_service, 'SimpleChromeWorkflowTest')
602
603 request = self._Input(sysroot_path='sysroot_path', build_target='board',
604 chrome_root='/path/to/chrome')
605 rc = test_controller.SimpleChromeWorkflowTest(request, self._Output(),
606 self.mock_call_config)
607 patch.assert_not_called()
608 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
609
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600610
Alex Klein231d2da2019-07-22 16:44:45 -0600611class VmTestTest(cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin):
Evan Hernandez4e388a52019-05-01 12:16:33 -0600612 """Test the VmTest endpoint."""
613
614 def _GetInput(self, **kwargs):
615 values = dict(
616 build_target=common_pb2.BuildTarget(name='target'),
Alex Klein311b8022019-06-05 16:00:07 -0600617 vm_path=common_pb2.Path(path='/path/to/image.bin',
618 location=common_pb2.Path.INSIDE),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600619 test_harness=test_pb2.VmTestRequest.TAST,
620 vm_tests=[test_pb2.VmTestRequest.VmTest(pattern='suite')],
621 ssh_options=test_pb2.VmTestRequest.SshOptions(
Alex Klein231d2da2019-07-22 16:44:45 -0600622 port=1234, private_key_path={'path': '/path/to/id_rsa',
Alex Kleinaa705412019-06-04 15:00:30 -0600623 'location': common_pb2.Path.INSIDE}),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600624 )
625 values.update(kwargs)
626 return test_pb2.VmTestRequest(**values)
627
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700628 def _Output(self):
629 return test_pb2.VmTestResponse()
630
Alex Klein231d2da2019-07-22 16:44:45 -0600631 def testValidateOnly(self):
632 """Sanity check that a validate only call does not execute any logic."""
633 test_controller.VmTest(self._GetInput(), None, self.validate_only_config)
634 self.assertEqual(0, self.rc.call_count)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600635
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700636 def testMockCall(self):
637 """Test mock call does not execute any logic."""
638 patch = self.PatchObject(cros_build_lib, 'run')
639
640 request = self._GetInput()
641 response = self._Output()
642 # VmTest does not return a value, checking mocked value is flagged by lint.
643 test_controller.VmTest(request, response, self.mock_call_config)
644 patch.assert_not_called()
645
Evan Hernandez4e388a52019-05-01 12:16:33 -0600646 def testTastAllOptions(self):
647 """Test VmTest for Tast with all options set."""
Alex Klein231d2da2019-07-22 16:44:45 -0600648 test_controller.VmTest(self._GetInput(), None, self.api_config)
649 self.assertCommandContains([
Achuith Bhandarkara9e9c3d2019-05-22 13:56:11 -0700650 'cros_run_test', '--debug', '--no-display', '--copy-on-write',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600651 '--board', 'target',
652 '--image-path', '/path/to/image.bin',
653 '--tast', 'suite',
654 '--ssh-port', '1234',
655 '--private-key', '/path/to/id_rsa',
656 ])
657
658 def testAutotestAllOptions(self):
659 """Test VmTest for Autotest with all options set."""
660 input_proto = self._GetInput(test_harness=test_pb2.VmTestRequest.AUTOTEST)
Alex Klein231d2da2019-07-22 16:44:45 -0600661 test_controller.VmTest(input_proto, None, self.api_config)
662 self.assertCommandContains([
Achuith Bhandarkara9e9c3d2019-05-22 13:56:11 -0700663 'cros_run_test', '--debug', '--no-display', '--copy-on-write',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600664 '--board', 'target',
665 '--image-path', '/path/to/image.bin',
666 '--autotest', 'suite',
667 '--ssh-port', '1234',
668 '--private-key', '/path/to/id_rsa',
Greg Edelstondcb0e912020-08-31 11:09:40 -0600669 '--test_that-args=--allow-chrome-crashes',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600670 ])
671
672 def testMissingBuildTarget(self):
673 """Test VmTest dies when build_target not set."""
674 input_proto = self._GetInput(build_target=None)
675 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600676 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600677
678 def testMissingVmImage(self):
679 """Test VmTest dies when vm_image not set."""
Alex Klein311b8022019-06-05 16:00:07 -0600680 input_proto = self._GetInput(vm_path=None)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600681 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600682 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600683
684 def testMissingTestHarness(self):
685 """Test VmTest dies when test_harness not specified."""
686 input_proto = self._GetInput(
687 test_harness=test_pb2.VmTestRequest.UNSPECIFIED)
688 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600689 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600690
691 def testMissingVmTests(self):
692 """Test VmTest dies when vm_tests not set."""
693 input_proto = self._GetInput(vm_tests=[])
694 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600695 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600696
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700697 def testVmTest(self):
698 """Call VmTest with valid args and temp dir."""
699 request = self._GetInput()
700 response = self._Output()
701 patch = self.PatchObject(
702 cros_build_lib, 'run',
703 return_value=cros_build_lib.CommandResult(returncode=0))
704
705 test_controller.VmTest(request, response, self.api_config)
706 patch.assert_called()
707
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600708
Alex Klein231d2da2019-07-22 16:44:45 -0600709class MoblabVmTestTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600710 """Test the MoblabVmTest endpoint."""
711
712 @staticmethod
713 def _Payload(path):
714 return test_pb2.MoblabVmTestRequest.Payload(
715 path=common_pb2.Path(path=path))
716
717 @staticmethod
718 def _Output():
719 return test_pb2.MoblabVmTestResponse()
720
721 def _Input(self):
722 return test_pb2.MoblabVmTestRequest(
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600723 chroot=common_pb2.Chroot(path=self.chroot_dir),
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600724 image_payload=self._Payload(self.image_payload_dir),
725 cache_payloads=[self._Payload(self.autotest_payload_dir)])
726
727 def setUp(self):
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600728 self.chroot_dir = '/chroot'
729 self.chroot_tmp_dir = '/chroot/tmp'
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600730 self.image_payload_dir = '/payloads/image'
731 self.autotest_payload_dir = '/payloads/autotest'
732 self.builder = 'moblab-generic-vm/R12-3.4.5-67.890'
733 self.image_cache_dir = '/mnt/moblab/cache'
734 self.image_mount_dir = '/mnt/image'
735
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600736 self.PatchObject(chroot_lib.Chroot, 'tempdir', osutils.TempDir)
Evan Hernandez655e8042019-06-13 12:50:44 -0600737
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600738 self.mock_create_moblab_vms = self.PatchObject(
739 test_service, 'CreateMoblabVm')
740 self.mock_prepare_moblab_vm_image_cache = self.PatchObject(
741 test_service, 'PrepareMoblabVmImageCache',
742 return_value=self.image_cache_dir)
743 self.mock_run_moblab_vm_tests = self.PatchObject(
744 test_service, 'RunMoblabVmTest')
745 self.mock_validate_moblab_vm_tests = self.PatchObject(
746 test_service, 'ValidateMoblabVmTest')
747
748 @contextlib.contextmanager
Alex Klein38c7d9e2019-05-08 09:31:19 -0600749 def MockLoopbackPartitions(*_args, **_kwargs):
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600750 mount = mock.MagicMock()
Evan Hernandez40ee7452019-06-13 12:51:43 -0600751 mount.Mount.return_value = [self.image_mount_dir]
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600752 yield mount
Alex Klein231d2da2019-07-22 16:44:45 -0600753
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600754 self.PatchObject(image_lib, 'LoopbackPartitions', MockLoopbackPartitions)
755
Alex Klein231d2da2019-07-22 16:44:45 -0600756 def testValidateOnly(self):
757 """Sanity check that a validate only call does not execute any logic."""
758 test_controller.MoblabVmTest(self._Input(), self._Output(),
759 self.validate_only_config)
760 self.mock_create_moblab_vms.assert_not_called()
761
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700762 def testMockCall(self):
763 """Test mock call does not execute any logic."""
764 patch = self.PatchObject(key_value_store, 'LoadFile')
765
766 # MoblabVmTest does not return a value, checking mocked value is flagged by
767 # lint.
768 test_controller.MoblabVmTest(self._Input(), self._Output(),
769 self.mock_call_config)
770 patch.assert_not_called()
771
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600772 def testImageContainsBuilder(self):
773 """MoblabVmTest calls service with correct args."""
774 request = self._Input()
775 response = self._Output()
776
777 self.PatchObject(
Mike Frysingere652ba12019-09-08 00:57:43 -0400778 key_value_store, 'LoadFile',
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600779 return_value={cros_set_lsb_release.LSB_KEY_BUILDER_PATH: self.builder})
780
Alex Klein231d2da2019-07-22 16:44:45 -0600781 test_controller.MoblabVmTest(request, response, self.api_config)
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600782
783 self.assertEqual(
784 self.mock_create_moblab_vms.call_args_list,
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600785 [mock.call(mock.ANY, self.chroot_dir, self.image_payload_dir)])
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600786 self.assertEqual(
787 self.mock_prepare_moblab_vm_image_cache.call_args_list,
788 [mock.call(mock.ANY, self.builder, [self.autotest_payload_dir])])
789 self.assertEqual(
790 self.mock_run_moblab_vm_tests.call_args_list,
Evan Hernandez655e8042019-06-13 12:50:44 -0600791 [mock.call(mock.ANY, mock.ANY, self.builder, self.image_cache_dir,
792 mock.ANY)])
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600793 self.assertEqual(
794 self.mock_validate_moblab_vm_tests.call_args_list,
795 [mock.call(mock.ANY)])
796
797 def testImageMissingBuilder(self):
798 """MoblabVmTest dies when builder path not found in lsb-release."""
799 request = self._Input()
800 response = self._Output()
801
Mike Frysingere652ba12019-09-08 00:57:43 -0400802 self.PatchObject(key_value_store, 'LoadFile', return_value={})
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600803
804 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600805 test_controller.MoblabVmTest(request, response, self.api_config)
David Wellingc1433c22021-06-25 16:29:48 +0000806
807
808class GetArtifactsTest(cros_test_lib.MockTempDirTestCase):
809 """Test GetArtifacts."""
810
811 CODE_COVERAGE_LLVM_ARTIFACT_TYPE = (
812 common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_LLVM_JSON
813 )
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600814 UNIT_TEST_ARTIFACT_TYPE = (
815 common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS
816 )
David Wellingc1433c22021-06-25 16:29:48 +0000817
818 def setUp(self):
819 """Set up the class for tests."""
820 chroot_dir = os.path.join(self.tempdir, 'chroot')
821 osutils.SafeMakedirs(chroot_dir)
822 osutils.SafeMakedirs(os.path.join(chroot_dir, 'tmp'))
823 self.chroot = chroot_lib.Chroot(chroot_dir)
824
825 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
826 osutils.SafeMakedirs(sysroot_path)
827 self.sysroot = sysroot_lib.Sysroot(sysroot_path)
828
Jack Neusc9707c32021-07-23 21:48:54 +0000829 self.build_target = build_target_lib.BuildTarget('board')
830
David Wellingc1433c22021-06-25 16:29:48 +0000831 def testReturnsEmptyListWhenNoOutputArtifactsProvided(self):
832 """Test empty list is returned when there are no output_artifacts."""
833 result = test_controller.GetArtifacts(
834 common_pb2.ArtifactsByService.Test(output_artifacts=[]),
Jack Neusc9707c32021-07-23 21:48:54 +0000835 self.chroot, self.sysroot, self.build_target, self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000836
837 self.assertEqual(len(result), 0)
838
839 def testShouldCallBundleCodeCoverageLlvmJsonForEachValidArtifact(self):
840 """Test BundleCodeCoverageLlvmJson is called on each valid artifact."""
Sean McAllister17eed8d2021-09-21 10:41:16 -0600841 BundleCodeCoverageLlvmJson_mock = (
842 self.PatchObject(
843 test_service,
844 'BundleCodeCoverageLlvmJson',
845 return_value='test'))
David Wellingc1433c22021-06-25 16:29:48 +0000846
847 test_controller.GetArtifacts(
848 common_pb2.ArtifactsByService.Test(output_artifacts=[
849 # Valid
850 common_pb2.ArtifactsByService.Test.ArtifactInfo(
851 artifact_types=[
852 self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE
853 ]
854 ),
855
856 # Invalid
857 common_pb2.ArtifactsByService.Test.ArtifactInfo(
858 artifact_types=[
859 common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS
860 ]
861 ),
862 ]),
Jack Neusc9707c32021-07-23 21:48:54 +0000863 self.chroot, self.sysroot, self.build_target, self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000864
865 BundleCodeCoverageLlvmJson_mock.assert_called_once()
866
867 def testShouldReturnValidResult(self):
868 """Test result contains paths and code_coverage_llvm_json type."""
869 self.PatchObject(test_service, 'BundleCodeCoverageLlvmJson',
Sean McAllister17eed8d2021-09-21 10:41:16 -0600870 return_value='test')
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600871 self.PatchObject(test_service, 'BuildTargetUnitTestTarball',
Sean McAllister17eed8d2021-09-21 10:41:16 -0600872 return_value='unit_tests.tar')
David Wellingc1433c22021-06-25 16:29:48 +0000873
874 result = test_controller.GetArtifacts(
875 common_pb2.ArtifactsByService.Test(output_artifacts=[
876 # Valid
877 common_pb2.ArtifactsByService.Test.ArtifactInfo(
878 artifact_types=[
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600879 self.UNIT_TEST_ARTIFACT_TYPE
880 ]
881 ),
882 common_pb2.ArtifactsByService.Test.ArtifactInfo(
883 artifact_types=[
David Wellingc1433c22021-06-25 16:29:48 +0000884 self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE
885 ]
886 ),
887 ]),
Jack Neusc9707c32021-07-23 21:48:54 +0000888 self.chroot, self.sysroot, self.build_target, self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000889
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600890 self.assertEqual(result[0]['paths'], ['unit_tests.tar'])
891 self.assertEqual(result[0]['type'], self.UNIT_TEST_ARTIFACT_TYPE)
892 self.assertEqual(result[1]['paths'], ['test'])
893 self.assertEqual(result[1]['type'], self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE)