blob: 8d5feb7853f471c5f492b4a25d32b0d46d9cdcba [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 Frysinger40443592022-05-05 13:03:40 -040010from typing import Union
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,
Navil Perezc0b29a82020-07-07 14:17:48 +0000118 chroot_path=None,
119 cache_dir=None,
120 empty_sysroot=None,
121 packages=None,
Alex Kleinb64e5f82020-09-23 10:55:31 -0600122 blocklist=None):
Alex Kleina2e42c42019-04-17 16:13:19 -0600123 """Helper to build an input message instance."""
Navil Perezc0b29a82020-07-07 14:17:48 +0000124 formatted_packages = []
125 for pkg in packages or []:
126 formatted_packages.append({
127 'category': pkg.category,
128 'package_name': pkg.package
129 })
Alex Kleinb64e5f82020-09-23 10:55:31 -0600130 formatted_blocklist = []
131 for pkg in blocklist or []:
Alex Klein4f215432022-05-23 10:41:14 -0600132 formatted_blocklist.append({
133 'category': pkg.category,
134 'package_name': pkg.package
135 })
Alex Kleinf2674462019-05-16 16:47:24 -0600136
Alex Kleina2e42c42019-04-17 16:13:19 -0600137 return test_pb2.BuildTargetUnitTestRequest(
Alex Klein4f215432022-05-23 10:41:14 -0600138 build_target={'name': board},
Alex Klein4f215432022-05-23 10:41:14 -0600139 chroot={
140 'path': chroot_path,
141 'cache_dir': cache_dir
142 },
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
Alex Klein4f215432022-05-23 10:41:14 -0600152 def _CreatePortageLogFile(self, log_path: Union[str, os.PathLike],
Mike Frysinger40443592022-05-05 13:03:40 -0400153 pkg_info: package_info.PackageInfo,
154 timestamp: datetime.datetime) -> str:
Lizzy Presland4feb2372022-01-20 05:16:30 +0000155 """Creates a log file for testing for individual packages built by Portage.
156
157 Args:
Mike Frysinger40443592022-05-05 13:03:40 -0400158 log_path: The PORTAGE_LOGDIR path.
159 pkg_info: name components for log file.
160 timestamp: Timestamp used to name the file.
Lizzy Presland4feb2372022-01-20 05:16:30 +0000161 """
162 path = os.path.join(log_path,
163 f'{pkg_info.category}:{pkg_info.pvr}:' \
164 f'{timestamp.strftime("%Y%m%d-%H%M%S")}.log')
Alex Klein4f215432022-05-23 10:41:14 -0600165 osutils.WriteFile(
166 path, f'Test log file for package {pkg_info.category}/'
167 f'{pkg_info.package} written to {path}')
Lizzy Presland4feb2372022-01-20 05:16:30 +0000168 return path
169
Alex Klein231d2da2019-07-22 16:44:45 -0600170 def testValidateOnly(self):
171 """Sanity check that a validate only call does not execute any logic."""
172 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
173
Alex Klein0aecf472022-05-23 10:48:45 -0600174 input_msg = self._GetInput(board='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600175 test_controller.BuildTargetUnitTest(input_msg, self._GetOutput(),
176 self.validate_only_config)
177 patch.assert_not_called()
178
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700179 def testMockCall(self):
180 """Test that a mock call does not execute logic, returns mocked value."""
181 patch = self.PatchObject(test_service, 'BuildTargetUnitTest')
182
Alex Klein0aecf472022-05-23 10:48:45 -0600183 input_msg = self._GetInput(board='board')
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700184 response = self._GetOutput()
185 test_controller.BuildTargetUnitTest(input_msg, response,
186 self.mock_call_config)
187 patch.assert_not_called()
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700188
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
Alex Klein0aecf472022-05-23 10:48:45 -0600193 input_msg = self._GetInput(board='board')
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700194 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)
Lizzy Presland239459a2022-05-05 22:03:19 +0000199 self.assertTrue(response.failed_package_data)
200 self.assertEqual(response.failed_package_data[0].name.category, 'foo')
201 self.assertEqual(response.failed_package_data[0].name.package_name, 'bar')
202 self.assertEqual(response.failed_package_data[1].name.category, 'cat')
203 self.assertEqual(response.failed_package_data[1].name.package_name, 'pkg')
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700204
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')
Alex Klein0aecf472022-05-23 10:48:45 -0600209 input_msg = self._GetInput(board='board', packages=[pkg])
Alex Klein64ac34c2020-09-23 10:21:33 -0600210 output_msg = self._GetOutput()
211 with self.assertRaises(cros_build_lib.DieSystemExit):
212 test_controller.BuildTargetUnitTest(input_msg, output_msg,
213 self.api_config)
214
Alex Kleina2e42c42019-04-17 16:13:19 -0600215 def testPackageBuildFailure(self):
216 """Test handling of raised BuildPackageFailure."""
217 tempdir = osutils.TempDir(base_dir=self.tempdir)
218 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
219
Lizzy Presland4feb2372022-01-20 05:16:30 +0000220 pkgs = ['cat/pkg-1.0-r1', 'foo/bar-2.0-r1']
221 cpvrs = [package_info.parse(pkg) for pkg in pkgs]
Alex Kleina2e42c42019-04-17 16:13:19 -0600222 expected = [('cat', 'pkg'), ('foo', 'bar')]
Lizzy Presland4feb2372022-01-20 05:16:30 +0000223 new_logs = {}
224 for i, pkg in enumerate(pkgs):
225 self._CreatePortageLogFile(self.portage_dir, cpvrs[i],
226 datetime.datetime(2021, 6, 9, 13, 37, 0))
Alex Klein4f215432022-05-23 10:41:14 -0600227 new_logs[pkg] = self._CreatePortageLogFile(
228 self.portage_dir, cpvrs[i], datetime.datetime(2021, 6, 9, 16, 20, 0))
Alex Kleina2e42c42019-04-17 16:13:19 -0600229
Alex Klein38c7d9e2019-05-08 09:31:19 -0600230 result = test_service.BuildTargetUnitTestResult(1, None)
Alex Kleinea0c89e2021-09-09 15:17:35 -0600231 result.failed_pkgs = [package_info.parse(p) for p in pkgs]
Alex Klein38c7d9e2019-05-08 09:31:19 -0600232 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
Alex Kleina2e42c42019-04-17 16:13:19 -0600233
Alex Klein0aecf472022-05-23 10:48:45 -0600234 input_msg = self._GetInput(board='board')
Alex Kleina2e42c42019-04-17 16:13:19 -0600235 output_msg = self._GetOutput()
236
Alex Klein231d2da2019-07-22 16:44:45 -0600237 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg,
238 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600239
Alex Klein8cb365a2019-05-15 16:24:53 -0600240 self.assertEqual(controller.RETURN_CODE_UNSUCCESSFUL_RESPONSE_AVAILABLE, rc)
Lizzy Presland4feb2372022-01-20 05:16:30 +0000241 self.assertTrue(output_msg.failed_package_data)
Alex Kleina2e42c42019-04-17 16:13:19 -0600242
Lizzy Presland4feb2372022-01-20 05:16:30 +0000243 failed_with_logs = []
244 for data in output_msg.failed_package_data:
245 failed_with_logs.append((data.name.category, data.name.package_name))
246 package = controller_util.deserialize_package_info(data.name)
247 self.assertEqual(data.log_path.path, new_logs[package.cpvr])
248 self.assertCountEqual(expected, failed_with_logs)
249
Alex Kleina2e42c42019-04-17 16:13:19 -0600250 def testOtherBuildScriptFailure(self):
251 """Test build script failure due to non-package emerge error."""
252 tempdir = osutils.TempDir(base_dir=self.tempdir)
253 self.PatchObject(osutils, 'TempDir', return_value=tempdir)
254
Alex Klein38c7d9e2019-05-08 09:31:19 -0600255 result = test_service.BuildTargetUnitTestResult(1, None)
256 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
Alex Kleina2e42c42019-04-17 16:13:19 -0600257
Alex Kleinf2674462019-05-16 16:47:24 -0600258 pkgs = ['foo/bar', 'cat/pkg']
Alex Kleinb64e5f82020-09-23 10:55:31 -0600259 blocklist = [package_info.SplitCPV(p, strict=False) for p in pkgs]
Alex Klein4f215432022-05-23 10:41:14 -0600260 input_msg = self._GetInput(
261 board='board', empty_sysroot=True, blocklist=blocklist)
Alex Kleina2e42c42019-04-17 16:13:19 -0600262 output_msg = self._GetOutput()
263
Alex Klein231d2da2019-07-22 16:44:45 -0600264 rc = test_controller.BuildTargetUnitTest(input_msg, output_msg,
265 self.api_config)
Alex Kleina2e42c42019-04-17 16:13:19 -0600266
Alex Klein8cb365a2019-05-15 16:24:53 -0600267 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
Lizzy Presland239459a2022-05-05 22:03:19 +0000268 self.assertFalse(output_msg.failed_package_data)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600269
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700270 def testBuildTargetUnitTest(self):
271 """Test BuildTargetUnitTest successful call."""
Navil Perezc0b29a82020-07-07 14:17:48 +0000272 pkgs = ['foo/bar', 'cat/pkg']
Alex Klein18a60af2020-06-11 12:08:47 -0600273 packages = [package_info.SplitCPV(p, strict=False) for p in pkgs]
Alex Klein2e91e522022-01-14 09:22:03 -0700274 input_msg = self._GetInput(board='board', packages=packages)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700275
276 result = test_service.BuildTargetUnitTestResult(0, None)
277 self.PatchObject(test_service, 'BuildTargetUnitTest', return_value=result)
278
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700279 response = self._GetOutput()
Alex Klein4f215432022-05-23 10:41:14 -0600280 test_controller.BuildTargetUnitTest(input_msg, response, self.api_config)
Lizzy Presland239459a2022-05-05 22:03:19 +0000281 self.assertFalse(response.failed_package_data)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700282
Evan Hernandez4e388a52019-05-01 12:16:33 -0600283
Sean McAllister17eed8d2021-09-21 10:41:16 -0600284class DockerConstraintsTest(cros_test_lib.MockTestCase):
285 """Tests for Docker argument constraints."""
286
287 def assertValid(self, output):
288 return output is None
289
290 def assertInvalid(self, output):
291 return not self.assertValid(output)
292
293 def testValidDockerTag(self):
294 """Check logic for validating docker tag format."""
295 # pylint: disable=protected-access
296
297 invalid_tags = [
298 '.invalid-tag',
299 '-invalid-tag',
300 'invalid-tag;',
Alex Klein4f215432022-05-23 10:41:14 -0600301 'invalid' * 100,
Sean McAllister17eed8d2021-09-21 10:41:16 -0600302 ]
303
304 for tag in invalid_tags:
305 self.assertInvalid(test_controller._ValidDockerTag(tag))
306
307 valid_tags = [
308 'valid-tag',
309 'valid-tag-',
310 'valid.tag.',
311 ]
312
313 for tag in valid_tags:
314 self.assertValid(test_controller._ValidDockerTag(tag))
315
Sean McAllister17eed8d2021-09-21 10:41:16 -0600316 def testValidDockerLabelKey(self):
317 """Check logic for validating docker label key format."""
318 # pylint: disable=protected-access
319
320 invalid_keys = [
321 'Invalid-keY',
322 'Invalid-key',
323 'invalid-keY',
324 'iNVALID-KEy',
325 'invalid_key',
326 'invalid-key;',
327 ]
328
329 for key in invalid_keys:
330 self.assertInvalid(test_controller._ValidDockerLabelKey(key))
331
332 valid_keys = [
333 'chromeos.valid-key',
334 'chromeos.valid-key-2',
335 ]
336
337 for key in valid_keys:
338 self.assertValid(test_controller._ValidDockerLabelKey(key))
339
340
Sean McAllister3834fef2021-10-08 15:45:18 -0600341class BuildTestServiceContainers(cros_test_lib.RunCommandTempDirTestCase,
David Wellingc1433c22021-06-25 16:29:48 +0000342 api_config.ApiConfigMixin):
C Shapiro91af1ce2021-06-17 12:42:09 -0500343 """Tests for the BuildTestServiceContainers function."""
344
345 def setUp(self):
346 self.request = test_pb2.BuildTestServiceContainersRequest(
347 chroot={'path': '/path/to/chroot'},
348 build_target={'name': 'build_target'},
David Wellingc1433c22021-06-25 16:29:48 +0000349 version='R93-14033.0.0',
C Shapiro91af1ce2021-06-17 12:42:09 -0500350 )
351
C Shapiro91af1ce2021-06-17 12:42:09 -0500352 def testSuccess(self):
353 """Check passing case with mocked cros_build_lib.run."""
Sean McAllister3834fef2021-10-08 15:45:18 -0600354
355 def ContainerMetadata():
356 """Return mocked ContainerImageInfo proto"""
357 metadata = container_metadata_pb2.ContainerImageInfo()
358 metadata.repository.hostname = 'gcr.io'
359 metadata.repository.project = 'chromeos-bot'
360 metadata.name = 'random-container-name'
361 metadata.digest = (
362 '09b730f8b6a862f9c2705cb3acf3554563325f5fca5c784bf5c98beb2e56f6db')
363 metadata.tags[:] = [
364 'staging-cq-amd64-generic.R96-1.2.3',
365 '8834106026340379089',
366 ]
367 return metadata
368
369 def WriteContainerMetadata(path):
370 """Write json formatted metadata to the given file."""
371 osutils.WriteFile(
372 path,
373 json_format.MessageToJson(ContainerMetadata()),
374 )
375
376 # Write out mocked container metadata to a temporary file.
377 output_path = os.path.join(self.tempdir, 'metadata.jsonpb')
378 self.rc.SetDefaultCmdResult(
379 returncode=0,
Alex Klein4f215432022-05-23 10:41:14 -0600380 side_effect=lambda *_, **__: WriteContainerMetadata(output_path))
Sean McAllister3834fef2021-10-08 15:45:18 -0600381
382 # Patch TempDir so that we always use this test's directory.
383 self.PatchObject(osutils.TempDir, '__enter__', return_value=self.tempdir)
C Shapiro91af1ce2021-06-17 12:42:09 -0500384
385 response = test_pb2.BuildTestServiceContainersResponse()
Alex Klein4f215432022-05-23 10:41:14 -0600386 test_controller.BuildTestServiceContainers(self.request, response,
387 self.api_config)
Sean McAllister3834fef2021-10-08 15:45:18 -0600388
389 self.assertTrue(self.rc.called)
C Shapiro91af1ce2021-06-17 12:42:09 -0500390 for result in response.results:
391 self.assertEqual(result.WhichOneof('result'), 'success')
Sean McAllister3834fef2021-10-08 15:45:18 -0600392 self.assertEqual(result.success.image_info, ContainerMetadata())
C Shapiro91af1ce2021-06-17 12:42:09 -0500393
C Shapiro91af1ce2021-06-17 12:42:09 -0500394 def testFailure(self):
395 """Check failure case with mocked cros_build_lib.run."""
396 patch = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600397 cros_build_lib,
398 'run',
C Shapiro91af1ce2021-06-17 12:42:09 -0500399 return_value=cros_build_lib.CommandResult(returncode=1))
400
401 response = test_pb2.BuildTestServiceContainersResponse()
Alex Klein4f215432022-05-23 10:41:14 -0600402 test_controller.BuildTestServiceContainers(self.request, response,
403 self.api_config)
C Shapiro91af1ce2021-06-17 12:42:09 -0500404 patch.assert_called()
405 for result in response.results:
Derek Beckett27eaa162022-05-09 10:42:53 -0700406 self.assertEqual(result.WhichOneof('result'), 'failure')
Derek Beckett344b5a82022-05-09 17:21:45 -0700407 self.assertEqual(result.name, 'Service Builder')
C Shapiro91af1ce2021-06-17 12:42:09 -0500408
Alex Klein4f215432022-05-23 10:41:14 -0600409
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700410class ChromiteUnitTestTest(cros_test_lib.MockTestCase,
411 api_config.ApiConfigMixin):
412 """Tests for the ChromiteInfoTest function."""
413
414 def setUp(self):
415 self.board = 'board'
416 self.chroot_path = '/path/to/chroot'
417
418 def _GetInput(self, chroot_path=None):
419 """Helper to build an input message instance."""
Alex Klein4f215432022-05-23 10:41:14 -0600420 proto = test_pb2.ChromiteUnitTestRequest(chroot={'path': chroot_path},)
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700421 return proto
422
423 def _GetOutput(self):
424 """Helper to get an empty output message instance."""
425 return test_pb2.ChromiteUnitTestResponse()
426
427 def testValidateOnly(self):
428 """Sanity check that a validate only call does not execute any logic."""
429 patch = self.PatchObject(cros_build_lib, 'run')
430
431 input_msg = self._GetInput(chroot_path=self.chroot_path)
432 test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
433 self.validate_only_config)
434 patch.assert_not_called()
435
Michael Mortensen7a860eb2019-12-03 20:25:15 -0700436 def testMockError(self):
437 """Test mock error call does not execute any logic, returns error."""
438 patch = self.PatchObject(cros_build_lib, 'run')
439
440 input_msg = self._GetInput(chroot_path=self.chroot_path)
441 rc = test_controller.ChromiteUnitTest(input_msg, self._GetOutput(),
442 self.mock_error_config)
443 patch.assert_not_called()
444 self.assertEqual(controller.RETURN_CODE_COMPLETED_UNSUCCESSFULLY, rc)
445
446 def testMockCall(self):
447 """Test mock call does not execute any logic, returns success."""
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_call_config)
453 patch.assert_not_called()
454 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
455
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700456 def testChromiteUnitTest(self):
457 """Call ChromiteUnitTest with mocked cros_build_lib.run."""
458 request = self._GetInput(chroot_path=self.chroot_path)
459 patch = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600460 cros_build_lib,
461 'run',
Michael Mortensen8ca4d3b2019-11-27 09:35:22 -0700462 return_value=cros_build_lib.CommandResult(returncode=0))
463
464 test_controller.ChromiteUnitTest(request, self._GetOutput(),
465 self.api_config)
466 patch.assert_called_once()
467
468
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600469class CrosSigningTestTest(cros_test_lib.RunCommandTestCase,
470 api_config.ApiConfigMixin):
471 """CrosSigningTest tests."""
472
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700473 def setUp(self):
474 self.chroot_path = '/path/to/chroot'
475
476 def _GetInput(self, chroot_path=None):
477 """Helper to build an input message instance."""
Alex Klein4f215432022-05-23 10:41:14 -0600478 proto = test_pb2.CrosSigningTestRequest(chroot={'path': chroot_path},)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700479 return proto
480
481 def _GetOutput(self):
482 """Helper to get an empty output message instance."""
483 return test_pb2.CrosSigningTestResponse()
484
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600485 def testValidateOnly(self):
486 """Sanity check that a validate only call does not execute any logic."""
487 test_controller.CrosSigningTest(None, None, self.validate_only_config)
488 self.assertFalse(self.rc.call_count)
489
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700490 def testMockCall(self):
491 """Test mock call does not execute any logic, returns success."""
492 rc = test_controller.CrosSigningTest(None, None, self.mock_call_config)
493 self.assertFalse(self.rc.call_count)
494 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
495
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700496 def testCrosSigningTest(self):
497 """Call CrosSigningTest with mocked cros_build_lib.run."""
498 request = self._GetInput(chroot_path=self.chroot_path)
499 patch = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600500 cros_build_lib,
501 'run',
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700502 return_value=cros_build_lib.CommandResult(returncode=0))
503
Alex Klein4f215432022-05-23 10:41:14 -0600504 test_controller.CrosSigningTest(request, self._GetOutput(), self.api_config)
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700505 patch.assert_called_once()
506
Alex Klein4bc8f4f2019-08-16 14:53:30 -0600507
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600508class SimpleChromeWorkflowTestTest(cros_test_lib.MockTestCase,
509 api_config.ApiConfigMixin):
510 """Test the SimpleChromeWorkflowTest endpoint."""
511
512 @staticmethod
513 def _Output():
514 return test_pb2.SimpleChromeWorkflowTestResponse()
515
David Wellingc1433c22021-06-25 16:29:48 +0000516 def _Input(self,
517 sysroot_path=None,
518 build_target=None,
519 chrome_root=None,
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600520 goma_config=None):
521 proto = test_pb2.SimpleChromeWorkflowTestRequest()
522 if sysroot_path:
523 proto.sysroot.path = sysroot_path
524 if build_target:
525 proto.sysroot.build_target.name = build_target
526 if chrome_root:
527 proto.chrome_root = chrome_root
528 if goma_config:
529 proto.goma_config = goma_config
530 return proto
531
532 def setUp(self):
533 self.chrome_path = 'path/to/chrome'
534 self.sysroot_dir = 'build/board'
535 self.build_target = 'amd64'
536 self.mock_simple_chrome_workflow_test = self.PatchObject(
537 test_service, 'SimpleChromeWorkflowTest')
538
539 def testMissingBuildTarget(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700540 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Alex Klein4f215432022-05-23 10:41:14 -0600541 input_proto = self._Input(
542 build_target=None,
543 sysroot_path='/sysroot/dir',
544 chrome_root='/chrome/path')
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600545 with self.assertRaises(cros_build_lib.DieSystemExit):
546 test_controller.SimpleChromeWorkflowTest(input_proto, None,
547 self.api_config)
548
549 def testMissingSysrootPath(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='board', sysroot_path=None, chrome_root='/chrome/path')
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600553 with self.assertRaises(cros_build_lib.DieSystemExit):
554 test_controller.SimpleChromeWorkflowTest(input_proto, None,
555 self.api_config)
556
557 def testMissingChromeRoot(self):
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700558 """Test SimpleChromeWorkflowTest dies when build_target not set."""
Alex Klein4f215432022-05-23 10:41:14 -0600559 input_proto = self._Input(
560 build_target='board', sysroot_path='/sysroot/dir', chrome_root=None)
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600561 with self.assertRaises(cros_build_lib.DieSystemExit):
562 test_controller.SimpleChromeWorkflowTest(input_proto, None,
563 self.api_config)
564
565 def testSimpleChromeWorkflowTest(self):
566 """Call SimpleChromeWorkflowTest with valid args and temp dir."""
Alex Klein4f215432022-05-23 10:41:14 -0600567 request = self._Input(
568 sysroot_path='sysroot_path',
569 build_target='board',
570 chrome_root='/path/to/chrome')
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600571 response = self._Output()
572
573 test_controller.SimpleChromeWorkflowTest(request, response, self.api_config)
574 self.mock_simple_chrome_workflow_test.assert_called()
575
576 def testValidateOnly(self):
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 test_controller.SimpleChromeWorkflowTest(request, self._Output(),
582 self.validate_only_config)
583 self.mock_simple_chrome_workflow_test.assert_not_called()
584
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700585 def testMockCall(self):
586 """Test mock call does not execute any logic, returns success."""
587 patch = self.mock_simple_chrome_workflow_test = self.PatchObject(
588 test_service, 'SimpleChromeWorkflowTest')
589
Alex Klein4f215432022-05-23 10:41:14 -0600590 request = self._Input(
591 sysroot_path='sysroot_path',
592 build_target='board',
593 chrome_root='/path/to/chrome')
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700594 rc = test_controller.SimpleChromeWorkflowTest(request, self._Output(),
595 self.mock_call_config)
596 patch.assert_not_called()
597 self.assertEqual(controller.RETURN_CODE_SUCCESS, rc)
598
Michael Mortensenc28d6f12019-10-03 13:34:51 -0600599
Alex Klein231d2da2019-07-22 16:44:45 -0600600class VmTestTest(cros_test_lib.RunCommandTestCase, api_config.ApiConfigMixin):
Evan Hernandez4e388a52019-05-01 12:16:33 -0600601 """Test the VmTest endpoint."""
602
603 def _GetInput(self, **kwargs):
604 values = dict(
605 build_target=common_pb2.BuildTarget(name='target'),
Alex Klein4f215432022-05-23 10:41:14 -0600606 vm_path=common_pb2.Path(
607 path='/path/to/image.bin', location=common_pb2.Path.INSIDE),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600608 test_harness=test_pb2.VmTestRequest.TAST,
609 vm_tests=[test_pb2.VmTestRequest.VmTest(pattern='suite')],
610 ssh_options=test_pb2.VmTestRequest.SshOptions(
Alex Klein4f215432022-05-23 10:41:14 -0600611 port=1234,
612 private_key_path={
613 'path': '/path/to/id_rsa',
614 'location': common_pb2.Path.INSIDE
615 }),
Evan Hernandez4e388a52019-05-01 12:16:33 -0600616 )
617 values.update(kwargs)
618 return test_pb2.VmTestRequest(**values)
619
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700620 def _Output(self):
621 return test_pb2.VmTestResponse()
622
Alex Klein231d2da2019-07-22 16:44:45 -0600623 def testValidateOnly(self):
624 """Sanity check that a validate only call does not execute any logic."""
625 test_controller.VmTest(self._GetInput(), None, self.validate_only_config)
626 self.assertEqual(0, self.rc.call_count)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600627
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700628 def testMockCall(self):
629 """Test mock call does not execute any logic."""
630 patch = self.PatchObject(cros_build_lib, 'run')
631
632 request = self._GetInput()
633 response = self._Output()
634 # VmTest does not return a value, checking mocked value is flagged by lint.
635 test_controller.VmTest(request, response, self.mock_call_config)
636 patch.assert_not_called()
637
Evan Hernandez4e388a52019-05-01 12:16:33 -0600638 def testTastAllOptions(self):
639 """Test VmTest for Tast with all options set."""
Alex Klein231d2da2019-07-22 16:44:45 -0600640 test_controller.VmTest(self._GetInput(), None, self.api_config)
641 self.assertCommandContains([
Alex Klein4f215432022-05-23 10:41:14 -0600642 'cros_run_test',
643 '--debug',
644 '--no-display',
645 '--copy-on-write',
646 '--board',
647 'target',
648 '--image-path',
649 '/path/to/image.bin',
650 '--tast',
651 'suite',
652 '--ssh-port',
653 '1234',
654 '--private-key',
655 '/path/to/id_rsa',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600656 ])
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([
Alex Klein4f215432022-05-23 10:41:14 -0600663 'cros_run_test',
664 '--debug',
665 '--no-display',
666 '--copy-on-write',
667 '--board',
668 'target',
669 '--image-path',
670 '/path/to/image.bin',
671 '--autotest',
672 'suite',
673 '--ssh-port',
674 '1234',
675 '--private-key',
676 '/path/to/id_rsa',
Greg Edelstondcb0e912020-08-31 11:09:40 -0600677 '--test_that-args=--allow-chrome-crashes',
Evan Hernandez4e388a52019-05-01 12:16:33 -0600678 ])
679
680 def testMissingBuildTarget(self):
681 """Test VmTest dies when build_target not set."""
682 input_proto = self._GetInput(build_target=None)
683 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600684 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600685
686 def testMissingVmImage(self):
687 """Test VmTest dies when vm_image not set."""
Alex Klein311b8022019-06-05 16:00:07 -0600688 input_proto = self._GetInput(vm_path=None)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600689 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600690 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600691
692 def testMissingTestHarness(self):
693 """Test VmTest dies when test_harness not specified."""
694 input_proto = self._GetInput(
695 test_harness=test_pb2.VmTestRequest.UNSPECIFIED)
696 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600697 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandez4e388a52019-05-01 12:16:33 -0600698
699 def testMissingVmTests(self):
700 """Test VmTest dies when vm_tests not set."""
701 input_proto = self._GetInput(vm_tests=[])
702 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600703 test_controller.VmTest(input_proto, None, self.api_config)
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600704
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700705 def testVmTest(self):
706 """Call VmTest with valid args and temp dir."""
707 request = self._GetInput()
708 response = self._Output()
709 patch = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600710 cros_build_lib,
711 'run',
Michael Mortensen82cd62d2019-12-01 14:58:54 -0700712 return_value=cros_build_lib.CommandResult(returncode=0))
713
714 test_controller.VmTest(request, response, self.api_config)
715 patch.assert_called()
716
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600717
Alex Klein231d2da2019-07-22 16:44:45 -0600718class MoblabVmTestTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600719 """Test the MoblabVmTest endpoint."""
720
721 @staticmethod
722 def _Payload(path):
Alex Klein4f215432022-05-23 10:41:14 -0600723 return test_pb2.MoblabVmTestRequest.Payload(path=common_pb2.Path(path=path))
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600724
725 @staticmethod
726 def _Output():
727 return test_pb2.MoblabVmTestResponse()
728
729 def _Input(self):
730 return test_pb2.MoblabVmTestRequest(
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600731 chroot=common_pb2.Chroot(path=self.chroot_dir),
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600732 image_payload=self._Payload(self.image_payload_dir),
733 cache_payloads=[self._Payload(self.autotest_payload_dir)])
734
735 def setUp(self):
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600736 self.chroot_dir = '/chroot'
737 self.chroot_tmp_dir = '/chroot/tmp'
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600738 self.image_payload_dir = '/payloads/image'
739 self.autotest_payload_dir = '/payloads/autotest'
740 self.builder = 'moblab-generic-vm/R12-3.4.5-67.890'
741 self.image_cache_dir = '/mnt/moblab/cache'
742 self.image_mount_dir = '/mnt/image'
743
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600744 self.PatchObject(chroot_lib.Chroot, 'tempdir', osutils.TempDir)
Evan Hernandez655e8042019-06-13 12:50:44 -0600745
Alex Klein4f215432022-05-23 10:41:14 -0600746 self.mock_create_moblab_vms = self.PatchObject(test_service,
747 'CreateMoblabVm')
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600748 self.mock_prepare_moblab_vm_image_cache = self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600749 test_service,
750 'PrepareMoblabVmImageCache',
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600751 return_value=self.image_cache_dir)
Alex Klein4f215432022-05-23 10:41:14 -0600752 self.mock_run_moblab_vm_tests = self.PatchObject(test_service,
753 'RunMoblabVmTest')
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600754 self.mock_validate_moblab_vm_tests = self.PatchObject(
755 test_service, 'ValidateMoblabVmTest')
756
757 @contextlib.contextmanager
Alex Klein38c7d9e2019-05-08 09:31:19 -0600758 def MockLoopbackPartitions(*_args, **_kwargs):
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600759 mount = mock.MagicMock()
Evan Hernandez40ee7452019-06-13 12:51:43 -0600760 mount.Mount.return_value = [self.image_mount_dir]
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600761 yield mount
Alex Klein231d2da2019-07-22 16:44:45 -0600762
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600763 self.PatchObject(image_lib, 'LoopbackPartitions', MockLoopbackPartitions)
764
Alex Klein231d2da2019-07-22 16:44:45 -0600765 def testValidateOnly(self):
766 """Sanity check that a validate only call does not execute any logic."""
767 test_controller.MoblabVmTest(self._Input(), self._Output(),
768 self.validate_only_config)
769 self.mock_create_moblab_vms.assert_not_called()
770
Michael Mortensen7a7646d2019-12-12 15:36:14 -0700771 def testMockCall(self):
772 """Test mock call does not execute any logic."""
773 patch = self.PatchObject(key_value_store, 'LoadFile')
774
775 # MoblabVmTest does not return a value, checking mocked value is flagged by
776 # lint.
777 test_controller.MoblabVmTest(self._Input(), self._Output(),
778 self.mock_call_config)
779 patch.assert_not_called()
780
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600781 def testImageContainsBuilder(self):
782 """MoblabVmTest calls service with correct args."""
783 request = self._Input()
784 response = self._Output()
785
786 self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600787 key_value_store,
788 'LoadFile',
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600789 return_value={cros_set_lsb_release.LSB_KEY_BUILDER_PATH: self.builder})
790
Alex Klein231d2da2019-07-22 16:44:45 -0600791 test_controller.MoblabVmTest(request, response, self.api_config)
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600792
793 self.assertEqual(
794 self.mock_create_moblab_vms.call_args_list,
Evan Hernandeze1e05d32019-07-19 12:32:18 -0600795 [mock.call(mock.ANY, self.chroot_dir, self.image_payload_dir)])
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600796 self.assertEqual(
797 self.mock_prepare_moblab_vm_image_cache.call_args_list,
798 [mock.call(mock.ANY, self.builder, [self.autotest_payload_dir])])
Alex Klein4f215432022-05-23 10:41:14 -0600799 self.assertEqual(self.mock_run_moblab_vm_tests.call_args_list, [
800 mock.call(mock.ANY, mock.ANY, self.builder, self.image_cache_dir,
801 mock.ANY)
802 ])
803 self.assertEqual(self.mock_validate_moblab_vm_tests.call_args_list,
804 [mock.call(mock.ANY)])
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600805
806 def testImageMissingBuilder(self):
807 """MoblabVmTest dies when builder path not found in lsb-release."""
808 request = self._Input()
809 response = self._Output()
810
Mike Frysingere652ba12019-09-08 00:57:43 -0400811 self.PatchObject(key_value_store, 'LoadFile', return_value={})
Evan Hernandezdc3f0bb2019-06-06 12:46:52 -0600812
813 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600814 test_controller.MoblabVmTest(request, response, self.api_config)
David Wellingc1433c22021-06-25 16:29:48 +0000815
816
817class GetArtifactsTest(cros_test_lib.MockTempDirTestCase):
818 """Test GetArtifacts."""
819
820 CODE_COVERAGE_LLVM_ARTIFACT_TYPE = (
Alex Klein4f215432022-05-23 10:41:14 -0600821 common_pb2.ArtifactsByService.Test.ArtifactType.CODE_COVERAGE_LLVM_JSON)
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600822 UNIT_TEST_ARTIFACT_TYPE = (
Alex Klein4f215432022-05-23 10:41:14 -0600823 common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS)
David Wellingc1433c22021-06-25 16:29:48 +0000824
825 def setUp(self):
826 """Set up the class for tests."""
827 chroot_dir = os.path.join(self.tempdir, 'chroot')
828 osutils.SafeMakedirs(chroot_dir)
829 osutils.SafeMakedirs(os.path.join(chroot_dir, 'tmp'))
830 self.chroot = chroot_lib.Chroot(chroot_dir)
831
832 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
833 osutils.SafeMakedirs(sysroot_path)
834 self.sysroot = sysroot_lib.Sysroot(sysroot_path)
835
Jack Neusc9707c32021-07-23 21:48:54 +0000836 self.build_target = build_target_lib.BuildTarget('board')
837
David Wellingc1433c22021-06-25 16:29:48 +0000838 def testReturnsEmptyListWhenNoOutputArtifactsProvided(self):
839 """Test empty list is returned when there are no output_artifacts."""
840 result = test_controller.GetArtifacts(
Alex Klein4f215432022-05-23 10:41:14 -0600841 common_pb2.ArtifactsByService.Test(output_artifacts=[]), self.chroot,
842 self.sysroot, self.build_target, self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000843
844 self.assertEqual(len(result), 0)
845
846 def testShouldCallBundleCodeCoverageLlvmJsonForEachValidArtifact(self):
847 """Test BundleCodeCoverageLlvmJson is called on each valid artifact."""
Sean McAllister17eed8d2021-09-21 10:41:16 -0600848 BundleCodeCoverageLlvmJson_mock = (
849 self.PatchObject(
Alex Klein4f215432022-05-23 10:41:14 -0600850 test_service, 'BundleCodeCoverageLlvmJson', return_value='test'))
David Wellingc1433c22021-06-25 16:29:48 +0000851
852 test_controller.GetArtifacts(
853 common_pb2.ArtifactsByService.Test(output_artifacts=[
854 # Valid
855 common_pb2.ArtifactsByService.Test.ArtifactInfo(
Alex Klein4f215432022-05-23 10:41:14 -0600856 artifact_types=[self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE]),
David Wellingc1433c22021-06-25 16:29:48 +0000857
858 # Invalid
Alex Klein4f215432022-05-23 10:41:14 -0600859 common_pb2.ArtifactsByService.Test.ArtifactInfo(artifact_types=[
860 common_pb2.ArtifactsByService.Test.ArtifactType.UNIT_TESTS
861 ]),
David Wellingc1433c22021-06-25 16:29:48 +0000862 ]),
Alex Klein4f215432022-05-23 10:41:14 -0600863 self.chroot,
864 self.sysroot,
865 self.build_target,
866 self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000867
868 BundleCodeCoverageLlvmJson_mock.assert_called_once()
869
870 def testShouldReturnValidResult(self):
871 """Test result contains paths and code_coverage_llvm_json type."""
Alex Klein4f215432022-05-23 10:41:14 -0600872 self.PatchObject(
873 test_service, 'BundleCodeCoverageLlvmJson', return_value='test')
874 self.PatchObject(
875 test_service,
876 'BuildTargetUnitTestTarball',
877 return_value='unit_tests.tar')
David Wellingc1433c22021-06-25 16:29:48 +0000878
879 result = test_controller.GetArtifacts(
880 common_pb2.ArtifactsByService.Test(output_artifacts=[
881 # Valid
882 common_pb2.ArtifactsByService.Test.ArtifactInfo(
Alex Klein4f215432022-05-23 10:41:14 -0600883 artifact_types=[self.UNIT_TEST_ARTIFACT_TYPE]),
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600884 common_pb2.ArtifactsByService.Test.ArtifactInfo(
Alex Klein4f215432022-05-23 10:41:14 -0600885 artifact_types=[self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE]),
David Wellingc1433c22021-06-25 16:29:48 +0000886 ]),
Alex Klein4f215432022-05-23 10:41:14 -0600887 self.chroot,
888 self.sysroot,
889 self.build_target,
890 self.tempdir)
David Wellingc1433c22021-06-25 16:29:48 +0000891
George Engelbrecht764b1cd2021-06-18 17:01:07 -0600892 self.assertEqual(result[0]['paths'], ['unit_tests.tar'])
893 self.assertEqual(result[0]['type'], self.UNIT_TEST_ARTIFACT_TYPE)
894 self.assertEqual(result[1]['paths'], ['test'])
895 self.assertEqual(result[1]['type'], self.CODE_COVERAGE_LLVM_ARTIFACT_TYPE)