| # Copyright 2018 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Test cros_choose_profile.""" |
| |
| import os |
| |
| from chromite.lib import commandline |
| from chromite.lib import cros_test_lib |
| from chromite.lib import osutils |
| from chromite.lib import unittest_lib |
| from chromite.scripts import cros_choose_profile |
| |
| |
| class ParseArgsTest(cros_test_lib.TestCase): |
| """Tests for argument parsing and validation rules.""" |
| |
| def testInvalidArgs(self) -> None: |
| """Test invalid argument parsing.""" |
| with self.assertRaises(SystemExit): |
| cros_choose_profile.ParseArgs([]) |
| |
| with self.assertRaises(SystemExit): |
| cros_choose_profile.ParseArgs( |
| ["--profile", "profile", "--variant", "variant"] |
| ) |
| |
| |
| class BoardTest(cros_test_lib.TestCase): |
| """Tests for the Board class logic.""" |
| |
| def setUp(self) -> None: |
| """Set up the boards with the different construction variations.""" |
| # For readability's sake. |
| Board = cros_choose_profile.Board |
| self.board_variant1 = Board(board="board_variant") |
| self.board_variant2 = Board(board="board", variant="variant") |
| self.board_variant3 = Board(board_root="/build/board_variant") |
| self.board_variant4 = Board( |
| board="board_variant", board_root="/build/ignored_value" |
| ) |
| |
| def testBoardVariant(self) -> None: |
| """Board.{board, variant, board_variant} building tests.""" |
| self.assertEqual("board", self.board_variant1.board) |
| self.assertEqual("variant", self.board_variant1.variant) |
| self.assertEqual("board_variant", self.board_variant1.board_variant) |
| |
| self.assertEqual("board", self.board_variant2.board) |
| self.assertEqual("variant", self.board_variant2.variant) |
| self.assertEqual("board_variant", self.board_variant2.board_variant) |
| |
| self.assertEqual("board", self.board_variant3.board) |
| self.assertEqual("variant", self.board_variant3.variant) |
| self.assertEqual("board_variant", self.board_variant3.board_variant) |
| |
| self.assertEqual("board", self.board_variant4.board) |
| self.assertEqual("variant", self.board_variant4.variant) |
| self.assertEqual("board_variant", self.board_variant4.board_variant) |
| |
| def testRoot(self) -> None: |
| """Board.root tests.""" |
| self.assertEqual(self.board_variant1.root, self.board_variant2.root) |
| self.assertEqual(self.board_variant1.root, self.board_variant3.root) |
| self.assertEqual(self.board_variant1.root, self.board_variant4.root) |
| |
| |
| class ProfileTest(cros_test_lib.TempDirTestCase): |
| """Tests for the Profile class and functions, and ChooseProfile.""" |
| |
| def setUp(self) -> None: |
| """Setup filesystem for the profile tests.""" |
| # Make sure everything will use the filesystem we're setting up. |
| cros_choose_profile.PathPrefixDecorator.prefix = self.tempdir |
| |
| D = cros_test_lib.Directory |
| filesystem = ( |
| D( |
| "board1-overlay", |
| ( |
| D( |
| "profiles", |
| ( |
| D("base", ("parent",)), |
| D("profile1", ("parent",)), |
| D("profile2", ("parent",)), |
| ), |
| ), |
| ), |
| ), |
| D( |
| "build", |
| ( |
| D( |
| "board1", |
| ( |
| D( |
| "etc", |
| ( |
| D( |
| "portage", () |
| ), # make.profile parent directory. |
| "make.conf.board_setup", |
| ), |
| ), |
| D("var", (D("cache", (D("edb", ("chromeos",)),)),)), |
| ), |
| ), |
| ), |
| ), |
| ) |
| |
| cros_test_lib.CreateOnDiskHierarchy(self.tempdir, filesystem) |
| |
| # Generate the required filesystem content. |
| # Build out the file names that need content. |
| b1_build_root = "/build/board1" |
| b1_board_setup = os.path.join( |
| b1_build_root, "etc/make.conf.board_setup" |
| ) |
| self.b1_sysroot = os.path.join(b1_build_root, "var/cache/edb/chromeos") |
| b1_profiles = "/board1-overlay/profiles" |
| |
| base_directory = os.path.join(b1_profiles, "base") |
| base_parent = os.path.join(base_directory, "parent") |
| p1_directory = os.path.join(b1_profiles, "profile1") |
| p1_parent = os.path.join(p1_directory, "parent") |
| p2_directory = os.path.join(b1_profiles, "profile2") |
| p2_parent = os.path.join(p2_directory, "parent") |
| |
| # Contents to write to the corresponding file. |
| |
| # self.profile_override is assumed to be a profile name in |
| # testGetProfile. Update code there if this changes. |
| self.profile_override = "profile1" |
| path_contents = { |
| b1_board_setup: 'ARCH="arch"\nBOARD_OVERLAY="/board1-overlay"', |
| self.b1_sysroot: 'PROFILE_OVERRIDE="%s"' % self.profile_override, |
| base_parent: "base parent contents", |
| p1_parent: "profile1 parent contents", |
| p2_parent: "profile2 parent contents", |
| } |
| |
| for filepath, contents in path_contents.items(): |
| osutils.WriteFile(self._TempdirPath(filepath), contents) |
| |
| # make.conf needs to exist to correctly read back config. |
| unittest_lib.create_stub_make_conf(self._TempdirPath(b1_build_root)) |
| |
| # Mapping between profile argument and the expected parent contents. |
| self.profile_expected_parent = { |
| "base": path_contents[base_parent], |
| "profile1": path_contents[p1_parent], |
| "profile2": path_contents[p2_parent], |
| } |
| |
| # Mapping between the profile argument and the profile's directory. |
| self.profile_directory = { |
| "base": base_directory, |
| "profile1": p1_directory, |
| "profile2": p2_directory, |
| } |
| |
| # The make profile directory from which parent files are read. |
| self.board1_make_profile = "/build/board1/etc/portage/make.profile" |
| |
| self.board1 = cros_choose_profile.Board(board_root=b1_build_root) |
| |
| osutils.SafeSymlink( |
| self._TempdirPath(p1_directory), |
| self._TempdirPath(self.board1_make_profile), |
| ) |
| |
| def tearDown(self) -> None: |
| # Reset the prefix. |
| cros_choose_profile.PathPrefixDecorator.prefix = None |
| |
| def _TempdirPath(self, path): |
| """Join the tempdir base path to the given path.""" |
| # lstrip leading / to prevent it returning the path without the tempdir. |
| return os.path.join(self.tempdir, path.lstrip(os.sep)) |
| |
| def testChooseProfile(self) -> None: |
| """ChooseProfile tests: verify profiles are properly chosen.""" |
| b1_parent_path = self._TempdirPath( |
| os.path.join(self.board1_make_profile, "parent") |
| ) |
| # Verify initial state - profile1. |
| self.assertEqual( |
| self.profile_expected_parent["profile1"], |
| osutils.ReadFile(b1_parent_path), |
| ) |
| |
| for profile_name, parent in self.profile_expected_parent.items(): |
| # Call ChooseProfile for the given profile and check contents as |
| # specified by self.profile_expected_parent (built in setUp). |
| |
| profile_dir = self.profile_directory[profile_name] |
| profile = cros_choose_profile.Profile( |
| profile_name, profile_dir, profile_name |
| ) |
| |
| # Test the profile changing. |
| cros_choose_profile.ChooseProfile(self.board1, profile) |
| self.assertEqual(parent, osutils.ReadFile(b1_parent_path)) |
| |
| # Test the profile staying the same. |
| cros_choose_profile.ChooseProfile(self.board1, profile) |
| self.assertEqual(parent, osutils.ReadFile(b1_parent_path)) |
| |
| def testGetProfile(self) -> None: |
| """Test each profile parameter type behaves as expected when fetched.""" |
| # pylint: disable=protected-access |
| # Test an invalid profile name. |
| args = commandline.ArgumentNamespace(profile="doesnotexist") |
| self.assertRaises( |
| cros_choose_profile.ProfileDirectoryNotFoundError, |
| cros_choose_profile._GetProfile, |
| args, |
| self.board1, |
| ) |
| |
| # Profile values for following tests. |
| profile_name = self.profile_override |
| profile_path = self._TempdirPath(self.profile_directory[profile_name]) |
| |
| # Test using the profile name. |
| args = commandline.ArgumentNamespace(profile=profile_name) |
| profile = cros_choose_profile._GetProfile(args, self.board1) |
| self.assertEqual(profile_name, profile.name) |
| self.assertEqual(profile_path, profile.directory) |
| self.assertEqual(profile_name, profile.override) |
| |
| # Test using the profile path. |
| args = commandline.ArgumentNamespace(profile=profile_path) |
| profile = cros_choose_profile._GetProfile(args, self.board1) |
| self.assertEqual(profile_name, profile.name) |
| self.assertEqual(profile_path, profile.directory) |
| self.assertEqual(profile_path, profile.override) |
| |
| # Test using PROFILE_OVERRIDE. |
| args = commandline.ArgumentNamespace(profile=None) |
| profile = cros_choose_profile._GetProfile(args, self.board1) |
| self.assertEqual(profile_name, profile.name) |
| self.assertEqual(profile_path, profile.directory) |
| self.assertEqual(self.profile_override, profile.override) |
| |
| # No override value, using default 'base'. |
| osutils.WriteFile(self._TempdirPath(self.b1_sysroot), "") |
| args = commandline.ArgumentNamespace(profile=None) |
| profile = cros_choose_profile._GetProfile(opts=args, board=self.board1) |
| self.assertEqual("base", profile.name) |
| self.assertEqual( |
| self._TempdirPath(self.profile_directory["base"]), profile.directory |
| ) |
| self.assertIsNone(profile.override) |