blob: f34bb481029b5e8c3309ef7d7e2cb78ca36598ae [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 Klein231d2da2019-07-22 16:44:45 -060028class BundleTestCase(cros_test_lib.MockTempDirTestCase,
29 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060030 """Basic setup for all artifacts unittests."""
31
32 def setUp(self):
Alex Klein231d2da2019-07-22 16:44:45 -060033 self.output_dir = os.path.join(self.tempdir, 'artifacts')
34 osutils.SafeMakedirs(self.output_dir)
35 self.sysroot_path = '/build/target'
36 self.chroot_path = os.path.join(self.tempdir, 'chroot')
37 full_sysroot_path = os.path.join(self.chroot_path,
38 self.sysroot_path.lstrip(os.sep))
39 osutils.SafeMakedirs(full_sysroot_path)
40
41 # Legacy call.
Evan Hernandezf388cbf2019-04-01 11:15:23 -060042 self.input_proto = artifacts_pb2.BundleRequest()
43 self.input_proto.build_target.name = 'target'
Alex Klein231d2da2019-07-22 16:44:45 -060044 self.input_proto.output_dir = self.output_dir
Evan Hernandezf388cbf2019-04-01 11:15:23 -060045 self.output_proto = artifacts_pb2.BundleResponse()
46
Alex Klein231d2da2019-07-22 16:44:45 -060047 # New call format.
48 self.request = artifacts_pb2.BundleRequest()
49 self.request.chroot.path = self.chroot_path
50 self.request.sysroot.path = self.sysroot_path
51 self.request.output_dir = self.output_dir
52 self.response = artifacts_pb2.BundleResponse()
53
54 self.source_root = self.tempdir
55 self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -060056
57
Alex Klein231d2da2019-07-22 16:44:45 -060058class BundleTempDirTestCase(cros_test_lib.MockTempDirTestCase,
59 api_config.ApiConfigMixin):
Alex Klein238d8862019-05-07 11:32:46 -060060 """Basic setup for artifacts unittests that need a tempdir."""
61
62 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
63 output_dir=None):
64 """Helper to create a request message instance.
65
66 Args:
67 chroot (str): The chroot path.
68 sysroot (str): The sysroot path.
69 build_target (str): The build target name.
70 output_dir (str): The output directory.
71 """
72 return artifacts_pb2.BundleRequest(
73 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
74 chroot={'path': chroot}, output_dir=output_dir)
75
Alex Klein238d8862019-05-07 11:32:46 -060076 def setUp(self):
77 self.output_dir = os.path.join(self.tempdir, 'artifacts')
78 osutils.SafeMakedirs(self.output_dir)
79
Alex Klein238d8862019-05-07 11:32:46 -060080 # Old style proto.
81 self.input_proto = artifacts_pb2.BundleRequest()
82 self.input_proto.build_target.name = 'target'
83 self.input_proto.output_dir = self.output_dir
84 self.output_proto = artifacts_pb2.BundleResponse()
85
Alex Kleine21a0952019-08-23 16:08:16 -060086 self.chroot_path = os.path.join(self.tempdir, 'chroot')
87 self.PatchObject(constants, 'DEFAULT_CHROOT_PATH', new=self.chroot_path)
Alex Klein238d8862019-05-07 11:32:46 -060088
89 # New style paths.
Alex Klein238d8862019-05-07 11:32:46 -060090 self.sysroot_path = '/build/target'
Alex Kleine21a0952019-08-23 16:08:16 -060091 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
92 full_sysroot_path = os.path.join(self.chroot_path,
93 self.sysroot_path.lstrip(os.sep))
94 osutils.SafeMakedirs(full_sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -060095
96 # New style proto.
97 self.request = artifacts_pb2.BundleRequest()
98 self.request.output_dir = self.output_dir
99 self.request.chroot.path = self.chroot_path
100 self.request.sysroot.path = self.sysroot_path
101 self.response = artifacts_pb2.BundleResponse()
102
103
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600104class BundleImageZipTest(BundleTestCase):
105 """Unittests for BundleImageZip."""
106
Alex Klein231d2da2019-07-22 16:44:45 -0600107 def testValidateOnly(self):
108 """Sanity check that a validate only call does not execute any logic."""
109 patch = self.PatchObject(commands, 'BuildImageZip')
110 artifacts.BundleImageZip(self.input_proto, self.output_proto,
111 self.validate_only_config)
112 patch.assert_not_called()
113
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600114 def testBundleImageZip(self):
115 """BundleImageZip calls cbuildbot/commands with correct args."""
Michael Mortensen01910922019-07-24 14:48:10 -0600116 bundle_image_zip = self.PatchObject(
117 artifacts_svc, 'BundleImageZip', return_value='image.zip')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600118 self.PatchObject(os.path, 'exists', return_value=True)
Alex Klein231d2da2019-07-22 16:44:45 -0600119 artifacts.BundleImageZip(self.input_proto, self.output_proto,
120 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600121 self.assertEqual(
122 [artifact.path for artifact in self.output_proto.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600123 [os.path.join(self.output_dir, 'image.zip')])
124
125 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600126 self.assertEqual(
Michael Mortensen01910922019-07-24 14:48:10 -0600127 bundle_image_zip.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600128 [mock.call(self.output_dir, latest)])
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600129
130 def testBundleImageZipNoImageDir(self):
131 """BundleImageZip dies when image dir does not exist."""
132 self.PatchObject(os.path, 'exists', return_value=False)
133 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600134 artifacts.BundleImageZip(self.input_proto, self.output_proto,
135 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600136
137
Alex Klein238d8862019-05-07 11:32:46 -0600138class BundleAutotestFilesTest(BundleTempDirTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600139 """Unittests for BundleAutotestFiles."""
140
Alex Klein231d2da2019-07-22 16:44:45 -0600141 def testValidateOnly(self):
142 """Sanity check that a validate only call does not execute any logic."""
143 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
144 artifacts.BundleAutotestFiles(self.input_proto, self.output_proto,
145 self.validate_only_config)
146 patch.assert_not_called()
147
Alex Klein238d8862019-05-07 11:32:46 -0600148 def testBundleAutotestFilesLegacy(self):
149 """BundleAutotestFiles calls service correctly with legacy args."""
150 files = {
151 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
152 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
153 }
154 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
155 return_value=files)
156
157 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
Alex Kleine21a0952019-08-23 16:08:16 -0600158 return_value=self.sysroot)
Alex Klein231d2da2019-07-22 16:44:45 -0600159 artifacts.BundleAutotestFiles(self.input_proto, self.output_proto,
160 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600161
162 # Verify the sysroot is being built out correctly.
Alex Kleine21a0952019-08-23 16:08:16 -0600163 sysroot_patch.assert_called_with(self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600164
165 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600166 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600167
168 # Verify the output proto is being populated correctly.
169 self.assertTrue(self.output_proto.artifacts)
170 paths = [artifact.path for artifact in self.output_proto.artifacts]
171 self.assertItemsEqual(files.values(), paths)
172
173 def testBundleAutotestFiles(self):
174 """BundleAutotestFiles calls service correctly."""
175 files = {
176 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
177 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
178 }
179 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
180 return_value=files)
181
182 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
183 return_value=self.sysroot)
Alex Klein231d2da2019-07-22 16:44:45 -0600184 artifacts.BundleAutotestFiles(self.request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600185
186 # Verify the sysroot is being built out correctly.
Alex Kleine21a0952019-08-23 16:08:16 -0600187 sysroot_patch.assert_called_with(self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600188
189 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600190 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600191
192 # Verify the output proto is being populated correctly.
193 self.assertTrue(self.response.artifacts)
194 paths = [artifact.path for artifact in self.response.artifacts]
195 self.assertItemsEqual(files.values(), paths)
196
197 def testInvalidOutputDir(self):
198 """Test invalid output directory argument."""
199 request = self._GetRequest(chroot=self.chroot_path,
200 sysroot=self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600201
202 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600203 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600204
205 def testInvalidSysroot(self):
206 """Test no sysroot directory."""
207 request = self._GetRequest(chroot=self.chroot_path,
208 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600209
210 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600211 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600212
213 def testSysrootDoesNotExist(self):
214 """Test dies when no sysroot does not exist."""
215 request = self._GetRequest(chroot=self.chroot_path,
216 sysroot='/does/not/exist',
217 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600218
219 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600220 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600221
222
223class BundleTastFilesTest(BundleTestCase):
224 """Unittests for BundleTastFiles."""
225
Alex Klein231d2da2019-07-22 16:44:45 -0600226 def testValidateOnly(self):
227 """Sanity check that a validate only call does not execute any logic."""
228 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
229 artifacts.BundleTastFiles(self.input_proto, self.output_proto,
230 self.validate_only_config)
231 patch.assert_not_called()
232
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600233 def testBundleTastFilesNoLogs(self):
234 """BundleTasteFiles dies when no tast files found."""
235 self.PatchObject(commands, 'BuildTastBundleTarball',
236 return_value=None)
237 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600238 artifacts.BundleTastFiles(self.input_proto, self.output_proto,
239 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600240
Alex Kleinb9d810b2019-07-01 12:38:02 -0600241 def testBundleTastFilesLegacy(self):
242 """BundleTastFiles handles legacy args correctly."""
243 buildroot = self.tempdir
244 chroot_dir = os.path.join(buildroot, 'chroot')
245 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
246 output_dir = os.path.join(self.tempdir, 'results')
247 osutils.SafeMakedirs(sysroot_path)
248 osutils.SafeMakedirs(output_dir)
249
Alex Klein171da612019-08-06 14:00:42 -0600250 chroot = chroot_lib.Chroot(chroot_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600251 sysroot = sysroot_lib.Sysroot('/build/board')
252
253 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
254 # Patch the service being called.
255 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
256 return_value=expected_archive)
257 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
258
259 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
260 output_dir=output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600261 artifacts.BundleTastFiles(request, self.output_proto, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600262 self.assertEqual(
263 [artifact.path for artifact in self.output_proto.artifacts],
264 [expected_archive])
265 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
266
267 def testBundleTastFiles(self):
268 """BundleTastFiles calls service correctly."""
269 # Setup.
270 sysroot_path = os.path.join(self.tempdir, 'sysroot')
271 output_dir = os.path.join(self.tempdir, 'results')
272 osutils.SafeMakedirs(sysroot_path)
273 osutils.SafeMakedirs(output_dir)
274
275 chroot = chroot_lib.Chroot(self.tempdir, env={'FEATURES': 'separatedebug'})
276 sysroot = sysroot_lib.Sysroot('/sysroot')
277
278 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
279 # Patch the service being called.
280 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
281 return_value=expected_archive)
282
283 # Request and response building.
284 request = artifacts_pb2.BundleRequest(chroot={'path': self.tempdir},
285 sysroot={'path': '/sysroot'},
286 output_dir=output_dir)
287 response = artifacts_pb2.BundleResponse()
288
Alex Klein231d2da2019-07-22 16:44:45 -0600289 artifacts.BundleTastFiles(request, response, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600290
291 # Make sure the artifact got recorded successfully.
292 self.assertTrue(response.artifacts)
293 self.assertEqual(expected_archive, response.artifacts[0].path)
294 # Make sure the service got called correctly.
295 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
296
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600297
298class BundlePinnedGuestImagesTest(BundleTestCase):
299 """Unittests for BundlePinnedGuestImages."""
300
Alex Klein231d2da2019-07-22 16:44:45 -0600301 def testValidateOnly(self):
302 """Sanity check that a validate only call does not execute any logic."""
303 patch = self.PatchObject(commands, 'BuildPinnedGuestImagesTarball')
304 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto,
305 self.validate_only_config)
306 patch.assert_not_called()
307
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600308 def testBundlePinnedGuestImages(self):
309 """BundlePinnedGuestImages calls cbuildbot/commands with correct args."""
310 build_pinned_guest_images_tarball = self.PatchObject(
311 commands,
312 'BuildPinnedGuestImagesTarball',
313 return_value='pinned-guest-images.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600314 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto,
315 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600316 self.assertEqual(
317 [artifact.path for artifact in self.output_proto.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600318 [os.path.join(self.output_dir, 'pinned-guest-images.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600319 self.assertEqual(build_pinned_guest_images_tarball.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600320 [mock.call(self.source_root, 'target', self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600321
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600322 def testBundlePinnedGuestImagesNoLogs(self):
Evan Hernandezde445982019-04-22 13:42:34 -0600323 """BundlePinnedGuestImages does not die when no pinned images found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600324 self.PatchObject(commands, 'BuildPinnedGuestImagesTarball',
325 return_value=None)
Alex Klein231d2da2019-07-22 16:44:45 -0600326 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto,
327 self.api_config)
Evan Hernandezde445982019-04-22 13:42:34 -0600328 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600329
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600330
331class BundleFirmwareTest(BundleTestCase):
332 """Unittests for BundleFirmware."""
333
Alex Klein231d2da2019-07-22 16:44:45 -0600334 def testValidateOnly(self):
335 """Sanity check that a validate only call does not execute any logic."""
336 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
337 artifacts.BundleFirmware(self.request, self.response,
338 self.validate_only_config)
339 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000340
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600341 def testBundleFirmware(self):
342 """BundleFirmware calls cbuildbot/commands with correct args."""
Alex Klein231d2da2019-07-22 16:44:45 -0600343 self.PatchObject(
344 artifacts_svc,
345 'BuildFirmwareArchive',
346 return_value=os.path.join(self.output_dir, 'firmware.tar.gz'))
347
348 artifacts.BundleFirmware(self.request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600349 self.assertEqual(
Alex Klein231d2da2019-07-22 16:44:45 -0600350 [artifact.path for artifact in self.response.artifacts],
351 [os.path.join(self.output_dir, 'firmware.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600352
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600353 def testBundleFirmwareNoLogs(self):
354 """BundleFirmware dies when no firmware found."""
355 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
356 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600357 artifacts.BundleFirmware(self.input_proto, self.output_proto,
358 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600359
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600360
361class BundleEbuildLogsTest(BundleTestCase):
362 """Unittests for BundleEbuildLogs."""
363
Alex Klein231d2da2019-07-22 16:44:45 -0600364 def testValidateOnly(self):
365 """Sanity check that a validate only call does not execute any logic."""
366 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
367 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto,
368 self.validate_only_config)
369 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600370
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600371 def testBundleEbuildLogs(self):
372 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600373 bundle_ebuild_logs_tarball = self.PatchObject(
374 artifacts_svc, 'BundleEBuildLogsTarball',
375 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600376 artifacts.BundleEbuildLogs(self.request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600377 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600378 [artifact.path for artifact in self.response.artifacts],
379 [os.path.join(self.request.output_dir, 'ebuild-logs.tar.gz')])
380 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Evan Hernandeza478d802019-04-08 15:08:24 -0600381 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600382 bundle_ebuild_logs_tarball.call_args_list,
383 [mock.call(mock.ANY, sysroot, self.output_dir)])
384
385 def testBundleEBuildLogsOldProto(self):
386 bundle_ebuild_logs_tarball = self.PatchObject(
387 artifacts_svc, 'BundleEBuildLogsTarball',
388 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600389
390 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto,
391 self.api_config)
392
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600393 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
394 self.assertEqual(
395 bundle_ebuild_logs_tarball.call_args_list,
396 [mock.call(mock.ANY, sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600397
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600398 def testBundleEbuildLogsNoLogs(self):
399 """BundleEbuildLogs dies when no logs found."""
400 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
401 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600402 artifacts.BundleEbuildLogs(self.request, self.response, self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600403
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600404
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600405class BundleChromeOSConfigTest(BundleTestCase):
406 """Unittests for BundleChromeOSConfig"""
407
408 def testValidateOnly(self):
409 """Sanity check that a validate only call does not execute any logic."""
410 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
411 artifacts.BundleChromeOSConfig(self.input_proto, self.output_proto,
412 self.validate_only_config)
413 patch.assert_not_called()
414
415 def testBundleChromeOSConfigCallWithSysroot(self):
416 """Call with a request that sets sysroot."""
417 bundle_chromeos_config = self.PatchObject(
418 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
419 artifacts.BundleChromeOSConfig(self.request, self.output_proto,
420 self.api_config)
421 self.assertEqual(
422 [artifact.path for artifact in self.output_proto.artifacts],
423 [os.path.join(self.output_dir, 'config.yaml')])
424
425 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
426 self.assertEqual(bundle_chromeos_config.call_args_list,
427 [mock.call(mock.ANY, sysroot, self.output_dir)])
428
429 def testBundleChromeOSConfigCallWithBuildTarget(self):
430 """Call with a request that sets build_target."""
431 bundle_chromeos_config = self.PatchObject(
432 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
433 artifacts.BundleChromeOSConfig(self.input_proto, self.output_proto,
434 self.api_config)
435
436 self.assertEqual(
437 [artifact.path for artifact in self.output_proto.artifacts],
438 [os.path.join(self.output_dir, 'config.yaml')])
439
440 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
441 self.assertEqual(bundle_chromeos_config.call_args_list,
442 [mock.call(mock.ANY, sysroot, self.output_dir)])
443
444 def testBundleChromeOSConfigNoConfigFound(self):
445 """An error is raised if the config payload isn't found."""
446 self.PatchObject(artifacts_svc, 'BundleChromeOSConfig', return_value=None)
447
448 with self.assertRaises(cros_build_lib.DieSystemExit):
449 artifacts.BundleChromeOSConfig(self.request, self.output_proto,
450 self.api_config)
451
452
Alex Klein231d2da2019-07-22 16:44:45 -0600453class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase,
454 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600455 """Unittests for BundleTestUpdatePayloads."""
456
457 def setUp(self):
458 self.source_root = os.path.join(self.tempdir, 'cros')
459 osutils.SafeMakedirs(self.source_root)
460
461 self.archive_root = os.path.join(self.tempdir, 'output')
462 osutils.SafeMakedirs(self.archive_root)
463
464 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600465 self.image_root = os.path.join(self.source_root,
466 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600467
468 self.input_proto = artifacts_pb2.BundleRequest()
469 self.input_proto.build_target.name = self.target
470 self.input_proto.output_dir = self.archive_root
471 self.output_proto = artifacts_pb2.BundleResponse()
472
473 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
474
Alex Kleincb541e82019-06-26 15:06:11 -0600475 def MockPayloads(image_path, archive_dir):
476 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
477 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
478 return [os.path.join(archive_dir, 'payload1.bin'),
479 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600480
Alex Kleincb541e82019-06-26 15:06:11 -0600481 self.bundle_patch = self.PatchObject(
482 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600483
Alex Klein231d2da2019-07-22 16:44:45 -0600484 def testValidateOnly(self):
485 """Sanity check that a validate only call does not execute any logic."""
486 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
487 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
488 self.validate_only_config)
489 patch.assert_not_called()
490
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600491 def testBundleTestUpdatePayloads(self):
492 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
493 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
494 osutils.WriteFile(image_path, 'image!', makedirs=True)
495
Alex Klein231d2da2019-07-22 16:44:45 -0600496 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
497 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600498
499 actual = [
500 os.path.relpath(artifact.path, self.archive_root)
501 for artifact in self.output_proto.artifacts
502 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600503 expected = ['payload1.bin', 'payload2.bin']
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600504 self.assertItemsEqual(actual, expected)
505
506 actual = [
507 os.path.relpath(path, self.archive_root)
508 for path in osutils.DirectoryIterator(self.archive_root)
509 ]
510 self.assertItemsEqual(actual, expected)
511
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600512 def testBundleTestUpdatePayloadsNoImageDir(self):
513 """BundleTestUpdatePayloads dies if no image dir is found."""
514 # Intentionally do not write image directory.
515 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600516 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
517 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600518
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600519 def testBundleTestUpdatePayloadsNoImage(self):
520 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600521 # Intentionally do not write image, but create the directory.
522 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600523 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600524 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
525 self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600526
527
Alex Klein231d2da2019-07-22 16:44:45 -0600528class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase,
529 api_config.ApiConfigMixin):
Alex Klein2275d692019-04-23 16:04:12 -0600530 """BundleSimpleChromeArtifacts tests."""
531
532 def setUp(self):
533 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
534 self.sysroot_path = '/sysroot'
535 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
536 osutils.SafeMakedirs(self.sysroot_dir)
537 self.output_dir = os.path.join(self.tempdir, 'output_dir')
538 osutils.SafeMakedirs(self.output_dir)
539
540 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
541
Alex Klein231d2da2019-07-22 16:44:45 -0600542 self.response = artifacts_pb2.BundleResponse()
543
Alex Klein2275d692019-04-23 16:04:12 -0600544 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
545 output_dir=None):
546 """Helper to create a request message instance.
547
548 Args:
549 chroot (str): The chroot path.
550 sysroot (str): The sysroot path.
551 build_target (str): The build target name.
552 output_dir (str): The output directory.
553 """
554 return artifacts_pb2.BundleRequest(
555 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
556 chroot={'path': chroot}, output_dir=output_dir)
557
Alex Klein231d2da2019-07-22 16:44:45 -0600558 def testValidateOnly(self):
559 """Sanity check that a validate only call does not execute any logic."""
560 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
561 request = self._GetRequest(chroot=self.chroot_dir,
562 sysroot=self.sysroot_path,
563 build_target='board', output_dir=self.output_dir)
564 artifacts.BundleSimpleChromeArtifacts(request, self.response,
565 self.validate_only_config)
566 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600567
568 def testNoBuildTarget(self):
569 """Test no build target fails."""
570 request = self._GetRequest(chroot=self.chroot_dir,
571 sysroot=self.sysroot_path,
572 output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600573 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600574 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600575 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600576
577 def testNoSysroot(self):
578 """Test no sysroot fails."""
579 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600580 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600581 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600582 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600583
584 def testSysrootDoesNotExist(self):
585 """Test no sysroot fails."""
586 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
587 sysroot=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600588 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600589 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600590 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600591
592 def testNoOutputDir(self):
593 """Test no output dir fails."""
594 request = self._GetRequest(chroot=self.chroot_dir,
595 sysroot=self.sysroot_path,
596 build_target='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600597 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600598 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600599 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600600
601 def testOutputDirDoesNotExist(self):
602 """Test no output dir fails."""
603 request = self._GetRequest(chroot=self.chroot_dir,
604 sysroot=self.sysroot_path,
605 build_target='board',
606 output_dir=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600607 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600608 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600609 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600610
611 def testOutputHandling(self):
612 """Test response output."""
613 files = ['file1', 'file2', 'file3']
614 expected_files = [os.path.join(self.output_dir, f) for f in files]
615 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
616 return_value=expected_files)
617 request = self._GetRequest(chroot=self.chroot_dir,
618 sysroot=self.sysroot_path,
619 build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600620 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600621
Alex Klein231d2da2019-07-22 16:44:45 -0600622 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600623
624 self.assertTrue(response.artifacts)
625 self.assertItemsEqual(expected_files, [a.path for a in response.artifacts])
626
627
Alex Klein231d2da2019-07-22 16:44:45 -0600628class BundleVmFilesTest(cros_test_lib.MockTempDirTestCase,
629 api_config.ApiConfigMixin):
Alex Klein6504eca2019-04-18 15:37:56 -0600630 """BuildVmFiles tests."""
631
Alex Klein231d2da2019-07-22 16:44:45 -0600632 def setUp(self):
633 self.output_dir = os.path.join(self.tempdir, 'output')
634 osutils.SafeMakedirs(self.output_dir)
635
636 self.response = artifacts_pb2.BundleResponse()
637
Alex Klein6504eca2019-04-18 15:37:56 -0600638 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
639 output_dir=None):
640 """Helper to build out an input message instance.
641
642 Args:
643 chroot (str|None): The chroot path.
644 sysroot (str|None): The sysroot path relative to the chroot.
645 test_results_dir (str|None): The test results directory relative to the
646 sysroot.
647 output_dir (str|None): The directory where the results tarball should be
648 saved.
649 """
650 return artifacts_pb2.BundleVmFilesRequest(
651 chroot={'path': chroot}, sysroot={'path': sysroot},
652 test_results_dir=test_results_dir, output_dir=output_dir,
653 )
654
Alex Klein231d2da2019-07-22 16:44:45 -0600655 def testValidateOnly(self):
656 """Sanity check that a validate only call does not execute any logic."""
657 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
658 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
659 test_results_dir='/test/results',
660 output_dir=self.output_dir)
661 artifacts.BundleVmFiles(in_proto, self.response, self.validate_only_config)
662 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600663
664 def testChrootMissing(self):
665 """Test error handling for missing chroot."""
666 in_proto = self._GetInput(sysroot='/build/board',
667 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600668 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600669
670 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600671 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600672
Alex Klein6504eca2019-04-18 15:37:56 -0600673 def testTestResultsDirMissing(self):
674 """Test error handling for missing test results directory."""
675 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
Alex Klein231d2da2019-07-22 16:44:45 -0600676 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600677
678 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600679 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600680
681 def testOutputDirMissing(self):
682 """Test error handling for missing output directory."""
683 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
684 test_results_dir='/test/results')
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)
688
689 def testOutputDirDoesNotExist(self):
690 """Test error handling for output directory that does not exist."""
691 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
692 output_dir=os.path.join(self.tempdir, 'dne'),
693 test_results_dir='/test/results')
694
695 with self.assertRaises(cros_build_lib.DieSystemExit):
696 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600697
698 def testValidCall(self):
699 """Test image dir building."""
700 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
701 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600702 output_dir=self.output_dir)
703
Alex Klein6504eca2019-04-18 15:37:56 -0600704 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600705 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600706 return_value=expected_files)
707
Alex Klein231d2da2019-07-22 16:44:45 -0600708 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600709
Alex Klein231d2da2019-07-22 16:44:45 -0600710 patch.assert_called_with(mock.ANY, '/test/results', self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600711
712 # Make sure we have artifacts, and that every artifact is an expected file.
Alex Klein231d2da2019-07-22 16:44:45 -0600713 self.assertTrue(self.response.artifacts)
714 for artifact in self.response.artifacts:
Alex Klein6504eca2019-04-18 15:37:56 -0600715 self.assertIn(artifact.path, expected_files)
716 expected_files.remove(artifact.path)
717
718 # Make sure we've seen all of the expected files.
719 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700720
Alex Kleinb9d810b2019-07-01 12:38:02 -0600721
Tiancong Wang50b80a92019-08-01 14:46:15 -0700722
723class BundleAFDOGenerationArtifactsTestCase(
Alex Klein231d2da2019-07-22 16:44:45 -0600724 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700725 """Unittests for BundleAFDOGenerationArtifacts."""
726
727 @staticmethod
728 def mock_die(message, *args):
729 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700730
731 def setUp(self):
732 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
733 osutils.SafeMakedirs(self.chroot_dir)
734 temp_dir = os.path.join(self.chroot_dir, 'tmp')
735 osutils.SafeMakedirs(temp_dir)
736 self.output_dir = os.path.join(self.tempdir, 'output_dir')
737 osutils.SafeMakedirs(self.output_dir)
738 self.build_target = 'board'
Tiancong Wang24a3df72019-08-20 15:48:51 -0700739 self.valid_artifact_type = toolchain_pb2.ORDERFILE
740 self.invalid_artifact_type = toolchain_pb2.NONE_TYPE
Tiancong Wangc4805b72019-06-11 12:12:03 -0700741 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700742 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700743
Alex Klein231d2da2019-07-22 16:44:45 -0600744 self.response = artifacts_pb2.BundleResponse()
745
Tiancong Wang50b80a92019-08-01 14:46:15 -0700746 def _GetRequest(self, chroot=None, build_target=None, output_dir=None,
747 artifact_type=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700748 """Helper to create a request message instance.
749
750 Args:
751 chroot (str): The chroot path.
752 build_target (str): The build target name.
753 output_dir (str): The output directory.
Tiancong Wang50b80a92019-08-01 14:46:15 -0700754 artifact_type (artifacts_pb2.AFDOArtifactType):
755 The type of the artifact.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700756 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700757 return artifacts_pb2.BundleChromeAFDORequest(
Tiancong Wangc4805b72019-06-11 12:12:03 -0700758 chroot={'path': chroot},
Tiancong Wang50b80a92019-08-01 14:46:15 -0700759 build_target={'name': build_target},
760 output_dir=output_dir,
761 artifact_type=artifact_type,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700762 )
763
Alex Klein231d2da2019-07-22 16:44:45 -0600764 def testValidateOnly(self):
765 """Sanity check that a validate only call does not execute any logic."""
766 patch = self.PatchObject(artifacts_svc,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700767 'BundleAFDOGenerationArtifacts')
Alex Klein231d2da2019-07-22 16:44:45 -0600768 request = self._GetRequest(chroot=self.chroot_dir,
769 build_target=self.build_target,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700770 output_dir=self.output_dir,
771 artifact_type=self.valid_artifact_type)
772 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
773 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600774 patch.assert_not_called()
Tiancong Wangc4805b72019-06-11 12:12:03 -0700775
776 def testNoBuildTarget(self):
777 """Test no build target fails."""
778 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700779 output_dir=self.output_dir,
780 artifact_type=self.valid_artifact_type)
781 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
782 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
783 self.api_config)
784 self.assertEqual('build_target.name is required.',
785 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700786
787 def testNoOutputDir(self):
788 """Test no output dir fails."""
789 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700790 build_target=self.build_target,
791 artifact_type=self.valid_artifact_type)
792 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
793 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
794 self.api_config)
795 self.assertEqual('output_dir is required.',
796 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700797
798 def testOutputDirDoesNotExist(self):
799 """Test output directory not existing fails."""
800 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700801 build_target=self.build_target,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700802 output_dir=self.does_not_exist,
803 artifact_type=self.valid_artifact_type)
804 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
805 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
806 self.api_config)
807 self.assertEqual(
808 'output_dir path does not exist: %s' % self.does_not_exist,
809 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700810
Tiancong Wang50b80a92019-08-01 14:46:15 -0700811 def testNoArtifactType(self):
812 """Test no artifact type."""
813 request = self._GetRequest(chroot=self.chroot_dir,
814 build_target=self.build_target,
815 output_dir=self.output_dir)
816 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
817 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
818 self.api_config)
819 self.assertIn('artifact_type (0) must be in',
820 str(context.exception))
821
822 def testWrongArtifactType(self):
823 """Test passing wrong artifact type."""
824 request = self._GetRequest(chroot=self.chroot_dir,
825 build_target=self.build_target,
826 output_dir=self.output_dir,
827 artifact_type=self.invalid_artifact_type)
828 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
829 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
830 self.api_config)
Tiancong Wang24a3df72019-08-20 15:48:51 -0700831 self.assertIn('artifact_type (%d) must be in' % self.invalid_artifact_type,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700832 str(context.exception))
833
834 def testOutputHandlingOnOrderfile(self,
Tiancong Wang24a3df72019-08-20 15:48:51 -0700835 artifact_type=toolchain_pb2.ORDERFILE):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700836 """Test response output for orderfile."""
837 files = ['artifact1', 'artifact2', 'artifact3']
Tiancong Wangc4805b72019-06-11 12:12:03 -0700838 expected_files = [os.path.join(self.output_dir, f) for f in files]
Tiancong Wang50b80a92019-08-01 14:46:15 -0700839 self.PatchObject(artifacts_svc, 'BundleAFDOGenerationArtifacts',
Tiancong Wangc4805b72019-06-11 12:12:03 -0700840 return_value=expected_files)
Alex Klein231d2da2019-07-22 16:44:45 -0600841
Tiancong Wangc4805b72019-06-11 12:12:03 -0700842 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700843 build_target=self.build_target,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700844 output_dir=self.output_dir,
845 artifact_type=artifact_type)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700846
Tiancong Wang50b80a92019-08-01 14:46:15 -0700847 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
848 self.api_config)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700849
Tiancong Wang50b80a92019-08-01 14:46:15 -0700850 self.assertTrue(self.response.artifacts)
851 self.assertItemsEqual(expected_files,
852 [a.path for a in self.response.artifacts])
853
854 def testOutputHandlingOnAFDO(self):
855 """Test response output for AFDO."""
856 self.testOutputHandlingOnOrderfile(
Tiancong Wang24a3df72019-08-20 15:48:51 -0700857 artifact_type=toolchain_pb2.BENCHMARK_AFDO)
Alex Klein0b1cbfc2019-08-14 10:09:58 -0600858
859
860class ExportCpeReportTest(cros_test_lib.MockTempDirTestCase,
861 api_config.ApiConfigMixin):
862 """ExportCpeReport tests."""
863
864 def setUp(self):
865 self.response = artifacts_pb2.BundleResponse()
866
867 def testValidateOnly(self):
868 """Sanity check validate only calls don't execute."""
869 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
870
871 request = artifacts_pb2.BundleRequest()
872 request.build_target.name = 'board'
873 request.output_dir = self.tempdir
874
875 artifacts.ExportCpeReport(request, self.response, self.validate_only_config)
876
877 patch.assert_not_called()
878
879 def testNoBuildTarget(self):
880 request = artifacts_pb2.BundleRequest()
881 request.output_dir = self.tempdir
882
883 with self.assertRaises(cros_build_lib.DieSystemExit):
884 artifacts.ExportCpeReport(request, self.response, self.api_config)
885
886 def testSuccess(self):
887 """Test success case."""
888 expected = artifacts_svc.CpeResult(
889 report='/output/report.json', warnings='/output/warnings.json')
890 self.PatchObject(artifacts_svc, 'GenerateCpeReport', return_value=expected)
891
892 request = artifacts_pb2.BundleRequest()
893 request.build_target.name = 'board'
894 request.output_dir = self.tempdir
895
896 artifacts.ExportCpeReport(request, self.response, self.api_config)
897
898 for artifact in self.response.artifacts:
899 self.assertIn(artifact.path, [expected.report, expected.warnings])