blob: 6fb07408daac4444fcf9dcdc1b23b9d2716d0cd4 [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
Mike Frysinger166fea02021-02-12 05:30:33 -05008from unittest import mock
Evan Hernandezf388cbf2019-04-01 11:15:23 -06009
Alex Klein231d2da2019-07-22 16:44:45 -060010from chromite.api import api_config
Evan Hernandezf388cbf2019-04-01 11:15:23 -060011from chromite.api.controller import artifacts
12from chromite.api.gen.chromite.api import artifacts_pb2
Tiancong Wang24a3df72019-08-20 15:48:51 -070013from chromite.api.gen.chromite.api import toolchain_pb2
Evan Hernandezf388cbf2019-04-01 11:15:23 -060014from chromite.cbuildbot import commands
Michael Mortensen7da39cc2021-03-09 10:28:45 -070015from chromite.lib import build_target_lib
Alex Kleinb9d810b2019-07-01 12:38:02 -060016from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060017from chromite.lib import constants
18from chromite.lib import cros_build_lib
19from chromite.lib import cros_test_lib
20from chromite.lib import osutils
Alex Klein238d8862019-05-07 11:32:46 -060021from chromite.lib import sysroot_lib
Alex Klein2275d692019-04-23 16:04:12 -060022from chromite.service import artifacts as artifacts_svc
Evan Hernandezf388cbf2019-04-01 11:15:23 -060023
24
Alex Kleind91e95a2019-09-17 10:39:02 -060025class BundleRequestMixin(object):
26 """Mixin to provide bundle request methods."""
27
28 def EmptyRequest(self):
29 return artifacts_pb2.BundleRequest()
30
31 def BuildTargetRequest(self, build_target=None, output_dir=None, chroot=None):
32 """Get a build target format request instance."""
33 request = self.EmptyRequest()
34 if build_target:
35 request.build_target.name = build_target
36 if output_dir:
37 request.output_dir = output_dir
38 if chroot:
39 request.chroot.path = chroot
40
41 return request
42
43 def SysrootRequest(self,
44 sysroot=None,
45 build_target=None,
46 output_dir=None,
47 chroot=None):
48 """Get a sysroot format request instance."""
49 request = self.EmptyRequest()
50 if sysroot:
51 request.sysroot.path = sysroot
52 if build_target:
53 request.sysroot.build_target.name = build_target
54 if output_dir:
55 request.output_dir = output_dir
56 if chroot:
57 request.chroot.path = chroot
58
59 return request
60
61
Alex Klein231d2da2019-07-22 16:44:45 -060062class BundleTestCase(cros_test_lib.MockTempDirTestCase,
Alex Kleind91e95a2019-09-17 10:39:02 -060063 api_config.ApiConfigMixin, BundleRequestMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060064 """Basic setup for all artifacts unittests."""
65
66 def setUp(self):
Alex Klein231d2da2019-07-22 16:44:45 -060067 self.output_dir = os.path.join(self.tempdir, 'artifacts')
68 osutils.SafeMakedirs(self.output_dir)
69 self.sysroot_path = '/build/target'
Alex Klein68c8fdf2019-09-25 15:09:11 -060070 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -060071 self.chroot_path = os.path.join(self.tempdir, 'chroot')
72 full_sysroot_path = os.path.join(self.chroot_path,
73 self.sysroot_path.lstrip(os.sep))
74 osutils.SafeMakedirs(full_sysroot_path)
75
Alex Klein68c8fdf2019-09-25 15:09:11 -060076 # All requests use same response type.
Alex Klein231d2da2019-07-22 16:44:45 -060077 self.response = artifacts_pb2.BundleResponse()
78
Alex Klein68c8fdf2019-09-25 15:09:11 -060079 # Build target request.
80 self.target_request = self.BuildTargetRequest(
81 build_target='target',
82 output_dir=self.output_dir,
83 chroot=self.chroot_path)
84
85 # Sysroot request.
86 self.sysroot_request = self.SysrootRequest(
87 sysroot=self.sysroot_path,
88 build_target='target',
89 output_dir=self.output_dir,
90 chroot=self.chroot_path)
91
Alex Klein231d2da2019-07-22 16:44:45 -060092 self.source_root = self.tempdir
93 self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -060094
95
Alex Kleind91e95a2019-09-17 10:39:02 -060096class BundleImageArchivesTest(BundleTestCase):
97 """BundleImageArchives tests."""
98
99 def testValidateOnly(self):
100 """Sanity check that a validate only call does not execute any logic."""
101 patch = self.PatchObject(artifacts_svc, 'ArchiveImages')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600102 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600103 self.validate_only_config)
104 patch.assert_not_called()
105
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700106 def testMockCall(self):
107 """Test that a mock call does not execute logic, returns mocked value."""
108 patch = self.PatchObject(artifacts_svc, 'ArchiveImages')
109 artifacts.BundleImageArchives(self.target_request, self.response,
110 self.mock_call_config)
111 patch.assert_not_called()
112 self.assertEqual(len(self.response.artifacts), 2)
113 self.assertEqual(self.response.artifacts[0].path,
114 os.path.join(self.output_dir, 'path0.tar.xz'))
115 self.assertEqual(self.response.artifacts[1].path,
116 os.path.join(self.output_dir, 'path1.tar.xz'))
117
Alex Kleind91e95a2019-09-17 10:39:02 -0600118 def testNoBuildTarget(self):
119 """Test that no build target fails."""
120 request = self.BuildTargetRequest(output_dir=self.tempdir)
121 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600122 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600123
124 def testNoOutputDir(self):
125 """Test no output dir fails."""
126 request = self.BuildTargetRequest(build_target='board')
127 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600128 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600129
130 def testInvalidOutputDir(self):
131 """Test invalid output dir fails."""
132 request = self.BuildTargetRequest(
133 build_target='board', output_dir=os.path.join(self.tempdir, 'DNE'))
134 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600135 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600136
137 def testOutputHandling(self):
138 """Test the artifact output handling."""
139 expected = [os.path.join(self.output_dir, f) for f in ('a', 'b', 'c')]
140 self.PatchObject(artifacts_svc, 'ArchiveImages', return_value=expected)
141 self.PatchObject(os.path, 'exists', return_value=True)
142
Alex Klein68c8fdf2019-09-25 15:09:11 -0600143 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600144 self.api_config)
145
Mike Frysinger678735c2019-09-28 18:23:28 -0400146 self.assertCountEqual(expected, [a.path for a in self.response.artifacts])
Alex Kleind91e95a2019-09-17 10:39:02 -0600147
148
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600149class BundleImageZipTest(BundleTestCase):
150 """Unittests for BundleImageZip."""
151
Alex Klein231d2da2019-07-22 16:44:45 -0600152 def testValidateOnly(self):
153 """Sanity check that a validate only call does not execute any logic."""
154 patch = self.PatchObject(commands, 'BuildImageZip')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600155 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600156 self.validate_only_config)
157 patch.assert_not_called()
158
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700159 def testMockCall(self):
160 """Test that a mock call does not execute logic, returns mocked value."""
161 patch = self.PatchObject(commands, 'BuildImageZip')
162 artifacts.BundleImageZip(self.target_request, self.response,
163 self.mock_call_config)
164 patch.assert_not_called()
165 self.assertEqual(len(self.response.artifacts), 1)
166 self.assertEqual(self.response.artifacts[0].path,
167 os.path.join(self.output_dir, 'image.zip'))
168
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600169 def testBundleImageZip(self):
170 """BundleImageZip calls cbuildbot/commands with correct args."""
Michael Mortensen01910922019-07-24 14:48:10 -0600171 bundle_image_zip = self.PatchObject(
172 artifacts_svc, 'BundleImageZip', return_value='image.zip')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600173 self.PatchObject(os.path, 'exists', return_value=True)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600174 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600175 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600176 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600177 [artifact.path for artifact in self.response.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600178 [os.path.join(self.output_dir, 'image.zip')])
179
180 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600181 self.assertEqual(
Michael Mortensen01910922019-07-24 14:48:10 -0600182 bundle_image_zip.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600183 [mock.call(self.output_dir, latest)])
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600184
185 def testBundleImageZipNoImageDir(self):
186 """BundleImageZip dies when image dir does not exist."""
187 self.PatchObject(os.path, 'exists', return_value=False)
188 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600189 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600190 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600191
192
Alex Klein68c8fdf2019-09-25 15:09:11 -0600193class BundleAutotestFilesTest(BundleTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600194 """Unittests for BundleAutotestFiles."""
195
Alex Klein231d2da2019-07-22 16:44:45 -0600196 def testValidateOnly(self):
197 """Sanity check that a validate only call does not execute any logic."""
198 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600199 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600200 self.validate_only_config)
201 patch.assert_not_called()
202
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700203 def testMockCall(self):
204 """Test that a mock call does not execute logic, returns mocked value."""
205 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
206 artifacts.BundleAutotestFiles(self.target_request, self.response,
207 self.mock_call_config)
208 patch.assert_not_called()
209 self.assertEqual(len(self.response.artifacts), 1)
210 self.assertEqual(self.response.artifacts[0].path,
211 os.path.join(self.output_dir, 'autotest-a.tar.gz'))
212
Alex Klein238d8862019-05-07 11:32:46 -0600213 def testBundleAutotestFilesLegacy(self):
214 """BundleAutotestFiles calls service correctly with legacy args."""
215 files = {
216 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
217 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
218 }
219 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
220 return_value=files)
221
Alex Klein68c8fdf2019-09-25 15:09:11 -0600222 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600223 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600224
Alex Klein238d8862019-05-07 11:32:46 -0600225 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600226 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600227
228 # Verify the output proto is being populated correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600229 self.assertTrue(self.response.artifacts)
230 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400231 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600232
233 def testBundleAutotestFiles(self):
234 """BundleAutotestFiles calls service correctly."""
235 files = {
236 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
237 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
238 }
239 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
240 return_value=files)
241
Alex Klein68c8fdf2019-09-25 15:09:11 -0600242 artifacts.BundleAutotestFiles(self.sysroot_request, self.response,
243 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600244
245 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600246 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600247
248 # Verify the output proto is being populated correctly.
249 self.assertTrue(self.response.artifacts)
250 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400251 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600252
253 def testInvalidOutputDir(self):
254 """Test invalid output directory argument."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600255 request = self.SysrootRequest(chroot=self.chroot_path,
256 sysroot=self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600257
258 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600259 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600260
261 def testInvalidSysroot(self):
262 """Test no sysroot directory."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600263 request = self.SysrootRequest(chroot=self.chroot_path,
264 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600265
266 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600267 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600268
269 def testSysrootDoesNotExist(self):
270 """Test dies when no sysroot does not exist."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600271 request = self.SysrootRequest(chroot=self.chroot_path,
272 sysroot='/does/not/exist',
273 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600274
275 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600276 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600277
278
279class BundleTastFilesTest(BundleTestCase):
280 """Unittests for BundleTastFiles."""
281
Alex Klein231d2da2019-07-22 16:44:45 -0600282 def testValidateOnly(self):
283 """Sanity check that a validate only call does not execute any logic."""
284 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600285 artifacts.BundleTastFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600286 self.validate_only_config)
287 patch.assert_not_called()
288
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700289 def testMockCall(self):
290 """Test that a mock call does not execute logic, returns mocked value."""
291 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
292 artifacts.BundleTastFiles(self.target_request, self.response,
293 self.mock_call_config)
294 patch.assert_not_called()
295 self.assertEqual(len(self.response.artifacts), 1)
296 self.assertEqual(self.response.artifacts[0].path,
297 os.path.join(self.output_dir, 'tast_bundles.tar.gz'))
298
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600299 def testBundleTastFilesNoLogs(self):
LaMont Jonesb9793cd2020-06-11 08:14:46 -0600300 """BundleTasteFiles succeeds when no tast files found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600301 self.PatchObject(commands, 'BuildTastBundleTarball',
302 return_value=None)
LaMont Jonesb9793cd2020-06-11 08:14:46 -0600303 artifacts.BundleTastFiles(self.target_request, self.response,
304 self.api_config)
305 self.assertEqual(list(self.response.artifacts), [])
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600306
Alex Kleinb9d810b2019-07-01 12:38:02 -0600307 def testBundleTastFilesLegacy(self):
308 """BundleTastFiles handles legacy args correctly."""
309 buildroot = self.tempdir
310 chroot_dir = os.path.join(buildroot, 'chroot')
311 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
312 output_dir = os.path.join(self.tempdir, 'results')
313 osutils.SafeMakedirs(sysroot_path)
314 osutils.SafeMakedirs(output_dir)
315
Alex Klein171da612019-08-06 14:00:42 -0600316 chroot = chroot_lib.Chroot(chroot_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600317 sysroot = sysroot_lib.Sysroot('/build/board')
318
319 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
320 # Patch the service being called.
321 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
322 return_value=expected_archive)
323 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
324
325 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
326 output_dir=output_dir)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600327 artifacts.BundleTastFiles(request, self.response, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600328 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600329 [artifact.path for artifact in self.response.artifacts],
Alex Kleinb9d810b2019-07-01 12:38:02 -0600330 [expected_archive])
331 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
332
333 def testBundleTastFiles(self):
334 """BundleTastFiles calls service correctly."""
Alex Kleinb49be8a2019-12-20 10:23:03 -0700335 chroot = chroot_lib.Chroot(self.chroot_path)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600336
Alex Klein68c8fdf2019-09-25 15:09:11 -0600337 expected_archive = os.path.join(self.output_dir,
338 artifacts_svc.TAST_BUNDLE_NAME)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600339 # Patch the service being called.
340 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
341 return_value=expected_archive)
342
Alex Klein68c8fdf2019-09-25 15:09:11 -0600343 artifacts.BundleTastFiles(self.sysroot_request, self.response,
344 self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600345
346 # Make sure the artifact got recorded successfully.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600347 self.assertTrue(self.response.artifacts)
348 self.assertEqual(expected_archive, self.response.artifacts[0].path)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600349 # Make sure the service got called correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600350 bundle_patch.assert_called_once_with(chroot, self.sysroot, self.output_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600351
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600352
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600353class BundleFirmwareTest(BundleTestCase):
354 """Unittests for BundleFirmware."""
355
Alex Klein231d2da2019-07-22 16:44:45 -0600356 def testValidateOnly(self):
357 """Sanity check that a validate only call does not execute any logic."""
358 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600359 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600360 self.validate_only_config)
361 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000362
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700363 def testMockCall(self):
364 """Test that a mock call does not execute logic, returns mocked value."""
365 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
366 artifacts.BundleFirmware(self.sysroot_request, self.response,
367 self.mock_call_config)
368 patch.assert_not_called()
369 self.assertEqual(len(self.response.artifacts), 1)
370 self.assertEqual(self.response.artifacts[0].path,
371 os.path.join(self.output_dir, 'firmware.tar.gz'))
372
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600373 def testBundleFirmware(self):
374 """BundleFirmware calls cbuildbot/commands with correct args."""
Alex Klein231d2da2019-07-22 16:44:45 -0600375 self.PatchObject(
376 artifacts_svc,
377 'BuildFirmwareArchive',
378 return_value=os.path.join(self.output_dir, 'firmware.tar.gz'))
379
Alex Klein68c8fdf2019-09-25 15:09:11 -0600380 artifacts.BundleFirmware(self.sysroot_request, self.response,
381 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600382 self.assertEqual(
Alex Klein231d2da2019-07-22 16:44:45 -0600383 [artifact.path for artifact in self.response.artifacts],
384 [os.path.join(self.output_dir, 'firmware.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600385
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600386 def testBundleFirmwareNoLogs(self):
387 """BundleFirmware dies when no firmware found."""
388 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
389 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600390 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600391 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600392
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600393
Yicheng Liea1181f2020-09-22 11:51:10 -0700394class BundleFpmcuUnittestsTest(BundleTestCase):
395 """Unittests for BundleFpmcuUnittests."""
396
397 def testValidateOnly(self):
398 """Sanity check that a validate only call does not execute any logic."""
399 patch = self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests')
400 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
401 self.validate_only_config)
402 patch.assert_not_called()
403
404 def testMockCall(self):
405 """Test that a mock call does not execute logic, returns mocked value."""
406 patch = self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests')
407 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
408 self.mock_call_config)
409 patch.assert_not_called()
410 self.assertEqual(len(self.response.artifacts), 1)
411 self.assertEqual(self.response.artifacts[0].path,
412 os.path.join(self.output_dir,
413 'fpmcu_unittests.tar.gz'))
414
415 def testBundleFpmcuUnittests(self):
416 """BundleFpmcuUnittests calls cbuildbot/commands with correct args."""
417 self.PatchObject(
418 artifacts_svc,
419 'BundleFpmcuUnittests',
420 return_value=os.path.join(self.output_dir, 'fpmcu_unittests.tar.gz'))
421 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
422 self.api_config)
423 self.assertEqual(
424 [artifact.path for artifact in self.response.artifacts],
425 [os.path.join(self.output_dir, 'fpmcu_unittests.tar.gz')])
426
427 def testBundleFpmcuUnittestsNoLogs(self):
428 """BundleFpmcuUnittests does not die when no fpmcu unittests found."""
429 self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests',
430 return_value=None)
431 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
432 self.api_config)
433 self.assertFalse(self.response.artifacts)
434
435
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600436class BundleEbuildLogsTest(BundleTestCase):
437 """Unittests for BundleEbuildLogs."""
438
Alex Klein231d2da2019-07-22 16:44:45 -0600439 def testValidateOnly(self):
440 """Sanity check that a validate only call does not execute any logic."""
441 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600442 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600443 self.validate_only_config)
444 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600445
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700446 def testMockCall(self):
447 """Test that a mock call does not execute logic, returns mocked value."""
448 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
449 artifacts.BundleEbuildLogs(self.target_request, self.response,
450 self.mock_call_config)
451 patch.assert_not_called()
452 self.assertEqual(len(self.response.artifacts), 1)
453 self.assertEqual(self.response.artifacts[0].path,
454 os.path.join(self.output_dir, 'ebuild-logs.tar.gz'))
455
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600456 def testBundleEbuildLogs(self):
457 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600458 bundle_ebuild_logs_tarball = self.PatchObject(
459 artifacts_svc, 'BundleEBuildLogsTarball',
460 return_value='ebuild-logs.tar.gz')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600461 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
462 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600463 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600464 [artifact.path for artifact in self.response.artifacts],
Alex Klein68c8fdf2019-09-25 15:09:11 -0600465 [os.path.join(self.output_dir, 'ebuild-logs.tar.gz')])
Evan Hernandeza478d802019-04-08 15:08:24 -0600466 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600467 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600468 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600469
470 def testBundleEBuildLogsOldProto(self):
471 bundle_ebuild_logs_tarball = self.PatchObject(
472 artifacts_svc, 'BundleEBuildLogsTarball',
473 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600474
Alex Klein68c8fdf2019-09-25 15:09:11 -0600475 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600476 self.api_config)
477
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600478 self.assertEqual(
479 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600480 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600481
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600482 def testBundleEbuildLogsNoLogs(self):
483 """BundleEbuildLogs dies when no logs found."""
484 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
485 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600486 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
487 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600488
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600489
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600490class BundleChromeOSConfigTest(BundleTestCase):
491 """Unittests for BundleChromeOSConfig"""
492
493 def testValidateOnly(self):
494 """Sanity check that a validate only call does not execute any logic."""
495 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600496 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600497 self.validate_only_config)
498 patch.assert_not_called()
499
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700500 def testMockCall(self):
501 """Test that a mock call does not execute logic, returns mocked value."""
502 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
503 artifacts.BundleChromeOSConfig(self.target_request, self.response,
504 self.mock_call_config)
505 patch.assert_not_called()
506 self.assertEqual(len(self.response.artifacts), 1)
507 self.assertEqual(self.response.artifacts[0].path,
508 os.path.join(self.output_dir, 'config.yaml'))
509
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600510 def testBundleChromeOSConfigCallWithSysroot(self):
511 """Call with a request that sets sysroot."""
512 bundle_chromeos_config = self.PatchObject(
513 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600514 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600515 self.api_config)
516 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600517 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600518 [os.path.join(self.output_dir, 'config.yaml')])
519
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600520 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600521 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600522
523 def testBundleChromeOSConfigCallWithBuildTarget(self):
524 """Call with a request that sets build_target."""
525 bundle_chromeos_config = self.PatchObject(
526 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600527 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600528 self.api_config)
529
530 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600531 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600532 [os.path.join(self.output_dir, 'config.yaml')])
533
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600534 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600535 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600536
537 def testBundleChromeOSConfigNoConfigFound(self):
538 """An error is raised if the config payload isn't found."""
539 self.PatchObject(artifacts_svc, 'BundleChromeOSConfig', return_value=None)
540
541 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600542 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600543 self.api_config)
544
545
Alex Klein231d2da2019-07-22 16:44:45 -0600546class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase,
547 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600548 """Unittests for BundleTestUpdatePayloads."""
549
550 def setUp(self):
551 self.source_root = os.path.join(self.tempdir, 'cros')
552 osutils.SafeMakedirs(self.source_root)
553
554 self.archive_root = os.path.join(self.tempdir, 'output')
555 osutils.SafeMakedirs(self.archive_root)
556
557 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600558 self.image_root = os.path.join(self.source_root,
559 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600560
561 self.input_proto = artifacts_pb2.BundleRequest()
562 self.input_proto.build_target.name = self.target
563 self.input_proto.output_dir = self.archive_root
564 self.output_proto = artifacts_pb2.BundleResponse()
565
566 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
567
Alex Kleincb541e82019-06-26 15:06:11 -0600568 def MockPayloads(image_path, archive_dir):
569 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
570 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
571 return [os.path.join(archive_dir, 'payload1.bin'),
572 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600573
Alex Kleincb541e82019-06-26 15:06:11 -0600574 self.bundle_patch = self.PatchObject(
575 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600576
Alex Klein231d2da2019-07-22 16:44:45 -0600577 def testValidateOnly(self):
578 """Sanity check that a validate only call does not execute any logic."""
579 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
580 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
581 self.validate_only_config)
582 patch.assert_not_called()
583
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700584 def testMockCall(self):
585 """Test that a mock call does not execute logic, returns mocked value."""
586 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
587 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
588 self.mock_call_config)
589 patch.assert_not_called()
590 self.assertEqual(len(self.output_proto.artifacts), 1)
591 self.assertEqual(self.output_proto.artifacts[0].path,
592 os.path.join(self.archive_root, 'payload1.bin'))
593
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600594 def testBundleTestUpdatePayloads(self):
595 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
596 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
597 osutils.WriteFile(image_path, 'image!', makedirs=True)
598
Alex Klein231d2da2019-07-22 16:44:45 -0600599 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
600 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600601
602 actual = [
603 os.path.relpath(artifact.path, self.archive_root)
604 for artifact in self.output_proto.artifacts
605 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600606 expected = ['payload1.bin', 'payload2.bin']
Mike Frysinger678735c2019-09-28 18:23:28 -0400607 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600608
609 actual = [
610 os.path.relpath(path, self.archive_root)
611 for path in osutils.DirectoryIterator(self.archive_root)
612 ]
Mike Frysinger678735c2019-09-28 18:23:28 -0400613 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600614
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600615 def testBundleTestUpdatePayloadsNoImageDir(self):
616 """BundleTestUpdatePayloads dies if no image dir is found."""
617 # Intentionally do not write image directory.
Alex Kleind2bf1462019-10-24 16:37:04 -0600618 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
619 self.api_config)
620 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600621
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600622 def testBundleTestUpdatePayloadsNoImage(self):
623 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600624 # Intentionally do not write image, but create the directory.
625 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600626 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600627 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
628 self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600629
630
Alex Klein231d2da2019-07-22 16:44:45 -0600631class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase,
632 api_config.ApiConfigMixin):
Alex Klein2275d692019-04-23 16:04:12 -0600633 """BundleSimpleChromeArtifacts tests."""
634
635 def setUp(self):
636 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
637 self.sysroot_path = '/sysroot'
638 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
639 osutils.SafeMakedirs(self.sysroot_dir)
640 self.output_dir = os.path.join(self.tempdir, 'output_dir')
641 osutils.SafeMakedirs(self.output_dir)
642
643 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
644
Alex Klein231d2da2019-07-22 16:44:45 -0600645 self.response = artifacts_pb2.BundleResponse()
646
Alex Klein2275d692019-04-23 16:04:12 -0600647 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
648 output_dir=None):
649 """Helper to create a request message instance.
650
651 Args:
652 chroot (str): The chroot path.
653 sysroot (str): The sysroot path.
654 build_target (str): The build target name.
655 output_dir (str): The output directory.
656 """
657 return artifacts_pb2.BundleRequest(
658 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
659 chroot={'path': chroot}, output_dir=output_dir)
660
Alex Klein231d2da2019-07-22 16:44:45 -0600661 def testValidateOnly(self):
662 """Sanity check that a validate only call does not execute any logic."""
663 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
664 request = self._GetRequest(chroot=self.chroot_dir,
665 sysroot=self.sysroot_path,
666 build_target='board', output_dir=self.output_dir)
667 artifacts.BundleSimpleChromeArtifacts(request, self.response,
668 self.validate_only_config)
669 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600670
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700671 def testMockCall(self):
672 """Test that a mock call does not execute logic, returns mocked value."""
673 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
674 request = self._GetRequest(chroot=self.chroot_dir,
675 sysroot=self.sysroot_path,
676 build_target='board', output_dir=self.output_dir)
677 artifacts.BundleSimpleChromeArtifacts(request, self.response,
678 self.mock_call_config)
679 patch.assert_not_called()
680 self.assertEqual(len(self.response.artifacts), 1)
681 self.assertEqual(self.response.artifacts[0].path,
682 os.path.join(self.output_dir, 'simple_chrome.txt'))
683
Alex Klein2275d692019-04-23 16:04:12 -0600684 def testNoBuildTarget(self):
685 """Test no build target fails."""
686 request = self._GetRequest(chroot=self.chroot_dir,
687 sysroot=self.sysroot_path,
688 output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600689 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600690 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600691 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600692
693 def testNoSysroot(self):
694 """Test no sysroot fails."""
695 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600696 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600697 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600698 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600699
700 def testSysrootDoesNotExist(self):
701 """Test no sysroot fails."""
702 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
703 sysroot=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600704 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600705 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600706 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600707
708 def testNoOutputDir(self):
709 """Test no output dir fails."""
710 request = self._GetRequest(chroot=self.chroot_dir,
711 sysroot=self.sysroot_path,
712 build_target='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600713 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600714 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600715 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600716
717 def testOutputDirDoesNotExist(self):
718 """Test no output dir fails."""
719 request = self._GetRequest(chroot=self.chroot_dir,
720 sysroot=self.sysroot_path,
721 build_target='board',
722 output_dir=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600723 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600724 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600725 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600726
727 def testOutputHandling(self):
728 """Test response output."""
729 files = ['file1', 'file2', 'file3']
730 expected_files = [os.path.join(self.output_dir, f) for f in files]
731 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
732 return_value=expected_files)
733 request = self._GetRequest(chroot=self.chroot_dir,
734 sysroot=self.sysroot_path,
735 build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600736 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600737
Alex Klein231d2da2019-07-22 16:44:45 -0600738 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600739
740 self.assertTrue(response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -0400741 self.assertCountEqual(expected_files, [a.path for a in response.artifacts])
Alex Klein2275d692019-04-23 16:04:12 -0600742
743
Alex Klein231d2da2019-07-22 16:44:45 -0600744class BundleVmFilesTest(cros_test_lib.MockTempDirTestCase,
745 api_config.ApiConfigMixin):
Alex Klein6504eca2019-04-18 15:37:56 -0600746 """BuildVmFiles tests."""
747
Alex Klein231d2da2019-07-22 16:44:45 -0600748 def setUp(self):
749 self.output_dir = os.path.join(self.tempdir, 'output')
750 osutils.SafeMakedirs(self.output_dir)
751
752 self.response = artifacts_pb2.BundleResponse()
753
Alex Klein6504eca2019-04-18 15:37:56 -0600754 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
755 output_dir=None):
756 """Helper to build out an input message instance.
757
758 Args:
759 chroot (str|None): The chroot path.
760 sysroot (str|None): The sysroot path relative to the chroot.
761 test_results_dir (str|None): The test results directory relative to the
762 sysroot.
763 output_dir (str|None): The directory where the results tarball should be
764 saved.
765 """
766 return artifacts_pb2.BundleVmFilesRequest(
767 chroot={'path': chroot}, sysroot={'path': sysroot},
768 test_results_dir=test_results_dir, output_dir=output_dir,
769 )
770
Alex Klein231d2da2019-07-22 16:44:45 -0600771 def testValidateOnly(self):
772 """Sanity check that a validate only call does not execute any logic."""
773 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
774 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
775 test_results_dir='/test/results',
776 output_dir=self.output_dir)
777 artifacts.BundleVmFiles(in_proto, self.response, self.validate_only_config)
778 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600779
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700780 def testMockCall(self):
781 """Test that a mock call does not execute logic, returns mocked value."""
782 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
783 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
784 test_results_dir='/test/results',
785 output_dir=self.output_dir)
786 artifacts.BundleVmFiles(in_proto, self.response, self.mock_call_config)
787 patch.assert_not_called()
788 self.assertEqual(len(self.response.artifacts), 1)
789 self.assertEqual(self.response.artifacts[0].path,
790 os.path.join(self.output_dir, 'f1.tar'))
791
Alex Klein6504eca2019-04-18 15:37:56 -0600792 def testChrootMissing(self):
793 """Test error handling for missing chroot."""
794 in_proto = self._GetInput(sysroot='/build/board',
795 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600796 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600797
798 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600799 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600800
Alex Klein6504eca2019-04-18 15:37:56 -0600801 def testTestResultsDirMissing(self):
802 """Test error handling for missing test results directory."""
803 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
Alex Klein231d2da2019-07-22 16:44:45 -0600804 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600805
806 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600807 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600808
809 def testOutputDirMissing(self):
810 """Test error handling for missing output directory."""
811 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
812 test_results_dir='/test/results')
Alex Klein6504eca2019-04-18 15:37:56 -0600813
814 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600815 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
816
817 def testOutputDirDoesNotExist(self):
818 """Test error handling for output directory that does not exist."""
819 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
820 output_dir=os.path.join(self.tempdir, 'dne'),
821 test_results_dir='/test/results')
822
823 with self.assertRaises(cros_build_lib.DieSystemExit):
824 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600825
826 def testValidCall(self):
827 """Test image dir building."""
828 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
829 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600830 output_dir=self.output_dir)
831
Alex Klein6504eca2019-04-18 15:37:56 -0600832 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600833 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600834 return_value=expected_files)
835
Alex Klein231d2da2019-07-22 16:44:45 -0600836 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600837
Alex Klein231d2da2019-07-22 16:44:45 -0600838 patch.assert_called_with(mock.ANY, '/test/results', self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600839
840 # Make sure we have artifacts, and that every artifact is an expected file.
Alex Klein231d2da2019-07-22 16:44:45 -0600841 self.assertTrue(self.response.artifacts)
842 for artifact in self.response.artifacts:
Alex Klein6504eca2019-04-18 15:37:56 -0600843 self.assertIn(artifact.path, expected_files)
844 expected_files.remove(artifact.path)
845
846 # Make sure we've seen all of the expected files.
847 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700848
Alex Kleinb9d810b2019-07-01 12:38:02 -0600849
Tiancong Wang50b80a92019-08-01 14:46:15 -0700850
851class BundleAFDOGenerationArtifactsTestCase(
Alex Klein231d2da2019-07-22 16:44:45 -0600852 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700853 """Unittests for BundleAFDOGenerationArtifacts."""
854
855 @staticmethod
856 def mock_die(message, *args):
857 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700858
859 def setUp(self):
860 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
861 osutils.SafeMakedirs(self.chroot_dir)
862 temp_dir = os.path.join(self.chroot_dir, 'tmp')
863 osutils.SafeMakedirs(temp_dir)
864 self.output_dir = os.path.join(self.tempdir, 'output_dir')
865 osutils.SafeMakedirs(self.output_dir)
Tiancong Wang2ade7932019-09-27 14:15:40 -0700866 self.chrome_root = os.path.join(self.tempdir, 'chrome_root')
867 osutils.SafeMakedirs(self.chrome_root)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700868 self.build_target = 'board'
Tiancong Wang24a3df72019-08-20 15:48:51 -0700869 self.valid_artifact_type = toolchain_pb2.ORDERFILE
870 self.invalid_artifact_type = toolchain_pb2.NONE_TYPE
Tiancong Wangc4805b72019-06-11 12:12:03 -0700871 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700872 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700873
Alex Klein231d2da2019-07-22 16:44:45 -0600874 self.response = artifacts_pb2.BundleResponse()
875
Tiancong Wang2ade7932019-09-27 14:15:40 -0700876 def _GetRequest(self, chroot=None, build_target=None, chrome_root=None,
877 output_dir=None, artifact_type=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700878 """Helper to create a request message instance.
879
880 Args:
881 chroot (str): The chroot path.
882 build_target (str): The build target name.
Tiancong Wang2ade7932019-09-27 14:15:40 -0700883 chrome_root (str): The path to Chrome root.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700884 output_dir (str): The output directory.
Tiancong Wang50b80a92019-08-01 14:46:15 -0700885 artifact_type (artifacts_pb2.AFDOArtifactType):
886 The type of the artifact.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700887 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700888 return artifacts_pb2.BundleChromeAFDORequest(
Tiancong Wang2ade7932019-09-27 14:15:40 -0700889 chroot={'path': chroot, 'chrome_dir': chrome_root},
Tiancong Wang50b80a92019-08-01 14:46:15 -0700890 build_target={'name': build_target},
891 output_dir=output_dir,
892 artifact_type=artifact_type,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700893 )
894
Alex Klein231d2da2019-07-22 16:44:45 -0600895 def testValidateOnly(self):
896 """Sanity check that a validate only call does not execute any logic."""
897 patch = self.PatchObject(artifacts_svc,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700898 'BundleAFDOGenerationArtifacts')
Alex Klein231d2da2019-07-22 16:44:45 -0600899 request = self._GetRequest(chroot=self.chroot_dir,
900 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700901 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700902 output_dir=self.output_dir,
903 artifact_type=self.valid_artifact_type)
904 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
905 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600906 patch.assert_not_called()
Tiancong Wangc4805b72019-06-11 12:12:03 -0700907
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700908 def testMockCall(self):
909 """Test that a mock call does not execute logic, returns mocked value."""
910 patch = self.PatchObject(artifacts_svc,
911 'BundleAFDOGenerationArtifacts')
912 request = self._GetRequest(chroot=self.chroot_dir,
913 build_target=self.build_target,
914 chrome_root=self.chrome_root,
915 output_dir=self.output_dir,
916 artifact_type=self.valid_artifact_type)
917 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
918 self.mock_call_config)
919 patch.assert_not_called()
920 self.assertEqual(len(self.response.artifacts), 1)
921 self.assertEqual(self.response.artifacts[0].path,
922 os.path.join(self.output_dir, 'artifact1'))
923
Tiancong Wangc4805b72019-06-11 12:12:03 -0700924 def testNoBuildTarget(self):
925 """Test no build target fails."""
926 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700927 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700928 output_dir=self.output_dir,
929 artifact_type=self.valid_artifact_type)
930 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
931 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
932 self.api_config)
933 self.assertEqual('build_target.name is required.',
934 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700935
Tiancong Wang2ade7932019-09-27 14:15:40 -0700936 def testNoChromeRoot(self):
937 """Test no chrome root fails."""
938 request = self._GetRequest(chroot=self.chroot_dir,
939 build_target=self.build_target,
940 output_dir=self.output_dir,
941 artifact_type=self.valid_artifact_type)
942 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
943 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
944 self.api_config)
945 self.assertEqual('chroot.chrome_dir path does not exist: ',
946 str(context.exception))
947
Tiancong Wangc4805b72019-06-11 12:12:03 -0700948 def testNoOutputDir(self):
949 """Test no output dir fails."""
950 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700951 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700952 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700953 artifact_type=self.valid_artifact_type)
954 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
955 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
956 self.api_config)
957 self.assertEqual('output_dir is required.',
958 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700959
960 def testOutputDirDoesNotExist(self):
961 """Test output directory not existing fails."""
962 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700963 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700964 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700965 output_dir=self.does_not_exist,
966 artifact_type=self.valid_artifact_type)
967 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
968 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
969 self.api_config)
970 self.assertEqual(
971 'output_dir path does not exist: %s' % self.does_not_exist,
972 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700973
Tiancong Wang50b80a92019-08-01 14:46:15 -0700974 def testNoArtifactType(self):
975 """Test no artifact type."""
976 request = self._GetRequest(chroot=self.chroot_dir,
977 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700978 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700979 output_dir=self.output_dir)
980 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
981 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
982 self.api_config)
983 self.assertIn('artifact_type (0) must be in',
984 str(context.exception))
985
986 def testWrongArtifactType(self):
987 """Test passing wrong artifact type."""
988 request = self._GetRequest(chroot=self.chroot_dir,
989 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700990 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700991 output_dir=self.output_dir,
992 artifact_type=self.invalid_artifact_type)
993 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
994 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
995 self.api_config)
Tiancong Wang24a3df72019-08-20 15:48:51 -0700996 self.assertIn('artifact_type (%d) must be in' % self.invalid_artifact_type,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700997 str(context.exception))
998
999 def testOutputHandlingOnOrderfile(self,
Tiancong Wang24a3df72019-08-20 15:48:51 -07001000 artifact_type=toolchain_pb2.ORDERFILE):
Tiancong Wang50b80a92019-08-01 14:46:15 -07001001 """Test response output for orderfile."""
1002 files = ['artifact1', 'artifact2', 'artifact3']
Tiancong Wangc4805b72019-06-11 12:12:03 -07001003 expected_files = [os.path.join(self.output_dir, f) for f in files]
Tiancong Wang50b80a92019-08-01 14:46:15 -07001004 self.PatchObject(artifacts_svc, 'BundleAFDOGenerationArtifacts',
Tiancong Wangc4805b72019-06-11 12:12:03 -07001005 return_value=expected_files)
Alex Klein231d2da2019-07-22 16:44:45 -06001006
Tiancong Wangc4805b72019-06-11 12:12:03 -07001007 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -07001008 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001009 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001010 output_dir=self.output_dir,
1011 artifact_type=artifact_type)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001012
Tiancong Wang50b80a92019-08-01 14:46:15 -07001013 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1014 self.api_config)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001015
Tiancong Wang50b80a92019-08-01 14:46:15 -07001016 self.assertTrue(self.response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -04001017 self.assertCountEqual(expected_files,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001018 [a.path for a in self.response.artifacts])
1019
1020 def testOutputHandlingOnAFDO(self):
1021 """Test response output for AFDO."""
1022 self.testOutputHandlingOnOrderfile(
Tiancong Wang24a3df72019-08-20 15:48:51 -07001023 artifact_type=toolchain_pb2.BENCHMARK_AFDO)
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001024
1025
1026class ExportCpeReportTest(cros_test_lib.MockTempDirTestCase,
1027 api_config.ApiConfigMixin):
1028 """ExportCpeReport tests."""
1029
1030 def setUp(self):
1031 self.response = artifacts_pb2.BundleResponse()
1032
1033 def testValidateOnly(self):
1034 """Sanity check validate only calls don't execute."""
1035 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1036
1037 request = artifacts_pb2.BundleRequest()
1038 request.build_target.name = 'board'
1039 request.output_dir = self.tempdir
1040
1041 artifacts.ExportCpeReport(request, self.response, self.validate_only_config)
1042
1043 patch.assert_not_called()
1044
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001045 def testMockCall(self):
1046 """Test that a mock call does not execute logic, returns mocked value."""
1047 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1048
1049 request = artifacts_pb2.BundleRequest()
1050 request.build_target.name = 'board'
1051 request.output_dir = self.tempdir
1052
1053 artifacts.ExportCpeReport(request, self.response, self.mock_call_config)
1054
1055 patch.assert_not_called()
1056 self.assertEqual(len(self.response.artifacts), 2)
1057 self.assertEqual(self.response.artifacts[0].path,
1058 os.path.join(self.tempdir, 'cpe_report.txt'))
1059 self.assertEqual(self.response.artifacts[1].path,
1060 os.path.join(self.tempdir, 'cpe_warnings.txt'))
1061
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001062 def testNoBuildTarget(self):
1063 request = artifacts_pb2.BundleRequest()
1064 request.output_dir = self.tempdir
1065
1066 with self.assertRaises(cros_build_lib.DieSystemExit):
1067 artifacts.ExportCpeReport(request, self.response, self.api_config)
1068
1069 def testSuccess(self):
1070 """Test success case."""
1071 expected = artifacts_svc.CpeResult(
1072 report='/output/report.json', warnings='/output/warnings.json')
1073 self.PatchObject(artifacts_svc, 'GenerateCpeReport', return_value=expected)
1074
1075 request = artifacts_pb2.BundleRequest()
1076 request.build_target.name = 'board'
1077 request.output_dir = self.tempdir
1078
1079 artifacts.ExportCpeReport(request, self.response, self.api_config)
1080
1081 for artifact in self.response.artifacts:
1082 self.assertIn(artifact.path, [expected.report, expected.warnings])
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001083
1084
1085class BundleGceTarballTest(BundleTestCase):
1086 """Unittests for BundleGceTarball."""
1087
1088 def testValidateOnly(self):
1089 """Check that a validate only call does not execute any logic."""
1090 patch = self.PatchObject(artifacts_svc, 'BundleGceTarball')
1091 artifacts.BundleGceTarball(self.target_request, self.response,
1092 self.validate_only_config)
1093 patch.assert_not_called()
1094
1095 def testMockCall(self):
1096 """Test that a mock call does not execute logic, returns mocked value."""
1097 patch = self.PatchObject(artifacts_svc, 'BundleGceTarball')
1098 artifacts.BundleGceTarball(self.target_request, self.response,
1099 self.mock_call_config)
1100 patch.assert_not_called()
1101 self.assertEqual(len(self.response.artifacts), 1)
1102 self.assertEqual(self.response.artifacts[0].path,
1103 os.path.join(self.output_dir,
1104 constants.TEST_IMAGE_GCE_TAR))
1105
1106 def testBundleGceTarball(self):
1107 """BundleGceTarball calls cbuildbot/commands with correct args."""
1108 bundle_gce_tarball = self.PatchObject(
1109 artifacts_svc, 'BundleGceTarball',
1110 return_value=os.path.join(self.output_dir,
1111 constants.TEST_IMAGE_GCE_TAR))
1112 self.PatchObject(os.path, 'exists', return_value=True)
1113 artifacts.BundleGceTarball(self.target_request, self.response,
1114 self.api_config)
1115 self.assertEqual(
1116 [artifact.path for artifact in self.response.artifacts],
1117 [os.path.join(self.output_dir, constants.TEST_IMAGE_GCE_TAR)])
1118
1119 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
1120 self.assertEqual(
1121 bundle_gce_tarball.call_args_list,
1122 [mock.call(self.output_dir, latest)])
1123
1124 def testBundleGceTarballNoImageDir(self):
1125 """BundleGceTarball dies when image dir does not exist."""
1126 self.PatchObject(os.path, 'exists', return_value=False)
1127 with self.assertRaises(cros_build_lib.DieSystemExit):
1128 artifacts.BundleGceTarball(self.target_request, self.response,
1129 self.api_config)
Michael Mortensen6667b542020-12-12 11:09:55 -07001130
1131
1132class BundleDebugSymbolsTest(BundleTestCase):
1133 """Unittests for BundleDebugSymbols."""
1134
1135 def setUp(self):
1136 # Create a chroot_path that also includes a chroot tmp dir.
1137 self.chroot_path = os.path.join(self.tempdir, 'chroot_dir')
1138 osutils.SafeMakedirs(self.chroot_path)
1139 osutils.SafeMakedirs(os.path.join(self.chroot_path, 'tmp'))
1140 # Create output dir.
1141 output_dir = os.path.join(self.tempdir, 'output_dir')
1142 osutils.SafeMakedirs(output_dir)
1143 # Build target request.
1144 self.target_request = self.BuildTargetRequest(
1145 build_target='target',
1146 output_dir=self.output_dir,
1147 chroot=self.chroot_path)
1148
1149 def testValidateOnly(self):
1150 """Check that a validate only call does not execute any logic."""
1151 patch = self.PatchObject(artifacts_svc, 'GenerateBreakpadSymbols')
1152 artifacts.BundleDebugSymbols(self.target_request, self.response,
1153 self.validate_only_config)
1154 patch.assert_not_called()
1155
1156 def testMockCall(self):
1157 """Test that a mock call does not execute logic, returns mocked value."""
1158 patch = self.PatchObject(artifacts_svc, 'GenerateBreakpadSymbols')
1159 artifacts.BundleDebugSymbols(self.target_request, self.response,
1160 self.mock_call_config)
1161 patch.assert_not_called()
1162 self.assertEqual(len(self.response.artifacts), 1)
1163 self.assertEqual(self.response.artifacts[0].path,
1164 os.path.join(self.output_dir,
1165 constants.DEBUG_SYMBOLS_TAR))
1166
1167 def testBundleDebugSymbols(self):
1168 """BundleDebugSymbols calls cbuildbot/commands with correct args."""
1169 # Patch service layer functions.
1170 generate_breakpad_symbols_patch = self.PatchObject(
1171 artifacts_svc, 'GenerateBreakpadSymbols',
1172 return_value=cros_build_lib.CommandResult(returncode=0, output=''))
1173 gather_symbol_files_patch = self.PatchObject(
1174 artifacts_svc, 'GatherSymbolFiles',
1175 return_value=[artifacts_svc.SymbolFileTuple(
1176 source_file_name='path/to/source/file1.sym',
1177 relative_path='file1.sym')])
1178
1179 artifacts.BundleDebugSymbols(self.target_request, self.response,
1180 self.api_config)
1181 # Verify mock objects were called.
Michael Mortensen7da39cc2021-03-09 10:28:45 -07001182 build_target = build_target_lib.BuildTarget('target')
1183 generate_breakpad_symbols_patch.assert_called_with(
1184 mock.ANY, build_target, debug=True)
Michael Mortensen6667b542020-12-12 11:09:55 -07001185 gather_symbol_files_patch.assert_called()
1186
1187 # Verify response proto contents and output directory contents.
1188 self.assertEqual(
1189 [artifact.path for artifact in self.response.artifacts],
1190 [os.path.join(self.output_dir, constants.DEBUG_SYMBOLS_TAR)])
1191 files = os.listdir(self.output_dir)
1192 self.assertEqual(files, [constants.DEBUG_SYMBOLS_TAR])
1193
1194 def testBundleGceTarballNoImageDir(self):
1195 """BundleDebugSymbols dies when image dir does not exist."""
1196 self.PatchObject(os.path, 'exists', return_value=False)
1197 with self.assertRaises(cros_build_lib.DieSystemExit):
1198 artifacts.BundleDebugSymbols(self.target_request, self.response,
1199 self.api_config)