blob: 0a063a504a159ed1694363c6e44828c7fb843203 [file] [log] [blame]
Evan Hernandezf388cbf2019-04-01 11:15:23 -06001# -*- coding: utf-8 -*-
2# Copyright 2019 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Unittests for Artifacts operations."""
7
8from __future__ import print_function
9
Evan Hernandezf388cbf2019-04-01 11:15:23 -060010import os
11
Mike Frysinger6db648e2018-07-24 19:57:58 -040012import mock
13
Alex Klein231d2da2019-07-22 16:44:45 -060014from chromite.api import api_config
Evan Hernandezf388cbf2019-04-01 11:15:23 -060015from chromite.api.controller import artifacts
16from chromite.api.gen.chromite.api import artifacts_pb2
Tiancong Wang24a3df72019-08-20 15:48:51 -070017from chromite.api.gen.chromite.api import toolchain_pb2
Evan Hernandezf388cbf2019-04-01 11:15:23 -060018from chromite.cbuildbot import commands
Michael Mortensen7da39cc2021-03-09 10:28:45 -070019from chromite.lib import build_target_lib
Alex Kleinb9d810b2019-07-01 12:38:02 -060020from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060021from chromite.lib import constants
22from chromite.lib import cros_build_lib
23from chromite.lib import cros_test_lib
24from chromite.lib import osutils
Alex Klein238d8862019-05-07 11:32:46 -060025from chromite.lib import sysroot_lib
Alex Klein2275d692019-04-23 16:04:12 -060026from chromite.service import artifacts as artifacts_svc
Evan Hernandezf388cbf2019-04-01 11:15:23 -060027
28
Alex Kleind91e95a2019-09-17 10:39:02 -060029class BundleRequestMixin(object):
30 """Mixin to provide bundle request methods."""
31
32 def EmptyRequest(self):
33 return artifacts_pb2.BundleRequest()
34
35 def BuildTargetRequest(self, build_target=None, output_dir=None, chroot=None):
36 """Get a build target format request instance."""
37 request = self.EmptyRequest()
38 if build_target:
39 request.build_target.name = build_target
40 if output_dir:
41 request.output_dir = output_dir
42 if chroot:
43 request.chroot.path = chroot
44
45 return request
46
47 def SysrootRequest(self,
48 sysroot=None,
49 build_target=None,
50 output_dir=None,
51 chroot=None):
52 """Get a sysroot format request instance."""
53 request = self.EmptyRequest()
54 if sysroot:
55 request.sysroot.path = sysroot
56 if build_target:
57 request.sysroot.build_target.name = build_target
58 if output_dir:
59 request.output_dir = output_dir
60 if chroot:
61 request.chroot.path = chroot
62
63 return request
64
65
Alex Klein231d2da2019-07-22 16:44:45 -060066class BundleTestCase(cros_test_lib.MockTempDirTestCase,
Alex Kleind91e95a2019-09-17 10:39:02 -060067 api_config.ApiConfigMixin, BundleRequestMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060068 """Basic setup for all artifacts unittests."""
69
70 def setUp(self):
Alex Klein231d2da2019-07-22 16:44:45 -060071 self.output_dir = os.path.join(self.tempdir, 'artifacts')
72 osutils.SafeMakedirs(self.output_dir)
73 self.sysroot_path = '/build/target'
Alex Klein68c8fdf2019-09-25 15:09:11 -060074 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -060075 self.chroot_path = os.path.join(self.tempdir, 'chroot')
76 full_sysroot_path = os.path.join(self.chroot_path,
77 self.sysroot_path.lstrip(os.sep))
78 osutils.SafeMakedirs(full_sysroot_path)
79
Alex Klein68c8fdf2019-09-25 15:09:11 -060080 # All requests use same response type.
Alex Klein231d2da2019-07-22 16:44:45 -060081 self.response = artifacts_pb2.BundleResponse()
82
Alex Klein68c8fdf2019-09-25 15:09:11 -060083 # Build target request.
84 self.target_request = self.BuildTargetRequest(
85 build_target='target',
86 output_dir=self.output_dir,
87 chroot=self.chroot_path)
88
89 # Sysroot request.
90 self.sysroot_request = self.SysrootRequest(
91 sysroot=self.sysroot_path,
92 build_target='target',
93 output_dir=self.output_dir,
94 chroot=self.chroot_path)
95
Alex Klein231d2da2019-07-22 16:44:45 -060096 self.source_root = self.tempdir
97 self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -060098
99
Alex Kleind91e95a2019-09-17 10:39:02 -0600100class BundleImageArchivesTest(BundleTestCase):
101 """BundleImageArchives tests."""
102
103 def testValidateOnly(self):
104 """Sanity check that a validate only call does not execute any logic."""
105 patch = self.PatchObject(artifacts_svc, 'ArchiveImages')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600106 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600107 self.validate_only_config)
108 patch.assert_not_called()
109
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700110 def testMockCall(self):
111 """Test that a mock call does not execute logic, returns mocked value."""
112 patch = self.PatchObject(artifacts_svc, 'ArchiveImages')
113 artifacts.BundleImageArchives(self.target_request, self.response,
114 self.mock_call_config)
115 patch.assert_not_called()
116 self.assertEqual(len(self.response.artifacts), 2)
117 self.assertEqual(self.response.artifacts[0].path,
118 os.path.join(self.output_dir, 'path0.tar.xz'))
119 self.assertEqual(self.response.artifacts[1].path,
120 os.path.join(self.output_dir, 'path1.tar.xz'))
121
Alex Kleind91e95a2019-09-17 10:39:02 -0600122 def testNoBuildTarget(self):
123 """Test that no build target fails."""
124 request = self.BuildTargetRequest(output_dir=self.tempdir)
125 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600126 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600127
128 def testNoOutputDir(self):
129 """Test no output dir fails."""
130 request = self.BuildTargetRequest(build_target='board')
131 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600132 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600133
134 def testInvalidOutputDir(self):
135 """Test invalid output dir fails."""
136 request = self.BuildTargetRequest(
137 build_target='board', output_dir=os.path.join(self.tempdir, 'DNE'))
138 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600139 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600140
141 def testOutputHandling(self):
142 """Test the artifact output handling."""
143 expected = [os.path.join(self.output_dir, f) for f in ('a', 'b', 'c')]
144 self.PatchObject(artifacts_svc, 'ArchiveImages', return_value=expected)
145 self.PatchObject(os.path, 'exists', return_value=True)
146
Alex Klein68c8fdf2019-09-25 15:09:11 -0600147 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600148 self.api_config)
149
Mike Frysinger678735c2019-09-28 18:23:28 -0400150 self.assertCountEqual(expected, [a.path for a in self.response.artifacts])
Alex Kleind91e95a2019-09-17 10:39:02 -0600151
152
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600153class BundleImageZipTest(BundleTestCase):
154 """Unittests for BundleImageZip."""
155
Alex Klein231d2da2019-07-22 16:44:45 -0600156 def testValidateOnly(self):
157 """Sanity check that a validate only call does not execute any logic."""
158 patch = self.PatchObject(commands, 'BuildImageZip')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600159 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600160 self.validate_only_config)
161 patch.assert_not_called()
162
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700163 def testMockCall(self):
164 """Test that a mock call does not execute logic, returns mocked value."""
165 patch = self.PatchObject(commands, 'BuildImageZip')
166 artifacts.BundleImageZip(self.target_request, self.response,
167 self.mock_call_config)
168 patch.assert_not_called()
169 self.assertEqual(len(self.response.artifacts), 1)
170 self.assertEqual(self.response.artifacts[0].path,
171 os.path.join(self.output_dir, 'image.zip'))
172
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600173 def testBundleImageZip(self):
174 """BundleImageZip calls cbuildbot/commands with correct args."""
Michael Mortensen01910922019-07-24 14:48:10 -0600175 bundle_image_zip = self.PatchObject(
176 artifacts_svc, 'BundleImageZip', return_value='image.zip')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600177 self.PatchObject(os.path, 'exists', return_value=True)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600178 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600179 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600180 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600181 [artifact.path for artifact in self.response.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600182 [os.path.join(self.output_dir, 'image.zip')])
183
184 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600185 self.assertEqual(
Michael Mortensen01910922019-07-24 14:48:10 -0600186 bundle_image_zip.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600187 [mock.call(self.output_dir, latest)])
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600188
189 def testBundleImageZipNoImageDir(self):
190 """BundleImageZip dies when image dir does not exist."""
191 self.PatchObject(os.path, 'exists', return_value=False)
192 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600193 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600194 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600195
196
Alex Klein68c8fdf2019-09-25 15:09:11 -0600197class BundleAutotestFilesTest(BundleTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600198 """Unittests for BundleAutotestFiles."""
199
Alex Klein231d2da2019-07-22 16:44:45 -0600200 def testValidateOnly(self):
201 """Sanity check that a validate only call does not execute any logic."""
202 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600203 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600204 self.validate_only_config)
205 patch.assert_not_called()
206
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700207 def testMockCall(self):
208 """Test that a mock call does not execute logic, returns mocked value."""
209 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
210 artifacts.BundleAutotestFiles(self.target_request, self.response,
211 self.mock_call_config)
212 patch.assert_not_called()
213 self.assertEqual(len(self.response.artifacts), 1)
214 self.assertEqual(self.response.artifacts[0].path,
215 os.path.join(self.output_dir, 'autotest-a.tar.gz'))
216
Alex Klein238d8862019-05-07 11:32:46 -0600217 def testBundleAutotestFilesLegacy(self):
218 """BundleAutotestFiles calls service correctly with legacy args."""
219 files = {
220 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
221 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
222 }
223 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
224 return_value=files)
225
Alex Klein68c8fdf2019-09-25 15:09:11 -0600226 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600227 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600228
Alex Klein238d8862019-05-07 11:32:46 -0600229 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600230 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600231
232 # Verify the output proto is being populated correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600233 self.assertTrue(self.response.artifacts)
234 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400235 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600236
237 def testBundleAutotestFiles(self):
238 """BundleAutotestFiles calls service correctly."""
239 files = {
240 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
241 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
242 }
243 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
244 return_value=files)
245
Alex Klein68c8fdf2019-09-25 15:09:11 -0600246 artifacts.BundleAutotestFiles(self.sysroot_request, self.response,
247 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600248
249 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600250 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600251
252 # Verify the output proto is being populated correctly.
253 self.assertTrue(self.response.artifacts)
254 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400255 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600256
257 def testInvalidOutputDir(self):
258 """Test invalid output directory argument."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600259 request = self.SysrootRequest(chroot=self.chroot_path,
260 sysroot=self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600261
262 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600263 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600264
265 def testInvalidSysroot(self):
266 """Test no sysroot directory."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600267 request = self.SysrootRequest(chroot=self.chroot_path,
268 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600269
270 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600271 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600272
273 def testSysrootDoesNotExist(self):
274 """Test dies when no sysroot does not exist."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600275 request = self.SysrootRequest(chroot=self.chroot_path,
276 sysroot='/does/not/exist',
277 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600278
279 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600280 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600281
282
283class BundleTastFilesTest(BundleTestCase):
284 """Unittests for BundleTastFiles."""
285
Alex Klein231d2da2019-07-22 16:44:45 -0600286 def testValidateOnly(self):
287 """Sanity check that a validate only call does not execute any logic."""
288 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600289 artifacts.BundleTastFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600290 self.validate_only_config)
291 patch.assert_not_called()
292
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700293 def testMockCall(self):
294 """Test that a mock call does not execute logic, returns mocked value."""
295 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
296 artifacts.BundleTastFiles(self.target_request, self.response,
297 self.mock_call_config)
298 patch.assert_not_called()
299 self.assertEqual(len(self.response.artifacts), 1)
300 self.assertEqual(self.response.artifacts[0].path,
301 os.path.join(self.output_dir, 'tast_bundles.tar.gz'))
302
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600303 def testBundleTastFilesNoLogs(self):
LaMont Jonesb9793cd2020-06-11 08:14:46 -0600304 """BundleTasteFiles succeeds when no tast files found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600305 self.PatchObject(commands, 'BuildTastBundleTarball',
306 return_value=None)
LaMont Jonesb9793cd2020-06-11 08:14:46 -0600307 artifacts.BundleTastFiles(self.target_request, self.response,
308 self.api_config)
309 self.assertEqual(list(self.response.artifacts), [])
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600310
Alex Kleinb9d810b2019-07-01 12:38:02 -0600311 def testBundleTastFilesLegacy(self):
312 """BundleTastFiles handles legacy args correctly."""
313 buildroot = self.tempdir
314 chroot_dir = os.path.join(buildroot, 'chroot')
315 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
316 output_dir = os.path.join(self.tempdir, 'results')
317 osutils.SafeMakedirs(sysroot_path)
318 osutils.SafeMakedirs(output_dir)
319
Alex Klein171da612019-08-06 14:00:42 -0600320 chroot = chroot_lib.Chroot(chroot_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600321 sysroot = sysroot_lib.Sysroot('/build/board')
322
323 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
324 # Patch the service being called.
325 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
326 return_value=expected_archive)
327 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
328
329 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
330 output_dir=output_dir)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600331 artifacts.BundleTastFiles(request, self.response, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600332 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600333 [artifact.path for artifact in self.response.artifacts],
Alex Kleinb9d810b2019-07-01 12:38:02 -0600334 [expected_archive])
335 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
336
337 def testBundleTastFiles(self):
338 """BundleTastFiles calls service correctly."""
Alex Kleinb49be8a2019-12-20 10:23:03 -0700339 chroot = chroot_lib.Chroot(self.chroot_path)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600340
Alex Klein68c8fdf2019-09-25 15:09:11 -0600341 expected_archive = os.path.join(self.output_dir,
342 artifacts_svc.TAST_BUNDLE_NAME)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600343 # Patch the service being called.
344 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
345 return_value=expected_archive)
346
Alex Klein68c8fdf2019-09-25 15:09:11 -0600347 artifacts.BundleTastFiles(self.sysroot_request, self.response,
348 self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600349
350 # Make sure the artifact got recorded successfully.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600351 self.assertTrue(self.response.artifacts)
352 self.assertEqual(expected_archive, self.response.artifacts[0].path)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600353 # Make sure the service got called correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600354 bundle_patch.assert_called_once_with(chroot, self.sysroot, self.output_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600355
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600356
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600357class BundleFirmwareTest(BundleTestCase):
358 """Unittests for BundleFirmware."""
359
Alex Klein231d2da2019-07-22 16:44:45 -0600360 def testValidateOnly(self):
361 """Sanity check that a validate only call does not execute any logic."""
362 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600363 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600364 self.validate_only_config)
365 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000366
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700367 def testMockCall(self):
368 """Test that a mock call does not execute logic, returns mocked value."""
369 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
370 artifacts.BundleFirmware(self.sysroot_request, self.response,
371 self.mock_call_config)
372 patch.assert_not_called()
373 self.assertEqual(len(self.response.artifacts), 1)
374 self.assertEqual(self.response.artifacts[0].path,
375 os.path.join(self.output_dir, 'firmware.tar.gz'))
376
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600377 def testBundleFirmware(self):
378 """BundleFirmware calls cbuildbot/commands with correct args."""
Alex Klein231d2da2019-07-22 16:44:45 -0600379 self.PatchObject(
380 artifacts_svc,
381 'BuildFirmwareArchive',
382 return_value=os.path.join(self.output_dir, 'firmware.tar.gz'))
383
Alex Klein68c8fdf2019-09-25 15:09:11 -0600384 artifacts.BundleFirmware(self.sysroot_request, self.response,
385 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600386 self.assertEqual(
Alex Klein231d2da2019-07-22 16:44:45 -0600387 [artifact.path for artifact in self.response.artifacts],
388 [os.path.join(self.output_dir, 'firmware.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600389
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600390 def testBundleFirmwareNoLogs(self):
391 """BundleFirmware dies when no firmware found."""
392 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
393 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600394 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600395 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600396
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600397
Yicheng Liea1181f2020-09-22 11:51:10 -0700398class BundleFpmcuUnittestsTest(BundleTestCase):
399 """Unittests for BundleFpmcuUnittests."""
400
401 def testValidateOnly(self):
402 """Sanity check that a validate only call does not execute any logic."""
403 patch = self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests')
404 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
405 self.validate_only_config)
406 patch.assert_not_called()
407
408 def testMockCall(self):
409 """Test that a mock call does not execute logic, returns mocked value."""
410 patch = self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests')
411 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
412 self.mock_call_config)
413 patch.assert_not_called()
414 self.assertEqual(len(self.response.artifacts), 1)
415 self.assertEqual(self.response.artifacts[0].path,
416 os.path.join(self.output_dir,
417 'fpmcu_unittests.tar.gz'))
418
419 def testBundleFpmcuUnittests(self):
420 """BundleFpmcuUnittests calls cbuildbot/commands with correct args."""
421 self.PatchObject(
422 artifacts_svc,
423 'BundleFpmcuUnittests',
424 return_value=os.path.join(self.output_dir, 'fpmcu_unittests.tar.gz'))
425 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
426 self.api_config)
427 self.assertEqual(
428 [artifact.path for artifact in self.response.artifacts],
429 [os.path.join(self.output_dir, 'fpmcu_unittests.tar.gz')])
430
431 def testBundleFpmcuUnittestsNoLogs(self):
432 """BundleFpmcuUnittests does not die when no fpmcu unittests found."""
433 self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests',
434 return_value=None)
435 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
436 self.api_config)
437 self.assertFalse(self.response.artifacts)
438
439
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600440class BundleEbuildLogsTest(BundleTestCase):
441 """Unittests for BundleEbuildLogs."""
442
Alex Klein231d2da2019-07-22 16:44:45 -0600443 def testValidateOnly(self):
444 """Sanity check that a validate only call does not execute any logic."""
445 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600446 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600447 self.validate_only_config)
448 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600449
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700450 def testMockCall(self):
451 """Test that a mock call does not execute logic, returns mocked value."""
452 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
453 artifacts.BundleEbuildLogs(self.target_request, self.response,
454 self.mock_call_config)
455 patch.assert_not_called()
456 self.assertEqual(len(self.response.artifacts), 1)
457 self.assertEqual(self.response.artifacts[0].path,
458 os.path.join(self.output_dir, 'ebuild-logs.tar.gz'))
459
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600460 def testBundleEbuildLogs(self):
461 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600462 bundle_ebuild_logs_tarball = self.PatchObject(
463 artifacts_svc, 'BundleEBuildLogsTarball',
464 return_value='ebuild-logs.tar.gz')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600465 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
466 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600467 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600468 [artifact.path for artifact in self.response.artifacts],
Alex Klein68c8fdf2019-09-25 15:09:11 -0600469 [os.path.join(self.output_dir, 'ebuild-logs.tar.gz')])
Evan Hernandeza478d802019-04-08 15:08:24 -0600470 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600471 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600472 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600473
474 def testBundleEBuildLogsOldProto(self):
475 bundle_ebuild_logs_tarball = self.PatchObject(
476 artifacts_svc, 'BundleEBuildLogsTarball',
477 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600478
Alex Klein68c8fdf2019-09-25 15:09:11 -0600479 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600480 self.api_config)
481
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600482 self.assertEqual(
483 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600484 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600485
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600486 def testBundleEbuildLogsNoLogs(self):
487 """BundleEbuildLogs dies when no logs found."""
488 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
489 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600490 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
491 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600492
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600493
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600494class BundleChromeOSConfigTest(BundleTestCase):
495 """Unittests for BundleChromeOSConfig"""
496
497 def testValidateOnly(self):
498 """Sanity check that a validate only call does not execute any logic."""
499 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600500 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600501 self.validate_only_config)
502 patch.assert_not_called()
503
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700504 def testMockCall(self):
505 """Test that a mock call does not execute logic, returns mocked value."""
506 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
507 artifacts.BundleChromeOSConfig(self.target_request, self.response,
508 self.mock_call_config)
509 patch.assert_not_called()
510 self.assertEqual(len(self.response.artifacts), 1)
511 self.assertEqual(self.response.artifacts[0].path,
512 os.path.join(self.output_dir, 'config.yaml'))
513
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600514 def testBundleChromeOSConfigCallWithSysroot(self):
515 """Call with a request that sets sysroot."""
516 bundle_chromeos_config = self.PatchObject(
517 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600518 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600519 self.api_config)
520 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600521 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600522 [os.path.join(self.output_dir, 'config.yaml')])
523
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600524 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600525 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600526
527 def testBundleChromeOSConfigCallWithBuildTarget(self):
528 """Call with a request that sets build_target."""
529 bundle_chromeos_config = self.PatchObject(
530 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600531 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600532 self.api_config)
533
534 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600535 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600536 [os.path.join(self.output_dir, 'config.yaml')])
537
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600538 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600539 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600540
541 def testBundleChromeOSConfigNoConfigFound(self):
542 """An error is raised if the config payload isn't found."""
543 self.PatchObject(artifacts_svc, 'BundleChromeOSConfig', return_value=None)
544
545 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600546 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600547 self.api_config)
548
549
Alex Klein231d2da2019-07-22 16:44:45 -0600550class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase,
551 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600552 """Unittests for BundleTestUpdatePayloads."""
553
554 def setUp(self):
555 self.source_root = os.path.join(self.tempdir, 'cros')
556 osutils.SafeMakedirs(self.source_root)
557
558 self.archive_root = os.path.join(self.tempdir, 'output')
559 osutils.SafeMakedirs(self.archive_root)
560
561 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600562 self.image_root = os.path.join(self.source_root,
563 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600564
565 self.input_proto = artifacts_pb2.BundleRequest()
566 self.input_proto.build_target.name = self.target
567 self.input_proto.output_dir = self.archive_root
568 self.output_proto = artifacts_pb2.BundleResponse()
569
570 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
571
Alex Kleincb541e82019-06-26 15:06:11 -0600572 def MockPayloads(image_path, archive_dir):
573 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
574 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
575 return [os.path.join(archive_dir, 'payload1.bin'),
576 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600577
Alex Kleincb541e82019-06-26 15:06:11 -0600578 self.bundle_patch = self.PatchObject(
579 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600580
Alex Klein231d2da2019-07-22 16:44:45 -0600581 def testValidateOnly(self):
582 """Sanity check that a validate only call does not execute any logic."""
583 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
584 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
585 self.validate_only_config)
586 patch.assert_not_called()
587
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700588 def testMockCall(self):
589 """Test that a mock call does not execute logic, returns mocked value."""
590 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
591 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
592 self.mock_call_config)
593 patch.assert_not_called()
594 self.assertEqual(len(self.output_proto.artifacts), 1)
595 self.assertEqual(self.output_proto.artifacts[0].path,
596 os.path.join(self.archive_root, 'payload1.bin'))
597
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600598 def testBundleTestUpdatePayloads(self):
599 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
600 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
601 osutils.WriteFile(image_path, 'image!', makedirs=True)
602
Alex Klein231d2da2019-07-22 16:44:45 -0600603 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
604 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600605
606 actual = [
607 os.path.relpath(artifact.path, self.archive_root)
608 for artifact in self.output_proto.artifacts
609 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600610 expected = ['payload1.bin', 'payload2.bin']
Mike Frysinger678735c2019-09-28 18:23:28 -0400611 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600612
613 actual = [
614 os.path.relpath(path, self.archive_root)
615 for path in osutils.DirectoryIterator(self.archive_root)
616 ]
Mike Frysinger678735c2019-09-28 18:23:28 -0400617 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600618
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600619 def testBundleTestUpdatePayloadsNoImageDir(self):
620 """BundleTestUpdatePayloads dies if no image dir is found."""
621 # Intentionally do not write image directory.
Alex Kleind2bf1462019-10-24 16:37:04 -0600622 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
623 self.api_config)
624 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600625
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600626 def testBundleTestUpdatePayloadsNoImage(self):
627 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600628 # Intentionally do not write image, but create the directory.
629 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600630 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600631 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
632 self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600633
634
Alex Klein231d2da2019-07-22 16:44:45 -0600635class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase,
636 api_config.ApiConfigMixin):
Alex Klein2275d692019-04-23 16:04:12 -0600637 """BundleSimpleChromeArtifacts tests."""
638
639 def setUp(self):
640 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
641 self.sysroot_path = '/sysroot'
642 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
643 osutils.SafeMakedirs(self.sysroot_dir)
644 self.output_dir = os.path.join(self.tempdir, 'output_dir')
645 osutils.SafeMakedirs(self.output_dir)
646
647 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
648
Alex Klein231d2da2019-07-22 16:44:45 -0600649 self.response = artifacts_pb2.BundleResponse()
650
Alex Klein2275d692019-04-23 16:04:12 -0600651 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
652 output_dir=None):
653 """Helper to create a request message instance.
654
655 Args:
656 chroot (str): The chroot path.
657 sysroot (str): The sysroot path.
658 build_target (str): The build target name.
659 output_dir (str): The output directory.
660 """
661 return artifacts_pb2.BundleRequest(
662 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
663 chroot={'path': chroot}, output_dir=output_dir)
664
Alex Klein231d2da2019-07-22 16:44:45 -0600665 def testValidateOnly(self):
666 """Sanity check that a validate only call does not execute any logic."""
667 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
668 request = self._GetRequest(chroot=self.chroot_dir,
669 sysroot=self.sysroot_path,
670 build_target='board', output_dir=self.output_dir)
671 artifacts.BundleSimpleChromeArtifacts(request, self.response,
672 self.validate_only_config)
673 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600674
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700675 def testMockCall(self):
676 """Test that a mock call does not execute logic, returns mocked value."""
677 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
678 request = self._GetRequest(chroot=self.chroot_dir,
679 sysroot=self.sysroot_path,
680 build_target='board', output_dir=self.output_dir)
681 artifacts.BundleSimpleChromeArtifacts(request, self.response,
682 self.mock_call_config)
683 patch.assert_not_called()
684 self.assertEqual(len(self.response.artifacts), 1)
685 self.assertEqual(self.response.artifacts[0].path,
686 os.path.join(self.output_dir, 'simple_chrome.txt'))
687
Alex Klein2275d692019-04-23 16:04:12 -0600688 def testNoBuildTarget(self):
689 """Test no build target fails."""
690 request = self._GetRequest(chroot=self.chroot_dir,
691 sysroot=self.sysroot_path,
692 output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600693 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600694 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600695 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600696
697 def testNoSysroot(self):
698 """Test no sysroot fails."""
699 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600700 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600701 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600702 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600703
704 def testSysrootDoesNotExist(self):
705 """Test no sysroot fails."""
706 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
707 sysroot=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600708 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600709 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600710 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600711
712 def testNoOutputDir(self):
713 """Test no output dir fails."""
714 request = self._GetRequest(chroot=self.chroot_dir,
715 sysroot=self.sysroot_path,
716 build_target='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600717 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600718 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600719 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600720
721 def testOutputDirDoesNotExist(self):
722 """Test no output dir fails."""
723 request = self._GetRequest(chroot=self.chroot_dir,
724 sysroot=self.sysroot_path,
725 build_target='board',
726 output_dir=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600727 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600728 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600729 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600730
731 def testOutputHandling(self):
732 """Test response output."""
733 files = ['file1', 'file2', 'file3']
734 expected_files = [os.path.join(self.output_dir, f) for f in files]
735 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
736 return_value=expected_files)
737 request = self._GetRequest(chroot=self.chroot_dir,
738 sysroot=self.sysroot_path,
739 build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600740 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600741
Alex Klein231d2da2019-07-22 16:44:45 -0600742 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600743
744 self.assertTrue(response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -0400745 self.assertCountEqual(expected_files, [a.path for a in response.artifacts])
Alex Klein2275d692019-04-23 16:04:12 -0600746
747
Alex Klein231d2da2019-07-22 16:44:45 -0600748class BundleVmFilesTest(cros_test_lib.MockTempDirTestCase,
749 api_config.ApiConfigMixin):
Alex Klein6504eca2019-04-18 15:37:56 -0600750 """BuildVmFiles tests."""
751
Alex Klein231d2da2019-07-22 16:44:45 -0600752 def setUp(self):
753 self.output_dir = os.path.join(self.tempdir, 'output')
754 osutils.SafeMakedirs(self.output_dir)
755
756 self.response = artifacts_pb2.BundleResponse()
757
Alex Klein6504eca2019-04-18 15:37:56 -0600758 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
759 output_dir=None):
760 """Helper to build out an input message instance.
761
762 Args:
763 chroot (str|None): The chroot path.
764 sysroot (str|None): The sysroot path relative to the chroot.
765 test_results_dir (str|None): The test results directory relative to the
766 sysroot.
767 output_dir (str|None): The directory where the results tarball should be
768 saved.
769 """
770 return artifacts_pb2.BundleVmFilesRequest(
771 chroot={'path': chroot}, sysroot={'path': sysroot},
772 test_results_dir=test_results_dir, output_dir=output_dir,
773 )
774
Alex Klein231d2da2019-07-22 16:44:45 -0600775 def testValidateOnly(self):
776 """Sanity check that a validate only call does not execute any logic."""
777 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
778 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
779 test_results_dir='/test/results',
780 output_dir=self.output_dir)
781 artifacts.BundleVmFiles(in_proto, self.response, self.validate_only_config)
782 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600783
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700784 def testMockCall(self):
785 """Test that a mock call does not execute logic, returns mocked value."""
786 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
787 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
788 test_results_dir='/test/results',
789 output_dir=self.output_dir)
790 artifacts.BundleVmFiles(in_proto, self.response, self.mock_call_config)
791 patch.assert_not_called()
792 self.assertEqual(len(self.response.artifacts), 1)
793 self.assertEqual(self.response.artifacts[0].path,
794 os.path.join(self.output_dir, 'f1.tar'))
795
Alex Klein6504eca2019-04-18 15:37:56 -0600796 def testChrootMissing(self):
797 """Test error handling for missing chroot."""
798 in_proto = self._GetInput(sysroot='/build/board',
799 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600800 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600801
802 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600803 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600804
Alex Klein6504eca2019-04-18 15:37:56 -0600805 def testTestResultsDirMissing(self):
806 """Test error handling for missing test results directory."""
807 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
Alex Klein231d2da2019-07-22 16:44:45 -0600808 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600809
810 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600811 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600812
813 def testOutputDirMissing(self):
814 """Test error handling for missing output directory."""
815 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
816 test_results_dir='/test/results')
Alex Klein6504eca2019-04-18 15:37:56 -0600817
818 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600819 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
820
821 def testOutputDirDoesNotExist(self):
822 """Test error handling for output directory that does not exist."""
823 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
824 output_dir=os.path.join(self.tempdir, 'dne'),
825 test_results_dir='/test/results')
826
827 with self.assertRaises(cros_build_lib.DieSystemExit):
828 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600829
830 def testValidCall(self):
831 """Test image dir building."""
832 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
833 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600834 output_dir=self.output_dir)
835
Alex Klein6504eca2019-04-18 15:37:56 -0600836 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600837 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600838 return_value=expected_files)
839
Alex Klein231d2da2019-07-22 16:44:45 -0600840 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600841
Alex Klein231d2da2019-07-22 16:44:45 -0600842 patch.assert_called_with(mock.ANY, '/test/results', self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600843
844 # Make sure we have artifacts, and that every artifact is an expected file.
Alex Klein231d2da2019-07-22 16:44:45 -0600845 self.assertTrue(self.response.artifacts)
846 for artifact in self.response.artifacts:
Alex Klein6504eca2019-04-18 15:37:56 -0600847 self.assertIn(artifact.path, expected_files)
848 expected_files.remove(artifact.path)
849
850 # Make sure we've seen all of the expected files.
851 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700852
Alex Kleinb9d810b2019-07-01 12:38:02 -0600853
Tiancong Wang50b80a92019-08-01 14:46:15 -0700854
855class BundleAFDOGenerationArtifactsTestCase(
Alex Klein231d2da2019-07-22 16:44:45 -0600856 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700857 """Unittests for BundleAFDOGenerationArtifacts."""
858
859 @staticmethod
860 def mock_die(message, *args):
861 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700862
863 def setUp(self):
864 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
865 osutils.SafeMakedirs(self.chroot_dir)
866 temp_dir = os.path.join(self.chroot_dir, 'tmp')
867 osutils.SafeMakedirs(temp_dir)
868 self.output_dir = os.path.join(self.tempdir, 'output_dir')
869 osutils.SafeMakedirs(self.output_dir)
Tiancong Wang2ade7932019-09-27 14:15:40 -0700870 self.chrome_root = os.path.join(self.tempdir, 'chrome_root')
871 osutils.SafeMakedirs(self.chrome_root)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700872 self.build_target = 'board'
Tiancong Wang24a3df72019-08-20 15:48:51 -0700873 self.valid_artifact_type = toolchain_pb2.ORDERFILE
874 self.invalid_artifact_type = toolchain_pb2.NONE_TYPE
Tiancong Wangc4805b72019-06-11 12:12:03 -0700875 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700876 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700877
Alex Klein231d2da2019-07-22 16:44:45 -0600878 self.response = artifacts_pb2.BundleResponse()
879
Tiancong Wang2ade7932019-09-27 14:15:40 -0700880 def _GetRequest(self, chroot=None, build_target=None, chrome_root=None,
881 output_dir=None, artifact_type=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700882 """Helper to create a request message instance.
883
884 Args:
885 chroot (str): The chroot path.
886 build_target (str): The build target name.
Tiancong Wang2ade7932019-09-27 14:15:40 -0700887 chrome_root (str): The path to Chrome root.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700888 output_dir (str): The output directory.
Tiancong Wang50b80a92019-08-01 14:46:15 -0700889 artifact_type (artifacts_pb2.AFDOArtifactType):
890 The type of the artifact.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700891 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700892 return artifacts_pb2.BundleChromeAFDORequest(
Tiancong Wang2ade7932019-09-27 14:15:40 -0700893 chroot={'path': chroot, 'chrome_dir': chrome_root},
Tiancong Wang50b80a92019-08-01 14:46:15 -0700894 build_target={'name': build_target},
895 output_dir=output_dir,
896 artifact_type=artifact_type,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700897 )
898
Alex Klein231d2da2019-07-22 16:44:45 -0600899 def testValidateOnly(self):
900 """Sanity check that a validate only call does not execute any logic."""
901 patch = self.PatchObject(artifacts_svc,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700902 'BundleAFDOGenerationArtifacts')
Alex Klein231d2da2019-07-22 16:44:45 -0600903 request = self._GetRequest(chroot=self.chroot_dir,
904 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700905 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700906 output_dir=self.output_dir,
907 artifact_type=self.valid_artifact_type)
908 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
909 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600910 patch.assert_not_called()
Tiancong Wangc4805b72019-06-11 12:12:03 -0700911
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700912 def testMockCall(self):
913 """Test that a mock call does not execute logic, returns mocked value."""
914 patch = self.PatchObject(artifacts_svc,
915 'BundleAFDOGenerationArtifacts')
916 request = self._GetRequest(chroot=self.chroot_dir,
917 build_target=self.build_target,
918 chrome_root=self.chrome_root,
919 output_dir=self.output_dir,
920 artifact_type=self.valid_artifact_type)
921 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
922 self.mock_call_config)
923 patch.assert_not_called()
924 self.assertEqual(len(self.response.artifacts), 1)
925 self.assertEqual(self.response.artifacts[0].path,
926 os.path.join(self.output_dir, 'artifact1'))
927
Tiancong Wangc4805b72019-06-11 12:12:03 -0700928 def testNoBuildTarget(self):
929 """Test no build target fails."""
930 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700931 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700932 output_dir=self.output_dir,
933 artifact_type=self.valid_artifact_type)
934 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
935 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
936 self.api_config)
937 self.assertEqual('build_target.name is required.',
938 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700939
Tiancong Wang2ade7932019-09-27 14:15:40 -0700940 def testNoChromeRoot(self):
941 """Test no chrome root fails."""
942 request = self._GetRequest(chroot=self.chroot_dir,
943 build_target=self.build_target,
944 output_dir=self.output_dir,
945 artifact_type=self.valid_artifact_type)
946 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
947 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
948 self.api_config)
949 self.assertEqual('chroot.chrome_dir path does not exist: ',
950 str(context.exception))
951
Tiancong Wangc4805b72019-06-11 12:12:03 -0700952 def testNoOutputDir(self):
953 """Test no output dir fails."""
954 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700955 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700956 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700957 artifact_type=self.valid_artifact_type)
958 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
959 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
960 self.api_config)
961 self.assertEqual('output_dir is required.',
962 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700963
964 def testOutputDirDoesNotExist(self):
965 """Test output directory not existing fails."""
966 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700967 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700968 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700969 output_dir=self.does_not_exist,
970 artifact_type=self.valid_artifact_type)
971 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
972 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
973 self.api_config)
974 self.assertEqual(
975 'output_dir path does not exist: %s' % self.does_not_exist,
976 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700977
Tiancong Wang50b80a92019-08-01 14:46:15 -0700978 def testNoArtifactType(self):
979 """Test no artifact type."""
980 request = self._GetRequest(chroot=self.chroot_dir,
981 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700982 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700983 output_dir=self.output_dir)
984 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
985 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
986 self.api_config)
987 self.assertIn('artifact_type (0) must be in',
988 str(context.exception))
989
990 def testWrongArtifactType(self):
991 """Test passing wrong artifact type."""
992 request = self._GetRequest(chroot=self.chroot_dir,
993 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700994 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700995 output_dir=self.output_dir,
996 artifact_type=self.invalid_artifact_type)
997 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
998 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
999 self.api_config)
Tiancong Wang24a3df72019-08-20 15:48:51 -07001000 self.assertIn('artifact_type (%d) must be in' % self.invalid_artifact_type,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001001 str(context.exception))
1002
1003 def testOutputHandlingOnOrderfile(self,
Tiancong Wang24a3df72019-08-20 15:48:51 -07001004 artifact_type=toolchain_pb2.ORDERFILE):
Tiancong Wang50b80a92019-08-01 14:46:15 -07001005 """Test response output for orderfile."""
1006 files = ['artifact1', 'artifact2', 'artifact3']
Tiancong Wangc4805b72019-06-11 12:12:03 -07001007 expected_files = [os.path.join(self.output_dir, f) for f in files]
Tiancong Wang50b80a92019-08-01 14:46:15 -07001008 self.PatchObject(artifacts_svc, 'BundleAFDOGenerationArtifacts',
Tiancong Wangc4805b72019-06-11 12:12:03 -07001009 return_value=expected_files)
Alex Klein231d2da2019-07-22 16:44:45 -06001010
Tiancong Wangc4805b72019-06-11 12:12:03 -07001011 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -07001012 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001013 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001014 output_dir=self.output_dir,
1015 artifact_type=artifact_type)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001016
Tiancong Wang50b80a92019-08-01 14:46:15 -07001017 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1018 self.api_config)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001019
Tiancong Wang50b80a92019-08-01 14:46:15 -07001020 self.assertTrue(self.response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -04001021 self.assertCountEqual(expected_files,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001022 [a.path for a in self.response.artifacts])
1023
1024 def testOutputHandlingOnAFDO(self):
1025 """Test response output for AFDO."""
1026 self.testOutputHandlingOnOrderfile(
Tiancong Wang24a3df72019-08-20 15:48:51 -07001027 artifact_type=toolchain_pb2.BENCHMARK_AFDO)
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001028
1029
1030class ExportCpeReportTest(cros_test_lib.MockTempDirTestCase,
1031 api_config.ApiConfigMixin):
1032 """ExportCpeReport tests."""
1033
1034 def setUp(self):
1035 self.response = artifacts_pb2.BundleResponse()
1036
1037 def testValidateOnly(self):
1038 """Sanity check validate only calls don't execute."""
1039 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1040
1041 request = artifacts_pb2.BundleRequest()
1042 request.build_target.name = 'board'
1043 request.output_dir = self.tempdir
1044
1045 artifacts.ExportCpeReport(request, self.response, self.validate_only_config)
1046
1047 patch.assert_not_called()
1048
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001049 def testMockCall(self):
1050 """Test that a mock call does not execute logic, returns mocked value."""
1051 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1052
1053 request = artifacts_pb2.BundleRequest()
1054 request.build_target.name = 'board'
1055 request.output_dir = self.tempdir
1056
1057 artifacts.ExportCpeReport(request, self.response, self.mock_call_config)
1058
1059 patch.assert_not_called()
1060 self.assertEqual(len(self.response.artifacts), 2)
1061 self.assertEqual(self.response.artifacts[0].path,
1062 os.path.join(self.tempdir, 'cpe_report.txt'))
1063 self.assertEqual(self.response.artifacts[1].path,
1064 os.path.join(self.tempdir, 'cpe_warnings.txt'))
1065
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001066 def testNoBuildTarget(self):
1067 request = artifacts_pb2.BundleRequest()
1068 request.output_dir = self.tempdir
1069
1070 with self.assertRaises(cros_build_lib.DieSystemExit):
1071 artifacts.ExportCpeReport(request, self.response, self.api_config)
1072
1073 def testSuccess(self):
1074 """Test success case."""
1075 expected = artifacts_svc.CpeResult(
1076 report='/output/report.json', warnings='/output/warnings.json')
1077 self.PatchObject(artifacts_svc, 'GenerateCpeReport', return_value=expected)
1078
1079 request = artifacts_pb2.BundleRequest()
1080 request.build_target.name = 'board'
1081 request.output_dir = self.tempdir
1082
1083 artifacts.ExportCpeReport(request, self.response, self.api_config)
1084
1085 for artifact in self.response.artifacts:
1086 self.assertIn(artifact.path, [expected.report, expected.warnings])
Shao-Chuan Leea44dddc2020-10-30 17:16:55 +09001087
1088
1089class BundleGceTarballTest(BundleTestCase):
1090 """Unittests for BundleGceTarball."""
1091
1092 def testValidateOnly(self):
1093 """Check that a validate only call does not execute any logic."""
1094 patch = self.PatchObject(artifacts_svc, 'BundleGceTarball')
1095 artifacts.BundleGceTarball(self.target_request, self.response,
1096 self.validate_only_config)
1097 patch.assert_not_called()
1098
1099 def testMockCall(self):
1100 """Test that a mock call does not execute logic, returns mocked value."""
1101 patch = self.PatchObject(artifacts_svc, 'BundleGceTarball')
1102 artifacts.BundleGceTarball(self.target_request, self.response,
1103 self.mock_call_config)
1104 patch.assert_not_called()
1105 self.assertEqual(len(self.response.artifacts), 1)
1106 self.assertEqual(self.response.artifacts[0].path,
1107 os.path.join(self.output_dir,
1108 constants.TEST_IMAGE_GCE_TAR))
1109
1110 def testBundleGceTarball(self):
1111 """BundleGceTarball calls cbuildbot/commands with correct args."""
1112 bundle_gce_tarball = self.PatchObject(
1113 artifacts_svc, 'BundleGceTarball',
1114 return_value=os.path.join(self.output_dir,
1115 constants.TEST_IMAGE_GCE_TAR))
1116 self.PatchObject(os.path, 'exists', return_value=True)
1117 artifacts.BundleGceTarball(self.target_request, self.response,
1118 self.api_config)
1119 self.assertEqual(
1120 [artifact.path for artifact in self.response.artifacts],
1121 [os.path.join(self.output_dir, constants.TEST_IMAGE_GCE_TAR)])
1122
1123 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
1124 self.assertEqual(
1125 bundle_gce_tarball.call_args_list,
1126 [mock.call(self.output_dir, latest)])
1127
1128 def testBundleGceTarballNoImageDir(self):
1129 """BundleGceTarball dies when image dir does not exist."""
1130 self.PatchObject(os.path, 'exists', return_value=False)
1131 with self.assertRaises(cros_build_lib.DieSystemExit):
1132 artifacts.BundleGceTarball(self.target_request, self.response,
1133 self.api_config)
Michael Mortensen6667b542020-12-12 11:09:55 -07001134
1135
1136class BundleDebugSymbolsTest(BundleTestCase):
1137 """Unittests for BundleDebugSymbols."""
1138
1139 def setUp(self):
1140 # Create a chroot_path that also includes a chroot tmp dir.
1141 self.chroot_path = os.path.join(self.tempdir, 'chroot_dir')
1142 osutils.SafeMakedirs(self.chroot_path)
1143 osutils.SafeMakedirs(os.path.join(self.chroot_path, 'tmp'))
1144 # Create output dir.
1145 output_dir = os.path.join(self.tempdir, 'output_dir')
1146 osutils.SafeMakedirs(output_dir)
1147 # Build target request.
1148 self.target_request = self.BuildTargetRequest(
1149 build_target='target',
1150 output_dir=self.output_dir,
1151 chroot=self.chroot_path)
1152
1153 def testValidateOnly(self):
1154 """Check that a validate only call does not execute any logic."""
1155 patch = self.PatchObject(artifacts_svc, 'GenerateBreakpadSymbols')
1156 artifacts.BundleDebugSymbols(self.target_request, self.response,
1157 self.validate_only_config)
1158 patch.assert_not_called()
1159
1160 def testMockCall(self):
1161 """Test that a mock call does not execute logic, returns mocked value."""
1162 patch = self.PatchObject(artifacts_svc, 'GenerateBreakpadSymbols')
1163 artifacts.BundleDebugSymbols(self.target_request, self.response,
1164 self.mock_call_config)
1165 patch.assert_not_called()
1166 self.assertEqual(len(self.response.artifacts), 1)
1167 self.assertEqual(self.response.artifacts[0].path,
1168 os.path.join(self.output_dir,
1169 constants.DEBUG_SYMBOLS_TAR))
1170
1171 def testBundleDebugSymbols(self):
1172 """BundleDebugSymbols calls cbuildbot/commands with correct args."""
1173 # Patch service layer functions.
1174 generate_breakpad_symbols_patch = self.PatchObject(
1175 artifacts_svc, 'GenerateBreakpadSymbols',
1176 return_value=cros_build_lib.CommandResult(returncode=0, output=''))
1177 gather_symbol_files_patch = self.PatchObject(
1178 artifacts_svc, 'GatherSymbolFiles',
1179 return_value=[artifacts_svc.SymbolFileTuple(
1180 source_file_name='path/to/source/file1.sym',
1181 relative_path='file1.sym')])
1182
1183 artifacts.BundleDebugSymbols(self.target_request, self.response,
1184 self.api_config)
1185 # Verify mock objects were called.
Michael Mortensen7da39cc2021-03-09 10:28:45 -07001186 build_target = build_target_lib.BuildTarget('target')
1187 generate_breakpad_symbols_patch.assert_called_with(
1188 mock.ANY, build_target, debug=True)
Michael Mortensen6667b542020-12-12 11:09:55 -07001189 gather_symbol_files_patch.assert_called()
1190
1191 # Verify response proto contents and output directory contents.
1192 self.assertEqual(
1193 [artifact.path for artifact in self.response.artifacts],
1194 [os.path.join(self.output_dir, constants.DEBUG_SYMBOLS_TAR)])
1195 files = os.listdir(self.output_dir)
1196 self.assertEqual(files, [constants.DEBUG_SYMBOLS_TAR])
1197
1198 def testBundleGceTarballNoImageDir(self):
1199 """BundleDebugSymbols dies when image dir does not exist."""
1200 self.PatchObject(os.path, 'exists', return_value=False)
1201 with self.assertRaises(cros_build_lib.DieSystemExit):
1202 artifacts.BundleDebugSymbols(self.target_request, self.response,
1203 self.api_config)