blob: 7520acb68099167884703d47dd306d32a5078d56 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Evan Hernandezf388cbf2019-04-01 11:15:23 -06002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Unittests for Artifacts operations."""
6
Evan Hernandezf388cbf2019-04-01 11:15:23 -06007import os
Greg Edelstondc941072021-08-11 12:32:30 -06008import pathlib
Varun Somani04dccd72021-10-09 01:06:11 +00009from typing import Optional
Mike Frysinger166fea02021-02-12 05:30:33 -050010from unittest import mock
Evan Hernandezf388cbf2019-04-01 11:15:23 -060011
Alex Klein231d2da2019-07-22 16:44:45 -060012from chromite.api import api_config
Evan Hernandezf388cbf2019-04-01 11:15:23 -060013from chromite.api.controller import artifacts
Greg Edelstondc941072021-08-11 12:32:30 -060014from chromite.api.controller import controller_util
Jack Neus26b94672022-10-27 17:33:21 +000015from chromite.api.controller import image as image_controller
16from chromite.api.controller import sysroot as sysroot_controller
17from chromite.api.controller import test as test_controller
Evan Hernandezf388cbf2019-04-01 11:15:23 -060018from chromite.api.gen.chromite.api import artifacts_pb2
Jack Neus26b94672022-10-27 17:33:21 +000019from chromite.api.gen.chromite.api import sysroot_pb2
Greg Edelstondc941072021-08-11 12:32:30 -060020from chromite.api.gen.chromiumos import common_pb2
Evan Hernandezf388cbf2019-04-01 11:15:23 -060021from chromite.cbuildbot import commands
Alex Kleinb9d810b2019-07-01 12:38:02 -060022from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060023from chromite.lib import constants
24from chromite.lib import cros_build_lib
25from chromite.lib import cros_test_lib
26from chromite.lib import osutils
Alex Klein238d8862019-05-07 11:32:46 -060027from chromite.lib import sysroot_lib
Alex Klein2275d692019-04-23 16:04:12 -060028from chromite.service import artifacts as artifacts_svc
Evan Hernandezf388cbf2019-04-01 11:15:23 -060029
30
Alex Klein074f94f2023-06-22 10:32:06 -060031class BundleRequestMixin:
Alex Klein1699fab2022-09-08 08:46:06 -060032 """Mixin to provide bundle request methods."""
Alex Kleind91e95a2019-09-17 10:39:02 -060033
Alex Klein1699fab2022-09-08 08:46:06 -060034 def EmptyRequest(self):
35 return artifacts_pb2.BundleRequest()
Alex Kleind91e95a2019-09-17 10:39:02 -060036
Alex Klein1699fab2022-09-08 08:46:06 -060037 def BuildTargetRequest(
38 self, build_target=None, output_dir=None, chroot=None
39 ):
40 """Get a build target format request instance."""
41 request = self.EmptyRequest()
42 if build_target:
43 request.build_target.name = build_target
44 if output_dir:
45 request.output_dir = output_dir
46 if chroot:
47 request.chroot.path = chroot
Alex Kleind91e95a2019-09-17 10:39:02 -060048
Alex Klein1699fab2022-09-08 08:46:06 -060049 return request
Alex Kleind91e95a2019-09-17 10:39:02 -060050
Alex Klein1699fab2022-09-08 08:46:06 -060051 def SysrootRequest(
Brian Norris09937012023-03-31 15:16:55 -070052 self,
53 sysroot=None,
54 build_target=None,
55 output_dir=None,
56 chroot=None,
57 chroot_out=None,
Alex Klein1699fab2022-09-08 08:46:06 -060058 ):
59 """Get a sysroot format request instance."""
60 request = self.EmptyRequest()
61 if sysroot:
62 request.sysroot.path = sysroot
63 if build_target:
64 request.sysroot.build_target.name = build_target
65 if output_dir:
66 request.output_dir = output_dir
67 if chroot:
Brian Norris09937012023-03-31 15:16:55 -070068 request.chroot.path = str(chroot)
69 if chroot_out:
70 request.chroot.out_path = str(chroot_out)
Alex Kleind91e95a2019-09-17 10:39:02 -060071
Alex Klein1699fab2022-09-08 08:46:06 -060072 return request
Alex Kleind91e95a2019-09-17 10:39:02 -060073
74
Alex Klein1699fab2022-09-08 08:46:06 -060075class BundleTestCase(
76 cros_test_lib.MockTempDirTestCase,
77 api_config.ApiConfigMixin,
78 BundleRequestMixin,
79):
80 """Basic setup for all artifacts unittests."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -060081
Alex Klein1699fab2022-09-08 08:46:06 -060082 def setUp(self):
83 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
84 self.output_dir = os.path.join(self.tempdir, "artifacts")
85 osutils.SafeMakedirs(self.output_dir)
86 self.sysroot_path = "/build/target"
87 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Brian Norrisa9cc6b32023-05-10 13:43:45 -070088 self.chroot = chroot_lib.Chroot(
89 path=self.tempdir / "chroot",
90 out_path=self.tempdir / "out",
Alex Klein1699fab2022-09-08 08:46:06 -060091 )
Brian Norrisa9cc6b32023-05-10 13:43:45 -070092 full_sysroot_path = self.chroot.full_path(self.sysroot_path)
Alex Klein1699fab2022-09-08 08:46:06 -060093 osutils.SafeMakedirs(full_sysroot_path)
Brian Norrisa9cc6b32023-05-10 13:43:45 -070094 osutils.SafeMakedirs(self.chroot.path)
95 osutils.SafeMakedirs(self.chroot.out_path)
Alex Klein231d2da2019-07-22 16:44:45 -060096
Alex Klein1699fab2022-09-08 08:46:06 -060097 # All requests use same response type.
98 self.response = artifacts_pb2.BundleResponse()
Alex Klein231d2da2019-07-22 16:44:45 -060099
Alex Klein1699fab2022-09-08 08:46:06 -0600100 # Build target request.
101 self.target_request = self.BuildTargetRequest(
102 build_target="target",
103 output_dir=self.output_dir,
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700104 chroot=self.chroot.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600105 )
Alex Klein68c8fdf2019-09-25 15:09:11 -0600106
Alex Klein1699fab2022-09-08 08:46:06 -0600107 # Sysroot request.
108 self.sysroot_request = self.SysrootRequest(
109 sysroot=self.sysroot_path,
110 build_target="target",
111 output_dir=self.output_dir,
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700112 chroot=self.chroot.path,
113 chroot_out=self.chroot.out_path,
Alex Klein1699fab2022-09-08 08:46:06 -0600114 )
Alex Klein68c8fdf2019-09-25 15:09:11 -0600115
Alex Klein1699fab2022-09-08 08:46:06 -0600116 self.source_root = self.tempdir
117 self.PatchObject(constants, "SOURCE_ROOT", new=self.tempdir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600118
119
Alex Kleind91e95a2019-09-17 10:39:02 -0600120class BundleImageArchivesTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600121 """BundleImageArchives tests."""
Alex Kleind91e95a2019-09-17 10:39:02 -0600122
Alex Klein1699fab2022-09-08 08:46:06 -0600123 def testValidateOnly(self):
124 """Quick check that a validate only call does not execute any logic."""
125 patch = self.PatchObject(artifacts_svc, "ArchiveImages")
126 artifacts.BundleImageArchives(
Hsin-Yi Wang09663da2023-06-28 21:40:24 +0800127 self.sysroot_request, self.response, self.validate_only_config
Alex Klein1699fab2022-09-08 08:46:06 -0600128 )
129 patch.assert_not_called()
Alex Kleind91e95a2019-09-17 10:39:02 -0600130
Alex Klein1699fab2022-09-08 08:46:06 -0600131 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700132 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600133 patch = self.PatchObject(artifacts_svc, "ArchiveImages")
134 artifacts.BundleImageArchives(
Hsin-Yi Wang09663da2023-06-28 21:40:24 +0800135 self.sysroot_request, self.response, self.mock_call_config
Alex Klein1699fab2022-09-08 08:46:06 -0600136 )
137 patch.assert_not_called()
138 self.assertEqual(len(self.response.artifacts), 2)
139 self.assertEqual(
140 self.response.artifacts[0].path,
141 os.path.join(self.output_dir, "path0.tar.xz"),
142 )
143 self.assertEqual(
144 self.response.artifacts[1].path,
145 os.path.join(self.output_dir, "path1.tar.xz"),
146 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700147
Alex Klein1699fab2022-09-08 08:46:06 -0600148 def testNoBuildTarget(self):
149 """Test that no build target fails."""
150 request = self.BuildTargetRequest(output_dir=str(self.tempdir))
151 with self.assertRaises(cros_build_lib.DieSystemExit):
152 artifacts.BundleImageArchives(
153 request, self.response, self.api_config
154 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600155
Alex Klein1699fab2022-09-08 08:46:06 -0600156 def testNoOutputDir(self):
157 """Test no output dir fails."""
158 request = self.BuildTargetRequest(build_target="board")
159 with self.assertRaises(cros_build_lib.DieSystemExit):
160 artifacts.BundleImageArchives(
161 request, self.response, self.api_config
162 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600163
Alex Klein1699fab2022-09-08 08:46:06 -0600164 def testInvalidOutputDir(self):
165 """Test invalid output dir fails."""
166 request = self.BuildTargetRequest(
167 build_target="board", output_dir=os.path.join(self.tempdir, "DNE")
168 )
169 with self.assertRaises(cros_build_lib.DieSystemExit):
170 artifacts.BundleImageArchives(
171 request, self.response, self.api_config
172 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600173
Alex Klein1699fab2022-09-08 08:46:06 -0600174 def testOutputHandling(self):
175 """Test the artifact output handling."""
176 expected = [os.path.join(self.output_dir, f) for f in ("a", "b", "c")]
177 self.PatchObject(artifacts_svc, "ArchiveImages", return_value=expected)
178 self.PatchObject(os.path, "exists", return_value=True)
Alex Kleind91e95a2019-09-17 10:39:02 -0600179
Alex Klein1699fab2022-09-08 08:46:06 -0600180 artifacts.BundleImageArchives(
Hsin-Yi Wang09663da2023-06-28 21:40:24 +0800181 self.sysroot_request, self.response, self.api_config
Alex Klein1699fab2022-09-08 08:46:06 -0600182 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600183
Alex Klein1699fab2022-09-08 08:46:06 -0600184 self.assertCountEqual(
185 expected, [a.path for a in self.response.artifacts]
186 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600187
188
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600189class BundleImageZipTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600190 """Unittests for BundleImageZip."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600191
Alex Klein1699fab2022-09-08 08:46:06 -0600192 def testValidateOnly(self):
193 """Quick check that a validate only call does not execute any logic."""
194 patch = self.PatchObject(commands, "BuildImageZip")
195 artifacts.BundleImageZip(
196 self.target_request, self.response, self.validate_only_config
197 )
198 patch.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600199
Alex Klein1699fab2022-09-08 08:46:06 -0600200 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700201 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600202 patch = self.PatchObject(commands, "BuildImageZip")
203 artifacts.BundleImageZip(
204 self.target_request, self.response, self.mock_call_config
205 )
206 patch.assert_not_called()
207 self.assertEqual(len(self.response.artifacts), 1)
208 self.assertEqual(
209 self.response.artifacts[0].path,
210 os.path.join(self.output_dir, "image.zip"),
211 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700212
Alex Klein1699fab2022-09-08 08:46:06 -0600213 def testBundleImageZip(self):
214 """BundleImageZip calls cbuildbot/commands with correct args."""
215 bundle_image_zip = self.PatchObject(
216 artifacts_svc, "BundleImageZip", return_value="image.zip"
217 )
218 self.PatchObject(os.path, "exists", return_value=True)
219 artifacts.BundleImageZip(
220 self.target_request, self.response, self.api_config
221 )
222 self.assertEqual(
223 [artifact.path for artifact in self.response.artifacts],
224 [os.path.join(self.output_dir, "image.zip")],
225 )
Alex Klein231d2da2019-07-22 16:44:45 -0600226
Alex Klein1699fab2022-09-08 08:46:06 -0600227 latest = os.path.join(
228 self.source_root, "src/build/images/target/latest"
229 )
230 self.assertEqual(
231 bundle_image_zip.call_args_list,
232 [mock.call(self.output_dir, latest)],
233 )
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600234
Alex Klein1699fab2022-09-08 08:46:06 -0600235 def testBundleImageZipNoImageDir(self):
236 """BundleImageZip dies when image dir does not exist."""
237 self.PatchObject(os.path, "exists", return_value=False)
238 with self.assertRaises(cros_build_lib.DieSystemExit):
239 artifacts.BundleImageZip(
240 self.target_request, self.response, self.api_config
241 )
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600242
243
Alex Klein68c8fdf2019-09-25 15:09:11 -0600244class BundleAutotestFilesTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600245 """Unittests for BundleAutotestFiles."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600246
Alex Klein1699fab2022-09-08 08:46:06 -0600247 def testValidateOnly(self):
248 """Quick check that a validate only call does not execute any logic."""
249 patch = self.PatchObject(artifacts_svc, "BundleAutotestFiles")
250 artifacts.BundleAutotestFiles(
251 self.sysroot_request, self.response, self.validate_only_config
252 )
253 patch.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600254
Alex Klein1699fab2022-09-08 08:46:06 -0600255 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700256 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600257 patch = self.PatchObject(artifacts_svc, "BundleAutotestFiles")
258 artifacts.BundleAutotestFiles(
259 self.sysroot_request, self.response, self.mock_call_config
260 )
261 patch.assert_not_called()
262 self.assertEqual(len(self.response.artifacts), 1)
263 self.assertEqual(
264 self.response.artifacts[0].path,
265 os.path.join(self.output_dir, "autotest-a.tar.gz"),
266 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700267
Alex Klein1699fab2022-09-08 08:46:06 -0600268 def testBundleAutotestFiles(self):
269 """BundleAutotestFiles calls service correctly."""
Alex Kleinab87ceb2023-01-24 12:00:51 -0700270
Alex Klein1699fab2022-09-08 08:46:06 -0600271 files = {
Alex Kleinab87ceb2023-01-24 12:00:51 -0700272 artifacts_svc.ARCHIVE_CONTROL_FILES: (
273 "/tmp/artifacts/autotest-a.tar.gz"
274 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600275 artifacts_svc.ARCHIVE_PACKAGES: "/tmp/artifacts/autotest-b.tar.gz",
276 }
277 patch = self.PatchObject(
278 artifacts_svc, "BundleAutotestFiles", return_value=files
279 )
Alex Klein238d8862019-05-07 11:32:46 -0600280
Alex Klein1699fab2022-09-08 08:46:06 -0600281 artifacts.BundleAutotestFiles(
282 self.sysroot_request, self.response, self.api_config
283 )
Alex Klein238d8862019-05-07 11:32:46 -0600284
Alex Klein1699fab2022-09-08 08:46:06 -0600285 # Verify the arguments are being passed through.
286 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600287
Alex Klein1699fab2022-09-08 08:46:06 -0600288 # Verify the output proto is being populated correctly.
289 self.assertTrue(self.response.artifacts)
290 paths = [artifact.path for artifact in self.response.artifacts]
291 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600292
Alex Klein1699fab2022-09-08 08:46:06 -0600293 def testInvalidOutputDir(self):
294 """Test invalid output directory argument."""
295 request = self.SysrootRequest(
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700296 chroot=self.chroot.path, sysroot=self.sysroot_path
Alex Klein1699fab2022-09-08 08:46:06 -0600297 )
Alex Klein238d8862019-05-07 11:32:46 -0600298
Alex Klein1699fab2022-09-08 08:46:06 -0600299 with self.assertRaises(cros_build_lib.DieSystemExit):
300 artifacts.BundleAutotestFiles(
301 request, self.response, self.api_config
302 )
Alex Klein238d8862019-05-07 11:32:46 -0600303
Alex Klein1699fab2022-09-08 08:46:06 -0600304 def testInvalidSysroot(self):
305 """Test no sysroot directory."""
306 request = self.SysrootRequest(
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700307 chroot=self.chroot.path, output_dir=self.output_dir
Alex Klein1699fab2022-09-08 08:46:06 -0600308 )
Alex Klein238d8862019-05-07 11:32:46 -0600309
Alex Klein1699fab2022-09-08 08:46:06 -0600310 with self.assertRaises(cros_build_lib.DieSystemExit):
311 artifacts.BundleAutotestFiles(
312 request, self.response, self.api_config
313 )
Alex Klein238d8862019-05-07 11:32:46 -0600314
Alex Klein1699fab2022-09-08 08:46:06 -0600315 def testSysrootDoesNotExist(self):
316 """Test dies when no sysroot does not exist."""
317 request = self.SysrootRequest(
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700318 chroot=self.chroot.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600319 sysroot="/does/not/exist",
320 output_dir=self.output_dir,
321 )
Alex Klein238d8862019-05-07 11:32:46 -0600322
Alex Klein1699fab2022-09-08 08:46:06 -0600323 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
324 self.assertFalse(self.response.artifacts)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600325
326
327class BundleTastFilesTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600328 """Unittests for BundleTastFiles."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600329
Alex Klein1699fab2022-09-08 08:46:06 -0600330 def testValidateOnly(self):
331 """Quick check that a validate only call does not execute any logic."""
332 patch = self.PatchObject(artifacts_svc, "BundleTastFiles")
333 artifacts.BundleTastFiles(
334 self.sysroot_request, self.response, self.validate_only_config
335 )
336 patch.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600337
Alex Klein1699fab2022-09-08 08:46:06 -0600338 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700339 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600340 patch = self.PatchObject(artifacts_svc, "BundleTastFiles")
341 artifacts.BundleTastFiles(
342 self.sysroot_request, self.response, self.mock_call_config
343 )
344 patch.assert_not_called()
345 self.assertEqual(len(self.response.artifacts), 1)
346 self.assertEqual(
347 self.response.artifacts[0].path,
348 os.path.join(self.output_dir, "tast_bundles.tar.gz"),
349 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700350
Alex Klein1699fab2022-09-08 08:46:06 -0600351 def testBundleTastFilesNoLogs(self):
352 """BundleTasteFiles succeeds when no tast files found."""
353 self.PatchObject(commands, "BuildTastBundleTarball", return_value=None)
354 artifacts.BundleTastFiles(
355 self.sysroot_request, self.response, self.api_config
356 )
357 self.assertFalse(self.response.artifacts)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600358
Alex Klein1699fab2022-09-08 08:46:06 -0600359 def testBundleTastFiles(self):
360 """BundleTastFiles calls service correctly."""
Alex Klein1699fab2022-09-08 08:46:06 -0600361 expected_archive = os.path.join(
362 self.output_dir, artifacts_svc.TAST_BUNDLE_NAME
363 )
364 # Patch the service being called.
365 bundle_patch = self.PatchObject(
366 artifacts_svc, "BundleTastFiles", return_value=expected_archive
367 )
Alex Kleinb9d810b2019-07-01 12:38:02 -0600368
Alex Klein1699fab2022-09-08 08:46:06 -0600369 artifacts.BundleTastFiles(
370 self.sysroot_request, self.response, self.api_config
371 )
Alex Kleinb9d810b2019-07-01 12:38:02 -0600372
Alex Klein1699fab2022-09-08 08:46:06 -0600373 # Make sure the artifact got recorded successfully.
374 self.assertTrue(self.response.artifacts)
375 self.assertEqual(expected_archive, self.response.artifacts[0].path)
376 # Make sure the service got called correctly.
377 bundle_patch.assert_called_once_with(
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700378 self.chroot, self.sysroot, self.output_dir
Alex Klein1699fab2022-09-08 08:46:06 -0600379 )
Alex Kleinb9d810b2019-07-01 12:38:02 -0600380
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600381
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600382class BundleFirmwareTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600383 """Unittests for BundleFirmware."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600384
Alex Klein1699fab2022-09-08 08:46:06 -0600385 def testValidateOnly(self):
386 """Quick check that a validate only call does not execute any logic."""
387 patch = self.PatchObject(artifacts_svc, "BundleTastFiles")
388 artifacts.BundleFirmware(
389 self.sysroot_request, self.response, self.validate_only_config
390 )
391 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000392
Alex Klein1699fab2022-09-08 08:46:06 -0600393 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700394 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600395 patch = self.PatchObject(artifacts_svc, "BundleTastFiles")
396 artifacts.BundleFirmware(
397 self.sysroot_request, self.response, self.mock_call_config
398 )
399 patch.assert_not_called()
400 self.assertEqual(len(self.response.artifacts), 1)
401 self.assertEqual(
402 self.response.artifacts[0].path,
403 os.path.join(self.output_dir, "firmware.tar.gz"),
404 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700405
Alex Klein1699fab2022-09-08 08:46:06 -0600406 def testBundleFirmware(self):
407 """BundleFirmware calls cbuildbot/commands with correct args."""
408 self.PatchObject(
409 artifacts_svc,
410 "BuildFirmwareArchive",
411 return_value=os.path.join(self.output_dir, "firmware.tar.gz"),
412 )
Alex Klein231d2da2019-07-22 16:44:45 -0600413
Alex Klein1699fab2022-09-08 08:46:06 -0600414 artifacts.BundleFirmware(
415 self.sysroot_request, self.response, self.api_config
416 )
417 self.assertEqual(
418 [artifact.path for artifact in self.response.artifacts],
419 [os.path.join(self.output_dir, "firmware.tar.gz")],
420 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600421
Alex Klein1699fab2022-09-08 08:46:06 -0600422 def testBundleFirmwareNoLogs(self):
423 """BundleFirmware dies when no firmware found."""
424 self.PatchObject(commands, "BuildFirmwareArchive", return_value=None)
425 artifacts.BundleFirmware(
426 self.sysroot_request, self.response, self.api_config
427 )
428 self.assertEqual(len(self.response.artifacts), 0)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600429
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600430
Yicheng Liea1181f2020-09-22 11:51:10 -0700431class BundleFpmcuUnittestsTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600432 """Unittests for BundleFpmcuUnittests."""
Yicheng Liea1181f2020-09-22 11:51:10 -0700433
Alex Klein1699fab2022-09-08 08:46:06 -0600434 def testValidateOnly(self):
435 """Quick check that a validate only call does not execute any logic."""
436 patch = self.PatchObject(artifacts_svc, "BundleFpmcuUnittests")
437 artifacts.BundleFpmcuUnittests(
438 self.sysroot_request, self.response, self.validate_only_config
439 )
440 patch.assert_not_called()
Yicheng Liea1181f2020-09-22 11:51:10 -0700441
Alex Klein1699fab2022-09-08 08:46:06 -0600442 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700443 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600444 patch = self.PatchObject(artifacts_svc, "BundleFpmcuUnittests")
445 artifacts.BundleFpmcuUnittests(
446 self.sysroot_request, self.response, self.mock_call_config
447 )
448 patch.assert_not_called()
449 self.assertEqual(len(self.response.artifacts), 1)
450 self.assertEqual(
451 self.response.artifacts[0].path,
452 os.path.join(self.output_dir, "fpmcu_unittests.tar.gz"),
453 )
Yicheng Liea1181f2020-09-22 11:51:10 -0700454
Alex Klein1699fab2022-09-08 08:46:06 -0600455 def testBundleFpmcuUnittests(self):
456 """BundleFpmcuUnittests calls cbuildbot/commands with correct args."""
457 self.PatchObject(
458 artifacts_svc,
459 "BundleFpmcuUnittests",
460 return_value=os.path.join(
461 self.output_dir, "fpmcu_unittests.tar.gz"
462 ),
463 )
464 artifacts.BundleFpmcuUnittests(
465 self.sysroot_request, self.response, self.api_config
466 )
467 self.assertEqual(
468 [artifact.path for artifact in self.response.artifacts],
469 [os.path.join(self.output_dir, "fpmcu_unittests.tar.gz")],
470 )
Yicheng Liea1181f2020-09-22 11:51:10 -0700471
Alex Klein1699fab2022-09-08 08:46:06 -0600472 def testBundleFpmcuUnittestsNoLogs(self):
473 """BundleFpmcuUnittests does not die when no fpmcu unittests found."""
474 self.PatchObject(
475 artifacts_svc, "BundleFpmcuUnittests", return_value=None
476 )
477 artifacts.BundleFpmcuUnittests(
478 self.sysroot_request, self.response, self.api_config
479 )
480 self.assertFalse(self.response.artifacts)
Yicheng Liea1181f2020-09-22 11:51:10 -0700481
482
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600483class BundleEbuildLogsTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600484 """Unittests for BundleEbuildLogs."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600485
Alex Klein1699fab2022-09-08 08:46:06 -0600486 def testValidateOnly(self):
487 """Quick check that a validate only call does not execute any logic."""
488 patch = self.PatchObject(commands, "BuildEbuildLogsTarball")
489 artifacts.BundleEbuildLogs(
490 self.sysroot_request, self.response, self.validate_only_config
491 )
492 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600493
Alex Klein1699fab2022-09-08 08:46:06 -0600494 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700495 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600496 patch = self.PatchObject(commands, "BuildEbuildLogsTarball")
497 artifacts.BundleEbuildLogs(
498 self.sysroot_request, self.response, self.mock_call_config
499 )
500 patch.assert_not_called()
501 self.assertEqual(len(self.response.artifacts), 1)
502 self.assertEqual(
503 self.response.artifacts[0].path,
504 os.path.join(self.output_dir, "ebuild-logs.tar.gz"),
505 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700506
Alex Klein1699fab2022-09-08 08:46:06 -0600507 def testBundleEbuildLogs(self):
508 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
509 bundle_ebuild_logs_tarball = self.PatchObject(
510 artifacts_svc,
511 "BundleEBuildLogsTarball",
512 return_value="ebuild-logs.tar.gz",
513 )
514 artifacts.BundleEbuildLogs(
515 self.sysroot_request, self.response, self.api_config
516 )
517 self.assertEqual(
518 [artifact.path for artifact in self.response.artifacts],
519 [os.path.join(self.output_dir, "ebuild-logs.tar.gz")],
520 )
521 self.assertEqual(
522 bundle_ebuild_logs_tarball.call_args_list,
523 [mock.call(mock.ANY, self.sysroot, self.output_dir)],
524 )
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600525
Alex Klein1699fab2022-09-08 08:46:06 -0600526 def testBundleEbuildLogsNoLogs(self):
527 """BundleEbuildLogs dies when no logs found."""
528 self.PatchObject(commands, "BuildEbuildLogsTarball", return_value=None)
529 artifacts.BundleEbuildLogs(
530 self.sysroot_request, self.response, self.api_config
531 )
Alex Klein036833d2022-06-01 13:05:01 -0600532
Alex Klein1699fab2022-09-08 08:46:06 -0600533 self.assertFalse(self.response.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600534
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600535
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600536class BundleChromeOSConfigTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600537 """Unittests for BundleChromeOSConfig"""
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600538
Alex Klein1699fab2022-09-08 08:46:06 -0600539 def testValidateOnly(self):
540 """Quick check that a validate only call does not execute any logic."""
541 patch = self.PatchObject(artifacts_svc, "BundleChromeOSConfig")
542 artifacts.BundleChromeOSConfig(
543 self.sysroot_request, self.response, self.validate_only_config
544 )
545 patch.assert_not_called()
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600546
Alex Klein1699fab2022-09-08 08:46:06 -0600547 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700548 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600549 patch = self.PatchObject(artifacts_svc, "BundleChromeOSConfig")
550 artifacts.BundleChromeOSConfig(
551 self.sysroot_request, self.response, self.mock_call_config
552 )
553 patch.assert_not_called()
554 self.assertEqual(len(self.response.artifacts), 1)
555 self.assertEqual(
556 self.response.artifacts[0].path,
557 os.path.join(self.output_dir, "config.yaml"),
558 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700559
Alex Klein1699fab2022-09-08 08:46:06 -0600560 def testBundleChromeOSConfigSuccess(self):
561 """Test standard success case."""
562 bundle_chromeos_config = self.PatchObject(
563 artifacts_svc, "BundleChromeOSConfig", return_value="config.yaml"
564 )
565 artifacts.BundleChromeOSConfig(
566 self.sysroot_request, self.response, self.api_config
567 )
568 self.assertEqual(
569 [artifact.path for artifact in self.response.artifacts],
570 [os.path.join(self.output_dir, "config.yaml")],
571 )
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600572
Alex Klein1699fab2022-09-08 08:46:06 -0600573 self.assertEqual(
574 bundle_chromeos_config.call_args_list,
575 [mock.call(mock.ANY, self.sysroot, self.output_dir)],
576 )
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600577
Alex Klein1699fab2022-09-08 08:46:06 -0600578 def testBundleChromeOSConfigNoConfigFound(self):
579 """Empty results when the config payload isn't found."""
580 self.PatchObject(
581 artifacts_svc, "BundleChromeOSConfig", return_value=None
582 )
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600583
Alex Klein1699fab2022-09-08 08:46:06 -0600584 artifacts.BundleChromeOSConfig(
585 self.sysroot_request, self.response, self.api_config
586 )
587 self.assertFalse(self.response.artifacts)
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600588
589
Alex Klein1699fab2022-09-08 08:46:06 -0600590class BundleTestUpdatePayloadsTest(
591 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
592):
593 """Unittests for BundleTestUpdatePayloads."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600594
Alex Klein1699fab2022-09-08 08:46:06 -0600595 def setUp(self):
596 self.source_root = os.path.join(self.tempdir, "cros")
597 osutils.SafeMakedirs(self.source_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600598
Alex Klein1699fab2022-09-08 08:46:06 -0600599 self.archive_root = os.path.join(self.tempdir, "output")
600 osutils.SafeMakedirs(self.archive_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600601
Alex Klein1699fab2022-09-08 08:46:06 -0600602 self.target = "target"
603 self.image_root = os.path.join(
604 self.source_root, "src/build/images/target/latest"
605 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600606
Alex Klein1699fab2022-09-08 08:46:06 -0600607 self.input_proto = artifacts_pb2.BundleRequest()
608 self.input_proto.build_target.name = self.target
609 self.input_proto.output_dir = self.archive_root
610 self.output_proto = artifacts_pb2.BundleResponse()
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600611
Alex Klein1699fab2022-09-08 08:46:06 -0600612 self.PatchObject(constants, "SOURCE_ROOT", new=self.source_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600613
Brian Norrisdd2e7e62023-06-16 14:07:32 -0700614 def MockPayloads(_, image_path, archive_dir):
Alex Klein1699fab2022-09-08 08:46:06 -0600615 osutils.WriteFile(
616 os.path.join(archive_dir, "payload1.bin"), image_path
617 )
618 osutils.WriteFile(
619 os.path.join(archive_dir, "payload2.bin"), image_path
620 )
621 return [
622 os.path.join(archive_dir, "payload1.bin"),
623 os.path.join(archive_dir, "payload2.bin"),
624 ]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600625
Alex Klein1699fab2022-09-08 08:46:06 -0600626 self.bundle_patch = self.PatchObject(
627 artifacts_svc, "BundleTestUpdatePayloads", side_effect=MockPayloads
628 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600629
Alex Klein1699fab2022-09-08 08:46:06 -0600630 def testValidateOnly(self):
631 """Quick check that a validate only call does not execute any logic."""
632 patch = self.PatchObject(artifacts_svc, "BundleTestUpdatePayloads")
633 artifacts.BundleTestUpdatePayloads(
634 self.input_proto, self.output_proto, self.validate_only_config
635 )
636 patch.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600637
Alex Klein1699fab2022-09-08 08:46:06 -0600638 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700639 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600640 patch = self.PatchObject(artifacts_svc, "BundleTestUpdatePayloads")
641 artifacts.BundleTestUpdatePayloads(
642 self.input_proto, self.output_proto, self.mock_call_config
643 )
644 patch.assert_not_called()
645 self.assertEqual(len(self.output_proto.artifacts), 3)
646 self.assertEqual(
647 self.output_proto.artifacts[0].path,
648 os.path.join(self.archive_root, "payload1.bin"),
649 )
650 self.assertEqual(
651 self.output_proto.artifacts[1].path,
652 os.path.join(self.archive_root, "payload1.json"),
653 )
654 self.assertEqual(
655 self.output_proto.artifacts[2].path,
656 os.path.join(self.archive_root, "payload1.log"),
657 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700658
Alex Klein1699fab2022-09-08 08:46:06 -0600659 def testBundleTestUpdatePayloads(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700660 """BundleTestUpdatePayloads calls cbuildbot/commands correctly."""
Alex Klein1699fab2022-09-08 08:46:06 -0600661 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
662 osutils.WriteFile(image_path, "image!", makedirs=True)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600663
Alex Klein1699fab2022-09-08 08:46:06 -0600664 artifacts.BundleTestUpdatePayloads(
665 self.input_proto, self.output_proto, self.api_config
666 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600667
Alex Klein1699fab2022-09-08 08:46:06 -0600668 actual = [
669 os.path.relpath(artifact.path, self.archive_root)
670 for artifact in self.output_proto.artifacts
671 ]
672 expected = ["payload1.bin", "payload2.bin"]
673 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600674
Alex Klein1699fab2022-09-08 08:46:06 -0600675 actual = [
676 os.path.relpath(path, self.archive_root)
677 for path in osutils.DirectoryIterator(self.archive_root)
678 ]
679 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600680
Alex Klein1699fab2022-09-08 08:46:06 -0600681 def testBundleTestUpdatePayloadsNoImageDir(self):
682 """BundleTestUpdatePayloads dies if no image dir is found."""
683 # Intentionally do not write image directory.
684 artifacts.BundleTestUpdatePayloads(
685 self.input_proto, self.output_proto, self.api_config
686 )
687 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600688
Alex Klein1699fab2022-09-08 08:46:06 -0600689 def testBundleTestUpdatePayloadsNoImage(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700690 """BundleTestUpdatePayloads dies if no usable image found for target."""
Alex Klein1699fab2022-09-08 08:46:06 -0600691 # Intentionally do not write image, but create the directory.
692 osutils.SafeMakedirs(self.image_root)
693 with self.assertRaises(cros_build_lib.DieSystemExit):
694 artifacts.BundleTestUpdatePayloads(
695 self.input_proto, self.output_proto, self.api_config
696 )
Alex Klein6504eca2019-04-18 15:37:56 -0600697
698
Alex Klein1699fab2022-09-08 08:46:06 -0600699class BundleSimpleChromeArtifactsTest(
700 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
701):
702 """BundleSimpleChromeArtifacts tests."""
Alex Klein2275d692019-04-23 16:04:12 -0600703
Alex Klein1699fab2022-09-08 08:46:06 -0600704 def setUp(self):
Brian Norrisd3e391e2023-06-30 09:53:11 -0700705 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
706
707 self.chroot = chroot_lib.Chroot(
708 path=self.tempdir / "chroot",
709 out_path=self.tempdir / "out",
710 )
Alex Klein1699fab2022-09-08 08:46:06 -0600711 self.sysroot_path = "/sysroot"
Brian Norrisd3e391e2023-06-30 09:53:11 -0700712 self.sysroot_dir = self.chroot.full_path(self.sysroot_path)
Alex Klein1699fab2022-09-08 08:46:06 -0600713 osutils.SafeMakedirs(self.sysroot_dir)
714 self.output_dir = os.path.join(self.tempdir, "output_dir")
715 osutils.SafeMakedirs(self.output_dir)
Alex Klein2275d692019-04-23 16:04:12 -0600716
Alex Klein1699fab2022-09-08 08:46:06 -0600717 self.does_not_exist = os.path.join(self.tempdir, "does_not_exist")
Alex Klein2275d692019-04-23 16:04:12 -0600718
Alex Klein1699fab2022-09-08 08:46:06 -0600719 self.response = artifacts_pb2.BundleResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600720
Alex Klein1699fab2022-09-08 08:46:06 -0600721 def _GetRequest(
722 self,
Brian Norrisd3e391e2023-06-30 09:53:11 -0700723 chroot: Optional[chroot_lib.Chroot] = None,
Alex Klein1699fab2022-09-08 08:46:06 -0600724 sysroot: Optional[str] = None,
725 build_target: Optional[str] = None,
726 output_dir: Optional[str] = None,
727 ) -> artifacts_pb2.BundleRequest:
728 """Helper to create a request message instance.
Alex Klein2275d692019-04-23 16:04:12 -0600729
Alex Klein1699fab2022-09-08 08:46:06 -0600730 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600731 chroot: The chroot path.
732 sysroot: The sysroot path.
733 build_target: The build target name.
734 output_dir: The output directory.
Alex Klein1699fab2022-09-08 08:46:06 -0600735 """
736 return artifacts_pb2.BundleRequest(
737 sysroot={"path": sysroot, "build_target": {"name": build_target}},
Brian Norrisd3e391e2023-06-30 09:53:11 -0700738 chroot={
739 "path": chroot.path if chroot else None,
740 "out_path": str(chroot.out_path) if chroot else None,
741 },
Alex Klein1699fab2022-09-08 08:46:06 -0600742 output_dir=output_dir,
743 )
Alex Klein2275d692019-04-23 16:04:12 -0600744
Alex Klein1699fab2022-09-08 08:46:06 -0600745 def testValidateOnly(self):
746 """Quick check that a validate only call does not execute any logic."""
747 patch = self.PatchObject(artifacts_svc, "BundleSimpleChromeArtifacts")
748 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700749 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600750 sysroot=self.sysroot_path,
751 build_target="board",
752 output_dir=self.output_dir,
753 )
754 artifacts.BundleSimpleChromeArtifacts(
755 request, self.response, self.validate_only_config
756 )
757 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600758
Alex Klein1699fab2022-09-08 08:46:06 -0600759 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700760 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600761 patch = self.PatchObject(artifacts_svc, "BundleSimpleChromeArtifacts")
762 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700763 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600764 sysroot=self.sysroot_path,
765 build_target="board",
766 output_dir=self.output_dir,
767 )
768 artifacts.BundleSimpleChromeArtifacts(
769 request, self.response, self.mock_call_config
770 )
771 patch.assert_not_called()
772 self.assertEqual(len(self.response.artifacts), 1)
773 self.assertEqual(
774 self.response.artifacts[0].path,
775 os.path.join(self.output_dir, "simple_chrome.txt"),
776 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700777
Alex Klein1699fab2022-09-08 08:46:06 -0600778 def testNoBuildTarget(self):
779 """Test no build target fails."""
780 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700781 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600782 sysroot=self.sysroot_path,
783 output_dir=self.output_dir,
784 )
785 response = self.response
786 with self.assertRaises(cros_build_lib.DieSystemExit):
787 artifacts.BundleSimpleChromeArtifacts(
788 request, response, self.api_config
789 )
Alex Klein2275d692019-04-23 16:04:12 -0600790
Alex Klein1699fab2022-09-08 08:46:06 -0600791 def testNoSysroot(self):
792 """Test no sysroot fails."""
793 request = self._GetRequest(
794 build_target="board", output_dir=self.output_dir
795 )
796 response = self.response
797 with self.assertRaises(cros_build_lib.DieSystemExit):
798 artifacts.BundleSimpleChromeArtifacts(
799 request, response, self.api_config
800 )
Alex Klein2275d692019-04-23 16:04:12 -0600801
Alex Klein1699fab2022-09-08 08:46:06 -0600802 def testSysrootDoesNotExist(self):
803 """Test no sysroot fails."""
804 request = self._GetRequest(
805 build_target="board",
806 output_dir=self.output_dir,
807 sysroot=self.does_not_exist,
808 )
809 response = self.response
Alex Kleinb6847e22022-11-07 10:44:48 -0700810 artifacts.BundleSimpleChromeArtifacts(
811 request, response, self.api_config
812 )
813 self.assertFalse(self.response.artifacts)
Alex Klein2275d692019-04-23 16:04:12 -0600814
Alex Klein1699fab2022-09-08 08:46:06 -0600815 def testNoOutputDir(self):
816 """Test no output dir fails."""
817 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700818 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600819 sysroot=self.sysroot_path,
820 build_target="board",
821 )
822 response = self.response
823 with self.assertRaises(cros_build_lib.DieSystemExit):
824 artifacts.BundleSimpleChromeArtifacts(
825 request, response, self.api_config
826 )
Alex Klein2275d692019-04-23 16:04:12 -0600827
Alex Klein1699fab2022-09-08 08:46:06 -0600828 def testOutputDirDoesNotExist(self):
829 """Test no output dir fails."""
830 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700831 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600832 sysroot=self.sysroot_path,
833 build_target="board",
834 output_dir=self.does_not_exist,
835 )
836 response = self.response
837 with self.assertRaises(cros_build_lib.DieSystemExit):
838 artifacts.BundleSimpleChromeArtifacts(
839 request, response, self.api_config
840 )
Alex Klein2275d692019-04-23 16:04:12 -0600841
Alex Klein1699fab2022-09-08 08:46:06 -0600842 def testOutputHandling(self):
843 """Test response output."""
844 files = ["file1", "file2", "file3"]
845 expected_files = [os.path.join(self.output_dir, f) for f in files]
846 self.PatchObject(
847 artifacts_svc,
848 "BundleSimpleChromeArtifacts",
849 return_value=expected_files,
850 )
851 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700852 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600853 sysroot=self.sysroot_path,
854 build_target="board",
855 output_dir=self.output_dir,
856 )
857 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600858
Alex Klein1699fab2022-09-08 08:46:06 -0600859 artifacts.BundleSimpleChromeArtifacts(
860 request, response, self.api_config
861 )
Alex Klein2275d692019-04-23 16:04:12 -0600862
Alex Klein1699fab2022-09-08 08:46:06 -0600863 self.assertTrue(response.artifacts)
864 self.assertCountEqual(
865 expected_files, [a.path for a in response.artifacts]
866 )
Alex Klein2275d692019-04-23 16:04:12 -0600867
868
Alex Klein1699fab2022-09-08 08:46:06 -0600869class BundleVmFilesTest(
870 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
871):
872 """BuildVmFiles tests."""
Alex Klein6504eca2019-04-18 15:37:56 -0600873
Alex Klein1699fab2022-09-08 08:46:06 -0600874 def setUp(self):
875 self.output_dir = os.path.join(self.tempdir, "output")
876 osutils.SafeMakedirs(self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600877
Alex Klein1699fab2022-09-08 08:46:06 -0600878 self.response = artifacts_pb2.BundleResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600879
Alex Klein1699fab2022-09-08 08:46:06 -0600880 def _GetInput(
881 self,
882 chroot: Optional[str] = None,
883 sysroot: Optional[str] = None,
884 test_results_dir: Optional[str] = None,
885 output_dir: Optional[str] = None,
886 ) -> artifacts_pb2.BundleVmFilesRequest:
887 """Helper to build out an input message instance.
Alex Klein6504eca2019-04-18 15:37:56 -0600888
Alex Klein1699fab2022-09-08 08:46:06 -0600889 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600890 chroot: The chroot path.
891 sysroot: The sysroot path relative to the chroot.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700892 test_results_dir: The test results directory relative to the
893 sysroot.
Alex Klein611dddd2022-10-11 17:02:01 -0600894 output_dir: The directory where the results tarball should be saved.
Alex Klein1699fab2022-09-08 08:46:06 -0600895 """
896 return artifacts_pb2.BundleVmFilesRequest(
897 chroot={"path": chroot},
898 sysroot={"path": sysroot},
899 test_results_dir=test_results_dir,
900 output_dir=output_dir,
901 )
Alex Klein6504eca2019-04-18 15:37:56 -0600902
Alex Klein1699fab2022-09-08 08:46:06 -0600903 def testValidateOnly(self):
904 """Quick check that a validate only call does not execute any logic."""
905 patch = self.PatchObject(artifacts_svc, "BundleVmFiles")
906 in_proto = self._GetInput(
907 chroot="/chroot/dir",
908 sysroot="/build/board",
909 test_results_dir="/test/results",
910 output_dir=self.output_dir,
911 )
912 artifacts.BundleVmFiles(
913 in_proto, self.response, self.validate_only_config
914 )
915 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600916
Alex Klein1699fab2022-09-08 08:46:06 -0600917 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700918 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600919 patch = self.PatchObject(artifacts_svc, "BundleVmFiles")
920 in_proto = self._GetInput(
921 chroot="/chroot/dir",
922 sysroot="/build/board",
923 test_results_dir="/test/results",
924 output_dir=self.output_dir,
925 )
926 artifacts.BundleVmFiles(in_proto, self.response, self.mock_call_config)
927 patch.assert_not_called()
928 self.assertEqual(len(self.response.artifacts), 1)
929 self.assertEqual(
930 self.response.artifacts[0].path,
931 os.path.join(self.output_dir, "f1.tar"),
932 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700933
Alex Klein1699fab2022-09-08 08:46:06 -0600934 def testChrootMissing(self):
935 """Test error handling for missing chroot."""
936 in_proto = self._GetInput(
937 sysroot="/build/board",
938 test_results_dir="/test/results",
939 output_dir=self.output_dir,
940 )
Alex Klein6504eca2019-04-18 15:37:56 -0600941
Alex Klein1699fab2022-09-08 08:46:06 -0600942 with self.assertRaises(cros_build_lib.DieSystemExit):
943 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600944
Alex Klein1699fab2022-09-08 08:46:06 -0600945 def testTestResultsDirMissing(self):
946 """Test error handling for missing test results directory."""
947 in_proto = self._GetInput(
948 chroot="/chroot/dir",
949 sysroot="/build/board",
950 output_dir=self.output_dir,
951 )
Alex Klein6504eca2019-04-18 15:37:56 -0600952
Alex Klein1699fab2022-09-08 08:46:06 -0600953 with self.assertRaises(cros_build_lib.DieSystemExit):
954 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600955
Alex Klein1699fab2022-09-08 08:46:06 -0600956 def testOutputDirMissing(self):
957 """Test error handling for missing output directory."""
958 in_proto = self._GetInput(
959 chroot="/chroot/dir",
960 sysroot="/build/board",
961 test_results_dir="/test/results",
962 )
Alex Klein6504eca2019-04-18 15:37:56 -0600963
Alex Klein1699fab2022-09-08 08:46:06 -0600964 with self.assertRaises(cros_build_lib.DieSystemExit):
965 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600966
Alex Klein1699fab2022-09-08 08:46:06 -0600967 def testOutputDirDoesNotExist(self):
968 """Test error handling for output directory that does not exist."""
969 in_proto = self._GetInput(
970 chroot="/chroot/dir",
971 sysroot="/build/board",
972 output_dir=os.path.join(self.tempdir, "dne"),
973 test_results_dir="/test/results",
974 )
Alex Klein231d2da2019-07-22 16:44:45 -0600975
Alex Klein1699fab2022-09-08 08:46:06 -0600976 with self.assertRaises(cros_build_lib.DieSystemExit):
977 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600978
Alex Klein1699fab2022-09-08 08:46:06 -0600979 def testValidCall(self):
980 """Test image dir building."""
981 in_proto = self._GetInput(
982 chroot="/chroot/dir",
983 sysroot="/build/board",
984 test_results_dir="/test/results",
985 output_dir=self.output_dir,
986 )
Alex Klein231d2da2019-07-22 16:44:45 -0600987
Alex Klein1699fab2022-09-08 08:46:06 -0600988 expected_files = ["/tmp/output/f1.tar", "/tmp/output/f2.tar"]
989 patch = self.PatchObject(
990 artifacts_svc, "BundleVmFiles", return_value=expected_files
991 )
Alex Klein6504eca2019-04-18 15:37:56 -0600992
Alex Klein1699fab2022-09-08 08:46:06 -0600993 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600994
Alex Klein1699fab2022-09-08 08:46:06 -0600995 patch.assert_called_with(mock.ANY, "/test/results", self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600996
Alex Kleinab87ceb2023-01-24 12:00:51 -0700997 # Make sure we have artifacts, and that every artifact is an expected
998 # file.
Alex Klein1699fab2022-09-08 08:46:06 -0600999 self.assertTrue(self.response.artifacts)
1000 for artifact in self.response.artifacts:
1001 self.assertIn(artifact.path, expected_files)
1002 expected_files.remove(artifact.path)
Alex Klein6504eca2019-04-18 15:37:56 -06001003
Alex Klein1699fab2022-09-08 08:46:06 -06001004 # Make sure we've seen all of the expected files.
1005 self.assertFalse(expected_files)
Alex Kleinb9d810b2019-07-01 12:38:02 -06001006
Tiancong Wang50b80a92019-08-01 14:46:15 -07001007
Alex Klein036833d2022-06-01 13:05:01 -06001008class ExportCpeReportTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -06001009 """ExportCpeReport tests."""
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001010
Alex Klein1699fab2022-09-08 08:46:06 -06001011 def testValidateOnly(self):
1012 """Quick check validate only calls don't execute."""
1013 patch = self.PatchObject(artifacts_svc, "GenerateCpeReport")
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001014
Alex Klein1699fab2022-09-08 08:46:06 -06001015 artifacts.ExportCpeReport(
1016 self.sysroot_request, self.response, self.validate_only_config
1017 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001018
Alex Klein1699fab2022-09-08 08:46:06 -06001019 patch.assert_not_called()
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001020
Alex Klein1699fab2022-09-08 08:46:06 -06001021 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -07001022 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -06001023 patch = self.PatchObject(artifacts_svc, "GenerateCpeReport")
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001024
Alex Klein1699fab2022-09-08 08:46:06 -06001025 artifacts.ExportCpeReport(
1026 self.sysroot_request, self.response, self.mock_call_config
1027 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001028
Alex Klein1699fab2022-09-08 08:46:06 -06001029 patch.assert_not_called()
1030 self.assertEqual(len(self.response.artifacts), 2)
1031 self.assertEqual(
1032 self.response.artifacts[0].path,
1033 os.path.join(self.output_dir, "cpe_report.txt"),
1034 )
1035 self.assertEqual(
1036 self.response.artifacts[1].path,
1037 os.path.join(self.output_dir, "cpe_warnings.txt"),
1038 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001039
Alex Klein1699fab2022-09-08 08:46:06 -06001040 def testSuccess(self):
1041 """Test success case."""
1042 expected = artifacts_svc.CpeResult(
1043 report="/output/report.json", warnings="/output/warnings.json"
1044 )
1045 self.PatchObject(
1046 artifacts_svc, "GenerateCpeReport", return_value=expected
1047 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001048
Alex Klein1699fab2022-09-08 08:46:06 -06001049 artifacts.ExportCpeReport(
1050 self.sysroot_request, self.response, self.api_config
1051 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001052
Alex Klein1699fab2022-09-08 08:46:06 -06001053 for artifact in self.response.artifacts:
1054 self.assertIn(artifact.path, [expected.report, expected.warnings])
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001055
1056
1057class BundleGceTarballTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -06001058 """Unittests for BundleGceTarball."""
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001059
Alex Klein1699fab2022-09-08 08:46:06 -06001060 def testValidateOnly(self):
1061 """Check that a validate only call does not execute any logic."""
1062 patch = self.PatchObject(artifacts_svc, "BundleGceTarball")
1063 artifacts.BundleGceTarball(
1064 self.target_request, self.response, self.validate_only_config
1065 )
1066 patch.assert_not_called()
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001067
Alex Klein1699fab2022-09-08 08:46:06 -06001068 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -07001069 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -06001070 patch = self.PatchObject(artifacts_svc, "BundleGceTarball")
1071 artifacts.BundleGceTarball(
1072 self.target_request, self.response, self.mock_call_config
1073 )
1074 patch.assert_not_called()
1075 self.assertEqual(len(self.response.artifacts), 1)
1076 self.assertEqual(
1077 self.response.artifacts[0].path,
1078 os.path.join(self.output_dir, constants.TEST_IMAGE_GCE_TAR),
1079 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001080
Alex Klein1699fab2022-09-08 08:46:06 -06001081 def testBundleGceTarball(self):
1082 """BundleGceTarball calls cbuildbot/commands with correct args."""
1083 bundle_gce_tarball = self.PatchObject(
1084 artifacts_svc,
1085 "BundleGceTarball",
1086 return_value=os.path.join(
1087 self.output_dir, constants.TEST_IMAGE_GCE_TAR
1088 ),
1089 )
1090 self.PatchObject(os.path, "exists", return_value=True)
1091 artifacts.BundleGceTarball(
1092 self.target_request, self.response, self.api_config
1093 )
1094 self.assertEqual(
1095 [artifact.path for artifact in self.response.artifacts],
1096 [os.path.join(self.output_dir, constants.TEST_IMAGE_GCE_TAR)],
1097 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001098
Alex Klein1699fab2022-09-08 08:46:06 -06001099 latest = os.path.join(
1100 self.source_root, "src/build/images/target/latest"
1101 )
1102 self.assertEqual(
1103 bundle_gce_tarball.call_args_list,
1104 [mock.call(self.output_dir, latest)],
1105 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001106
Alex Klein1699fab2022-09-08 08:46:06 -06001107 def testBundleGceTarballNoImageDir(self):
1108 """BundleGceTarball dies when image dir does not exist."""
1109 self.PatchObject(os.path, "exists", return_value=False)
1110 with self.assertRaises(cros_build_lib.DieSystemExit):
1111 artifacts.BundleGceTarball(
1112 self.target_request, self.response, self.api_config
1113 )
Greg Edelstondc941072021-08-11 12:32:30 -06001114
Greg Edelstondc941072021-08-11 12:32:30 -06001115
Alex Klein1699fab2022-09-08 08:46:06 -06001116class FetchMetadataTestCase(
1117 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
1118):
1119 """Unittests for FetchMetadata."""
Greg Edelstondc941072021-08-11 12:32:30 -06001120
Alex Klein1699fab2022-09-08 08:46:06 -06001121 sysroot_path = "/build/coral"
1122 chroot_name = "chroot"
Greg Edelstondc941072021-08-11 12:32:30 -06001123
Alex Klein1699fab2022-09-08 08:46:06 -06001124 def setUp(self):
1125 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001126 self.chroot = chroot_lib.Chroot(
1127 path=self.tempdir / "chroot",
1128 out_path=self.tempdir / "out",
1129 )
1130 pathlib.Path(self.chroot.path).touch()
1131 self.chroot.out_path.touch()
Alex Klein1699fab2022-09-08 08:46:06 -06001132 self.expected_filepaths = [
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001133 self.chroot.full_path(fp)
Alex Klein1699fab2022-09-08 08:46:06 -06001134 for fp in (
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001135 "/build/coral/usr/local/build/autotest/autotest_metadata.pb",
1136 "/build/coral/usr/share/tast/metadata/local/cros.pb",
1137 "/build/coral/build/share/tast/metadata/local/crosint.pb",
1138 "/usr/share/tast/metadata/remote/cros.pb",
Alex Klein1699fab2022-09-08 08:46:06 -06001139 )
1140 ]
1141 self.PatchObject(cros_build_lib, "AssertOutsideChroot")
Greg Edelstondc941072021-08-11 12:32:30 -06001142
Alex Klein1699fab2022-09-08 08:46:06 -06001143 def createFetchMetadataRequest(
1144 self, use_sysroot_path=True, use_chroot=True
1145 ):
1146 """Construct a FetchMetadataRequest for use in test cases."""
1147 request = artifacts_pb2.FetchMetadataRequest()
1148 if use_sysroot_path:
1149 request.sysroot.path = self.sysroot_path
1150 if use_chroot:
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001151 request.chroot.path = self.chroot.path
1152 request.chroot.out_path = str(self.chroot.out_path)
Alex Klein1699fab2022-09-08 08:46:06 -06001153 return request
Greg Edelstondc941072021-08-11 12:32:30 -06001154
Alex Klein1699fab2022-09-08 08:46:06 -06001155 def testValidateOnly(self):
1156 """Check that a validate only call does not execute any logic."""
1157 patch = self.PatchObject(controller_util, "ParseSysroot")
1158 request = self.createFetchMetadataRequest()
1159 response = artifacts_pb2.FetchMetadataResponse()
1160 artifacts.FetchMetadata(request, response, self.validate_only_config)
1161 patch.assert_not_called()
Greg Edelstondc941072021-08-11 12:32:30 -06001162
Alex Klein1699fab2022-09-08 08:46:06 -06001163 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -07001164 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -06001165 patch = self.PatchObject(controller_util, "ParseSysroot")
1166 request = self.createFetchMetadataRequest()
1167 response = artifacts_pb2.FetchMetadataResponse()
1168 artifacts.FetchMetadata(request, response, self.mock_call_config)
1169 patch.assert_not_called()
1170 self.assertGreater(len(response.filepaths), 0)
Greg Edelstondc941072021-08-11 12:32:30 -06001171
Alex Klein1699fab2022-09-08 08:46:06 -06001172 def testNoSysrootPath(self):
1173 """Check that a request with no sysroot.path results in failure."""
1174 request = self.createFetchMetadataRequest(use_sysroot_path=False)
1175 response = artifacts_pb2.FetchMetadataResponse()
1176 with self.assertRaises(cros_build_lib.DieSystemExit):
1177 artifacts.FetchMetadata(request, response, self.api_config)
Greg Edelstondc941072021-08-11 12:32:30 -06001178
Alex Klein1699fab2022-09-08 08:46:06 -06001179 def testNoChroot(self):
1180 """Check that a request with no chroot results in failure."""
1181 request = self.createFetchMetadataRequest(use_chroot=False)
1182 response = artifacts_pb2.FetchMetadataResponse()
1183 with self.assertRaises(cros_build_lib.DieSystemExit):
1184 artifacts.FetchMetadata(request, response, self.api_config)
1185
1186 def testSuccess(self):
1187 """Check that a well-formed request yields the expected results."""
1188 request = self.createFetchMetadataRequest(use_chroot=True)
1189 response = artifacts_pb2.FetchMetadataResponse()
1190 artifacts.FetchMetadata(request, response, self.api_config)
1191 actual_filepaths = [fp.path.path for fp in response.filepaths]
1192 self.assertEqual(
1193 sorted(actual_filepaths), sorted(self.expected_filepaths)
1194 )
1195 self.assertTrue(
1196 all(
1197 fp.path.location == common_pb2.Path.OUTSIDE
1198 for fp in response.filepaths
1199 )
1200 )
Jack Neus26b94672022-10-27 17:33:21 +00001201
1202
1203class GetTest(cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
1204 """Get function tests."""
1205
1206 def setUp(self):
1207 self.sysroot_path = "/build/target"
1208 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
1209
1210 def _InputProto(self):
1211 """Helper to build an input proto instance."""
Alex Kleinab87ceb2023-01-24 12:00:51 -07001212 # pylint: disable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001213 return artifacts_pb2.GetRequest(
1214 sysroot=sysroot_pb2.Sysroot(path=self.sysroot_path),
1215 artifact_info=common_pb2.ArtifactsByService(
1216 sysroot=common_pb2.ArtifactsByService.Sysroot(
1217 output_artifacts=[
1218 common_pb2.ArtifactsByService.Sysroot.ArtifactInfo(
1219 artifact_types=[
1220 common_pb2.ArtifactsByService.Sysroot.ArtifactType.FUZZER_SYSROOT
1221 ]
1222 )
1223 ],
1224 ),
1225 image=common_pb2.ArtifactsByService.Image(
1226 output_artifacts=[
1227 common_pb2.ArtifactsByService.Image.ArtifactInfo(
1228 artifact_types=[
1229 common_pb2.ArtifactsByService.Image.ArtifactType.LICENSE_CREDITS
1230 ]
1231 )
1232 ],
1233 ),
1234 test=common_pb2.ArtifactsByService.Test(
1235 output_artifacts=[
1236 common_pb2.ArtifactsByService.Test.ArtifactInfo(
1237 artifact_types=[
1238 common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL
1239 ]
1240 )
1241 ],
1242 ),
1243 ),
1244 result_path=common_pb2.ResultPath(
1245 path=common_pb2.Path(path=str(self.tempdir))
1246 ),
1247 )
Alex Kleinab87ceb2023-01-24 12:00:51 -07001248 # pylint: enable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001249
1250 def _OutputProto(self):
1251 """Helper to build an output proto instance."""
1252 return artifacts_pb2.GetResponse()
1253
1254 def testSuccess(self):
1255 """Test Get."""
Alex Kleinab87ceb2023-01-24 12:00:51 -07001256 # pylint: disable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001257 image_mock = self.PatchObject(
1258 image_controller,
1259 "GetArtifacts",
1260 return_value=[
1261 {
1262 "paths": ["/foo/bar/license_credits.html"],
1263 "type": common_pb2.ArtifactsByService.Image.ArtifactType.LICENSE_CREDITS,
1264 }
1265 ],
1266 )
1267 sysroot_mock = self.PatchObject(
1268 sysroot_controller,
1269 "GetArtifacts",
1270 return_value=[
1271 {
1272 "type": common_pb2.ArtifactsByService.Sysroot.ArtifactType.FUZZER_SYSROOT,
1273 "failed": True,
1274 "failure_reason": "Bad data!",
1275 }
1276 ],
1277 )
1278 test_mock = self.PatchObject(
1279 test_controller,
1280 "GetArtifacts",
1281 return_value=[
1282 {
1283 "paths": ["/foo/bar/hwqual.tar.xz"],
1284 "type": common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL,
1285 }
1286 ],
1287 )
Alex Kleinab87ceb2023-01-24 12:00:51 -07001288 # pylint: enable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001289
1290 in_proto = self._InputProto()
1291 out_proto = self._OutputProto()
1292 artifacts.Get(
1293 in_proto,
1294 out_proto,
1295 self.api_config,
1296 )
1297
1298 image_mock.assert_called_once()
1299 sysroot_mock.assert_called_once()
1300 test_mock.assert_called_once()
1301
Alex Kleinab87ceb2023-01-24 12:00:51 -07001302 # pylint: disable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001303 expected = common_pb2.UploadedArtifactsByService(
1304 sysroot=common_pb2.UploadedArtifactsByService.Sysroot(
1305 artifacts=[
1306 common_pb2.UploadedArtifactsByService.Sysroot.ArtifactPaths(
1307 artifact_type=common_pb2.ArtifactsByService.Sysroot.ArtifactType.FUZZER_SYSROOT,
1308 failed=True,
1309 failure_reason="Bad data!",
1310 )
1311 ]
1312 ),
1313 image=common_pb2.UploadedArtifactsByService.Image(
1314 artifacts=[
1315 common_pb2.UploadedArtifactsByService.Image.ArtifactPaths(
1316 artifact_type=common_pb2.ArtifactsByService.Image.ArtifactType.LICENSE_CREDITS,
1317 paths=[
1318 common_pb2.Path(
1319 path="/foo/bar/license_credits.html",
1320 location=common_pb2.Path.OUTSIDE,
1321 )
1322 ],
1323 )
1324 ]
1325 ),
1326 test=common_pb2.UploadedArtifactsByService.Test(
1327 artifacts=[
1328 common_pb2.UploadedArtifactsByService.Test.ArtifactPaths(
1329 artifact_type=common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL,
1330 paths=[
1331 common_pb2.Path(
1332 path="/foo/bar/hwqual.tar.xz",
1333 location=common_pb2.Path.OUTSIDE,
1334 )
1335 ],
1336 )
1337 ]
1338 ),
1339 )
Alex Kleinab87ceb2023-01-24 12:00:51 -07001340 # pylint: enable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001341 self.assertEqual(out_proto.artifacts, expected)