blob: a0d14fdc19b0e019e94d11ea723aad7ebf58cde1 [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
Yicheng Liea1181f2020-09-22 11:51:10 -0700504class BundleFpmcuUnittestsTest(BundleTestCase):
505 """Unittests for BundleFpmcuUnittests."""
506
507 def testValidateOnly(self):
508 """Sanity check that a validate only call does not execute any logic."""
509 patch = self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests')
510 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
511 self.validate_only_config)
512 patch.assert_not_called()
513
514 def testMockCall(self):
515 """Test that a mock call does not execute logic, returns mocked value."""
516 patch = self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests')
517 artifacts.BundleFpmcuUnittests(self.sysroot_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,
523 'fpmcu_unittests.tar.gz'))
524
525 def testBundleFpmcuUnittests(self):
526 """BundleFpmcuUnittests calls cbuildbot/commands with correct args."""
527 self.PatchObject(
528 artifacts_svc,
529 'BundleFpmcuUnittests',
530 return_value=os.path.join(self.output_dir, 'fpmcu_unittests.tar.gz'))
531 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
532 self.api_config)
533 self.assertEqual(
534 [artifact.path for artifact in self.response.artifacts],
535 [os.path.join(self.output_dir, 'fpmcu_unittests.tar.gz')])
536
537 def testBundleFpmcuUnittestsNoLogs(self):
538 """BundleFpmcuUnittests does not die when no fpmcu unittests found."""
539 self.PatchObject(artifacts_svc, 'BundleFpmcuUnittests',
540 return_value=None)
541 artifacts.BundleFpmcuUnittests(self.sysroot_request, self.response,
542 self.api_config)
543 self.assertFalse(self.response.artifacts)
544
545
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600546class BundleEbuildLogsTest(BundleTestCase):
547 """Unittests for BundleEbuildLogs."""
548
Alex Klein231d2da2019-07-22 16:44:45 -0600549 def testValidateOnly(self):
550 """Sanity check that a validate only call does not execute any logic."""
551 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600552 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600553 self.validate_only_config)
554 patch.assert_not_called()
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600555
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700556 def testMockCall(self):
557 """Test that a mock call does not execute logic, returns mocked value."""
558 patch = self.PatchObject(commands, 'BuildEbuildLogsTarball')
559 artifacts.BundleEbuildLogs(self.target_request, self.response,
560 self.mock_call_config)
561 patch.assert_not_called()
562 self.assertEqual(len(self.response.artifacts), 1)
563 self.assertEqual(self.response.artifacts[0].path,
564 os.path.join(self.output_dir, 'ebuild-logs.tar.gz'))
565
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600566 def testBundleEbuildLogs(self):
567 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600568 bundle_ebuild_logs_tarball = self.PatchObject(
569 artifacts_svc, 'BundleEBuildLogsTarball',
570 return_value='ebuild-logs.tar.gz')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600571 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
572 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600573 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600574 [artifact.path for artifact in self.response.artifacts],
Alex Klein68c8fdf2019-09-25 15:09:11 -0600575 [os.path.join(self.output_dir, 'ebuild-logs.tar.gz')])
Evan Hernandeza478d802019-04-08 15:08:24 -0600576 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600577 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600578 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600579
580 def testBundleEBuildLogsOldProto(self):
581 bundle_ebuild_logs_tarball = self.PatchObject(
582 artifacts_svc, 'BundleEBuildLogsTarball',
583 return_value='ebuild-logs.tar.gz')
Alex Klein231d2da2019-07-22 16:44:45 -0600584
Alex Klein68c8fdf2019-09-25 15:09:11 -0600585 artifacts.BundleEbuildLogs(self.target_request, self.response,
Alex Klein231d2da2019-07-22 16:44:45 -0600586 self.api_config)
587
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600588 self.assertEqual(
589 bundle_ebuild_logs_tarball.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600590 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600591
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600592 def testBundleEbuildLogsNoLogs(self):
593 """BundleEbuildLogs dies when no logs found."""
594 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
595 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600596 artifacts.BundleEbuildLogs(self.sysroot_request, self.response,
597 self.api_config)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600598
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600599
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600600class BundleChromeOSConfigTest(BundleTestCase):
601 """Unittests for BundleChromeOSConfig"""
602
603 def testValidateOnly(self):
604 """Sanity check that a validate only call does not execute any logic."""
605 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600606 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600607 self.validate_only_config)
608 patch.assert_not_called()
609
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700610 def testMockCall(self):
611 """Test that a mock call does not execute logic, returns mocked value."""
612 patch = self.PatchObject(artifacts_svc, 'BundleChromeOSConfig')
613 artifacts.BundleChromeOSConfig(self.target_request, self.response,
614 self.mock_call_config)
615 patch.assert_not_called()
616 self.assertEqual(len(self.response.artifacts), 1)
617 self.assertEqual(self.response.artifacts[0].path,
618 os.path.join(self.output_dir, 'config.yaml'))
619
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600620 def testBundleChromeOSConfigCallWithSysroot(self):
621 """Call with a request that sets sysroot."""
622 bundle_chromeos_config = self.PatchObject(
623 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600624 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600625 self.api_config)
626 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600627 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600628 [os.path.join(self.output_dir, 'config.yaml')])
629
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600630 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600631 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600632
633 def testBundleChromeOSConfigCallWithBuildTarget(self):
634 """Call with a request that sets build_target."""
635 bundle_chromeos_config = self.PatchObject(
636 artifacts_svc, 'BundleChromeOSConfig', return_value='config.yaml')
Alex Klein68c8fdf2019-09-25 15:09:11 -0600637 artifacts.BundleChromeOSConfig(self.target_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600638 self.api_config)
639
640 self.assertEqual(
Alex Klein68c8fdf2019-09-25 15:09:11 -0600641 [artifact.path for artifact in self.response.artifacts],
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600642 [os.path.join(self.output_dir, 'config.yaml')])
643
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600644 self.assertEqual(bundle_chromeos_config.call_args_list,
Alex Klein68c8fdf2019-09-25 15:09:11 -0600645 [mock.call(mock.ANY, self.sysroot, self.output_dir)])
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600646
647 def testBundleChromeOSConfigNoConfigFound(self):
648 """An error is raised if the config payload isn't found."""
649 self.PatchObject(artifacts_svc, 'BundleChromeOSConfig', return_value=None)
650
651 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein68c8fdf2019-09-25 15:09:11 -0600652 artifacts.BundleChromeOSConfig(self.sysroot_request, self.response,
Andrew Lamb67bd68f2019-08-15 09:09:15 -0600653 self.api_config)
654
655
Alex Klein231d2da2019-07-22 16:44:45 -0600656class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase,
657 api_config.ApiConfigMixin):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600658 """Unittests for BundleTestUpdatePayloads."""
659
660 def setUp(self):
661 self.source_root = os.path.join(self.tempdir, 'cros')
662 osutils.SafeMakedirs(self.source_root)
663
664 self.archive_root = os.path.join(self.tempdir, 'output')
665 osutils.SafeMakedirs(self.archive_root)
666
667 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600668 self.image_root = os.path.join(self.source_root,
669 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600670
671 self.input_proto = artifacts_pb2.BundleRequest()
672 self.input_proto.build_target.name = self.target
673 self.input_proto.output_dir = self.archive_root
674 self.output_proto = artifacts_pb2.BundleResponse()
675
676 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
677
Alex Kleincb541e82019-06-26 15:06:11 -0600678 def MockPayloads(image_path, archive_dir):
679 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
680 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
681 return [os.path.join(archive_dir, 'payload1.bin'),
682 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600683
Alex Kleincb541e82019-06-26 15:06:11 -0600684 self.bundle_patch = self.PatchObject(
685 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600686
Alex Klein231d2da2019-07-22 16:44:45 -0600687 def testValidateOnly(self):
688 """Sanity check that a validate only call does not execute any logic."""
689 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
690 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
691 self.validate_only_config)
692 patch.assert_not_called()
693
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700694 def testMockCall(self):
695 """Test that a mock call does not execute logic, returns mocked value."""
696 patch = self.PatchObject(artifacts_svc, 'BundleTestUpdatePayloads')
697 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
698 self.mock_call_config)
699 patch.assert_not_called()
700 self.assertEqual(len(self.output_proto.artifacts), 1)
701 self.assertEqual(self.output_proto.artifacts[0].path,
702 os.path.join(self.archive_root, 'payload1.bin'))
703
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600704 def testBundleTestUpdatePayloads(self):
705 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
706 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
707 osutils.WriteFile(image_path, 'image!', makedirs=True)
708
Alex Klein231d2da2019-07-22 16:44:45 -0600709 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
710 self.api_config)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600711
712 actual = [
713 os.path.relpath(artifact.path, self.archive_root)
714 for artifact in self.output_proto.artifacts
715 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600716 expected = ['payload1.bin', 'payload2.bin']
Mike Frysinger678735c2019-09-28 18:23:28 -0400717 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600718
719 actual = [
720 os.path.relpath(path, self.archive_root)
721 for path in osutils.DirectoryIterator(self.archive_root)
722 ]
Mike Frysinger678735c2019-09-28 18:23:28 -0400723 self.assertCountEqual(actual, expected)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600724
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600725 def testBundleTestUpdatePayloadsNoImageDir(self):
726 """BundleTestUpdatePayloads dies if no image dir is found."""
727 # Intentionally do not write image directory.
Alex Kleind2bf1462019-10-24 16:37:04 -0600728 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
729 self.api_config)
730 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600731
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600732 def testBundleTestUpdatePayloadsNoImage(self):
733 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600734 # Intentionally do not write image, but create the directory.
735 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600736 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600737 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto,
738 self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600739
740
Alex Klein231d2da2019-07-22 16:44:45 -0600741class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase,
742 api_config.ApiConfigMixin):
Alex Klein2275d692019-04-23 16:04:12 -0600743 """BundleSimpleChromeArtifacts tests."""
744
745 def setUp(self):
746 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
747 self.sysroot_path = '/sysroot'
748 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
749 osutils.SafeMakedirs(self.sysroot_dir)
750 self.output_dir = os.path.join(self.tempdir, 'output_dir')
751 osutils.SafeMakedirs(self.output_dir)
752
753 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
754
Alex Klein231d2da2019-07-22 16:44:45 -0600755 self.response = artifacts_pb2.BundleResponse()
756
Alex Klein2275d692019-04-23 16:04:12 -0600757 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
758 output_dir=None):
759 """Helper to create a request message instance.
760
761 Args:
762 chroot (str): The chroot path.
763 sysroot (str): The sysroot path.
764 build_target (str): The build target name.
765 output_dir (str): The output directory.
766 """
767 return artifacts_pb2.BundleRequest(
768 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
769 chroot={'path': chroot}, output_dir=output_dir)
770
Alex Klein231d2da2019-07-22 16:44:45 -0600771 def testValidateOnly(self):
772 """Sanity check that a validate only call does not execute any logic."""
773 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
774 request = self._GetRequest(chroot=self.chroot_dir,
775 sysroot=self.sysroot_path,
776 build_target='board', output_dir=self.output_dir)
777 artifacts.BundleSimpleChromeArtifacts(request, self.response,
778 self.validate_only_config)
779 patch.assert_not_called()
Alex Klein2275d692019-04-23 16:04:12 -0600780
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700781 def testMockCall(self):
782 """Test that a mock call does not execute logic, returns mocked value."""
783 patch = self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts')
784 request = self._GetRequest(chroot=self.chroot_dir,
785 sysroot=self.sysroot_path,
786 build_target='board', output_dir=self.output_dir)
787 artifacts.BundleSimpleChromeArtifacts(request, self.response,
788 self.mock_call_config)
789 patch.assert_not_called()
790 self.assertEqual(len(self.response.artifacts), 1)
791 self.assertEqual(self.response.artifacts[0].path,
792 os.path.join(self.output_dir, 'simple_chrome.txt'))
793
Alex Klein2275d692019-04-23 16:04:12 -0600794 def testNoBuildTarget(self):
795 """Test no build target fails."""
796 request = self._GetRequest(chroot=self.chroot_dir,
797 sysroot=self.sysroot_path,
798 output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600799 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600800 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600801 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600802
803 def testNoSysroot(self):
804 """Test no sysroot fails."""
805 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600806 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600807 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600808 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600809
810 def testSysrootDoesNotExist(self):
811 """Test no sysroot fails."""
812 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
813 sysroot=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600814 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600815 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600816 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600817
818 def testNoOutputDir(self):
819 """Test no output dir fails."""
820 request = self._GetRequest(chroot=self.chroot_dir,
821 sysroot=self.sysroot_path,
822 build_target='board')
Alex Klein231d2da2019-07-22 16:44:45 -0600823 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600824 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600825 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600826
827 def testOutputDirDoesNotExist(self):
828 """Test no output dir fails."""
829 request = self._GetRequest(chroot=self.chroot_dir,
830 sysroot=self.sysroot_path,
831 build_target='board',
832 output_dir=self.does_not_exist)
Alex Klein231d2da2019-07-22 16:44:45 -0600833 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600834 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600835 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600836
837 def testOutputHandling(self):
838 """Test response output."""
839 files = ['file1', 'file2', 'file3']
840 expected_files = [os.path.join(self.output_dir, f) for f in files]
841 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
842 return_value=expected_files)
843 request = self._GetRequest(chroot=self.chroot_dir,
844 sysroot=self.sysroot_path,
845 build_target='board', output_dir=self.output_dir)
Alex Klein231d2da2019-07-22 16:44:45 -0600846 response = self.response
Alex Klein2275d692019-04-23 16:04:12 -0600847
Alex Klein231d2da2019-07-22 16:44:45 -0600848 artifacts.BundleSimpleChromeArtifacts(request, response, self.api_config)
Alex Klein2275d692019-04-23 16:04:12 -0600849
850 self.assertTrue(response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -0400851 self.assertCountEqual(expected_files, [a.path for a in response.artifacts])
Alex Klein2275d692019-04-23 16:04:12 -0600852
853
Alex Klein231d2da2019-07-22 16:44:45 -0600854class BundleVmFilesTest(cros_test_lib.MockTempDirTestCase,
855 api_config.ApiConfigMixin):
Alex Klein6504eca2019-04-18 15:37:56 -0600856 """BuildVmFiles tests."""
857
Alex Klein231d2da2019-07-22 16:44:45 -0600858 def setUp(self):
859 self.output_dir = os.path.join(self.tempdir, 'output')
860 osutils.SafeMakedirs(self.output_dir)
861
862 self.response = artifacts_pb2.BundleResponse()
863
Alex Klein6504eca2019-04-18 15:37:56 -0600864 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
865 output_dir=None):
866 """Helper to build out an input message instance.
867
868 Args:
869 chroot (str|None): The chroot path.
870 sysroot (str|None): The sysroot path relative to the chroot.
871 test_results_dir (str|None): The test results directory relative to the
872 sysroot.
873 output_dir (str|None): The directory where the results tarball should be
874 saved.
875 """
876 return artifacts_pb2.BundleVmFilesRequest(
877 chroot={'path': chroot}, sysroot={'path': sysroot},
878 test_results_dir=test_results_dir, output_dir=output_dir,
879 )
880
Alex Klein231d2da2019-07-22 16:44:45 -0600881 def testValidateOnly(self):
882 """Sanity check that a validate only call does not execute any logic."""
883 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
884 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
885 test_results_dir='/test/results',
886 output_dir=self.output_dir)
887 artifacts.BundleVmFiles(in_proto, self.response, self.validate_only_config)
888 patch.assert_not_called()
Alex Klein6504eca2019-04-18 15:37:56 -0600889
Michael Mortensen2d6a2402019-11-26 13:40:40 -0700890 def testMockCall(self):
891 """Test that a mock call does not execute logic, returns mocked value."""
892 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles')
893 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
894 test_results_dir='/test/results',
895 output_dir=self.output_dir)
896 artifacts.BundleVmFiles(in_proto, self.response, self.mock_call_config)
897 patch.assert_not_called()
898 self.assertEqual(len(self.response.artifacts), 1)
899 self.assertEqual(self.response.artifacts[0].path,
900 os.path.join(self.output_dir, 'f1.tar'))
901
Alex Klein6504eca2019-04-18 15:37:56 -0600902 def testChrootMissing(self):
903 """Test error handling for missing chroot."""
904 in_proto = self._GetInput(sysroot='/build/board',
905 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600906 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600907
908 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600909 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600910
Alex Klein6504eca2019-04-18 15:37:56 -0600911 def testTestResultsDirMissing(self):
912 """Test error handling for missing test results directory."""
913 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
Alex Klein231d2da2019-07-22 16:44:45 -0600914 output_dir=self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600915
916 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600917 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600918
919 def testOutputDirMissing(self):
920 """Test error handling for missing output directory."""
921 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
922 test_results_dir='/test/results')
Alex Klein6504eca2019-04-18 15:37:56 -0600923
924 with self.assertRaises(cros_build_lib.DieSystemExit):
Alex Klein231d2da2019-07-22 16:44:45 -0600925 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
926
927 def testOutputDirDoesNotExist(self):
928 """Test error handling for output directory that does not exist."""
929 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
930 output_dir=os.path.join(self.tempdir, 'dne'),
931 test_results_dir='/test/results')
932
933 with self.assertRaises(cros_build_lib.DieSystemExit):
934 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600935
936 def testValidCall(self):
937 """Test image dir building."""
938 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
939 test_results_dir='/test/results',
Alex Klein231d2da2019-07-22 16:44:45 -0600940 output_dir=self.output_dir)
941
Alex Klein6504eca2019-04-18 15:37:56 -0600942 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600943 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600944 return_value=expected_files)
945
Alex Klein231d2da2019-07-22 16:44:45 -0600946 artifacts.BundleVmFiles(in_proto, self.response, self.api_config)
Alex Klein6504eca2019-04-18 15:37:56 -0600947
Alex Klein231d2da2019-07-22 16:44:45 -0600948 patch.assert_called_with(mock.ANY, '/test/results', self.output_dir)
Alex Klein6504eca2019-04-18 15:37:56 -0600949
950 # Make sure we have artifacts, and that every artifact is an expected file.
Alex Klein231d2da2019-07-22 16:44:45 -0600951 self.assertTrue(self.response.artifacts)
952 for artifact in self.response.artifacts:
Alex Klein6504eca2019-04-18 15:37:56 -0600953 self.assertIn(artifact.path, expected_files)
954 expected_files.remove(artifact.path)
955
956 # Make sure we've seen all of the expected files.
957 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700958
Alex Kleinb9d810b2019-07-01 12:38:02 -0600959
Tiancong Wang50b80a92019-08-01 14:46:15 -0700960
961class BundleAFDOGenerationArtifactsTestCase(
Alex Klein231d2da2019-07-22 16:44:45 -0600962 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin):
Tiancong Wang50b80a92019-08-01 14:46:15 -0700963 """Unittests for BundleAFDOGenerationArtifacts."""
964
965 @staticmethod
966 def mock_die(message, *args):
967 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700968
969 def setUp(self):
970 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
971 osutils.SafeMakedirs(self.chroot_dir)
972 temp_dir = os.path.join(self.chroot_dir, 'tmp')
973 osutils.SafeMakedirs(temp_dir)
974 self.output_dir = os.path.join(self.tempdir, 'output_dir')
975 osutils.SafeMakedirs(self.output_dir)
Tiancong Wang2ade7932019-09-27 14:15:40 -0700976 self.chrome_root = os.path.join(self.tempdir, 'chrome_root')
977 osutils.SafeMakedirs(self.chrome_root)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700978 self.build_target = 'board'
Tiancong Wang24a3df72019-08-20 15:48:51 -0700979 self.valid_artifact_type = toolchain_pb2.ORDERFILE
980 self.invalid_artifact_type = toolchain_pb2.NONE_TYPE
Tiancong Wangc4805b72019-06-11 12:12:03 -0700981 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
Tiancong Wang50b80a92019-08-01 14:46:15 -0700982 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700983
Alex Klein231d2da2019-07-22 16:44:45 -0600984 self.response = artifacts_pb2.BundleResponse()
985
Tiancong Wang2ade7932019-09-27 14:15:40 -0700986 def _GetRequest(self, chroot=None, build_target=None, chrome_root=None,
987 output_dir=None, artifact_type=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700988 """Helper to create a request message instance.
989
990 Args:
991 chroot (str): The chroot path.
992 build_target (str): The build target name.
Tiancong Wang2ade7932019-09-27 14:15:40 -0700993 chrome_root (str): The path to Chrome root.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700994 output_dir (str): The output directory.
Tiancong Wang50b80a92019-08-01 14:46:15 -0700995 artifact_type (artifacts_pb2.AFDOArtifactType):
996 The type of the artifact.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700997 """
Tiancong Wang50b80a92019-08-01 14:46:15 -0700998 return artifacts_pb2.BundleChromeAFDORequest(
Tiancong Wang2ade7932019-09-27 14:15:40 -0700999 chroot={'path': chroot, 'chrome_dir': chrome_root},
Tiancong Wang50b80a92019-08-01 14:46:15 -07001000 build_target={'name': build_target},
1001 output_dir=output_dir,
1002 artifact_type=artifact_type,
Tiancong Wangc4805b72019-06-11 12:12:03 -07001003 )
1004
Alex Klein231d2da2019-07-22 16:44:45 -06001005 def testValidateOnly(self):
1006 """Sanity check that a validate only call does not execute any logic."""
1007 patch = self.PatchObject(artifacts_svc,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001008 'BundleAFDOGenerationArtifacts')
Alex Klein231d2da2019-07-22 16:44:45 -06001009 request = self._GetRequest(chroot=self.chroot_dir,
1010 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001011 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001012 output_dir=self.output_dir,
1013 artifact_type=self.valid_artifact_type)
1014 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1015 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -06001016 patch.assert_not_called()
Tiancong Wangc4805b72019-06-11 12:12:03 -07001017
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001018 def testMockCall(self):
1019 """Test that a mock call does not execute logic, returns mocked value."""
1020 patch = self.PatchObject(artifacts_svc,
1021 'BundleAFDOGenerationArtifacts')
1022 request = self._GetRequest(chroot=self.chroot_dir,
1023 build_target=self.build_target,
1024 chrome_root=self.chrome_root,
1025 output_dir=self.output_dir,
1026 artifact_type=self.valid_artifact_type)
1027 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1028 self.mock_call_config)
1029 patch.assert_not_called()
1030 self.assertEqual(len(self.response.artifacts), 1)
1031 self.assertEqual(self.response.artifacts[0].path,
1032 os.path.join(self.output_dir, 'artifact1'))
1033
Tiancong Wangc4805b72019-06-11 12:12:03 -07001034 def testNoBuildTarget(self):
1035 """Test no build target fails."""
1036 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001037 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001038 output_dir=self.output_dir,
1039 artifact_type=self.valid_artifact_type)
1040 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1041 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1042 self.api_config)
1043 self.assertEqual('build_target.name is required.',
1044 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -07001045
Tiancong Wang2ade7932019-09-27 14:15:40 -07001046 def testNoChromeRoot(self):
1047 """Test no chrome root fails."""
1048 request = self._GetRequest(chroot=self.chroot_dir,
1049 build_target=self.build_target,
1050 output_dir=self.output_dir,
1051 artifact_type=self.valid_artifact_type)
1052 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1053 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1054 self.api_config)
1055 self.assertEqual('chroot.chrome_dir path does not exist: ',
1056 str(context.exception))
1057
Tiancong Wangc4805b72019-06-11 12:12:03 -07001058 def testNoOutputDir(self):
1059 """Test no output dir fails."""
1060 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001061 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001062 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001063 artifact_type=self.valid_artifact_type)
1064 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1065 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1066 self.api_config)
1067 self.assertEqual('output_dir is required.',
1068 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -07001069
1070 def testOutputDirDoesNotExist(self):
1071 """Test output directory not existing fails."""
1072 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -07001073 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001074 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001075 output_dir=self.does_not_exist,
1076 artifact_type=self.valid_artifact_type)
1077 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1078 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1079 self.api_config)
1080 self.assertEqual(
1081 'output_dir path does not exist: %s' % self.does_not_exist,
1082 str(context.exception))
Tiancong Wangc4805b72019-06-11 12:12:03 -07001083
Tiancong Wang50b80a92019-08-01 14:46:15 -07001084 def testNoArtifactType(self):
1085 """Test no artifact type."""
1086 request = self._GetRequest(chroot=self.chroot_dir,
1087 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001088 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001089 output_dir=self.output_dir)
1090 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1091 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1092 self.api_config)
1093 self.assertIn('artifact_type (0) must be in',
1094 str(context.exception))
1095
1096 def testWrongArtifactType(self):
1097 """Test passing wrong artifact type."""
1098 request = self._GetRequest(chroot=self.chroot_dir,
1099 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001100 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001101 output_dir=self.output_dir,
1102 artifact_type=self.invalid_artifact_type)
1103 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
1104 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1105 self.api_config)
Tiancong Wang24a3df72019-08-20 15:48:51 -07001106 self.assertIn('artifact_type (%d) must be in' % self.invalid_artifact_type,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001107 str(context.exception))
1108
1109 def testOutputHandlingOnOrderfile(self,
Tiancong Wang24a3df72019-08-20 15:48:51 -07001110 artifact_type=toolchain_pb2.ORDERFILE):
Tiancong Wang50b80a92019-08-01 14:46:15 -07001111 """Test response output for orderfile."""
1112 files = ['artifact1', 'artifact2', 'artifact3']
Tiancong Wangc4805b72019-06-11 12:12:03 -07001113 expected_files = [os.path.join(self.output_dir, f) for f in files]
Tiancong Wang50b80a92019-08-01 14:46:15 -07001114 self.PatchObject(artifacts_svc, 'BundleAFDOGenerationArtifacts',
Tiancong Wangc4805b72019-06-11 12:12:03 -07001115 return_value=expected_files)
Alex Klein231d2da2019-07-22 16:44:45 -06001116
Tiancong Wangc4805b72019-06-11 12:12:03 -07001117 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -07001118 build_target=self.build_target,
Tiancong Wang2ade7932019-09-27 14:15:40 -07001119 chrome_root=self.chrome_root,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001120 output_dir=self.output_dir,
1121 artifact_type=artifact_type)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001122
Tiancong Wang50b80a92019-08-01 14:46:15 -07001123 artifacts.BundleAFDOGenerationArtifacts(request, self.response,
1124 self.api_config)
Tiancong Wangc4805b72019-06-11 12:12:03 -07001125
Tiancong Wang50b80a92019-08-01 14:46:15 -07001126 self.assertTrue(self.response.artifacts)
Mike Frysinger678735c2019-09-28 18:23:28 -04001127 self.assertCountEqual(expected_files,
Tiancong Wang50b80a92019-08-01 14:46:15 -07001128 [a.path for a in self.response.artifacts])
1129
1130 def testOutputHandlingOnAFDO(self):
1131 """Test response output for AFDO."""
1132 self.testOutputHandlingOnOrderfile(
Tiancong Wang24a3df72019-08-20 15:48:51 -07001133 artifact_type=toolchain_pb2.BENCHMARK_AFDO)
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001134
1135
1136class ExportCpeReportTest(cros_test_lib.MockTempDirTestCase,
1137 api_config.ApiConfigMixin):
1138 """ExportCpeReport tests."""
1139
1140 def setUp(self):
1141 self.response = artifacts_pb2.BundleResponse()
1142
1143 def testValidateOnly(self):
1144 """Sanity check validate only calls don't execute."""
1145 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1146
1147 request = artifacts_pb2.BundleRequest()
1148 request.build_target.name = 'board'
1149 request.output_dir = self.tempdir
1150
1151 artifacts.ExportCpeReport(request, self.response, self.validate_only_config)
1152
1153 patch.assert_not_called()
1154
Michael Mortensen2d6a2402019-11-26 13:40:40 -07001155 def testMockCall(self):
1156 """Test that a mock call does not execute logic, returns mocked value."""
1157 patch = self.PatchObject(artifacts_svc, 'GenerateCpeReport')
1158
1159 request = artifacts_pb2.BundleRequest()
1160 request.build_target.name = 'board'
1161 request.output_dir = self.tempdir
1162
1163 artifacts.ExportCpeReport(request, self.response, self.mock_call_config)
1164
1165 patch.assert_not_called()
1166 self.assertEqual(len(self.response.artifacts), 2)
1167 self.assertEqual(self.response.artifacts[0].path,
1168 os.path.join(self.tempdir, 'cpe_report.txt'))
1169 self.assertEqual(self.response.artifacts[1].path,
1170 os.path.join(self.tempdir, 'cpe_warnings.txt'))
1171
Alex Klein0b1cbfc2019-08-14 10:09:58 -06001172 def testNoBuildTarget(self):
1173 request = artifacts_pb2.BundleRequest()
1174 request.output_dir = self.tempdir
1175
1176 with self.assertRaises(cros_build_lib.DieSystemExit):
1177 artifacts.ExportCpeReport(request, self.response, self.api_config)
1178
1179 def testSuccess(self):
1180 """Test success case."""
1181 expected = artifacts_svc.CpeResult(
1182 report='/output/report.json', warnings='/output/warnings.json')
1183 self.PatchObject(artifacts_svc, 'GenerateCpeReport', return_value=expected)
1184
1185 request = artifacts_pb2.BundleRequest()
1186 request.build_target.name = 'board'
1187 request.output_dir = self.tempdir
1188
1189 artifacts.ExportCpeReport(request, self.response, self.api_config)
1190
1191 for artifact in self.response.artifacts:
1192 self.assertIn(artifact.path, [expected.report, expected.warnings])