| # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """This module tests the cros image command.""" |
| |
| from __future__ import print_function |
| |
| import os |
| |
| from chromite.cbuildbot import constants |
| from chromite.cli import command |
| from chromite.cli import command_unittest |
| from chromite.cli.cros import cros_image |
| from chromite.lib import commandline |
| from chromite.lib import cros_build_lib |
| from chromite.lib import cros_build_lib_unittest |
| from chromite.lib import cros_test_lib |
| from chromite.lib import image_lib |
| |
| |
| class MockImageCommand(command_unittest.MockCommand): |
| """Mock out the image command.""" |
| TARGET = 'chromite.cli.cros.cros_image.ImageCommand' |
| TARGET_CLASS = cros_image.ImageCommand |
| COMMAND = 'image' |
| |
| def __init__(self, *args, **kwargs): |
| super(MockImageCommand, self).__init__(*args, **kwargs) |
| |
| def Run(self, inst): |
| return super(MockImageCommand, self).Run(inst) |
| |
| |
| class ImageCommandTest(cros_test_lib.WorkspaceTestCase, |
| cros_test_lib.OutputTestCase): |
| """Test class for our ImageCommand class.""" |
| |
| def SetupCommandMock(self, cmd_args): |
| """Sets up the `cros image` command mock.""" |
| self.cmd_mock = MockImageCommand(cmd_args) |
| |
| def setUp(self): |
| self.cmd_mock = None |
| self.CreateWorkspace() |
| |
| # Since the build_image command is mocked out and the workspace directory |
| # is patched, fake being in the chroot to allow running the unittest |
| # outside the chroot. |
| self.PatchObject(cros_build_lib, 'IsInsideChroot', return_value=True) |
| |
| self.rc_mock = self.StartPatcher(cros_build_lib_unittest.RunCommandMock()) |
| self.rc_mock.SetDefaultCmdResult() |
| |
| def testBlueprint(self): |
| """Tests running the full image command with a blueprint.""" |
| self.CreateBrick(name='brick1', main_package='brick/foo') |
| self.CreateBrick(name='brick2', main_package='brick/bar') |
| self.CreateBrick(name='bsp1', main_package='bsp/baz') |
| self.CreateBlueprint(name='foo.json', bricks=['//brick1', '//brick2'], |
| bsp='//bsp1') |
| |
| args = ['--blueprint=//foo.json'] |
| self.SetupCommandMock(args) |
| self.cmd_mock.inst.Run() |
| |
| expected_args = [os.path.join(constants.CROSUTILS_DIR, 'build_image'), |
| '--board=foo.json', |
| '--extra_packages=brick/foo brick/bar bsp/baz', |
| '--noenable_bootcache', '--enable_rootfs_verification', |
| '--loglevel=7'] |
| self.rc_mock.assertCommandContains(expected_args) |
| |
| def testBlueprintWithBuildTargetId(self): |
| """Tests running the full image command with a valid BuildTargetId.""" |
| self.CreateBrick(name='brick1', main_package='brick/foo') |
| self.CreateBrick(name='brick2', main_package='brick/bar') |
| self.CreateBrick(name='bsp1', main_package='bsp/baz') |
| self.CreateBlueprint(name='foo.json', bricks=['//brick1', '//brick2'], |
| bsp='//bsp1', |
| buildTargetId='{01234567-89AB-CDEF-0123-456789ABCDEF}') |
| |
| args = ['--blueprint=//foo.json'] |
| self.SetupCommandMock(args) |
| self.cmd_mock.inst.Run() |
| |
| expected_args = [os.path.join(constants.CROSUTILS_DIR, 'build_image'), |
| '--app_id={01234567-89AB-CDEF-0123-456789ABCDEF}', |
| '--board=foo.json', |
| '--extra_packages=brick/foo brick/bar bsp/baz', |
| '--noenable_bootcache', '--enable_rootfs_verification', |
| '--loglevel=7'] |
| self.rc_mock.assertCommandContains(expected_args) |
| |
| def testBlueprintWithInvalidBuildTargetId(self): |
| """Tests running the full image command with invalid BuildTargetId.""" |
| self.CreateBrick(name='brick1', main_package='brick/foo') |
| self.CreateBrick(name='brick2', main_package='brick/bar') |
| self.CreateBrick(name='bsp1', main_package='bsp/baz') |
| self.CreateBlueprint(name='foo.json', bricks=['//brick1', '//brick2'], |
| bsp='//bsp1', |
| buildTargetId='{01234567-89AB-CDEF-0123-45678}') |
| |
| args = ['--blueprint=//foo.json'] |
| self.SetupCommandMock(args) |
| self.AssertFuncSystemExitNonZero(self.cmd_mock.inst.Run) |
| |
| def testOutputRootInWorkspace(self): |
| """Tests running the image command with an output root in the workspace.""" |
| self.CreateWorkspace() |
| self.CreateBrick(name='brick1', main_package='brick/foo') |
| self.CreateBrick(name='bsp1', main_package='bsp/baz') |
| self.CreateBlueprint(name='bar.json', bricks=['//brick1'], bsp='//bsp1') |
| |
| args = ['--blueprint=//bar.json', '--output_root=//images'] |
| self.SetupCommandMock(args) |
| self.cmd_mock.inst.Run() |
| |
| expected_args = [os.path.join(constants.CROSUTILS_DIR, 'build_image'), |
| '--board=bar.json', |
| '--extra_packages=brick/foo bsp/baz', |
| '--noenable_bootcache', '--enable_rootfs_verification', |
| '--output_root=%s' % os.path.join(self.workspace_path, |
| 'images'), |
| '--loglevel=7'] |
| self.rc_mock.assertCommandContains(expected_args) |
| |
| def testProgressBar(self): |
| """Test that RunCommand is called with --progress_bar.""" |
| self.PatchObject(command, 'UseProgressBar', return_value=True) |
| op = self.PatchObject(image_lib.BrilloImageOperation, 'Run') |
| self.SetupCommandMock([]) |
| self.cmd_mock.inst.Run() |
| |
| # Test that BrilloImageOperation.Run is called with the correct arguments. |
| self.assertEqual(1, op.call_count) |
| self.assertTrue('--progress_bar' in op.call_args[0][1]) |
| |
| def testToolsetBrillo(self): |
| """Test RunCommand called with --toolset=brillo when using brillo.""" |
| self.PatchObject(command, 'GetToolset', return_value='brillo') |
| self.SetupCommandMock([]) |
| self.cmd_mock.inst.Run() |
| |
| # Test that build_image is called with the correct arguments. |
| cmds = '\n'.join(repr(x) for x in self.rc_mock.call_args_list) |
| self.assertIn('--toolset=brillo', cmds) |
| |
| |
| class ImageCommandParserTest(cros_test_lib.TestCase): |
| """Test class for our ImageCommand's parser.""" |
| |
| def testParserDefaults(self): |
| """Tests that the parser's default values are correct.""" |
| fake_parser = commandline.ArgumentParser() |
| fake_subparser = fake_parser.add_subparsers() |
| image_parser = fake_subparser.add_parser('image') |
| cros_image.ImageCommand.AddParser(image_parser) |
| |
| options = fake_parser.parse_args(['image']) |
| instance = options.command_class(options) |
| self.assertEqual(instance.options.adjust_part, None) |
| self.assertEqual(instance.options.board, None) |
| self.assertEqual(instance.options.boot_args, None) |
| self.assertFalse(instance.options.enable_bootcache, False) |
| self.assertTrue(instance.options.enable_rootfs_verification, True) |
| self.assertEqual(instance.options.output_root, '//build/images') |
| self.assertEqual(instance.options.disk_layout, None) |
| self.assertEqual(instance.options.enable_serial, None) |
| self.assertEqual(instance.options.kernel_log_level, 7) |
| self.assertEqual(instance.options.image_types, 'test') |
| |
| def testParserSetValues(self): |
| """Tests that the parser reads in values correctly.""" |
| fake_parser = commandline.ArgumentParser() |
| fake_subparser = fake_parser.add_subparsers() |
| image_parser = fake_subparser.add_parser('image') |
| cros_image.ImageCommand.AddParser(image_parser) |
| |
| options = fake_parser.parse_args(['image', |
| '--adjust_part=PARTX', |
| '--board=fooboard', |
| '--boot_args=bar', |
| '--enable_bootcache=True', |
| '--enable_rootfs_verification=False', |
| '--output_root=/foo/bar/baz', |
| '--disk_layout=fooboard/layout.conf', |
| '--enable_serial=ttyS0', |
| '--kernel_log_level=2', |
| 'dev', 'test']) |
| instance = options.command_class(options) |
| self.assertEqual(instance.options.adjust_part, 'PARTX') |
| self.assertEqual(instance.options.board, 'fooboard') |
| self.assertEqual(instance.options.boot_args, 'bar') |
| self.assertTrue(instance.options.enable_bootcache) |
| self.assertFalse(instance.options.enable_rootfs_verification) |
| self.assertEqual(instance.options.output_root, '/foo/bar/baz') |
| self.assertEqual(instance.options.disk_layout, 'fooboard/layout.conf') |
| self.assertEqual(instance.options.enable_serial, 'ttyS0') |
| self.assertEqual(instance.options.kernel_log_level, 2) |
| self.assertEqual(instance.options.image_types, ['dev', 'test']) |
| |
| def testParserSetValuesDefaults(self): |
| """Tests that the parser reads in values correctly when set to defaults.""" |
| fake_parser = commandline.ArgumentParser() |
| fake_subparser = fake_parser.add_subparsers() |
| image_parser = fake_subparser.add_parser('image') |
| cros_image.ImageCommand.AddParser(image_parser) |
| |
| options = fake_parser.parse_args(['image', |
| '--adjust_part=PARTX', |
| '--board=fooboard', |
| '--boot_args=bar', |
| '--enable_bootcache=False', |
| '--enable_rootfs_verification=True', |
| '--output_root=//build/images', |
| '--disk_layout=fooboard/layout.conf', |
| '--enable_serial=ttyS0', |
| '--kernel_log_level=7', |
| 'dev', 'test']) |
| instance = options.command_class(options) |
| self.assertEqual(instance.options.adjust_part, 'PARTX') |
| self.assertEqual(instance.options.board, 'fooboard') |
| self.assertEqual(instance.options.boot_args, 'bar') |
| self.assertFalse(instance.options.enable_bootcache) |
| self.assertTrue(instance.options.enable_rootfs_verification) |
| self.assertEqual(instance.options.output_root, '//build/images') |
| self.assertEqual(instance.options.disk_layout, 'fooboard/layout.conf') |
| self.assertEqual(instance.options.enable_serial, 'ttyS0') |
| self.assertEqual(instance.options.kernel_log_level, 7) |
| self.assertEqual(instance.options.image_types, ['dev', 'test']) |
| |
| def testParserSetBooleansTrue(self): |
| """Tests that the parser reads in booleans correctly when set to True.""" |
| fake_parser = commandline.ArgumentParser() |
| fake_subparser = fake_parser.add_subparsers() |
| image_parser = fake_subparser.add_parser('image') |
| cros_image.ImageCommand.AddParser(image_parser) |
| |
| options = fake_parser.parse_args(['image', |
| '--board=fooboard', |
| '--enable_bootcache=True', |
| '--enable_rootfs_verification=True', |
| 'dev', 'test']) |
| instance = options.command_class(options) |
| self.assertEqual(instance.options.board, 'fooboard') |
| self.assertTrue(instance.options.enable_bootcache) |
| self.assertTrue(instance.options.enable_rootfs_verification) |
| self.assertEqual(instance.options.image_types, ['dev', 'test']) |
| |
| def testParserSetBooleansFalse(self): |
| """Tests that the parser reads in booleans correctly when set to False.""" |
| fake_parser = commandline.ArgumentParser() |
| fake_subparser = fake_parser.add_subparsers() |
| image_parser = fake_subparser.add_parser('image') |
| cros_image.ImageCommand.AddParser(image_parser) |
| |
| options = fake_parser.parse_args(['image', |
| '--board=fooboard', |
| '--enable_bootcache=False', |
| '--enable_rootfs_verification=False', |
| 'dev', 'test']) |
| instance = options.command_class(options) |
| self.assertEqual(instance.options.board, 'fooboard') |
| self.assertFalse(instance.options.enable_bootcache) |
| self.assertFalse(instance.options.enable_rootfs_verification) |
| self.assertEqual(instance.options.image_types, ['dev', 'test']) |
| |
| def testParserBooleanDefaults(self): |
| """Tests that the parser sets booleans to defaults when they are omitted.""" |
| fake_parser = commandline.ArgumentParser() |
| fake_subparser = fake_parser.add_subparsers() |
| image_parser = fake_subparser.add_parser('image') |
| cros_image.ImageCommand.AddParser(image_parser) |
| |
| options = fake_parser.parse_args(['image', |
| '--board=fooboard', |
| 'dev', 'test']) |
| instance = options.command_class(options) |
| self.assertEqual(instance.options.board, 'fooboard') |
| self.assertFalse(instance.options.enable_bootcache) |
| self.assertTrue(instance.options.enable_rootfs_verification) |
| self.assertEqual(instance.options.image_types, ['dev', 'test']) |