blob: 77bff4024a55f10ca6919fc8abe6e45f442b414a [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(
127 self.target_request, self.response, self.validate_only_config
128 )
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(
135 self.target_request, self.response, self.mock_call_config
136 )
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(
181 self.target_request, self.response, self.api_config
182 )
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):
705 self.chroot_dir = os.path.join(self.tempdir, "chroot_dir")
706 self.sysroot_path = "/sysroot"
707 self.sysroot_dir = os.path.join(self.chroot_dir, "sysroot")
708 osutils.SafeMakedirs(self.sysroot_dir)
709 self.output_dir = os.path.join(self.tempdir, "output_dir")
710 osutils.SafeMakedirs(self.output_dir)
Alex Klein2275d692019-04-23 16:04:12 -0600711
Alex Klein1699fab2022-09-08 08:46:06 -0600712 self.does_not_exist = os.path.join(self.tempdir, "does_not_exist")
Alex Klein2275d692019-04-23 16:04:12 -0600713
Alex Klein1699fab2022-09-08 08:46:06 -0600714 self.response = artifacts_pb2.BundleResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600715
Alex Klein1699fab2022-09-08 08:46:06 -0600716 def _GetRequest(
717 self,
718 chroot: Optional[str] = None,
719 sysroot: Optional[str] = None,
720 build_target: Optional[str] = None,
721 output_dir: Optional[str] = None,
722 ) -> artifacts_pb2.BundleRequest:
723 """Helper to create a request message instance.
Alex Klein2275d692019-04-23 16:04:12 -0600724
Alex Klein1699fab2022-09-08 08:46:06 -0600725 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600726 chroot: The chroot path.
727 sysroot: The sysroot path.
728 build_target: The build target name.
729 output_dir: The output directory.
Alex Klein1699fab2022-09-08 08:46:06 -0600730 """
731 return artifacts_pb2.BundleRequest(
732 sysroot={"path": sysroot, "build_target": {"name": build_target}},
733 chroot={"path": chroot},
734 output_dir=output_dir,
735 )
Alex Klein2275d692019-04-23 16:04:12 -0600736
Alex Klein1699fab2022-09-08 08:46:06 -0600737 def testValidateOnly(self):
738 """Quick check that a validate only call does not execute any logic."""
739 patch = self.PatchObject(artifacts_svc, "BundleSimpleChromeArtifacts")
740 request = self._GetRequest(
741 chroot=self.chroot_dir,
742 sysroot=self.sysroot_path,
743 build_target="board",
744 output_dir=self.output_dir,
745 )
746 artifacts.BundleSimpleChromeArtifacts(
747 request, self.response, self.validate_only_config
748 )
749 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600750
Alex Klein1699fab2022-09-08 08:46:06 -0600751 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700752 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600753 patch = self.PatchObject(artifacts_svc, "BundleSimpleChromeArtifacts")
754 request = self._GetRequest(
755 chroot=self.chroot_dir,
756 sysroot=self.sysroot_path,
757 build_target="board",
758 output_dir=self.output_dir,
759 )
760 artifacts.BundleSimpleChromeArtifacts(
761 request, self.response, self.mock_call_config
762 )
763 patch.assert_not_called()
764 self.assertEqual(len(self.response.artifacts), 1)
765 self.assertEqual(
766 self.response.artifacts[0].path,
767 os.path.join(self.output_dir, "simple_chrome.txt"),
768 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700769
Alex Klein1699fab2022-09-08 08:46:06 -0600770 def testNoBuildTarget(self):
771 """Test no build target fails."""
772 request = self._GetRequest(
773 chroot=self.chroot_dir,
774 sysroot=self.sysroot_path,
775 output_dir=self.output_dir,
776 )
777 response = self.response
778 with self.assertRaises(cros_build_lib.DieSystemExit):
779 artifacts.BundleSimpleChromeArtifacts(
780 request, response, self.api_config
781 )
Alex Klein2275d692019-04-23 16:04:12 -0600782
Alex Klein1699fab2022-09-08 08:46:06 -0600783 def testNoSysroot(self):
784 """Test no sysroot fails."""
785 request = self._GetRequest(
786 build_target="board", output_dir=self.output_dir
787 )
788 response = self.response
789 with self.assertRaises(cros_build_lib.DieSystemExit):
790 artifacts.BundleSimpleChromeArtifacts(
791 request, response, self.api_config
792 )
Alex Klein2275d692019-04-23 16:04:12 -0600793
Alex Klein1699fab2022-09-08 08:46:06 -0600794 def testSysrootDoesNotExist(self):
795 """Test no sysroot fails."""
796 request = self._GetRequest(
797 build_target="board",
798 output_dir=self.output_dir,
799 sysroot=self.does_not_exist,
800 )
801 response = self.response
Alex Kleinb6847e22022-11-07 10:44:48 -0700802 artifacts.BundleSimpleChromeArtifacts(
803 request, response, self.api_config
804 )
805 self.assertFalse(self.response.artifacts)
Alex Klein2275d692019-04-23 16:04:12 -0600806
Alex Klein1699fab2022-09-08 08:46:06 -0600807 def testNoOutputDir(self):
808 """Test no output dir fails."""
809 request = self._GetRequest(
810 chroot=self.chroot_dir,
811 sysroot=self.sysroot_path,
812 build_target="board",
813 )
814 response = self.response
815 with self.assertRaises(cros_build_lib.DieSystemExit):
816 artifacts.BundleSimpleChromeArtifacts(
817 request, response, self.api_config
818 )
Alex Klein2275d692019-04-23 16:04:12 -0600819
Alex Klein1699fab2022-09-08 08:46:06 -0600820 def testOutputDirDoesNotExist(self):
821 """Test no output dir fails."""
822 request = self._GetRequest(
823 chroot=self.chroot_dir,
824 sysroot=self.sysroot_path,
825 build_target="board",
826 output_dir=self.does_not_exist,
827 )
828 response = self.response
829 with self.assertRaises(cros_build_lib.DieSystemExit):
830 artifacts.BundleSimpleChromeArtifacts(
831 request, response, self.api_config
832 )
Alex Klein2275d692019-04-23 16:04:12 -0600833
Alex Klein1699fab2022-09-08 08:46:06 -0600834 def testOutputHandling(self):
835 """Test response output."""
836 files = ["file1", "file2", "file3"]
837 expected_files = [os.path.join(self.output_dir, f) for f in files]
838 self.PatchObject(
839 artifacts_svc,
840 "BundleSimpleChromeArtifacts",
841 return_value=expected_files,
842 )
843 request = self._GetRequest(
844 chroot=self.chroot_dir,
845 sysroot=self.sysroot_path,
846 build_target="board",
847 output_dir=self.output_dir,
848 )
849 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600850
Alex Klein1699fab2022-09-08 08:46:06 -0600851 artifacts.BundleSimpleChromeArtifacts(
852 request, response, self.api_config
853 )
Alex Klein2275d692019-04-23 16:04:12 -0600854
Alex Klein1699fab2022-09-08 08:46:06 -0600855 self.assertTrue(response.artifacts)
856 self.assertCountEqual(
857 expected_files, [a.path for a in response.artifacts]
858 )
Alex Klein2275d692019-04-23 16:04:12 -0600859
860
Alex Klein1699fab2022-09-08 08:46:06 -0600861class BundleVmFilesTest(
862 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
863):
864 """BuildVmFiles tests."""
Alex Klein6504eca2019-04-18 15:37:56 -0600865
Alex Klein1699fab2022-09-08 08:46:06 -0600866 def setUp(self):
867 self.output_dir = os.path.join(self.tempdir, "output")
868 osutils.SafeMakedirs(self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600869
Alex Klein1699fab2022-09-08 08:46:06 -0600870 self.response = artifacts_pb2.BundleResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600871
Alex Klein1699fab2022-09-08 08:46:06 -0600872 def _GetInput(
873 self,
874 chroot: Optional[str] = None,
875 sysroot: Optional[str] = None,
876 test_results_dir: Optional[str] = None,
877 output_dir: Optional[str] = None,
878 ) -> artifacts_pb2.BundleVmFilesRequest:
879 """Helper to build out an input message instance.
Alex Klein6504eca2019-04-18 15:37:56 -0600880
Alex Klein1699fab2022-09-08 08:46:06 -0600881 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600882 chroot: The chroot path.
883 sysroot: The sysroot path relative to the chroot.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700884 test_results_dir: The test results directory relative to the
885 sysroot.
Alex Klein611dddd2022-10-11 17:02:01 -0600886 output_dir: The directory where the results tarball should be saved.
Alex Klein1699fab2022-09-08 08:46:06 -0600887 """
888 return artifacts_pb2.BundleVmFilesRequest(
889 chroot={"path": chroot},
890 sysroot={"path": sysroot},
891 test_results_dir=test_results_dir,
892 output_dir=output_dir,
893 )
Alex Klein6504eca2019-04-18 15:37:56 -0600894
Alex Klein1699fab2022-09-08 08:46:06 -0600895 def testValidateOnly(self):
896 """Quick check that a validate only call does not execute any logic."""
897 patch = self.PatchObject(artifacts_svc, "BundleVmFiles")
898 in_proto = self._GetInput(
899 chroot="/chroot/dir",
900 sysroot="/build/board",
901 test_results_dir="/test/results",
902 output_dir=self.output_dir,
903 )
904 artifacts.BundleVmFiles(
905 in_proto, self.response, self.validate_only_config
906 )
907 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600908
Alex Klein1699fab2022-09-08 08:46:06 -0600909 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700910 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600911 patch = self.PatchObject(artifacts_svc, "BundleVmFiles")
912 in_proto = self._GetInput(
913 chroot="/chroot/dir",
914 sysroot="/build/board",
915 test_results_dir="/test/results",
916 output_dir=self.output_dir,
917 )
918 artifacts.BundleVmFiles(in_proto, self.response, self.mock_call_config)
919 patch.assert_not_called()
920 self.assertEqual(len(self.response.artifacts), 1)
921 self.assertEqual(
922 self.response.artifacts[0].path,
923 os.path.join(self.output_dir, "f1.tar"),
924 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700925
Alex Klein1699fab2022-09-08 08:46:06 -0600926 def testChrootMissing(self):
927 """Test error handling for missing chroot."""
928 in_proto = self._GetInput(
929 sysroot="/build/board",
930 test_results_dir="/test/results",
931 output_dir=self.output_dir,
932 )
Alex Klein6504eca2019-04-18 15:37:56 -0600933
Alex Klein1699fab2022-09-08 08:46:06 -0600934 with self.assertRaises(cros_build_lib.DieSystemExit):
935 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600936
Alex Klein1699fab2022-09-08 08:46:06 -0600937 def testTestResultsDirMissing(self):
938 """Test error handling for missing test results directory."""
939 in_proto = self._GetInput(
940 chroot="/chroot/dir",
941 sysroot="/build/board",
942 output_dir=self.output_dir,
943 )
Alex Klein6504eca2019-04-18 15:37:56 -0600944
Alex Klein1699fab2022-09-08 08:46:06 -0600945 with self.assertRaises(cros_build_lib.DieSystemExit):
946 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600947
Alex Klein1699fab2022-09-08 08:46:06 -0600948 def testOutputDirMissing(self):
949 """Test error handling for missing output directory."""
950 in_proto = self._GetInput(
951 chroot="/chroot/dir",
952 sysroot="/build/board",
953 test_results_dir="/test/results",
954 )
Alex Klein6504eca2019-04-18 15:37:56 -0600955
Alex Klein1699fab2022-09-08 08:46:06 -0600956 with self.assertRaises(cros_build_lib.DieSystemExit):
957 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600958
Alex Klein1699fab2022-09-08 08:46:06 -0600959 def testOutputDirDoesNotExist(self):
960 """Test error handling for output directory that does not exist."""
961 in_proto = self._GetInput(
962 chroot="/chroot/dir",
963 sysroot="/build/board",
964 output_dir=os.path.join(self.tempdir, "dne"),
965 test_results_dir="/test/results",
966 )
Alex Klein231d2da2019-07-22 16:44:45 -0600967
Alex Klein1699fab2022-09-08 08:46:06 -0600968 with self.assertRaises(cros_build_lib.DieSystemExit):
969 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600970
Alex Klein1699fab2022-09-08 08:46:06 -0600971 def testValidCall(self):
972 """Test image dir building."""
973 in_proto = self._GetInput(
974 chroot="/chroot/dir",
975 sysroot="/build/board",
976 test_results_dir="/test/results",
977 output_dir=self.output_dir,
978 )
Alex Klein231d2da2019-07-22 16:44:45 -0600979
Alex Klein1699fab2022-09-08 08:46:06 -0600980 expected_files = ["/tmp/output/f1.tar", "/tmp/output/f2.tar"]
981 patch = self.PatchObject(
982 artifacts_svc, "BundleVmFiles", return_value=expected_files
983 )
Alex Klein6504eca2019-04-18 15:37:56 -0600984
Alex Klein1699fab2022-09-08 08:46:06 -0600985 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600986
Alex Klein1699fab2022-09-08 08:46:06 -0600987 patch.assert_called_with(mock.ANY, "/test/results", self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600988
Alex Kleinab87ceb2023-01-24 12:00:51 -0700989 # Make sure we have artifacts, and that every artifact is an expected
990 # file.
Alex Klein1699fab2022-09-08 08:46:06 -0600991 self.assertTrue(self.response.artifacts)
992 for artifact in self.response.artifacts:
993 self.assertIn(artifact.path, expected_files)
994 expected_files.remove(artifact.path)
Alex Klein6504eca2019-04-18 15:37:56 -0600995
Alex Klein1699fab2022-09-08 08:46:06 -0600996 # Make sure we've seen all of the expected files.
997 self.assertFalse(expected_files)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600998
Tiancong Wang50b80a92019-08-01 14:46:15 -0700999
Alex Klein036833d2022-06-01 13:05:01 -06001000class ExportCpeReportTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -06001001 """ExportCpeReport tests."""
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001002
Alex Klein1699fab2022-09-08 08:46:06 -06001003 def testValidateOnly(self):
1004 """Quick check validate only calls don't execute."""
1005 patch = self.PatchObject(artifacts_svc, "GenerateCpeReport")
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001006
Alex Klein1699fab2022-09-08 08:46:06 -06001007 artifacts.ExportCpeReport(
1008 self.sysroot_request, self.response, self.validate_only_config
1009 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001010
Alex Klein1699fab2022-09-08 08:46:06 -06001011 patch.assert_not_called()
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001012
Alex Klein1699fab2022-09-08 08:46:06 -06001013 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -07001014 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -06001015 patch = self.PatchObject(artifacts_svc, "GenerateCpeReport")
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001016
Alex Klein1699fab2022-09-08 08:46:06 -06001017 artifacts.ExportCpeReport(
1018 self.sysroot_request, self.response, self.mock_call_config
1019 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001020
Alex Klein1699fab2022-09-08 08:46:06 -06001021 patch.assert_not_called()
1022 self.assertEqual(len(self.response.artifacts), 2)
1023 self.assertEqual(
1024 self.response.artifacts[0].path,
1025 os.path.join(self.output_dir, "cpe_report.txt"),
1026 )
1027 self.assertEqual(
1028 self.response.artifacts[1].path,
1029 os.path.join(self.output_dir, "cpe_warnings.txt"),
1030 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001031
Alex Klein1699fab2022-09-08 08:46:06 -06001032 def testSuccess(self):
1033 """Test success case."""
1034 expected = artifacts_svc.CpeResult(
1035 report="/output/report.json", warnings="/output/warnings.json"
1036 )
1037 self.PatchObject(
1038 artifacts_svc, "GenerateCpeReport", return_value=expected
1039 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001040
Alex Klein1699fab2022-09-08 08:46:06 -06001041 artifacts.ExportCpeReport(
1042 self.sysroot_request, self.response, self.api_config
1043 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001044
Alex Klein1699fab2022-09-08 08:46:06 -06001045 for artifact in self.response.artifacts:
1046 self.assertIn(artifact.path, [expected.report, expected.warnings])
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001047
1048
1049class BundleGceTarballTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -06001050 """Unittests for BundleGceTarball."""
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001051
Alex Klein1699fab2022-09-08 08:46:06 -06001052 def testValidateOnly(self):
1053 """Check that a validate only call does not execute any logic."""
1054 patch = self.PatchObject(artifacts_svc, "BundleGceTarball")
1055 artifacts.BundleGceTarball(
1056 self.target_request, self.response, self.validate_only_config
1057 )
1058 patch.assert_not_called()
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001059
Alex Klein1699fab2022-09-08 08:46:06 -06001060 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -07001061 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -06001062 patch = self.PatchObject(artifacts_svc, "BundleGceTarball")
1063 artifacts.BundleGceTarball(
1064 self.target_request, self.response, self.mock_call_config
1065 )
1066 patch.assert_not_called()
1067 self.assertEqual(len(self.response.artifacts), 1)
1068 self.assertEqual(
1069 self.response.artifacts[0].path,
1070 os.path.join(self.output_dir, constants.TEST_IMAGE_GCE_TAR),
1071 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001072
Alex Klein1699fab2022-09-08 08:46:06 -06001073 def testBundleGceTarball(self):
1074 """BundleGceTarball calls cbuildbot/commands with correct args."""
1075 bundle_gce_tarball = self.PatchObject(
1076 artifacts_svc,
1077 "BundleGceTarball",
1078 return_value=os.path.join(
1079 self.output_dir, constants.TEST_IMAGE_GCE_TAR
1080 ),
1081 )
1082 self.PatchObject(os.path, "exists", return_value=True)
1083 artifacts.BundleGceTarball(
1084 self.target_request, self.response, self.api_config
1085 )
1086 self.assertEqual(
1087 [artifact.path for artifact in self.response.artifacts],
1088 [os.path.join(self.output_dir, constants.TEST_IMAGE_GCE_TAR)],
1089 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001090
Alex Klein1699fab2022-09-08 08:46:06 -06001091 latest = os.path.join(
1092 self.source_root, "src/build/images/target/latest"
1093 )
1094 self.assertEqual(
1095 bundle_gce_tarball.call_args_list,
1096 [mock.call(self.output_dir, latest)],
1097 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001098
Alex Klein1699fab2022-09-08 08:46:06 -06001099 def testBundleGceTarballNoImageDir(self):
1100 """BundleGceTarball dies when image dir does not exist."""
1101 self.PatchObject(os.path, "exists", return_value=False)
1102 with self.assertRaises(cros_build_lib.DieSystemExit):
1103 artifacts.BundleGceTarball(
1104 self.target_request, self.response, self.api_config
1105 )
Greg Edelstondc941072021-08-11 12:32:30 -06001106
Greg Edelstondc941072021-08-11 12:32:30 -06001107
Alex Klein1699fab2022-09-08 08:46:06 -06001108class FetchMetadataTestCase(
1109 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
1110):
1111 """Unittests for FetchMetadata."""
Greg Edelstondc941072021-08-11 12:32:30 -06001112
Alex Klein1699fab2022-09-08 08:46:06 -06001113 sysroot_path = "/build/coral"
1114 chroot_name = "chroot"
Greg Edelstondc941072021-08-11 12:32:30 -06001115
Alex Klein1699fab2022-09-08 08:46:06 -06001116 def setUp(self):
1117 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001118 self.chroot = chroot_lib.Chroot(
1119 path=self.tempdir / "chroot",
1120 out_path=self.tempdir / "out",
1121 )
1122 pathlib.Path(self.chroot.path).touch()
1123 self.chroot.out_path.touch()
Alex Klein1699fab2022-09-08 08:46:06 -06001124 self.expected_filepaths = [
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001125 self.chroot.full_path(fp)
Alex Klein1699fab2022-09-08 08:46:06 -06001126 for fp in (
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001127 "/build/coral/usr/local/build/autotest/autotest_metadata.pb",
1128 "/build/coral/usr/share/tast/metadata/local/cros.pb",
1129 "/build/coral/build/share/tast/metadata/local/crosint.pb",
1130 "/usr/share/tast/metadata/remote/cros.pb",
Alex Klein1699fab2022-09-08 08:46:06 -06001131 )
1132 ]
1133 self.PatchObject(cros_build_lib, "AssertOutsideChroot")
Greg Edelstondc941072021-08-11 12:32:30 -06001134
Alex Klein1699fab2022-09-08 08:46:06 -06001135 def createFetchMetadataRequest(
1136 self, use_sysroot_path=True, use_chroot=True
1137 ):
1138 """Construct a FetchMetadataRequest for use in test cases."""
1139 request = artifacts_pb2.FetchMetadataRequest()
1140 if use_sysroot_path:
1141 request.sysroot.path = self.sysroot_path
1142 if use_chroot:
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001143 request.chroot.path = self.chroot.path
1144 request.chroot.out_path = str(self.chroot.out_path)
Alex Klein1699fab2022-09-08 08:46:06 -06001145 return request
Greg Edelstondc941072021-08-11 12:32:30 -06001146
Alex Klein1699fab2022-09-08 08:46:06 -06001147 def testValidateOnly(self):
1148 """Check that a validate only call does not execute any logic."""
1149 patch = self.PatchObject(controller_util, "ParseSysroot")
1150 request = self.createFetchMetadataRequest()
1151 response = artifacts_pb2.FetchMetadataResponse()
1152 artifacts.FetchMetadata(request, response, self.validate_only_config)
1153 patch.assert_not_called()
Greg Edelstondc941072021-08-11 12:32:30 -06001154
Alex Klein1699fab2022-09-08 08:46:06 -06001155 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -07001156 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -06001157 patch = self.PatchObject(controller_util, "ParseSysroot")
1158 request = self.createFetchMetadataRequest()
1159 response = artifacts_pb2.FetchMetadataResponse()
1160 artifacts.FetchMetadata(request, response, self.mock_call_config)
1161 patch.assert_not_called()
1162 self.assertGreater(len(response.filepaths), 0)
Greg Edelstondc941072021-08-11 12:32:30 -06001163
Alex Klein1699fab2022-09-08 08:46:06 -06001164 def testNoSysrootPath(self):
1165 """Check that a request with no sysroot.path results in failure."""
1166 request = self.createFetchMetadataRequest(use_sysroot_path=False)
1167 response = artifacts_pb2.FetchMetadataResponse()
1168 with self.assertRaises(cros_build_lib.DieSystemExit):
1169 artifacts.FetchMetadata(request, response, self.api_config)
Greg Edelstondc941072021-08-11 12:32:30 -06001170
Alex Klein1699fab2022-09-08 08:46:06 -06001171 def testNoChroot(self):
1172 """Check that a request with no chroot results in failure."""
1173 request = self.createFetchMetadataRequest(use_chroot=False)
1174 response = artifacts_pb2.FetchMetadataResponse()
1175 with self.assertRaises(cros_build_lib.DieSystemExit):
1176 artifacts.FetchMetadata(request, response, self.api_config)
1177
1178 def testSuccess(self):
1179 """Check that a well-formed request yields the expected results."""
1180 request = self.createFetchMetadataRequest(use_chroot=True)
1181 response = artifacts_pb2.FetchMetadataResponse()
1182 artifacts.FetchMetadata(request, response, self.api_config)
1183 actual_filepaths = [fp.path.path for fp in response.filepaths]
1184 self.assertEqual(
1185 sorted(actual_filepaths), sorted(self.expected_filepaths)
1186 )
1187 self.assertTrue(
1188 all(
1189 fp.path.location == common_pb2.Path.OUTSIDE
1190 for fp in response.filepaths
1191 )
1192 )
Jack Neus26b94672022-10-27 17:33:21 +00001193
1194
1195class GetTest(cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
1196 """Get function tests."""
1197
1198 def setUp(self):
1199 self.sysroot_path = "/build/target"
1200 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
1201
1202 def _InputProto(self):
1203 """Helper to build an input proto instance."""
Alex Kleinab87ceb2023-01-24 12:00:51 -07001204 # pylint: disable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001205 return artifacts_pb2.GetRequest(
1206 sysroot=sysroot_pb2.Sysroot(path=self.sysroot_path),
1207 artifact_info=common_pb2.ArtifactsByService(
1208 sysroot=common_pb2.ArtifactsByService.Sysroot(
1209 output_artifacts=[
1210 common_pb2.ArtifactsByService.Sysroot.ArtifactInfo(
1211 artifact_types=[
1212 common_pb2.ArtifactsByService.Sysroot.ArtifactType.FUZZER_SYSROOT
1213 ]
1214 )
1215 ],
1216 ),
1217 image=common_pb2.ArtifactsByService.Image(
1218 output_artifacts=[
1219 common_pb2.ArtifactsByService.Image.ArtifactInfo(
1220 artifact_types=[
1221 common_pb2.ArtifactsByService.Image.ArtifactType.LICENSE_CREDITS
1222 ]
1223 )
1224 ],
1225 ),
1226 test=common_pb2.ArtifactsByService.Test(
1227 output_artifacts=[
1228 common_pb2.ArtifactsByService.Test.ArtifactInfo(
1229 artifact_types=[
1230 common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL
1231 ]
1232 )
1233 ],
1234 ),
1235 ),
1236 result_path=common_pb2.ResultPath(
1237 path=common_pb2.Path(path=str(self.tempdir))
1238 ),
1239 )
Alex Kleinab87ceb2023-01-24 12:00:51 -07001240 # pylint: enable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001241
1242 def _OutputProto(self):
1243 """Helper to build an output proto instance."""
1244 return artifacts_pb2.GetResponse()
1245
1246 def testSuccess(self):
1247 """Test Get."""
Alex Kleinab87ceb2023-01-24 12:00:51 -07001248 # pylint: disable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001249 image_mock = self.PatchObject(
1250 image_controller,
1251 "GetArtifacts",
1252 return_value=[
1253 {
1254 "paths": ["/foo/bar/license_credits.html"],
1255 "type": common_pb2.ArtifactsByService.Image.ArtifactType.LICENSE_CREDITS,
1256 }
1257 ],
1258 )
1259 sysroot_mock = self.PatchObject(
1260 sysroot_controller,
1261 "GetArtifacts",
1262 return_value=[
1263 {
1264 "type": common_pb2.ArtifactsByService.Sysroot.ArtifactType.FUZZER_SYSROOT,
1265 "failed": True,
1266 "failure_reason": "Bad data!",
1267 }
1268 ],
1269 )
1270 test_mock = self.PatchObject(
1271 test_controller,
1272 "GetArtifacts",
1273 return_value=[
1274 {
1275 "paths": ["/foo/bar/hwqual.tar.xz"],
1276 "type": common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL,
1277 }
1278 ],
1279 )
Alex Kleinab87ceb2023-01-24 12:00:51 -07001280 # pylint: enable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001281
1282 in_proto = self._InputProto()
1283 out_proto = self._OutputProto()
1284 artifacts.Get(
1285 in_proto,
1286 out_proto,
1287 self.api_config,
1288 )
1289
1290 image_mock.assert_called_once()
1291 sysroot_mock.assert_called_once()
1292 test_mock.assert_called_once()
1293
Alex Kleinab87ceb2023-01-24 12:00:51 -07001294 # pylint: disable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001295 expected = common_pb2.UploadedArtifactsByService(
1296 sysroot=common_pb2.UploadedArtifactsByService.Sysroot(
1297 artifacts=[
1298 common_pb2.UploadedArtifactsByService.Sysroot.ArtifactPaths(
1299 artifact_type=common_pb2.ArtifactsByService.Sysroot.ArtifactType.FUZZER_SYSROOT,
1300 failed=True,
1301 failure_reason="Bad data!",
1302 )
1303 ]
1304 ),
1305 image=common_pb2.UploadedArtifactsByService.Image(
1306 artifacts=[
1307 common_pb2.UploadedArtifactsByService.Image.ArtifactPaths(
1308 artifact_type=common_pb2.ArtifactsByService.Image.ArtifactType.LICENSE_CREDITS,
1309 paths=[
1310 common_pb2.Path(
1311 path="/foo/bar/license_credits.html",
1312 location=common_pb2.Path.OUTSIDE,
1313 )
1314 ],
1315 )
1316 ]
1317 ),
1318 test=common_pb2.UploadedArtifactsByService.Test(
1319 artifacts=[
1320 common_pb2.UploadedArtifactsByService.Test.ArtifactPaths(
1321 artifact_type=common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL,
1322 paths=[
1323 common_pb2.Path(
1324 path="/foo/bar/hwqual.tar.xz",
1325 location=common_pb2.Path.OUTSIDE,
1326 )
1327 ],
1328 )
1329 ]
1330 ),
1331 )
Alex Kleinab87ceb2023-01-24 12:00:51 -07001332 # pylint: enable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001333 self.assertEqual(out_proto.artifacts, expected)