blob: d11a595f4b0f58849dab52b2b0fcda63e5f1df23 [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
Alex Kleinb9d810b2019-07-01 12:38:02 -060019from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060020from chromite.lib import constants
21from chromite.lib import cros_build_lib
22from chromite.lib import cros_test_lib
23from chromite.lib import osutils
Alex Klein238d8862019-05-07 11:32:46 -060024from chromite.lib import sysroot_lib
Alex Klein2275d692019-04-23 16:04:12 -060025from chromite.service import artifacts as artifacts_svc
Evan Hernandezf388cbf2019-04-01 11:15:23 -060026
27
Alex Kleind91e95a2019-09-17 10:39:02 -060028class BundleRequestMixin(object):
29 """Mixin to provide bundle request methods."""
30
31 def EmptyRequest(self):
32 return artifacts_pb2.BundleRequest()
33
34 def BuildTargetRequest(self, build_target=None, output_dir=None, chroot=None):
35 """Get a build target format request instance."""
36 request = self.EmptyRequest()
37 if build_target:
38 request.build_target.name = build_target
39 if output_dir:
40 request.output_dir = output_dir
41 if chroot:
42 request.chroot.path = chroot
43
44 return request
45
46 def SysrootRequest(self,
47 sysroot=None,
48 build_target=None,
49 output_dir=None,
50 chroot=None):
51 """Get a sysroot format request instance."""
52 request = self.EmptyRequest()
53 if sysroot:
54 request.sysroot.path = sysroot
55 if build_target:
56 request.sysroot.build_target.name = build_target
57 if output_dir:
58 request.output_dir = output_dir
59 if chroot:
60 request.chroot.path = chroot
61
62 return request
63
64
Alex Klein231d2da2019-07-22 16:44:45 -060065class BundleTestCase(cros_test_lib.MockTempDirTestCase,
Alex Kleind91e95a2019-09-17 10:39:02 -060066 api_config.ApiConfigMixin, BundleRequestMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060067 """Basic setup for all artifacts unittests."""
68
69 def setUp(self):
Alex Klein231d2da2019-07-22 16:44:45 -060070 self.output_dir = os.path.join(self.tempdir, 'artifacts')
71 osutils.SafeMakedirs(self.output_dir)
72 self.sysroot_path = '/build/target'
Alex Klein68c8fdf2019-09-25 15:09:11 -060073 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -060074 self.chroot_path = os.path.join(self.tempdir, 'chroot')
75 full_sysroot_path = os.path.join(self.chroot_path,
76 self.sysroot_path.lstrip(os.sep))
77 osutils.SafeMakedirs(full_sysroot_path)
78
Alex Klein68c8fdf2019-09-25 15:09:11 -060079 # All requests use same response type.
Alex Klein231d2da2019-07-22 16:44:45 -060080 self.response = artifacts_pb2.BundleResponse()
81
Alex Klein68c8fdf2019-09-25 15:09:11 -060082 # Build target request.
83 self.target_request = self.BuildTargetRequest(
84 build_target='target',
85 output_dir=self.output_dir,
86 chroot=self.chroot_path)
87
88 # Sysroot request.
89 self.sysroot_request = self.SysrootRequest(
90 sysroot=self.sysroot_path,
91 build_target='target',
92 output_dir=self.output_dir,
93 chroot=self.chroot_path)
94
Alex Klein231d2da2019-07-22 16:44:45 -060095 self.source_root = self.tempdir
96 self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -060097
98
Alex Kleind91e95a2019-09-17 10:39:02 -060099class BundleImageArchivesTest(BundleTestCase):
100 """BundleImageArchives tests."""
101
102 def testValidateOnly(self):
103 """Sanity check that a validate only call does not execute any logic."""
104 patch = self.PatchObject(artifacts_svc, 'ArchiveImages')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600105 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600106 self.validate_only_config)
107 patch.assert_not_called()
108
109 def testNoBuildTarget(self):
110 """Test that no build target fails."""
111 request = self.BuildTargetRequest(output_dir=self.tempdir)
112 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600113 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600114
115 def testNoOutputDir(self):
116 """Test no output dir fails."""
117 request = self.BuildTargetRequest(build_target='board')
118 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600119 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600120
121 def testInvalidOutputDir(self):
122 """Test invalid output dir fails."""
123 request = self.BuildTargetRequest(
124 build_target='board', output_dir=os.path.join(self.tempdir, 'DNE'))
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 testOutputHandling(self):
129 """Test the artifact output handling."""
130 expected = [os.path.join(self.output_dir, f) for f in ('a', 'b', 'c')]
131 self.PatchObject(artifacts_svc, 'ArchiveImages', return_value=expected)
132 self.PatchObject(os.path, 'exists', return_value=True)
133
Alex Klein68c8fdf2019-09-25 15:09:11 -0600134 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600135 self.api_config)
136
Mike Frysinger678735c2019-09-28 18:23:28 -0400137 self.assertCountEqual(expected, [a.path for a in self.response.artifacts])
Alex Kleind91e95a2019-09-17 10:39:02 -0600138
139
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600140class BundleImageZipTest(BundleTestCase):
141 """Unittests for BundleImageZip."""
142
Alex Klein231d2da2019-07-22 16:44:45 -0600143 def testValidateOnly(self):
144 """Sanity check that a validate only call does not execute any logic."""
145 patch = self.PatchObject(commands, 'BuildImageZip')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600146 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600147 self.validate_only_config)
148 patch.assert_not_called()
149
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600150 def testBundleImageZip(self):
151 """BundleImageZip calls cbuildbot/commands with correct args."""
Michael Mortensen01910922019-07-24 14:48:10 -0600152 bundle_image_zip = self.PatchObject(
153 artifacts_svc, 'BundleImageZip', return_value='image.zip')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600154 self.PatchObject(os.path, 'exists', return_value=True)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600155 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600156 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600157 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600158 [artifact.path for artifact in self.response.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600159 [os.path.join(self.output_dir, 'image.zip')])
160
161 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600162 self.assertEqual(
Michael Mortensen01910922019-07-24 14:48:10 -0600163 bundle_image_zip.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600164 [mock.call(self.output_dir, latest)])
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600165
166 def testBundleImageZipNoImageDir(self):
167 """BundleImageZip dies when image dir does not exist."""
168 self.PatchObject(os.path, 'exists', return_value=False)
169 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600170 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600171 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600172
173
Alex Klein68c8fdf2019-09-25 15:09:11 -0600174class BundleAutotestFilesTest(BundleTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600175 """Unittests for BundleAutotestFiles."""
176
Alex Klein231d2da2019-07-22 16:44:45 -0600177 def testValidateOnly(self):
178 """Sanity check that a validate only call does not execute any logic."""
179 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600180 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600181 self.validate_only_config)
182 patch.assert_not_called()
183
Alex Klein238d8862019-05-07 11:32:46 -0600184 def testBundleAutotestFilesLegacy(self):
185 """BundleAutotestFiles calls service correctly with legacy args."""
186 files = {
187 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
188 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
189 }
190 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
191 return_value=files)
192
Alex Klein68c8fdf2019-09-25 15:09:11 -0600193 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600194 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600195
Alex Klein238d8862019-05-07 11:32:46 -0600196 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600197 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600198
199 # Verify the output proto is being populated correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600200 self.assertTrue(self.response.artifacts)
201 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400202 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600203
204 def testBundleAutotestFiles(self):
205 """BundleAutotestFiles calls service correctly."""
206 files = {
207 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
208 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
209 }
210 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
211 return_value=files)
212
Alex Klein68c8fdf2019-09-25 15:09:11 -0600213 artifacts.BundleAutotestFiles(self.sysroot_request, self.response,
214 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600215
216 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600217 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600218
219 # Verify the output proto is being populated correctly.
220 self.assertTrue(self.response.artifacts)
221 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400222 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600223
224 def testInvalidOutputDir(self):
225 """Test invalid output directory argument."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600226 request = self.SysrootRequest(chroot=self.chroot_path,
227 sysroot=self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600228
229 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600230 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600231
232 def testInvalidSysroot(self):
233 """Test no sysroot directory."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600234 request = self.SysrootRequest(chroot=self.chroot_path,
235 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600236
237 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600238 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600239
240 def testSysrootDoesNotExist(self):
241 """Test dies when no sysroot does not exist."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600242 request = self.SysrootRequest(chroot=self.chroot_path,
243 sysroot='/does/not/exist',
244 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600245
246 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600247 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600248
249
250class BundleTastFilesTest(BundleTestCase):
251 """Unittests for BundleTastFiles."""
252
Alex Klein231d2da2019-07-22 16:44:45 -0600253 def testValidateOnly(self):
254 """Sanity check that a validate only call does not execute any logic."""
255 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600256 artifacts.BundleTastFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600257 self.validate_only_config)
258 patch.assert_not_called()
259
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600260 def testBundleTastFilesNoLogs(self):
261 """BundleTasteFiles dies when no tast files found."""
262 self.PatchObject(commands, 'BuildTastBundleTarball',
263 return_value=None)
264 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600265 artifacts.BundleTastFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600266 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600267
Alex Kleinb9d810b2019-07-01 12:38:02 -0600268 def testBundleTastFilesLegacy(self):
269 """BundleTastFiles handles legacy args correctly."""
270 buildroot = self.tempdir
271 chroot_dir = os.path.join(buildroot, 'chroot')
272 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
273 output_dir = os.path.join(self.tempdir, 'results')
274 osutils.SafeMakedirs(sysroot_path)
275 osutils.SafeMakedirs(output_dir)
276
Alex Klein171da612019-08-06 14:00:42 -0600277 chroot = chroot_lib.Chroot(chroot_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600278 sysroot = sysroot_lib.Sysroot('/build/board')
279
280 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
281 # Patch the service being called.
282 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
283 return_value=expected_archive)
284 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
285
286 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
287 output_dir=output_dir)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600288 artifacts.BundleTastFiles(request, self.response, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600289 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600290 [artifact.path for artifact in self.response.artifacts],
Alex Kleinb9d810b2019-07-01 12:38:02 -0600291 [expected_archive])
292 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
293
294 def testBundleTastFiles(self):
295 """BundleTastFiles calls service correctly."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600296 chroot = chroot_lib.Chroot(self.chroot_path,
297 env={'FEATURES': 'separatedebug'})
Alex Kleinb9d810b2019-07-01 12:38:02 -0600298
Alex Klein68c8fdf2019-09-25 15:09:11 -0600299 expected_archive = os.path.join(self.output_dir,
300 artifacts_svc.TAST_BUNDLE_NAME)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600301 # Patch the service being called.
302 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
303 return_value=expected_archive)
304
Alex Klein68c8fdf2019-09-25 15:09:11 -0600305 artifacts.BundleTastFiles(self.sysroot_request, self.response,
306 self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600307
308 # Make sure the artifact got recorded successfully.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600309 self.assertTrue(self.response.artifacts)
310 self.assertEqual(expected_archive, self.response.artifacts[0].path)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600311 # Make sure the service got called correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600312 bundle_patch.assert_called_once_with(chroot, self.sysroot, self.output_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600313
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600314
315class BundlePinnedGuestImagesTest(BundleTestCase):
316 """Unittests for BundlePinnedGuestImages."""
317
Alex Klein231d2da2019-07-22 16:44:45 -0600318 def testValidateOnly(self):
319 """Sanity check that a validate only call does not execute any logic."""
320 patch = self.PatchObject(commands, 'BuildPinnedGuestImagesTarball')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600321 artifacts.BundlePinnedGuestImages(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600322 self.validate_only_config)
323 patch.assert_not_called()
324
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600325 def testBundlePinnedGuestImages(self):
326 """BundlePinnedGuestImages calls cbuildbot/commands with correct args."""
327 build_pinned_guest_images_tarball = self.PatchObject(
328 commands,
329 'BuildPinnedGuestImagesTarball',
330 return_value='pinned-guest-images.tar.gz')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600331 artifacts.BundlePinnedGuestImages(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600332 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600333 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600334 [artifact.path for artifact in self.response.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600335 [os.path.join(self.output_dir, 'pinned-guest-images.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600336 self.assertEqual(build_pinned_guest_images_tarball.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600337 [mock.call(self.source_root, 'target', self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600338
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600339 def testBundlePinnedGuestImagesNoLogs(self):
Evan Hernandezde445982019-04-22 13:42:34 -0600340 """BundlePinnedGuestImages does not die when no pinned images found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600341 self.PatchObject(commands, 'BuildPinnedGuestImagesTarball',
342 return_value=None)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600343 artifacts.BundlePinnedGuestImages(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600344 self.api_config)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600345 self.assertFalse(self.response.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600346
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600347
348class BundleFirmwareTest(BundleTestCase):
349 """Unittests for BundleFirmware."""
350
Alex Klein231d2da2019-07-22 16:44:45 -0600351 def testValidateOnly(self):
352 """Sanity check that a validate only call does not execute any logic."""
353 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600354 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600355 self.validate_only_config)
356 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000357
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600358 def testBundleFirmware(self):
359 """BundleFirmware calls cbuildbot/commands with correct args."""
Alex Klein231d2da2019-07-22 16:44:45 -0600360 self.PatchObject(
361 artifacts_svc,
362 'BuildFirmwareArchive',
363 return_value=os.path.join(self.output_dir, 'firmware.tar.gz'))
364
Alex Klein68c8fdf2019-09-25 15:09:11 -0600365 artifacts.BundleFirmware(self.sysroot_request, self.response,
366 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600367 self.assertEqual(
Alex Klein231d2da2019-07-22 16:44:45 -0600368 [artifact.path for artifact in self.response.artifacts],
369 [os.path.join(self.output_dir, 'firmware.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600370
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600371 def testBundleFirmwareNoLogs(self):
372 """BundleFirmware dies when no firmware found."""
373 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
374 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600375 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600376 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600377
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600378
379class BundleEbuildLogsTest(BundleTestCase):
380 """Unittests for BundleEbuildLogs."""
381
Alex Klein231d2da2019-07-22 16:44:45 -0600382 def testValidateOnly(self):
383 """Sanity check that a validate only call does not execute any logic."""
384 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600385 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600386 self.validate_only_config)
387 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600388
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600389 def testBundleEbuildLogs(self):
390 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600391 bundle_ebuild_logs_tarball = self.PatchObject(
392 artifacts_svc, 'BundleEBuildLogsTarball',
393 return_value='ebuild-logs.tar.gz')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600394 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
395 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600396 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600397 [artifact.path for artifact in self.response.artifacts],
Alex Klein68c8fdf2019-09-25 15:09:11 -0600398 [os.path.join(self.output_dir, 'ebuild-logs.tar.gz')])
Evan Hernandeza478d802019-04-08 15:08:24 -0600399 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600400 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600401 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600402
403 def testBundleEBuildLogsOldProto(self):
404 bundle_ebuild_logs_tarball = self.PatchObject(
405 artifacts_svc, 'BundleEBuildLogsTarball',
406 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600407
Alex Klein68c8fdf2019-09-25 15:09:11 -0600408 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600409 self.api_config)
410
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600411 self.assertEqual(
412 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600413 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600414
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600415 def testBundleEbuildLogsNoLogs(self):
416 """BundleEbuildLogs dies when no logs found."""
417 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
418 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600419 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
420 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600421
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600422
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600423class BundleChromeOSConfigTest(BundleTestCase):
424 """Unittests for BundleChromeOSConfig"""
425
426 def testValidateOnly(self):
427 """Sanity check that a validate only call does not execute any logic."""
428 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600429 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600430 self.validate_only_config)
431 patch.assert_not_called()
432
433 def testBundleChromeOSConfigCallWithSysroot(self):
434 """Call with a request that sets sysroot."""
435 bundle_chromeos_config = self.PatchObject(
436 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600437 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600438 self.api_config)
439 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600440 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600441 [os.path.join(self.output_dir, 'config.yaml')])
442
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600443 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600444 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600445
446 def testBundleChromeOSConfigCallWithBuildTarget(self):
447 """Call with a request that sets build_target."""
448 bundle_chromeos_config = self.PatchObject(
449 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600450 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600451 self.api_config)
452
453 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600454 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600455 [os.path.join(self.output_dir, 'config.yaml')])
456
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600457 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600458 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600459
460 def testBundleChromeOSConfigNoConfigFound(self):
461 """An error is raised if the config payload isn't found."""
462 self.PatchObject(artifacts_svc, 'BundleChromeOSConfig', return_value=None)
463
464 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600465 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600466 self.api_config)
467
468
Alex Klein231d2da2019-07-22 16:44:45 -0600469class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase,
470 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600471 """Unittests for BundleTestUpdatePayloads."""
472
473 def setUp(self):
474 self.source_root = os.path.join(self.tempdir, 'cros')
475 osutils.SafeMakedirs(self.source_root)
476
477 self.archive_root = os.path.join(self.tempdir, 'output')
478 osutils.SafeMakedirs(self.archive_root)
479
480 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600481 self.image_root = os.path.join(self.source_root,
482 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600483
484 self.input_proto = artifacts_pb2.BundleRequest()
485 self.input_proto.build_target.name = self.target
486 self.input_proto.output_dir = self.archive_root
487 self.output_proto = artifacts_pb2.BundleResponse()
488
489 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
490
Alex Kleincb541e82019-06-26 15:06:11 -0600491 def MockPayloads(image_path, archive_dir):
492 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
493 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
494 return [os.path.join(archive_dir, 'payload1.bin'),
495 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600496
Alex Kleincb541e82019-06-26 15:06:11 -0600497 self.bundle_patch = self.PatchObject(
498 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600499
Alex Klein231d2da2019-07-22 16:44:45 -0600500 def testValidateOnly(self):
501 """Sanity check that a validate only call does not execute any logic."""
502 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
503 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
504 self.validate_only_config)
505 patch.assert_not_called()
506
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600507 def testBundleTestUpdatePayloads(self):
508 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
509 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
510 osutils.WriteFile(image_path, 'image!', makedirs=True)
511
Alex Klein231d2da2019-07-22 16:44:45 -0600512 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
513 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600514
515 actual = [
516 os.path.relpath(artifact.path, self.archive_root)
517 for artifact in self.output_proto.artifacts
518 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600519 expected = ['payload1.bin', 'payload2.bin']
Mike Frysinger678735c2019-09-28 18:23:28 -0400520 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600521
522 actual = [
523 os.path.relpath(path, self.archive_root)
524 for path in osutils.DirectoryIterator(self.archive_root)
525 ]
Mike Frysinger678735c2019-09-28 18:23:28 -0400526 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600527
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600528 def testBundleTestUpdatePayloadsNoImageDir(self):
529 """BundleTestUpdatePayloads dies if no image dir is found."""
530 # Intentionally do not write image directory.
Alex Kleind2bf1462019-10-24 16:37:04 -0600531 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
532 self.api_config)
533 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600534
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600535 def testBundleTestUpdatePayloadsNoImage(self):
536 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600537 # Intentionally do not write image, but create the directory.
538 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600539 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600540 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
541 self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600542
543
Alex Klein231d2da2019-07-22 16:44:45 -0600544class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase,
545 api_config.ApiConfigMixin):
Alex Klein2275d692019-04-23 16:04:12 -0600546 """BundleSimpleChromeArtifacts tests."""
547
548 def setUp(self):
549 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
550 self.sysroot_path = '/sysroot'
551 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
552 osutils.SafeMakedirs(self.sysroot_dir)
553 self.output_dir = os.path.join(self.tempdir, 'output_dir')
554 osutils.SafeMakedirs(self.output_dir)
555
556 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
557
Alex Klein231d2da2019-07-22 16:44:45 -0600558 self.response = artifacts_pb2.BundleResponse()
559
Alex Klein2275d692019-04-23 16:04:12 -0600560 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
561 output_dir=None):
562 """Helper to create a request message instance.
563
564 Args:
565 chroot (str): The chroot path.
566 sysroot (str): The sysroot path.
567 build_target (str): The build target name.
568 output_dir (str): The output directory.
569 """
570 return artifacts_pb2.BundleRequest(
571 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
572 chroot={'path': chroot}, output_dir=output_dir)
573
Alex Klein231d2da2019-07-22 16:44:45 -0600574 def testValidateOnly(self):
575 """Sanity check that a validate only call does not execute any logic."""
576 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
577 request = self._GetRequest(chroot=self.chroot_dir,
578 sysroot=self.sysroot_path,
579 build_target='board', output_dir=self.output_dir)
580 artifacts.BundleSimpleChromeArtifacts(request, self.response,
581 self.validate_only_config)
582 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600583
584 def testNoBuildTarget(self):
585 """Test no build target fails."""
586 request = self._GetRequest(chroot=self.chroot_dir,
587 sysroot=self.sysroot_path,
588 output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600589 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600590 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600591 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600592
593 def testNoSysroot(self):
594 """Test no sysroot fails."""
595 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600596 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600597 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600598 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600599
600 def testSysrootDoesNotExist(self):
601 """Test no sysroot fails."""
602 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
603 sysroot=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600604 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600605 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600606 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600607
608 def testNoOutputDir(self):
609 """Test no output dir fails."""
610 request = self._GetRequest(chroot=self.chroot_dir,
611 sysroot=self.sysroot_path,
612 build_target='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600613 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600614 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600615 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600616
617 def testOutputDirDoesNotExist(self):
618 """Test no output dir fails."""
619 request = self._GetRequest(chroot=self.chroot_dir,
620 sysroot=self.sysroot_path,
621 build_target='board',
622 output_dir=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600623 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600624 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600625 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600626
627 def testOutputHandling(self):
628 """Test response output."""
629 files = ['file1', 'file2', 'file3']
630 expected_files = [os.path.join(self.output_dir, f) for f in files]
631 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
632 return_value=expected_files)
633 request = self._GetRequest(chroot=self.chroot_dir,
634 sysroot=self.sysroot_path,
635 build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600636 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600637
Alex Klein231d2da2019-07-22 16:44:45 -0600638 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600639
640 self.assertTrue(response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -0400641 self.assertCountEqual(expected_files, [a.path for a in response.artifacts])
Alex Klein2275d692019-04-23 16:04:12 -0600642
643
Alex Klein231d2da2019-07-22 16:44:45 -0600644class BundleVmFilesTest(cros_test_lib.MockTempDirTestCase,
645 api_config.ApiConfigMixin):
Alex Klein6504eca2019-04-18 15:37:56 -0600646 """BuildVmFiles tests."""
647
Alex Klein231d2da2019-07-22 16:44:45 -0600648 def setUp(self):
649 self.output_dir = os.path.join(self.tempdir, 'output')
650 osutils.SafeMakedirs(self.output_dir)
651
652 self.response = artifacts_pb2.BundleResponse()
653
Alex Klein6504eca2019-04-18 15:37:56 -0600654 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
655 output_dir=None):
656 """Helper to build out an input message instance.
657
658 Args:
659 chroot (str|None): The chroot path.
660 sysroot (str|None): The sysroot path relative to the chroot.
661 test_results_dir (str|None): The test results directory relative to the
662 sysroot.
663 output_dir (str|None): The directory where the results tarball should be
664 saved.
665 """
666 return artifacts_pb2.BundleVmFilesRequest(
667 chroot={'path': chroot}, sysroot={'path': sysroot},
668 test_results_dir=test_results_dir, output_dir=output_dir,
669 )
670
Alex Klein231d2da2019-07-22 16:44:45 -0600671 def testValidateOnly(self):
672 """Sanity check that a validate only call does not execute any logic."""
673 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
674 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
675 test_results_dir='/test/results',
676 output_dir=self.output_dir)
677 artifacts.BundleVmFiles(in_proto, self.response, self.validate_only_config)
678 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600679
680 def testChrootMissing(self):
681 """Test error handling for missing chroot."""
682 in_proto = self._GetInput(sysroot='/build/board',
683 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600684 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600685
686 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600687 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600688
Alex Klein6504eca2019-04-18 15:37:56 -0600689 def testTestResultsDirMissing(self):
690 """Test error handling for missing test results directory."""
691 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
Alex Klein231d2da2019-07-22 16:44:45 -0600692 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600693
694 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600695 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600696
697 def testOutputDirMissing(self):
698 """Test error handling for missing output directory."""
699 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
700 test_results_dir='/test/results')
Alex Klein6504eca2019-04-18 15:37:56 -0600701
702 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600703 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
704
705 def testOutputDirDoesNotExist(self):
706 """Test error handling for output directory that does not exist."""
707 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
708 output_dir=os.path.join(self.tempdir, 'dne'),
709 test_results_dir='/test/results')
710
711 with self.assertRaises(cros_build_lib.DieSystemExit):
712 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600713
714 def testValidCall(self):
715 """Test image dir building."""
716 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
717 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600718 output_dir=self.output_dir)
719
Alex Klein6504eca2019-04-18 15:37:56 -0600720 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600721 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600722 return_value=expected_files)
723
Alex Klein231d2da2019-07-22 16:44:45 -0600724 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600725
Alex Klein231d2da2019-07-22 16:44:45 -0600726 patch.assert_called_with(mock.ANY, '/test/results', self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600727
728 # Make sure we have artifacts, and that every artifact is an expected file.
Alex Klein231d2da2019-07-22 16:44:45 -0600729 self.assertTrue(self.response.artifacts)
730 for artifact in self.response.artifacts:
Alex Klein6504eca2019-04-18 15:37:56 -0600731 self.assertIn(artifact.path, expected_files)
732 expected_files.remove(artifact.path)
733
734 # Make sure we've seen all of the expected files.
735 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700736
Alex Kleinb9d810b2019-07-01 12:38:02 -0600737
Tiancong Wang50b80a92019-08-01 14:46:15 -0700738
739class BundleAFDOGenerationArtifactsTestCase(
Alex Klein231d2da2019-07-22 16:44:45 -0600740 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700741 """Unittests for BundleAFDOGenerationArtifacts."""
742
743 @staticmethod
744 def mock_die(message, *args):
745 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700746
747 def setUp(self):
748 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
749 osutils.SafeMakedirs(self.chroot_dir)
750 temp_dir = os.path.join(self.chroot_dir, 'tmp')
751 osutils.SafeMakedirs(temp_dir)
752 self.output_dir = os.path.join(self.tempdir, 'output_dir')
753 osutils.SafeMakedirs(self.output_dir)
Tiancong Wang2ade7932019-09-27 14:15:40 -0700754 self.chrome_root = os.path.join(self.tempdir, 'chrome_root')
755 osutils.SafeMakedirs(self.chrome_root)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700756 self.build_target = 'board'
Tiancong Wang24a3df72019-08-20 15:48:51 -0700757 self.valid_artifact_type = toolchain_pb2.ORDERFILE
758 self.invalid_artifact_type = toolchain_pb2.NONE_TYPE
Tiancong Wangc4805b72019-06-11 12:12:03 -0700759 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700760 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700761
Alex Klein231d2da2019-07-22 16:44:45 -0600762 self.response = artifacts_pb2.BundleResponse()
763
Tiancong Wang2ade7932019-09-27 14:15:40 -0700764 def _GetRequest(self, chroot=None, build_target=None, chrome_root=None,
765 output_dir=None, artifact_type=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700766 """Helper to create a request message instance.
767
768 Args:
769 chroot (str): The chroot path.
770 build_target (str): The build target name.
Tiancong Wang2ade7932019-09-27 14:15:40 -0700771 chrome_root (str): The path to Chrome root.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700772 output_dir (str): The output directory.
Tiancong Wang50b80a92019-08-01 14:46:15 -0700773 artifact_type (artifacts_pb2.AFDOArtifactType):
774 The type of the artifact.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700775 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700776 return artifacts_pb2.BundleChromeAFDORequest(
Tiancong Wang2ade7932019-09-27 14:15:40 -0700777 chroot={'path': chroot, 'chrome_dir': chrome_root},
Tiancong Wang50b80a92019-08-01 14:46:15 -0700778 build_target={'name': build_target},
779 output_dir=output_dir,
780 artifact_type=artifact_type,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700781 )
782
Alex Klein231d2da2019-07-22 16:44:45 -0600783 def testValidateOnly(self):
784 """Sanity check that a validate only call does not execute any logic."""
785 patch = self.PatchObject(artifacts_svc,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700786 'BundleAFDOGenerationArtifacts')
Alex Klein231d2da2019-07-22 16:44:45 -0600787 request = self._GetRequest(chroot=self.chroot_dir,
788 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700789 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700790 output_dir=self.output_dir,
791 artifact_type=self.valid_artifact_type)
792 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
793 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600794 patch.assert_not_called()
Tiancong Wangc4805b72019-06-11 12:12:03 -0700795
796 def testNoBuildTarget(self):
797 """Test no build target fails."""
798 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700799 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700800 output_dir=self.output_dir,
801 artifact_type=self.valid_artifact_type)
802 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
803 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
804 self.api_config)
805 self.assertEqual('build_target.name is required.',
806 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700807
Tiancong Wang2ade7932019-09-27 14:15:40 -0700808 def testNoChromeRoot(self):
809 """Test no chrome root fails."""
810 request = self._GetRequest(chroot=self.chroot_dir,
811 build_target=self.build_target,
812 output_dir=self.output_dir,
813 artifact_type=self.valid_artifact_type)
814 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
815 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
816 self.api_config)
817 self.assertEqual('chroot.chrome_dir path does not exist: ',
818 str(context.exception))
819
Tiancong Wangc4805b72019-06-11 12:12:03 -0700820 def testNoOutputDir(self):
821 """Test no output dir fails."""
822 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700823 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700824 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700825 artifact_type=self.valid_artifact_type)
826 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
827 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
828 self.api_config)
829 self.assertEqual('output_dir is required.',
830 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700831
832 def testOutputDirDoesNotExist(self):
833 """Test output directory not existing fails."""
834 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700835 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700836 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700837 output_dir=self.does_not_exist,
838 artifact_type=self.valid_artifact_type)
839 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
840 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
841 self.api_config)
842 self.assertEqual(
843 'output_dir path does not exist: %s' % self.does_not_exist,
844 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700845
Tiancong Wang50b80a92019-08-01 14:46:15 -0700846 def testNoArtifactType(self):
847 """Test no artifact type."""
848 request = self._GetRequest(chroot=self.chroot_dir,
849 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700850 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700851 output_dir=self.output_dir)
852 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
853 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
854 self.api_config)
855 self.assertIn('artifact_type (0) must be in',
856 str(context.exception))
857
858 def testWrongArtifactType(self):
859 """Test passing wrong artifact type."""
860 request = self._GetRequest(chroot=self.chroot_dir,
861 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700862 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700863 output_dir=self.output_dir,
864 artifact_type=self.invalid_artifact_type)
865 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
866 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
867 self.api_config)
Tiancong Wang24a3df72019-08-20 15:48:51 -0700868 self.assertIn('artifact_type (%d) must be in' % self.invalid_artifact_type,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700869 str(context.exception))
870
871 def testOutputHandlingOnOrderfile(self,
Tiancong Wang24a3df72019-08-20 15:48:51 -0700872 artifact_type=toolchain_pb2.ORDERFILE):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700873 """Test response output for orderfile."""
874 files = ['artifact1', 'artifact2', 'artifact3']
Tiancong Wangc4805b72019-06-11 12:12:03 -0700875 expected_files = [os.path.join(self.output_dir, f) for f in files]
Tiancong Wang50b80a92019-08-01 14:46:15 -0700876 self.PatchObject(artifacts_svc, 'BundleAFDOGenerationArtifacts',
Tiancong Wangc4805b72019-06-11 12:12:03 -0700877 return_value=expected_files)
Alex Klein231d2da2019-07-22 16:44:45 -0600878
Tiancong Wangc4805b72019-06-11 12:12:03 -0700879 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700880 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700881 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700882 output_dir=self.output_dir,
883 artifact_type=artifact_type)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700884
Tiancong Wang50b80a92019-08-01 14:46:15 -0700885 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
886 self.api_config)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700887
Tiancong Wang50b80a92019-08-01 14:46:15 -0700888 self.assertTrue(self.response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -0400889 self.assertCountEqual(expected_files,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700890 [a.path for a in self.response.artifacts])
891
892 def testOutputHandlingOnAFDO(self):
893 """Test response output for AFDO."""
894 self.testOutputHandlingOnOrderfile(
Tiancong Wang24a3df72019-08-20 15:48:51 -0700895 artifact_type=toolchain_pb2.BENCHMARK_AFDO)
Alex Klein0b1cbfc2019-08-14 10:09:58 -0600896
897
898class ExportCpeReportTest(cros_test_lib.MockTempDirTestCase,
899 api_config.ApiConfigMixin):
900 """ExportCpeReport tests."""
901
902 def setUp(self):
903 self.response = artifacts_pb2.BundleResponse()
904
905 def testValidateOnly(self):
906 """Sanity check validate only calls don't execute."""
907 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
908
909 request = artifacts_pb2.BundleRequest()
910 request.build_target.name = 'board'
911 request.output_dir = self.tempdir
912
913 artifacts.ExportCpeReport(request, self.response, self.validate_only_config)
914
915 patch.assert_not_called()
916
917 def testNoBuildTarget(self):
918 request = artifacts_pb2.BundleRequest()
919 request.output_dir = self.tempdir
920
921 with self.assertRaises(cros_build_lib.DieSystemExit):
922 artifacts.ExportCpeReport(request, self.response, self.api_config)
923
924 def testSuccess(self):
925 """Test success case."""
926 expected = artifacts_svc.CpeResult(
927 report='/output/report.json', warnings='/output/warnings.json')
928 self.PatchObject(artifacts_svc, 'GenerateCpeReport', return_value=expected)
929
930 request = artifacts_pb2.BundleRequest()
931 request.build_target.name = 'board'
932 request.output_dir = self.tempdir
933
934 artifacts.ExportCpeReport(request, self.response, self.api_config)
935
936 for artifact in self.response.artifacts:
937 self.assertIn(artifact.path, [expected.report, expected.warnings])