blob: ab8f5581686780abb30a89a83f3cfb65aadd503d [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
Alex Klein238d8862019-05-07 11:32:46 -060079 # Old style proto.
80 self.input_proto = artifacts_pb2.BundleRequest()
81 self.input_proto.build_target.name = 'target'
82 self.input_proto.output_dir = self.output_dir
83 self.output_proto = artifacts_pb2.BundleResponse()
84
Alex Kleine21a0952019-08-23 16:08:16 -060085 self.chroot_path = os.path.join(self.tempdir, 'chroot')
86 self.PatchObject(constants, 'DEFAULT_CHROOT_PATH', new=self.chroot_path)
Alex Klein238d8862019-05-07 11:32:46 -060087
88 # New style paths.
Alex Klein238d8862019-05-07 11:32:46 -060089 self.sysroot_path = '/build/target'
Alex Kleine21a0952019-08-23 16:08:16 -060090 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
91 full_sysroot_path = os.path.join(self.chroot_path,
92 self.sysroot_path.lstrip(os.sep))
93 osutils.SafeMakedirs(full_sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -060094
95 # New style proto.
96 self.request = artifacts_pb2.BundleRequest()
97 self.request.output_dir = self.output_dir
98 self.request.chroot.path = self.chroot_path
99 self.request.sysroot.path = self.sysroot_path
100 self.response = artifacts_pb2.BundleResponse()
101
102
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600103class BundleImageZipTest(BundleTestCase):
104 """Unittests for BundleImageZip."""
105
Alex Klein231d2da2019-07-22 16:44:45 -0600106 def testValidateOnly(self):
107 """Sanity check that a validate only call does not execute any logic."""
108 patch = self.PatchObject(commands, 'BuildImageZip')
109 artifacts.BundleImageZip(self.input_proto, self.output_proto,
110 self.validate_only_config)
111 patch.assert_not_called()
112
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600113 def testBundleImageZip(self):
114 """BundleImageZip calls cbuildbot/commands with correct args."""
Michael Mortensen01910922019-07-24 14:48:10 -0600115 bundle_image_zip = self.PatchObject(
116 artifacts_svc, 'BundleImageZip', return_value='image.zip')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600117 self.PatchObject(os.path, 'exists', return_value=True)
Alex Klein231d2da2019-07-22 16:44:45 -0600118 artifacts.BundleImageZip(self.input_proto, self.output_proto,
119 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600120 self.assertEqual(
121 [artifact.path for artifact in self.output_proto.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600122 [os.path.join(self.output_dir, 'image.zip')])
123
124 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600125 self.assertEqual(
Michael Mortensen01910922019-07-24 14:48:10 -0600126 bundle_image_zip.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600127 [mock.call(self.output_dir, latest)])
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600128
129 def testBundleImageZipNoImageDir(self):
130 """BundleImageZip dies when image dir does not exist."""
131 self.PatchObject(os.path, 'exists', return_value=False)
132 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600133 artifacts.BundleImageZip(self.input_proto, self.output_proto,
134 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600135
136
Alex Klein238d8862019-05-07 11:32:46 -0600137class BundleAutotestFilesTest(BundleTempDirTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600138 """Unittests for BundleAutotestFiles."""
139
Alex Klein231d2da2019-07-22 16:44:45 -0600140 def testValidateOnly(self):
141 """Sanity check that a validate only call does not execute any logic."""
142 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
143 artifacts.BundleAutotestFiles(self.input_proto, self.output_proto,
144 self.validate_only_config)
145 patch.assert_not_called()
146
Alex Klein238d8862019-05-07 11:32:46 -0600147 def testBundleAutotestFilesLegacy(self):
148 """BundleAutotestFiles calls service correctly with legacy args."""
149 files = {
150 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
151 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
152 }
153 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
154 return_value=files)
155
156 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
Alex Kleine21a0952019-08-23 16:08:16 -0600157 return_value=self.sysroot)
Alex Klein231d2da2019-07-22 16:44:45 -0600158 artifacts.BundleAutotestFiles(self.input_proto, self.output_proto,
159 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600160
161 # Verify the sysroot is being built out correctly.
Alex Kleine21a0952019-08-23 16:08:16 -0600162 sysroot_patch.assert_called_with(self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600163
164 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600165 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600166
167 # Verify the output proto is being populated correctly.
168 self.assertTrue(self.output_proto.artifacts)
169 paths = [artifact.path for artifact in self.output_proto.artifacts]
170 self.assertItemsEqual(files.values(), paths)
171
172 def testBundleAutotestFiles(self):
173 """BundleAutotestFiles calls service correctly."""
174 files = {
175 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
176 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
177 }
178 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
179 return_value=files)
180
181 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
182 return_value=self.sysroot)
Alex Klein231d2da2019-07-22 16:44:45 -0600183 artifacts.BundleAutotestFiles(self.request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600184
185 # Verify the sysroot is being built out correctly.
Alex Kleine21a0952019-08-23 16:08:16 -0600186 sysroot_patch.assert_called_with(self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600187
188 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600189 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600190
191 # Verify the output proto is being populated correctly.
192 self.assertTrue(self.response.artifacts)
193 paths = [artifact.path for artifact in self.response.artifacts]
194 self.assertItemsEqual(files.values(), paths)
195
196 def testInvalidOutputDir(self):
197 """Test invalid output directory argument."""
198 request = self._GetRequest(chroot=self.chroot_path,
199 sysroot=self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600200
201 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600202 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600203
204 def testInvalidSysroot(self):
205 """Test no sysroot directory."""
206 request = self._GetRequest(chroot=self.chroot_path,
207 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600208
209 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600210 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600211
212 def testSysrootDoesNotExist(self):
213 """Test dies when no sysroot does not exist."""
214 request = self._GetRequest(chroot=self.chroot_path,
215 sysroot='/does/not/exist',
216 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600217
218 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600219 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600220
221
222class BundleTastFilesTest(BundleTestCase):
223 """Unittests for BundleTastFiles."""
224
Alex Klein231d2da2019-07-22 16:44:45 -0600225 def testValidateOnly(self):
226 """Sanity check that a validate only call does not execute any logic."""
227 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
228 artifacts.BundleTastFiles(self.input_proto, self.output_proto,
229 self.validate_only_config)
230 patch.assert_not_called()
231
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600232 def testBundleTastFilesNoLogs(self):
233 """BundleTasteFiles dies when no tast files found."""
234 self.PatchObject(commands, 'BuildTastBundleTarball',
235 return_value=None)
236 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600237 artifacts.BundleTastFiles(self.input_proto, self.output_proto,
238 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600239
Alex Kleinb9d810b2019-07-01 12:38:02 -0600240 def testBundleTastFilesLegacy(self):
241 """BundleTastFiles handles legacy args correctly."""
242 buildroot = self.tempdir
243 chroot_dir = os.path.join(buildroot, 'chroot')
244 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
245 output_dir = os.path.join(self.tempdir, 'results')
246 osutils.SafeMakedirs(sysroot_path)
247 osutils.SafeMakedirs(output_dir)
248
Alex Klein171da612019-08-06 14:00:42 -0600249 chroot = chroot_lib.Chroot(chroot_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600250 sysroot = sysroot_lib.Sysroot('/build/board')
251
252 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
253 # Patch the service being called.
254 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
255 return_value=expected_archive)
256 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
257
258 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
259 output_dir=output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600260 artifacts.BundleTastFiles(request, self.output_proto, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600261 self.assertEqual(
262 [artifact.path for artifact in self.output_proto.artifacts],
263 [expected_archive])
264 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
265
266 def testBundleTastFiles(self):
267 """BundleTastFiles calls service correctly."""
268 # Setup.
269 sysroot_path = os.path.join(self.tempdir, 'sysroot')
270 output_dir = os.path.join(self.tempdir, 'results')
271 osutils.SafeMakedirs(sysroot_path)
272 osutils.SafeMakedirs(output_dir)
273
274 chroot = chroot_lib.Chroot(self.tempdir, env={'FEATURES': 'separatedebug'})
275 sysroot = sysroot_lib.Sysroot('/sysroot')
276
277 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
278 # Patch the service being called.
279 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
280 return_value=expected_archive)
281
282 # Request and response building.
283 request = artifacts_pb2.BundleRequest(chroot={'path': self.tempdir},
284 sysroot={'path': '/sysroot'},
285 output_dir=output_dir)
286 response = artifacts_pb2.BundleResponse()
287
Alex Klein231d2da2019-07-22 16:44:45 -0600288 artifacts.BundleTastFiles(request, response, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600289
290 # Make sure the artifact got recorded successfully.
291 self.assertTrue(response.artifacts)
292 self.assertEqual(expected_archive, response.artifacts[0].path)
293 # Make sure the service got called correctly.
294 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
295
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600296
297class BundlePinnedGuestImagesTest(BundleTestCase):
298 """Unittests for BundlePinnedGuestImages."""
299
Alex Klein231d2da2019-07-22 16:44:45 -0600300 def testValidateOnly(self):
301 """Sanity check that a validate only call does not execute any logic."""
302 patch = self.PatchObject(commands, 'BuildPinnedGuestImagesTarball')
303 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto,
304 self.validate_only_config)
305 patch.assert_not_called()
306
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600307 def testBundlePinnedGuestImages(self):
308 """BundlePinnedGuestImages calls cbuildbot/commands with correct args."""
309 build_pinned_guest_images_tarball = self.PatchObject(
310 commands,
311 'BuildPinnedGuestImagesTarball',
312 return_value='pinned-guest-images.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600313 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto,
314 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600315 self.assertEqual(
316 [artifact.path for artifact in self.output_proto.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600317 [os.path.join(self.output_dir, 'pinned-guest-images.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600318 self.assertEqual(build_pinned_guest_images_tarball.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600319 [mock.call(self.source_root, 'target', self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600320
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600321 def testBundlePinnedGuestImagesNoLogs(self):
Evan Hernandezde445982019-04-22 13:42:34 -0600322 """BundlePinnedGuestImages does not die when no pinned images found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600323 self.PatchObject(commands, 'BuildPinnedGuestImagesTarball',
324 return_value=None)
Alex Klein231d2da2019-07-22 16:44:45 -0600325 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto,
326 self.api_config)
Evan Hernandezde445982019-04-22 13:42:34 -0600327 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600328
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600329
330class BundleFirmwareTest(BundleTestCase):
331 """Unittests for BundleFirmware."""
332
Alex Klein231d2da2019-07-22 16:44:45 -0600333 def testValidateOnly(self):
334 """Sanity check that a validate only call does not execute any logic."""
335 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
336 artifacts.BundleFirmware(self.request, self.response,
337 self.validate_only_config)
338 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000339
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600340 def testBundleFirmware(self):
341 """BundleFirmware calls cbuildbot/commands with correct args."""
Alex Klein231d2da2019-07-22 16:44:45 -0600342 self.PatchObject(
343 artifacts_svc,
344 'BuildFirmwareArchive',
345 return_value=os.path.join(self.output_dir, 'firmware.tar.gz'))
346
347 artifacts.BundleFirmware(self.request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600348 self.assertEqual(
Alex Klein231d2da2019-07-22 16:44:45 -0600349 [artifact.path for artifact in self.response.artifacts],
350 [os.path.join(self.output_dir, 'firmware.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600351
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600352 def testBundleFirmwareNoLogs(self):
353 """BundleFirmware dies when no firmware found."""
354 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
355 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600356 artifacts.BundleFirmware(self.input_proto, self.output_proto,
357 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600358
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600359
360class BundleEbuildLogsTest(BundleTestCase):
361 """Unittests for BundleEbuildLogs."""
362
Alex Klein231d2da2019-07-22 16:44:45 -0600363 def testValidateOnly(self):
364 """Sanity check that a validate only call does not execute any logic."""
365 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
366 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto,
367 self.validate_only_config)
368 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600369
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600370 def testBundleEbuildLogs(self):
371 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600372 bundle_ebuild_logs_tarball = self.PatchObject(
373 artifacts_svc, 'BundleEBuildLogsTarball',
374 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600375 artifacts.BundleEbuildLogs(self.request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600376 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600377 [artifact.path for artifact in self.response.artifacts],
378 [os.path.join(self.request.output_dir, 'ebuild-logs.tar.gz')])
379 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Evan Hernandeza478d802019-04-08 15:08:24 -0600380 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600381 bundle_ebuild_logs_tarball.call_args_list,
382 [mock.call(mock.ANY, sysroot, self.output_dir)])
383
384 def testBundleEBuildLogsOldProto(self):
385 bundle_ebuild_logs_tarball = self.PatchObject(
386 artifacts_svc, 'BundleEBuildLogsTarball',
387 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600388
389 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto,
390 self.api_config)
391
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600392 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
393 self.assertEqual(
394 bundle_ebuild_logs_tarball.call_args_list,
395 [mock.call(mock.ANY, sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600396
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600397 def testBundleEbuildLogsNoLogs(self):
398 """BundleEbuildLogs dies when no logs found."""
399 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
400 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600401 artifacts.BundleEbuildLogs(self.request, self.response, self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600402
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600403
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600404class BundleChromeOSConfigTest(BundleTestCase):
405 """Unittests for BundleChromeOSConfig"""
406
407 def testValidateOnly(self):
408 """Sanity check that a validate only call does not execute any logic."""
409 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
410 artifacts.BundleChromeOSConfig(self.input_proto, self.output_proto,
411 self.validate_only_config)
412 patch.assert_not_called()
413
414 def testBundleChromeOSConfigCallWithSysroot(self):
415 """Call with a request that sets sysroot."""
416 bundle_chromeos_config = self.PatchObject(
417 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
418 artifacts.BundleChromeOSConfig(self.request, self.output_proto,
419 self.api_config)
420 self.assertEqual(
421 [artifact.path for artifact in self.output_proto.artifacts],
422 [os.path.join(self.output_dir, 'config.yaml')])
423
424 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
425 self.assertEqual(bundle_chromeos_config.call_args_list,
426 [mock.call(mock.ANY, sysroot, self.output_dir)])
427
428 def testBundleChromeOSConfigCallWithBuildTarget(self):
429 """Call with a request that sets build_target."""
430 bundle_chromeos_config = self.PatchObject(
431 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
432 artifacts.BundleChromeOSConfig(self.input_proto, self.output_proto,
433 self.api_config)
434
435 self.assertEqual(
436 [artifact.path for artifact in self.output_proto.artifacts],
437 [os.path.join(self.output_dir, 'config.yaml')])
438
439 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
440 self.assertEqual(bundle_chromeos_config.call_args_list,
441 [mock.call(mock.ANY, sysroot, self.output_dir)])
442
443 def testBundleChromeOSConfigNoConfigFound(self):
444 """An error is raised if the config payload isn't found."""
445 self.PatchObject(artifacts_svc, 'BundleChromeOSConfig', return_value=None)
446
447 with self.assertRaises(cros_build_lib.DieSystemExit):
448 artifacts.BundleChromeOSConfig(self.request, self.output_proto,
449 self.api_config)
450
451
Alex Klein231d2da2019-07-22 16:44:45 -0600452class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase,
453 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600454 """Unittests for BundleTestUpdatePayloads."""
455
456 def setUp(self):
457 self.source_root = os.path.join(self.tempdir, 'cros')
458 osutils.SafeMakedirs(self.source_root)
459
460 self.archive_root = os.path.join(self.tempdir, 'output')
461 osutils.SafeMakedirs(self.archive_root)
462
463 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600464 self.image_root = os.path.join(self.source_root,
465 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600466
467 self.input_proto = artifacts_pb2.BundleRequest()
468 self.input_proto.build_target.name = self.target
469 self.input_proto.output_dir = self.archive_root
470 self.output_proto = artifacts_pb2.BundleResponse()
471
472 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
473
Alex Kleincb541e82019-06-26 15:06:11 -0600474 def MockPayloads(image_path, archive_dir):
475 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
476 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
477 return [os.path.join(archive_dir, 'payload1.bin'),
478 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600479
Alex Kleincb541e82019-06-26 15:06:11 -0600480 self.bundle_patch = self.PatchObject(
481 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600482
Alex Klein231d2da2019-07-22 16:44:45 -0600483 def testValidateOnly(self):
484 """Sanity check that a validate only call does not execute any logic."""
485 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
486 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
487 self.validate_only_config)
488 patch.assert_not_called()
489
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600490 def testBundleTestUpdatePayloads(self):
491 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
492 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
493 osutils.WriteFile(image_path, 'image!', makedirs=True)
494
Alex Klein231d2da2019-07-22 16:44:45 -0600495 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
496 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600497
498 actual = [
499 os.path.relpath(artifact.path, self.archive_root)
500 for artifact in self.output_proto.artifacts
501 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600502 expected = ['payload1.bin', 'payload2.bin']
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600503 self.assertItemsEqual(actual, expected)
504
505 actual = [
506 os.path.relpath(path, self.archive_root)
507 for path in osutils.DirectoryIterator(self.archive_root)
508 ]
509 self.assertItemsEqual(actual, expected)
510
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600511 def testBundleTestUpdatePayloadsNoImageDir(self):
512 """BundleTestUpdatePayloads dies if no image dir is found."""
513 # Intentionally do not write image directory.
514 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600515 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
516 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600517
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600518 def testBundleTestUpdatePayloadsNoImage(self):
519 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600520 # Intentionally do not write image, but create the directory.
521 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600522 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600523 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
524 self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600525
526
Alex Klein231d2da2019-07-22 16:44:45 -0600527class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase,
528 api_config.ApiConfigMixin):
Alex Klein2275d692019-04-23 16:04:12 -0600529 """BundleSimpleChromeArtifacts tests."""
530
531 def setUp(self):
532 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
533 self.sysroot_path = '/sysroot'
534 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
535 osutils.SafeMakedirs(self.sysroot_dir)
536 self.output_dir = os.path.join(self.tempdir, 'output_dir')
537 osutils.SafeMakedirs(self.output_dir)
538
539 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
540
Alex Klein231d2da2019-07-22 16:44:45 -0600541 self.response = artifacts_pb2.BundleResponse()
542
Alex Klein2275d692019-04-23 16:04:12 -0600543 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
544 output_dir=None):
545 """Helper to create a request message instance.
546
547 Args:
548 chroot (str): The chroot path.
549 sysroot (str): The sysroot path.
550 build_target (str): The build target name.
551 output_dir (str): The output directory.
552 """
553 return artifacts_pb2.BundleRequest(
554 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
555 chroot={'path': chroot}, output_dir=output_dir)
556
Alex Klein231d2da2019-07-22 16:44:45 -0600557 def testValidateOnly(self):
558 """Sanity check that a validate only call does not execute any logic."""
559 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
560 request = self._GetRequest(chroot=self.chroot_dir,
561 sysroot=self.sysroot_path,
562 build_target='board', output_dir=self.output_dir)
563 artifacts.BundleSimpleChromeArtifacts(request, self.response,
564 self.validate_only_config)
565 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600566
567 def testNoBuildTarget(self):
568 """Test no build target fails."""
569 request = self._GetRequest(chroot=self.chroot_dir,
570 sysroot=self.sysroot_path,
571 output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600572 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600573 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600574 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600575
576 def testNoSysroot(self):
577 """Test no sysroot fails."""
578 request = self._GetRequest(build_target='board', 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 testSysrootDoesNotExist(self):
584 """Test no sysroot fails."""
585 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
586 sysroot=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600587 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600588 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600589 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600590
591 def testNoOutputDir(self):
592 """Test no output dir fails."""
593 request = self._GetRequest(chroot=self.chroot_dir,
594 sysroot=self.sysroot_path,
595 build_target='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600596 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600597 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600598 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600599
600 def testOutputDirDoesNotExist(self):
601 """Test no output dir fails."""
602 request = self._GetRequest(chroot=self.chroot_dir,
603 sysroot=self.sysroot_path,
604 build_target='board',
605 output_dir=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600606 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600607 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600608 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600609
610 def testOutputHandling(self):
611 """Test response output."""
612 files = ['file1', 'file2', 'file3']
613 expected_files = [os.path.join(self.output_dir, f) for f in files]
614 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
615 return_value=expected_files)
616 request = self._GetRequest(chroot=self.chroot_dir,
617 sysroot=self.sysroot_path,
618 build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600619 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600620
Alex Klein231d2da2019-07-22 16:44:45 -0600621 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600622
623 self.assertTrue(response.artifacts)
624 self.assertItemsEqual(expected_files, [a.path for a in response.artifacts])
625
626
Alex Klein231d2da2019-07-22 16:44:45 -0600627class BundleVmFilesTest(cros_test_lib.MockTempDirTestCase,
628 api_config.ApiConfigMixin):
Alex Klein6504eca2019-04-18 15:37:56 -0600629 """BuildVmFiles tests."""
630
Alex Klein231d2da2019-07-22 16:44:45 -0600631 def setUp(self):
632 self.output_dir = os.path.join(self.tempdir, 'output')
633 osutils.SafeMakedirs(self.output_dir)
634
635 self.response = artifacts_pb2.BundleResponse()
636
Alex Klein6504eca2019-04-18 15:37:56 -0600637 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
638 output_dir=None):
639 """Helper to build out an input message instance.
640
641 Args:
642 chroot (str|None): The chroot path.
643 sysroot (str|None): The sysroot path relative to the chroot.
644 test_results_dir (str|None): The test results directory relative to the
645 sysroot.
646 output_dir (str|None): The directory where the results tarball should be
647 saved.
648 """
649 return artifacts_pb2.BundleVmFilesRequest(
650 chroot={'path': chroot}, sysroot={'path': sysroot},
651 test_results_dir=test_results_dir, output_dir=output_dir,
652 )
653
Alex Klein231d2da2019-07-22 16:44:45 -0600654 def testValidateOnly(self):
655 """Sanity check that a validate only call does not execute any logic."""
656 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
657 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
658 test_results_dir='/test/results',
659 output_dir=self.output_dir)
660 artifacts.BundleVmFiles(in_proto, self.response, self.validate_only_config)
661 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600662
663 def testChrootMissing(self):
664 """Test error handling for missing chroot."""
665 in_proto = self._GetInput(sysroot='/build/board',
666 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600667 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600668
669 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600670 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600671
Alex Klein6504eca2019-04-18 15:37:56 -0600672 def testTestResultsDirMissing(self):
673 """Test error handling for missing test results directory."""
674 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
Alex Klein231d2da2019-07-22 16:44:45 -0600675 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600676
677 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600678 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600679
680 def testOutputDirMissing(self):
681 """Test error handling for missing output directory."""
682 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
683 test_results_dir='/test/results')
Alex Klein6504eca2019-04-18 15:37:56 -0600684
685 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600686 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
687
688 def testOutputDirDoesNotExist(self):
689 """Test error handling for output directory that does not exist."""
690 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
691 output_dir=os.path.join(self.tempdir, 'dne'),
692 test_results_dir='/test/results')
693
694 with self.assertRaises(cros_build_lib.DieSystemExit):
695 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600696
697 def testValidCall(self):
698 """Test image dir building."""
699 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
700 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600701 output_dir=self.output_dir)
702
Alex Klein6504eca2019-04-18 15:37:56 -0600703 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600704 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600705 return_value=expected_files)
706
Alex Klein231d2da2019-07-22 16:44:45 -0600707 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600708
Alex Klein231d2da2019-07-22 16:44:45 -0600709 patch.assert_called_with(mock.ANY, '/test/results', self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600710
711 # Make sure we have artifacts, and that every artifact is an expected file.
Alex Klein231d2da2019-07-22 16:44:45 -0600712 self.assertTrue(self.response.artifacts)
713 for artifact in self.response.artifacts:
Alex Klein6504eca2019-04-18 15:37:56 -0600714 self.assertIn(artifact.path, expected_files)
715 expected_files.remove(artifact.path)
716
717 # Make sure we've seen all of the expected files.
718 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700719
Alex Kleinb9d810b2019-07-01 12:38:02 -0600720
Tiancong Wang50b80a92019-08-01 14:46:15 -0700721
722class BundleAFDOGenerationArtifactsTestCase(
Alex Klein231d2da2019-07-22 16:44:45 -0600723 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700724 """Unittests for BundleAFDOGenerationArtifacts."""
725
726 @staticmethod
727 def mock_die(message, *args):
728 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700729
730 def setUp(self):
731 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
732 osutils.SafeMakedirs(self.chroot_dir)
733 temp_dir = os.path.join(self.chroot_dir, 'tmp')
734 osutils.SafeMakedirs(temp_dir)
735 self.output_dir = os.path.join(self.tempdir, 'output_dir')
736 osutils.SafeMakedirs(self.output_dir)
737 self.build_target = 'board'
Tiancong Wang50b80a92019-08-01 14:46:15 -0700738 self.valid_artifact_type = artifacts_pb2.ORDERFILE
739 self.invalid_artifact_type = artifacts_pb2.NONE_TYPE
Tiancong Wangc4805b72019-06-11 12:12:03 -0700740 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700741 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700742
Alex Klein231d2da2019-07-22 16:44:45 -0600743 self.response = artifacts_pb2.BundleResponse()
744
Tiancong Wang50b80a92019-08-01 14:46:15 -0700745 def _GetRequest(self, chroot=None, build_target=None, output_dir=None,
746 artifact_type=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700747 """Helper to create a request message instance.
748
749 Args:
750 chroot (str): The chroot path.
751 build_target (str): The build target name.
752 output_dir (str): The output directory.
Tiancong Wang50b80a92019-08-01 14:46:15 -0700753 artifact_type (artifacts_pb2.AFDOArtifactType):
754 The type of the artifact.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700755 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700756 return artifacts_pb2.BundleChromeAFDORequest(
Tiancong Wangc4805b72019-06-11 12:12:03 -0700757 chroot={'path': chroot},
Tiancong Wang50b80a92019-08-01 14:46:15 -0700758 build_target={'name': build_target},
759 output_dir=output_dir,
760 artifact_type=artifact_type,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700761 )
762
Alex Klein231d2da2019-07-22 16:44:45 -0600763 def testValidateOnly(self):
764 """Sanity check that a validate only call does not execute any logic."""
765 patch = self.PatchObject(artifacts_svc,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700766 'BundleAFDOGenerationArtifacts')
Alex Klein231d2da2019-07-22 16:44:45 -0600767 request = self._GetRequest(chroot=self.chroot_dir,
768 build_target=self.build_target,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700769 output_dir=self.output_dir,
770 artifact_type=self.valid_artifact_type)
771 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
772 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600773 patch.assert_not_called()
Tiancong Wangc4805b72019-06-11 12:12:03 -0700774
775 def testNoBuildTarget(self):
776 """Test no build target fails."""
777 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700778 output_dir=self.output_dir,
779 artifact_type=self.valid_artifact_type)
780 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
781 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
782 self.api_config)
783 self.assertEqual('build_target.name is required.',
784 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700785
786 def testNoOutputDir(self):
787 """Test no output dir fails."""
788 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700789 build_target=self.build_target,
790 artifact_type=self.valid_artifact_type)
791 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
792 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
793 self.api_config)
794 self.assertEqual('output_dir is required.',
795 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700796
797 def testOutputDirDoesNotExist(self):
798 """Test output directory not existing fails."""
799 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700800 build_target=self.build_target,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700801 output_dir=self.does_not_exist,
802 artifact_type=self.valid_artifact_type)
803 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
804 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
805 self.api_config)
806 self.assertEqual(
807 'output_dir path does not exist: %s' % self.does_not_exist,
808 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -0700809
Tiancong Wang50b80a92019-08-01 14:46:15 -0700810 def testNoArtifactType(self):
811 """Test no artifact type."""
812 request = self._GetRequest(chroot=self.chroot_dir,
813 build_target=self.build_target,
814 output_dir=self.output_dir)
815 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
816 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
817 self.api_config)
818 self.assertIn('artifact_type (0) must be in',
819 str(context.exception))
820
821 def testWrongArtifactType(self):
822 """Test passing wrong artifact type."""
823 request = self._GetRequest(chroot=self.chroot_dir,
824 build_target=self.build_target,
825 output_dir=self.output_dir,
826 artifact_type=self.invalid_artifact_type)
827 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
828 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
829 self.api_config)
830 # FIXME(tcwang): The error message here should print the error message
831 # of the artifact_type not in valid list. But instead, it reports
832 # no artifact_type specified.
833 self.assertIn('artifact_type (0) must be in',
834 str(context.exception))
835
836 def testOutputHandlingOnOrderfile(self,
837 artifact_type=artifacts_pb2.ORDERFILE):
838 """Test response output for orderfile."""
839 files = ['artifact1', 'artifact2', 'artifact3']
Tiancong Wangc4805b72019-06-11 12:12:03 -0700840 expected_files = [os.path.join(self.output_dir, f) for f in files]
Tiancong Wang50b80a92019-08-01 14:46:15 -0700841 self.PatchObject(artifacts_svc, 'BundleAFDOGenerationArtifacts',
Tiancong Wangc4805b72019-06-11 12:12:03 -0700842 return_value=expected_files)
Alex Klein231d2da2019-07-22 16:44:45 -0600843
Tiancong Wangc4805b72019-06-11 12:12:03 -0700844 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700845 build_target=self.build_target,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700846 output_dir=self.output_dir,
847 artifact_type=artifact_type)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700848
Tiancong Wang50b80a92019-08-01 14:46:15 -0700849 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
850 self.api_config)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700851
Tiancong Wang50b80a92019-08-01 14:46:15 -0700852 self.assertTrue(self.response.artifacts)
853 self.assertItemsEqual(expected_files,
854 [a.path for a in self.response.artifacts])
855
856 def testOutputHandlingOnAFDO(self):
857 """Test response output for AFDO."""
858 self.testOutputHandlingOnOrderfile(
859 artifact_type=artifacts_pb2.BENCHMARK_AFDO)
Alex Klein0b1cbfc2019-08-14 10:09:58 -0600860
861
862class ExportCpeReportTest(cros_test_lib.MockTempDirTestCase,
863 api_config.ApiConfigMixin):
864 """ExportCpeReport tests."""
865
866 def setUp(self):
867 self.response = artifacts_pb2.BundleResponse()
868
869 def testValidateOnly(self):
870 """Sanity check validate only calls don't execute."""
871 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
872
873 request = artifacts_pb2.BundleRequest()
874 request.build_target.name = 'board'
875 request.output_dir = self.tempdir
876
877 artifacts.ExportCpeReport(request, self.response, self.validate_only_config)
878
879 patch.assert_not_called()
880
881 def testNoBuildTarget(self):
882 request = artifacts_pb2.BundleRequest()
883 request.output_dir = self.tempdir
884
885 with self.assertRaises(cros_build_lib.DieSystemExit):
886 artifacts.ExportCpeReport(request, self.response, self.api_config)
887
888 def testSuccess(self):
889 """Test success case."""
890 expected = artifacts_svc.CpeResult(
891 report='/output/report.json', warnings='/output/warnings.json')
892 self.PatchObject(artifacts_svc, 'GenerateCpeReport', return_value=expected)
893
894 request = artifacts_pb2.BundleRequest()
895 request.build_target.name = 'board'
896 request.output_dir = self.tempdir
897
898 artifacts.ExportCpeReport(request, self.response, self.api_config)
899
900 for artifact in self.response.artifacts:
901 self.assertIn(artifact.path, [expected.report, expected.warnings])