blob: b1079ca94a3b4ce3181596e10eaa18a41563a902 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Alex Kleina2e42c42019-04-17 16:13:19 -06002# 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
Lizzy Presland4feb2372022-01-20 05:16:30 +00007import datetime
Mike Frysingeref94e4c2020-02-10 23:59:54 -05008import os
Mike Frysinger40443592022-05-05 13:03:40 -04009from typing import Union
Mike Frysingeref94e4c2020-02-10 23:59:54 -050010
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040011from chromite.third_party.google.protobuf import json_format
12
Alex Klein231d2da2019-07-22 16:44:45 -060013from chromite.api import api_config
Alex Klein8cb365a2019-05-15 16:24:53 -060014from chromite.api import controller
Lizzy Presland4feb2372022-01-20 05:16:30 +000015from chromite.api.controller import controller_util
Alex Kleina2e42c42019-04-17 16:13:19 -060016from chromite.api.controller import test as test_controller
17from chromite.api.gen.chromite.api import test_pb2
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040018from chromite.api.gen.chromiumos import common_pb2
Sean McAllister3834fef2021-10-08 15:45:18 -060019from chromite.api.gen.chromiumos.build.api import container_metadata_pb2
Jack Neusc9707c32021-07-23 21:48:54 +000020from chromite.lib import build_target_lib
Evan Hernandeze1e05d32019-07-19 12:32:18 -060021from chromite.lib import chroot_lib
Alex Kleina2e42c42019-04-17 16:13:19 -060022from chromite.lib import cros_build_lib
23from chromite.lib import cros_test_lib
Alex Kleina2e42c42019-04-17 16:13:19 -060024from chromite.lib import osutils
David Wellingc1433c22021-06-25 16:29:48 +000025from chromite.lib import sysroot_lib
Alex Klein18a60af2020-06-11 12:08:47 -060026from chromite.lib.parser import package_info
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -060027from chromite.service import test as test_service
Alex Kleina2e42c42019-04-17 16:13:19 -060028
29
Alex Klein1699fab2022-09-08 08:46:06 -060030class DebugInfoTestTest(
31 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
32):
33 """Tests for the DebugInfoTest function."""
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070034
Alex Klein1699fab2022-09-08 08:46:06 -060035 def setUp(self):
36 self.board = "board"
37 self.chroot_path = os.path.join(self.tempdir, "chroot")
38 self.sysroot_path = "/build/board"
39 self.full_sysroot_path = os.path.join(
40 self.chroot_path, self.sysroot_path.lstrip(os.sep)
41 )
42 osutils.SafeMakedirs(self.full_sysroot_path)
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070043
Alex Klein1699fab2022-09-08 08:46:06 -060044 def _GetInput(self, sysroot_path=None, build_target=None):
45 """Helper to build an input message instance."""
46 proto = test_pb2.DebugInfoTestRequest()
47 if sysroot_path:
48 proto.sysroot.path = sysroot_path
49 if build_target:
50 proto.sysroot.build_target.name = build_target
51 return proto
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070052
Alex Klein1699fab2022-09-08 08:46:06 -060053 def _GetOutput(self):
54 """Helper to get an empty output message instance."""
55 return test_pb2.DebugInfoTestResponse()
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070056
Alex Klein1699fab2022-09-08 08:46:06 -060057 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -070058 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -060059 patch = self.PatchObject(test_service, "DebugInfoTest")
60 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
61 test_controller.DebugInfoTest(
62 input_msg, self._GetOutput(), self.validate_only_config
63 )
64 patch.assert_not_called()
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070065
Alex Klein1699fab2022-09-08 08:46:06 -060066 def testMockError(self):
67 """Test mock error call does not execute any logic, returns error."""
68 patch = self.PatchObject(test_service, "DebugInfoTest")
Michael Mortensen85d38402019-12-12 09:50:29 -070069
Alex Klein1699fab2022-09-08 08:46:06 -060070 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
71 rc = test_controller.DebugInfoTest(
72 input_msg, self._GetOutput(), self.mock_error_config
73 )
74 patch.assert_not_called()
75 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
Michael Mortensen85d38402019-12-12 09:50:29 -070076
Alex Klein1699fab2022-09-08 08:46:06 -060077 def testMockCall(self):
78 """Test mock call does not execute any logic, returns success."""
79 patch = self.PatchObject(test_service, "DebugInfoTest")
Michael Mortensen85d38402019-12-12 09:50:29 -070080
Alex Klein1699fab2022-09-08 08:46:06 -060081 input_msg = self._GetInput(sysroot_path=self.full_sysroot_path)
82 rc = test_controller.DebugInfoTest(
83 input_msg, self._GetOutput(), self.mock_call_config
84 )
85 patch.assert_not_called()
86 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
Michael Mortensen85d38402019-12-12 09:50:29 -070087
Alex Klein1699fab2022-09-08 08:46:06 -060088 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(
94 input_msg, output_msg, self.api_config
95 )
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -070096
Alex Klein1699fab2022-09-08 08:46:06 -060097 def testDebugInfoTest(self):
98 """Call DebugInfoTest with valid sysroot_path."""
99 request = self._GetInput(sysroot_path=self.full_sysroot_path)
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700100
Alex Klein1699fab2022-09-08 08:46:06 -0600101 test_controller.DebugInfoTest(
102 request, self._GetOutput(), self.api_config
103 )
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700104
105
Alex Klein1699fab2022-09-08 08:46:06 -0600106class BuildTargetUnitTestTest(
107 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
108):
109 """Tests for the UnitTest function."""
Alex Kleina2e42c42019-04-17 16:13:19 -0600110
Alex Klein1699fab2022-09-08 08:46:06 -0600111 def setUp(self):
112 # Set up portage log directory.
113 self.sysroot = os.path.join(self.tempdir, "build", "board")
114 osutils.SafeMakedirs(self.sysroot)
115 self.target_sysroot = sysroot_lib.Sysroot(self.sysroot)
116 self.portage_dir = os.path.join(self.tempdir, "portage_logdir")
117 self.PatchObject(
118 sysroot_lib.Sysroot, "portage_logdir", new=self.portage_dir
119 )
120 osutils.SafeMakedirs(self.portage_dir)
Lizzy Presland4feb2372022-01-20 05:16:30 +0000121
Alex Klein1699fab2022-09-08 08:46:06 -0600122 def _GetInput(
123 self,
124 board=None,
125 chroot_path=None,
126 cache_dir=None,
127 empty_sysroot=None,
128 packages=None,
129 blocklist=None,
130 ):
131 """Helper to build an input message instance."""
132 formatted_packages = []
133 for pkg in packages or []:
134 formatted_packages.append(
135 {"category": pkg.category, "package_name": pkg.package}
136 )
137 formatted_blocklist = []
138 for pkg in blocklist or []:
139 formatted_blocklist.append(
140 {"category": pkg.category, "package_name": pkg.package}
141 )
Alex Kleinf2674462019-05-16 16:47:24 -0600142
Alex Klein1699fab2022-09-08 08:46:06 -0600143 return test_pb2.BuildTargetUnitTestRequest(
144 build_target={"name": board},
145 chroot={"path": chroot_path, "cache_dir": cache_dir},
146 flags={"empty_sysroot": empty_sysroot},
147 packages=formatted_packages,
148 package_blocklist=formatted_blocklist,
149 )
Alex Kleina2e42c42019-04-17 16:13:19 -0600150
Alex Klein1699fab2022-09-08 08:46:06 -0600151 def _GetOutput(self):
152 """Helper to get an empty output message instance."""
153 return test_pb2.BuildTargetUnitTestResponse()
Alex Kleina2e42c42019-04-17 16:13:19 -0600154
Alex Klein1699fab2022-09-08 08:46:06 -0600155 def _CreatePortageLogFile(
156 self,
157 log_path: Union[str, os.PathLike],
158 pkg_info: package_info.PackageInfo,
159 timestamp: datetime.datetime,
160 ) -> str:
Alex Kleinab87ceb2023-01-24 12:00:51 -0700161 """Creates a log file to test for individual packages built by Portage.
Lizzy Presland4feb2372022-01-20 05:16:30 +0000162
Alex Klein1699fab2022-09-08 08:46:06 -0600163 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600164 log_path: The PORTAGE_LOGDIR path.
165 pkg_info: name components for log file.
166 timestamp: Timestamp used to name the file.
Alex Klein1699fab2022-09-08 08:46:06 -0600167 """
168 path = os.path.join(
169 log_path,
170 f"{pkg_info.category}:{pkg_info.pvr}:"
171 f'{timestamp.strftime("%Y%m%d-%H%M%S")}.log',
172 )
173 osutils.WriteFile(
174 path,
175 f"Test log file for package {pkg_info.category}/"
176 f"{pkg_info.package} written to {path}",
177 )
178 return path
Lizzy Presland4feb2372022-01-20 05:16:30 +0000179
Alex Klein1699fab2022-09-08 08:46:06 -0600180 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700181 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600182 patch = self.PatchObject(test_service, "BuildTargetUnitTest")
Alex Klein231d2da2019-07-22 16:44:45 -0600183
Alex Klein1699fab2022-09-08 08:46:06 -0600184 input_msg = self._GetInput(board="board")
185 test_controller.BuildTargetUnitTest(
186 input_msg, self._GetOutput(), self.validate_only_config
187 )
188 patch.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600189
Alex Klein1699fab2022-09-08 08:46:06 -0600190 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700191 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600192 patch = self.PatchObject(test_service, "BuildTargetUnitTest")
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700193
Alex Klein1699fab2022-09-08 08:46:06 -0600194 input_msg = self._GetInput(board="board")
195 response = self._GetOutput()
196 test_controller.BuildTargetUnitTest(
197 input_msg, response, self.mock_call_config
198 )
199 patch.assert_not_called()
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700200
Alex Klein1699fab2022-09-08 08:46:06 -0600201 def testMockError(self):
202 """Test that a mock error does not execute logic, returns error."""
203 patch = self.PatchObject(test_service, "BuildTargetUnitTest")
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700204
Alex Klein1699fab2022-09-08 08:46:06 -0600205 input_msg = self._GetInput(board="board")
206 response = self._GetOutput()
207 rc = test_controller.BuildTargetUnitTest(
208 input_msg, response, self.mock_error_config
209 )
210 patch.assert_not_called()
211 self.assertEqual(
212 controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc
213 )
214 self.assertTrue(response.failed_package_data)
215 self.assertEqual(response.failed_package_data[0].name.category, "foo")
216 self.assertEqual(
217 response.failed_package_data[0].name.package_name, "bar"
218 )
219 self.assertEqual(response.failed_package_data[1].name.category, "cat")
220 self.assertEqual(
221 response.failed_package_data[1].name.package_name, "pkg"
222 )
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700223
Alex Klein1699fab2022-09-08 08:46:06 -0600224 def testInvalidPackageFails(self):
225 """Test missing result path fails."""
226 # Missing result_path.
227 pkg = package_info.PackageInfo(package="bar")
228 input_msg = self._GetInput(board="board", packages=[pkg])
229 output_msg = self._GetOutput()
230 with self.assertRaises(cros_build_lib.DieSystemExit):
231 test_controller.BuildTargetUnitTest(
232 input_msg, output_msg, self.api_config
233 )
Alex Klein64ac34c2020-09-23 10:21:33 -0600234
Alex Klein1699fab2022-09-08 08:46:06 -0600235 def testPackageBuildFailure(self):
236 """Test handling of raised BuildPackageFailure."""
237 tempdir = osutils.TempDir(base_dir=self.tempdir)
238 self.PatchObject(osutils, "TempDir", return_value=tempdir)
Alex Kleina2e42c42019-04-17 16:13:19 -0600239
Alex Klein1699fab2022-09-08 08:46:06 -0600240 pkgs = ["cat/pkg-1.0-r1", "foo/bar-2.0-r1"]
241 cpvrs = [package_info.parse(pkg) for pkg in pkgs]
242 expected = [("cat", "pkg"), ("foo", "bar")]
243 new_logs = {}
244 for i, pkg in enumerate(pkgs):
245 self._CreatePortageLogFile(
246 self.portage_dir,
247 cpvrs[i],
248 datetime.datetime(2021, 6, 9, 13, 37, 0),
249 )
250 new_logs[pkg] = self._CreatePortageLogFile(
251 self.portage_dir,
252 cpvrs[i],
253 datetime.datetime(2021, 6, 9, 16, 20, 0),
254 )
Alex Kleina2e42c42019-04-17 16:13:19 -0600255
Alex Klein1699fab2022-09-08 08:46:06 -0600256 result = test_service.BuildTargetUnitTestResult(1, None)
257 result.failed_pkgs = [package_info.parse(p) for p in pkgs]
258 self.PatchObject(
259 test_service, "BuildTargetUnitTest", return_value=result
260 )
Alex Kleina2e42c42019-04-17 16:13:19 -0600261
Alex Klein1699fab2022-09-08 08:46:06 -0600262 input_msg = self._GetInput(board="board")
263 output_msg = self._GetOutput()
Alex Kleina2e42c42019-04-17 16:13:19 -0600264
Alex Klein1699fab2022-09-08 08:46:06 -0600265 rc = test_controller.BuildTargetUnitTest(
266 input_msg, output_msg, self.api_config
267 )
Alex Kleina2e42c42019-04-17 16:13:19 -0600268
Alex Klein1699fab2022-09-08 08:46:06 -0600269 self.assertEqual(
270 controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc
271 )
272 self.assertTrue(output_msg.failed_package_data)
Alex Kleina2e42c42019-04-17 16:13:19 -0600273
Alex Klein1699fab2022-09-08 08:46:06 -0600274 failed_with_logs = []
275 for data in output_msg.failed_package_data:
276 failed_with_logs.append(
277 (data.name.category, data.name.package_name)
278 )
279 package = controller_util.deserialize_package_info(data.name)
280 self.assertEqual(data.log_path.path, new_logs[package.cpvr])
281 self.assertCountEqual(expected, failed_with_logs)
Lizzy Presland4feb2372022-01-20 05:16:30 +0000282
Alex Klein1699fab2022-09-08 08:46:06 -0600283 def testOtherBuildScriptFailure(self):
284 """Test build script failure due to non-package emerge error."""
285 tempdir = osutils.TempDir(base_dir=self.tempdir)
286 self.PatchObject(osutils, "TempDir", return_value=tempdir)
Alex Kleina2e42c42019-04-17 16:13:19 -0600287
Alex Klein1699fab2022-09-08 08:46:06 -0600288 result = test_service.BuildTargetUnitTestResult(1, None)
289 self.PatchObject(
290 test_service, "BuildTargetUnitTest", return_value=result
291 )
Alex Kleina2e42c42019-04-17 16:13:19 -0600292
Alex Klein1699fab2022-09-08 08:46:06 -0600293 pkgs = ["foo/bar", "cat/pkg"]
Alex Kleind3b84042023-05-19 14:43:59 -0600294 blocklist = [package_info.parse(p) for p in pkgs]
Alex Klein1699fab2022-09-08 08:46:06 -0600295 input_msg = self._GetInput(
296 board="board", empty_sysroot=True, blocklist=blocklist
297 )
298 output_msg = self._GetOutput()
Alex Kleina2e42c42019-04-17 16:13:19 -0600299
Alex Klein1699fab2022-09-08 08:46:06 -0600300 rc = test_controller.BuildTargetUnitTest(
301 input_msg, output_msg, self.api_config
302 )
Alex Kleina2e42c42019-04-17 16:13:19 -0600303
Alex Klein1699fab2022-09-08 08:46:06 -0600304 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
305 self.assertFalse(output_msg.failed_package_data)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600306
Alex Klein1699fab2022-09-08 08:46:06 -0600307 def testBuildTargetUnitTest(self):
308 """Test BuildTargetUnitTest successful call."""
309 pkgs = ["foo/bar", "cat/pkg"]
310 packages = [package_info.SplitCPV(p, strict=False) for p in pkgs]
311 input_msg = self._GetInput(board="board", packages=packages)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700312
Alex Klein1699fab2022-09-08 08:46:06 -0600313 result = test_service.BuildTargetUnitTestResult(0, None)
314 self.PatchObject(
315 test_service, "BuildTargetUnitTest", return_value=result
316 )
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700317
Alex Klein1699fab2022-09-08 08:46:06 -0600318 response = self._GetOutput()
319 test_controller.BuildTargetUnitTest(
320 input_msg, response, self.api_config
321 )
322 self.assertFalse(response.failed_package_data)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700323
Evan Hernandez4e388a52019-05-01 12:16:33 -0600324
Sean McAllister17eed8d2021-09-21 10:41:16 -0600325class DockerConstraintsTest(cros_test_lib.MockTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600326 """Tests for Docker argument constraints."""
Sean McAllister17eed8d2021-09-21 10:41:16 -0600327
Alex Klein1699fab2022-09-08 08:46:06 -0600328 def assertValid(self, output):
329 return output is None
Sean McAllister17eed8d2021-09-21 10:41:16 -0600330
Alex Klein1699fab2022-09-08 08:46:06 -0600331 def assertInvalid(self, output):
332 return not self.assertValid(output)
Sean McAllister17eed8d2021-09-21 10:41:16 -0600333
Alex Klein1699fab2022-09-08 08:46:06 -0600334 def testValidDockerTag(self):
335 """Check logic for validating docker tag format."""
336 # pylint: disable=protected-access
Sean McAllister17eed8d2021-09-21 10:41:16 -0600337
Alex Klein1699fab2022-09-08 08:46:06 -0600338 invalid_tags = [
339 ".invalid-tag",
340 "-invalid-tag",
341 "invalid-tag;",
342 "invalid" * 100,
343 ]
Sean McAllister17eed8d2021-09-21 10:41:16 -0600344
Alex Klein1699fab2022-09-08 08:46:06 -0600345 for tag in invalid_tags:
346 self.assertInvalid(test_controller._ValidDockerTag(tag))
Sean McAllister17eed8d2021-09-21 10:41:16 -0600347
Alex Klein1699fab2022-09-08 08:46:06 -0600348 valid_tags = [
349 "valid-tag",
350 "valid-tag-",
351 "valid.tag.",
352 ]
Sean McAllister17eed8d2021-09-21 10:41:16 -0600353
Alex Klein1699fab2022-09-08 08:46:06 -0600354 for tag in valid_tags:
355 self.assertValid(test_controller._ValidDockerTag(tag))
Sean McAllister17eed8d2021-09-21 10:41:16 -0600356
Alex Klein1699fab2022-09-08 08:46:06 -0600357 def testValidDockerLabelKey(self):
358 """Check logic for validating docker label key format."""
359 # pylint: disable=protected-access
Sean McAllister17eed8d2021-09-21 10:41:16 -0600360
Alex Klein1699fab2022-09-08 08:46:06 -0600361 invalid_keys = [
362 "Invalid-keY",
363 "Invalid-key",
364 "invalid-keY",
365 "iNVALID-KEy",
366 "invalid_key",
367 "invalid-key;",
368 ]
Sean McAllister17eed8d2021-09-21 10:41:16 -0600369
Alex Klein1699fab2022-09-08 08:46:06 -0600370 for key in invalid_keys:
371 self.assertInvalid(test_controller._ValidDockerLabelKey(key))
Sean McAllister17eed8d2021-09-21 10:41:16 -0600372
Alex Klein1699fab2022-09-08 08:46:06 -0600373 valid_keys = [
374 "chromeos.valid-key",
375 "chromeos.valid-key-2",
376 ]
Sean McAllister17eed8d2021-09-21 10:41:16 -0600377
Alex Klein1699fab2022-09-08 08:46:06 -0600378 for key in valid_keys:
379 self.assertValid(test_controller._ValidDockerLabelKey(key))
Sean McAllister17eed8d2021-09-21 10:41:16 -0600380
381
Alex Klein1699fab2022-09-08 08:46:06 -0600382class BuildTestServiceContainers(
383 cros_test_lib.RunCommandTempDirTestCase, api_config.ApiConfigMixin
384):
385 """Tests for the BuildTestServiceContainers function."""
C Shapiro91af1ce2021-06-17 12:42:09 -0500386
Alex Klein1699fab2022-09-08 08:46:06 -0600387 def setUp(self):
388 self.request = test_pb2.BuildTestServiceContainersRequest(
Brian Norris7ac08e22023-06-15 11:03:01 -0700389 chroot={"path": "/path/to/chroot", "out_path": "/path/to/out"},
Alex Klein1699fab2022-09-08 08:46:06 -0600390 build_target={"name": "build_target"},
391 version="R93-14033.0.0",
392 )
C Shapiro91af1ce2021-06-17 12:42:09 -0500393
Alex Klein1699fab2022-09-08 08:46:06 -0600394 def testSuccess(self):
395 """Check passing case with mocked cros_build_lib.run."""
Sean McAllister3834fef2021-10-08 15:45:18 -0600396
Alex Klein1699fab2022-09-08 08:46:06 -0600397 def ContainerMetadata():
398 """Return mocked ContainerImageInfo proto"""
399 metadata = container_metadata_pb2.ContainerImageInfo()
400 metadata.repository.hostname = "gcr.io"
401 metadata.repository.project = "chromeos-bot"
402 metadata.name = "random-container-name"
Alex Kleinab87ceb2023-01-24 12:00:51 -0700403 # pylint: disable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600404 metadata.digest = "09b730f8b6a862f9c2705cb3acf3554563325f5fca5c784bf5c98beb2e56f6db"
Alex Kleinab87ceb2023-01-24 12:00:51 -0700405 # pylint: enable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600406 metadata.tags[:] = [
407 "staging-cq-amd64-generic.R96-1.2.3",
408 "8834106026340379089",
409 ]
410 return metadata
Sean McAllister3834fef2021-10-08 15:45:18 -0600411
Alex Klein1699fab2022-09-08 08:46:06 -0600412 def WriteContainerMetadata(path):
413 """Write json formatted metadata to the given file."""
414 osutils.WriteFile(
415 path,
416 json_format.MessageToJson(ContainerMetadata()),
417 )
Sean McAllister3834fef2021-10-08 15:45:18 -0600418
Alex Klein1699fab2022-09-08 08:46:06 -0600419 # Write out mocked container metadata to a temporary file.
420 output_path = os.path.join(self.tempdir, "metadata.jsonpb")
421 self.rc.SetDefaultCmdResult(
422 returncode=0,
423 side_effect=lambda *_, **__: WriteContainerMetadata(output_path),
424 )
Sean McAllister3834fef2021-10-08 15:45:18 -0600425
Alex Klein1699fab2022-09-08 08:46:06 -0600426 # Patch TempDir so that we always use this test's directory.
427 self.PatchObject(
428 osutils.TempDir, "__enter__", return_value=self.tempdir
429 )
C Shapiro91af1ce2021-06-17 12:42:09 -0500430
Alex Klein1699fab2022-09-08 08:46:06 -0600431 response = test_pb2.BuildTestServiceContainersResponse()
432 test_controller.BuildTestServiceContainers(
433 self.request, response, self.api_config
434 )
Sean McAllister3834fef2021-10-08 15:45:18 -0600435
Alex Klein1699fab2022-09-08 08:46:06 -0600436 self.assertTrue(self.rc.called)
437 for result in response.results:
438 self.assertEqual(result.WhichOneof("result"), "success")
439 self.assertEqual(result.success.image_info, ContainerMetadata())
C Shapiro91af1ce2021-06-17 12:42:09 -0500440
Alex Klein1699fab2022-09-08 08:46:06 -0600441 def testFailure(self):
442 """Check failure case with mocked cros_build_lib.run."""
Alex Klein1699fab2022-09-08 08:46:06 -0600443 response = test_pb2.BuildTestServiceContainersResponse()
444 test_controller.BuildTestServiceContainers(
445 self.request, response, self.api_config
446 )
Mike Frysinger5d85a542023-07-06 16:05:54 -0400447 self.assertTrue(self.rc.called)
Alex Klein1699fab2022-09-08 08:46:06 -0600448 for result in response.results:
449 self.assertEqual(result.WhichOneof("result"), "failure")
450 self.assertEqual(result.name, "Service Builder")
C Shapiro91af1ce2021-06-17 12:42:09 -0500451
Alex Klein4f215432022-05-23 10:41:14 -0600452
Alex Klein1699fab2022-09-08 08:46:06 -0600453class ChromiteUnitTestTest(
Mike Frysinger5d85a542023-07-06 16:05:54 -0400454 cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin
Alex Klein1699fab2022-09-08 08:46:06 -0600455):
456 """Tests for the ChromiteInfoTest function."""
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700457
Alex Klein1699fab2022-09-08 08:46:06 -0600458 def setUp(self):
459 self.board = "board"
460 self.chroot_path = "/path/to/chroot"
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700461
Alex Klein1699fab2022-09-08 08:46:06 -0600462 def _GetInput(self, chroot_path=None):
463 """Helper to build an input message instance."""
464 proto = test_pb2.ChromiteUnitTestRequest(
465 chroot={"path": chroot_path},
466 )
467 return proto
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700468
Alex Klein1699fab2022-09-08 08:46:06 -0600469 def _GetOutput(self):
470 """Helper to get an empty output message instance."""
471 return test_pb2.ChromiteUnitTestResponse()
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700472
Alex Klein1699fab2022-09-08 08:46:06 -0600473 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700474 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600475 input_msg = self._GetInput(chroot_path=self.chroot_path)
476 test_controller.ChromiteUnitTest(
477 input_msg, self._GetOutput(), self.validate_only_config
478 )
Mike Frysinger5d85a542023-07-06 16:05:54 -0400479 self.assertFalse(self.rc.called)
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700480
Alex Klein1699fab2022-09-08 08:46:06 -0600481 def testMockError(self):
482 """Test mock error call does not execute any logic, returns error."""
Alex Klein1699fab2022-09-08 08:46:06 -0600483 input_msg = self._GetInput(chroot_path=self.chroot_path)
484 rc = test_controller.ChromiteUnitTest(
485 input_msg, self._GetOutput(), self.mock_error_config
486 )
Mike Frysinger5d85a542023-07-06 16:05:54 -0400487 self.assertFalse(self.rc.called)
Alex Klein1699fab2022-09-08 08:46:06 -0600488 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
Michael Mortensen7a860eb2019-12-03 20:25:15 -0700489
Alex Klein1699fab2022-09-08 08:46:06 -0600490 def testMockCall(self):
491 """Test mock call does not execute any logic, returns success."""
Alex Klein1699fab2022-09-08 08:46:06 -0600492 input_msg = self._GetInput(chroot_path=self.chroot_path)
493 rc = test_controller.ChromiteUnitTest(
494 input_msg, self._GetOutput(), self.mock_call_config
495 )
Mike Frysinger5d85a542023-07-06 16:05:54 -0400496 self.assertFalse(self.rc.called)
Alex Klein1699fab2022-09-08 08:46:06 -0600497 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
Michael Mortensen7a860eb2019-12-03 20:25:15 -0700498
Alex Klein1699fab2022-09-08 08:46:06 -0600499 def testChromiteUnitTest(self):
500 """Call ChromiteUnitTest with mocked cros_build_lib.run."""
501 request = self._GetInput(chroot_path=self.chroot_path)
Alex Klein1699fab2022-09-08 08:46:06 -0600502 test_controller.ChromiteUnitTest(
503 request, self._GetOutput(), self.api_config
504 )
Mike Frysinger5d85a542023-07-06 16:05:54 -0400505 self.assertEqual(self.rc.call_count, 1)
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700506
507
Alex Klein1699fab2022-09-08 08:46:06 -0600508class CrosSigningTestTest(
509 cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin
510):
511 """CrosSigningTest tests."""
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600512
Alex Klein1699fab2022-09-08 08:46:06 -0600513 def setUp(self):
514 self.chroot_path = "/path/to/chroot"
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700515
Alex Klein1699fab2022-09-08 08:46:06 -0600516 def _GetInput(self, chroot_path=None):
517 """Helper to build an input message instance."""
518 proto = test_pb2.CrosSigningTestRequest(
519 chroot={"path": chroot_path},
520 )
521 return proto
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700522
Alex Klein1699fab2022-09-08 08:46:06 -0600523 def _GetOutput(self):
524 """Helper to get an empty output message instance."""
525 return test_pb2.CrosSigningTestResponse()
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700526
Alex Klein1699fab2022-09-08 08:46:06 -0600527 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700528 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600529 test_controller.CrosSigningTest(None, None, self.validate_only_config)
Mike Frysinger5d85a542023-07-06 16:05:54 -0400530 self.assertFalse(self.rc.called)
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600531
Alex Klein1699fab2022-09-08 08:46:06 -0600532 def testMockCall(self):
533 """Test mock call does not execute any logic, returns success."""
534 rc = test_controller.CrosSigningTest(None, None, self.mock_call_config)
Mike Frysinger5d85a542023-07-06 16:05:54 -0400535 self.assertFalse(self.rc.called)
Alex Klein1699fab2022-09-08 08:46:06 -0600536 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700537
Alex Klein1699fab2022-09-08 08:46:06 -0600538 def testCrosSigningTest(self):
539 """Call CrosSigningTest with mocked cros_build_lib.run."""
540 request = self._GetInput(chroot_path=self.chroot_path)
Alex Klein1699fab2022-09-08 08:46:06 -0600541 test_controller.CrosSigningTest(
542 request, self._GetOutput(), self.api_config
543 )
Mike Frysinger5d85a542023-07-06 16:05:54 -0400544 self.assertEqual(self.rc.call_count, 1)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700545
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600546
Alex Klein1699fab2022-09-08 08:46:06 -0600547class SimpleChromeWorkflowTestTest(
548 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
549):
550 """Test the SimpleChromeWorkflowTest endpoint."""
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600551
Alex Klein1699fab2022-09-08 08:46:06 -0600552 @staticmethod
553 def _Output():
554 return test_pb2.SimpleChromeWorkflowTestResponse()
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600555
Alex Klein1699fab2022-09-08 08:46:06 -0600556 def _Input(
557 self,
558 sysroot_path=None,
Alex Klein4f215432022-05-23 10:41:14 -0600559 build_target=None,
Alex Klein1699fab2022-09-08 08:46:06 -0600560 chrome_root=None,
561 goma_config=None,
562 ):
563 proto = test_pb2.SimpleChromeWorkflowTestRequest()
564 if sysroot_path:
565 proto.sysroot.path = sysroot_path
566 if build_target:
567 proto.sysroot.build_target.name = build_target
568 if chrome_root:
569 proto.chrome_root = chrome_root
570 if goma_config:
571 proto.goma_config = goma_config
572 return proto
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600573
Alex Klein1699fab2022-09-08 08:46:06 -0600574 def setUp(self):
575 self.chrome_path = "path/to/chrome"
576 self.sysroot_dir = "build/board"
577 self.build_target = "amd64"
578 self.mock_simple_chrome_workflow_test = self.PatchObject(
579 test_service, "SimpleChromeWorkflowTest"
580 )
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600581
Alex Klein1699fab2022-09-08 08:46:06 -0600582 def testMissingBuildTarget(self):
583 """Test SimpleChromeWorkflowTest dies when build_target not set."""
584 input_proto = self._Input(
585 build_target=None,
586 sysroot_path="/sysroot/dir",
587 chrome_root="/chrome/path",
588 )
589 with self.assertRaises(cros_build_lib.DieSystemExit):
590 test_controller.SimpleChromeWorkflowTest(
591 input_proto, None, self.api_config
592 )
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600593
Alex Klein1699fab2022-09-08 08:46:06 -0600594 def testMissingSysrootPath(self):
595 """Test SimpleChromeWorkflowTest dies when build_target not set."""
596 input_proto = self._Input(
597 build_target="board", sysroot_path=None, chrome_root="/chrome/path"
598 )
599 with self.assertRaises(cros_build_lib.DieSystemExit):
600 test_controller.SimpleChromeWorkflowTest(
601 input_proto, None, self.api_config
602 )
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600603
Alex Klein1699fab2022-09-08 08:46:06 -0600604 def testMissingChromeRoot(self):
605 """Test SimpleChromeWorkflowTest dies when build_target not set."""
606 input_proto = self._Input(
607 build_target="board", sysroot_path="/sysroot/dir", chrome_root=None
608 )
609 with self.assertRaises(cros_build_lib.DieSystemExit):
610 test_controller.SimpleChromeWorkflowTest(
611 input_proto, None, self.api_config
612 )
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600613
Alex Klein1699fab2022-09-08 08:46:06 -0600614 def testSimpleChromeWorkflowTest(self):
615 """Call SimpleChromeWorkflowTest with valid args and temp dir."""
616 request = self._Input(
617 sysroot_path="sysroot_path",
618 build_target="board",
619 chrome_root="/path/to/chrome",
620 )
621 response = self._Output()
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600622
Alex Klein1699fab2022-09-08 08:46:06 -0600623 test_controller.SimpleChromeWorkflowTest(
624 request, response, self.api_config
625 )
626 self.mock_simple_chrome_workflow_test.assert_called()
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700627
Alex Klein1699fab2022-09-08 08:46:06 -0600628 def testValidateOnly(self):
629 request = self._Input(
630 sysroot_path="sysroot_path",
631 build_target="board",
632 chrome_root="/path/to/chrome",
633 )
634 test_controller.SimpleChromeWorkflowTest(
635 request, self._Output(), self.validate_only_config
636 )
637 self.mock_simple_chrome_workflow_test.assert_not_called()
638
639 def testMockCall(self):
640 """Test mock call does not execute any logic, returns success."""
641 patch = self.mock_simple_chrome_workflow_test = self.PatchObject(
642 test_service, "SimpleChromeWorkflowTest"
643 )
644
645 request = self._Input(
646 sysroot_path="sysroot_path",
647 build_target="board",
648 chrome_root="/path/to/chrome",
649 )
650 rc = test_controller.SimpleChromeWorkflowTest(
651 request, self._Output(), self.mock_call_config
652 )
653 patch.assert_not_called()
654 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700655
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600656
Alex Klein231d2da2019-07-22 16:44:45 -0600657class VmTestTest(cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600658 """Test the VmTest endpoint."""
Evan Hernandez4e388a52019-05-01 12:16:33 -0600659
Alex Klein1699fab2022-09-08 08:46:06 -0600660 def _GetInput(self, **kwargs):
661 values = dict(
662 build_target=common_pb2.BuildTarget(name="target"),
663 vm_path=common_pb2.Path(
664 path="/path/to/image.bin", location=common_pb2.Path.INSIDE
665 ),
666 test_harness=test_pb2.VmTestRequest.TAST,
667 vm_tests=[test_pb2.VmTestRequest.VmTest(pattern="suite")],
668 ssh_options=test_pb2.VmTestRequest.SshOptions(
669 port=1234,
670 private_key_path={
671 "path": "/path/to/id_rsa",
672 "location": common_pb2.Path.INSIDE,
673 },
674 ),
675 )
676 values.update(kwargs)
677 return test_pb2.VmTestRequest(**values)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600678
Alex Klein1699fab2022-09-08 08:46:06 -0600679 def _Output(self):
680 return test_pb2.VmTestResponse()
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700681
Alex Klein1699fab2022-09-08 08:46:06 -0600682 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700683 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600684 test_controller.VmTest(
685 self._GetInput(), None, self.validate_only_config
686 )
687 self.assertEqual(0, self.rc.call_count)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600688
Alex Klein1699fab2022-09-08 08:46:06 -0600689 def testMockCall(self):
690 """Test mock call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600691 request = self._GetInput()
692 response = self._Output()
Alex Kleinab87ceb2023-01-24 12:00:51 -0700693 # VmTest does not return a value, checking mocked value is flagged by
694 # lint.
Alex Klein1699fab2022-09-08 08:46:06 -0600695 test_controller.VmTest(request, response, self.mock_call_config)
Mike Frysinger5d85a542023-07-06 16:05:54 -0400696 self.assertFalse(self.rc.called)
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700697
Alex Klein1699fab2022-09-08 08:46:06 -0600698 def testTastAllOptions(self):
699 """Test VmTest for Tast with all options set."""
700 test_controller.VmTest(self._GetInput(), None, self.api_config)
701 self.assertCommandContains(
702 [
703 "cros_run_test",
704 "--debug",
705 "--no-display",
706 "--copy-on-write",
707 "--board",
708 "target",
709 "--image-path",
710 "/path/to/image.bin",
711 "--tast",
712 "suite",
713 "--ssh-port",
714 "1234",
715 "--private-key",
716 "/path/to/id_rsa",
717 ]
718 )
Evan Hernandez4e388a52019-05-01 12:16:33 -0600719
Alex Klein1699fab2022-09-08 08:46:06 -0600720 def testAutotestAllOptions(self):
721 """Test VmTest for Autotest with all options set."""
722 input_proto = self._GetInput(
723 test_harness=test_pb2.VmTestRequest.AUTOTEST
724 )
725 test_controller.VmTest(input_proto, None, self.api_config)
726 self.assertCommandContains(
727 [
728 "cros_run_test",
729 "--debug",
730 "--no-display",
731 "--copy-on-write",
732 "--board",
733 "target",
734 "--image-path",
735 "/path/to/image.bin",
736 "--autotest",
737 "suite",
738 "--ssh-port",
739 "1234",
740 "--private-key",
741 "/path/to/id_rsa",
742 "--test_that-args=--allow-chrome-crashes",
743 ]
744 )
Evan Hernandez4e388a52019-05-01 12:16:33 -0600745
Alex Klein1699fab2022-09-08 08:46:06 -0600746 def testMissingBuildTarget(self):
747 """Test VmTest dies when build_target not set."""
748 input_proto = self._GetInput(build_target=None)
749 with self.assertRaises(cros_build_lib.DieSystemExit):
750 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600751
Alex Klein1699fab2022-09-08 08:46:06 -0600752 def testMissingVmImage(self):
753 """Test VmTest dies when vm_image not set."""
754 input_proto = self._GetInput(vm_path=None)
755 with self.assertRaises(cros_build_lib.DieSystemExit):
756 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600757
Alex Klein1699fab2022-09-08 08:46:06 -0600758 def testMissingTestHarness(self):
759 """Test VmTest dies when test_harness not specified."""
760 input_proto = self._GetInput(
761 test_harness=test_pb2.VmTestRequest.UNSPECIFIED
762 )
763 with self.assertRaises(cros_build_lib.DieSystemExit):
764 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600765
Alex Klein1699fab2022-09-08 08:46:06 -0600766 def testMissingVmTests(self):
767 """Test VmTest dies when vm_tests not set."""
768 input_proto = self._GetInput(vm_tests=[])
769 with self.assertRaises(cros_build_lib.DieSystemExit):
770 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600771
Alex Klein1699fab2022-09-08 08:46:06 -0600772 def testVmTest(self):
773 """Call VmTest with valid args and temp dir."""
774 request = self._GetInput()
775 response = self._Output()
Alex Klein1699fab2022-09-08 08:46:06 -0600776 test_controller.VmTest(request, response, self.api_config)
Mike Frysinger5d85a542023-07-06 16:05:54 -0400777 self.assertTrue(self.rc.called)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700778
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600779
David Wellingc1433c22021-06-25 16:29:48 +0000780class GetArtifactsTest(cros_test_lib.MockTempDirTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600781 """Test GetArtifacts."""
David Wellingc1433c22021-06-25 16:29:48 +0000782
Alex Klein1699fab2022-09-08 08:46:06 -0600783 CODE_COVERAGE_LLVM_ARTIFACT_TYPE = (
784 common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_LLVM_JSON
785 )
David Wellingc1433c22021-06-25 16:29:48 +0000786
Alex Kleinab87ceb2023-01-24 12:00:51 -0700787 # pylint: disable=line-too-long
Josiah Hounyode113e52022-11-30 06:30:33 +0000788 _artifact_funcs = {
789 common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_LLVM_JSON: test_service.BundleCodeCoverageLlvmJson,
790 common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_RUST_LLVM_JSON: test_service.BundleCodeCoverageRustLlvmJson,
791 common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL: test_service.BundleHwqualTarball,
792 common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_GOLANG: test_service.BundleCodeCoverageGolang,
793 }
Alex Kleinab87ceb2023-01-24 12:00:51 -0700794 # pylint: enable=line-too-long
Josiah Hounyode113e52022-11-30 06:30:33 +0000795
Alex Klein1699fab2022-09-08 08:46:06 -0600796 def setUp(self):
797 """Set up the class for tests."""
Brian Norrisa4e46282023-06-30 11:35:19 -0700798 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
David Wellingc1433c22021-06-25 16:29:48 +0000799
Brian Norrisa4e46282023-06-30 11:35:19 -0700800 self.chroot = chroot_lib.Chroot(
801 path=self.tempdir / "chroot",
802 out_path=self.tempdir / "out",
803 )
804 osutils.SafeMakedirs(self.chroot.tmp)
805
806 sysroot_path = self.chroot.full_path("/build/board")
Alex Klein1699fab2022-09-08 08:46:06 -0600807 osutils.SafeMakedirs(sysroot_path)
808 self.sysroot = sysroot_lib.Sysroot(sysroot_path)
David Wellingc1433c22021-06-25 16:29:48 +0000809
Alex Klein1699fab2022-09-08 08:46:06 -0600810 self.build_target = build_target_lib.BuildTarget("board")
Jack Neusc9707c32021-07-23 21:48:54 +0000811
Josiah Hounyode113e52022-11-30 06:30:33 +0000812 self._mocks = {}
813 for artifact, func in self._artifact_funcs.items():
814 self._mocks[artifact] = self.PatchObject(
815 test_service, func.__name__
816 )
817
818 def _InputProto(
819 self,
820 artifact_types=_artifact_funcs.keys(),
821 ):
822 """Helper to build an input proto instance."""
823 return common_pb2.ArtifactsByService.Test(
824 output_artifacts=[
825 common_pb2.ArtifactsByService.Test.ArtifactInfo(
826 artifact_types=artifact_types
827 )
828 ]
829 )
830
Alex Klein1699fab2022-09-08 08:46:06 -0600831 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=[]),
835 self.chroot,
836 self.sysroot,
837 self.build_target,
838 self.tempdir,
839 )
David Wellingc1433c22021-06-25 16:29:48 +0000840
Alex Klein1699fab2022-09-08 08:46:06 -0600841 self.assertEqual(len(result), 0)
David Wellingc1433c22021-06-25 16:29:48 +0000842
Alex Klein1699fab2022-09-08 08:46:06 -0600843 def testShouldCallBundleCodeCoverageLlvmJsonForEachValidArtifact(self):
844 """Test BundleCodeCoverageLlvmJson is called on each valid artifact."""
845 BundleCodeCoverageLlvmJson_mock = self.PatchObject(
846 test_service, "BundleCodeCoverageLlvmJson", return_value="test"
847 )
848
Alex Kleinab87ceb2023-01-24 12:00:51 -0700849 # pylint: disable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600850 test_controller.GetArtifacts(
851 common_pb2.ArtifactsByService.Test(
852 output_artifacts=[
853 # Valid
854 common_pb2.ArtifactsByService.Test.ArtifactInfo(
855 artifact_types=[self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE]
856 ),
857 # Invalid
858 common_pb2.ArtifactsByService.Test.ArtifactInfo(
859 artifact_types=[
860 common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS
861 ]
862 ),
863 ]
864 ),
865 self.chroot,
866 self.sysroot,
867 self.build_target,
868 self.tempdir,
869 )
Alex Kleinab87ceb2023-01-24 12:00:51 -0700870 # pylint: enable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600871
872 BundleCodeCoverageLlvmJson_mock.assert_called_once()
873
874 def testShouldReturnValidResult(self):
875 """Test result contains paths and code_coverage_llvm_json type."""
Sean McAllister17eed8d2021-09-21 10:41:16 -0600876 self.PatchObject(
Alex Klein1699fab2022-09-08 08:46:06 -0600877 test_service, "BundleCodeCoverageLlvmJson", return_value="test"
878 )
David Wellingc1433c22021-06-25 16:29:48 +0000879
Alex Klein1699fab2022-09-08 08:46:06 -0600880 result = test_controller.GetArtifacts(
881 common_pb2.ArtifactsByService.Test(
882 output_artifacts=[
883 # Valid
884 common_pb2.ArtifactsByService.Test.ArtifactInfo(
885 artifact_types=[self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE]
886 ),
887 ]
888 ),
889 self.chroot,
890 self.sysroot,
891 self.build_target,
892 self.tempdir,
893 )
David Wellingc1433c22021-06-25 16:29:48 +0000894
Alex Klein1699fab2022-09-08 08:46:06 -0600895 self.assertEqual(result[0]["paths"], ["test"])
896 self.assertEqual(
897 result[0]["type"], self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE
898 )
Josiah Hounyode113e52022-11-30 06:30:33 +0000899
900 def testNoArtifacts(self):
901 """Test GetArtifacts with no artifact types."""
902 in_proto = self._InputProto(artifact_types=[])
903 test_controller.GetArtifacts(
904 in_proto, None, None, self.build_target, ""
905 )
906
907 for _, patch in self._mocks.items():
908 patch.assert_not_called()
909
910 def testArtifactsSuccess(self):
911 """Test GetArtifacts with all artifact types."""
912 test_controller.GetArtifacts(
913 self._InputProto(), None, None, self.build_target, ""
914 )
915
916 for _, patch in self._mocks.items():
917 patch.assert_called_once()
918
919 def testArtifactsException(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700920 """Test with all artifact types when one type throws an exception."""
Josiah Hounyode113e52022-11-30 06:30:33 +0000921
922 self._mocks[
923 common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_GOLANG
924 ].side_effect = Exception("foo bar")
925 generated = test_controller.GetArtifacts(
926 self._InputProto(), None, None, self.build_target, ""
927 )
928
929 for _, patch in self._mocks.items():
930 patch.assert_called_once()
931
932 found_artifact = False
933 for data in generated:
934 artifact_type = (
935 common_pb2.ArtifactsByService.Test.ArtifactType.Name(
936 data["type"]
937 )
938 )
939 if artifact_type == "CODE_COVERAGE_GOLANG":
940 found_artifact = True
941 self.assertTrue(data["failed"])
942 self.assertEqual(data["failure_reason"], "foo bar")
943 self.assertTrue(found_artifact)