blob: 71f7659e24e1012cc014fb416ff4b1c83a01de06 [file] [log] [blame]
# Copyright 2015 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.
"""Unit tests for brillo_package."""
from __future__ import print_function
import os
from chromite.cli import command_unittest
from chromite.cli.brillo import brillo_package
from chromite.lib import brick_lib
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import osutils
class MockPackageCommand(command_unittest.MockCommand):
"""Mock out the `brillo package` command."""
TARGET = 'chromite.cli.brillo.brillo_package.PackageCommand'
TARGET_CLASS = brillo_package.PackageCommand
COMMAND = 'package'
class PackageCommandTest(cros_test_lib.OutputTestCase,
cros_test_lib.WorkspaceTestCase):
"""Test the flow of PackageCommand.Run()."""
_PACKAGE_CATEGORY = 'foo'
_PACKAGE_NAME = 'bar'
_PACKAGE = '%s/%s' % (_PACKAGE_CATEGORY, _PACKAGE_NAME)
def SetupCommandMock(self, cmd_args, create_cwd_brick=True):
"""Sets up the MockPackageCommand.
Args:
cmd_args: List of args to pass to `cros package`.
create_cwd_brick: True to create an implicit CWD brick to use.
"""
if create_cwd_brick:
self.cwd_brick = self.CreateBrick()
self.PatchObject(brick_lib, 'FindBrickInPath',
return_value=self.cwd_brick)
# Save some long paths that are required by several tests.
self.cwd_brick_categories_file = os.path.join(
self.cwd_brick.OverlayDir(), 'profiles', 'categories')
self.cwd_brick_ebuild_file = os.path.join(
self.cwd_brick.OverlayDir(), self._PACKAGE_CATEGORY,
self._PACKAGE_NAME, '%s-9999.ebuild' % self._PACKAGE_NAME)
self.cmd_mock = MockPackageCommand(cmd_args)
self.StartPatcher(self.cmd_mock)
def RunCommandMock(self, *args, **kwargs):
"""Sets up and runs the MockPackageCommand.
Convenience function to call SetupCommandMock() and run the
mock in one call.
Args:
args: Args to pass to SetupCommandMock().
kwargs: Keyword args to pass to SetupCommandMock().
"""
self.SetupCommandMock(*args, **kwargs)
self.cmd_mock.inst.Run()
def setUp(self):
"""Patches objects."""
self.CreateWorkspace()
self.PatchObject(commandline, 'RunInsideChroot')
# These objects are valid after SetupCommandMock() has been called.
self.cmd_mock = None
self.cwd_brick = None
self.cwd_brick_categories_file = None
self.cwd_brick_ebuild_file = None
def testCwdBrick(self):
"""Tests no-op using the CWD brick."""
self.RunCommandMock([self._PACKAGE])
self.assertEqual(self.cwd_brick.brick_locator,
self.cmd_mock.inst.brick.brick_locator)
def testExplicitBrick(self):
"""Tests the --brick argument takes priority over CWD."""
brick_locator = '//bricks/mybrick'
self.CreateBrick(brick_locator)
self.RunCommandMock(['--brick', brick_locator, self._PACKAGE])
self.assertEqual(brick_locator, self.cmd_mock.inst.brick.brick_locator)
def testBrickPathNormalization(self):
"""Tests brick path normalization."""
brick_locator = '//bricks/mybrick'
short_path = 'mybrick'
self.CreateBrick(brick_locator)
self.RunCommandMock(['--brick', short_path, self._PACKAGE])
self.assertEqual(brick_locator, self.cmd_mock.inst.brick.brick_locator)
def testNoBrick(self):
"""Tests that execution fails without a brick."""
with self.assertRaises(cros_build_lib.DieSystemExit):
self.RunCommandMock([self._PACKAGE], create_cwd_brick=False)
def testInvalidBrick(self):
"""Tests that execution fails with a non-existent brick."""
with self.assertRaises(cros_build_lib.DieSystemExit):
self.RunCommandMock(['--brick', '//not/a/brick', self._PACKAGE])
def testEnableLatest(self):
"""Tests --enable latest."""
self.RunCommandMock(['--enable', 'latest', self._PACKAGE])
self.cmd_mock.rc_mock.assertCommandContains(
['cros_workon', 'start', '--brick=%s' % self.cwd_brick.brick_locator,
self._PACKAGE])
def testEnableStable(self):
"""Tests --enable stable."""
self.RunCommandMock(['--enable', 'stable', self._PACKAGE])
self.cmd_mock.rc_mock.assertCommandContains(
['cros_workon', 'stop', '--brick=%s' % self.cwd_brick.brick_locator,
self._PACKAGE])
def testHasLatest(self):
"""Tests @has-latest."""
self.RunCommandMock(['--enable', 'latest', '@has-latest'])
self.cmd_mock.rc_mock.assertCommandContains(
['cros_workon', 'start', '--brick=%s' % self.cwd_brick.brick_locator,
'--all'])
def testOnlyLatest(self):
"""Tests @only-latest."""
self.RunCommandMock(['--enable', 'latest', '@only-latest'])
self.cmd_mock.rc_mock.assertCommandContains(
['cros_workon', 'start', '--brick=%s' % self.cwd_brick.brick_locator,
'--workon_only'])
def testCreateSource(self):
"""Tests --create-source."""
self.RunCommandMock(['--create-source', '.', self._PACKAGE])
# Consider it successful if the ebuild file was created and our package
# category was written to the categories file.
self.assertExists(self.cwd_brick_ebuild_file)
self.assertEqual('%s\n' % self._PACKAGE_CATEGORY,
osutils.ReadFile(self.cwd_brick_categories_file))
def testCreateSourceMissingDirectory(self):
"""Tests --create-source with a missing source directory."""
with self.assertRaises(cros_build_lib.DieSystemExit):
self.RunCommandMock(['--create-source', 'no/source/dir', self._PACKAGE])
def testCreateSourceMissingDirectoryForce(self):
"""Tests --create-source --force with a missing source directory."""
self.RunCommandMock(['--create-source', 'no/source/dir', self._PACKAGE,
'--force'])
def testCreateSourceAddCategory(self):
"""Tests --create-source when the category file already exists."""
existing_category = 'existing_package_category'
self.SetupCommandMock(['--create-source', '.', self._PACKAGE])
osutils.WriteFile(self.cwd_brick_categories_file,
'%s\n' % existing_category, makedirs=True)
self.cmd_mock.inst.Run()
# Our new package category should be appended to the existing file.
self.assertEqual('%s\n%s\n' % (existing_category, self._PACKAGE_CATEGORY),
osutils.ReadFile(self.cwd_brick_categories_file))
def testCreateSourceEbuildExists(self):
"""Tests --create-source exits when the ebuild already exists."""
existing_file_contents = 'existing ebuild file'
self.SetupCommandMock(['--create-source', '.', self._PACKAGE])
osutils.WriteFile(self.cwd_brick_ebuild_file, existing_file_contents,
makedirs=True)
with self.assertRaises(cros_build_lib.DieSystemExit):
self.cmd_mock.inst.Run()
# The existing file should not have been touched.
self.assertEqual(existing_file_contents,
osutils.ReadFile(self.cwd_brick_ebuild_file))