blob: 211cea22bcc5778bfaf54de8eb4a822686e77212 [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
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
25class BundleTestCase(cros_test_lib.MockTestCase):
26 """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 Mortensen3df9c762019-06-19 07:50:09 -060033 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."""
100 build_image_zip = self.PatchObject(
101 commands, 'BuildImageZip', return_value='image.zip')
102 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(
108 build_image_zip.call_args_list,
109 [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
201 def testBundleTastFiles(self):
202 """BundleTastFiles calls cbuildbot/commands with correct args."""
203 build_tast_bundle_tarball = self.PatchObject(
204 commands,
205 'BuildTastBundleTarball',
206 return_value='/tmp/artifacts/tast.tar.gz')
207 artifacts.BundleTastFiles(self.input_proto, self.output_proto)
208 self.assertEqual(
209 [artifact.path for artifact in self.output_proto.artifacts],
210 ['/tmp/artifacts/tast.tar.gz'])
211 self.assertEqual(build_tast_bundle_tarball.call_args_list, [
212 mock.call('/cros', '/cros/chroot/build/target/build', '/tmp/artifacts')
213 ])
214
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600215 def testBundleTastFilesNoLogs(self):
216 """BundleTasteFiles dies when no tast files found."""
217 self.PatchObject(commands, 'BuildTastBundleTarball',
218 return_value=None)
219 with self.assertRaises(cros_build_lib.DieSystemExit):
220 artifacts.BundleTastFiles(self.input_proto, self.output_proto)
221
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600222
223class BundlePinnedGuestImagesTest(BundleTestCase):
224 """Unittests for BundlePinnedGuestImages."""
225
226 def testBundlePinnedGuestImages(self):
227 """BundlePinnedGuestImages calls cbuildbot/commands with correct args."""
228 build_pinned_guest_images_tarball = self.PatchObject(
229 commands,
230 'BuildPinnedGuestImagesTarball',
231 return_value='pinned-guest-images.tar.gz')
232 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto)
233 self.assertEqual(
234 [artifact.path for artifact in self.output_proto.artifacts],
235 ['/tmp/artifacts/pinned-guest-images.tar.gz'])
236 self.assertEqual(build_pinned_guest_images_tarball.call_args_list,
237 [mock.call('/cros', 'target', '/tmp/artifacts')])
238
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600239 def testBundlePinnedGuestImagesNoLogs(self):
Evan Hernandezde445982019-04-22 13:42:34 -0600240 """BundlePinnedGuestImages does not die when no pinned images found."""
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600241 self.PatchObject(commands, 'BuildPinnedGuestImagesTarball',
242 return_value=None)
Evan Hernandezde445982019-04-22 13:42:34 -0600243 artifacts.BundlePinnedGuestImages(self.input_proto, self.output_proto)
244 self.assertFalse(self.output_proto.artifacts)
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600245
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600246
247class BundleFirmwareTest(BundleTestCase):
248 """Unittests for BundleFirmware."""
249
250 def testBundleFirmware(self):
251 """BundleFirmware calls cbuildbot/commands with correct args."""
Michael Mortensen3df9c762019-06-19 07:50:09 -0600252 self.PatchObject(artifacts_svc,
253 'BuildFirmwareArchive', return_value='firmware.tar.gz')
254 artifacts.BundleFirmware(self.sysroot_input_proto, self.output_proto)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600255 self.assertEqual(
256 [artifact.path for artifact in self.output_proto.artifacts],
257 ['/tmp/artifacts/firmware.tar.gz'])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600258
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600259 def testBundleFirmwareNoLogs(self):
260 """BundleFirmware dies when no firmware found."""
261 self.PatchObject(commands, 'BuildFirmwareArchive', return_value=None)
262 with self.assertRaises(cros_build_lib.DieSystemExit):
263 artifacts.BundleFirmware(self.input_proto, self.output_proto)
264
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600265
266class BundleEbuildLogsTest(BundleTestCase):
267 """Unittests for BundleEbuildLogs."""
268
269 def testBundleEbuildLogs(self):
270 """BundleEbuildLogs calls cbuildbot/commands with correct args."""
271 build_ebuild_logs_tarball = self.PatchObject(
272 commands, 'BuildEbuildLogsTarball', return_value='ebuild-logs.tar.gz')
273 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto)
274 self.assertEqual(
275 [artifact.path for artifact in self.output_proto.artifacts],
276 ['/tmp/artifacts/ebuild-logs.tar.gz'])
Evan Hernandeza478d802019-04-08 15:08:24 -0600277 self.assertEqual(
278 build_ebuild_logs_tarball.call_args_list,
279 [mock.call('/cros/chroot/build', 'target', '/tmp/artifacts')])
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600280
Evan Hernandez9a5d3122019-04-09 10:51:23 -0600281 def testBundleEbuildLogsNoLogs(self):
282 """BundleEbuildLogs dies when no logs found."""
283 self.PatchObject(commands, 'BuildEbuildLogsTarball', return_value=None)
284 with self.assertRaises(cros_build_lib.DieSystemExit):
285 artifacts.BundleEbuildLogs(self.input_proto, self.output_proto)
286
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600287
288class BundleTestUpdatePayloadsTest(cros_test_lib.MockTempDirTestCase):
289 """Unittests for BundleTestUpdatePayloads."""
290
291 def setUp(self):
292 self.source_root = os.path.join(self.tempdir, 'cros')
293 osutils.SafeMakedirs(self.source_root)
294
295 self.archive_root = os.path.join(self.tempdir, 'output')
296 osutils.SafeMakedirs(self.archive_root)
297
298 self.target = 'target'
Evan Hernandez59690b72019-04-08 16:24:45 -0600299 self.image_root = os.path.join(self.source_root,
300 'src/build/images/target/latest')
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600301
302 self.input_proto = artifacts_pb2.BundleRequest()
303 self.input_proto.build_target.name = self.target
304 self.input_proto.output_dir = self.archive_root
305 self.output_proto = artifacts_pb2.BundleResponse()
306
307 self.PatchObject(constants, 'SOURCE_ROOT', new=self.source_root)
308
309 def MockGeneratePayloads(image_path, archive_dir, **kwargs):
310 assert kwargs
311 osutils.WriteFile(os.path.join(archive_dir, 'payload.bin'), image_path)
312
313 self.generate_payloads = self.PatchObject(
314 commands, 'GeneratePayloads', side_effect=MockGeneratePayloads)
315
316 def MockGenerateQuickProvisionPayloads(image_path, archive_dir):
317 osutils.WriteFile(os.path.join(archive_dir, 'payload-qp.bin'), image_path)
318
319 self.generate_quick_provision_payloads = self.PatchObject(
320 commands,
321 'GenerateQuickProvisionPayloads',
322 side_effect=MockGenerateQuickProvisionPayloads)
323
324 def testBundleTestUpdatePayloads(self):
325 """BundleTestUpdatePayloads calls cbuildbot/commands with correct args."""
326 image_path = os.path.join(self.image_root, constants.BASE_IMAGE_BIN)
327 osutils.WriteFile(image_path, 'image!', makedirs=True)
328
329 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto)
330
331 actual = [
332 os.path.relpath(artifact.path, self.archive_root)
333 for artifact in self.output_proto.artifacts
334 ]
335 expected = ['payload.bin', 'payload-qp.bin']
336 self.assertItemsEqual(actual, expected)
337
338 actual = [
339 os.path.relpath(path, self.archive_root)
340 for path in osutils.DirectoryIterator(self.archive_root)
341 ]
342 self.assertItemsEqual(actual, expected)
343
344 self.assertEqual(self.generate_payloads.call_args_list, [
345 mock.call(image_path, mock.ANY, full=True, stateful=True, delta=True),
346 ])
347
348 self.assertEqual(self.generate_quick_provision_payloads.call_args_list,
349 [mock.call(image_path, mock.ANY)])
350
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600351 def testBundleTestUpdatePayloadsNoImageDir(self):
352 """BundleTestUpdatePayloads dies if no image dir is found."""
353 # Intentionally do not write image directory.
354 with self.assertRaises(cros_build_lib.DieSystemExit):
355 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto)
356
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600357 def testBundleTestUpdatePayloadsNoImage(self):
358 """BundleTestUpdatePayloads dies if no usable image is found for target."""
Evan Hernandez9f125ac2019-04-08 17:18:47 -0600359 # Intentionally do not write image, but create the directory.
360 osutils.SafeMakedirs(self.image_root)
Evan Hernandezf388cbf2019-04-01 11:15:23 -0600361 with self.assertRaises(cros_build_lib.DieSystemExit):
362 artifacts.BundleTestUpdatePayloads(self.input_proto, self.output_proto)
Alex Klein6504eca2019-04-18 15:37:56 -0600363
364
Alex Klein2275d692019-04-23 16:04:12 -0600365class BundleSimpleChromeArtifactsTest(cros_test_lib.MockTempDirTestCase):
366 """BundleSimpleChromeArtifacts tests."""
367
368 def setUp(self):
369 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
370 self.sysroot_path = '/sysroot'
371 self.sysroot_dir = os.path.join(self.chroot_dir, 'sysroot')
372 osutils.SafeMakedirs(self.sysroot_dir)
373 self.output_dir = os.path.join(self.tempdir, 'output_dir')
374 osutils.SafeMakedirs(self.output_dir)
375
376 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
377
378 def _GetRequest(self, chroot=None, sysroot=None, build_target=None,
379 output_dir=None):
380 """Helper to create a request message instance.
381
382 Args:
383 chroot (str): The chroot path.
384 sysroot (str): The sysroot path.
385 build_target (str): The build target name.
386 output_dir (str): The output directory.
387 """
388 return artifacts_pb2.BundleRequest(
389 sysroot={'path': sysroot, 'build_target': {'name': build_target}},
390 chroot={'path': chroot}, output_dir=output_dir)
391
392 def _GetResponse(self):
393 return artifacts_pb2.BundleResponse()
394
395 def testNoBuildTarget(self):
396 """Test no build target fails."""
397 request = self._GetRequest(chroot=self.chroot_dir,
398 sysroot=self.sysroot_path,
399 output_dir=self.output_dir)
400 response = self._GetResponse()
401 with self.assertRaises(cros_build_lib.DieSystemExit):
402 artifacts.BundleSimpleChromeArtifacts(request, response)
403
404 def testNoSysroot(self):
405 """Test no sysroot fails."""
406 request = self._GetRequest(build_target='board', output_dir=self.output_dir)
407 response = self._GetResponse()
408 with self.assertRaises(cros_build_lib.DieSystemExit):
409 artifacts.BundleSimpleChromeArtifacts(request, response)
410
411 def testSysrootDoesNotExist(self):
412 """Test no sysroot fails."""
413 request = self._GetRequest(build_target='board', output_dir=self.output_dir,
414 sysroot=self.does_not_exist)
415 response = self._GetResponse()
416 with self.assertRaises(cros_build_lib.DieSystemExit):
417 artifacts.BundleSimpleChromeArtifacts(request, response)
418
419 def testNoOutputDir(self):
420 """Test no output dir fails."""
421 request = self._GetRequest(chroot=self.chroot_dir,
422 sysroot=self.sysroot_path,
423 build_target='board')
424 response = self._GetResponse()
425 with self.assertRaises(cros_build_lib.DieSystemExit):
426 artifacts.BundleSimpleChromeArtifacts(request, response)
427
428 def testOutputDirDoesNotExist(self):
429 """Test no output dir fails."""
430 request = self._GetRequest(chroot=self.chroot_dir,
431 sysroot=self.sysroot_path,
432 build_target='board',
433 output_dir=self.does_not_exist)
434 response = self._GetResponse()
435 with self.assertRaises(cros_build_lib.DieSystemExit):
436 artifacts.BundleSimpleChromeArtifacts(request, response)
437
438 def testOutputHandling(self):
439 """Test response output."""
440 files = ['file1', 'file2', 'file3']
441 expected_files = [os.path.join(self.output_dir, f) for f in files]
442 self.PatchObject(artifacts_svc, 'BundleSimpleChromeArtifacts',
443 return_value=expected_files)
444 request = self._GetRequest(chroot=self.chroot_dir,
445 sysroot=self.sysroot_path,
446 build_target='board', output_dir=self.output_dir)
447 response = self._GetResponse()
448
449 artifacts.BundleSimpleChromeArtifacts(request, response)
450
451 self.assertTrue(response.artifacts)
452 self.assertItemsEqual(expected_files, [a.path for a in response.artifacts])
453
454
Alex Klein6504eca2019-04-18 15:37:56 -0600455class BundleVmFilesTest(cros_test_lib.MockTestCase):
456 """BuildVmFiles tests."""
457
458 def _GetInput(self, chroot=None, sysroot=None, test_results_dir=None,
459 output_dir=None):
460 """Helper to build out an input message instance.
461
462 Args:
463 chroot (str|None): The chroot path.
464 sysroot (str|None): The sysroot path relative to the chroot.
465 test_results_dir (str|None): The test results directory relative to the
466 sysroot.
467 output_dir (str|None): The directory where the results tarball should be
468 saved.
469 """
470 return artifacts_pb2.BundleVmFilesRequest(
471 chroot={'path': chroot}, sysroot={'path': sysroot},
472 test_results_dir=test_results_dir, output_dir=output_dir,
473 )
474
475 def _GetOutput(self):
476 """Helper to get an empty output message instance."""
477 return artifacts_pb2.BundleResponse()
478
479 def testChrootMissing(self):
480 """Test error handling for missing chroot."""
481 in_proto = self._GetInput(sysroot='/build/board',
482 test_results_dir='/test/results',
483 output_dir='/tmp/output')
484 out_proto = self._GetOutput()
485
486 with self.assertRaises(cros_build_lib.DieSystemExit):
487 artifacts.BundleVmFiles(in_proto, out_proto)
488
489 def testSysrootMissing(self):
490 """Test error handling for missing sysroot."""
491 in_proto = self._GetInput(chroot='/chroot/dir',
492 test_results_dir='/test/results',
493 output_dir='/tmp/output')
494 out_proto = self._GetOutput()
495
496 with self.assertRaises(cros_build_lib.DieSystemExit):
497 artifacts.BundleVmFiles(in_proto, out_proto)
498
Alex Klein6504eca2019-04-18 15:37:56 -0600499 def testTestResultsDirMissing(self):
500 """Test error handling for missing test results directory."""
501 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
502 output_dir='/tmp/output')
503 out_proto = self._GetOutput()
504
505 with self.assertRaises(cros_build_lib.DieSystemExit):
506 artifacts.BundleVmFiles(in_proto, out_proto)
507
508 def testOutputDirMissing(self):
509 """Test error handling for missing output directory."""
510 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
511 test_results_dir='/test/results')
512 out_proto = self._GetOutput()
513
514 with self.assertRaises(cros_build_lib.DieSystemExit):
515 artifacts.BundleVmFiles(in_proto, out_proto)
516
517 def testValidCall(self):
518 """Test image dir building."""
519 in_proto = self._GetInput(chroot='/chroot/dir', sysroot='/build/board',
520 test_results_dir='/test/results',
521 output_dir='/tmp/output')
522 out_proto = self._GetOutput()
523 expected_files = ['/tmp/output/f1.tar', '/tmp/output/f2.tar']
524 patch = self.PatchObject(vm_test_stages, 'ArchiveVMFilesFromImageDir',
525 return_value=expected_files)
526
527 artifacts.BundleVmFiles(in_proto, out_proto)
528
529 patch.assert_called_with('/chroot/dir/build/board/test/results',
530 '/tmp/output')
531
532 # Make sure we have artifacts, and that every artifact is an expected file.
533 self.assertTrue(out_proto.artifacts)
534 for artifact in out_proto.artifacts:
535 self.assertIn(artifact.path, expected_files)
536 expected_files.remove(artifact.path)
537
538 # Make sure we've seen all of the expected files.
539 self.assertFalse(expected_files)
Tiancong Wangc4805b72019-06-11 12:12:03 -0700540
541class BundleOrderfileGenerationArtifactsTestCase(BundleTempDirTestCase):
542 """Unittests for BundleOrderfileGenerationArtifacts."""
543
544 def setUp(self):
545 self.chroot_dir = os.path.join(self.tempdir, 'chroot_dir')
546 osutils.SafeMakedirs(self.chroot_dir)
547 temp_dir = os.path.join(self.chroot_dir, 'tmp')
548 osutils.SafeMakedirs(temp_dir)
549 self.output_dir = os.path.join(self.tempdir, 'output_dir')
550 osutils.SafeMakedirs(self.output_dir)
551 self.build_target = 'board'
552 self.chrome_version = 'chromeos-chrome-1.0'
553
554 self.does_not_exist = os.path.join(self.tempdir, 'does_not_exist')
555
556 def _GetRequest(self, chroot=None, build_target=None,
557 output_dir=None, chrome_version=None):
558 """Helper to create a request message instance.
559
560 Args:
561 chroot (str): The chroot path.
562 build_target (str): The build target name.
563 output_dir (str): The output directory.
564 chrome_version (str): The chromeos-chrome version name.
565 """
566 return artifacts_pb2.BundleChromeOrderfileRequest(
567 build_target={'name': build_target},
568 chroot={'path': chroot},
569 output_dir=output_dir,
570 chrome_version=chrome_version
571 )
572
573 def _GetResponse(self):
574 return artifacts_pb2.BundleResponse()
575
576 def testNoBuildTarget(self):
577 """Test no build target fails."""
578 request = self._GetRequest(chroot=self.chroot_dir,
579 output_dir=self.output_dir,
580 chrome_version=self.chrome_version)
581 response = self._GetResponse()
582 with self.assertRaises(cros_build_lib.DieSystemExit):
583 artifacts.BundleOrderfileGenerationArtifacts(request, response)
584
585 def testNoChromeVersion(self):
586 """Test no Chrome version fails."""
587 request = self._GetRequest(chroot=self.chroot_dir,
588 output_dir=self.output_dir,
589 build_target=self.build_target)
590 response = self._GetResponse()
591 with self.assertRaises(cros_build_lib.DieSystemExit):
592 artifacts.BundleOrderfileGenerationArtifacts(request, response)
593
594 def testNoOutputDir(self):
595 """Test no output dir fails."""
596 request = self._GetRequest(chroot=self.chroot_dir,
597 chrome_version=self.chrome_version,
598 build_target=self.build_target)
599 response = self._GetResponse()
600 with self.assertRaises(cros_build_lib.DieSystemExit):
601 artifacts.BundleOrderfileGenerationArtifacts(request, response)
602
603 def testOutputDirDoesNotExist(self):
604 """Test output directory not existing fails."""
605 request = self._GetRequest(chroot=self.chroot_dir,
606 chrome_version=self.chrome_version,
607 build_target=self.build_target,
608 output_dir=self.does_not_exist)
609 response = self._GetResponse()
610 with self.assertRaises(cros_build_lib.DieSystemExit):
611 artifacts.BundleOrderfileGenerationArtifacts(request, response)
612
613 def testOutputHandling(self):
614 """Test response output."""
615 files = [self.chrome_version+'.orderfile.tar.xz',
616 self.chrome_version+'.nm.tar.xz']
617 expected_files = [os.path.join(self.output_dir, f) for f in files]
618 self.PatchObject(artifacts_svc, 'BundleOrderfileGenerationArtifacts',
619 return_value=expected_files)
620 request = self._GetRequest(chroot=self.chroot_dir,
621 chrome_version=self.chrome_version,
622 build_target=self.build_target,
623 output_dir=self.output_dir)
624
625 response = self._GetResponse()
626
627 artifacts.BundleOrderfileGenerationArtifacts(request, response)
628
629 self.assertTrue(response.artifacts)
630 self.assertItemsEqual(expected_files, [a.path for a in response.artifacts])