blob: f7b73d1d9e7bfc902ae6cb04ad742ba40a576ed1 [file] [log] [blame]
Evan Hernandezf388cbf2019-04-01 11:15:23 -06001# Copyright 2019 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Unittests for Artifacts operations."""
6
Evan Hernandezf388cbf2019-04-01 11:15:23 -06007import os
Greg Edelstondc941072021-08-11 12:32:30 -06008import pathlib
Mike Frysinger166fea02021-02-12 05:30:33 -05009from unittest import mock
Evan Hernandezf388cbf2019-04-01 11:15:23 -060010
Alex Klein231d2da2019-07-22 16:44:45 -060011from chromite.api import api_config
Evan Hernandezf388cbf2019-04-01 11:15:23 -060012from chromite.api.controller import artifacts
Greg Edelstondc941072021-08-11 12:32:30 -060013from chromite.api.controller import controller_util
Evan Hernandezf388cbf2019-04-01 11:15:23 -060014from chromite.api.gen.chromite.api import artifacts_pb2
Tiancong Wang24a3df72019-08-20 15:48:51 -070015from chromite.api.gen.chromite.api import toolchain_pb2
Greg Edelstondc941072021-08-11 12:32:30 -060016from chromite.api.gen.chromiumos import common_pb2
Evan Hernandezf388cbf2019-04-01 11:15:23 -060017from chromite.cbuildbot import commands
Alex Kleinb9d810b2019-07-01 12:38:02 -060018from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060019from chromite.lib import constants
20from chromite.lib import cros_build_lib
21from chromite.lib import cros_test_lib
22from chromite.lib import osutils
Alex Klein238d8862019-05-07 11:32:46 -060023from chromite.lib import sysroot_lib
Alex Klein2275d692019-04-23 16:04:12 -060024from chromite.service import artifacts as artifacts_svc
Evan Hernandezf388cbf2019-04-01 11:15:23 -060025
26
Alex Kleind91e95a2019-09-17 10:39:02 -060027class BundleRequestMixin(object):
28 """Mixin to provide bundle request methods."""
29
30 def EmptyRequest(self):
31 return artifacts_pb2.BundleRequest()
32
33 def BuildTargetRequest(self, build_target=None, output_dir=None, chroot=None):
34 """Get a build target format request instance."""
35 request = self.EmptyRequest()
36 if build_target:
37 request.build_target.name = build_target
38 if output_dir:
39 request.output_dir = output_dir
40 if chroot:
41 request.chroot.path = chroot
42
43 return request
44
45 def SysrootRequest(self,
46 sysroot=None,
47 build_target=None,
48 output_dir=None,
49 chroot=None):
50 """Get a sysroot format request instance."""
51 request = self.EmptyRequest()
52 if sysroot:
53 request.sysroot.path = sysroot
54 if build_target:
55 request.sysroot.build_target.name = build_target
56 if output_dir:
57 request.output_dir = output_dir
58 if chroot:
59 request.chroot.path = chroot
60
61 return request
62
63
Alex Klein231d2da2019-07-22 16:44:45 -060064class BundleTestCase(cros_test_lib.MockTempDirTestCase,
Alex Kleind91e95a2019-09-17 10:39:02 -060065 api_config.ApiConfigMixin, BundleRequestMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060066 """Basic setup for all artifacts unittests."""
67
68 def setUp(self):
Alex Klein231d2da2019-07-22 16:44:45 -060069 self.output_dir = os.path.join(self.tempdir, 'artifacts')
70 osutils.SafeMakedirs(self.output_dir)
71 self.sysroot_path = '/build/target'
Alex Klein68c8fdf2019-09-25 15:09:11 -060072 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -060073 self.chroot_path = os.path.join(self.tempdir, 'chroot')
74 full_sysroot_path = os.path.join(self.chroot_path,
75 self.sysroot_path.lstrip(os.sep))
76 osutils.SafeMakedirs(full_sysroot_path)
77
Alex Klein68c8fdf2019-09-25 15:09:11 -060078 # All requests use same response type.
Alex Klein231d2da2019-07-22 16:44:45 -060079 self.response = artifacts_pb2.BundleResponse()
80
Alex Klein68c8fdf2019-09-25 15:09:11 -060081 # Build target request.
82 self.target_request = self.BuildTargetRequest(
83 build_target='target',
84 output_dir=self.output_dir,
85 chroot=self.chroot_path)
86
87 # Sysroot request.
88 self.sysroot_request = self.SysrootRequest(
89 sysroot=self.sysroot_path,
90 build_target='target',
91 output_dir=self.output_dir,
92 chroot=self.chroot_path)
93
Alex Klein231d2da2019-07-22 16:44:45 -060094 self.source_root = self.tempdir
95 self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -060096
97
Alex Kleind91e95a2019-09-17 10:39:02 -060098class BundleImageArchivesTest(BundleTestCase):
99 """BundleImageArchives tests."""
100
101 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600102 """Quick check that a validate only call does not execute any logic."""
Alex Kleind91e95a2019-09-17 10:39:02 -0600103 patch = self.PatchObject(artifacts_svc, 'ArchiveImages')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600104 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600105 self.validate_only_config)
106 patch.assert_not_called()
107
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700108 def testMockCall(self):
109 """Test that a mock call does not execute logic, returns mocked value."""
110 patch = self.PatchObject(artifacts_svc, 'ArchiveImages')
111 artifacts.BundleImageArchives(self.target_request, self.response,
112 self.mock_call_config)
113 patch.assert_not_called()
114 self.assertEqual(len(self.response.artifacts), 2)
115 self.assertEqual(self.response.artifacts[0].path,
116 os.path.join(self.output_dir, 'path0.tar.xz'))
117 self.assertEqual(self.response.artifacts[1].path,
118 os.path.join(self.output_dir, 'path1.tar.xz'))
119
Alex Kleind91e95a2019-09-17 10:39:02 -0600120 def testNoBuildTarget(self):
121 """Test that no build target fails."""
122 request = self.BuildTargetRequest(output_dir=self.tempdir)
123 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600124 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600125
126 def testNoOutputDir(self):
127 """Test no output dir fails."""
128 request = self.BuildTargetRequest(build_target='board')
129 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600130 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600131
132 def testInvalidOutputDir(self):
133 """Test invalid output dir fails."""
134 request = self.BuildTargetRequest(
135 build_target='board', output_dir=os.path.join(self.tempdir, 'DNE'))
136 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600137 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600138
139 def testOutputHandling(self):
140 """Test the artifact output handling."""
141 expected = [os.path.join(self.output_dir, f) for f in ('a', 'b', 'c')]
142 self.PatchObject(artifacts_svc, 'ArchiveImages', return_value=expected)
143 self.PatchObject(os.path, 'exists', return_value=True)
144
Alex Klein68c8fdf2019-09-25 15:09:11 -0600145 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600146 self.api_config)
147
Mike Frysinger678735c2019-09-28 18:23:28 -0400148 self.assertCountEqual(expected, [a.path for a in self.response.artifacts])
Alex Kleind91e95a2019-09-17 10:39:02 -0600149
150
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600151class BundleImageZipTest(BundleTestCase):
152 """Unittests for BundleImageZip."""
153
Alex Klein231d2da2019-07-22 16:44:45 -0600154 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600155 """Quick check that a validate only call does not execute any logic."""
Alex Klein231d2da2019-07-22 16:44:45 -0600156 patch = self.PatchObject(commands, 'BuildImageZip')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600157 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600158 self.validate_only_config)
159 patch.assert_not_called()
160
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700161 def testMockCall(self):
162 """Test that a mock call does not execute logic, returns mocked value."""
163 patch = self.PatchObject(commands, 'BuildImageZip')
164 artifacts.BundleImageZip(self.target_request, self.response,
165 self.mock_call_config)
166 patch.assert_not_called()
167 self.assertEqual(len(self.response.artifacts), 1)
168 self.assertEqual(self.response.artifacts[0].path,
169 os.path.join(self.output_dir, 'image.zip'))
170
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600171 def testBundleImageZip(self):
172 """BundleImageZip calls cbuildbot/commands with correct args."""
Michael Mortensen01910922019-07-24 14:48:10 -0600173 bundle_image_zip = self.PatchObject(
174 artifacts_svc, 'BundleImageZip', return_value='image.zip')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600175 self.PatchObject(os.path, 'exists', return_value=True)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600176 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600177 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600178 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600179 [artifact.path for artifact in self.response.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600180 [os.path.join(self.output_dir, 'image.zip')])
181
182 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600183 self.assertEqual(
Michael Mortensen01910922019-07-24 14:48:10 -0600184 bundle_image_zip.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600185 [mock.call(self.output_dir, latest)])
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600186
187 def testBundleImageZipNoImageDir(self):
188 """BundleImageZip dies when image dir does not exist."""
189 self.PatchObject(os.path, 'exists', return_value=False)
190 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600191 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600192 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600193
194
Alex Klein68c8fdf2019-09-25 15:09:11 -0600195class BundleAutotestFilesTest(BundleTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600196 """Unittests for BundleAutotestFiles."""
197
Alex Klein231d2da2019-07-22 16:44:45 -0600198 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600199 """Quick check that a validate only call does not execute any logic."""
Alex Klein231d2da2019-07-22 16:44:45 -0600200 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600201 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600202 self.validate_only_config)
203 patch.assert_not_called()
204
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700205 def testMockCall(self):
206 """Test that a mock call does not execute logic, returns mocked value."""
207 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
208 artifacts.BundleAutotestFiles(self.target_request, self.response,
209 self.mock_call_config)
210 patch.assert_not_called()
211 self.assertEqual(len(self.response.artifacts), 1)
212 self.assertEqual(self.response.artifacts[0].path,
213 os.path.join(self.output_dir, 'autotest-a.tar.gz'))
214
Alex Klein238d8862019-05-07 11:32:46 -0600215 def testBundleAutotestFilesLegacy(self):
216 """BundleAutotestFiles calls service correctly with legacy args."""
217 files = {
218 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
219 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
220 }
221 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
222 return_value=files)
223
Alex Klein68c8fdf2019-09-25 15:09:11 -0600224 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600225 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600226
Alex Klein238d8862019-05-07 11:32:46 -0600227 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600228 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600229
230 # Verify the output proto is being populated correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600231 self.assertTrue(self.response.artifacts)
232 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400233 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600234
235 def testBundleAutotestFiles(self):
236 """BundleAutotestFiles calls service correctly."""
237 files = {
238 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
239 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
240 }
241 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
242 return_value=files)
243
Alex Klein68c8fdf2019-09-25 15:09:11 -0600244 artifacts.BundleAutotestFiles(self.sysroot_request, self.response,
245 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600246
247 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600248 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600249
250 # Verify the output proto is being populated correctly.
251 self.assertTrue(self.response.artifacts)
252 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400253 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600254
255 def testInvalidOutputDir(self):
256 """Test invalid output directory argument."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600257 request = self.SysrootRequest(chroot=self.chroot_path,
258 sysroot=self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600259
260 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600261 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600262
263 def testInvalidSysroot(self):
264 """Test no sysroot directory."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600265 request = self.SysrootRequest(chroot=self.chroot_path,
266 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600267
268 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600269 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600270
271 def testSysrootDoesNotExist(self):
272 """Test dies when no sysroot does not exist."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600273 request = self.SysrootRequest(chroot=self.chroot_path,
274 sysroot='/does/not/exist',
275 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600276
277 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600278 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600279
280
281class BundleTastFilesTest(BundleTestCase):
282 """Unittests for BundleTastFiles."""
283
Alex Klein231d2da2019-07-22 16:44:45 -0600284 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600285 """Quick check that a validate only call does not execute any logic."""
Alex Klein231d2da2019-07-22 16:44:45 -0600286 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600287 artifacts.BundleTastFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600288 self.validate_only_config)
289 patch.assert_not_called()
290
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700291 def testMockCall(self):
292 """Test that a mock call does not execute logic, returns mocked value."""
293 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
294 artifacts.BundleTastFiles(self.target_request, self.response,
295 self.mock_call_config)
296 patch.assert_not_called()
297 self.assertEqual(len(self.response.artifacts), 1)
298 self.assertEqual(self.response.artifacts[0].path,
299 os.path.join(self.output_dir, 'tast_bundles.tar.gz'))
300
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600301 def testBundleTastFilesNoLogs(self):
LaMont Jonesb9793cd2020-06-11 08:14:46 -0600302 """BundleTasteFiles succeeds when no tast files found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600303 self.PatchObject(commands, 'BuildTastBundleTarball',
304 return_value=None)
LaMont Jonesb9793cd2020-06-11 08:14:46 -0600305 artifacts.BundleTastFiles(self.target_request, self.response,
306 self.api_config)
307 self.assertEqual(list(self.response.artifacts), [])
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600308
Alex Kleinb9d810b2019-07-01 12:38:02 -0600309 def testBundleTastFilesLegacy(self):
310 """BundleTastFiles handles legacy args correctly."""
311 buildroot = self.tempdir
312 chroot_dir = os.path.join(buildroot, 'chroot')
313 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
314 output_dir = os.path.join(self.tempdir, 'results')
315 osutils.SafeMakedirs(sysroot_path)
316 osutils.SafeMakedirs(output_dir)
317
Alex Klein171da612019-08-06 14:00:42 -0600318 chroot = chroot_lib.Chroot(chroot_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600319 sysroot = sysroot_lib.Sysroot('/build/board')
320
321 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
322 # Patch the service being called.
323 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
324 return_value=expected_archive)
325 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
326
327 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
328 output_dir=output_dir)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600329 artifacts.BundleTastFiles(request, self.response, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600330 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600331 [artifact.path for artifact in self.response.artifacts],
Alex Kleinb9d810b2019-07-01 12:38:02 -0600332 [expected_archive])
333 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
334
335 def testBundleTastFiles(self):
336 """BundleTastFiles calls service correctly."""
Alex Kleinb49be8a2019-12-20 10:23:03 -0700337 chroot = chroot_lib.Chroot(self.chroot_path)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600338
Alex Klein68c8fdf2019-09-25 15:09:11 -0600339 expected_archive = os.path.join(self.output_dir,
340 artifacts_svc.TAST_BUNDLE_NAME)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600341 # Patch the service being called.
342 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
343 return_value=expected_archive)
344
Alex Klein68c8fdf2019-09-25 15:09:11 -0600345 artifacts.BundleTastFiles(self.sysroot_request, self.response,
346 self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600347
348 # Make sure the artifact got recorded successfully.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600349 self.assertTrue(self.response.artifacts)
350 self.assertEqual(expected_archive, self.response.artifacts[0].path)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600351 # Make sure the service got called correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600352 bundle_patch.assert_called_once_with(chroot, self.sysroot, self.output_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600353
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600354
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600355class BundleFirmwareTest(BundleTestCase):
356 """Unittests for BundleFirmware."""
357
Alex Klein231d2da2019-07-22 16:44:45 -0600358 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600359 """Quick check that a validate only call does not execute any logic."""
Alex Klein231d2da2019-07-22 16:44:45 -0600360 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600361 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600362 self.validate_only_config)
363 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000364
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700365 def testMockCall(self):
366 """Test that a mock call does not execute logic, returns mocked value."""
367 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
368 artifacts.BundleFirmware(self.sysroot_request, self.response,
369 self.mock_call_config)
370 patch.assert_not_called()
371 self.assertEqual(len(self.response.artifacts), 1)
372 self.assertEqual(self.response.artifacts[0].path,
373 os.path.join(self.output_dir, 'firmware.tar.gz'))
374
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600375 def testBundleFirmware(self):
376 """BundleFirmware calls cbuildbot/commands with correct args."""
Alex Klein231d2da2019-07-22 16:44:45 -0600377 self.PatchObject(
378 artifacts_svc,
379 'BuildFirmwareArchive',
380 return_value=os.path.join(self.output_dir, 'firmware.tar.gz'))
381
Alex Klein68c8fdf2019-09-25 15:09:11 -0600382 artifacts.BundleFirmware(self.sysroot_request, self.response,
383 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600384 self.assertEqual(
Alex Klein231d2da2019-07-22 16:44:45 -0600385 [artifact.path for artifact in self.response.artifacts],
386 [os.path.join(self.output_dir, 'firmware.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600387
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600388 def testBundleFirmwareNoLogs(self):
389 """BundleFirmware dies when no firmware found."""
390 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
391 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600392 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600393 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600394
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600395
Yicheng Liea1181f2020-09-22 11:51:10 -0700396class BundleFpmcuUnittestsTest(BundleTestCase):
397 """Unittests for BundleFpmcuUnittests."""
398
399 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600400 """Quick check that a validate only call does not execute any logic."""
Yicheng Liea1181f2020-09-22 11:51:10 -0700401 patch = self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests')
402 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
403 self.validate_only_config)
404 patch.assert_not_called()
405
406 def testMockCall(self):
407 """Test that a mock call does not execute logic, returns mocked value."""
408 patch = self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests')
409 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
410 self.mock_call_config)
411 patch.assert_not_called()
412 self.assertEqual(len(self.response.artifacts), 1)
413 self.assertEqual(self.response.artifacts[0].path,
414 os.path.join(self.output_dir,
415 'fpmcu_unittests.tar.gz'))
416
417 def testBundleFpmcuUnittests(self):
418 """BundleFpmcuUnittests calls cbuildbot/commands with correct args."""
419 self.PatchObject(
420 artifacts_svc,
421 'BundleFpmcuUnittests',
422 return_value=os.path.join(self.output_dir, 'fpmcu_unittests.tar.gz'))
423 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
424 self.api_config)
425 self.assertEqual(
426 [artifact.path for artifact in self.response.artifacts],
427 [os.path.join(self.output_dir, 'fpmcu_unittests.tar.gz')])
428
429 def testBundleFpmcuUnittestsNoLogs(self):
430 """BundleFpmcuUnittests does not die when no fpmcu unittests found."""
431 self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests',
432 return_value=None)
433 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
434 self.api_config)
435 self.assertFalse(self.response.artifacts)
436
437
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600438class BundleEbuildLogsTest(BundleTestCase):
439 """Unittests for BundleEbuildLogs."""
440
Alex Klein231d2da2019-07-22 16:44:45 -0600441 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600442 """Quick check that a validate only call does not execute any logic."""
Alex Klein231d2da2019-07-22 16:44:45 -0600443 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600444 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600445 self.validate_only_config)
446 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600447
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700448 def testMockCall(self):
449 """Test that a mock call does not execute logic, returns mocked value."""
450 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
451 artifacts.BundleEbuildLogs(self.target_request, self.response,
452 self.mock_call_config)
453 patch.assert_not_called()
454 self.assertEqual(len(self.response.artifacts), 1)
455 self.assertEqual(self.response.artifacts[0].path,
456 os.path.join(self.output_dir, 'ebuild-logs.tar.gz'))
457
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600458 def testBundleEbuildLogs(self):
459 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600460 bundle_ebuild_logs_tarball = self.PatchObject(
461 artifacts_svc, 'BundleEBuildLogsTarball',
462 return_value='ebuild-logs.tar.gz')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600463 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
464 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600465 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600466 [artifact.path for artifact in self.response.artifacts],
Alex Klein68c8fdf2019-09-25 15:09:11 -0600467 [os.path.join(self.output_dir, 'ebuild-logs.tar.gz')])
Evan Hernandeza478d802019-04-08 15:08:24 -0600468 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600469 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600470 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600471
472 def testBundleEBuildLogsOldProto(self):
473 bundle_ebuild_logs_tarball = self.PatchObject(
474 artifacts_svc, 'BundleEBuildLogsTarball',
475 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600476
Alex Klein68c8fdf2019-09-25 15:09:11 -0600477 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600478 self.api_config)
479
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600480 self.assertEqual(
481 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600482 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600483
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600484 def testBundleEbuildLogsNoLogs(self):
485 """BundleEbuildLogs dies when no logs found."""
486 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
487 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600488 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
489 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600490
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600491
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600492class BundleChromeOSConfigTest(BundleTestCase):
493 """Unittests for BundleChromeOSConfig"""
494
495 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600496 """Quick check that a validate only call does not execute any logic."""
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600497 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600498 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600499 self.validate_only_config)
500 patch.assert_not_called()
501
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700502 def testMockCall(self):
503 """Test that a mock call does not execute logic, returns mocked value."""
504 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
505 artifacts.BundleChromeOSConfig(self.target_request, self.response,
506 self.mock_call_config)
507 patch.assert_not_called()
508 self.assertEqual(len(self.response.artifacts), 1)
509 self.assertEqual(self.response.artifacts[0].path,
510 os.path.join(self.output_dir, 'config.yaml'))
511
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600512 def testBundleChromeOSConfigCallWithSysroot(self):
513 """Call with a request that sets sysroot."""
514 bundle_chromeos_config = self.PatchObject(
515 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600516 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600517 self.api_config)
518 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600519 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600520 [os.path.join(self.output_dir, 'config.yaml')])
521
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600522 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600523 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600524
525 def testBundleChromeOSConfigCallWithBuildTarget(self):
526 """Call with a request that sets build_target."""
527 bundle_chromeos_config = self.PatchObject(
528 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600529 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600530 self.api_config)
531
532 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600533 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600534 [os.path.join(self.output_dir, 'config.yaml')])
535
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600536 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600537 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600538
539 def testBundleChromeOSConfigNoConfigFound(self):
540 """An error is raised if the config payload isn't found."""
541 self.PatchObject(artifacts_svc, 'BundleChromeOSConfig', return_value=None)
542
543 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600544 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600545 self.api_config)
546
547
Alex Klein231d2da2019-07-22 16:44:45 -0600548class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase,
549 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600550 """Unittests for BundleTestUpdatePayloads."""
551
552 def setUp(self):
553 self.source_root = os.path.join(self.tempdir, 'cros')
554 osutils.SafeMakedirs(self.source_root)
555
556 self.archive_root = os.path.join(self.tempdir, 'output')
557 osutils.SafeMakedirs(self.archive_root)
558
559 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600560 self.image_root = os.path.join(self.source_root,
561 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600562
563 self.input_proto = artifacts_pb2.BundleRequest()
564 self.input_proto.build_target.name = self.target
565 self.input_proto.output_dir = self.archive_root
566 self.output_proto = artifacts_pb2.BundleResponse()
567
568 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
569
Alex Kleincb541e82019-06-26 15:06:11 -0600570 def MockPayloads(image_path, archive_dir):
571 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
572 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
573 return [os.path.join(archive_dir, 'payload1.bin'),
574 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600575
Alex Kleincb541e82019-06-26 15:06:11 -0600576 self.bundle_patch = self.PatchObject(
577 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600578
Alex Klein231d2da2019-07-22 16:44:45 -0600579 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600580 """Quick check that a validate only call does not execute any logic."""
Alex Klein231d2da2019-07-22 16:44:45 -0600581 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
582 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
583 self.validate_only_config)
584 patch.assert_not_called()
585
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700586 def testMockCall(self):
587 """Test that a mock call does not execute logic, returns mocked value."""
588 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
589 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
590 self.mock_call_config)
591 patch.assert_not_called()
592 self.assertEqual(len(self.output_proto.artifacts), 1)
593 self.assertEqual(self.output_proto.artifacts[0].path,
594 os.path.join(self.archive_root, 'payload1.bin'))
595
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600596 def testBundleTestUpdatePayloads(self):
597 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
598 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
599 osutils.WriteFile(image_path, 'image!', makedirs=True)
600
Alex Klein231d2da2019-07-22 16:44:45 -0600601 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
602 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600603
604 actual = [
605 os.path.relpath(artifact.path, self.archive_root)
606 for artifact in self.output_proto.artifacts
607 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600608 expected = ['payload1.bin', 'payload2.bin']
Mike Frysinger678735c2019-09-28 18:23:28 -0400609 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600610
611 actual = [
612 os.path.relpath(path, self.archive_root)
613 for path in osutils.DirectoryIterator(self.archive_root)
614 ]
Mike Frysinger678735c2019-09-28 18:23:28 -0400615 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600616
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600617 def testBundleTestUpdatePayloadsNoImageDir(self):
618 """BundleTestUpdatePayloads dies if no image dir is found."""
619 # Intentionally do not write image directory.
Alex Kleind2bf1462019-10-24 16:37:04 -0600620 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
621 self.api_config)
622 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600623
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600624 def testBundleTestUpdatePayloadsNoImage(self):
625 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600626 # Intentionally do not write image, but create the directory.
627 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600628 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600629 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
630 self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600631
632
Alex Klein231d2da2019-07-22 16:44:45 -0600633class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase,
634 api_config.ApiConfigMixin):
Alex Klein2275d692019-04-23 16:04:12 -0600635 """BundleSimpleChromeArtifacts tests."""
636
637 def setUp(self):
638 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
639 self.sysroot_path = '/sysroot'
640 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
641 osutils.SafeMakedirs(self.sysroot_dir)
642 self.output_dir = os.path.join(self.tempdir, 'output_dir')
643 osutils.SafeMakedirs(self.output_dir)
644
645 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
646
Alex Klein231d2da2019-07-22 16:44:45 -0600647 self.response = artifacts_pb2.BundleResponse()
648
Alex Klein2275d692019-04-23 16:04:12 -0600649 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
650 output_dir=None):
651 """Helper to create a request message instance.
652
653 Args:
654 chroot (str): The chroot path.
655 sysroot (str): The sysroot path.
656 build_target (str): The build target name.
657 output_dir (str): The output directory.
658 """
659 return artifacts_pb2.BundleRequest(
660 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
661 chroot={'path': chroot}, output_dir=output_dir)
662
Alex Klein231d2da2019-07-22 16:44:45 -0600663 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600664 """Quick check that a validate only call does not execute any logic."""
Alex Klein231d2da2019-07-22 16:44:45 -0600665 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
666 request = self._GetRequest(chroot=self.chroot_dir,
667 sysroot=self.sysroot_path,
668 build_target='board', output_dir=self.output_dir)
669 artifacts.BundleSimpleChromeArtifacts(request, self.response,
670 self.validate_only_config)
671 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600672
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700673 def testMockCall(self):
674 """Test that a mock call does not execute logic, returns mocked value."""
675 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
676 request = self._GetRequest(chroot=self.chroot_dir,
677 sysroot=self.sysroot_path,
678 build_target='board', output_dir=self.output_dir)
679 artifacts.BundleSimpleChromeArtifacts(request, self.response,
680 self.mock_call_config)
681 patch.assert_not_called()
682 self.assertEqual(len(self.response.artifacts), 1)
683 self.assertEqual(self.response.artifacts[0].path,
684 os.path.join(self.output_dir, 'simple_chrome.txt'))
685
Alex Klein2275d692019-04-23 16:04:12 -0600686 def testNoBuildTarget(self):
687 """Test no build target fails."""
688 request = self._GetRequest(chroot=self.chroot_dir,
689 sysroot=self.sysroot_path,
690 output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600691 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600692 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600693 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600694
695 def testNoSysroot(self):
696 """Test no sysroot fails."""
697 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600698 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600699 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600700 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600701
702 def testSysrootDoesNotExist(self):
703 """Test no sysroot fails."""
704 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
705 sysroot=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600706 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600707 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600708 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600709
710 def testNoOutputDir(self):
711 """Test no output dir fails."""
712 request = self._GetRequest(chroot=self.chroot_dir,
713 sysroot=self.sysroot_path,
714 build_target='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600715 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600716 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600717 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600718
719 def testOutputDirDoesNotExist(self):
720 """Test no output dir fails."""
721 request = self._GetRequest(chroot=self.chroot_dir,
722 sysroot=self.sysroot_path,
723 build_target='board',
724 output_dir=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600725 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600726 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600727 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600728
729 def testOutputHandling(self):
730 """Test response output."""
731 files = ['file1', 'file2', 'file3']
732 expected_files = [os.path.join(self.output_dir, f) for f in files]
733 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
734 return_value=expected_files)
735 request = self._GetRequest(chroot=self.chroot_dir,
736 sysroot=self.sysroot_path,
737 build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600738 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600739
Alex Klein231d2da2019-07-22 16:44:45 -0600740 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600741
742 self.assertTrue(response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -0400743 self.assertCountEqual(expected_files, [a.path for a in response.artifacts])
Alex Klein2275d692019-04-23 16:04:12 -0600744
745
Alex Klein231d2da2019-07-22 16:44:45 -0600746class BundleVmFilesTest(cros_test_lib.MockTempDirTestCase,
747 api_config.ApiConfigMixin):
Alex Klein6504eca2019-04-18 15:37:56 -0600748 """BuildVmFiles tests."""
749
Alex Klein231d2da2019-07-22 16:44:45 -0600750 def setUp(self):
751 self.output_dir = os.path.join(self.tempdir, 'output')
752 osutils.SafeMakedirs(self.output_dir)
753
754 self.response = artifacts_pb2.BundleResponse()
755
Alex Klein6504eca2019-04-18 15:37:56 -0600756 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
757 output_dir=None):
758 """Helper to build out an input message instance.
759
760 Args:
761 chroot (str|None): The chroot path.
762 sysroot (str|None): The sysroot path relative to the chroot.
763 test_results_dir (str|None): The test results directory relative to the
764 sysroot.
765 output_dir (str|None): The directory where the results tarball should be
766 saved.
767 """
768 return artifacts_pb2.BundleVmFilesRequest(
769 chroot={'path': chroot}, sysroot={'path': sysroot},
770 test_results_dir=test_results_dir, output_dir=output_dir,
771 )
772
Alex Klein231d2da2019-07-22 16:44:45 -0600773 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600774 """Quick check that a validate only call does not execute any logic."""
Alex Klein231d2da2019-07-22 16:44:45 -0600775 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
776 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
777 test_results_dir='/test/results',
778 output_dir=self.output_dir)
779 artifacts.BundleVmFiles(in_proto, self.response, self.validate_only_config)
780 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600781
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700782 def testMockCall(self):
783 """Test that a mock call does not execute logic, returns mocked value."""
784 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
785 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
786 test_results_dir='/test/results',
787 output_dir=self.output_dir)
788 artifacts.BundleVmFiles(in_proto, self.response, self.mock_call_config)
789 patch.assert_not_called()
790 self.assertEqual(len(self.response.artifacts), 1)
791 self.assertEqual(self.response.artifacts[0].path,
792 os.path.join(self.output_dir, 'f1.tar'))
793
Alex Klein6504eca2019-04-18 15:37:56 -0600794 def testChrootMissing(self):
795 """Test error handling for missing chroot."""
796 in_proto = self._GetInput(sysroot='/build/board',
797 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600798 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600799
800 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600801 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600802
Alex Klein6504eca2019-04-18 15:37:56 -0600803 def testTestResultsDirMissing(self):
804 """Test error handling for missing test results directory."""
805 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
Alex Klein231d2da2019-07-22 16:44:45 -0600806 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600807
808 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600809 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600810
811 def testOutputDirMissing(self):
812 """Test error handling for missing output directory."""
813 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
814 test_results_dir='/test/results')
Alex Klein6504eca2019-04-18 15:37:56 -0600815
816 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600817 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
818
819 def testOutputDirDoesNotExist(self):
820 """Test error handling for output directory that does not exist."""
821 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
822 output_dir=os.path.join(self.tempdir, 'dne'),
823 test_results_dir='/test/results')
824
825 with self.assertRaises(cros_build_lib.DieSystemExit):
826 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600827
828 def testValidCall(self):
829 """Test image dir building."""
830 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
831 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600832 output_dir=self.output_dir)
833
Alex Klein6504eca2019-04-18 15:37:56 -0600834 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600835 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600836 return_value=expected_files)
837
Alex Klein231d2da2019-07-22 16:44:45 -0600838 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600839
Alex Klein231d2da2019-07-22 16:44:45 -0600840 patch.assert_called_with(mock.ANY, '/test/results', self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600841
842 # Make sure we have artifacts, and that every artifact is an expected file.
Alex Klein231d2da2019-07-22 16:44:45 -0600843 self.assertTrue(self.response.artifacts)
844 for artifact in self.response.artifacts:
Alex Klein6504eca2019-04-18 15:37:56 -0600845 self.assertIn(artifact.path, expected_files)
846 expected_files.remove(artifact.path)
847
848 # Make sure we've seen all of the expected files.
849 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700850
Alex Kleinb9d810b2019-07-01 12:38:02 -0600851
Tiancong Wang50b80a92019-08-01 14:46:15 -0700852
853class BundleAFDOGenerationArtifactsTestCase(
Alex Klein231d2da2019-07-22 16:44:45 -0600854 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700855 """Unittests for BundleAFDOGenerationArtifacts."""
856
857 @staticmethod
858 def mock_die(message, *args):
859 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700860
861 def setUp(self):
862 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
863 osutils.SafeMakedirs(self.chroot_dir)
864 temp_dir = os.path.join(self.chroot_dir, 'tmp')
865 osutils.SafeMakedirs(temp_dir)
866 self.output_dir = os.path.join(self.tempdir, 'output_dir')
867 osutils.SafeMakedirs(self.output_dir)
Tiancong Wang2ade7932019-09-27 14:15:40 -0700868 self.chrome_root = os.path.join(self.tempdir, 'chrome_root')
869 osutils.SafeMakedirs(self.chrome_root)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700870 self.build_target = 'board'
Tiancong Wang24a3df72019-08-20 15:48:51 -0700871 self.valid_artifact_type = toolchain_pb2.ORDERFILE
872 self.invalid_artifact_type = toolchain_pb2.NONE_TYPE
Tiancong Wangc4805b72019-06-11 12:12:03 -0700873 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700874 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700875
Alex Klein231d2da2019-07-22 16:44:45 -0600876 self.response = artifacts_pb2.BundleResponse()
877
Tiancong Wang2ade7932019-09-27 14:15:40 -0700878 def _GetRequest(self, chroot=None, build_target=None, chrome_root=None,
879 output_dir=None, artifact_type=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700880 """Helper to create a request message instance.
881
882 Args:
883 chroot (str): The chroot path.
884 build_target (str): The build target name.
Tiancong Wang2ade7932019-09-27 14:15:40 -0700885 chrome_root (str): The path to Chrome root.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700886 output_dir (str): The output directory.
Tiancong Wang50b80a92019-08-01 14:46:15 -0700887 artifact_type (artifacts_pb2.AFDOArtifactType):
888 The type of the artifact.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700889 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700890 return artifacts_pb2.BundleChromeAFDORequest(
Tiancong Wang2ade7932019-09-27 14:15:40 -0700891 chroot={'path': chroot, 'chrome_dir': chrome_root},
Tiancong Wang50b80a92019-08-01 14:46:15 -0700892 build_target={'name': build_target},
893 output_dir=output_dir,
894 artifact_type=artifact_type,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700895 )
896
Alex Klein231d2da2019-07-22 16:44:45 -0600897 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -0600898 """Quick check that a validate only call does not execute any logic."""
Alex Klein231d2da2019-07-22 16:44:45 -0600899 patch = self.PatchObject(artifacts_svc,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700900 'BundleAFDOGenerationArtifacts')
Alex Klein231d2da2019-07-22 16:44:45 -0600901 request = self._GetRequest(chroot=self.chroot_dir,
902 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700903 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700904 output_dir=self.output_dir,
905 artifact_type=self.valid_artifact_type)
906 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
907 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600908 patch.assert_not_called()
Tiancong Wangc4805b72019-06-11 12:12:03 -0700909
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700910 def testMockCall(self):
911 """Test that a mock call does not execute logic, returns mocked value."""
912 patch = self.PatchObject(artifacts_svc,
913 'BundleAFDOGenerationArtifacts')
914 request = self._GetRequest(chroot=self.chroot_dir,
915 build_target=self.build_target,
916 chrome_root=self.chrome_root,
917 output_dir=self.output_dir,
918 artifact_type=self.valid_artifact_type)
919 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
920 self.mock_call_config)
921 patch.assert_not_called()
922 self.assertEqual(len(self.response.artifacts), 1)
923 self.assertEqual(self.response.artifacts[0].path,
924 os.path.join(self.output_dir, 'artifact1'))
925
Tiancong Wangc4805b72019-06-11 12:12:03 -0700926 def testNoBuildTarget(self):
927 """Test no build target fails."""
928 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700929 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700930 output_dir=self.output_dir,
931 artifact_type=self.valid_artifact_type)
932 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
933 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
934 self.api_config)
935 self.assertEqual('build_target.name is required.',
936 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700937
Tiancong Wang2ade7932019-09-27 14:15:40 -0700938 def testNoChromeRoot(self):
939 """Test no chrome root fails."""
940 request = self._GetRequest(chroot=self.chroot_dir,
941 build_target=self.build_target,
942 output_dir=self.output_dir,
943 artifact_type=self.valid_artifact_type)
944 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
945 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
946 self.api_config)
947 self.assertEqual('chroot.chrome_dir path does not exist: ',
948 str(context.exception))
949
Tiancong Wangc4805b72019-06-11 12:12:03 -0700950 def testNoOutputDir(self):
951 """Test no output dir fails."""
952 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700953 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700954 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700955 artifact_type=self.valid_artifact_type)
956 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
957 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
958 self.api_config)
959 self.assertEqual('output_dir is required.',
960 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700961
962 def testOutputDirDoesNotExist(self):
963 """Test output directory not existing fails."""
964 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700965 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700966 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700967 output_dir=self.does_not_exist,
968 artifact_type=self.valid_artifact_type)
969 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
970 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
971 self.api_config)
972 self.assertEqual(
973 'output_dir path does not exist: %s' % self.does_not_exist,
974 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700975
Tiancong Wang50b80a92019-08-01 14:46:15 -0700976 def testNoArtifactType(self):
977 """Test no artifact type."""
978 request = self._GetRequest(chroot=self.chroot_dir,
979 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700980 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700981 output_dir=self.output_dir)
982 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
983 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
984 self.api_config)
985 self.assertIn('artifact_type (0) must be in',
986 str(context.exception))
987
988 def testWrongArtifactType(self):
989 """Test passing wrong artifact type."""
990 request = self._GetRequest(chroot=self.chroot_dir,
991 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700992 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700993 output_dir=self.output_dir,
994 artifact_type=self.invalid_artifact_type)
995 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
996 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
997 self.api_config)
Tiancong Wang24a3df72019-08-20 15:48:51 -0700998 self.assertIn('artifact_type (%d) must be in' % self.invalid_artifact_type,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700999 str(context.exception))
1000
1001 def testOutputHandlingOnOrderfile(self,
Tiancong Wang24a3df72019-08-20 15:48:51 -07001002 artifact_type=toolchain_pb2.ORDERFILE):
Tiancong Wang50b80a92019-08-01 14:46:15 -07001003 """Test response output for orderfile."""
1004 files = ['artifact1', 'artifact2', 'artifact3']
Tiancong Wangc4805b72019-06-11 12:12:03 -07001005 expected_files = [os.path.join(self.output_dir, f) for f in files]
Tiancong Wang50b80a92019-08-01 14:46:15 -07001006 self.PatchObject(artifacts_svc, 'BundleAFDOGenerationArtifacts',
Tiancong Wangc4805b72019-06-11 12:12:03 -07001007 return_value=expected_files)
Alex Klein231d2da2019-07-22 16:44:45 -06001008
Tiancong Wangc4805b72019-06-11 12:12:03 -07001009 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -07001010 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001011 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001012 output_dir=self.output_dir,
1013 artifact_type=artifact_type)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001014
Tiancong Wang50b80a92019-08-01 14:46:15 -07001015 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1016 self.api_config)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001017
Tiancong Wang50b80a92019-08-01 14:46:15 -07001018 self.assertTrue(self.response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -04001019 self.assertCountEqual(expected_files,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001020 [a.path for a in self.response.artifacts])
1021
1022 def testOutputHandlingOnAFDO(self):
1023 """Test response output for AFDO."""
1024 self.testOutputHandlingOnOrderfile(
Tiancong Wang24a3df72019-08-20 15:48:51 -07001025 artifact_type=toolchain_pb2.BENCHMARK_AFDO)
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001026
1027
1028class ExportCpeReportTest(cros_test_lib.MockTempDirTestCase,
1029 api_config.ApiConfigMixin):
1030 """ExportCpeReport tests."""
1031
1032 def setUp(self):
1033 self.response = artifacts_pb2.BundleResponse()
1034
1035 def testValidateOnly(self):
Greg Edelstondc941072021-08-11 12:32:30 -06001036 """Quick check validate only calls don't execute."""
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001037 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1038
1039 request = artifacts_pb2.BundleRequest()
1040 request.build_target.name = 'board'
1041 request.output_dir = self.tempdir
1042
1043 artifacts.ExportCpeReport(request, self.response, self.validate_only_config)
1044
1045 patch.assert_not_called()
1046
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001047 def testMockCall(self):
1048 """Test that a mock call does not execute logic, returns mocked value."""
1049 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1050
1051 request = artifacts_pb2.BundleRequest()
1052 request.build_target.name = 'board'
1053 request.output_dir = self.tempdir
1054
1055 artifacts.ExportCpeReport(request, self.response, self.mock_call_config)
1056
1057 patch.assert_not_called()
1058 self.assertEqual(len(self.response.artifacts), 2)
1059 self.assertEqual(self.response.artifacts[0].path,
1060 os.path.join(self.tempdir, 'cpe_report.txt'))
1061 self.assertEqual(self.response.artifacts[1].path,
1062 os.path.join(self.tempdir, 'cpe_warnings.txt'))
1063
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001064 def testNoBuildTarget(self):
1065 request = artifacts_pb2.BundleRequest()
1066 request.output_dir = self.tempdir
1067
1068 with self.assertRaises(cros_build_lib.DieSystemExit):
1069 artifacts.ExportCpeReport(request, self.response, self.api_config)
1070
1071 def testSuccess(self):
1072 """Test success case."""
1073 expected = artifacts_svc.CpeResult(
1074 report='/output/report.json', warnings='/output/warnings.json')
1075 self.PatchObject(artifacts_svc, 'GenerateCpeReport', return_value=expected)
1076
1077 request = artifacts_pb2.BundleRequest()
1078 request.build_target.name = 'board'
1079 request.output_dir = self.tempdir
1080
1081 artifacts.ExportCpeReport(request, self.response, self.api_config)
1082
1083 for artifact in self.response.artifacts:
1084 self.assertIn(artifact.path, [expected.report, expected.warnings])
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001085
1086
1087class BundleGceTarballTest(BundleTestCase):
1088 """Unittests for BundleGceTarball."""
1089
1090 def testValidateOnly(self):
1091 """Check that a validate only call does not execute any logic."""
1092 patch = self.PatchObject(artifacts_svc, 'BundleGceTarball')
1093 artifacts.BundleGceTarball(self.target_request, self.response,
1094 self.validate_only_config)
1095 patch.assert_not_called()
1096
1097 def testMockCall(self):
1098 """Test that a mock call does not execute logic, returns mocked value."""
1099 patch = self.PatchObject(artifacts_svc, 'BundleGceTarball')
1100 artifacts.BundleGceTarball(self.target_request, self.response,
1101 self.mock_call_config)
1102 patch.assert_not_called()
1103 self.assertEqual(len(self.response.artifacts), 1)
1104 self.assertEqual(self.response.artifacts[0].path,
1105 os.path.join(self.output_dir,
1106 constants.TEST_IMAGE_GCE_TAR))
1107
1108 def testBundleGceTarball(self):
1109 """BundleGceTarball calls cbuildbot/commands with correct args."""
1110 bundle_gce_tarball = self.PatchObject(
1111 artifacts_svc, 'BundleGceTarball',
1112 return_value=os.path.join(self.output_dir,
1113 constants.TEST_IMAGE_GCE_TAR))
1114 self.PatchObject(os.path, 'exists', return_value=True)
1115 artifacts.BundleGceTarball(self.target_request, self.response,
1116 self.api_config)
1117 self.assertEqual(
1118 [artifact.path for artifact in self.response.artifacts],
1119 [os.path.join(self.output_dir, constants.TEST_IMAGE_GCE_TAR)])
1120
1121 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
1122 self.assertEqual(
1123 bundle_gce_tarball.call_args_list,
1124 [mock.call(self.output_dir, latest)])
1125
1126 def testBundleGceTarballNoImageDir(self):
1127 """BundleGceTarball dies when image dir does not exist."""
1128 self.PatchObject(os.path, 'exists', return_value=False)
1129 with self.assertRaises(cros_build_lib.DieSystemExit):
1130 artifacts.BundleGceTarball(self.target_request, self.response,
1131 self.api_config)
Greg Edelstondc941072021-08-11 12:32:30 -06001132
1133class FetchMetadataTestCase(cros_test_lib.MockTempDirTestCase,
1134 api_config.ApiConfigMixin):
1135 """Unittests for FetchMetadata."""
1136
1137 sysroot_path = '/build/coral'
1138 chroot_name = 'chroot'
1139
1140 def setUp(self):
1141 self.chroot_path = os.path.join(self.tempdir, 'chroot')
1142 pathlib.Path(self.chroot_path).touch()
1143 self.expected_filepaths = [os.path.join(self.chroot_path, fp) for fp in (
1144 'build/coral/usr/local/build/autotest/autotest_metadata.pb',
1145 'build/coral/usr/share/tast/metadata/local/cros.pb',
1146 'build/coral/build/share/tast/metadata/local/crosint.pb',
1147 'usr/share/tast/metadata/remote/cros.pb',
1148 )]
1149 self.PatchObject(cros_build_lib, 'AssertOutsideChroot')
1150
1151 def createFetchMetadataRequest(self, use_sysroot_path=True, use_chroot=True):
1152 """Construct a FetchMetadataRequest for use in test cases."""
1153 request = artifacts_pb2.FetchMetadataRequest()
1154 if use_sysroot_path:
1155 request.sysroot.path = self.sysroot_path
1156 if use_chroot:
1157 request.chroot.path = self.chroot_path
1158 return request
1159
1160 def testValidateOnly(self):
1161 """Check that a validate only call does not execute any logic."""
1162 patch = self.PatchObject(controller_util, 'ParseSysroot')
1163 request = self.createFetchMetadataRequest()
1164 response = artifacts_pb2.FetchMetadataResponse()
1165 artifacts.FetchMetadata(request, response, self.validate_only_config)
1166 patch.assert_not_called()
1167
1168 def testMockCall(self):
1169 """Test that a mock call does not execute logic, returns mocked value."""
1170 patch = self.PatchObject(controller_util, 'ParseSysroot')
1171 request = self.createFetchMetadataRequest()
1172 response = artifacts_pb2.FetchMetadataResponse()
1173 artifacts.FetchMetadata(request, response, self.mock_call_config)
1174 patch.assert_not_called()
1175 self.assertGreater(len(response.filepaths), 0)
1176
1177 def testNoSysrootPath(self):
1178 """Check that a request with no sysroot.path results in failure."""
1179 request = self.createFetchMetadataRequest(use_sysroot_path=False)
1180 response = artifacts_pb2.FetchMetadataResponse()
1181 with self.assertRaises(cros_build_lib.DieSystemExit):
1182 artifacts.FetchMetadata(request, response, self.api_config)
1183
1184 def testNoChroot(self):
1185 """Check that a request with no chroot results in failure."""
1186 request = self.createFetchMetadataRequest(use_chroot=False)
1187 response = artifacts_pb2.FetchMetadataResponse()
1188 with self.assertRaises(cros_build_lib.DieSystemExit):
1189 artifacts.FetchMetadata(request, response, self.api_config)
1190
1191 def testSuccess(self):
1192 """Check that a well-formed request yields the expected results."""
1193 request = self.createFetchMetadataRequest(use_chroot=True)
1194 response = artifacts_pb2.FetchMetadataResponse()
1195 artifacts.FetchMetadata(request, response, self.api_config)
1196 actual_filepaths = [fp.path.path for fp in response.filepaths]
1197 self.assertEqual(sorted(actual_filepaths), sorted(self.expected_filepaths))
1198 self.assertTrue(all([fp.path.location == common_pb2.Path.OUTSIDE
1199 for fp in response.filepaths]))