blob: 1629190bc086ad784a6404b2982c4a2ab017511a [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
10import mock
11import os
12
13from chromite.api.controller import artifacts
14from chromite.api.gen.chromite.api import artifacts_pb2
15from chromite.cbuildbot import commands
Alex Kleinb9d810b2019-07-01 12:38:02 -060016from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060017from chromite.lib import constants
18from chromite.lib import cros_build_lib
19from chromite.lib import cros_test_lib
20from chromite.lib import osutils
Alex Klein238d8862019-05-07 11:32:46 -060021from chromite.lib import sysroot_lib
Alex Klein2275d692019-04-23 16:04:12 -060022from chromite.service import artifacts as artifacts_svc
Evan Hernandezf388cbf2019-04-01 11:15:23 -060023
24
Alex Kleinb9d810b2019-07-01 12:38:02 -060025class BundleTestCase(cros_test_lib.MockTempDirTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060026 """Basic setup for all artifacts unittests."""
27
28 def setUp(self):
29 self.input_proto = artifacts_pb2.BundleRequest()
30 self.input_proto.build_target.name = 'target'
31 self.input_proto.output_dir = '/tmp/artifacts'
32 self.output_proto = artifacts_pb2.BundleResponse()
Michael Mortensen38675192019-06-28 16:52:55 +000033 self.sysroot_input_proto = artifacts_pb2.BundleRequest()
34 self.sysroot_input_proto.sysroot.path = '/tmp/sysroot'
35 self.sysroot_input_proto.output_dir = '/tmp/artifacts'
Evan Hernandezf388cbf2019-04-01 11:15:23 -060036
37 self.PatchObject(constants, 'SOURCE_ROOT', new='/cros')
38
39
Alex Klein238d8862019-05-07 11:32:46 -060040class BundleTempDirTestCase(cros_test_lib.MockTempDirTestCase):
41 """Basic setup for artifacts unittests that need a tempdir."""
42
43 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
44 output_dir=None):
45 """Helper to create a request message instance.
46
47 Args:
48 chroot (str): The chroot path.
49 sysroot (str): The sysroot path.
50 build_target (str): The build target name.
51 output_dir (str): The output directory.
52 """
53 return artifacts_pb2.BundleRequest(
54 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
55 chroot={'path': chroot}, output_dir=output_dir)
56
57 def _GetResponse(self):
58 return artifacts_pb2.BundleResponse()
59
60 def setUp(self):
61 self.output_dir = os.path.join(self.tempdir, 'artifacts')
62 osutils.SafeMakedirs(self.output_dir)
63
64 # Old style paths.
65 self.old_sysroot_path = os.path.join(self.tempdir, 'cros', 'chroot',
66 'build', 'target')
67 self.old_sysroot = sysroot_lib.Sysroot(self.old_sysroot_path)
68 osutils.SafeMakedirs(self.old_sysroot_path)
69
70 # Old style proto.
71 self.input_proto = artifacts_pb2.BundleRequest()
72 self.input_proto.build_target.name = 'target'
73 self.input_proto.output_dir = self.output_dir
74 self.output_proto = artifacts_pb2.BundleResponse()
75
76 source_root = os.path.join(self.tempdir, 'cros')
77 self.PatchObject(constants, 'SOURCE_ROOT', new=source_root)
78
79 # New style paths.
80 self.chroot_path = os.path.join(self.tempdir, 'cros', 'chroot')
81 self.sysroot_path = '/build/target'
82 self.full_sysroot_path = os.path.join(self.chroot_path,
83 self.sysroot_path.lstrip(os.sep))
84 self.sysroot = sysroot_lib.Sysroot(self.full_sysroot_path)
85 osutils.SafeMakedirs(self.full_sysroot_path)
86
87 # New style proto.
88 self.request = artifacts_pb2.BundleRequest()
89 self.request.output_dir = self.output_dir
90 self.request.chroot.path = self.chroot_path
91 self.request.sysroot.path = self.sysroot_path
92 self.response = artifacts_pb2.BundleResponse()
93
94
Evan Hernandez9f125ac2019-04-08 17:18:47 -060095class BundleImageZipTest(BundleTestCase):
96 """Unittests for BundleImageZip."""
97
98 def testBundleImageZip(self):
99 """BundleImageZip calls cbuildbot/commands with correct args."""
Michael Mortensen01910922019-07-24 14:48:10 -0600100 bundle_image_zip = self.PatchObject(
101 artifacts_svc, 'BundleImageZip', return_value='image.zip')
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600102 self.PatchObject(os.path, 'exists', return_value=True)
103 artifacts.BundleImageZip(self.input_proto, self.output_proto)
104 self.assertEqual(
105 [artifact.path for artifact in self.output_proto.artifacts],
106 ['/tmp/artifacts/image.zip'])
107 self.assertEqual(
Michael Mortensen01910922019-07-24 14:48:10 -0600108 bundle_image_zip.call_args_list,
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600109 [mock.call('/tmp/artifacts', '/cros/src/build/images/target/latest')])
110
111 def testBundleImageZipNoImageDir(self):
112 """BundleImageZip dies when image dir does not exist."""
113 self.PatchObject(os.path, 'exists', return_value=False)
114 with self.assertRaises(cros_build_lib.DieSystemExit):
115 artifacts.BundleImageZip(self.input_proto, self.output_proto)
116
117
Alex Klein238d8862019-05-07 11:32:46 -0600118class BundleAutotestFilesTest(BundleTempDirTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600119 """Unittests for BundleAutotestFiles."""
120
Alex Klein238d8862019-05-07 11:32:46 -0600121 def testBundleAutotestFilesLegacy(self):
122 """BundleAutotestFiles calls service correctly with legacy args."""
123 files = {
124 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
125 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
126 }
127 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
128 return_value=files)
129
130 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
131 return_value=self.old_sysroot)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600132 artifacts.BundleAutotestFiles(self.input_proto, self.output_proto)
Alex Klein238d8862019-05-07 11:32:46 -0600133
134 # Verify the sysroot is being built out correctly.
135 sysroot_patch.assert_called_with(self.old_sysroot_path)
136
137 # Verify the arguments are being passed through.
138 patch.assert_called_with(self.old_sysroot, self.output_dir)
139
140 # Verify the output proto is being populated correctly.
141 self.assertTrue(self.output_proto.artifacts)
142 paths = [artifact.path for artifact in self.output_proto.artifacts]
143 self.assertItemsEqual(files.values(), paths)
144
145 def testBundleAutotestFiles(self):
146 """BundleAutotestFiles calls service correctly."""
147 files = {
148 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
149 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
150 }
151 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
152 return_value=files)
153
154 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
155 return_value=self.sysroot)
156 artifacts.BundleAutotestFiles(self.request, self.response)
157
158 # Verify the sysroot is being built out correctly.
159 sysroot_patch.assert_called_with(self.full_sysroot_path)
160
161 # Verify the arguments are being passed through.
162 patch.assert_called_with(self.sysroot, self.output_dir)
163
164 # Verify the output proto is being populated correctly.
165 self.assertTrue(self.response.artifacts)
166 paths = [artifact.path for artifact in self.response.artifacts]
167 self.assertItemsEqual(files.values(), paths)
168
169 def testInvalidOutputDir(self):
170 """Test invalid output directory argument."""
171 request = self._GetRequest(chroot=self.chroot_path,
172 sysroot=self.sysroot_path)
173 response = self._GetResponse()
174
175 with self.assertRaises(cros_build_lib.DieSystemExit):
176 artifacts.BundleAutotestFiles(request, response)
177
178 def testInvalidSysroot(self):
179 """Test no sysroot directory."""
180 request = self._GetRequest(chroot=self.chroot_path,
181 output_dir=self.output_dir)
182 response = self._GetResponse()
183
184 with self.assertRaises(cros_build_lib.DieSystemExit):
185 artifacts.BundleAutotestFiles(request, response)
186
187 def testSysrootDoesNotExist(self):
188 """Test dies when no sysroot does not exist."""
189 request = self._GetRequest(chroot=self.chroot_path,
190 sysroot='/does/not/exist',
191 output_dir=self.output_dir)
192 response = self._GetResponse()
193
194 with self.assertRaises(cros_build_lib.DieSystemExit):
195 artifacts.BundleAutotestFiles(request, response)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600196
197
198class BundleTastFilesTest(BundleTestCase):
199 """Unittests for BundleTastFiles."""
200
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600201 def testBundleTastFilesNoLogs(self):
202 """BundleTasteFiles dies when no tast files found."""
203 self.PatchObject(commands, 'BuildTastBundleTarball',
204 return_value=None)
205 with self.assertRaises(cros_build_lib.DieSystemExit):
206 artifacts.BundleTastFiles(self.input_proto, self.output_proto)
207
Alex Kleinb9d810b2019-07-01 12:38:02 -0600208 def testBundleTastFilesLegacy(self):
209 """BundleTastFiles handles legacy args correctly."""
210 buildroot = self.tempdir
211 chroot_dir = os.path.join(buildroot, 'chroot')
212 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
213 output_dir = os.path.join(self.tempdir, 'results')
214 osutils.SafeMakedirs(sysroot_path)
215 osutils.SafeMakedirs(output_dir)
216
217 chroot = chroot_lib.Chroot(chroot_dir, env={'FEATURES': 'separatedebug'})
218 sysroot = sysroot_lib.Sysroot('/build/board')
219
220 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
221 # Patch the service being called.
222 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
223 return_value=expected_archive)
224 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
225
226 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
227 output_dir=output_dir)
228 artifacts.BundleTastFiles(request, self.output_proto)
229 self.assertEqual(
230 [artifact.path for artifact in self.output_proto.artifacts],
231 [expected_archive])
232 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
233
234 def testBundleTastFiles(self):
235 """BundleTastFiles calls service correctly."""
236 # Setup.
237 sysroot_path = os.path.join(self.tempdir, 'sysroot')
238 output_dir = os.path.join(self.tempdir, 'results')
239 osutils.SafeMakedirs(sysroot_path)
240 osutils.SafeMakedirs(output_dir)
241
242 chroot = chroot_lib.Chroot(self.tempdir, env={'FEATURES': 'separatedebug'})
243 sysroot = sysroot_lib.Sysroot('/sysroot')
244
245 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
246 # Patch the service being called.
247 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
248 return_value=expected_archive)
249
250 # Request and response building.
251 request = artifacts_pb2.BundleRequest(chroot={'path': self.tempdir},
252 sysroot={'path': '/sysroot'},
253 output_dir=output_dir)
254 response = artifacts_pb2.BundleResponse()
255
256 artifacts.BundleTastFiles(request, response)
257
258 # Make sure the artifact got recorded successfully.
259 self.assertTrue(response.artifacts)
260 self.assertEqual(expected_archive, response.artifacts[0].path)
261 # Make sure the service got called correctly.
262 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
263
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600264
265class BundlePinnedGuestImagesTest(BundleTestCase):
266 """Unittests for BundlePinnedGuestImages."""
267
268 def testBundlePinnedGuestImages(self):
269 """BundlePinnedGuestImages calls cbuildbot/commands with correct args."""
270 build_pinned_guest_images_tarball = self.PatchObject(
271 commands,
272 'BuildPinnedGuestImagesTarball',
273 return_value='pinned-guest-images.tar.gz')
274 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto)
275 self.assertEqual(
276 [artifact.path for artifact in self.output_proto.artifacts],
277 ['/tmp/artifacts/pinned-guest-images.tar.gz'])
278 self.assertEqual(build_pinned_guest_images_tarball.call_args_list,
279 [mock.call('/cros', 'target', '/tmp/artifacts')])
280
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600281 def testBundlePinnedGuestImagesNoLogs(self):
Evan Hernandezde445982019-04-22 13:42:34 -0600282 """BundlePinnedGuestImages does not die when no pinned images found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600283 self.PatchObject(commands, 'BuildPinnedGuestImagesTarball',
284 return_value=None)
Evan Hernandezde445982019-04-22 13:42:34 -0600285 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto)
286 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600287
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600288
289class BundleFirmwareTest(BundleTestCase):
290 """Unittests for BundleFirmware."""
291
Michael Mortensen38675192019-06-28 16:52:55 +0000292 def setUp(self):
293 self.sysroot_path = '/build/target'
294 # Empty input_proto object.
295 self.input_proto = artifacts_pb2.BundleRequest()
296 # Input proto object with sysroot.path and output_dir set up when invoking
297 # the controller BundleFirmware method which will validate proto fields.
298 self.sysroot_input_proto = artifacts_pb2.BundleRequest()
299 self.sysroot_input_proto.sysroot.path = '/tmp/sysroot'
300 self.sysroot_input_proto.output_dir = '/tmp/artifacts'
301 self.output_proto = artifacts_pb2.BundleResponse()
302
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600303 def testBundleFirmware(self):
304 """BundleFirmware calls cbuildbot/commands with correct args."""
Michael Mortensen38675192019-06-28 16:52:55 +0000305 self.PatchObject(artifacts_svc,
306 'BuildFirmwareArchive', return_value='firmware.tar.gz')
307 artifacts.BundleFirmware(self.sysroot_input_proto, self.output_proto)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600308 self.assertEqual(
309 [artifact.path for artifact in self.output_proto.artifacts],
310 ['/tmp/artifacts/firmware.tar.gz'])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600311
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600312 def testBundleFirmwareNoLogs(self):
313 """BundleFirmware dies when no firmware found."""
314 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
315 with self.assertRaises(cros_build_lib.DieSystemExit):
316 artifacts.BundleFirmware(self.input_proto, self.output_proto)
317
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600318
319class BundleEbuildLogsTest(BundleTestCase):
320 """Unittests for BundleEbuildLogs."""
321
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600322 def setUp(self):
323 # New style paths.
324 self.chroot_path = os.path.join(self.tempdir, 'cros', 'chroot')
325 self.sysroot_path = '/build/target'
326 self.output_dir = os.path.join(self.tempdir, 'artifacts')
327 # New style proto.
328 self.request = artifacts_pb2.BundleRequest()
329 self.request.output_dir = self.output_dir
330 self.request.chroot.path = self.chroot_path
331 self.request.sysroot.path = self.sysroot_path
332 self.response = artifacts_pb2.BundleResponse()
333
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600334 def testBundleEbuildLogs(self):
335 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600336 bundle_ebuild_logs_tarball = self.PatchObject(
337 artifacts_svc, 'BundleEBuildLogsTarball',
338 return_value='ebuild-logs.tar.gz')
339 # Create the output_dir since otherwise validate.exists will fail.
340 os.mkdir(self.output_dir)
341 artifacts.BundleEbuildLogs(self.request, self.response)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600342 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600343 [artifact.path for artifact in self.response.artifacts],
344 [os.path.join(self.request.output_dir, 'ebuild-logs.tar.gz')])
345 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
Evan Hernandeza478d802019-04-08 15:08:24 -0600346 self.assertEqual(
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600347 bundle_ebuild_logs_tarball.call_args_list,
348 [mock.call(mock.ANY, sysroot, self.output_dir)])
349
350 def testBundleEBuildLogsOldProto(self):
351 bundle_ebuild_logs_tarball = self.PatchObject(
352 artifacts_svc, 'BundleEBuildLogsTarball',
353 return_value='ebuild-logs.tar.gz')
354 # Create old style proto
355 input_proto = artifacts_pb2.BundleRequest()
356 input_proto.build_target.name = 'target'
357 input_proto.output_dir = self.output_dir
358 # Create the output_dir since otherwise validate.exists will fail.
359 os.mkdir(self.output_dir)
360 output_proto = artifacts_pb2.BundleResponse()
361 artifacts.BundleEbuildLogs(input_proto, output_proto)
362 sysroot = sysroot_lib.Sysroot(self.sysroot_path)
363 self.assertEqual(
364 bundle_ebuild_logs_tarball.call_args_list,
365 [mock.call(mock.ANY, sysroot, self.output_dir)])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600366
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600367 def testBundleEbuildLogsNoLogs(self):
368 """BundleEbuildLogs dies when no logs found."""
369 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
370 with self.assertRaises(cros_build_lib.DieSystemExit):
Michael Mortensen3f382cb2019-07-29 13:21:49 -0600371 artifacts.BundleEbuildLogs(self.request, self.response)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600372
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600373
374class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase):
375 """Unittests for BundleTestUpdatePayloads."""
376
377 def setUp(self):
378 self.source_root = os.path.join(self.tempdir, 'cros')
379 osutils.SafeMakedirs(self.source_root)
380
381 self.archive_root = os.path.join(self.tempdir, 'output')
382 osutils.SafeMakedirs(self.archive_root)
383
384 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600385 self.image_root = os.path.join(self.source_root,
386 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600387
388 self.input_proto = artifacts_pb2.BundleRequest()
389 self.input_proto.build_target.name = self.target
390 self.input_proto.output_dir = self.archive_root
391 self.output_proto = artifacts_pb2.BundleResponse()
392
393 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
394
Alex Kleincb541e82019-06-26 15:06:11 -0600395 def MockPayloads(image_path, archive_dir):
396 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
397 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
398 return [os.path.join(archive_dir, 'payload1.bin'),
399 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600400
Alex Kleincb541e82019-06-26 15:06:11 -0600401 self.bundle_patch = self.PatchObject(
402 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600403
404 def testBundleTestUpdatePayloads(self):
405 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
406 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
407 osutils.WriteFile(image_path, 'image!', makedirs=True)
408
409 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto)
410
411 actual = [
412 os.path.relpath(artifact.path, self.archive_root)
413 for artifact in self.output_proto.artifacts
414 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600415 expected = ['payload1.bin', 'payload2.bin']
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600416 self.assertItemsEqual(actual, expected)
417
418 actual = [
419 os.path.relpath(path, self.archive_root)
420 for path in osutils.DirectoryIterator(self.archive_root)
421 ]
422 self.assertItemsEqual(actual, expected)
423
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600424 def testBundleTestUpdatePayloadsNoImageDir(self):
425 """BundleTestUpdatePayloads dies if no image dir is found."""
426 # Intentionally do not write image directory.
427 with self.assertRaises(cros_build_lib.DieSystemExit):
428 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto)
429
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600430 def testBundleTestUpdatePayloadsNoImage(self):
431 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600432 # Intentionally do not write image, but create the directory.
433 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600434 with self.assertRaises(cros_build_lib.DieSystemExit):
435 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto)
Alex Klein6504eca2019-04-18 15:37:56 -0600436
437
Alex Klein2275d692019-04-23 16:04:12 -0600438class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase):
439 """BundleSimpleChromeArtifacts tests."""
440
441 def setUp(self):
442 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
443 self.sysroot_path = '/sysroot'
444 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
445 osutils.SafeMakedirs(self.sysroot_dir)
446 self.output_dir = os.path.join(self.tempdir, 'output_dir')
447 osutils.SafeMakedirs(self.output_dir)
448
449 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
450
451 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
452 output_dir=None):
453 """Helper to create a request message instance.
454
455 Args:
456 chroot (str): The chroot path.
457 sysroot (str): The sysroot path.
458 build_target (str): The build target name.
459 output_dir (str): The output directory.
460 """
461 return artifacts_pb2.BundleRequest(
462 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
463 chroot={'path': chroot}, output_dir=output_dir)
464
465 def _GetResponse(self):
466 return artifacts_pb2.BundleResponse()
467
468 def testNoBuildTarget(self):
469 """Test no build target fails."""
470 request = self._GetRequest(chroot=self.chroot_dir,
471 sysroot=self.sysroot_path,
472 output_dir=self.output_dir)
473 response = self._GetResponse()
474 with self.assertRaises(cros_build_lib.DieSystemExit):
475 artifacts.BundleSimpleChromeArtifacts(request, response)
476
477 def testNoSysroot(self):
478 """Test no sysroot fails."""
479 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
480 response = self._GetResponse()
481 with self.assertRaises(cros_build_lib.DieSystemExit):
482 artifacts.BundleSimpleChromeArtifacts(request, response)
483
484 def testSysrootDoesNotExist(self):
485 """Test no sysroot fails."""
486 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
487 sysroot=self.does_not_exist)
488 response = self._GetResponse()
489 with self.assertRaises(cros_build_lib.DieSystemExit):
490 artifacts.BundleSimpleChromeArtifacts(request, response)
491
492 def testNoOutputDir(self):
493 """Test no output dir fails."""
494 request = self._GetRequest(chroot=self.chroot_dir,
495 sysroot=self.sysroot_path,
496 build_target='board')
497 response = self._GetResponse()
498 with self.assertRaises(cros_build_lib.DieSystemExit):
499 artifacts.BundleSimpleChromeArtifacts(request, response)
500
501 def testOutputDirDoesNotExist(self):
502 """Test no output dir fails."""
503 request = self._GetRequest(chroot=self.chroot_dir,
504 sysroot=self.sysroot_path,
505 build_target='board',
506 output_dir=self.does_not_exist)
507 response = self._GetResponse()
508 with self.assertRaises(cros_build_lib.DieSystemExit):
509 artifacts.BundleSimpleChromeArtifacts(request, response)
510
511 def testOutputHandling(self):
512 """Test response output."""
513 files = ['file1', 'file2', 'file3']
514 expected_files = [os.path.join(self.output_dir, f) for f in files]
515 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
516 return_value=expected_files)
517 request = self._GetRequest(chroot=self.chroot_dir,
518 sysroot=self.sysroot_path,
519 build_target='board', output_dir=self.output_dir)
520 response = self._GetResponse()
521
522 artifacts.BundleSimpleChromeArtifacts(request, response)
523
524 self.assertTrue(response.artifacts)
525 self.assertItemsEqual(expected_files, [a.path for a in response.artifacts])
526
527
Alex Klein6504eca2019-04-18 15:37:56 -0600528class BundleVmFilesTest(cros_test_lib.MockTestCase):
529 """BuildVmFiles tests."""
530
531 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
532 output_dir=None):
533 """Helper to build out an input message instance.
534
535 Args:
536 chroot (str|None): The chroot path.
537 sysroot (str|None): The sysroot path relative to the chroot.
538 test_results_dir (str|None): The test results directory relative to the
539 sysroot.
540 output_dir (str|None): The directory where the results tarball should be
541 saved.
542 """
543 return artifacts_pb2.BundleVmFilesRequest(
544 chroot={'path': chroot}, sysroot={'path': sysroot},
545 test_results_dir=test_results_dir, output_dir=output_dir,
546 )
547
548 def _GetOutput(self):
549 """Helper to get an empty output message instance."""
550 return artifacts_pb2.BundleResponse()
551
552 def testChrootMissing(self):
553 """Test error handling for missing chroot."""
554 in_proto = self._GetInput(sysroot='/build/board',
555 test_results_dir='/test/results',
556 output_dir='/tmp/output')
557 out_proto = self._GetOutput()
558
559 with self.assertRaises(cros_build_lib.DieSystemExit):
560 artifacts.BundleVmFiles(in_proto, out_proto)
561
Alex Klein6504eca2019-04-18 15:37:56 -0600562 def testTestResultsDirMissing(self):
563 """Test error handling for missing test results directory."""
564 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
565 output_dir='/tmp/output')
566 out_proto = self._GetOutput()
567
568 with self.assertRaises(cros_build_lib.DieSystemExit):
569 artifacts.BundleVmFiles(in_proto, out_proto)
570
571 def testOutputDirMissing(self):
572 """Test error handling for missing output directory."""
573 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
574 test_results_dir='/test/results')
575 out_proto = self._GetOutput()
576
577 with self.assertRaises(cros_build_lib.DieSystemExit):
578 artifacts.BundleVmFiles(in_proto, out_proto)
579
580 def testValidCall(self):
581 """Test image dir building."""
582 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
583 test_results_dir='/test/results',
584 output_dir='/tmp/output')
585 out_proto = self._GetOutput()
586 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
Michael Mortensen51f06722019-07-18 09:55:50 -0600587 patch = self.PatchObject(artifacts_svc, 'BundleVmFiles',
Alex Klein6504eca2019-04-18 15:37:56 -0600588 return_value=expected_files)
589
590 artifacts.BundleVmFiles(in_proto, out_proto)
591
Michael Mortensen51f06722019-07-18 09:55:50 -0600592 patch.assert_called_with(mock.ANY, '/test/results', '/tmp/output')
Alex Klein6504eca2019-04-18 15:37:56 -0600593
594 # Make sure we have artifacts, and that every artifact is an expected file.
595 self.assertTrue(out_proto.artifacts)
596 for artifact in out_proto.artifacts:
597 self.assertIn(artifact.path, expected_files)
598 expected_files.remove(artifact.path)
599
600 # Make sure we've seen all of the expected files.
601 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700602
Alex Kleinb9d810b2019-07-01 12:38:02 -0600603
Tiancong Wang78b685d2019-07-29 13:57:23 -0700604class BundleOrderfileGenerationArtifactsTestCase(
605 cros_test_lib.MockTempDirTestCase):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700606 """Unittests for BundleOrderfileGenerationArtifacts."""
607
608 def setUp(self):
609 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
610 osutils.SafeMakedirs(self.chroot_dir)
611 temp_dir = os.path.join(self.chroot_dir, 'tmp')
612 osutils.SafeMakedirs(temp_dir)
613 self.output_dir = os.path.join(self.tempdir, 'output_dir')
614 osutils.SafeMakedirs(self.output_dir)
615 self.build_target = 'board'
Tiancong Wang78b685d2019-07-29 13:57:23 -0700616 self.orderfile_name = 'chromeos-chrome-1.0'
Tiancong Wangc4805b72019-06-11 12:12:03 -0700617
618 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
619
Tiancong Wang78b685d2019-07-29 13:57:23 -0700620 def _GetRequest(self, chroot=None, build_target=None, output_dir=None):
Tiancong Wangc4805b72019-06-11 12:12:03 -0700621 """Helper to create a request message instance.
622
623 Args:
624 chroot (str): The chroot path.
625 build_target (str): The build target name.
626 output_dir (str): The output directory.
Tiancong Wangc4805b72019-06-11 12:12:03 -0700627 """
628 return artifacts_pb2.BundleChromeOrderfileRequest(
629 build_target={'name': build_target},
630 chroot={'path': chroot},
Tiancong Wang78b685d2019-07-29 13:57:23 -0700631 output_dir=output_dir
Tiancong Wangc4805b72019-06-11 12:12:03 -0700632 )
633
634 def _GetResponse(self):
635 return artifacts_pb2.BundleResponse()
636
637 def testNoBuildTarget(self):
638 """Test no build target fails."""
639 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wang78b685d2019-07-29 13:57:23 -0700640 output_dir=self.output_dir)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700641 response = self._GetResponse()
642 with self.assertRaises(cros_build_lib.DieSystemExit):
643 artifacts.BundleOrderfileGenerationArtifacts(request, response)
644
645 def testNoOutputDir(self):
646 """Test no output dir fails."""
647 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700648 build_target=self.build_target)
649 response = self._GetResponse()
650 with self.assertRaises(cros_build_lib.DieSystemExit):
651 artifacts.BundleOrderfileGenerationArtifacts(request, response)
652
653 def testOutputDirDoesNotExist(self):
654 """Test output directory not existing fails."""
655 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700656 build_target=self.build_target,
657 output_dir=self.does_not_exist)
658 response = self._GetResponse()
659 with self.assertRaises(cros_build_lib.DieSystemExit):
660 artifacts.BundleOrderfileGenerationArtifacts(request, response)
661
662 def testOutputHandling(self):
663 """Test response output."""
Tiancong Wang78b685d2019-07-29 13:57:23 -0700664 files = [self.orderfile_name + '.orderfile.tar.xz',
665 self.orderfile_name + '.nm.tar.xz']
Tiancong Wangc4805b72019-06-11 12:12:03 -0700666 expected_files = [os.path.join(self.output_dir, f) for f in files]
667 self.PatchObject(artifacts_svc, 'BundleOrderfileGenerationArtifacts',
668 return_value=expected_files)
669 request = self._GetRequest(chroot=self.chroot_dir,
Tiancong Wangc4805b72019-06-11 12:12:03 -0700670 build_target=self.build_target,
671 output_dir=self.output_dir)
672
673 response = self._GetResponse()
674
675 artifacts.BundleOrderfileGenerationArtifacts(request, response)
676
677 self.assertTrue(response.artifacts)
678 self.assertItemsEqual(expected_files, [a.path for a in response.artifacts])