blob: 1d6267ff116d4ebb08b3c305fc4da77675b7d3c5 [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
Michael Mortensen2d6a2402019-11-26 13:40:40 -070010import collections
Evan Hernandezf388cbf2019-04-01 11:15:23 -060011import os
Mike Frysingeref94e4c2020-02-10 23:59:54 -050012import sys
Evan Hernandezf388cbf2019-04-01 11:15:23 -060013
Mike Frysinger6db648e2018-07-24 19:57:58 -040014import mock
15
Alex Klein231d2da2019-07-22 16:44:45 -060016from chromite.api import api_config
Evan Hernandezf388cbf2019-04-01 11:15:23 -060017from chromite.api.controller import artifacts
18from chromite.api.gen.chromite.api import artifacts_pb2
Tiancong Wang24a3df72019-08-20 15:48:51 -070019from chromite.api.gen.chromite.api import toolchain_pb2
Evan Hernandezf388cbf2019-04-01 11:15:23 -060020from chromite.cbuildbot import commands
Alex Kleinb9d810b2019-07-01 12:38:02 -060021from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060022from chromite.lib import constants
23from chromite.lib import cros_build_lib
24from chromite.lib import cros_test_lib
25from chromite.lib import osutils
Alex Klein238d8862019-05-07 11:32:46 -060026from chromite.lib import sysroot_lib
Alex Klein2275d692019-04-23 16:04:12 -060027from chromite.service import artifacts as artifacts_svc
Evan Hernandezf388cbf2019-04-01 11:15:23 -060028
29
Mike Frysingeref94e4c2020-02-10 23:59:54 -050030assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'
31
32
Michael Mortensen2d6a2402019-11-26 13:40:40 -070033PinnedGuestImage = collections.namedtuple('PinnedGuestImage',
34 ['filename', 'uri'])
35
36
Alex Kleind91e95a2019-09-17 10:39:02 -060037class BundleRequestMixin(object):
38 """Mixin to provide bundle request methods."""
39
40 def EmptyRequest(self):
41 return artifacts_pb2.BundleRequest()
42
43 def BuildTargetRequest(self, build_target=None, output_dir=None, chroot=None):
44 """Get a build target format request instance."""
45 request = self.EmptyRequest()
46 if build_target:
47 request.build_target.name = build_target
48 if output_dir:
49 request.output_dir = output_dir
50 if chroot:
51 request.chroot.path = chroot
52
53 return request
54
55 def SysrootRequest(self,
56 sysroot=None,
57 build_target=None,
58 output_dir=None,
59 chroot=None):
60 """Get a sysroot format request instance."""
61 request = self.EmptyRequest()
62 if sysroot:
63 request.sysroot.path = sysroot
64 if build_target:
65 request.sysroot.build_target.name = build_target
66 if output_dir:
67 request.output_dir = output_dir
68 if chroot:
69 request.chroot.path = chroot
70
71 return request
72
73
Alex Klein231d2da2019-07-22 16:44:45 -060074class BundleTestCase(cros_test_lib.MockTempDirTestCase,
Alex Kleind91e95a2019-09-17 10:39:02 -060075 api_config.ApiConfigMixin, BundleRequestMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060076 """Basic setup for all artifacts unittests."""
77
78 def setUp(self):
Alex Klein231d2da2019-07-22 16:44:45 -060079 self.output_dir = os.path.join(self.tempdir, 'artifacts')
80 osutils.SafeMakedirs(self.output_dir)
81 self.sysroot_path = '/build/target'
Alex Klein68c8fdf2019-09-25 15:09:11 -060082 self.sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Alex Klein231d2da2019-07-22 16:44:45 -060083 self.chroot_path = os.path.join(self.tempdir, 'chroot')
84 full_sysroot_path = os.path.join(self.chroot_path,
85 self.sysroot_path.lstrip(os.sep))
86 osutils.SafeMakedirs(full_sysroot_path)
87
Alex Klein68c8fdf2019-09-25 15:09:11 -060088 # All requests use same response type.
Alex Klein231d2da2019-07-22 16:44:45 -060089 self.response = artifacts_pb2.BundleResponse()
90
Alex Klein68c8fdf2019-09-25 15:09:11 -060091 # Build target request.
92 self.target_request = self.BuildTargetRequest(
93 build_target='target',
94 output_dir=self.output_dir,
95 chroot=self.chroot_path)
96
97 # Sysroot request.
98 self.sysroot_request = self.SysrootRequest(
99 sysroot=self.sysroot_path,
100 build_target='target',
101 output_dir=self.output_dir,
102 chroot=self.chroot_path)
103
Alex Klein231d2da2019-07-22 16:44:45 -0600104 self.source_root = self.tempdir
105 self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600106
107
Alex Kleind91e95a2019-09-17 10:39:02 -0600108class BundleImageArchivesTest(BundleTestCase):
109 """BundleImageArchives tests."""
110
111 def testValidateOnly(self):
112 """Sanity check that a validate only call does not execute any logic."""
113 patch = self.PatchObject(artifacts_svc, 'ArchiveImages')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600114 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600115 self.validate_only_config)
116 patch.assert_not_called()
117
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700118 def testMockCall(self):
119 """Test that a mock call does not execute logic, returns mocked value."""
120 patch = self.PatchObject(artifacts_svc, 'ArchiveImages')
121 artifacts.BundleImageArchives(self.target_request, self.response,
122 self.mock_call_config)
123 patch.assert_not_called()
124 self.assertEqual(len(self.response.artifacts), 2)
125 self.assertEqual(self.response.artifacts[0].path,
126 os.path.join(self.output_dir, 'path0.tar.xz'))
127 self.assertEqual(self.response.artifacts[1].path,
128 os.path.join(self.output_dir, 'path1.tar.xz'))
129
Alex Kleind91e95a2019-09-17 10:39:02 -0600130 def testNoBuildTarget(self):
131 """Test that no build target fails."""
132 request = self.BuildTargetRequest(output_dir=self.tempdir)
133 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600134 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600135
136 def testNoOutputDir(self):
137 """Test no output dir fails."""
138 request = self.BuildTargetRequest(build_target='board')
139 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600140 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600141
142 def testInvalidOutputDir(self):
143 """Test invalid output dir fails."""
144 request = self.BuildTargetRequest(
145 build_target='board', output_dir=os.path.join(self.tempdir, 'DNE'))
146 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600147 artifacts.BundleImageArchives(request, self.response, self.api_config)
Alex Kleind91e95a2019-09-17 10:39:02 -0600148
149 def testOutputHandling(self):
150 """Test the artifact output handling."""
151 expected = [os.path.join(self.output_dir, f) for f in ('a', 'b', 'c')]
152 self.PatchObject(artifacts_svc, 'ArchiveImages', return_value=expected)
153 self.PatchObject(os.path, 'exists', return_value=True)
154
Alex Klein68c8fdf2019-09-25 15:09:11 -0600155 artifacts.BundleImageArchives(self.target_request, self.response,
Alex Kleind91e95a2019-09-17 10:39:02 -0600156 self.api_config)
157
Mike Frysinger678735c2019-09-28 18:23:28 -0400158 self.assertCountEqual(expected, [a.path for a in self.response.artifacts])
Alex Kleind91e95a2019-09-17 10:39:02 -0600159
160
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600161class BundleImageZipTest(BundleTestCase):
162 """Unittests for BundleImageZip."""
163
Alex Klein231d2da2019-07-22 16:44:45 -0600164 def testValidateOnly(self):
165 """Sanity check that a validate only call does not execute any logic."""
166 patch = self.PatchObject(commands, 'BuildImageZip')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600167 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600168 self.validate_only_config)
169 patch.assert_not_called()
170
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700171 def testMockCall(self):
172 """Test that a mock call does not execute logic, returns mocked value."""
173 patch = self.PatchObject(commands, 'BuildImageZip')
174 artifacts.BundleImageZip(self.target_request, self.response,
175 self.mock_call_config)
176 patch.assert_not_called()
177 self.assertEqual(len(self.response.artifacts), 1)
178 self.assertEqual(self.response.artifacts[0].path,
179 os.path.join(self.output_dir, 'image.zip'))
180
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600181 def testBundleImageZip(self):
182 """BundleImageZip calls cbuildbot/commands with correct args."""
Michael Mortensen01910922019-07-24 14:48:10 -0600183 bundle_image_zip = self.PatchObject(
184 artifacts_svc, 'BundleImageZip', return_value='image.zip')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600185 self.PatchObject(os.path, 'exists', return_value=True)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600186 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600187 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600188 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600189 [artifact.path for artifact in self.response.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600190 [os.path.join(self.output_dir, 'image.zip')])
191
192 latest = os.path.join(self.source_root, 'src/build/images/target/latest')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600193 self.assertEqual(
Michael Mortensen01910922019-07-24 14:48:10 -0600194 bundle_image_zip.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600195 [mock.call(self.output_dir, latest)])
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600196
197 def testBundleImageZipNoImageDir(self):
198 """BundleImageZip dies when image dir does not exist."""
199 self.PatchObject(os.path, 'exists', return_value=False)
200 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600201 artifacts.BundleImageZip(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600202 self.api_config)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600203
204
Alex Klein68c8fdf2019-09-25 15:09:11 -0600205class BundleAutotestFilesTest(BundleTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600206 """Unittests for BundleAutotestFiles."""
207
Alex Klein231d2da2019-07-22 16:44:45 -0600208 def testValidateOnly(self):
209 """Sanity check that a validate only call does not execute any logic."""
210 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600211 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600212 self.validate_only_config)
213 patch.assert_not_called()
214
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700215 def testMockCall(self):
216 """Test that a mock call does not execute logic, returns mocked value."""
217 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles')
218 artifacts.BundleAutotestFiles(self.target_request, self.response,
219 self.mock_call_config)
220 patch.assert_not_called()
221 self.assertEqual(len(self.response.artifacts), 1)
222 self.assertEqual(self.response.artifacts[0].path,
223 os.path.join(self.output_dir, 'autotest-a.tar.gz'))
224
Alex Klein238d8862019-05-07 11:32:46 -0600225 def testBundleAutotestFilesLegacy(self):
226 """BundleAutotestFiles calls service correctly with legacy args."""
227 files = {
228 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
229 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
230 }
231 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
232 return_value=files)
233
Alex Klein68c8fdf2019-09-25 15:09:11 -0600234 artifacts.BundleAutotestFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600235 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600236
Alex Klein238d8862019-05-07 11:32:46 -0600237 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600238 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600239
240 # Verify the output proto is being populated correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600241 self.assertTrue(self.response.artifacts)
242 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400243 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600244
245 def testBundleAutotestFiles(self):
246 """BundleAutotestFiles calls service correctly."""
247 files = {
248 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
249 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
250 }
251 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
252 return_value=files)
253
Alex Klein68c8fdf2019-09-25 15:09:11 -0600254 artifacts.BundleAutotestFiles(self.sysroot_request, self.response,
255 self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600256
257 # Verify the arguments are being passed through.
Alex Kleine21a0952019-08-23 16:08:16 -0600258 patch.assert_called_with(mock.ANY, self.sysroot, self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600259
260 # Verify the output proto is being populated correctly.
261 self.assertTrue(self.response.artifacts)
262 paths = [artifact.path for artifact in self.response.artifacts]
Mike Frysinger1f4478c2019-10-20 18:33:17 -0400263 self.assertCountEqual(list(files.values()), paths)
Alex Klein238d8862019-05-07 11:32:46 -0600264
265 def testInvalidOutputDir(self):
266 """Test invalid output directory argument."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600267 request = self.SysrootRequest(chroot=self.chroot_path,
268 sysroot=self.sysroot_path)
Alex Klein238d8862019-05-07 11:32:46 -0600269
270 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600271 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600272
273 def testInvalidSysroot(self):
274 """Test no sysroot directory."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600275 request = self.SysrootRequest(chroot=self.chroot_path,
276 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600277
278 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600279 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Alex Klein238d8862019-05-07 11:32:46 -0600280
281 def testSysrootDoesNotExist(self):
282 """Test dies when no sysroot does not exist."""
Alex Klein68c8fdf2019-09-25 15:09:11 -0600283 request = self.SysrootRequest(chroot=self.chroot_path,
284 sysroot='/does/not/exist',
285 output_dir=self.output_dir)
Alex Klein238d8862019-05-07 11:32:46 -0600286
287 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600288 artifacts.BundleAutotestFiles(request, self.response, self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600289
290
291class BundleTastFilesTest(BundleTestCase):
292 """Unittests for BundleTastFiles."""
293
Alex Klein231d2da2019-07-22 16:44:45 -0600294 def testValidateOnly(self):
295 """Sanity check that a validate only call does not execute any logic."""
296 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600297 artifacts.BundleTastFiles(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600298 self.validate_only_config)
299 patch.assert_not_called()
300
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700301 def testMockCall(self):
302 """Test that a mock call does not execute logic, returns mocked value."""
303 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
304 artifacts.BundleTastFiles(self.target_request, self.response,
305 self.mock_call_config)
306 patch.assert_not_called()
307 self.assertEqual(len(self.response.artifacts), 1)
308 self.assertEqual(self.response.artifacts[0].path,
309 os.path.join(self.output_dir, 'tast_bundles.tar.gz'))
310
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600311 def testBundleTastFilesNoLogs(self):
LaMont Jonesb9793cd2020-06-11 08:14:46 -0600312 """BundleTasteFiles succeeds when no tast files found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600313 self.PatchObject(commands, 'BuildTastBundleTarball',
314 return_value=None)
LaMont Jonesb9793cd2020-06-11 08:14:46 -0600315 artifacts.BundleTastFiles(self.target_request, self.response,
316 self.api_config)
317 self.assertEqual(list(self.response.artifacts), [])
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600318
Alex Kleinb9d810b2019-07-01 12:38:02 -0600319 def testBundleTastFilesLegacy(self):
320 """BundleTastFiles handles legacy args correctly."""
321 buildroot = self.tempdir
322 chroot_dir = os.path.join(buildroot, 'chroot')
323 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
324 output_dir = os.path.join(self.tempdir, 'results')
325 osutils.SafeMakedirs(sysroot_path)
326 osutils.SafeMakedirs(output_dir)
327
Alex Klein171da612019-08-06 14:00:42 -0600328 chroot = chroot_lib.Chroot(chroot_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600329 sysroot = sysroot_lib.Sysroot('/build/board')
330
331 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
332 # Patch the service being called.
333 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
334 return_value=expected_archive)
335 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
336
337 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
338 output_dir=output_dir)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600339 artifacts.BundleTastFiles(request, self.response, self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600340 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600341 [artifact.path for artifact in self.response.artifacts],
Alex Kleinb9d810b2019-07-01 12:38:02 -0600342 [expected_archive])
343 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
344
345 def testBundleTastFiles(self):
346 """BundleTastFiles calls service correctly."""
Alex Kleinb49be8a2019-12-20 10:23:03 -0700347 chroot = chroot_lib.Chroot(self.chroot_path)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600348
Alex Klein68c8fdf2019-09-25 15:09:11 -0600349 expected_archive = os.path.join(self.output_dir,
350 artifacts_svc.TAST_BUNDLE_NAME)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600351 # Patch the service being called.
352 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
353 return_value=expected_archive)
354
Alex Klein68c8fdf2019-09-25 15:09:11 -0600355 artifacts.BundleTastFiles(self.sysroot_request, self.response,
356 self.api_config)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600357
358 # Make sure the artifact got recorded successfully.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600359 self.assertTrue(self.response.artifacts)
360 self.assertEqual(expected_archive, self.response.artifacts[0].path)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600361 # Make sure the service got called correctly.
Alex Klein68c8fdf2019-09-25 15:09:11 -0600362 bundle_patch.assert_called_once_with(chroot, self.sysroot, self.output_dir)
Alex Kleinb9d810b2019-07-01 12:38:02 -0600363
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600364
365class BundlePinnedGuestImagesTest(BundleTestCase):
366 """Unittests for BundlePinnedGuestImages."""
367
Alex Klein231d2da2019-07-22 16:44:45 -0600368 def testValidateOnly(self):
369 """Sanity check that a validate only call does not execute any logic."""
370 patch = self.PatchObject(commands, 'BuildPinnedGuestImagesTarball')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600371 artifacts.BundlePinnedGuestImages(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600372 self.validate_only_config)
373 patch.assert_not_called()
374
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700375 def testMockCall(self):
376 """Test that a mock call does not execute logic, returns mocked value."""
377 patch = self.PatchObject(commands, 'BuildPinnedGuestImagesTarball')
378 artifacts.BundlePinnedGuestImages(self.target_request, self.response,
379 self.mock_call_config)
380 patch.assert_not_called()
381 self.assertEqual(len(self.response.artifacts), 1)
382 self.assertEqual(self.response.artifacts[0].path,
383 os.path.join(self.output_dir,
384 'pinned-guest-images.tar.gz'))
385
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600386 def testBundlePinnedGuestImages(self):
387 """BundlePinnedGuestImages calls cbuildbot/commands with correct args."""
388 build_pinned_guest_images_tarball = self.PatchObject(
389 commands,
390 'BuildPinnedGuestImagesTarball',
391 return_value='pinned-guest-images.tar.gz')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600392 artifacts.BundlePinnedGuestImages(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600393 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600394 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600395 [artifact.path for artifact in self.response.artifacts],
Alex Klein231d2da2019-07-22 16:44:45 -0600396 [os.path.join(self.output_dir, 'pinned-guest-images.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600397 self.assertEqual(build_pinned_guest_images_tarball.call_args_list,
Alex Klein231d2da2019-07-22 16:44:45 -0600398 [mock.call(self.source_root, 'target', self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600399
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600400 def testBundlePinnedGuestImagesNoLogs(self):
Evan Hernandezde445982019-04-22 13:42:34 -0600401 """BundlePinnedGuestImages does not die when no pinned images found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600402 self.PatchObject(commands, 'BuildPinnedGuestImagesTarball',
403 return_value=None)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600404 artifacts.BundlePinnedGuestImages(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600405 self.api_config)
Alex Klein68c8fdf2019-09-25 15:09:11 -0600406 self.assertFalse(self.response.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600407
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600408
Alex Kleinc3e8d0c2020-05-15 11:20:22 -0600409class FetchPinnedGuestImageUrisTest(cros_test_lib.MockTempDirTestCase,
410 api_config.ApiConfigMixin,
411 BundleRequestMixin):
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700412 """Unittests for FetchPinnedGuestImages."""
413
414 def setUp(self):
415 self.build_target = 'board'
416 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
417 self.sysroot_path = '/sysroot'
418 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
419 osutils.SafeMakedirs(self.sysroot_dir)
420
421 self.input_request = artifacts_pb2.PinnedGuestImageUriRequest(
422 sysroot={'path': self.sysroot_path,
423 'build_target': {'name': self.build_target}},
424 chroot={'path': self.chroot_dir})
425
426 self.response = artifacts_pb2.PinnedGuestImageUriResponse()
427
428 def testValidateOnly(self):
429 """Sanity check that a validate only call does not execute any logic."""
430 patch = self.PatchObject(artifacts_svc, 'FetchPinnedGuestImages')
Alex Kleinc3e8d0c2020-05-15 11:20:22 -0600431 artifacts.FetchPinnedGuestImageUris(self.input_request, self.response,
432 self.validate_only_config)
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700433 patch.assert_not_called()
434
435 def testMockCall(self):
436 """Test that a mock call does not execute logic, returns mocked value."""
437 patch = self.PatchObject(artifacts_svc, 'FetchPinnedGuestImages')
Alex Kleinc3e8d0c2020-05-15 11:20:22 -0600438 artifacts.FetchPinnedGuestImageUris(self.input_request, self.response,
439 self.mock_call_config)
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700440 patch.assert_not_called()
441 self.assertEqual(len(self.response.pinned_images), 1)
442 self.assertEqual(self.response.pinned_images[0].filename,
443 'pinned_file.tar.gz')
444 self.assertEqual(self.response.pinned_images[0].uri,
445 'https://testuri.com')
446
447 def testFetchPinnedGuestImages(self):
448 """FetchPinnedGuestImages calls service with correct args."""
449 pins = []
450 pins.append(PinnedGuestImage(
451 filename='my_pinned_file.tar.gz', uri='https://the_testuri.com'))
452 self.PatchObject(artifacts_svc, 'FetchPinnedGuestImages',
453 return_value=pins)
Alex Kleinc3e8d0c2020-05-15 11:20:22 -0600454 artifacts.FetchPinnedGuestImageUris(self.input_request, self.response,
455 self.api_config)
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700456 self.assertEqual(len(self.response.pinned_images), 1)
457 self.assertEqual(self.response.pinned_images[0].filename,
458 'my_pinned_file.tar.gz')
459 self.assertEqual(self.response.pinned_images[0].uri,
460 'https://the_testuri.com')
461
462
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600463class BundleFirmwareTest(BundleTestCase):
464 """Unittests for BundleFirmware."""
465
Alex Klein231d2da2019-07-22 16:44:45 -0600466 def testValidateOnly(self):
467 """Sanity check that a validate only call does not execute any logic."""
468 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600469 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600470 self.validate_only_config)
471 patch.assert_not_called()
Michael Mortensen38675192019-06-28 16:52:55 +0000472
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700473 def testMockCall(self):
474 """Test that a mock call does not execute logic, returns mocked value."""
475 patch = self.PatchObject(artifacts_svc, 'BundleTastFiles')
476 artifacts.BundleFirmware(self.sysroot_request, self.response,
477 self.mock_call_config)
478 patch.assert_not_called()
479 self.assertEqual(len(self.response.artifacts), 1)
480 self.assertEqual(self.response.artifacts[0].path,
481 os.path.join(self.output_dir, 'firmware.tar.gz'))
482
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600483 def testBundleFirmware(self):
484 """BundleFirmware calls cbuildbot/commands with correct args."""
Alex Klein231d2da2019-07-22 16:44:45 -0600485 self.PatchObject(
486 artifacts_svc,
487 'BuildFirmwareArchive',
488 return_value=os.path.join(self.output_dir, 'firmware.tar.gz'))
489
Alex Klein68c8fdf2019-09-25 15:09:11 -0600490 artifacts.BundleFirmware(self.sysroot_request, self.response,
491 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600492 self.assertEqual(
Alex Klein231d2da2019-07-22 16:44:45 -0600493 [artifact.path for artifact in self.response.artifacts],
494 [os.path.join(self.output_dir, 'firmware.tar.gz')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600495
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600496 def testBundleFirmwareNoLogs(self):
497 """BundleFirmware dies when no firmware found."""
498 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
499 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600500 artifacts.BundleFirmware(self.sysroot_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600501 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600502
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600503
504class BundleEbuildLogsTest(BundleTestCase):
505 """Unittests for BundleEbuildLogs."""
506
Alex Klein231d2da2019-07-22 16:44:45 -0600507 def testValidateOnly(self):
508 """Sanity check that a validate only call does not execute any logic."""
509 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600510 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600511 self.validate_only_config)
512 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600513
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700514 def testMockCall(self):
515 """Test that a mock call does not execute logic, returns mocked value."""
516 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
517 artifacts.BundleEbuildLogs(self.target_request, self.response,
518 self.mock_call_config)
519 patch.assert_not_called()
520 self.assertEqual(len(self.response.artifacts), 1)
521 self.assertEqual(self.response.artifacts[0].path,
522 os.path.join(self.output_dir, 'ebuild-logs.tar.gz'))
523
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600524 def testBundleEbuildLogs(self):
525 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600526 bundle_ebuild_logs_tarball = self.PatchObject(
527 artifacts_svc, 'BundleEBuildLogsTarball',
528 return_value='ebuild-logs.tar.gz')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600529 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
530 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600531 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600532 [artifact.path for artifact in self.response.artifacts],
Alex Klein68c8fdf2019-09-25 15:09:11 -0600533 [os.path.join(self.output_dir, 'ebuild-logs.tar.gz')])
Evan Hernandeza478d802019-04-08 15:08:24 -0600534 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600535 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600536 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600537
538 def testBundleEBuildLogsOldProto(self):
539 bundle_ebuild_logs_tarball = self.PatchObject(
540 artifacts_svc, 'BundleEBuildLogsTarball',
541 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600542
Alex Klein68c8fdf2019-09-25 15:09:11 -0600543 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600544 self.api_config)
545
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600546 self.assertEqual(
547 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600548 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600549
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600550 def testBundleEbuildLogsNoLogs(self):
551 """BundleEbuildLogs dies when no logs found."""
552 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
553 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600554 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
555 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600556
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600557
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600558class BundleChromeOSConfigTest(BundleTestCase):
559 """Unittests for BundleChromeOSConfig"""
560
561 def testValidateOnly(self):
562 """Sanity check that a validate only call does not execute any logic."""
563 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600564 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600565 self.validate_only_config)
566 patch.assert_not_called()
567
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700568 def testMockCall(self):
569 """Test that a mock call does not execute logic, returns mocked value."""
570 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
571 artifacts.BundleChromeOSConfig(self.target_request, self.response,
572 self.mock_call_config)
573 patch.assert_not_called()
574 self.assertEqual(len(self.response.artifacts), 1)
575 self.assertEqual(self.response.artifacts[0].path,
576 os.path.join(self.output_dir, 'config.yaml'))
577
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600578 def testBundleChromeOSConfigCallWithSysroot(self):
579 """Call with a request that sets sysroot."""
580 bundle_chromeos_config = self.PatchObject(
581 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600582 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600583 self.api_config)
584 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600585 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600586 [os.path.join(self.output_dir, 'config.yaml')])
587
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600588 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600589 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600590
591 def testBundleChromeOSConfigCallWithBuildTarget(self):
592 """Call with a request that sets build_target."""
593 bundle_chromeos_config = self.PatchObject(
594 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600595 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600596 self.api_config)
597
598 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600599 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600600 [os.path.join(self.output_dir, 'config.yaml')])
601
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600602 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600603 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600604
605 def testBundleChromeOSConfigNoConfigFound(self):
606 """An error is raised if the config payload isn't found."""
607 self.PatchObject(artifacts_svc, 'BundleChromeOSConfig', return_value=None)
608
609 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600610 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600611 self.api_config)
612
613
Alex Klein231d2da2019-07-22 16:44:45 -0600614class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase,
615 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600616 """Unittests for BundleTestUpdatePayloads."""
617
618 def setUp(self):
619 self.source_root = os.path.join(self.tempdir, 'cros')
620 osutils.SafeMakedirs(self.source_root)
621
622 self.archive_root = os.path.join(self.tempdir, 'output')
623 osutils.SafeMakedirs(self.archive_root)
624
625 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600626 self.image_root = os.path.join(self.source_root,
627 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600628
629 self.input_proto = artifacts_pb2.BundleRequest()
630 self.input_proto.build_target.name = self.target
631 self.input_proto.output_dir = self.archive_root
632 self.output_proto = artifacts_pb2.BundleResponse()
633
634 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
635
Alex Kleincb541e82019-06-26 15:06:11 -0600636 def MockPayloads(image_path, archive_dir):
637 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
638 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
639 return [os.path.join(archive_dir, 'payload1.bin'),
640 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600641
Alex Kleincb541e82019-06-26 15:06:11 -0600642 self.bundle_patch = self.PatchObject(
643 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600644
Alex Klein231d2da2019-07-22 16:44:45 -0600645 def testValidateOnly(self):
646 """Sanity check that a validate only call does not execute any logic."""
647 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
648 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
649 self.validate_only_config)
650 patch.assert_not_called()
651
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700652 def testMockCall(self):
653 """Test that a mock call does not execute logic, returns mocked value."""
654 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
655 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
656 self.mock_call_config)
657 patch.assert_not_called()
658 self.assertEqual(len(self.output_proto.artifacts), 1)
659 self.assertEqual(self.output_proto.artifacts[0].path,
660 os.path.join(self.archive_root, 'payload1.bin'))
661
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600662 def testBundleTestUpdatePayloads(self):
663 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
664 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
665 osutils.WriteFile(image_path, 'image!', makedirs=True)
666
Alex Klein231d2da2019-07-22 16:44:45 -0600667 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
668 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600669
670 actual = [
671 os.path.relpath(artifact.path, self.archive_root)
672 for artifact in self.output_proto.artifacts
673 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600674 expected = ['payload1.bin', 'payload2.bin']
Mike Frysinger678735c2019-09-28 18:23:28 -0400675 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600676
677 actual = [
678 os.path.relpath(path, self.archive_root)
679 for path in osutils.DirectoryIterator(self.archive_root)
680 ]
Mike Frysinger678735c2019-09-28 18:23:28 -0400681 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600682
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600683 def testBundleTestUpdatePayloadsNoImageDir(self):
684 """BundleTestUpdatePayloads dies if no image dir is found."""
685 # Intentionally do not write image directory.
Alex Kleind2bf1462019-10-24 16:37:04 -0600686 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
687 self.api_config)
688 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600689
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600690 def testBundleTestUpdatePayloadsNoImage(self):
691 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600692 # Intentionally do not write image, but create the directory.
693 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600694 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600695 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
696 self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600697
698
Alex Klein231d2da2019-07-22 16:44:45 -0600699class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase,
700 api_config.ApiConfigMixin):
Alex Klein2275d692019-04-23 16:04:12 -0600701 """BundleSimpleChromeArtifacts tests."""
702
703 def setUp(self):
704 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
705 self.sysroot_path = '/sysroot'
706 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
707 osutils.SafeMakedirs(self.sysroot_dir)
708 self.output_dir = os.path.join(self.tempdir, 'output_dir')
709 osutils.SafeMakedirs(self.output_dir)
710
711 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
712
Alex Klein231d2da2019-07-22 16:44:45 -0600713 self.response = artifacts_pb2.BundleResponse()
714
Alex Klein2275d692019-04-23 16:04:12 -0600715 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
716 output_dir=None):
717 """Helper to create a request message instance.
718
719 Args:
720 chroot (str): The chroot path.
721 sysroot (str): The sysroot path.
722 build_target (str): The build target name.
723 output_dir (str): The output directory.
724 """
725 return artifacts_pb2.BundleRequest(
726 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
727 chroot={'path': chroot}, output_dir=output_dir)
728
Alex Klein231d2da2019-07-22 16:44:45 -0600729 def testValidateOnly(self):
730 """Sanity check that a validate only call does not execute any logic."""
731 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
732 request = self._GetRequest(chroot=self.chroot_dir,
733 sysroot=self.sysroot_path,
734 build_target='board', output_dir=self.output_dir)
735 artifacts.BundleSimpleChromeArtifacts(request, self.response,
736 self.validate_only_config)
737 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600738
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700739 def testMockCall(self):
740 """Test that a mock call does not execute logic, returns mocked value."""
741 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
742 request = self._GetRequest(chroot=self.chroot_dir,
743 sysroot=self.sysroot_path,
744 build_target='board', output_dir=self.output_dir)
745 artifacts.BundleSimpleChromeArtifacts(request, self.response,
746 self.mock_call_config)
747 patch.assert_not_called()
748 self.assertEqual(len(self.response.artifacts), 1)
749 self.assertEqual(self.response.artifacts[0].path,
750 os.path.join(self.output_dir, 'simple_chrome.txt'))
751
Alex Klein2275d692019-04-23 16:04:12 -0600752 def testNoBuildTarget(self):
753 """Test no build target fails."""
754 request = self._GetRequest(chroot=self.chroot_dir,
755 sysroot=self.sysroot_path,
756 output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600757 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600758 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600759 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600760
761 def testNoSysroot(self):
762 """Test no sysroot fails."""
763 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600764 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600765 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600766 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600767
768 def testSysrootDoesNotExist(self):
769 """Test no sysroot fails."""
770 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
771 sysroot=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600772 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600773 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600774 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600775
776 def testNoOutputDir(self):
777 """Test no output dir fails."""
778 request = self._GetRequest(chroot=self.chroot_dir,
779 sysroot=self.sysroot_path,
780 build_target='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600781 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600782 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600783 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600784
785 def testOutputDirDoesNotExist(self):
786 """Test no output dir fails."""
787 request = self._GetRequest(chroot=self.chroot_dir,
788 sysroot=self.sysroot_path,
789 build_target='board',
790 output_dir=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600791 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600792 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600793 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600794
795 def testOutputHandling(self):
796 """Test response output."""
797 files = ['file1', 'file2', 'file3']
798 expected_files = [os.path.join(self.output_dir, f) for f in files]
799 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
800 return_value=expected_files)
801 request = self._GetRequest(chroot=self.chroot_dir,
802 sysroot=self.sysroot_path,
803 build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600804 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600805
Alex Klein231d2da2019-07-22 16:44:45 -0600806 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600807
808 self.assertTrue(response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -0400809 self.assertCountEqual(expected_files, [a.path for a in response.artifacts])
Alex Klein2275d692019-04-23 16:04:12 -0600810
811
Alex Klein231d2da2019-07-22 16:44:45 -0600812class BundleVmFilesTest(cros_test_lib.MockTempDirTestCase,
813 api_config.ApiConfigMixin):
Alex Klein6504eca2019-04-18 15:37:56 -0600814 """BuildVmFiles tests."""
815
Alex Klein231d2da2019-07-22 16:44:45 -0600816 def setUp(self):
817 self.output_dir = os.path.join(self.tempdir, 'output')
818 osutils.SafeMakedirs(self.output_dir)
819
820 self.response = artifacts_pb2.BundleResponse()
821
Alex Klein6504eca2019-04-18 15:37:56 -0600822 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
823 output_dir=None):
824 """Helper to build out an input message instance.
825
826 Args:
827 chroot (str|None): The chroot path.
828 sysroot (str|None): The sysroot path relative to the chroot.
829 test_results_dir (str|None): The test results directory relative to the
830 sysroot.
831 output_dir (str|None): The directory where the results tarball should be
832 saved.
833 """
834 return artifacts_pb2.BundleVmFilesRequest(
835 chroot={'path': chroot}, sysroot={'path': sysroot},
836 test_results_dir=test_results_dir, output_dir=output_dir,
837 )
838
Alex Klein231d2da2019-07-22 16:44:45 -0600839 def testValidateOnly(self):
840 """Sanity check that a validate only call does not execute any logic."""
841 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
842 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
843 test_results_dir='/test/results',
844 output_dir=self.output_dir)
845 artifacts.BundleVmFiles(in_proto, self.response, self.validate_only_config)
846 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600847
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700848 def testMockCall(self):
849 """Test that a mock call does not execute logic, returns mocked value."""
850 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
851 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
852 test_results_dir='/test/results',
853 output_dir=self.output_dir)
854 artifacts.BundleVmFiles(in_proto, self.response, self.mock_call_config)
855 patch.assert_not_called()
856 self.assertEqual(len(self.response.artifacts), 1)
857 self.assertEqual(self.response.artifacts[0].path,
858 os.path.join(self.output_dir, 'f1.tar'))
859
Alex Klein6504eca2019-04-18 15:37:56 -0600860 def testChrootMissing(self):
861 """Test error handling for missing chroot."""
862 in_proto = self._GetInput(sysroot='/build/board',
863 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600864 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600865
866 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600867 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600868
Alex Klein6504eca2019-04-18 15:37:56 -0600869 def testTestResultsDirMissing(self):
870 """Test error handling for missing test results directory."""
871 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
Alex Klein231d2da2019-07-22 16:44:45 -0600872 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600873
874 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600875 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600876
877 def testOutputDirMissing(self):
878 """Test error handling for missing output directory."""
879 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
880 test_results_dir='/test/results')
Alex Klein6504eca2019-04-18 15:37:56 -0600881
882 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600883 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
884
885 def testOutputDirDoesNotExist(self):
886 """Test error handling for output directory that does not exist."""
887 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
888 output_dir=os.path.join(self.tempdir, 'dne'),
889 test_results_dir='/test/results')
890
891 with self.assertRaises(cros_build_lib.DieSystemExit):
892 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600893
894 def testValidCall(self):
895 """Test image dir building."""
896 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
897 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600898 output_dir=self.output_dir)
899
Alex Klein6504eca2019-04-18 15:37:56 -0600900 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600901 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600902 return_value=expected_files)
903
Alex Klein231d2da2019-07-22 16:44:45 -0600904 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600905
Alex Klein231d2da2019-07-22 16:44:45 -0600906 patch.assert_called_with(mock.ANY, '/test/results', self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600907
908 # Make sure we have artifacts, and that every artifact is an expected file.
Alex Klein231d2da2019-07-22 16:44:45 -0600909 self.assertTrue(self.response.artifacts)
910 for artifact in self.response.artifacts:
Alex Klein6504eca2019-04-18 15:37:56 -0600911 self.assertIn(artifact.path, expected_files)
912 expected_files.remove(artifact.path)
913
914 # Make sure we've seen all of the expected files.
915 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700916
Alex Kleinb9d810b2019-07-01 12:38:02 -0600917
Tiancong Wang50b80a92019-08-01 14:46:15 -0700918
919class BundleAFDOGenerationArtifactsTestCase(
Alex Klein231d2da2019-07-22 16:44:45 -0600920 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700921 """Unittests for BundleAFDOGenerationArtifacts."""
922
923 @staticmethod
924 def mock_die(message, *args):
925 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700926
927 def setUp(self):
928 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
929 osutils.SafeMakedirs(self.chroot_dir)
930 temp_dir = os.path.join(self.chroot_dir, 'tmp')
931 osutils.SafeMakedirs(temp_dir)
932 self.output_dir = os.path.join(self.tempdir, 'output_dir')
933 osutils.SafeMakedirs(self.output_dir)
Tiancong Wang2ade7932019-09-27 14:15:40 -0700934 self.chrome_root = os.path.join(self.tempdir, 'chrome_root')
935 osutils.SafeMakedirs(self.chrome_root)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700936 self.build_target = 'board'
Tiancong Wang24a3df72019-08-20 15:48:51 -0700937 self.valid_artifact_type = toolchain_pb2.ORDERFILE
938 self.invalid_artifact_type = toolchain_pb2.NONE_TYPE
Tiancong Wangc4805b72019-06-11 12:12:03 -0700939 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700940 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700941
Alex Klein231d2da2019-07-22 16:44:45 -0600942 self.response = artifacts_pb2.BundleResponse()
943
Tiancong Wang2ade7932019-09-27 14:15:40 -0700944 def _GetRequest(self, chroot=None, build_target=None, chrome_root=None,
945 output_dir=None, artifact_type=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700946 """Helper to create a request message instance.
947
948 Args:
949 chroot (str): The chroot path.
950 build_target (str): The build target name.
Tiancong Wang2ade7932019-09-27 14:15:40 -0700951 chrome_root (str): The path to Chrome root.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700952 output_dir (str): The output directory.
Tiancong Wang50b80a92019-08-01 14:46:15 -0700953 artifact_type (artifacts_pb2.AFDOArtifactType):
954 The type of the artifact.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700955 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700956 return artifacts_pb2.BundleChromeAFDORequest(
Tiancong Wang2ade7932019-09-27 14:15:40 -0700957 chroot={'path': chroot, 'chrome_dir': chrome_root},
Tiancong Wang50b80a92019-08-01 14:46:15 -0700958 build_target={'name': build_target},
959 output_dir=output_dir,
960 artifact_type=artifact_type,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700961 )
962
Alex Klein231d2da2019-07-22 16:44:45 -0600963 def testValidateOnly(self):
964 """Sanity check that a validate only call does not execute any logic."""
965 patch = self.PatchObject(artifacts_svc,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700966 'BundleAFDOGenerationArtifacts')
Alex Klein231d2da2019-07-22 16:44:45 -0600967 request = self._GetRequest(chroot=self.chroot_dir,
968 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700969 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700970 output_dir=self.output_dir,
971 artifact_type=self.valid_artifact_type)
972 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
973 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -0600974 patch.assert_not_called()
Tiancong Wangc4805b72019-06-11 12:12:03 -0700975
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700976 def testMockCall(self):
977 """Test that a mock call does not execute logic, returns mocked value."""
978 patch = self.PatchObject(artifacts_svc,
979 'BundleAFDOGenerationArtifacts')
980 request = self._GetRequest(chroot=self.chroot_dir,
981 build_target=self.build_target,
982 chrome_root=self.chrome_root,
983 output_dir=self.output_dir,
984 artifact_type=self.valid_artifact_type)
985 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
986 self.mock_call_config)
987 patch.assert_not_called()
988 self.assertEqual(len(self.response.artifacts), 1)
989 self.assertEqual(self.response.artifacts[0].path,
990 os.path.join(self.output_dir, 'artifact1'))
991
Tiancong Wangc4805b72019-06-11 12:12:03 -0700992 def testNoBuildTarget(self):
993 """Test no build target fails."""
994 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang2ade7932019-09-27 14:15:40 -0700995 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -0700996 output_dir=self.output_dir,
997 artifact_type=self.valid_artifact_type)
998 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
999 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1000 self.api_config)
1001 self.assertEqual('build_target.name is required.',
1002 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -07001003
Tiancong Wang2ade7932019-09-27 14:15:40 -07001004 def testNoChromeRoot(self):
1005 """Test no chrome root fails."""
1006 request = self._GetRequest(chroot=self.chroot_dir,
1007 build_target=self.build_target,
1008 output_dir=self.output_dir,
1009 artifact_type=self.valid_artifact_type)
1010 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1011 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1012 self.api_config)
1013 self.assertEqual('chroot.chrome_dir path does not exist: ',
1014 str(context.exception))
1015
Tiancong Wangc4805b72019-06-11 12:12:03 -07001016 def testNoOutputDir(self):
1017 """Test no output dir fails."""
1018 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001019 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001020 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001021 artifact_type=self.valid_artifact_type)
1022 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1023 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1024 self.api_config)
1025 self.assertEqual('output_dir is required.',
1026 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -07001027
1028 def testOutputDirDoesNotExist(self):
1029 """Test output directory not existing fails."""
1030 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -07001031 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001032 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001033 output_dir=self.does_not_exist,
1034 artifact_type=self.valid_artifact_type)
1035 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1036 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1037 self.api_config)
1038 self.assertEqual(
1039 'output_dir path does not exist: %s' % self.does_not_exist,
1040 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -07001041
Tiancong Wang50b80a92019-08-01 14:46:15 -07001042 def testNoArtifactType(self):
1043 """Test no artifact type."""
1044 request = self._GetRequest(chroot=self.chroot_dir,
1045 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001046 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001047 output_dir=self.output_dir)
1048 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1049 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1050 self.api_config)
1051 self.assertIn('artifact_type (0) must be in',
1052 str(context.exception))
1053
1054 def testWrongArtifactType(self):
1055 """Test passing wrong artifact type."""
1056 request = self._GetRequest(chroot=self.chroot_dir,
1057 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001058 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001059 output_dir=self.output_dir,
1060 artifact_type=self.invalid_artifact_type)
1061 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1062 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1063 self.api_config)
Tiancong Wang24a3df72019-08-20 15:48:51 -07001064 self.assertIn('artifact_type (%d) must be in' % self.invalid_artifact_type,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001065 str(context.exception))
1066
1067 def testOutputHandlingOnOrderfile(self,
Tiancong Wang24a3df72019-08-20 15:48:51 -07001068 artifact_type=toolchain_pb2.ORDERFILE):
Tiancong Wang50b80a92019-08-01 14:46:15 -07001069 """Test response output for orderfile."""
1070 files = ['artifact1', 'artifact2', 'artifact3']
Tiancong Wangc4805b72019-06-11 12:12:03 -07001071 expected_files = [os.path.join(self.output_dir, f) for f in files]
Tiancong Wang50b80a92019-08-01 14:46:15 -07001072 self.PatchObject(artifacts_svc, 'BundleAFDOGenerationArtifacts',
Tiancong Wangc4805b72019-06-11 12:12:03 -07001073 return_value=expected_files)
Alex Klein231d2da2019-07-22 16:44:45 -06001074
Tiancong Wangc4805b72019-06-11 12:12:03 -07001075 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -07001076 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001077 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001078 output_dir=self.output_dir,
1079 artifact_type=artifact_type)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001080
Tiancong Wang50b80a92019-08-01 14:46:15 -07001081 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1082 self.api_config)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001083
Tiancong Wang50b80a92019-08-01 14:46:15 -07001084 self.assertTrue(self.response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -04001085 self.assertCountEqual(expected_files,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001086 [a.path for a in self.response.artifacts])
1087
1088 def testOutputHandlingOnAFDO(self):
1089 """Test response output for AFDO."""
1090 self.testOutputHandlingOnOrderfile(
Tiancong Wang24a3df72019-08-20 15:48:51 -07001091 artifact_type=toolchain_pb2.BENCHMARK_AFDO)
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001092
1093
1094class ExportCpeReportTest(cros_test_lib.MockTempDirTestCase,
1095 api_config.ApiConfigMixin):
1096 """ExportCpeReport tests."""
1097
1098 def setUp(self):
1099 self.response = artifacts_pb2.BundleResponse()
1100
1101 def testValidateOnly(self):
1102 """Sanity check validate only calls don't execute."""
1103 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1104
1105 request = artifacts_pb2.BundleRequest()
1106 request.build_target.name = 'board'
1107 request.output_dir = self.tempdir
1108
1109 artifacts.ExportCpeReport(request, self.response, self.validate_only_config)
1110
1111 patch.assert_not_called()
1112
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001113 def testMockCall(self):
1114 """Test that a mock call does not execute logic, returns mocked value."""
1115 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1116
1117 request = artifacts_pb2.BundleRequest()
1118 request.build_target.name = 'board'
1119 request.output_dir = self.tempdir
1120
1121 artifacts.ExportCpeReport(request, self.response, self.mock_call_config)
1122
1123 patch.assert_not_called()
1124 self.assertEqual(len(self.response.artifacts), 2)
1125 self.assertEqual(self.response.artifacts[0].path,
1126 os.path.join(self.tempdir, 'cpe_report.txt'))
1127 self.assertEqual(self.response.artifacts[1].path,
1128 os.path.join(self.tempdir, 'cpe_warnings.txt'))
1129
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001130 def testNoBuildTarget(self):
1131 request = artifacts_pb2.BundleRequest()
1132 request.output_dir = self.tempdir
1133
1134 with self.assertRaises(cros_build_lib.DieSystemExit):
1135 artifacts.ExportCpeReport(request, self.response, self.api_config)
1136
1137 def testSuccess(self):
1138 """Test success case."""
1139 expected = artifacts_svc.CpeResult(
1140 report='/output/report.json', warnings='/output/warnings.json')
1141 self.PatchObject(artifacts_svc, 'GenerateCpeReport', return_value=expected)
1142
1143 request = artifacts_pb2.BundleRequest()
1144 request.build_target.name = 'board'
1145 request.output_dir = self.tempdir
1146
1147 artifacts.ExportCpeReport(request, self.response, self.api_config)
1148
1149 for artifact in self.response.artifacts:
1150 self.assertIn(artifact.path, [expected.report, expected.warnings])