blob: 1ab1a021ebb2775225f25629f4c248b0802fcd2e [file] [log] [blame]
# 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'])