blob: 0fcb715efb07bfecbec6fe1934b6dfb3a1817187 [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 Frysinger40443592022-05-05 13:03:40 -040011from typing import Union
Mike Frysinger166fea02021-02-12 05:30:33 -050012from unittest import mock
Mike Frysingeref94e4c2020-02-10 23:59:54 -050013
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040014from chromite.third_party.google.protobuf import json_format
15
Alex Klein231d2da2019-07-22 16:44:45 -060016from chromite.api import api_config
Alex Klein8cb365a2019-05-15 16:24:53 -060017from chromite.api import controller
Lizzy Presland4feb2372022-01-20 05:16:30 +000018from chromite.api.controller import controller_util
Alex Kleina2e42c42019-04-17 16:13:19 -060019from chromite.api.controller import test as test_controller
20from chromite.api.gen.chromite.api import test_pb2
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040021from chromite.api.gen.chromiumos import common_pb2
Sean McAllister3834fef2021-10-08 15:45:18 -060022from chromite.api.gen.chromiumos.build.api import container_metadata_pb2
Jack Neusc9707c32021-07-23 21:48:54 +000023from chromite.lib import build_target_lib
Evan Hernandeze1e05d32019-07-19 12:32:18 -060024from chromite.lib import chroot_lib
Alex Kleina2e42c42019-04-17 16:13:19 -060025from chromite.lib import cros_build_lib
26from chromite.lib import cros_test_lib
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -060027from chromite.lib import image_lib
Alex Kleina2e42c42019-04-17 16:13:19 -060028from chromite.lib import osutils
David Wellingc1433c22021-06-25 16:29:48 +000029from chromite.lib import sysroot_lib
Alex Klein18a60af2020-06-11 12:08:47 -060030from chromite.lib.parser import package_info
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -060031from chromite.scripts import cros_set_lsb_release
32from chromite.service import test as test_service
Mike Frysingere652ba12019-09-08 00:57:43 -040033from chromite.utils import key_value_store
Alex Kleina2e42c42019-04-17 16:13:19 -060034
35
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070036class DebugInfoTestTest(cros_test_lib.MockTempDirTestCase,
37 api_config.ApiConfigMixin):
38 """Tests for the DebugInfoTest function."""
39
40 def setUp(self):
41 self.board = 'board'
42 self.chroot_path = os.path.join(self.tempdir, 'chroot')
43 self.sysroot_path = '/build/board'
44 self.full_sysroot_path = os.path.join(self.chroot_path,
45 self.sysroot_path.lstrip(os.sep))
46 osutils.SafeMakedirs(self.full_sysroot_path)
47
48 def _GetInput(self, sysroot_path=None, build_target=None):
49 """Helper to build an input message instance."""
50 proto = test_pb2.DebugInfoTestRequest()
51 if sysroot_path:
52 proto.sysroot.path = sysroot_path
53 if build_target:
54 proto.sysroot.build_target.name = build_target
55 return proto
56
57 def _GetOutput(self):
58 """Helper to get an empty output message instance."""
59 return test_pb2.DebugInfoTestResponse()
60
61 def testValidateOnly(self):
62 """Sanity check that a validate only call does not execute any logic."""
63 patch = self.PatchObject(test_service, 'DebugInfoTest')
64 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
65 test_controller.DebugInfoTest(input_msg, self._GetOutput(),
66 self.validate_only_config)
67 patch.assert_not_called()
68
Michael Mortensen85d38402019-12-12 09:50:29 -070069 def testMockError(self):
70 """Test mock error call does not execute any logic, returns error."""
71 patch = self.PatchObject(test_service, 'DebugInfoTest')
72
73 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
74 rc = test_controller.DebugInfoTest(input_msg, self._GetOutput(),
75 self.mock_error_config)
76 patch.assert_not_called()
77 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
78
79 def testMockCall(self):
80 """Test mock call does not execute any logic, returns success."""
81 patch = self.PatchObject(test_service, 'DebugInfoTest')
82
83 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
84 rc = test_controller.DebugInfoTest(input_msg, self._GetOutput(),
85 self.mock_call_config)
86 patch.assert_not_called()
87 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
88
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070089 def testNoBuildTargetNoSysrootFails(self):
90 """Test missing build target name and sysroot path fails."""
91 input_msg = self._GetInput()
92 output_msg = self._GetOutput()
93 with self.assertRaises(cros_build_lib.DieSystemExit):
94 test_controller.DebugInfoTest(input_msg, output_msg, self.api_config)
95
96 def testDebugInfoTest(self):
97 """Call DebugInfoTest with valid sysroot_path."""
98 request = self._GetInput(sysroot_path=self.full_sysroot_path)
99
100 test_controller.DebugInfoTest(request, self._GetOutput(), self.api_config)
101
102
Alex Klein231d2da2019-07-22 16:44:45 -0600103class BuildTargetUnitTestTest(cros_test_lib.MockTempDirTestCase,
104 api_config.ApiConfigMixin):
Alex Kleina2e42c42019-04-17 16:13:19 -0600105 """Tests for the UnitTest function."""
106
Lizzy Presland4feb2372022-01-20 05:16:30 +0000107 def setUp(self):
108 # Set up portage log directory.
109 self.sysroot = os.path.join(self.tempdir, 'build', 'board')
110 osutils.SafeMakedirs(self.sysroot)
111 self.target_sysroot = sysroot_lib.Sysroot(self.sysroot)
112 self.portage_dir = os.path.join(self.tempdir, 'portage_logdir')
113 self.PatchObject(
114 sysroot_lib.Sysroot, 'portage_logdir', new=self.portage_dir)
115 osutils.SafeMakedirs(self.portage_dir)
116
Navil Perezc0b29a82020-07-07 14:17:48 +0000117 def _GetInput(self,
118 board=None,
119 result_path=None,
120 chroot_path=None,
121 cache_dir=None,
122 empty_sysroot=None,
123 packages=None,
Alex Kleinb64e5f82020-09-23 10:55:31 -0600124 blocklist=None):
Alex Kleina2e42c42019-04-17 16:13:19 -0600125 """Helper to build an input message instance."""
Navil Perezc0b29a82020-07-07 14:17:48 +0000126 formatted_packages = []
127 for pkg in packages or []:
128 formatted_packages.append({
129 'category': pkg.category,
130 'package_name': pkg.package
131 })
Alex Kleinb64e5f82020-09-23 10:55:31 -0600132 formatted_blocklist = []
133 for pkg in blocklist or []:
Alex Klein4f215432022-05-23 10:41:14 -0600134 formatted_blocklist.append({
135 'category': pkg.category,
136 'package_name': pkg.package
137 })
Alex Kleinf2674462019-05-16 16:47:24 -0600138
Mike Frysinger3bb61cb2022-04-14 16:07:44 -0400139 # Protobufs can't handle Path objects.
140 if isinstance(result_path, Path):
141 result_path = str(result_path)
142
Alex Kleina2e42c42019-04-17 16:13:19 -0600143 return test_pb2.BuildTargetUnitTestRequest(
Alex Klein4f215432022-05-23 10:41:14 -0600144 build_target={'name': board},
145 result_path=result_path,
146 chroot={
147 'path': chroot_path,
148 'cache_dir': cache_dir
149 },
Alex Kleinf2674462019-05-16 16:47:24 -0600150 flags={'empty_sysroot': empty_sysroot},
Alex Klein64ac34c2020-09-23 10:21:33 -0600151 packages=formatted_packages,
Alex Klein157caf42021-07-01 14:36:43 -0600152 package_blocklist=formatted_blocklist,
Alex Kleina2e42c42019-04-17 16:13:19 -0600153 )
154
155 def _GetOutput(self):
156 """Helper to get an empty output message instance."""
157 return test_pb2.BuildTargetUnitTestResponse()
158
Alex Klein4f215432022-05-23 10:41:14 -0600159 def _CreatePortageLogFile(self, log_path: Union[str, os.PathLike],
Mike Frysinger40443592022-05-05 13:03:40 -0400160 pkg_info: package_info.PackageInfo,
161 timestamp: datetime.datetime) -> str:
Lizzy Presland4feb2372022-01-20 05:16:30 +0000162 """Creates a log file for testing for individual packages built by Portage.
163
164 Args:
Mike Frysinger40443592022-05-05 13:03:40 -0400165 log_path: The PORTAGE_LOGDIR path.
166 pkg_info: name components for log file.
167 timestamp: Timestamp used to name the file.
Lizzy Presland4feb2372022-01-20 05:16:30 +0000168 """
169 path = os.path.join(log_path,
170 f'{pkg_info.category}:{pkg_info.pvr}:' \
171 f'{timestamp.strftime("%Y%m%d-%H%M%S")}.log')
Alex Klein4f215432022-05-23 10:41:14 -0600172 osutils.WriteFile(
173 path, f'Test log file for package {pkg_info.category}/'
174 f'{pkg_info.package} written to {path}')
Lizzy Presland4feb2372022-01-20 05:16:30 +0000175 return path
176
Alex Klein231d2da2019-07-22 16:44:45 -0600177 def testValidateOnly(self):
178 """Sanity check that a validate only call does not execute any logic."""
179 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
180
181 input_msg = self._GetInput(board='board', result_path=self.tempdir)
182 test_controller.BuildTargetUnitTest(input_msg, self._GetOutput(),
183 self.validate_only_config)
184 patch.assert_not_called()
185
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700186 def testMockCall(self):
187 """Test that a mock call does not execute logic, returns mocked value."""
188 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
189
190 input_msg = self._GetInput(board='board', result_path=self.tempdir)
191 response = self._GetOutput()
192 test_controller.BuildTargetUnitTest(input_msg, response,
193 self.mock_call_config)
194 patch.assert_not_called()
195 self.assertEqual(response.tarball_path,
196 os.path.join(input_msg.result_path, 'unit_tests.tar'))
197
198 def testMockError(self):
Michael Mortensen85d38402019-12-12 09:50:29 -0700199 """Test that a mock error does not execute logic, returns error."""
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700200 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
201
202 input_msg = self._GetInput(board='board', result_path=self.tempdir)
203 response = self._GetOutput()
204 rc = test_controller.BuildTargetUnitTest(input_msg, response,
205 self.mock_error_config)
206 patch.assert_not_called()
207 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
Lizzy Presland239459a2022-05-05 22:03:19 +0000208 self.assertTrue(response.failed_package_data)
209 self.assertEqual(response.failed_package_data[0].name.category, 'foo')
210 self.assertEqual(response.failed_package_data[0].name.package_name, 'bar')
211 self.assertEqual(response.failed_package_data[1].name.category, 'cat')
212 self.assertEqual(response.failed_package_data[1].name.package_name, 'pkg')
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700213
Alex Klein64ac34c2020-09-23 10:21:33 -0600214 def testInvalidPackageFails(self):
215 """Test missing result path fails."""
216 # Missing result_path.
217 pkg = package_info.PackageInfo(package='bar')
Alex Klein4f215432022-05-23 10:41:14 -0600218 input_msg = self._GetInput(
219 board='board', result_path=self.tempdir, packages=[pkg])
Alex Klein64ac34c2020-09-23 10:21:33 -0600220 output_msg = self._GetOutput()
221 with self.assertRaises(cros_build_lib.DieSystemExit):
222 test_controller.BuildTargetUnitTest(input_msg, output_msg,
223 self.api_config)
224
Alex Kleina2e42c42019-04-17 16:13:19 -0600225 def testPackageBuildFailure(self):
226 """Test handling of raised BuildPackageFailure."""
227 tempdir = osutils.TempDir(base_dir=self.tempdir)
228 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
229
Lizzy Presland4feb2372022-01-20 05:16:30 +0000230 pkgs = ['cat/pkg-1.0-r1', 'foo/bar-2.0-r1']
231 cpvrs = [package_info.parse(pkg) for pkg in pkgs]
Alex Kleina2e42c42019-04-17 16:13:19 -0600232 expected = [('cat', 'pkg'), ('foo', 'bar')]
Lizzy Presland4feb2372022-01-20 05:16:30 +0000233 new_logs = {}
234 for i, pkg in enumerate(pkgs):
235 self._CreatePortageLogFile(self.portage_dir, cpvrs[i],
236 datetime.datetime(2021, 6, 9, 13, 37, 0))
Alex Klein4f215432022-05-23 10:41:14 -0600237 new_logs[pkg] = self._CreatePortageLogFile(
238 self.portage_dir, cpvrs[i], datetime.datetime(2021, 6, 9, 16, 20, 0))
Alex Kleina2e42c42019-04-17 16:13:19 -0600239
Alex Klein38c7d9e2019-05-08 09:31:19 -0600240 result = test_service.BuildTargetUnitTestResult(1, None)
Alex Kleinea0c89e2021-09-09 15:17:35 -0600241 result.failed_pkgs = [package_info.parse(p) for p in pkgs]
Alex Klein38c7d9e2019-05-08 09:31:19 -0600242 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
Alex Kleina2e42c42019-04-17 16:13:19 -0600243
244 input_msg = self._GetInput(board='board', result_path=self.tempdir)
245 output_msg = self._GetOutput()
246
Alex Klein231d2da2019-07-22 16:44:45 -0600247 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg,
248 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600249
Alex Klein8cb365a2019-05-15 16:24:53 -0600250 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
Lizzy Presland4feb2372022-01-20 05:16:30 +0000251 self.assertTrue(output_msg.failed_package_data)
Alex Kleina2e42c42019-04-17 16:13:19 -0600252
Lizzy Presland4feb2372022-01-20 05:16:30 +0000253 failed_with_logs = []
254 for data in output_msg.failed_package_data:
255 failed_with_logs.append((data.name.category, data.name.package_name))
256 package = controller_util.deserialize_package_info(data.name)
257 self.assertEqual(data.log_path.path, new_logs[package.cpvr])
258 self.assertCountEqual(expected, failed_with_logs)
259
Alex Kleina2e42c42019-04-17 16:13:19 -0600260 def testOtherBuildScriptFailure(self):
261 """Test build script failure due to non-package emerge error."""
262 tempdir = osutils.TempDir(base_dir=self.tempdir)
263 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
264
Alex Klein38c7d9e2019-05-08 09:31:19 -0600265 result = test_service.BuildTargetUnitTestResult(1, None)
266 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
Alex Kleina2e42c42019-04-17 16:13:19 -0600267
Alex Kleinf2674462019-05-16 16:47:24 -0600268 pkgs = ['foo/bar', 'cat/pkg']
Alex Kleinb64e5f82020-09-23 10:55:31 -0600269 blocklist = [package_info.SplitCPV(p, strict=False) for p in pkgs]
Alex Klein4f215432022-05-23 10:41:14 -0600270 input_msg = self._GetInput(
271 board='board', empty_sysroot=True, blocklist=blocklist)
Alex Kleina2e42c42019-04-17 16:13:19 -0600272 output_msg = self._GetOutput()
273
Alex Klein231d2da2019-07-22 16:44:45 -0600274 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg,
275 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600276
Alex Klein8cb365a2019-05-15 16:24:53 -0600277 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
Lizzy Presland239459a2022-05-05 22:03:19 +0000278 self.assertFalse(output_msg.failed_package_data)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600279
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700280 def testBuildTargetUnitTest(self):
281 """Test BuildTargetUnitTest successful call."""
Navil Perezc0b29a82020-07-07 14:17:48 +0000282 pkgs = ['foo/bar', 'cat/pkg']
Alex Klein18a60af2020-06-11 12:08:47 -0600283 packages = [package_info.SplitCPV(p, strict=False) for p in pkgs]
Alex Klein2e91e522022-01-14 09:22:03 -0700284 input_msg = self._GetInput(board='board', packages=packages)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700285
286 result = test_service.BuildTargetUnitTestResult(0, None)
287 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
288
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700289 response = self._GetOutput()
Alex Klein4f215432022-05-23 10:41:14 -0600290 test_controller.BuildTargetUnitTest(input_msg, response, self.api_config)
Lizzy Presland239459a2022-05-05 22:03:19 +0000291 self.assertFalse(response.failed_package_data)
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;',
Alex Klein4f215432022-05-23 10:41:14 -0600311 'invalid' * 100,
Sean McAllister17eed8d2021-09-21 10:41:16 -0600312 ]
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
Sean McAllister17eed8d2021-09-21 10:41:16 -0600326 def testValidDockerLabelKey(self):
327 """Check logic for validating docker label key format."""
328 # pylint: disable=protected-access
329
330 invalid_keys = [
331 'Invalid-keY',
332 'Invalid-key',
333 'invalid-keY',
334 'iNVALID-KEy',
335 'invalid_key',
336 'invalid-key;',
337 ]
338
339 for key in invalid_keys:
340 self.assertInvalid(test_controller._ValidDockerLabelKey(key))
341
342 valid_keys = [
343 'chromeos.valid-key',
344 'chromeos.valid-key-2',
345 ]
346
347 for key in valid_keys:
348 self.assertValid(test_controller._ValidDockerLabelKey(key))
349
350
Sean McAllister3834fef2021-10-08 15:45:18 -0600351class BuildTestServiceContainers(cros_test_lib.RunCommandTempDirTestCase,
David Wellingc1433c22021-06-25 16:29:48 +0000352 api_config.ApiConfigMixin):
C Shapiro91af1ce2021-06-17 12:42:09 -0500353 """Tests for the BuildTestServiceContainers function."""
354
355 def setUp(self):
356 self.request = test_pb2.BuildTestServiceContainersRequest(
357 chroot={'path': '/path/to/chroot'},
358 build_target={'name': 'build_target'},
David Wellingc1433c22021-06-25 16:29:48 +0000359 version='R93-14033.0.0',
C Shapiro91af1ce2021-06-17 12:42:09 -0500360 )
361
C Shapiro91af1ce2021-06-17 12:42:09 -0500362 def testSuccess(self):
363 """Check passing case with mocked cros_build_lib.run."""
Sean McAllister3834fef2021-10-08 15:45:18 -0600364
365 def ContainerMetadata():
366 """Return mocked ContainerImageInfo proto"""
367 metadata = container_metadata_pb2.ContainerImageInfo()
368 metadata.repository.hostname = 'gcr.io'
369 metadata.repository.project = 'chromeos-bot'
370 metadata.name = 'random-container-name'
371 metadata.digest = (
372 '09b730f8b6a862f9c2705cb3acf3554563325f5fca5c784bf5c98beb2e56f6db')
373 metadata.tags[:] = [
374 'staging-cq-amd64-generic.R96-1.2.3',
375 '8834106026340379089',
376 ]
377 return metadata
378
379 def WriteContainerMetadata(path):
380 """Write json formatted metadata to the given file."""
381 osutils.WriteFile(
382 path,
383 json_format.MessageToJson(ContainerMetadata()),
384 )
385
386 # Write out mocked container metadata to a temporary file.
387 output_path = os.path.join(self.tempdir, 'metadata.jsonpb')
388 self.rc.SetDefaultCmdResult(
389 returncode=0,
Alex Klein4f215432022-05-23 10:41:14 -0600390 side_effect=lambda *_, **__: WriteContainerMetadata(output_path))
Sean McAllister3834fef2021-10-08 15:45:18 -0600391
392 # Patch TempDir so that we always use this test's directory.
393 self.PatchObject(osutils.TempDir, '__enter__', return_value=self.tempdir)
C Shapiro91af1ce2021-06-17 12:42:09 -0500394
395 response = test_pb2.BuildTestServiceContainersResponse()
Alex Klein4f215432022-05-23 10:41:14 -0600396 test_controller.BuildTestServiceContainers(self.request, response,
397 self.api_config)
Sean McAllister3834fef2021-10-08 15:45:18 -0600398
399 self.assertTrue(self.rc.called)
C Shapiro91af1ce2021-06-17 12:42:09 -0500400 for result in response.results:
401 self.assertEqual(result.WhichOneof('result'), 'success')
Sean McAllister3834fef2021-10-08 15:45:18 -0600402 self.assertEqual(result.success.image_info, ContainerMetadata())
C Shapiro91af1ce2021-06-17 12:42:09 -0500403
C Shapiro91af1ce2021-06-17 12:42:09 -0500404 def testFailure(self):
405 """Check failure case with mocked cros_build_lib.run."""
406 patch = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600407 cros_build_lib,
408 'run',
C Shapiro91af1ce2021-06-17 12:42:09 -0500409 return_value=cros_build_lib.CommandResult(returncode=1))
410
411 response = test_pb2.BuildTestServiceContainersResponse()
Alex Klein4f215432022-05-23 10:41:14 -0600412 test_controller.BuildTestServiceContainers(self.request, response,
413 self.api_config)
C Shapiro91af1ce2021-06-17 12:42:09 -0500414 patch.assert_called()
415 for result in response.results:
Derek Beckett27eaa162022-05-09 10:42:53 -0700416 self.assertEqual(result.WhichOneof('result'), 'failure')
Derek Beckett344b5a82022-05-09 17:21:45 -0700417 self.assertEqual(result.name, 'Service Builder')
C Shapiro91af1ce2021-06-17 12:42:09 -0500418
Alex Klein4f215432022-05-23 10:41:14 -0600419
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700420class ChromiteUnitTestTest(cros_test_lib.MockTestCase,
421 api_config.ApiConfigMixin):
422 """Tests for the ChromiteInfoTest function."""
423
424 def setUp(self):
425 self.board = 'board'
426 self.chroot_path = '/path/to/chroot'
427
428 def _GetInput(self, chroot_path=None):
429 """Helper to build an input message instance."""
Alex Klein4f215432022-05-23 10:41:14 -0600430 proto = test_pb2.ChromiteUnitTestRequest(chroot={'path': chroot_path},)
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700431 return proto
432
433 def _GetOutput(self):
434 """Helper to get an empty output message instance."""
435 return test_pb2.ChromiteUnitTestResponse()
436
437 def testValidateOnly(self):
438 """Sanity check that a validate only call does not execute any logic."""
439 patch = self.PatchObject(cros_build_lib, 'run')
440
441 input_msg = self._GetInput(chroot_path=self.chroot_path)
442 test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
443 self.validate_only_config)
444 patch.assert_not_called()
445
Michael Mortensen7a860eb2019-12-03 20:25:15 -0700446 def testMockError(self):
447 """Test mock error call does not execute any logic, returns error."""
448 patch = self.PatchObject(cros_build_lib, 'run')
449
450 input_msg = self._GetInput(chroot_path=self.chroot_path)
451 rc = test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
452 self.mock_error_config)
453 patch.assert_not_called()
454 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
455
456 def testMockCall(self):
457 """Test mock call does not execute any logic, returns success."""
458 patch = self.PatchObject(cros_build_lib, 'run')
459
460 input_msg = self._GetInput(chroot_path=self.chroot_path)
461 rc = test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
462 self.mock_call_config)
463 patch.assert_not_called()
464 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
465
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700466 def testChromiteUnitTest(self):
467 """Call ChromiteUnitTest with mocked cros_build_lib.run."""
468 request = self._GetInput(chroot_path=self.chroot_path)
469 patch = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600470 cros_build_lib,
471 'run',
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700472 return_value=cros_build_lib.CommandResult(returncode=0))
473
474 test_controller.ChromiteUnitTest(request, self._GetOutput(),
475 self.api_config)
476 patch.assert_called_once()
477
478
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600479class CrosSigningTestTest(cros_test_lib.RunCommandTestCase,
480 api_config.ApiConfigMixin):
481 """CrosSigningTest tests."""
482
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700483 def setUp(self):
484 self.chroot_path = '/path/to/chroot'
485
486 def _GetInput(self, chroot_path=None):
487 """Helper to build an input message instance."""
Alex Klein4f215432022-05-23 10:41:14 -0600488 proto = test_pb2.CrosSigningTestRequest(chroot={'path': chroot_path},)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700489 return proto
490
491 def _GetOutput(self):
492 """Helper to get an empty output message instance."""
493 return test_pb2.CrosSigningTestResponse()
494
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600495 def testValidateOnly(self):
496 """Sanity check that a validate only call does not execute any logic."""
497 test_controller.CrosSigningTest(None, None, self.validate_only_config)
498 self.assertFalse(self.rc.call_count)
499
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700500 def testMockCall(self):
501 """Test mock call does not execute any logic, returns success."""
502 rc = test_controller.CrosSigningTest(None, None, self.mock_call_config)
503 self.assertFalse(self.rc.call_count)
504 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
505
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700506 def testCrosSigningTest(self):
507 """Call CrosSigningTest with mocked cros_build_lib.run."""
508 request = self._GetInput(chroot_path=self.chroot_path)
509 patch = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600510 cros_build_lib,
511 'run',
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700512 return_value=cros_build_lib.CommandResult(returncode=0))
513
Alex Klein4f215432022-05-23 10:41:14 -0600514 test_controller.CrosSigningTest(request, self._GetOutput(), self.api_config)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700515 patch.assert_called_once()
516
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600517
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600518class SimpleChromeWorkflowTestTest(cros_test_lib.MockTestCase,
519 api_config.ApiConfigMixin):
520 """Test the SimpleChromeWorkflowTest endpoint."""
521
522 @staticmethod
523 def _Output():
524 return test_pb2.SimpleChromeWorkflowTestResponse()
525
David Wellingc1433c22021-06-25 16:29:48 +0000526 def _Input(self,
527 sysroot_path=None,
528 build_target=None,
529 chrome_root=None,
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600530 goma_config=None):
531 proto = test_pb2.SimpleChromeWorkflowTestRequest()
532 if sysroot_path:
533 proto.sysroot.path = sysroot_path
534 if build_target:
535 proto.sysroot.build_target.name = build_target
536 if chrome_root:
537 proto.chrome_root = chrome_root
538 if goma_config:
539 proto.goma_config = goma_config
540 return proto
541
542 def setUp(self):
543 self.chrome_path = 'path/to/chrome'
544 self.sysroot_dir = 'build/board'
545 self.build_target = 'amd64'
546 self.mock_simple_chrome_workflow_test = self.PatchObject(
547 test_service, 'SimpleChromeWorkflowTest')
548
549 def testMissingBuildTarget(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700550 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Alex Klein4f215432022-05-23 10:41:14 -0600551 input_proto = self._Input(
552 build_target=None,
553 sysroot_path='/sysroot/dir',
554 chrome_root='/chrome/path')
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600555 with self.assertRaises(cros_build_lib.DieSystemExit):
556 test_controller.SimpleChromeWorkflowTest(input_proto, None,
557 self.api_config)
558
559 def testMissingSysrootPath(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700560 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Alex Klein4f215432022-05-23 10:41:14 -0600561 input_proto = self._Input(
562 build_target='board', sysroot_path=None, chrome_root='/chrome/path')
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600563 with self.assertRaises(cros_build_lib.DieSystemExit):
564 test_controller.SimpleChromeWorkflowTest(input_proto, None,
565 self.api_config)
566
567 def testMissingChromeRoot(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700568 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Alex Klein4f215432022-05-23 10:41:14 -0600569 input_proto = self._Input(
570 build_target='board', sysroot_path='/sysroot/dir', chrome_root=None)
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600571 with self.assertRaises(cros_build_lib.DieSystemExit):
572 test_controller.SimpleChromeWorkflowTest(input_proto, None,
573 self.api_config)
574
575 def testSimpleChromeWorkflowTest(self):
576 """Call SimpleChromeWorkflowTest with valid args and temp dir."""
Alex Klein4f215432022-05-23 10:41:14 -0600577 request = self._Input(
578 sysroot_path='sysroot_path',
579 build_target='board',
580 chrome_root='/path/to/chrome')
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600581 response = self._Output()
582
583 test_controller.SimpleChromeWorkflowTest(request, response, self.api_config)
584 self.mock_simple_chrome_workflow_test.assert_called()
585
586 def testValidateOnly(self):
Alex Klein4f215432022-05-23 10:41:14 -0600587 request = self._Input(
588 sysroot_path='sysroot_path',
589 build_target='board',
590 chrome_root='/path/to/chrome')
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600591 test_controller.SimpleChromeWorkflowTest(request, self._Output(),
592 self.validate_only_config)
593 self.mock_simple_chrome_workflow_test.assert_not_called()
594
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700595 def testMockCall(self):
596 """Test mock call does not execute any logic, returns success."""
597 patch = self.mock_simple_chrome_workflow_test = self.PatchObject(
598 test_service, 'SimpleChromeWorkflowTest')
599
Alex Klein4f215432022-05-23 10:41:14 -0600600 request = self._Input(
601 sysroot_path='sysroot_path',
602 build_target='board',
603 chrome_root='/path/to/chrome')
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700604 rc = test_controller.SimpleChromeWorkflowTest(request, self._Output(),
605 self.mock_call_config)
606 patch.assert_not_called()
607 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
608
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600609
Alex Klein231d2da2019-07-22 16:44:45 -0600610class VmTestTest(cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin):
Evan Hernandez4e388a52019-05-01 12:16:33 -0600611 """Test the VmTest endpoint."""
612
613 def _GetInput(self, **kwargs):
614 values = dict(
615 build_target=common_pb2.BuildTarget(name='target'),
Alex Klein4f215432022-05-23 10:41:14 -0600616 vm_path=common_pb2.Path(
617 path='/path/to/image.bin', location=common_pb2.Path.INSIDE),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600618 test_harness=test_pb2.VmTestRequest.TAST,
619 vm_tests=[test_pb2.VmTestRequest.VmTest(pattern='suite')],
620 ssh_options=test_pb2.VmTestRequest.SshOptions(
Alex Klein4f215432022-05-23 10:41:14 -0600621 port=1234,
622 private_key_path={
623 'path': '/path/to/id_rsa',
624 'location': common_pb2.Path.INSIDE
625 }),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600626 )
627 values.update(kwargs)
628 return test_pb2.VmTestRequest(**values)
629
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700630 def _Output(self):
631 return test_pb2.VmTestResponse()
632
Alex Klein231d2da2019-07-22 16:44:45 -0600633 def testValidateOnly(self):
634 """Sanity check that a validate only call does not execute any logic."""
635 test_controller.VmTest(self._GetInput(), None, self.validate_only_config)
636 self.assertEqual(0, self.rc.call_count)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600637
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700638 def testMockCall(self):
639 """Test mock call does not execute any logic."""
640 patch = self.PatchObject(cros_build_lib, 'run')
641
642 request = self._GetInput()
643 response = self._Output()
644 # VmTest does not return a value, checking mocked value is flagged by lint.
645 test_controller.VmTest(request, response, self.mock_call_config)
646 patch.assert_not_called()
647
Evan Hernandez4e388a52019-05-01 12:16:33 -0600648 def testTastAllOptions(self):
649 """Test VmTest for Tast with all options set."""
Alex Klein231d2da2019-07-22 16:44:45 -0600650 test_controller.VmTest(self._GetInput(), None, self.api_config)
651 self.assertCommandContains([
Alex Klein4f215432022-05-23 10:41:14 -0600652 'cros_run_test',
653 '--debug',
654 '--no-display',
655 '--copy-on-write',
656 '--board',
657 'target',
658 '--image-path',
659 '/path/to/image.bin',
660 '--tast',
661 'suite',
662 '--ssh-port',
663 '1234',
664 '--private-key',
665 '/path/to/id_rsa',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600666 ])
667
668 def testAutotestAllOptions(self):
669 """Test VmTest for Autotest with all options set."""
670 input_proto = self._GetInput(test_harness=test_pb2.VmTestRequest.AUTOTEST)
Alex Klein231d2da2019-07-22 16:44:45 -0600671 test_controller.VmTest(input_proto, None, self.api_config)
672 self.assertCommandContains([
Alex Klein4f215432022-05-23 10:41:14 -0600673 'cros_run_test',
674 '--debug',
675 '--no-display',
676 '--copy-on-write',
677 '--board',
678 'target',
679 '--image-path',
680 '/path/to/image.bin',
681 '--autotest',
682 'suite',
683 '--ssh-port',
684 '1234',
685 '--private-key',
686 '/path/to/id_rsa',
Greg Edelstondcb0e912020-08-31 11:09:40 -0600687 '--test_that-args=--allow-chrome-crashes',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600688 ])
689
690 def testMissingBuildTarget(self):
691 """Test VmTest dies when build_target not set."""
692 input_proto = self._GetInput(build_target=None)
693 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600694 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600695
696 def testMissingVmImage(self):
697 """Test VmTest dies when vm_image not set."""
Alex Klein311b8022019-06-05 16:00:07 -0600698 input_proto = self._GetInput(vm_path=None)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600699 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600700 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600701
702 def testMissingTestHarness(self):
703 """Test VmTest dies when test_harness not specified."""
704 input_proto = self._GetInput(
705 test_harness=test_pb2.VmTestRequest.UNSPECIFIED)
706 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600707 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600708
709 def testMissingVmTests(self):
710 """Test VmTest dies when vm_tests not set."""
711 input_proto = self._GetInput(vm_tests=[])
712 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600713 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600714
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700715 def testVmTest(self):
716 """Call VmTest with valid args and temp dir."""
717 request = self._GetInput()
718 response = self._Output()
719 patch = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600720 cros_build_lib,
721 'run',
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700722 return_value=cros_build_lib.CommandResult(returncode=0))
723
724 test_controller.VmTest(request, response, self.api_config)
725 patch.assert_called()
726
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600727
Alex Klein231d2da2019-07-22 16:44:45 -0600728class MoblabVmTestTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600729 """Test the MoblabVmTest endpoint."""
730
731 @staticmethod
732 def _Payload(path):
Alex Klein4f215432022-05-23 10:41:14 -0600733 return test_pb2.MoblabVmTestRequest.Payload(path=common_pb2.Path(path=path))
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600734
735 @staticmethod
736 def _Output():
737 return test_pb2.MoblabVmTestResponse()
738
739 def _Input(self):
740 return test_pb2.MoblabVmTestRequest(
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600741 chroot=common_pb2.Chroot(path=self.chroot_dir),
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600742 image_payload=self._Payload(self.image_payload_dir),
743 cache_payloads=[self._Payload(self.autotest_payload_dir)])
744
745 def setUp(self):
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600746 self.chroot_dir = '/chroot'
747 self.chroot_tmp_dir = '/chroot/tmp'
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600748 self.image_payload_dir = '/payloads/image'
749 self.autotest_payload_dir = '/payloads/autotest'
750 self.builder = 'moblab-generic-vm/R12-3.4.5-67.890'
751 self.image_cache_dir = '/mnt/moblab/cache'
752 self.image_mount_dir = '/mnt/image'
753
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600754 self.PatchObject(chroot_lib.Chroot, 'tempdir', osutils.TempDir)
Evan Hernandez655e8042019-06-13 12:50:44 -0600755
Alex Klein4f215432022-05-23 10:41:14 -0600756 self.mock_create_moblab_vms = self.PatchObject(test_service,
757 'CreateMoblabVm')
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600758 self.mock_prepare_moblab_vm_image_cache = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600759 test_service,
760 'PrepareMoblabVmImageCache',
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600761 return_value=self.image_cache_dir)
Alex Klein4f215432022-05-23 10:41:14 -0600762 self.mock_run_moblab_vm_tests = self.PatchObject(test_service,
763 'RunMoblabVmTest')
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600764 self.mock_validate_moblab_vm_tests = self.PatchObject(
765 test_service, 'ValidateMoblabVmTest')
766
767 @contextlib.contextmanager
Alex Klein38c7d9e2019-05-08 09:31:19 -0600768 def MockLoopbackPartitions(*_args, **_kwargs):
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600769 mount = mock.MagicMock()
Evan Hernandez40ee7452019-06-13 12:51:43 -0600770 mount.Mount.return_value = [self.image_mount_dir]
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600771 yield mount
Alex Klein231d2da2019-07-22 16:44:45 -0600772
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600773 self.PatchObject(image_lib, 'LoopbackPartitions', MockLoopbackPartitions)
774
Alex Klein231d2da2019-07-22 16:44:45 -0600775 def testValidateOnly(self):
776 """Sanity check that a validate only call does not execute any logic."""
777 test_controller.MoblabVmTest(self._Input(), self._Output(),
778 self.validate_only_config)
779 self.mock_create_moblab_vms.assert_not_called()
780
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700781 def testMockCall(self):
782 """Test mock call does not execute any logic."""
783 patch = self.PatchObject(key_value_store, 'LoadFile')
784
785 # MoblabVmTest does not return a value, checking mocked value is flagged by
786 # lint.
787 test_controller.MoblabVmTest(self._Input(), self._Output(),
788 self.mock_call_config)
789 patch.assert_not_called()
790
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600791 def testImageContainsBuilder(self):
792 """MoblabVmTest calls service with correct args."""
793 request = self._Input()
794 response = self._Output()
795
796 self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600797 key_value_store,
798 'LoadFile',
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600799 return_value={cros_set_lsb_release.LSB_KEY_BUILDER_PATH: self.builder})
800
Alex Klein231d2da2019-07-22 16:44:45 -0600801 test_controller.MoblabVmTest(request, response, self.api_config)
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600802
803 self.assertEqual(
804 self.mock_create_moblab_vms.call_args_list,
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600805 [mock.call(mock.ANY, self.chroot_dir, self.image_payload_dir)])
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600806 self.assertEqual(
807 self.mock_prepare_moblab_vm_image_cache.call_args_list,
808 [mock.call(mock.ANY, self.builder, [self.autotest_payload_dir])])
Alex Klein4f215432022-05-23 10:41:14 -0600809 self.assertEqual(self.mock_run_moblab_vm_tests.call_args_list, [
810 mock.call(mock.ANY, mock.ANY, self.builder, self.image_cache_dir,
811 mock.ANY)
812 ])
813 self.assertEqual(self.mock_validate_moblab_vm_tests.call_args_list,
814 [mock.call(mock.ANY)])
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600815
816 def testImageMissingBuilder(self):
817 """MoblabVmTest dies when builder path not found in lsb-release."""
818 request = self._Input()
819 response = self._Output()
820
Mike Frysingere652ba12019-09-08 00:57:43 -0400821 self.PatchObject(key_value_store, 'LoadFile', return_value={})
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600822
823 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600824 test_controller.MoblabVmTest(request, response, self.api_config)
David Wellingc1433c22021-06-25 16:29:48 +0000825
826
827class GetArtifactsTest(cros_test_lib.MockTempDirTestCase):
828 """Test GetArtifacts."""
829
830 CODE_COVERAGE_LLVM_ARTIFACT_TYPE = (
Alex Klein4f215432022-05-23 10:41:14 -0600831 common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_LLVM_JSON)
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600832 UNIT_TEST_ARTIFACT_TYPE = (
Alex Klein4f215432022-05-23 10:41:14 -0600833 common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS)
David Wellingc1433c22021-06-25 16:29:48 +0000834
835 def setUp(self):
836 """Set up the class for tests."""
837 chroot_dir = os.path.join(self.tempdir, 'chroot')
838 osutils.SafeMakedirs(chroot_dir)
839 osutils.SafeMakedirs(os.path.join(chroot_dir, 'tmp'))
840 self.chroot = chroot_lib.Chroot(chroot_dir)
841
842 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
843 osutils.SafeMakedirs(sysroot_path)
844 self.sysroot = sysroot_lib.Sysroot(sysroot_path)
845
Jack Neusc9707c32021-07-23 21:48:54 +0000846 self.build_target = build_target_lib.BuildTarget('board')
847
David Wellingc1433c22021-06-25 16:29:48 +0000848 def testReturnsEmptyListWhenNoOutputArtifactsProvided(self):
849 """Test empty list is returned when there are no output_artifacts."""
850 result = test_controller.GetArtifacts(
Alex Klein4f215432022-05-23 10:41:14 -0600851 common_pb2.ArtifactsByService.Test(output_artifacts=[]), self.chroot,
852 self.sysroot, self.build_target, self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000853
854 self.assertEqual(len(result), 0)
855
856 def testShouldCallBundleCodeCoverageLlvmJsonForEachValidArtifact(self):
857 """Test BundleCodeCoverageLlvmJson is called on each valid artifact."""
Sean McAllister17eed8d2021-09-21 10:41:16 -0600858 BundleCodeCoverageLlvmJson_mock = (
859 self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600860 test_service, 'BundleCodeCoverageLlvmJson', return_value='test'))
David Wellingc1433c22021-06-25 16:29:48 +0000861
862 test_controller.GetArtifacts(
863 common_pb2.ArtifactsByService.Test(output_artifacts=[
864 # Valid
865 common_pb2.ArtifactsByService.Test.ArtifactInfo(
Alex Klein4f215432022-05-23 10:41:14 -0600866 artifact_types=[self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE]),
David Wellingc1433c22021-06-25 16:29:48 +0000867
868 # Invalid
Alex Klein4f215432022-05-23 10:41:14 -0600869 common_pb2.ArtifactsByService.Test.ArtifactInfo(artifact_types=[
870 common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS
871 ]),
David Wellingc1433c22021-06-25 16:29:48 +0000872 ]),
Alex Klein4f215432022-05-23 10:41:14 -0600873 self.chroot,
874 self.sysroot,
875 self.build_target,
876 self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000877
878 BundleCodeCoverageLlvmJson_mock.assert_called_once()
879
880 def testShouldReturnValidResult(self):
881 """Test result contains paths and code_coverage_llvm_json type."""
Alex Klein4f215432022-05-23 10:41:14 -0600882 self.PatchObject(
883 test_service, 'BundleCodeCoverageLlvmJson', return_value='test')
884 self.PatchObject(
885 test_service,
886 'BuildTargetUnitTestTarball',
887 return_value='unit_tests.tar')
David Wellingc1433c22021-06-25 16:29:48 +0000888
889 result = test_controller.GetArtifacts(
890 common_pb2.ArtifactsByService.Test(output_artifacts=[
891 # Valid
892 common_pb2.ArtifactsByService.Test.ArtifactInfo(
Alex Klein4f215432022-05-23 10:41:14 -0600893 artifact_types=[self.UNIT_TEST_ARTIFACT_TYPE]),
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600894 common_pb2.ArtifactsByService.Test.ArtifactInfo(
Alex Klein4f215432022-05-23 10:41:14 -0600895 artifact_types=[self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE]),
David Wellingc1433c22021-06-25 16:29:48 +0000896 ]),
Alex Klein4f215432022-05-23 10:41:14 -0600897 self.chroot,
898 self.sysroot,
899 self.build_target,
900 self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000901
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600902 self.assertEqual(result[0]['paths'], ['unit_tests.tar'])
903 self.assertEqual(result[0]['type'], self.UNIT_TEST_ARTIFACT_TYPE)
904 self.assertEqual(result[1]['paths'], ['test'])
905 self.assertEqual(result[1]['type'], self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE)