blob: 9630a6d88916dba4463e966ff5224ca0a86fab21 [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:
Brian Norris2711f3a2023-07-18 11:09:00 -070045 request.result_path.path.path = str(output_dir)
46 request.result_path.path.location = common_pb2.Path.Location.OUTSIDE
Alex Klein1699fab2022-09-08 08:46:06 -060047 if chroot:
48 request.chroot.path = chroot
Alex Kleind91e95a2019-09-17 10:39:02 -060049
Alex Klein1699fab2022-09-08 08:46:06 -060050 return request
Alex Kleind91e95a2019-09-17 10:39:02 -060051
Alex Klein1699fab2022-09-08 08:46:06 -060052 def SysrootRequest(
Brian Norris09937012023-03-31 15:16:55 -070053 self,
54 sysroot=None,
55 build_target=None,
56 output_dir=None,
57 chroot=None,
58 chroot_out=None,
Alex Klein1699fab2022-09-08 08:46:06 -060059 ):
60 """Get a sysroot format request instance."""
61 request = self.EmptyRequest()
62 if sysroot:
63 request.sysroot.path = sysroot
64 if build_target:
65 request.sysroot.build_target.name = build_target
66 if output_dir:
Brian Norris2711f3a2023-07-18 11:09:00 -070067 request.result_path.path.path = output_dir
68 request.result_path.path.location = common_pb2.Path.Location.OUTSIDE
Alex Klein1699fab2022-09-08 08:46:06 -060069 if chroot:
Brian Norris09937012023-03-31 15:16:55 -070070 request.chroot.path = str(chroot)
71 if chroot_out:
72 request.chroot.out_path = str(chroot_out)
Alex Kleind91e95a2019-09-17 10:39:02 -060073
Alex Klein1699fab2022-09-08 08:46:06 -060074 return request
Alex Kleind91e95a2019-09-17 10:39:02 -060075
76
Alex Klein1699fab2022-09-08 08:46:06 -060077class BundleTestCase(
78 cros_test_lib.MockTempDirTestCase,
79 api_config.ApiConfigMixin,
80 BundleRequestMixin,
81):
82 """Basic setup for all artifacts unittests."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -060083
Alex Klein1699fab2022-09-08 08:46:06 -060084 def setUp(self):
85 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
86 self.output_dir = os.path.join(self.tempdir, "artifacts")
87 osutils.SafeMakedirs(self.output_dir)
88 self.sysroot_path = "/build/target"
89 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Brian Norrisa9cc6b32023-05-10 13:43:45 -070090 self.chroot = chroot_lib.Chroot(
91 path=self.tempdir / "chroot",
92 out_path=self.tempdir / "out",
Alex Klein1699fab2022-09-08 08:46:06 -060093 )
Brian Norrisa9cc6b32023-05-10 13:43:45 -070094 full_sysroot_path = self.chroot.full_path(self.sysroot_path)
Alex Klein1699fab2022-09-08 08:46:06 -060095 osutils.SafeMakedirs(full_sysroot_path)
Brian Norrisa9cc6b32023-05-10 13:43:45 -070096 osutils.SafeMakedirs(self.chroot.path)
97 osutils.SafeMakedirs(self.chroot.out_path)
Alex Klein231d2da2019-07-22 16:44:45 -060098
Alex Klein1699fab2022-09-08 08:46:06 -060099 # All requests use same response type.
100 self.response = artifacts_pb2.BundleResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600101
Alex Klein1699fab2022-09-08 08:46:06 -0600102 # Build target request.
103 self.target_request = self.BuildTargetRequest(
104 build_target="target",
105 output_dir=self.output_dir,
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700106 chroot=self.chroot.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600107 )
Alex Klein68c8fdf2019-09-25 15:09:11 -0600108
Alex Klein1699fab2022-09-08 08:46:06 -0600109 # Sysroot request.
110 self.sysroot_request = self.SysrootRequest(
111 sysroot=self.sysroot_path,
112 build_target="target",
113 output_dir=self.output_dir,
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700114 chroot=self.chroot.path,
115 chroot_out=self.chroot.out_path,
Alex Klein1699fab2022-09-08 08:46:06 -0600116 )
Alex Klein68c8fdf2019-09-25 15:09:11 -0600117
Alex Klein1699fab2022-09-08 08:46:06 -0600118 self.source_root = self.tempdir
119 self.PatchObject(constants, "SOURCE_ROOT", new=self.tempdir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600120
121
Alex Kleind91e95a2019-09-17 10:39:02 -0600122class BundleImageArchivesTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600123 """BundleImageArchives tests."""
Alex Kleind91e95a2019-09-17 10:39:02 -0600124
Alex Klein1699fab2022-09-08 08:46:06 -0600125 def testValidateOnly(self):
126 """Quick check that a validate only call does not execute any logic."""
127 patch = self.PatchObject(artifacts_svc, "ArchiveImages")
128 artifacts.BundleImageArchives(
Hsin-Yi Wang09663da2023-06-28 21:40:24 +0800129 self.sysroot_request, self.response, self.validate_only_config
Alex Klein1699fab2022-09-08 08:46:06 -0600130 )
131 patch.assert_not_called()
Alex Kleind91e95a2019-09-17 10:39:02 -0600132
Alex Klein1699fab2022-09-08 08:46:06 -0600133 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700134 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600135 patch = self.PatchObject(artifacts_svc, "ArchiveImages")
136 artifacts.BundleImageArchives(
Hsin-Yi Wang09663da2023-06-28 21:40:24 +0800137 self.sysroot_request, self.response, self.mock_call_config
Alex Klein1699fab2022-09-08 08:46:06 -0600138 )
139 patch.assert_not_called()
140 self.assertEqual(len(self.response.artifacts), 2)
141 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700142 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600143 os.path.join(self.output_dir, "path0.tar.xz"),
144 )
145 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700146 self.response.artifacts[1].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600147 os.path.join(self.output_dir, "path1.tar.xz"),
148 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700149
Alex Klein1699fab2022-09-08 08:46:06 -0600150 def testNoBuildTarget(self):
151 """Test that no build target fails."""
152 request = self.BuildTargetRequest(output_dir=str(self.tempdir))
153 with self.assertRaises(cros_build_lib.DieSystemExit):
154 artifacts.BundleImageArchives(
155 request, self.response, self.api_config
156 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600157
Alex Klein1699fab2022-09-08 08:46:06 -0600158 def testNoOutputDir(self):
159 """Test no output dir fails."""
160 request = self.BuildTargetRequest(build_target="board")
161 with self.assertRaises(cros_build_lib.DieSystemExit):
162 artifacts.BundleImageArchives(
163 request, self.response, self.api_config
164 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600165
Alex Klein1699fab2022-09-08 08:46:06 -0600166 def testInvalidOutputDir(self):
167 """Test invalid output dir fails."""
168 request = self.BuildTargetRequest(
169 build_target="board", output_dir=os.path.join(self.tempdir, "DNE")
170 )
171 with self.assertRaises(cros_build_lib.DieSystemExit):
172 artifacts.BundleImageArchives(
173 request, self.response, self.api_config
174 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600175
Alex Klein1699fab2022-09-08 08:46:06 -0600176 def testOutputHandling(self):
177 """Test the artifact output handling."""
178 expected = [os.path.join(self.output_dir, f) for f in ("a", "b", "c")]
179 self.PatchObject(artifacts_svc, "ArchiveImages", return_value=expected)
180 self.PatchObject(os.path, "exists", return_value=True)
Alex Kleind91e95a2019-09-17 10:39:02 -0600181
Alex Klein1699fab2022-09-08 08:46:06 -0600182 artifacts.BundleImageArchives(
Hsin-Yi Wang09663da2023-06-28 21:40:24 +0800183 self.sysroot_request, self.response, self.api_config
Alex Klein1699fab2022-09-08 08:46:06 -0600184 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600185
Alex Klein1699fab2022-09-08 08:46:06 -0600186 self.assertCountEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700187 expected, [a.artifact_path.path for a in self.response.artifacts]
Alex Klein1699fab2022-09-08 08:46:06 -0600188 )
Alex Kleind91e95a2019-09-17 10:39:02 -0600189
190
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600191class BundleImageZipTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600192 """Unittests for BundleImageZip."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600193
Alex Klein1699fab2022-09-08 08:46:06 -0600194 def testValidateOnly(self):
195 """Quick check that a validate only call does not execute any logic."""
196 patch = self.PatchObject(commands, "BuildImageZip")
197 artifacts.BundleImageZip(
198 self.target_request, self.response, self.validate_only_config
199 )
200 patch.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600201
Alex Klein1699fab2022-09-08 08:46:06 -0600202 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700203 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600204 patch = self.PatchObject(commands, "BuildImageZip")
205 artifacts.BundleImageZip(
206 self.target_request, self.response, self.mock_call_config
207 )
208 patch.assert_not_called()
209 self.assertEqual(len(self.response.artifacts), 1)
210 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700211 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600212 os.path.join(self.output_dir, "image.zip"),
213 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700214
Alex Klein1699fab2022-09-08 08:46:06 -0600215 def testBundleImageZip(self):
216 """BundleImageZip calls cbuildbot/commands with correct args."""
217 bundle_image_zip = self.PatchObject(
218 artifacts_svc, "BundleImageZip", return_value="image.zip"
219 )
220 self.PatchObject(os.path, "exists", return_value=True)
221 artifacts.BundleImageZip(
222 self.target_request, self.response, self.api_config
223 )
224 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700225 [
226 artifact.artifact_path.path
227 for artifact in self.response.artifacts
228 ],
Alex Klein1699fab2022-09-08 08:46:06 -0600229 [os.path.join(self.output_dir, "image.zip")],
230 )
Alex Klein231d2da2019-07-22 16:44:45 -0600231
Alex Klein1699fab2022-09-08 08:46:06 -0600232 latest = os.path.join(
233 self.source_root, "src/build/images/target/latest"
234 )
235 self.assertEqual(
236 bundle_image_zip.call_args_list,
237 [mock.call(self.output_dir, latest)],
238 )
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600239
Alex Klein1699fab2022-09-08 08:46:06 -0600240 def testBundleImageZipNoImageDir(self):
241 """BundleImageZip dies when image dir does not exist."""
242 self.PatchObject(os.path, "exists", return_value=False)
243 with self.assertRaises(cros_build_lib.DieSystemExit):
244 artifacts.BundleImageZip(
245 self.target_request, self.response, self.api_config
246 )
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600247
248
Alex Klein68c8fdf2019-09-25 15:09:11 -0600249class BundleAutotestFilesTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600250 """Unittests for BundleAutotestFiles."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600251
Alex Klein1699fab2022-09-08 08:46:06 -0600252 def testValidateOnly(self):
253 """Quick check that a validate only call does not execute any logic."""
254 patch = self.PatchObject(artifacts_svc, "BundleAutotestFiles")
255 artifacts.BundleAutotestFiles(
256 self.sysroot_request, self.response, self.validate_only_config
257 )
258 patch.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600259
Alex Klein1699fab2022-09-08 08:46:06 -0600260 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700261 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600262 patch = self.PatchObject(artifacts_svc, "BundleAutotestFiles")
263 artifacts.BundleAutotestFiles(
264 self.sysroot_request, self.response, self.mock_call_config
265 )
266 patch.assert_not_called()
267 self.assertEqual(len(self.response.artifacts), 1)
268 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700269 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600270 os.path.join(self.output_dir, "autotest-a.tar.gz"),
271 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700272
Alex Klein1699fab2022-09-08 08:46:06 -0600273 def testBundleAutotestFiles(self):
274 """BundleAutotestFiles calls service correctly."""
Alex Kleinab87ceb2023-01-24 12:00:51 -0700275
Alex Klein1699fab2022-09-08 08:46:06 -0600276 files = {
Alex Kleinab87ceb2023-01-24 12:00:51 -0700277 artifacts_svc.ARCHIVE_CONTROL_FILES: (
278 "/tmp/artifacts/autotest-a.tar.gz"
279 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600280 artifacts_svc.ARCHIVE_PACKAGES: "/tmp/artifacts/autotest-b.tar.gz",
281 }
282 patch = self.PatchObject(
283 artifacts_svc, "BundleAutotestFiles", return_value=files
284 )
Alex Klein238d8862019-05-07 11:32:46 -0600285
Alex Klein1699fab2022-09-08 08:46:06 -0600286 artifacts.BundleAutotestFiles(
287 self.sysroot_request, self.response, self.api_config
288 )
Alex Klein238d8862019-05-07 11:32:46 -0600289
Alex Klein1699fab2022-09-08 08:46:06 -0600290 # Verify the arguments are being passed through.
291 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600292
Alex Klein1699fab2022-09-08 08:46:06 -0600293 # Verify the output proto is being populated correctly.
294 self.assertTrue(self.response.artifacts)
Brian Norris2711f3a2023-07-18 11:09:00 -0700295 paths = [
296 artifact.artifact_path.path for artifact in self.response.artifacts
297 ]
Alex Klein1699fab2022-09-08 08:46:06 -0600298 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600299
Alex Klein1699fab2022-09-08 08:46:06 -0600300 def testInvalidOutputDir(self):
301 """Test invalid output directory argument."""
302 request = self.SysrootRequest(
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700303 chroot=self.chroot.path, sysroot=self.sysroot_path
Alex Klein1699fab2022-09-08 08:46:06 -0600304 )
Alex Klein238d8862019-05-07 11:32:46 -0600305
Alex Klein1699fab2022-09-08 08:46:06 -0600306 with self.assertRaises(cros_build_lib.DieSystemExit):
307 artifacts.BundleAutotestFiles(
308 request, self.response, self.api_config
309 )
Alex Klein238d8862019-05-07 11:32:46 -0600310
Alex Klein1699fab2022-09-08 08:46:06 -0600311 def testInvalidSysroot(self):
312 """Test no sysroot directory."""
313 request = self.SysrootRequest(
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700314 chroot=self.chroot.path, output_dir=self.output_dir
Alex Klein1699fab2022-09-08 08:46:06 -0600315 )
Alex Klein238d8862019-05-07 11:32:46 -0600316
Alex Klein1699fab2022-09-08 08:46:06 -0600317 with self.assertRaises(cros_build_lib.DieSystemExit):
318 artifacts.BundleAutotestFiles(
319 request, self.response, self.api_config
320 )
Alex Klein238d8862019-05-07 11:32:46 -0600321
Alex Klein1699fab2022-09-08 08:46:06 -0600322 def testSysrootDoesNotExist(self):
323 """Test dies when no sysroot does not exist."""
324 request = self.SysrootRequest(
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700325 chroot=self.chroot.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600326 sysroot="/does/not/exist",
327 output_dir=self.output_dir,
328 )
Alex Klein238d8862019-05-07 11:32:46 -0600329
Alex Klein1699fab2022-09-08 08:46:06 -0600330 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
331 self.assertFalse(self.response.artifacts)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600332
333
334class BundleTastFilesTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600335 """Unittests for BundleTastFiles."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600336
Alex Klein1699fab2022-09-08 08:46:06 -0600337 def testValidateOnly(self):
338 """Quick check that a validate only call does not execute any logic."""
339 patch = self.PatchObject(artifacts_svc, "BundleTastFiles")
340 artifacts.BundleTastFiles(
341 self.sysroot_request, self.response, self.validate_only_config
342 )
343 patch.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600344
Alex Klein1699fab2022-09-08 08:46:06 -0600345 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700346 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600347 patch = self.PatchObject(artifacts_svc, "BundleTastFiles")
348 artifacts.BundleTastFiles(
349 self.sysroot_request, self.response, self.mock_call_config
350 )
351 patch.assert_not_called()
352 self.assertEqual(len(self.response.artifacts), 1)
353 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700354 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600355 os.path.join(self.output_dir, "tast_bundles.tar.gz"),
356 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700357
Alex Klein1699fab2022-09-08 08:46:06 -0600358 def testBundleTastFilesNoLogs(self):
359 """BundleTasteFiles succeeds when no tast files found."""
360 self.PatchObject(commands, "BuildTastBundleTarball", return_value=None)
361 artifacts.BundleTastFiles(
362 self.sysroot_request, self.response, self.api_config
363 )
364 self.assertFalse(self.response.artifacts)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600365
Alex Klein1699fab2022-09-08 08:46:06 -0600366 def testBundleTastFiles(self):
367 """BundleTastFiles calls service correctly."""
Alex Klein1699fab2022-09-08 08:46:06 -0600368 expected_archive = os.path.join(
369 self.output_dir, artifacts_svc.TAST_BUNDLE_NAME
370 )
371 # Patch the service being called.
372 bundle_patch = self.PatchObject(
373 artifacts_svc, "BundleTastFiles", return_value=expected_archive
374 )
Alex Kleinb9d810b2019-07-01 12:38:02 -0600375
Alex Klein1699fab2022-09-08 08:46:06 -0600376 artifacts.BundleTastFiles(
377 self.sysroot_request, self.response, self.api_config
378 )
Alex Kleinb9d810b2019-07-01 12:38:02 -0600379
Alex Klein1699fab2022-09-08 08:46:06 -0600380 # Make sure the artifact got recorded successfully.
381 self.assertTrue(self.response.artifacts)
Brian Norris2711f3a2023-07-18 11:09:00 -0700382 self.assertEqual(
383 expected_archive, self.response.artifacts[0].artifact_path.path
384 )
Alex Klein1699fab2022-09-08 08:46:06 -0600385 # Make sure the service got called correctly.
386 bundle_patch.assert_called_once_with(
Brian Norrisa9cc6b32023-05-10 13:43:45 -0700387 self.chroot, self.sysroot, self.output_dir
Alex Klein1699fab2022-09-08 08:46:06 -0600388 )
Alex Kleinb9d810b2019-07-01 12:38:02 -0600389
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600390
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600391class BundleFirmwareTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600392 """Unittests for BundleFirmware."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600393
Alex Klein1699fab2022-09-08 08:46:06 -0600394 def testValidateOnly(self):
395 """Quick check that a validate only call does not execute any logic."""
396 patch = self.PatchObject(artifacts_svc, "BundleTastFiles")
397 artifacts.BundleFirmware(
398 self.sysroot_request, self.response, self.validate_only_config
399 )
400 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000401
Alex Klein1699fab2022-09-08 08:46:06 -0600402 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700403 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600404 patch = self.PatchObject(artifacts_svc, "BundleTastFiles")
405 artifacts.BundleFirmware(
406 self.sysroot_request, self.response, self.mock_call_config
407 )
408 patch.assert_not_called()
409 self.assertEqual(len(self.response.artifacts), 1)
410 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700411 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600412 os.path.join(self.output_dir, "firmware.tar.gz"),
413 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700414
Alex Klein1699fab2022-09-08 08:46:06 -0600415 def testBundleFirmware(self):
416 """BundleFirmware calls cbuildbot/commands with correct args."""
417 self.PatchObject(
418 artifacts_svc,
419 "BuildFirmwareArchive",
420 return_value=os.path.join(self.output_dir, "firmware.tar.gz"),
421 )
Alex Klein231d2da2019-07-22 16:44:45 -0600422
Alex Klein1699fab2022-09-08 08:46:06 -0600423 artifacts.BundleFirmware(
424 self.sysroot_request, self.response, self.api_config
425 )
426 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700427 [
428 artifact.artifact_path.path
429 for artifact in self.response.artifacts
430 ],
Alex Klein1699fab2022-09-08 08:46:06 -0600431 [os.path.join(self.output_dir, "firmware.tar.gz")],
432 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600433
Alex Klein1699fab2022-09-08 08:46:06 -0600434 def testBundleFirmwareNoLogs(self):
435 """BundleFirmware dies when no firmware found."""
436 self.PatchObject(commands, "BuildFirmwareArchive", return_value=None)
437 artifacts.BundleFirmware(
438 self.sysroot_request, self.response, self.api_config
439 )
440 self.assertEqual(len(self.response.artifacts), 0)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600441
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600442
Yicheng Liea1181f2020-09-22 11:51:10 -0700443class BundleFpmcuUnittestsTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600444 """Unittests for BundleFpmcuUnittests."""
Yicheng Liea1181f2020-09-22 11:51:10 -0700445
Alex Klein1699fab2022-09-08 08:46:06 -0600446 def testValidateOnly(self):
447 """Quick check that a validate only call does not execute any logic."""
448 patch = self.PatchObject(artifacts_svc, "BundleFpmcuUnittests")
449 artifacts.BundleFpmcuUnittests(
450 self.sysroot_request, self.response, self.validate_only_config
451 )
452 patch.assert_not_called()
Yicheng Liea1181f2020-09-22 11:51:10 -0700453
Alex Klein1699fab2022-09-08 08:46:06 -0600454 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700455 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600456 patch = self.PatchObject(artifacts_svc, "BundleFpmcuUnittests")
457 artifacts.BundleFpmcuUnittests(
458 self.sysroot_request, self.response, self.mock_call_config
459 )
460 patch.assert_not_called()
461 self.assertEqual(len(self.response.artifacts), 1)
462 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700463 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600464 os.path.join(self.output_dir, "fpmcu_unittests.tar.gz"),
465 )
Yicheng Liea1181f2020-09-22 11:51:10 -0700466
Alex Klein1699fab2022-09-08 08:46:06 -0600467 def testBundleFpmcuUnittests(self):
468 """BundleFpmcuUnittests calls cbuildbot/commands with correct args."""
469 self.PatchObject(
470 artifacts_svc,
471 "BundleFpmcuUnittests",
472 return_value=os.path.join(
473 self.output_dir, "fpmcu_unittests.tar.gz"
474 ),
475 )
476 artifacts.BundleFpmcuUnittests(
477 self.sysroot_request, self.response, self.api_config
478 )
479 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700480 [
481 artifact.artifact_path.path
482 for artifact in self.response.artifacts
483 ],
Alex Klein1699fab2022-09-08 08:46:06 -0600484 [os.path.join(self.output_dir, "fpmcu_unittests.tar.gz")],
485 )
Yicheng Liea1181f2020-09-22 11:51:10 -0700486
Alex Klein1699fab2022-09-08 08:46:06 -0600487 def testBundleFpmcuUnittestsNoLogs(self):
488 """BundleFpmcuUnittests does not die when no fpmcu unittests found."""
489 self.PatchObject(
490 artifacts_svc, "BundleFpmcuUnittests", return_value=None
491 )
492 artifacts.BundleFpmcuUnittests(
493 self.sysroot_request, self.response, self.api_config
494 )
495 self.assertFalse(self.response.artifacts)
Yicheng Liea1181f2020-09-22 11:51:10 -0700496
497
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600498class BundleEbuildLogsTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600499 """Unittests for BundleEbuildLogs."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600500
Alex Klein1699fab2022-09-08 08:46:06 -0600501 def testValidateOnly(self):
502 """Quick check that a validate only call does not execute any logic."""
503 patch = self.PatchObject(commands, "BuildEbuildLogsTarball")
504 artifacts.BundleEbuildLogs(
505 self.sysroot_request, self.response, self.validate_only_config
506 )
507 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600508
Alex Klein1699fab2022-09-08 08:46:06 -0600509 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700510 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600511 patch = self.PatchObject(commands, "BuildEbuildLogsTarball")
512 artifacts.BundleEbuildLogs(
513 self.sysroot_request, self.response, self.mock_call_config
514 )
515 patch.assert_not_called()
516 self.assertEqual(len(self.response.artifacts), 1)
517 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700518 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600519 os.path.join(self.output_dir, "ebuild-logs.tar.gz"),
520 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700521
Alex Klein1699fab2022-09-08 08:46:06 -0600522 def testBundleEbuildLogs(self):
523 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
524 bundle_ebuild_logs_tarball = self.PatchObject(
525 artifacts_svc,
526 "BundleEBuildLogsTarball",
527 return_value="ebuild-logs.tar.gz",
528 )
529 artifacts.BundleEbuildLogs(
530 self.sysroot_request, self.response, self.api_config
531 )
532 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700533 [
534 artifact.artifact_path.path
535 for artifact in self.response.artifacts
536 ],
Alex Klein1699fab2022-09-08 08:46:06 -0600537 [os.path.join(self.output_dir, "ebuild-logs.tar.gz")],
538 )
539 self.assertEqual(
540 bundle_ebuild_logs_tarball.call_args_list,
541 [mock.call(mock.ANY, self.sysroot, self.output_dir)],
542 )
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600543
Alex Klein1699fab2022-09-08 08:46:06 -0600544 def testBundleEbuildLogsNoLogs(self):
545 """BundleEbuildLogs dies when no logs found."""
546 self.PatchObject(commands, "BuildEbuildLogsTarball", return_value=None)
547 artifacts.BundleEbuildLogs(
548 self.sysroot_request, self.response, self.api_config
549 )
Alex Klein036833d2022-06-01 13:05:01 -0600550
Alex Klein1699fab2022-09-08 08:46:06 -0600551 self.assertFalse(self.response.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600552
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600553
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600554class BundleChromeOSConfigTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600555 """Unittests for BundleChromeOSConfig"""
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600556
Alex Klein1699fab2022-09-08 08:46:06 -0600557 def testValidateOnly(self):
558 """Quick check that a validate only call does not execute any logic."""
559 patch = self.PatchObject(artifacts_svc, "BundleChromeOSConfig")
560 artifacts.BundleChromeOSConfig(
561 self.sysroot_request, self.response, self.validate_only_config
562 )
563 patch.assert_not_called()
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600564
Alex Klein1699fab2022-09-08 08:46:06 -0600565 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700566 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600567 patch = self.PatchObject(artifacts_svc, "BundleChromeOSConfig")
568 artifacts.BundleChromeOSConfig(
569 self.sysroot_request, self.response, self.mock_call_config
570 )
571 patch.assert_not_called()
572 self.assertEqual(len(self.response.artifacts), 1)
573 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700574 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600575 os.path.join(self.output_dir, "config.yaml"),
576 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700577
Alex Klein1699fab2022-09-08 08:46:06 -0600578 def testBundleChromeOSConfigSuccess(self):
579 """Test standard success case."""
580 bundle_chromeos_config = self.PatchObject(
581 artifacts_svc, "BundleChromeOSConfig", return_value="config.yaml"
582 )
583 artifacts.BundleChromeOSConfig(
584 self.sysroot_request, self.response, self.api_config
585 )
586 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700587 [
588 artifact.artifact_path.path
589 for artifact in self.response.artifacts
590 ],
Alex Klein1699fab2022-09-08 08:46:06 -0600591 [os.path.join(self.output_dir, "config.yaml")],
592 )
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600593
Alex Klein1699fab2022-09-08 08:46:06 -0600594 self.assertEqual(
595 bundle_chromeos_config.call_args_list,
596 [mock.call(mock.ANY, self.sysroot, self.output_dir)],
597 )
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600598
Alex Klein1699fab2022-09-08 08:46:06 -0600599 def testBundleChromeOSConfigNoConfigFound(self):
600 """Empty results when the config payload isn't found."""
601 self.PatchObject(
602 artifacts_svc, "BundleChromeOSConfig", return_value=None
603 )
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600604
Alex Klein1699fab2022-09-08 08:46:06 -0600605 artifacts.BundleChromeOSConfig(
606 self.sysroot_request, self.response, self.api_config
607 )
608 self.assertFalse(self.response.artifacts)
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600609
610
Alex Klein1699fab2022-09-08 08:46:06 -0600611class BundleTestUpdatePayloadsTest(
612 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
613):
614 """Unittests for BundleTestUpdatePayloads."""
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600615
Alex Klein1699fab2022-09-08 08:46:06 -0600616 def setUp(self):
617 self.source_root = os.path.join(self.tempdir, "cros")
618 osutils.SafeMakedirs(self.source_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600619
Alex Klein1699fab2022-09-08 08:46:06 -0600620 self.archive_root = os.path.join(self.tempdir, "output")
621 osutils.SafeMakedirs(self.archive_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600622
Alex Klein1699fab2022-09-08 08:46:06 -0600623 self.target = "target"
624 self.image_root = os.path.join(
625 self.source_root, "src/build/images/target/latest"
626 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600627
Alex Klein1699fab2022-09-08 08:46:06 -0600628 self.input_proto = artifacts_pb2.BundleRequest()
629 self.input_proto.build_target.name = self.target
630 self.input_proto.output_dir = self.archive_root
Brian Norris2711f3a2023-07-18 11:09:00 -0700631 self.input_proto.result_path.path.path = self.archive_root
632 self.input_proto.result_path.path.location = (
633 common_pb2.Path.Location.OUTSIDE
634 )
635
Alex Klein1699fab2022-09-08 08:46:06 -0600636 self.output_proto = artifacts_pb2.BundleResponse()
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600637
Alex Klein1699fab2022-09-08 08:46:06 -0600638 self.PatchObject(constants, "SOURCE_ROOT", new=self.source_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600639
Brian Norrisdd2e7e62023-06-16 14:07:32 -0700640 def MockPayloads(_, image_path, archive_dir):
Alex Klein1699fab2022-09-08 08:46:06 -0600641 osutils.WriteFile(
642 os.path.join(archive_dir, "payload1.bin"), image_path
643 )
644 osutils.WriteFile(
645 os.path.join(archive_dir, "payload2.bin"), image_path
646 )
647 return [
648 os.path.join(archive_dir, "payload1.bin"),
649 os.path.join(archive_dir, "payload2.bin"),
650 ]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600651
Alex Klein1699fab2022-09-08 08:46:06 -0600652 self.bundle_patch = self.PatchObject(
653 artifacts_svc, "BundleTestUpdatePayloads", side_effect=MockPayloads
654 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600655
Alex Klein1699fab2022-09-08 08:46:06 -0600656 def testValidateOnly(self):
657 """Quick check that a validate only call does not execute any logic."""
658 patch = self.PatchObject(artifacts_svc, "BundleTestUpdatePayloads")
659 artifacts.BundleTestUpdatePayloads(
660 self.input_proto, self.output_proto, self.validate_only_config
661 )
662 patch.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600663
Alex Klein1699fab2022-09-08 08:46:06 -0600664 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700665 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600666 patch = self.PatchObject(artifacts_svc, "BundleTestUpdatePayloads")
667 artifacts.BundleTestUpdatePayloads(
668 self.input_proto, self.output_proto, self.mock_call_config
669 )
670 patch.assert_not_called()
671 self.assertEqual(len(self.output_proto.artifacts), 3)
672 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700673 self.output_proto.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600674 os.path.join(self.archive_root, "payload1.bin"),
675 )
676 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700677 self.output_proto.artifacts[1].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600678 os.path.join(self.archive_root, "payload1.json"),
679 )
680 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700681 self.output_proto.artifacts[2].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600682 os.path.join(self.archive_root, "payload1.log"),
683 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700684
Alex Klein1699fab2022-09-08 08:46:06 -0600685 def testBundleTestUpdatePayloads(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700686 """BundleTestUpdatePayloads calls cbuildbot/commands correctly."""
Alex Klein1699fab2022-09-08 08:46:06 -0600687 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
688 osutils.WriteFile(image_path, "image!", makedirs=True)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600689
Alex Klein1699fab2022-09-08 08:46:06 -0600690 artifacts.BundleTestUpdatePayloads(
691 self.input_proto, self.output_proto, self.api_config
692 )
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600693
Alex Klein1699fab2022-09-08 08:46:06 -0600694 actual = [
Brian Norris2711f3a2023-07-18 11:09:00 -0700695 os.path.relpath(artifact.artifact_path.path, self.archive_root)
Alex Klein1699fab2022-09-08 08:46:06 -0600696 for artifact in self.output_proto.artifacts
697 ]
698 expected = ["payload1.bin", "payload2.bin"]
699 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600700
Alex Klein1699fab2022-09-08 08:46:06 -0600701 actual = [
702 os.path.relpath(path, self.archive_root)
703 for path in osutils.DirectoryIterator(self.archive_root)
704 ]
705 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600706
Alex Klein1699fab2022-09-08 08:46:06 -0600707 def testBundleTestUpdatePayloadsNoImageDir(self):
708 """BundleTestUpdatePayloads dies if no image dir is found."""
709 # Intentionally do not write image directory.
710 artifacts.BundleTestUpdatePayloads(
711 self.input_proto, self.output_proto, self.api_config
712 )
713 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600714
Alex Klein1699fab2022-09-08 08:46:06 -0600715 def testBundleTestUpdatePayloadsNoImage(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700716 """BundleTestUpdatePayloads dies if no usable image found for target."""
Alex Klein1699fab2022-09-08 08:46:06 -0600717 # Intentionally do not write image, but create the directory.
718 osutils.SafeMakedirs(self.image_root)
719 with self.assertRaises(cros_build_lib.DieSystemExit):
720 artifacts.BundleTestUpdatePayloads(
721 self.input_proto, self.output_proto, self.api_config
722 )
Alex Klein6504eca2019-04-18 15:37:56 -0600723
724
Alex Klein1699fab2022-09-08 08:46:06 -0600725class BundleSimpleChromeArtifactsTest(
726 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
727):
728 """BundleSimpleChromeArtifacts tests."""
Alex Klein2275d692019-04-23 16:04:12 -0600729
Alex Klein1699fab2022-09-08 08:46:06 -0600730 def setUp(self):
Brian Norrisd3e391e2023-06-30 09:53:11 -0700731 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
732
733 self.chroot = chroot_lib.Chroot(
734 path=self.tempdir / "chroot",
735 out_path=self.tempdir / "out",
736 )
Alex Klein1699fab2022-09-08 08:46:06 -0600737 self.sysroot_path = "/sysroot"
Brian Norrisd3e391e2023-06-30 09:53:11 -0700738 self.sysroot_dir = self.chroot.full_path(self.sysroot_path)
Alex Klein1699fab2022-09-08 08:46:06 -0600739 osutils.SafeMakedirs(self.sysroot_dir)
740 self.output_dir = os.path.join(self.tempdir, "output_dir")
741 osutils.SafeMakedirs(self.output_dir)
Alex Klein2275d692019-04-23 16:04:12 -0600742
Alex Klein1699fab2022-09-08 08:46:06 -0600743 self.does_not_exist = os.path.join(self.tempdir, "does_not_exist")
Alex Klein2275d692019-04-23 16:04:12 -0600744
Alex Klein1699fab2022-09-08 08:46:06 -0600745 self.response = artifacts_pb2.BundleResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600746
Alex Klein1699fab2022-09-08 08:46:06 -0600747 def _GetRequest(
748 self,
Brian Norrisd3e391e2023-06-30 09:53:11 -0700749 chroot: Optional[chroot_lib.Chroot] = None,
Alex Klein1699fab2022-09-08 08:46:06 -0600750 sysroot: Optional[str] = None,
751 build_target: Optional[str] = None,
752 output_dir: Optional[str] = None,
753 ) -> artifacts_pb2.BundleRequest:
754 """Helper to create a request message instance.
Alex Klein2275d692019-04-23 16:04:12 -0600755
Alex Klein1699fab2022-09-08 08:46:06 -0600756 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600757 chroot: The chroot path.
758 sysroot: The sysroot path.
759 build_target: The build target name.
760 output_dir: The output directory.
Alex Klein1699fab2022-09-08 08:46:06 -0600761 """
762 return artifacts_pb2.BundleRequest(
763 sysroot={"path": sysroot, "build_target": {"name": build_target}},
Brian Norrisd3e391e2023-06-30 09:53:11 -0700764 chroot={
765 "path": chroot.path if chroot else None,
766 "out_path": str(chroot.out_path) if chroot else None,
767 },
Brian Norris2711f3a2023-07-18 11:09:00 -0700768 result_path=common_pb2.ResultPath(
769 path=common_pb2.Path(
770 path=output_dir,
771 location=common_pb2.Path.OUTSIDE,
772 )
773 ),
Alex Klein1699fab2022-09-08 08:46:06 -0600774 )
Alex Klein2275d692019-04-23 16:04:12 -0600775
Alex Klein1699fab2022-09-08 08:46:06 -0600776 def testValidateOnly(self):
777 """Quick check that a validate only call does not execute any logic."""
778 patch = self.PatchObject(artifacts_svc, "BundleSimpleChromeArtifacts")
779 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700780 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600781 sysroot=self.sysroot_path,
782 build_target="board",
783 output_dir=self.output_dir,
784 )
785 artifacts.BundleSimpleChromeArtifacts(
786 request, self.response, self.validate_only_config
787 )
788 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600789
Alex Klein1699fab2022-09-08 08:46:06 -0600790 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700791 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600792 patch = self.PatchObject(artifacts_svc, "BundleSimpleChromeArtifacts")
793 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700794 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600795 sysroot=self.sysroot_path,
796 build_target="board",
797 output_dir=self.output_dir,
798 )
799 artifacts.BundleSimpleChromeArtifacts(
800 request, self.response, self.mock_call_config
801 )
802 patch.assert_not_called()
803 self.assertEqual(len(self.response.artifacts), 1)
804 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700805 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -0600806 os.path.join(self.output_dir, "simple_chrome.txt"),
807 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700808
Alex Klein1699fab2022-09-08 08:46:06 -0600809 def testNoBuildTarget(self):
810 """Test no build target fails."""
811 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700812 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600813 sysroot=self.sysroot_path,
814 output_dir=self.output_dir,
815 )
816 response = self.response
817 with self.assertRaises(cros_build_lib.DieSystemExit):
818 artifacts.BundleSimpleChromeArtifacts(
819 request, response, self.api_config
820 )
Alex Klein2275d692019-04-23 16:04:12 -0600821
Alex Klein1699fab2022-09-08 08:46:06 -0600822 def testNoSysroot(self):
823 """Test no sysroot fails."""
824 request = self._GetRequest(
825 build_target="board", output_dir=self.output_dir
826 )
827 response = self.response
828 with self.assertRaises(cros_build_lib.DieSystemExit):
829 artifacts.BundleSimpleChromeArtifacts(
830 request, response, self.api_config
831 )
Alex Klein2275d692019-04-23 16:04:12 -0600832
Alex Klein1699fab2022-09-08 08:46:06 -0600833 def testSysrootDoesNotExist(self):
834 """Test no sysroot fails."""
835 request = self._GetRequest(
836 build_target="board",
837 output_dir=self.output_dir,
838 sysroot=self.does_not_exist,
839 )
840 response = self.response
Alex Kleinb6847e22022-11-07 10:44:48 -0700841 artifacts.BundleSimpleChromeArtifacts(
842 request, response, self.api_config
843 )
844 self.assertFalse(self.response.artifacts)
Alex Klein2275d692019-04-23 16:04:12 -0600845
Alex Klein1699fab2022-09-08 08:46:06 -0600846 def testNoOutputDir(self):
847 """Test no output dir fails."""
848 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700849 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600850 sysroot=self.sysroot_path,
851 build_target="board",
852 )
853 response = self.response
854 with self.assertRaises(cros_build_lib.DieSystemExit):
855 artifacts.BundleSimpleChromeArtifacts(
856 request, response, self.api_config
857 )
Alex Klein2275d692019-04-23 16:04:12 -0600858
Alex Klein1699fab2022-09-08 08:46:06 -0600859 def testOutputDirDoesNotExist(self):
860 """Test no output dir fails."""
861 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700862 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600863 sysroot=self.sysroot_path,
864 build_target="board",
865 output_dir=self.does_not_exist,
866 )
867 response = self.response
868 with self.assertRaises(cros_build_lib.DieSystemExit):
869 artifacts.BundleSimpleChromeArtifacts(
870 request, response, self.api_config
871 )
Alex Klein2275d692019-04-23 16:04:12 -0600872
Alex Klein1699fab2022-09-08 08:46:06 -0600873 def testOutputHandling(self):
874 """Test response output."""
875 files = ["file1", "file2", "file3"]
876 expected_files = [os.path.join(self.output_dir, f) for f in files]
877 self.PatchObject(
878 artifacts_svc,
879 "BundleSimpleChromeArtifacts",
880 return_value=expected_files,
881 )
882 request = self._GetRequest(
Brian Norrisd3e391e2023-06-30 09:53:11 -0700883 chroot=self.chroot,
Alex Klein1699fab2022-09-08 08:46:06 -0600884 sysroot=self.sysroot_path,
885 build_target="board",
886 output_dir=self.output_dir,
887 )
888 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600889
Alex Klein1699fab2022-09-08 08:46:06 -0600890 artifacts.BundleSimpleChromeArtifacts(
891 request, response, self.api_config
892 )
Alex Klein2275d692019-04-23 16:04:12 -0600893
Alex Klein1699fab2022-09-08 08:46:06 -0600894 self.assertTrue(response.artifacts)
895 self.assertCountEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -0700896 expected_files, [a.artifact_path.path for a in response.artifacts]
Alex Klein1699fab2022-09-08 08:46:06 -0600897 )
Alex Klein2275d692019-04-23 16:04:12 -0600898
899
Alex Klein1699fab2022-09-08 08:46:06 -0600900class BundleVmFilesTest(
901 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
902):
903 """BuildVmFiles tests."""
Alex Klein6504eca2019-04-18 15:37:56 -0600904
Alex Klein1699fab2022-09-08 08:46:06 -0600905 def setUp(self):
906 self.output_dir = os.path.join(self.tempdir, "output")
907 osutils.SafeMakedirs(self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600908
Alex Klein1699fab2022-09-08 08:46:06 -0600909 self.response = artifacts_pb2.BundleResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600910
Alex Klein1699fab2022-09-08 08:46:06 -0600911 def _GetInput(
912 self,
913 chroot: Optional[str] = None,
914 sysroot: Optional[str] = None,
915 test_results_dir: Optional[str] = None,
916 output_dir: Optional[str] = None,
917 ) -> artifacts_pb2.BundleVmFilesRequest:
918 """Helper to build out an input message instance.
Alex Klein6504eca2019-04-18 15:37:56 -0600919
Alex Klein1699fab2022-09-08 08:46:06 -0600920 Args:
Alex Klein611dddd2022-10-11 17:02:01 -0600921 chroot: The chroot path.
922 sysroot: The sysroot path relative to the chroot.
Alex Kleinab87ceb2023-01-24 12:00:51 -0700923 test_results_dir: The test results directory relative to the
924 sysroot.
Alex Klein611dddd2022-10-11 17:02:01 -0600925 output_dir: The directory where the results tarball should be saved.
Alex Klein1699fab2022-09-08 08:46:06 -0600926 """
927 return artifacts_pb2.BundleVmFilesRequest(
928 chroot={"path": chroot},
929 sysroot={"path": sysroot},
930 test_results_dir=test_results_dir,
931 output_dir=output_dir,
932 )
Alex Klein6504eca2019-04-18 15:37:56 -0600933
Alex Klein1699fab2022-09-08 08:46:06 -0600934 def testValidateOnly(self):
935 """Quick check that a validate only call does not execute any logic."""
936 patch = self.PatchObject(artifacts_svc, "BundleVmFiles")
937 in_proto = self._GetInput(
938 chroot="/chroot/dir",
939 sysroot="/build/board",
940 test_results_dir="/test/results",
941 output_dir=self.output_dir,
942 )
943 artifacts.BundleVmFiles(
944 in_proto, self.response, self.validate_only_config
945 )
946 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600947
Alex Klein1699fab2022-09-08 08:46:06 -0600948 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700949 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -0600950 patch = self.PatchObject(artifacts_svc, "BundleVmFiles")
951 in_proto = self._GetInput(
952 chroot="/chroot/dir",
953 sysroot="/build/board",
954 test_results_dir="/test/results",
955 output_dir=self.output_dir,
956 )
957 artifacts.BundleVmFiles(in_proto, self.response, self.mock_call_config)
958 patch.assert_not_called()
959 self.assertEqual(len(self.response.artifacts), 1)
960 self.assertEqual(
961 self.response.artifacts[0].path,
962 os.path.join(self.output_dir, "f1.tar"),
963 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700964
Alex Klein1699fab2022-09-08 08:46:06 -0600965 def testChrootMissing(self):
966 """Test error handling for missing chroot."""
967 in_proto = self._GetInput(
968 sysroot="/build/board",
969 test_results_dir="/test/results",
970 output_dir=self.output_dir,
971 )
Alex Klein6504eca2019-04-18 15:37:56 -0600972
Alex Klein1699fab2022-09-08 08:46:06 -0600973 with self.assertRaises(cros_build_lib.DieSystemExit):
974 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600975
Alex Klein1699fab2022-09-08 08:46:06 -0600976 def testTestResultsDirMissing(self):
977 """Test error handling for missing test results directory."""
978 in_proto = self._GetInput(
979 chroot="/chroot/dir",
980 sysroot="/build/board",
981 output_dir=self.output_dir,
982 )
Alex Klein6504eca2019-04-18 15:37:56 -0600983
Alex Klein1699fab2022-09-08 08:46:06 -0600984 with self.assertRaises(cros_build_lib.DieSystemExit):
985 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 def testOutputDirMissing(self):
988 """Test error handling for missing output directory."""
989 in_proto = self._GetInput(
990 chroot="/chroot/dir",
991 sysroot="/build/board",
992 test_results_dir="/test/results",
993 )
Alex Klein6504eca2019-04-18 15:37:56 -0600994
Alex Klein1699fab2022-09-08 08:46:06 -0600995 with self.assertRaises(cros_build_lib.DieSystemExit):
996 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600997
Alex Klein1699fab2022-09-08 08:46:06 -0600998 def testOutputDirDoesNotExist(self):
999 """Test error handling for output directory that does not exist."""
1000 in_proto = self._GetInput(
1001 chroot="/chroot/dir",
1002 sysroot="/build/board",
1003 output_dir=os.path.join(self.tempdir, "dne"),
1004 test_results_dir="/test/results",
1005 )
Alex Klein231d2da2019-07-22 16:44:45 -06001006
Alex Klein1699fab2022-09-08 08:46:06 -06001007 with self.assertRaises(cros_build_lib.DieSystemExit):
1008 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -06001009
Alex Klein1699fab2022-09-08 08:46:06 -06001010 def testValidCall(self):
1011 """Test image dir building."""
1012 in_proto = self._GetInput(
1013 chroot="/chroot/dir",
1014 sysroot="/build/board",
1015 test_results_dir="/test/results",
1016 output_dir=self.output_dir,
1017 )
Alex Klein231d2da2019-07-22 16:44:45 -06001018
Alex Klein1699fab2022-09-08 08:46:06 -06001019 expected_files = ["/tmp/output/f1.tar", "/tmp/output/f2.tar"]
1020 patch = self.PatchObject(
1021 artifacts_svc, "BundleVmFiles", return_value=expected_files
1022 )
Alex Klein6504eca2019-04-18 15:37:56 -06001023
Alex Klein1699fab2022-09-08 08:46:06 -06001024 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -06001025
Alex Klein1699fab2022-09-08 08:46:06 -06001026 patch.assert_called_with(mock.ANY, "/test/results", self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -06001027
Alex Kleinab87ceb2023-01-24 12:00:51 -07001028 # Make sure we have artifacts, and that every artifact is an expected
1029 # file.
Alex Klein1699fab2022-09-08 08:46:06 -06001030 self.assertTrue(self.response.artifacts)
1031 for artifact in self.response.artifacts:
1032 self.assertIn(artifact.path, expected_files)
1033 expected_files.remove(artifact.path)
Alex Klein6504eca2019-04-18 15:37:56 -06001034
Alex Klein1699fab2022-09-08 08:46:06 -06001035 # Make sure we've seen all of the expected files.
1036 self.assertFalse(expected_files)
Alex Kleinb9d810b2019-07-01 12:38:02 -06001037
Tiancong Wang50b80a92019-08-01 14:46:15 -07001038
Alex Klein036833d2022-06-01 13:05:01 -06001039class ExportCpeReportTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -06001040 """ExportCpeReport tests."""
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001041
Alex Klein1699fab2022-09-08 08:46:06 -06001042 def testValidateOnly(self):
1043 """Quick check validate only calls don't execute."""
1044 patch = self.PatchObject(artifacts_svc, "GenerateCpeReport")
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001045
Alex Klein1699fab2022-09-08 08:46:06 -06001046 artifacts.ExportCpeReport(
1047 self.sysroot_request, self.response, self.validate_only_config
1048 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001049
Alex Klein1699fab2022-09-08 08:46:06 -06001050 patch.assert_not_called()
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001051
Alex Klein1699fab2022-09-08 08:46:06 -06001052 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -07001053 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -06001054 patch = self.PatchObject(artifacts_svc, "GenerateCpeReport")
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001055
Alex Klein1699fab2022-09-08 08:46:06 -06001056 artifacts.ExportCpeReport(
1057 self.sysroot_request, self.response, self.mock_call_config
1058 )
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001059
Alex Klein1699fab2022-09-08 08:46:06 -06001060 patch.assert_not_called()
1061 self.assertEqual(len(self.response.artifacts), 2)
1062 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -07001063 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -06001064 os.path.join(self.output_dir, "cpe_report.txt"),
1065 )
1066 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -07001067 self.response.artifacts[1].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -06001068 os.path.join(self.output_dir, "cpe_warnings.txt"),
1069 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001070
Alex Klein1699fab2022-09-08 08:46:06 -06001071 def testSuccess(self):
1072 """Test success case."""
1073 expected = artifacts_svc.CpeResult(
1074 report="/output/report.json", warnings="/output/warnings.json"
1075 )
1076 self.PatchObject(
1077 artifacts_svc, "GenerateCpeReport", return_value=expected
1078 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001079
Alex Klein1699fab2022-09-08 08:46:06 -06001080 artifacts.ExportCpeReport(
1081 self.sysroot_request, self.response, self.api_config
1082 )
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001083
Alex Klein1699fab2022-09-08 08:46:06 -06001084 for artifact in self.response.artifacts:
Brian Norris2711f3a2023-07-18 11:09:00 -07001085 self.assertIn(
1086 artifact.artifact_path.path,
1087 [expected.report, expected.warnings],
1088 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001089
1090
1091class BundleGceTarballTest(BundleTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -06001092 """Unittests for BundleGceTarball."""
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001093
Alex Klein1699fab2022-09-08 08:46:06 -06001094 def testValidateOnly(self):
1095 """Check that a validate only call does not execute any logic."""
1096 patch = self.PatchObject(artifacts_svc, "BundleGceTarball")
1097 artifacts.BundleGceTarball(
1098 self.target_request, self.response, self.validate_only_config
1099 )
1100 patch.assert_not_called()
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001101
Alex Klein1699fab2022-09-08 08:46:06 -06001102 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -07001103 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -06001104 patch = self.PatchObject(artifacts_svc, "BundleGceTarball")
1105 artifacts.BundleGceTarball(
1106 self.target_request, self.response, self.mock_call_config
1107 )
1108 patch.assert_not_called()
1109 self.assertEqual(len(self.response.artifacts), 1)
1110 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -07001111 self.response.artifacts[0].artifact_path.path,
Alex Klein1699fab2022-09-08 08:46:06 -06001112 os.path.join(self.output_dir, constants.TEST_IMAGE_GCE_TAR),
1113 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001114
Alex Klein1699fab2022-09-08 08:46:06 -06001115 def testBundleGceTarball(self):
1116 """BundleGceTarball calls cbuildbot/commands with correct args."""
1117 bundle_gce_tarball = self.PatchObject(
1118 artifacts_svc,
1119 "BundleGceTarball",
1120 return_value=os.path.join(
1121 self.output_dir, constants.TEST_IMAGE_GCE_TAR
1122 ),
1123 )
1124 self.PatchObject(os.path, "exists", return_value=True)
1125 artifacts.BundleGceTarball(
1126 self.target_request, self.response, self.api_config
1127 )
1128 self.assertEqual(
Brian Norris2711f3a2023-07-18 11:09:00 -07001129 [
1130 artifact.artifact_path.path
1131 for artifact in self.response.artifacts
1132 ],
Alex Klein1699fab2022-09-08 08:46:06 -06001133 [os.path.join(self.output_dir, constants.TEST_IMAGE_GCE_TAR)],
1134 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001135
Alex Klein1699fab2022-09-08 08:46:06 -06001136 latest = os.path.join(
1137 self.source_root, "src/build/images/target/latest"
1138 )
1139 self.assertEqual(
1140 bundle_gce_tarball.call_args_list,
1141 [mock.call(self.output_dir, latest)],
1142 )
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001143
Alex Klein1699fab2022-09-08 08:46:06 -06001144 def testBundleGceTarballNoImageDir(self):
1145 """BundleGceTarball dies when image dir does not exist."""
1146 self.PatchObject(os.path, "exists", return_value=False)
1147 with self.assertRaises(cros_build_lib.DieSystemExit):
1148 artifacts.BundleGceTarball(
1149 self.target_request, self.response, self.api_config
1150 )
Greg Edelstondc941072021-08-11 12:32:30 -06001151
Greg Edelstondc941072021-08-11 12:32:30 -06001152
Alex Klein1699fab2022-09-08 08:46:06 -06001153class FetchMetadataTestCase(
1154 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
1155):
1156 """Unittests for FetchMetadata."""
Greg Edelstondc941072021-08-11 12:32:30 -06001157
Alex Klein1699fab2022-09-08 08:46:06 -06001158 sysroot_path = "/build/coral"
1159 chroot_name = "chroot"
Greg Edelstondc941072021-08-11 12:32:30 -06001160
Alex Klein1699fab2022-09-08 08:46:06 -06001161 def setUp(self):
1162 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001163 self.chroot = chroot_lib.Chroot(
1164 path=self.tempdir / "chroot",
1165 out_path=self.tempdir / "out",
1166 )
1167 pathlib.Path(self.chroot.path).touch()
1168 self.chroot.out_path.touch()
Alex Klein1699fab2022-09-08 08:46:06 -06001169 self.expected_filepaths = [
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001170 self.chroot.full_path(fp)
Alex Klein1699fab2022-09-08 08:46:06 -06001171 for fp in (
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001172 "/build/coral/usr/local/build/autotest/autotest_metadata.pb",
1173 "/build/coral/usr/share/tast/metadata/local/cros.pb",
1174 "/build/coral/build/share/tast/metadata/local/crosint.pb",
1175 "/usr/share/tast/metadata/remote/cros.pb",
Alex Klein1699fab2022-09-08 08:46:06 -06001176 )
1177 ]
1178 self.PatchObject(cros_build_lib, "AssertOutsideChroot")
Greg Edelstondc941072021-08-11 12:32:30 -06001179
Alex Klein1699fab2022-09-08 08:46:06 -06001180 def createFetchMetadataRequest(
1181 self, use_sysroot_path=True, use_chroot=True
1182 ):
1183 """Construct a FetchMetadataRequest for use in test cases."""
1184 request = artifacts_pb2.FetchMetadataRequest()
1185 if use_sysroot_path:
1186 request.sysroot.path = self.sysroot_path
1187 if use_chroot:
Brian Norrisa9cc6b32023-05-10 13:43:45 -07001188 request.chroot.path = self.chroot.path
1189 request.chroot.out_path = str(self.chroot.out_path)
Alex Klein1699fab2022-09-08 08:46:06 -06001190 return request
Greg Edelstondc941072021-08-11 12:32:30 -06001191
Alex Klein1699fab2022-09-08 08:46:06 -06001192 def testValidateOnly(self):
1193 """Check that a validate only call does not execute any logic."""
1194 patch = self.PatchObject(controller_util, "ParseSysroot")
1195 request = self.createFetchMetadataRequest()
1196 response = artifacts_pb2.FetchMetadataResponse()
1197 artifacts.FetchMetadata(request, response, self.validate_only_config)
1198 patch.assert_not_called()
Greg Edelstondc941072021-08-11 12:32:30 -06001199
Alex Klein1699fab2022-09-08 08:46:06 -06001200 def testMockCall(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -07001201 """Test a mock call does not execute logic, returns mocked value."""
Alex Klein1699fab2022-09-08 08:46:06 -06001202 patch = self.PatchObject(controller_util, "ParseSysroot")
1203 request = self.createFetchMetadataRequest()
1204 response = artifacts_pb2.FetchMetadataResponse()
1205 artifacts.FetchMetadata(request, response, self.mock_call_config)
1206 patch.assert_not_called()
1207 self.assertGreater(len(response.filepaths), 0)
Greg Edelstondc941072021-08-11 12:32:30 -06001208
Alex Klein1699fab2022-09-08 08:46:06 -06001209 def testNoSysrootPath(self):
1210 """Check that a request with no sysroot.path results in failure."""
1211 request = self.createFetchMetadataRequest(use_sysroot_path=False)
1212 response = artifacts_pb2.FetchMetadataResponse()
1213 with self.assertRaises(cros_build_lib.DieSystemExit):
1214 artifacts.FetchMetadata(request, response, self.api_config)
Greg Edelstondc941072021-08-11 12:32:30 -06001215
Alex Klein1699fab2022-09-08 08:46:06 -06001216 def testNoChroot(self):
1217 """Check that a request with no chroot results in failure."""
1218 request = self.createFetchMetadataRequest(use_chroot=False)
1219 response = artifacts_pb2.FetchMetadataResponse()
1220 with self.assertRaises(cros_build_lib.DieSystemExit):
1221 artifacts.FetchMetadata(request, response, self.api_config)
1222
1223 def testSuccess(self):
1224 """Check that a well-formed request yields the expected results."""
1225 request = self.createFetchMetadataRequest(use_chroot=True)
1226 response = artifacts_pb2.FetchMetadataResponse()
1227 artifacts.FetchMetadata(request, response, self.api_config)
1228 actual_filepaths = [fp.path.path for fp in response.filepaths]
1229 self.assertEqual(
1230 sorted(actual_filepaths), sorted(self.expected_filepaths)
1231 )
1232 self.assertTrue(
1233 all(
1234 fp.path.location == common_pb2.Path.OUTSIDE
1235 for fp in response.filepaths
1236 )
1237 )
Jack Neus26b94672022-10-27 17:33:21 +00001238
1239
1240class GetTest(cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
1241 """Get function tests."""
1242
1243 def setUp(self):
1244 self.sysroot_path = "/build/target"
1245 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
1246
1247 def _InputProto(self):
1248 """Helper to build an input proto instance."""
Alex Kleinab87ceb2023-01-24 12:00:51 -07001249 # pylint: disable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001250 return artifacts_pb2.GetRequest(
1251 sysroot=sysroot_pb2.Sysroot(path=self.sysroot_path),
1252 artifact_info=common_pb2.ArtifactsByService(
1253 sysroot=common_pb2.ArtifactsByService.Sysroot(
1254 output_artifacts=[
1255 common_pb2.ArtifactsByService.Sysroot.ArtifactInfo(
1256 artifact_types=[
1257 common_pb2.ArtifactsByService.Sysroot.ArtifactType.FUZZER_SYSROOT
1258 ]
1259 )
1260 ],
1261 ),
1262 image=common_pb2.ArtifactsByService.Image(
1263 output_artifacts=[
1264 common_pb2.ArtifactsByService.Image.ArtifactInfo(
1265 artifact_types=[
1266 common_pb2.ArtifactsByService.Image.ArtifactType.LICENSE_CREDITS
1267 ]
1268 )
1269 ],
1270 ),
1271 test=common_pb2.ArtifactsByService.Test(
1272 output_artifacts=[
1273 common_pb2.ArtifactsByService.Test.ArtifactInfo(
1274 artifact_types=[
1275 common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL
1276 ]
1277 )
1278 ],
1279 ),
1280 ),
1281 result_path=common_pb2.ResultPath(
1282 path=common_pb2.Path(path=str(self.tempdir))
1283 ),
1284 )
Alex Kleinab87ceb2023-01-24 12:00:51 -07001285 # pylint: enable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001286
1287 def _OutputProto(self):
1288 """Helper to build an output proto instance."""
1289 return artifacts_pb2.GetResponse()
1290
1291 def testSuccess(self):
1292 """Test Get."""
Alex Kleinab87ceb2023-01-24 12:00:51 -07001293 # pylint: disable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001294 image_mock = self.PatchObject(
1295 image_controller,
1296 "GetArtifacts",
1297 return_value=[
1298 {
1299 "paths": ["/foo/bar/license_credits.html"],
1300 "type": common_pb2.ArtifactsByService.Image.ArtifactType.LICENSE_CREDITS,
1301 }
1302 ],
1303 )
1304 sysroot_mock = self.PatchObject(
1305 sysroot_controller,
1306 "GetArtifacts",
1307 return_value=[
1308 {
1309 "type": common_pb2.ArtifactsByService.Sysroot.ArtifactType.FUZZER_SYSROOT,
1310 "failed": True,
1311 "failure_reason": "Bad data!",
1312 }
1313 ],
1314 )
1315 test_mock = self.PatchObject(
1316 test_controller,
1317 "GetArtifacts",
1318 return_value=[
1319 {
1320 "paths": ["/foo/bar/hwqual.tar.xz"],
1321 "type": common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL,
1322 }
1323 ],
1324 )
Alex Kleinab87ceb2023-01-24 12:00:51 -07001325 # pylint: enable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001326
1327 in_proto = self._InputProto()
1328 out_proto = self._OutputProto()
1329 artifacts.Get(
1330 in_proto,
1331 out_proto,
1332 self.api_config,
1333 )
1334
1335 image_mock.assert_called_once()
1336 sysroot_mock.assert_called_once()
1337 test_mock.assert_called_once()
1338
Alex Kleinab87ceb2023-01-24 12:00:51 -07001339 # pylint: disable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001340 expected = common_pb2.UploadedArtifactsByService(
1341 sysroot=common_pb2.UploadedArtifactsByService.Sysroot(
1342 artifacts=[
1343 common_pb2.UploadedArtifactsByService.Sysroot.ArtifactPaths(
1344 artifact_type=common_pb2.ArtifactsByService.Sysroot.ArtifactType.FUZZER_SYSROOT,
1345 failed=True,
1346 failure_reason="Bad data!",
1347 )
1348 ]
1349 ),
1350 image=common_pb2.UploadedArtifactsByService.Image(
1351 artifacts=[
1352 common_pb2.UploadedArtifactsByService.Image.ArtifactPaths(
1353 artifact_type=common_pb2.ArtifactsByService.Image.ArtifactType.LICENSE_CREDITS,
1354 paths=[
1355 common_pb2.Path(
1356 path="/foo/bar/license_credits.html",
1357 location=common_pb2.Path.OUTSIDE,
1358 )
1359 ],
1360 )
1361 ]
1362 ),
1363 test=common_pb2.UploadedArtifactsByService.Test(
1364 artifacts=[
1365 common_pb2.UploadedArtifactsByService.Test.ArtifactPaths(
1366 artifact_type=common_pb2.ArtifactsByService.Test.ArtifactType.HWQUAL,
1367 paths=[
1368 common_pb2.Path(
1369 path="/foo/bar/hwqual.tar.xz",
1370 location=common_pb2.Path.OUTSIDE,
1371 )
1372 ],
1373 )
1374 ]
1375 ),
1376 )
Alex Kleinab87ceb2023-01-24 12:00:51 -07001377 # pylint: enable=line-too-long
Jack Neus26b94672022-10-27 17:33:21 +00001378 self.assertEqual(out_proto.artifacts, expected)