blob: 5603c131fadb8bf1fa482b25951b6d20c6d16fb0 [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 Klein6504eca2019-04-18 15:37:56 -060016from chromite.cbuildbot.stages import vm_test_stages
Alex Kleinb9d810b2019-07-01 12:38:02 -060017from chromite.lib import chroot_lib
Evan Hernandezf388cbf2019-04-01 11:15:23 -060018from chromite.lib import constants
19from chromite.lib import cros_build_lib
20from chromite.lib import cros_test_lib
21from chromite.lib import osutils
Alex Klein238d8862019-05-07 11:32:46 -060022from chromite.lib import sysroot_lib
Alex Klein2275d692019-04-23 16:04:12 -060023from chromite.service import artifacts as artifacts_svc
Evan Hernandezf388cbf2019-04-01 11:15:23 -060024
25
Alex Kleinb9d810b2019-07-01 12:38:02 -060026class BundleTestCase(cros_test_lib.MockTempDirTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -060027 """Basic setup for all artifacts unittests."""
28
29 def setUp(self):
30 self.input_proto = artifacts_pb2.BundleRequest()
31 self.input_proto.build_target.name = 'target'
32 self.input_proto.output_dir = '/tmp/artifacts'
33 self.output_proto = artifacts_pb2.BundleResponse()
Michael Mortensen38675192019-06-28 16:52:55 +000034 self.sysroot_input_proto = artifacts_pb2.BundleRequest()
35 self.sysroot_input_proto.sysroot.path = '/tmp/sysroot'
36 self.sysroot_input_proto.output_dir = '/tmp/artifacts'
Evan Hernandezf388cbf2019-04-01 11:15:23 -060037
38 self.PatchObject(constants, 'SOURCE_ROOT', new='/cros')
39
40
Alex Klein238d8862019-05-07 11:32:46 -060041class BundleTempDirTestCase(cros_test_lib.MockTempDirTestCase):
42 """Basic setup for artifacts unittests that need a tempdir."""
43
44 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
45 output_dir=None):
46 """Helper to create a request message instance.
47
48 Args:
49 chroot (str): The chroot path.
50 sysroot (str): The sysroot path.
51 build_target (str): The build target name.
52 output_dir (str): The output directory.
53 """
54 return artifacts_pb2.BundleRequest(
55 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
56 chroot={'path': chroot}, output_dir=output_dir)
57
58 def _GetResponse(self):
59 return artifacts_pb2.BundleResponse()
60
61 def setUp(self):
62 self.output_dir = os.path.join(self.tempdir, 'artifacts')
63 osutils.SafeMakedirs(self.output_dir)
64
65 # Old style paths.
66 self.old_sysroot_path = os.path.join(self.tempdir, 'cros', 'chroot',
67 'build', 'target')
68 self.old_sysroot = sysroot_lib.Sysroot(self.old_sysroot_path)
69 osutils.SafeMakedirs(self.old_sysroot_path)
70
71 # Old style proto.
72 self.input_proto = artifacts_pb2.BundleRequest()
73 self.input_proto.build_target.name = 'target'
74 self.input_proto.output_dir = self.output_dir
75 self.output_proto = artifacts_pb2.BundleResponse()
76
77 source_root = os.path.join(self.tempdir, 'cros')
78 self.PatchObject(constants, 'SOURCE_ROOT', new=source_root)
79
80 # New style paths.
81 self.chroot_path = os.path.join(self.tempdir, 'cros', 'chroot')
82 self.sysroot_path = '/build/target'
83 self.full_sysroot_path = os.path.join(self.chroot_path,
84 self.sysroot_path.lstrip(os.sep))
85 self.sysroot = sysroot_lib.Sysroot(self.full_sysroot_path)
86 osutils.SafeMakedirs(self.full_sysroot_path)
87
88 # New style proto.
89 self.request = artifacts_pb2.BundleRequest()
90 self.request.output_dir = self.output_dir
91 self.request.chroot.path = self.chroot_path
92 self.request.sysroot.path = self.sysroot_path
93 self.response = artifacts_pb2.BundleResponse()
94
95
Evan Hernandez9f125ac2019-04-08 17:18:47 -060096class BundleImageZipTest(BundleTestCase):
97 """Unittests for BundleImageZip."""
98
99 def testBundleImageZip(self):
100 """BundleImageZip calls cbuildbot/commands with correct args."""
101 build_image_zip = self.PatchObject(
102 commands, 'BuildImageZip', return_value='image.zip')
103 self.PatchObject(os.path, 'exists', return_value=True)
104 artifacts.BundleImageZip(self.input_proto, self.output_proto)
105 self.assertEqual(
106 [artifact.path for artifact in self.output_proto.artifacts],
107 ['/tmp/artifacts/image.zip'])
108 self.assertEqual(
109 build_image_zip.call_args_list,
110 [mock.call('/tmp/artifacts', '/cros/src/build/images/target/latest')])
111
112 def testBundleImageZipNoImageDir(self):
113 """BundleImageZip dies when image dir does not exist."""
114 self.PatchObject(os.path, 'exists', return_value=False)
115 with self.assertRaises(cros_build_lib.DieSystemExit):
116 artifacts.BundleImageZip(self.input_proto, self.output_proto)
117
118
Alex Klein238d8862019-05-07 11:32:46 -0600119class BundleAutotestFilesTest(BundleTempDirTestCase):
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600120 """Unittests for BundleAutotestFiles."""
121
Alex Klein238d8862019-05-07 11:32:46 -0600122 def testBundleAutotestFilesLegacy(self):
123 """BundleAutotestFiles calls service correctly with legacy args."""
124 files = {
125 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
126 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
127 }
128 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
129 return_value=files)
130
131 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
132 return_value=self.old_sysroot)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600133 artifacts.BundleAutotestFiles(self.input_proto, self.output_proto)
Alex Klein238d8862019-05-07 11:32:46 -0600134
135 # Verify the sysroot is being built out correctly.
136 sysroot_patch.assert_called_with(self.old_sysroot_path)
137
138 # Verify the arguments are being passed through.
139 patch.assert_called_with(self.old_sysroot, self.output_dir)
140
141 # Verify the output proto is being populated correctly.
142 self.assertTrue(self.output_proto.artifacts)
143 paths = [artifact.path for artifact in self.output_proto.artifacts]
144 self.assertItemsEqual(files.values(), paths)
145
146 def testBundleAutotestFiles(self):
147 """BundleAutotestFiles calls service correctly."""
148 files = {
149 artifacts_svc.ARCHIVE_CONTROL_FILES: '/tmp/artifacts/autotest-a.tar.gz',
150 artifacts_svc.ARCHIVE_PACKAGES: '/tmp/artifacts/autotest-b.tar.gz',
151 }
152 patch = self.PatchObject(artifacts_svc, 'BundleAutotestFiles',
153 return_value=files)
154
155 sysroot_patch = self.PatchObject(sysroot_lib, 'Sysroot',
156 return_value=self.sysroot)
157 artifacts.BundleAutotestFiles(self.request, self.response)
158
159 # Verify the sysroot is being built out correctly.
160 sysroot_patch.assert_called_with(self.full_sysroot_path)
161
162 # Verify the arguments are being passed through.
163 patch.assert_called_with(self.sysroot, self.output_dir)
164
165 # Verify the output proto is being populated correctly.
166 self.assertTrue(self.response.artifacts)
167 paths = [artifact.path for artifact in self.response.artifacts]
168 self.assertItemsEqual(files.values(), paths)
169
170 def testInvalidOutputDir(self):
171 """Test invalid output directory argument."""
172 request = self._GetRequest(chroot=self.chroot_path,
173 sysroot=self.sysroot_path)
174 response = self._GetResponse()
175
176 with self.assertRaises(cros_build_lib.DieSystemExit):
177 artifacts.BundleAutotestFiles(request, response)
178
179 def testInvalidSysroot(self):
180 """Test no sysroot directory."""
181 request = self._GetRequest(chroot=self.chroot_path,
182 output_dir=self.output_dir)
183 response = self._GetResponse()
184
185 with self.assertRaises(cros_build_lib.DieSystemExit):
186 artifacts.BundleAutotestFiles(request, response)
187
188 def testSysrootDoesNotExist(self):
189 """Test dies when no sysroot does not exist."""
190 request = self._GetRequest(chroot=self.chroot_path,
191 sysroot='/does/not/exist',
192 output_dir=self.output_dir)
193 response = self._GetResponse()
194
195 with self.assertRaises(cros_build_lib.DieSystemExit):
196 artifacts.BundleAutotestFiles(request, response)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600197
198
199class BundleTastFilesTest(BundleTestCase):
200 """Unittests for BundleTastFiles."""
201
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600202 def testBundleTastFilesNoLogs(self):
203 """BundleTasteFiles dies when no tast files found."""
204 self.PatchObject(commands, 'BuildTastBundleTarball',
205 return_value=None)
206 with self.assertRaises(cros_build_lib.DieSystemExit):
207 artifacts.BundleTastFiles(self.input_proto, self.output_proto)
208
Alex Kleinb9d810b2019-07-01 12:38:02 -0600209 def testBundleTastFilesLegacy(self):
210 """BundleTastFiles handles legacy args correctly."""
211 buildroot = self.tempdir
212 chroot_dir = os.path.join(buildroot, 'chroot')
213 sysroot_path = os.path.join(chroot_dir, 'build', 'board')
214 output_dir = os.path.join(self.tempdir, 'results')
215 osutils.SafeMakedirs(sysroot_path)
216 osutils.SafeMakedirs(output_dir)
217
218 chroot = chroot_lib.Chroot(chroot_dir, env={'FEATURES': 'separatedebug'})
219 sysroot = sysroot_lib.Sysroot('/build/board')
220
221 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
222 # Patch the service being called.
223 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
224 return_value=expected_archive)
225 self.PatchObject(constants, 'SOURCE_ROOT', new=buildroot)
226
227 request = artifacts_pb2.BundleRequest(build_target={'name': 'board'},
228 output_dir=output_dir)
229 artifacts.BundleTastFiles(request, self.output_proto)
230 self.assertEqual(
231 [artifact.path for artifact in self.output_proto.artifacts],
232 [expected_archive])
233 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
234
235 def testBundleTastFiles(self):
236 """BundleTastFiles calls service correctly."""
237 # Setup.
238 sysroot_path = os.path.join(self.tempdir, 'sysroot')
239 output_dir = os.path.join(self.tempdir, 'results')
240 osutils.SafeMakedirs(sysroot_path)
241 osutils.SafeMakedirs(output_dir)
242
243 chroot = chroot_lib.Chroot(self.tempdir, env={'FEATURES': 'separatedebug'})
244 sysroot = sysroot_lib.Sysroot('/sysroot')
245
246 expected_archive = os.path.join(output_dir, artifacts_svc.TAST_BUNDLE_NAME)
247 # Patch the service being called.
248 bundle_patch = self.PatchObject(artifacts_svc, 'BundleTastFiles',
249 return_value=expected_archive)
250
251 # Request and response building.
252 request = artifacts_pb2.BundleRequest(chroot={'path': self.tempdir},
253 sysroot={'path': '/sysroot'},
254 output_dir=output_dir)
255 response = artifacts_pb2.BundleResponse()
256
257 artifacts.BundleTastFiles(request, response)
258
259 # Make sure the artifact got recorded successfully.
260 self.assertTrue(response.artifacts)
261 self.assertEqual(expected_archive, response.artifacts[0].path)
262 # Make sure the service got called correctly.
263 bundle_patch.assert_called_once_with(chroot, sysroot, output_dir)
264
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600265
266class BundlePinnedGuestImagesTest(BundleTestCase):
267 """Unittests for BundlePinnedGuestImages."""
268
269 def testBundlePinnedGuestImages(self):
270 """BundlePinnedGuestImages calls cbuildbot/commands with correct args."""
271 build_pinned_guest_images_tarball = self.PatchObject(
272 commands,
273 'BuildPinnedGuestImagesTarball',
274 return_value='pinned-guest-images.tar.gz')
275 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto)
276 self.assertEqual(
277 [artifact.path for artifact in self.output_proto.artifacts],
278 ['/tmp/artifacts/pinned-guest-images.tar.gz'])
279 self.assertEqual(build_pinned_guest_images_tarball.call_args_list,
280 [mock.call('/cros', 'target', '/tmp/artifacts')])
281
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600282 def testBundlePinnedGuestImagesNoLogs(self):
Evan Hernandezde445982019-04-22 13:42:34 -0600283 """BundlePinnedGuestImages does not die when no pinned images found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600284 self.PatchObject(commands, 'BuildPinnedGuestImagesTarball',
285 return_value=None)
Evan Hernandezde445982019-04-22 13:42:34 -0600286 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto)
287 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600288
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600289
290class BundleFirmwareTest(BundleTestCase):
291 """Unittests for BundleFirmware."""
292
Michael Mortensen38675192019-06-28 16:52:55 +0000293 def setUp(self):
294 self.sysroot_path = '/build/target'
295 # Empty input_proto object.
296 self.input_proto = artifacts_pb2.BundleRequest()
297 # Input proto object with sysroot.path and output_dir set up when invoking
298 # the controller BundleFirmware method which will validate proto fields.
299 self.sysroot_input_proto = artifacts_pb2.BundleRequest()
300 self.sysroot_input_proto.sysroot.path = '/tmp/sysroot'
301 self.sysroot_input_proto.output_dir = '/tmp/artifacts'
302 self.output_proto = artifacts_pb2.BundleResponse()
303
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600304 def testBundleFirmware(self):
305 """BundleFirmware calls cbuildbot/commands with correct args."""
Michael Mortensen38675192019-06-28 16:52:55 +0000306 self.PatchObject(artifacts_svc,
307 'BuildFirmwareArchive', return_value='firmware.tar.gz')
308 artifacts.BundleFirmware(self.sysroot_input_proto, self.output_proto)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600309 self.assertEqual(
310 [artifact.path for artifact in self.output_proto.artifacts],
311 ['/tmp/artifacts/firmware.tar.gz'])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600312
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600313 def testBundleFirmwareNoLogs(self):
314 """BundleFirmware dies when no firmware found."""
315 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
316 with self.assertRaises(cros_build_lib.DieSystemExit):
317 artifacts.BundleFirmware(self.input_proto, self.output_proto)
318
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600319
320class BundleEbuildLogsTest(BundleTestCase):
321 """Unittests for BundleEbuildLogs."""
322
323 def testBundleEbuildLogs(self):
324 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
325 build_ebuild_logs_tarball = self.PatchObject(
326 commands, 'BuildEbuildLogsTarball', return_value='ebuild-logs.tar.gz')
327 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto)
328 self.assertEqual(
329 [artifact.path for artifact in self.output_proto.artifacts],
330 ['/tmp/artifacts/ebuild-logs.tar.gz'])
Evan Hernandeza478d802019-04-08 15:08:24 -0600331 self.assertEqual(
332 build_ebuild_logs_tarball.call_args_list,
333 [mock.call('/cros/chroot/build', 'target', '/tmp/artifacts')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600334
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600335 def testBundleEbuildLogsNoLogs(self):
336 """BundleEbuildLogs dies when no logs found."""
337 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
338 with self.assertRaises(cros_build_lib.DieSystemExit):
339 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto)
340
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600341
342class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase):
343 """Unittests for BundleTestUpdatePayloads."""
344
345 def setUp(self):
346 self.source_root = os.path.join(self.tempdir, 'cros')
347 osutils.SafeMakedirs(self.source_root)
348
349 self.archive_root = os.path.join(self.tempdir, 'output')
350 osutils.SafeMakedirs(self.archive_root)
351
352 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600353 self.image_root = os.path.join(self.source_root,
354 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600355
356 self.input_proto = artifacts_pb2.BundleRequest()
357 self.input_proto.build_target.name = self.target
358 self.input_proto.output_dir = self.archive_root
359 self.output_proto = artifacts_pb2.BundleResponse()
360
361 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
362
Alex Kleincb541e82019-06-26 15:06:11 -0600363 def MockPayloads(image_path, archive_dir):
364 osutils.WriteFile(os.path.join(archive_dir, 'payload1.bin'), image_path)
365 osutils.WriteFile(os.path.join(archive_dir, 'payload2.bin'), image_path)
366 return [os.path.join(archive_dir, 'payload1.bin'),
367 os.path.join(archive_dir, 'payload2.bin')]
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600368
Alex Kleincb541e82019-06-26 15:06:11 -0600369 self.bundle_patch = self.PatchObject(
370 artifacts_svc, 'BundleTestUpdatePayloads', side_effect=MockPayloads)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600371
372 def testBundleTestUpdatePayloads(self):
373 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
374 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
375 osutils.WriteFile(image_path, 'image!', makedirs=True)
376
377 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto)
378
379 actual = [
380 os.path.relpath(artifact.path, self.archive_root)
381 for artifact in self.output_proto.artifacts
382 ]
Alex Kleincb541e82019-06-26 15:06:11 -0600383 expected = ['payload1.bin', 'payload2.bin']
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600384 self.assertItemsEqual(actual, expected)
385
386 actual = [
387 os.path.relpath(path, self.archive_root)
388 for path in osutils.DirectoryIterator(self.archive_root)
389 ]
390 self.assertItemsEqual(actual, expected)
391
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600392 def testBundleTestUpdatePayloadsNoImageDir(self):
393 """BundleTestUpdatePayloads dies if no image dir is found."""
394 # Intentionally do not write image directory.
395 with self.assertRaises(cros_build_lib.DieSystemExit):
396 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto)
397
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600398 def testBundleTestUpdatePayloadsNoImage(self):
399 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600400 # Intentionally do not write image, but create the directory.
401 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600402 with self.assertRaises(cros_build_lib.DieSystemExit):
403 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto)
Alex Klein6504eca2019-04-18 15:37:56 -0600404
405
Alex Klein2275d692019-04-23 16:04:12 -0600406class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase):
407 """BundleSimpleChromeArtifacts tests."""
408
409 def setUp(self):
410 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
411 self.sysroot_path = '/sysroot'
412 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
413 osutils.SafeMakedirs(self.sysroot_dir)
414 self.output_dir = os.path.join(self.tempdir, 'output_dir')
415 osutils.SafeMakedirs(self.output_dir)
416
417 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
418
419 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
420 output_dir=None):
421 """Helper to create a request message instance.
422
423 Args:
424 chroot (str): The chroot path.
425 sysroot (str): The sysroot path.
426 build_target (str): The build target name.
427 output_dir (str): The output directory.
428 """
429 return artifacts_pb2.BundleRequest(
430 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
431 chroot={'path': chroot}, output_dir=output_dir)
432
433 def _GetResponse(self):
434 return artifacts_pb2.BundleResponse()
435
436 def testNoBuildTarget(self):
437 """Test no build target fails."""
438 request = self._GetRequest(chroot=self.chroot_dir,
439 sysroot=self.sysroot_path,
440 output_dir=self.output_dir)
441 response = self._GetResponse()
442 with self.assertRaises(cros_build_lib.DieSystemExit):
443 artifacts.BundleSimpleChromeArtifacts(request, response)
444
445 def testNoSysroot(self):
446 """Test no sysroot fails."""
447 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
448 response = self._GetResponse()
449 with self.assertRaises(cros_build_lib.DieSystemExit):
450 artifacts.BundleSimpleChromeArtifacts(request, response)
451
452 def testSysrootDoesNotExist(self):
453 """Test no sysroot fails."""
454 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
455 sysroot=self.does_not_exist)
456 response = self._GetResponse()
457 with self.assertRaises(cros_build_lib.DieSystemExit):
458 artifacts.BundleSimpleChromeArtifacts(request, response)
459
460 def testNoOutputDir(self):
461 """Test no output dir fails."""
462 request = self._GetRequest(chroot=self.chroot_dir,
463 sysroot=self.sysroot_path,
464 build_target='board')
465 response = self._GetResponse()
466 with self.assertRaises(cros_build_lib.DieSystemExit):
467 artifacts.BundleSimpleChromeArtifacts(request, response)
468
469 def testOutputDirDoesNotExist(self):
470 """Test no output dir fails."""
471 request = self._GetRequest(chroot=self.chroot_dir,
472 sysroot=self.sysroot_path,
473 build_target='board',
474 output_dir=self.does_not_exist)
475 response = self._GetResponse()
476 with self.assertRaises(cros_build_lib.DieSystemExit):
477 artifacts.BundleSimpleChromeArtifacts(request, response)
478
479 def testOutputHandling(self):
480 """Test response output."""
481 files = ['file1', 'file2', 'file3']
482 expected_files = [os.path.join(self.output_dir, f) for f in files]
483 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
484 return_value=expected_files)
485 request = self._GetRequest(chroot=self.chroot_dir,
486 sysroot=self.sysroot_path,
487 build_target='board', output_dir=self.output_dir)
488 response = self._GetResponse()
489
490 artifacts.BundleSimpleChromeArtifacts(request, response)
491
492 self.assertTrue(response.artifacts)
493 self.assertItemsEqual(expected_files, [a.path for a in response.artifacts])
494
495
Alex Klein6504eca2019-04-18 15:37:56 -0600496class BundleVmFilesTest(cros_test_lib.MockTestCase):
497 """BuildVmFiles tests."""
498
499 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
500 output_dir=None):
501 """Helper to build out an input message instance.
502
503 Args:
504 chroot (str|None): The chroot path.
505 sysroot (str|None): The sysroot path relative to the chroot.
506 test_results_dir (str|None): The test results directory relative to the
507 sysroot.
508 output_dir (str|None): The directory where the results tarball should be
509 saved.
510 """
511 return artifacts_pb2.BundleVmFilesRequest(
512 chroot={'path': chroot}, sysroot={'path': sysroot},
513 test_results_dir=test_results_dir, output_dir=output_dir,
514 )
515
516 def _GetOutput(self):
517 """Helper to get an empty output message instance."""
518 return artifacts_pb2.BundleResponse()
519
520 def testChrootMissing(self):
521 """Test error handling for missing chroot."""
522 in_proto = self._GetInput(sysroot='/build/board',
523 test_results_dir='/test/results',
524 output_dir='/tmp/output')
525 out_proto = self._GetOutput()
526
527 with self.assertRaises(cros_build_lib.DieSystemExit):
528 artifacts.BundleVmFiles(in_proto, out_proto)
529
530 def testSysrootMissing(self):
531 """Test error handling for missing sysroot."""
532 in_proto = self._GetInput(chroot='/chroot/dir',
533 test_results_dir='/test/results',
534 output_dir='/tmp/output')
535 out_proto = self._GetOutput()
536
537 with self.assertRaises(cros_build_lib.DieSystemExit):
538 artifacts.BundleVmFiles(in_proto, out_proto)
539
Alex Klein6504eca2019-04-18 15:37:56 -0600540 def testTestResultsDirMissing(self):
541 """Test error handling for missing test results directory."""
542 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
543 output_dir='/tmp/output')
544 out_proto = self._GetOutput()
545
546 with self.assertRaises(cros_build_lib.DieSystemExit):
547 artifacts.BundleVmFiles(in_proto, out_proto)
548
549 def testOutputDirMissing(self):
550 """Test error handling for missing output directory."""
551 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
552 test_results_dir='/test/results')
553 out_proto = self._GetOutput()
554
555 with self.assertRaises(cros_build_lib.DieSystemExit):
556 artifacts.BundleVmFiles(in_proto, out_proto)
557
558 def testValidCall(self):
559 """Test image dir building."""
560 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
561 test_results_dir='/test/results',
562 output_dir='/tmp/output')
563 out_proto = self._GetOutput()
564 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
565 patch = self.PatchObject(vm_test_stages, 'ArchiveVMFilesFromImageDir',
566 return_value=expected_files)
567
568 artifacts.BundleVmFiles(in_proto, out_proto)
569
570 patch.assert_called_with('/chroot/dir/build/board/test/results',
571 '/tmp/output')
572
573 # Make sure we have artifacts, and that every artifact is an expected file.
574 self.assertTrue(out_proto.artifacts)
575 for artifact in out_proto.artifacts:
576 self.assertIn(artifact.path, expected_files)
577 expected_files.remove(artifact.path)
578
579 # Make sure we've seen all of the expected files.
580 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700581
Alex Kleinb9d810b2019-07-01 12:38:02 -0600582
Tiancong Wangc4805b72019-06-11 12:12:03 -0700583class BundleOrderfileGenerationArtifactsTestCase(BundleTempDirTestCase):
584 """Unittests for BundleOrderfileGenerationArtifacts."""
585
586 def setUp(self):
587 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
588 osutils.SafeMakedirs(self.chroot_dir)
589 temp_dir = os.path.join(self.chroot_dir, 'tmp')
590 osutils.SafeMakedirs(temp_dir)
591 self.output_dir = os.path.join(self.tempdir, 'output_dir')
592 osutils.SafeMakedirs(self.output_dir)
593 self.build_target = 'board'
594 self.chrome_version = 'chromeos-chrome-1.0'
595
596 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
597
598 def _GetRequest(self, chroot=None, build_target=None,
599 output_dir=None, chrome_version=None):
600 """Helper to create a request message instance.
601
602 Args:
603 chroot (str): The chroot path.
604 build_target (str): The build target name.
605 output_dir (str): The output directory.
606 chrome_version (str): The chromeos-chrome version name.
607 """
608 return artifacts_pb2.BundleChromeOrderfileRequest(
609 build_target={'name': build_target},
610 chroot={'path': chroot},
611 output_dir=output_dir,
612 chrome_version=chrome_version
613 )
614
615 def _GetResponse(self):
616 return artifacts_pb2.BundleResponse()
617
618 def testNoBuildTarget(self):
619 """Test no build target fails."""
620 request = self._GetRequest(chroot=self.chroot_dir,
621 output_dir=self.output_dir,
622 chrome_version=self.chrome_version)
623 response = self._GetResponse()
624 with self.assertRaises(cros_build_lib.DieSystemExit):
625 artifacts.BundleOrderfileGenerationArtifacts(request, response)
626
627 def testNoChromeVersion(self):
628 """Test no Chrome version fails."""
629 request = self._GetRequest(chroot=self.chroot_dir,
630 output_dir=self.output_dir,
631 build_target=self.build_target)
632 response = self._GetResponse()
633 with self.assertRaises(cros_build_lib.DieSystemExit):
634 artifacts.BundleOrderfileGenerationArtifacts(request, response)
635
636 def testNoOutputDir(self):
637 """Test no output dir fails."""
638 request = self._GetRequest(chroot=self.chroot_dir,
639 chrome_version=self.chrome_version,
640 build_target=self.build_target)
641 response = self._GetResponse()
642 with self.assertRaises(cros_build_lib.DieSystemExit):
643 artifacts.BundleOrderfileGenerationArtifacts(request, response)
644
645 def testOutputDirDoesNotExist(self):
646 """Test output directory not existing fails."""
647 request = self._GetRequest(chroot=self.chroot_dir,
648 chrome_version=self.chrome_version,
649 build_target=self.build_target,
650 output_dir=self.does_not_exist)
651 response = self._GetResponse()
652 with self.assertRaises(cros_build_lib.DieSystemExit):
653 artifacts.BundleOrderfileGenerationArtifacts(request, response)
654
655 def testOutputHandling(self):
656 """Test response output."""
Alex Kleinb9d810b2019-07-01 12:38:02 -0600657 files = [self.chrome_version + '.orderfile.tar.xz',
658 self.chrome_version + '.nm.tar.xz']
Tiancong Wangc4805b72019-06-11 12:12:03 -0700659 expected_files = [os.path.join(self.output_dir, f) for f in files]
660 self.PatchObject(artifacts_svc, 'BundleOrderfileGenerationArtifacts',
661 return_value=expected_files)
662 request = self._GetRequest(chroot=self.chroot_dir,
663 chrome_version=self.chrome_version,
664 build_target=self.build_target,
665 output_dir=self.output_dir)
666
667 response = self._GetResponse()
668
669 artifacts.BundleOrderfileGenerationArtifacts(request, response)
670
671 self.assertTrue(response.artifacts)
672 self.assertItemsEqual(expected_files, [a.path for a in response.artifacts])