blob: eb5e2d9b5e08e6c9e091b18058bfd45222759469 [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
17from chromite.cbuildbot import commands
Alex Kleinb9d810b2019-07-01 12:38:02 -060018from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060019from chromite.lib import constants
20from chromite.lib import cros_build_lib
21from chromite.lib import cros_test_lib
22from chromite.lib import osutils
Alex Klein238d8862019-05-07 11:32:46 -060023from chromite.lib import sysroot_lib
Alex Klein2275d692019-04-23 16:04:12 -060024from chromite.service import artifacts as artifacts_svc
Evan Hernandezf388cbf2019-04-01 11:15:23 -060025
26
Alex Klein231d2da2019-07-22 16:44:45 -060027class BundleTestCase(cros_test_lib.MockTempDirTestCase,
28 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060029 """Basic setup for all artifacts unittests."""
30
31 def setUp(self):
Alex Klein231d2da2019-07-22 16:44:45 -060032 self.output_dir = os.path.join(self.tempdir, 'artifacts')
33 osutils.SafeMakedirs(self.output_dir)
34 self.sysroot_path = '/build/target'
35 self.chroot_path = os.path.join(self.tempdir, 'chroot')
36 full_sysroot_path = os.path.join(self.chroot_path,
37 self.sysroot_path.lstrip(os.sep))
38 osutils.SafeMakedirs(full_sysroot_path)
39
40 # Legacy call.
Evan Hernandezf388cbf2019-04-01 11:15:23 -060041 self.input_proto = artifacts_pb2.BundleRequest()
42 self.input_proto.build_target.name = 'target'
Alex Klein231d2da2019-07-22 16:44:45 -060043 self.input_proto.output_dir = self.output_dir
Evan Hernandezf388cbf2019-04-01 11:15:23 -060044 self.output_proto = artifacts_pb2.BundleResponse()
45
Alex Klein231d2da2019-07-22 16:44:45 -060046 # New call format.
47 self.request = artifacts_pb2.BundleRequest()
48 self.request.chroot.path = self.chroot_path
49 self.request.sysroot.path = self.sysroot_path
50 self.request.output_dir = self.output_dir
51 self.response = artifacts_pb2.BundleResponse()
52
53 self.source_root = self.tempdir
54 self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -060055
56
Alex Klein231d2da2019-07-22 16:44:45 -060057class BundleTempDirTestCase(cros_test_lib.MockTempDirTestCase,
58 api_config.ApiConfigMixin):
Alex Klein238d8862019-05-07 11:32:46 -060059 """Basic setup for artifacts unittests that need a tempdir."""
60
61 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
62 output_dir=None):
63 """Helper to create a request message instance.
64
65 Args:
66 chroot (str): The chroot path.
67 sysroot (str): The sysroot path.
68 build_target (str): The build target name.
69 output_dir (str): The output directory.
70 """
71 return artifacts_pb2.BundleRequest(
72 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
73 chroot={'path': chroot}, output_dir=output_dir)
74
Alex Klein238d8862019-05-07 11:32:46 -060075 def setUp(self):
76 self.output_dir = os.path.join(self.tempdir, 'artifacts')
77 osutils.SafeMakedirs(self.output_dir)
78
79 # Old style paths.
80 self.old_sysroot_path = os.path.join(self.tempdir, 'cros', 'chroot',
81 'build', 'target')
82 self.old_sysroot = sysroot_lib.Sysroot(self.old_sysroot_path)
83 osutils.SafeMakedirs(self.old_sysroot_path)
84
85 # Old style proto.
86 self.input_proto = artifacts_pb2.BundleRequest()
87 self.input_proto.build_target.name = 'target'
88 self.input_proto.output_dir = self.output_dir
89 self.output_proto = artifacts_pb2.BundleResponse()
90
91 source_root = os.path.join(self.tempdir, 'cros')
92 self.PatchObject(constants, 'SOURCE_ROOT', new=source_root)
93
94 # New style paths.
95 self.chroot_path = os.path.join(self.tempdir, 'cros', 'chroot')
96 self.sysroot_path = '/build/target'
97 self.full_sysroot_path = os.path.join(self.chroot_path,
98 self.sysroot_path.lstrip(os.sep))
99 self.sysroot = sysroot_lib.Sysroot(self.full_sysroot_path)
100 osutils.SafeMakedirs(self.full_sysroot_path)
101
102 # New style proto.
103 self.request = artifacts_pb2.BundleRequest()
104 self.request.output_dir = self.output_dir
105 self.request.chroot.path = self.chroot_path
106 self.request.sysroot.path = self.sysroot_path
107 self.response = artifacts_pb2.BundleResponse()
108
109
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600110class BundleImageZipTest(BundleTestCase):
111 """Unittests for BundleImageZip."""
112
Alex Klein231d2da2019-07-22 16:44:45 -0600113 def testValidateOnly(self):
114 """Sanity check that a validate only call does not execute any logic."""
115 patch = self.PatchObject(commands, 'BuildImageZip')
116 artifacts.BundleImageZip(self.input_proto, self.output_proto,
117 self.validate_only_config)
118 patch.assert_not_called()
119
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600120 def testBundleImageZip(self):
121 """BundleImageZip calls cbuildbot/commands with correct args."""
Michael Mortensen01910922019-07-24 14:48:10 -0600122 bundle_image_zip = self.PatchObject(
123 artifacts_svc, 'BundleImageZip', return_value='image.zip')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600124 self.PatchObject(os.path, 'exists', return_value=True)
Alex Klein231d2da2019-07-22 16:44:45 -0600125 artifacts.BundleImageZip(self.input_proto, self.output_proto,
126 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600127 self.assertEqual(
128 [artifact.path for artifact in self.output_proto.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600129 [os.path.join(self.output_dir, 'image.zip')])
130
131 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600132 self.assertEqual(
Michael Mortensen01910922019-07-24 14:48:10 -0600133 bundle_image_zip.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600134 [mock.call(self.output_dir, latest)])
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600135
136 def testBundleImageZipNoImageDir(self):
137 """BundleImageZip dies when image dir does not exist."""
138 self.PatchObject(os.path, 'exists', return_value=False)
139 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600140 artifacts.BundleImageZip(self.input_proto, self.output_proto,
141 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600142
143
Alex Klein238d8862019-05-07 11:32:46 -0600144class BundleAutotestFilesTest(BundleTempDirTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600145 """Unittests for BundleAutotestFiles."""
146
Alex Klein231d2da2019-07-22 16:44:45 -0600147 def testValidateOnly(self):
148 """Sanity check that a validate only call does not execute any logic."""
149 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
150 artifacts.BundleAutotestFiles(self.input_proto, self.output_proto,
151 self.validate_only_config)
152 patch.assert_not_called()
153
Alex Klein238d8862019-05-07 11:32:46 -0600154 def testBundleAutotestFilesLegacy(self):
155 """BundleAutotestFiles calls service correctly with legacy args."""
156 files = {
157 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
158 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
159 }
160 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
161 return_value=files)
162
163 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
164 return_value=self.old_sysroot)
Alex Klein231d2da2019-07-22 16:44:45 -0600165 artifacts.BundleAutotestFiles(self.input_proto, self.output_proto,
166 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600167
168 # Verify the sysroot is being built out correctly.
169 sysroot_patch.assert_called_with(self.old_sysroot_path)
170
171 # Verify the arguments are being passed through.
172 patch.assert_called_with(self.old_sysroot, self.output_dir)
173
174 # Verify the output proto is being populated correctly.
175 self.assertTrue(self.output_proto.artifacts)
176 paths = [artifact.path for artifact in self.output_proto.artifacts]
177 self.assertItemsEqual(files.values(), paths)
178
179 def testBundleAutotestFiles(self):
180 """BundleAutotestFiles calls service correctly."""
181 files = {
182 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
183 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
184 }
185 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
186 return_value=files)
187
188 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
189 return_value=self.sysroot)
Alex Klein231d2da2019-07-22 16:44:45 -0600190 artifacts.BundleAutotestFiles(self.request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600191
192 # Verify the sysroot is being built out correctly.
193 sysroot_patch.assert_called_with(self.full_sysroot_path)
194
195 # Verify the arguments are being passed through.
196 patch.assert_called_with(self.sysroot, self.output_dir)
197
198 # Verify the output proto is being populated correctly.
199 self.assertTrue(self.response.artifacts)
200 paths = [artifact.path for artifact in self.response.artifacts]
201 self.assertItemsEqual(files.values(), paths)
202
203 def testInvalidOutputDir(self):
204 """Test invalid output directory argument."""
205 request = self._GetRequest(chroot=self.chroot_path,
206 sysroot=self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600207
208 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600209 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600210
211 def testInvalidSysroot(self):
212 """Test no sysroot directory."""
213 request = self._GetRequest(chroot=self.chroot_path,
214 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600215
216 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600217 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600218
219 def testSysrootDoesNotExist(self):
220 """Test dies when no sysroot does not exist."""
221 request = self._GetRequest(chroot=self.chroot_path,
222 sysroot='/does/not/exist',
223 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600224
225 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600226 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600227
228
229class BundleTastFilesTest(BundleTestCase):
230 """Unittests for BundleTastFiles."""
231
Alex Klein231d2da2019-07-22 16:44:45 -0600232 def testValidateOnly(self):
233 """Sanity check that a validate only call does not execute any logic."""
234 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
235 artifacts.BundleTastFiles(self.input_proto, self.output_proto,
236 self.validate_only_config)
237 patch.assert_not_called()
238
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600239 def testBundleTastFilesNoLogs(self):
240 """BundleTasteFiles dies when no tast files found."""
241 self.PatchObject(commands, 'BuildTastBundleTarball',
242 return_value=None)
243 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600244 artifacts.BundleTastFiles(self.input_proto, self.output_proto,
245 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600246
Alex Kleinb9d810b2019-07-01 12:38:02 -0600247 def testBundleTastFilesLegacy(self):
248 """BundleTastFiles handles legacy args correctly."""
249 buildroot = self.tempdir
250 chroot_dir = os.path.join(buildroot, 'chroot')
251 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
252 output_dir = os.path.join(self.tempdir, 'results')
253 osutils.SafeMakedirs(sysroot_path)
254 osutils.SafeMakedirs(output_dir)
255
Alex Klein171da612019-08-06 14:00:42 -0600256 chroot = chroot_lib.Chroot(chroot_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600257 sysroot = sysroot_lib.Sysroot('/build/board')
258
259 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
260 # Patch the service being called.
261 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
262 return_value=expected_archive)
263 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
264
265 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
266 output_dir=output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600267 artifacts.BundleTastFiles(request, self.output_proto, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600268 self.assertEqual(
269 [artifact.path for artifact in self.output_proto.artifacts],
270 [expected_archive])
271 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
272
273 def testBundleTastFiles(self):
274 """BundleTastFiles calls service correctly."""
275 # Setup.
276 sysroot_path = os.path.join(self.tempdir, 'sysroot')
277 output_dir = os.path.join(self.tempdir, 'results')
278 osutils.SafeMakedirs(sysroot_path)
279 osutils.SafeMakedirs(output_dir)
280
281 chroot = chroot_lib.Chroot(self.tempdir, env={'FEATURES': 'separatedebug'})
282 sysroot = sysroot_lib.Sysroot('/sysroot')
283
284 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
285 # Patch the service being called.
286 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
287 return_value=expected_archive)
288
289 # Request and response building.
290 request = artifacts_pb2.BundleRequest(chroot={'path': self.tempdir},
291 sysroot={'path': '/sysroot'},
292 output_dir=output_dir)
293 response = artifacts_pb2.BundleResponse()
294
Alex Klein231d2da2019-07-22 16:44:45 -0600295 artifacts.BundleTastFiles(request, response, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600296
297 # Make sure the artifact got recorded successfully.
298 self.assertTrue(response.artifacts)
299 self.assertEqual(expected_archive, response.artifacts[0].path)
300 # Make sure the service got called correctly.
301 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
302
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600303
304class BundlePinnedGuestImagesTest(BundleTestCase):
305 """Unittests for BundlePinnedGuestImages."""
306
Alex Klein231d2da2019-07-22 16:44:45 -0600307 def testValidateOnly(self):
308 """Sanity check that a validate only call does not execute any logic."""
309 patch = self.PatchObject(commands, 'BuildPinnedGuestImagesTarball')
310 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto,
311 self.validate_only_config)
312 patch.assert_not_called()
313
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600314 def testBundlePinnedGuestImages(self):
315 """BundlePinnedGuestImages calls cbuildbot/commands with correct args."""
316 build_pinned_guest_images_tarball = self.PatchObject(
317 commands,
318 'BuildPinnedGuestImagesTarball',
319 return_value='pinned-guest-images.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600320 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto,
321 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600322 self.assertEqual(
323 [artifact.path for artifact in self.output_proto.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600324 [os.path.join(self.output_dir, 'pinned-guest-images.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600325 self.assertEqual(build_pinned_guest_images_tarball.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600326 [mock.call(self.source_root, 'target', self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600327
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600328 def testBundlePinnedGuestImagesNoLogs(self):
Evan Hernandezde445982019-04-22 13:42:34 -0600329 """BundlePinnedGuestImages does not die when no pinned images found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600330 self.PatchObject(commands, 'BuildPinnedGuestImagesTarball',
331 return_value=None)
Alex Klein231d2da2019-07-22 16:44:45 -0600332 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto,
333 self.api_config)
Evan Hernandezde445982019-04-22 13:42:34 -0600334 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600335
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600336
337class BundleFirmwareTest(BundleTestCase):
338 """Unittests for BundleFirmware."""
339
Alex Klein231d2da2019-07-22 16:44:45 -0600340 def testValidateOnly(self):
341 """Sanity check that a validate only call does not execute any logic."""
342 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
343 artifacts.BundleFirmware(self.request, self.response,
344 self.validate_only_config)
345 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000346
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600347 def testBundleFirmware(self):
348 """BundleFirmware calls cbuildbot/commands with correct args."""
Alex Klein231d2da2019-07-22 16:44:45 -0600349 self.PatchObject(
350 artifacts_svc,
351 'BuildFirmwareArchive',
352 return_value=os.path.join(self.output_dir, 'firmware.tar.gz'))
353
354 artifacts.BundleFirmware(self.request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600355 self.assertEqual(
Alex Klein231d2da2019-07-22 16:44:45 -0600356 [artifact.path for artifact in self.response.artifacts],
357 [os.path.join(self.output_dir, 'firmware.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600358
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600359 def testBundleFirmwareNoLogs(self):
360 """BundleFirmware dies when no firmware found."""
361 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
362 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600363 artifacts.BundleFirmware(self.input_proto, self.output_proto,
364 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600365
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600366
367class BundleEbuildLogsTest(BundleTestCase):
368 """Unittests for BundleEbuildLogs."""
369
Alex Klein231d2da2019-07-22 16:44:45 -0600370 def testValidateOnly(self):
371 """Sanity check that a validate only call does not execute any logic."""
372 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
373 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto,
374 self.validate_only_config)
375 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600376
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600377 def testBundleEbuildLogs(self):
378 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600379 bundle_ebuild_logs_tarball = self.PatchObject(
380 artifacts_svc, 'BundleEBuildLogsTarball',
381 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600382 artifacts.BundleEbuildLogs(self.request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600383 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600384 [artifact.path for artifact in self.response.artifacts],
385 [os.path.join(self.request.output_dir, 'ebuild-logs.tar.gz')])
386 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Evan Hernandeza478d802019-04-08 15:08:24 -0600387 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600388 bundle_ebuild_logs_tarball.call_args_list,
389 [mock.call(mock.ANY, sysroot, self.output_dir)])
390
391 def testBundleEBuildLogsOldProto(self):
392 bundle_ebuild_logs_tarball = self.PatchObject(
393 artifacts_svc, 'BundleEBuildLogsTarball',
394 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600395
396 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto,
397 self.api_config)
398
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600399 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
400 self.assertEqual(
401 bundle_ebuild_logs_tarball.call_args_list,
402 [mock.call(mock.ANY, sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600403
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600404 def testBundleEbuildLogsNoLogs(self):
405 """BundleEbuildLogs dies when no logs found."""
406 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
407 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600408 artifacts.BundleEbuildLogs(self.request, self.response, self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600409
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600410
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600411class BundleChromeOSConfigTest(BundleTestCase):
412 """Unittests for BundleChromeOSConfig"""
413
414 def testValidateOnly(self):
415 """Sanity check that a validate only call does not execute any logic."""
416 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
417 artifacts.BundleChromeOSConfig(self.input_proto, self.output_proto,
418 self.validate_only_config)
419 patch.assert_not_called()
420
421 def testBundleChromeOSConfigCallWithSysroot(self):
422 """Call with a request that sets sysroot."""
423 bundle_chromeos_config = self.PatchObject(
424 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
425 artifacts.BundleChromeOSConfig(self.request, self.output_proto,
426 self.api_config)
427 self.assertEqual(
428 [artifact.path for artifact in self.output_proto.artifacts],
429 [os.path.join(self.output_dir, 'config.yaml')])
430
431 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
432 self.assertEqual(bundle_chromeos_config.call_args_list,
433 [mock.call(mock.ANY, sysroot, self.output_dir)])
434
435 def testBundleChromeOSConfigCallWithBuildTarget(self):
436 """Call with a request that sets build_target."""
437 bundle_chromeos_config = self.PatchObject(
438 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
439 artifacts.BundleChromeOSConfig(self.input_proto, self.output_proto,
440 self.api_config)
441
442 self.assertEqual(
443 [artifact.path for artifact in self.output_proto.artifacts],
444 [os.path.join(self.output_dir, 'config.yaml')])
445
446 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
447 self.assertEqual(bundle_chromeos_config.call_args_list,
448 [mock.call(mock.ANY, sysroot, self.output_dir)])
449
450 def testBundleChromeOSConfigNoConfigFound(self):
451 """An error is raised if the config payload isn't found."""
452 self.PatchObject(artifacts_svc, 'BundleChromeOSConfig', return_value=None)
453
454 with self.assertRaises(cros_build_lib.DieSystemExit):
455 artifacts.BundleChromeOSConfig(self.request, self.output_proto,
456 self.api_config)
457
458
Alex Klein231d2da2019-07-22 16:44:45 -0600459class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase,
460 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600461 """Unittests for BundleTestUpdatePayloads."""
462
463 def setUp(self):
464 self.source_root = os.path.join(self.tempdir, 'cros')
465 osutils.SafeMakedirs(self.source_root)
466
467 self.archive_root = os.path.join(self.tempdir, 'output')
468 osutils.SafeMakedirs(self.archive_root)
469
470 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600471 self.image_root = os.path.join(self.source_root,
472 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600473
474 self.input_proto = artifacts_pb2.BundleRequest()
475 self.input_proto.build_target.name = self.target
476 self.input_proto.output_dir = self.archive_root
477 self.output_proto = artifacts_pb2.BundleResponse()
478
479 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
480
Alex Kleincb541e82019-06-26 15:06:11 -0600481 def MockPayloads(image_path, archive_dir):
482 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
483 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
484 return [os.path.join(archive_dir, 'payload1.bin'),
485 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600486
Alex Kleincb541e82019-06-26 15:06:11 -0600487 self.bundle_patch = self.PatchObject(
488 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600489
Alex Klein231d2da2019-07-22 16:44:45 -0600490 def testValidateOnly(self):
491 """Sanity check that a validate only call does not execute any logic."""
492 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
493 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
494 self.validate_only_config)
495 patch.assert_not_called()
496
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600497 def testBundleTestUpdatePayloads(self):
498 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
499 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
500 osutils.WriteFile(image_path, 'image!', makedirs=True)
501
Alex Klein231d2da2019-07-22 16:44:45 -0600502 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
503 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600504
505 actual = [
506 os.path.relpath(artifact.path, self.archive_root)
507 for artifact in self.output_proto.artifacts
508 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600509 expected = ['payload1.bin', 'payload2.bin']
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600510 self.assertItemsEqual(actual, expected)
511
512 actual = [
513 os.path.relpath(path, self.archive_root)
514 for path in osutils.DirectoryIterator(self.archive_root)
515 ]
516 self.assertItemsEqual(actual, expected)
517
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600518 def testBundleTestUpdatePayloadsNoImageDir(self):
519 """BundleTestUpdatePayloads dies if no image dir is found."""
520 # Intentionally do not write image directory.
521 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600522 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
523 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600524
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600525 def testBundleTestUpdatePayloadsNoImage(self):
526 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600527 # Intentionally do not write image, but create the directory.
528 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600529 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600530 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
531 self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600532
533
Alex Klein231d2da2019-07-22 16:44:45 -0600534class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase,
535 api_config.ApiConfigMixin):
Alex Klein2275d692019-04-23 16:04:12 -0600536 """BundleSimpleChromeArtifacts tests."""
537
538 def setUp(self):
539 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
540 self.sysroot_path = '/sysroot'
541 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
542 osutils.SafeMakedirs(self.sysroot_dir)
543 self.output_dir = os.path.join(self.tempdir, 'output_dir')
544 osutils.SafeMakedirs(self.output_dir)
545
546 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
547
Alex Klein231d2da2019-07-22 16:44:45 -0600548 self.response = artifacts_pb2.BundleResponse()
549
Alex Klein2275d692019-04-23 16:04:12 -0600550 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
551 output_dir=None):
552 """Helper to create a request message instance.
553
554 Args:
555 chroot (str): The chroot path.
556 sysroot (str): The sysroot path.
557 build_target (str): The build target name.
558 output_dir (str): The output directory.
559 """
560 return artifacts_pb2.BundleRequest(
561 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
562 chroot={'path': chroot}, output_dir=output_dir)
563
Alex Klein231d2da2019-07-22 16:44:45 -0600564 def testValidateOnly(self):
565 """Sanity check that a validate only call does not execute any logic."""
566 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
567 request = self._GetRequest(chroot=self.chroot_dir,
568 sysroot=self.sysroot_path,
569 build_target='board', output_dir=self.output_dir)
570 artifacts.BundleSimpleChromeArtifacts(request, self.response,
571 self.validate_only_config)
572 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600573
574 def testNoBuildTarget(self):
575 """Test no build target fails."""
576 request = self._GetRequest(chroot=self.chroot_dir,
577 sysroot=self.sysroot_path,
578 output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600579 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600580 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600581 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600582
583 def testNoSysroot(self):
584 """Test no sysroot fails."""
585 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600586 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600587 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600588 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600589
590 def testSysrootDoesNotExist(self):
591 """Test no sysroot fails."""
592 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
593 sysroot=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600594 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600595 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600596 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600597
598 def testNoOutputDir(self):
599 """Test no output dir fails."""
600 request = self._GetRequest(chroot=self.chroot_dir,
601 sysroot=self.sysroot_path,
602 build_target='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600603 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600604 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600605 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600606
607 def testOutputDirDoesNotExist(self):
608 """Test no output dir fails."""
609 request = self._GetRequest(chroot=self.chroot_dir,
610 sysroot=self.sysroot_path,
611 build_target='board',
612 output_dir=self.does_not_exist)
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 testOutputHandling(self):
618 """Test response output."""
619 files = ['file1', 'file2', 'file3']
620 expected_files = [os.path.join(self.output_dir, f) for f in files]
621 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
622 return_value=expected_files)
623 request = self._GetRequest(chroot=self.chroot_dir,
624 sysroot=self.sysroot_path,
625 build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600626 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600627
Alex Klein231d2da2019-07-22 16:44:45 -0600628 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600629
630 self.assertTrue(response.artifacts)
631 self.assertItemsEqual(expected_files, [a.path for a in response.artifacts])
632
633
Alex Klein231d2da2019-07-22 16:44:45 -0600634class BundleVmFilesTest(cros_test_lib.MockTempDirTestCase,
635 api_config.ApiConfigMixin):
Alex Klein6504eca2019-04-18 15:37:56 -0600636 """BuildVmFiles tests."""
637
Alex Klein231d2da2019-07-22 16:44:45 -0600638 def setUp(self):
639 self.output_dir = os.path.join(self.tempdir, 'output')
640 osutils.SafeMakedirs(self.output_dir)
641
642 self.response = artifacts_pb2.BundleResponse()
643
Alex Klein6504eca2019-04-18 15:37:56 -0600644 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
645 output_dir=None):
646 """Helper to build out an input message instance.
647
648 Args:
649 chroot (str|None): The chroot path.
650 sysroot (str|None): The sysroot path relative to the chroot.
651 test_results_dir (str|None): The test results directory relative to the
652 sysroot.
653 output_dir (str|None): The directory where the results tarball should be
654 saved.
655 """
656 return artifacts_pb2.BundleVmFilesRequest(
657 chroot={'path': chroot}, sysroot={'path': sysroot},
658 test_results_dir=test_results_dir, output_dir=output_dir,
659 )
660
Alex Klein231d2da2019-07-22 16:44:45 -0600661 def testValidateOnly(self):
662 """Sanity check that a validate only call does not execute any logic."""
663 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
664 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
665 test_results_dir='/test/results',
666 output_dir=self.output_dir)
667 artifacts.BundleVmFiles(in_proto, self.response, self.validate_only_config)
668 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600669
670 def testChrootMissing(self):
671 """Test error handling for missing chroot."""
672 in_proto = self._GetInput(sysroot='/build/board',
673 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600674 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600675
676 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600677 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600678
Alex Klein6504eca2019-04-18 15:37:56 -0600679 def testTestResultsDirMissing(self):
680 """Test error handling for missing test results directory."""
681 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
Alex Klein231d2da2019-07-22 16:44:45 -0600682 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600683
684 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600685 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600686
687 def testOutputDirMissing(self):
688 """Test error handling for missing output directory."""
689 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
690 test_results_dir='/test/results')
Alex Klein6504eca2019-04-18 15:37:56 -0600691
692 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600693 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
694
695 def testOutputDirDoesNotExist(self):
696 """Test error handling for output directory that does not exist."""
697 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
698 output_dir=os.path.join(self.tempdir, 'dne'),
699 test_results_dir='/test/results')
700
701 with self.assertRaises(cros_build_lib.DieSystemExit):
702 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600703
704 def testValidCall(self):
705 """Test image dir building."""
706 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
707 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600708 output_dir=self.output_dir)
709
Alex Klein6504eca2019-04-18 15:37:56 -0600710 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600711 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600712 return_value=expected_files)
713
Alex Klein231d2da2019-07-22 16:44:45 -0600714 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600715
Alex Klein231d2da2019-07-22 16:44:45 -0600716 patch.assert_called_with(mock.ANY, '/test/results', self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600717
718 # Make sure we have artifacts, and that every artifact is an expected file.
Alex Klein231d2da2019-07-22 16:44:45 -0600719 self.assertTrue(self.response.artifacts)
720 for artifact in self.response.artifacts:
Alex Klein6504eca2019-04-18 15:37:56 -0600721 self.assertIn(artifact.path, expected_files)
722 expected_files.remove(artifact.path)
723
724 # Make sure we've seen all of the expected files.
725 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700726
Alex Kleinb9d810b2019-07-01 12:38:02 -0600727
Tiancong Wang50b80a92019-08-01 14:46:15 -0700728
729class BundleAFDOGenerationArtifactsTestCase(
Alex Klein231d2da2019-07-22 16:44:45 -0600730 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700731 """Unittests for BundleAFDOGenerationArtifacts."""
732
733 @staticmethod
734 def mock_die(message, *args):
735 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700736
737 def setUp(self):
738 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
739 osutils.SafeMakedirs(self.chroot_dir)
740 temp_dir = os.path.join(self.chroot_dir, 'tmp')
741 osutils.SafeMakedirs(temp_dir)
742 self.output_dir = os.path.join(self.tempdir, 'output_dir')
743 osutils.SafeMakedirs(self.output_dir)
744 self.build_target = 'board'
Tiancong Wang50b80a92019-08-01 14:46:15 -0700745 self.valid_artifact_type = artifacts_pb2.ORDERFILE
746 self.invalid_artifact_type = artifacts_pb2.NONE_TYPE
Tiancong Wangc4805b72019-06-11 12:12:03 -0700747 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700748 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700749
Alex Klein231d2da2019-07-22 16:44:45 -0600750 self.response = artifacts_pb2.BundleResponse()
751
Tiancong Wang50b80a92019-08-01 14:46:15 -0700752 def _GetRequest(self, chroot=None, build_target=None, output_dir=None,
753 artifact_type=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700754 """Helper to create a request message instance.
755
756 Args:
757 chroot (str): The chroot path.
758 build_target (str): The build target name.
759 output_dir (str): The output directory.
Tiancong Wang50b80a92019-08-01 14:46:15 -0700760 artifact_type (artifacts_pb2.AFDOArtifactType):
761 The type of the artifact.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700762 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700763 return artifacts_pb2.BundleChromeAFDORequest(
Tiancong Wangc4805b72019-06-11 12:12:03 -0700764 chroot={'path': chroot},
Tiancong Wang50b80a92019-08-01 14:46:15 -0700765 build_target={'name': build_target},
766 output_dir=output_dir,
767 artifact_type=artifact_type,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700768 )
769
Alex Klein231d2da2019-07-22 16:44:45 -0600770 def testValidateOnly(self):
771 """Sanity check that a validate only call does not execute any logic."""
772 patch = self.PatchObject(artifacts_svc,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700773 'BundleAFDOGenerationArtifacts')
Alex Klein231d2da2019-07-22 16:44:45 -0600774 request = self._GetRequest(chroot=self.chroot_dir,
775 build_target=self.build_target,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700776 output_dir=self.output_dir,
777 artifact_type=self.valid_artifact_type)
778 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
779 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600780 patch.assert_not_called()
Tiancong Wangc4805b72019-06-11 12:12:03 -0700781
782 def testNoBuildTarget(self):
783 """Test no build target fails."""
784 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700785 output_dir=self.output_dir,
786 artifact_type=self.valid_artifact_type)
787 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
788 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
789 self.api_config)
790 self.assertEqual('build_target.name is required.',
791 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700792
793 def testNoOutputDir(self):
794 """Test no output dir fails."""
795 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700796 build_target=self.build_target,
797 artifact_type=self.valid_artifact_type)
798 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
799 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
800 self.api_config)
801 self.assertEqual('output_dir is required.',
802 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700803
804 def testOutputDirDoesNotExist(self):
805 """Test output directory not existing fails."""
806 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700807 build_target=self.build_target,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700808 output_dir=self.does_not_exist,
809 artifact_type=self.valid_artifact_type)
810 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
811 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
812 self.api_config)
813 self.assertEqual(
814 'output_dir path does not exist: %s' % self.does_not_exist,
815 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700816
Tiancong Wang50b80a92019-08-01 14:46:15 -0700817 def testNoArtifactType(self):
818 """Test no artifact type."""
819 request = self._GetRequest(chroot=self.chroot_dir,
820 build_target=self.build_target,
821 output_dir=self.output_dir)
822 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
823 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
824 self.api_config)
825 self.assertIn('artifact_type (0) must be in',
826 str(context.exception))
827
828 def testWrongArtifactType(self):
829 """Test passing wrong artifact type."""
830 request = self._GetRequest(chroot=self.chroot_dir,
831 build_target=self.build_target,
832 output_dir=self.output_dir,
833 artifact_type=self.invalid_artifact_type)
834 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
835 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
836 self.api_config)
837 # FIXME(tcwang): The error message here should print the error message
838 # of the artifact_type not in valid list. But instead, it reports
839 # no artifact_type specified.
840 self.assertIn('artifact_type (0) must be in',
841 str(context.exception))
842
843 def testOutputHandlingOnOrderfile(self,
844 artifact_type=artifacts_pb2.ORDERFILE):
845 """Test response output for orderfile."""
846 files = ['artifact1', 'artifact2', 'artifact3']
Tiancong Wangc4805b72019-06-11 12:12:03 -0700847 expected_files = [os.path.join(self.output_dir, f) for f in files]
Tiancong Wang50b80a92019-08-01 14:46:15 -0700848 self.PatchObject(artifacts_svc, 'BundleAFDOGenerationArtifacts',
Tiancong Wangc4805b72019-06-11 12:12:03 -0700849 return_value=expected_files)
Alex Klein231d2da2019-07-22 16:44:45 -0600850
Tiancong Wangc4805b72019-06-11 12:12:03 -0700851 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700852 build_target=self.build_target,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700853 output_dir=self.output_dir,
854 artifact_type=artifact_type)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700855
Tiancong Wang50b80a92019-08-01 14:46:15 -0700856 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
857 self.api_config)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700858
Tiancong Wang50b80a92019-08-01 14:46:15 -0700859 self.assertTrue(self.response.artifacts)
860 self.assertItemsEqual(expected_files,
861 [a.path for a in self.response.artifacts])
862
863 def testOutputHandlingOnAFDO(self):
864 """Test response output for AFDO."""
865 self.testOutputHandlingOnOrderfile(
866 artifact_type=artifacts_pb2.BENCHMARK_AFDO)
Alex Klein0b1cbfc2019-08-14 10:09:58 -0600867
868
869class ExportCpeReportTest(cros_test_lib.MockTempDirTestCase,
870 api_config.ApiConfigMixin):
871 """ExportCpeReport tests."""
872
873 def setUp(self):
874 self.response = artifacts_pb2.BundleResponse()
875
876 def testValidateOnly(self):
877 """Sanity check validate only calls don't execute."""
878 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
879
880 request = artifacts_pb2.BundleRequest()
881 request.build_target.name = 'board'
882 request.output_dir = self.tempdir
883
884 artifacts.ExportCpeReport(request, self.response, self.validate_only_config)
885
886 patch.assert_not_called()
887
888 def testNoBuildTarget(self):
889 request = artifacts_pb2.BundleRequest()
890 request.output_dir = self.tempdir
891
892 with self.assertRaises(cros_build_lib.DieSystemExit):
893 artifacts.ExportCpeReport(request, self.response, self.api_config)
894
895 def testSuccess(self):
896 """Test success case."""
897 expected = artifacts_svc.CpeResult(
898 report='/output/report.json', warnings='/output/warnings.json')
899 self.PatchObject(artifacts_svc, 'GenerateCpeReport', return_value=expected)
900
901 request = artifacts_pb2.BundleRequest()
902 request.build_target.name = 'board'
903 request.output_dir = self.tempdir
904
905 artifacts.ExportCpeReport(request, self.response, self.api_config)
906
907 for artifact in self.response.artifacts:
908 self.assertIn(artifact.path, [expected.report, expected.warnings])