Alex Klein | a2ceb19 | 2018-08-17 11:19:32 -0600 | [diff] [blame] | 1 | # Copyright 2018 The Chromium OS Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """Test cros_choose_profile.""" |
| 6 | |
Alex Klein | a2ceb19 | 2018-08-17 11:19:32 -0600 | [diff] [blame] | 7 | import os |
| 8 | |
| 9 | from chromite.lib import commandline |
| 10 | from chromite.lib import cros_test_lib |
| 11 | from chromite.lib import osutils |
Sloan Johnson | a85640f | 2021-10-01 22:32:40 +0000 | [diff] [blame^] | 12 | from chromite.lib import unittest_lib |
Alex Klein | a2ceb19 | 2018-08-17 11:19:32 -0600 | [diff] [blame] | 13 | from chromite.scripts import cros_choose_profile |
| 14 | |
| 15 | |
| 16 | class ParseArgsTest(cros_test_lib.TestCase): |
| 17 | """Tests for argument parsing and validation rules.""" |
| 18 | |
| 19 | def testInvalidArgs(self): |
| 20 | """Test invalid argument parsing.""" |
| 21 | with self.assertRaises(SystemExit): |
| 22 | cros_choose_profile.ParseArgs([]) |
| 23 | |
| 24 | with self.assertRaises(SystemExit): |
| 25 | cros_choose_profile.ParseArgs(['--profile', 'profile', |
| 26 | '--variant', 'variant']) |
| 27 | |
| 28 | |
| 29 | class BoardTest(cros_test_lib.TestCase): |
| 30 | """Tests for the Board class logic.""" |
| 31 | |
| 32 | def setUp(self): |
| 33 | """Set up the boards with the different construction variations.""" |
| 34 | # For readability's sake. |
| 35 | Board = cros_choose_profile.Board |
| 36 | self.board_variant1 = Board(board='board_variant') |
| 37 | self.board_variant2 = Board(board='board', variant='variant') |
| 38 | self.board_variant3 = Board(board_root='/build/board_variant') |
| 39 | self.board_variant4 = Board(board='board_variant', |
| 40 | board_root='/build/ignored_value') |
| 41 | |
| 42 | def testBoardVariant(self): |
| 43 | """Board.{board, variant, board_variant} building tests.""" |
| 44 | self.assertEqual('board', self.board_variant1.board) |
| 45 | self.assertEqual('variant', self.board_variant1.variant) |
| 46 | self.assertEqual('board_variant', self.board_variant1.board_variant) |
| 47 | |
| 48 | self.assertEqual('board', self.board_variant2.board) |
| 49 | self.assertEqual('variant', self.board_variant2.variant) |
| 50 | self.assertEqual('board_variant', self.board_variant2.board_variant) |
| 51 | |
| 52 | self.assertEqual('board', self.board_variant3.board) |
| 53 | self.assertEqual('variant', self.board_variant3.variant) |
| 54 | self.assertEqual('board_variant', self.board_variant3.board_variant) |
| 55 | |
| 56 | self.assertEqual('board', self.board_variant4.board) |
| 57 | self.assertEqual('variant', self.board_variant4.variant) |
| 58 | self.assertEqual('board_variant', self.board_variant4.board_variant) |
| 59 | |
| 60 | def testRoot(self): |
| 61 | """Board.root tests.""" |
| 62 | self.assertEqual(self.board_variant1.root, self.board_variant2.root) |
| 63 | self.assertEqual(self.board_variant1.root, self.board_variant3.root) |
| 64 | self.assertEqual(self.board_variant1.root, self.board_variant4.root) |
| 65 | |
| 66 | |
| 67 | class ProfileTest(cros_test_lib.TempDirTestCase): |
| 68 | """Tests for the Profile class and functions, and ChooseProfile.""" |
| 69 | |
| 70 | def setUp(self): |
| 71 | """Setup filesystem for the profile tests.""" |
| 72 | # Make sure everything will use the filesystem we're setting up. |
| 73 | cros_choose_profile.PathPrefixDecorator.prefix = self.tempdir |
| 74 | |
| 75 | D = cros_test_lib.Directory |
| 76 | filesystem = ( |
| 77 | D('board1-overlay', ( |
| 78 | D('profiles', ( |
| 79 | D('base', ('parent', )), |
| 80 | D('profile1', ('parent',)), |
| 81 | D('profile2', ('parent',)), |
| 82 | )), |
| 83 | )), |
| 84 | D('build', ( |
| 85 | D('board1', ( |
| 86 | D('etc', ( |
| 87 | D('portage', ()), # make.profile parent directory. |
| 88 | 'make.conf.board_setup', |
| 89 | )), |
| 90 | D('var', ( |
| 91 | D('cache', ( |
| 92 | D('edb', ('chromeos',)), |
| 93 | )), |
| 94 | )), |
| 95 | )), |
| 96 | )), |
| 97 | ) |
| 98 | |
| 99 | cros_test_lib.CreateOnDiskHierarchy(self.tempdir, filesystem) |
| 100 | |
| 101 | # Generate the required filesystem content. |
| 102 | # Build out the file names that need content. |
| 103 | b1_build_root = '/build/board1' |
| 104 | b1_board_setup = os.path.join(b1_build_root, 'etc/make.conf.board_setup') |
| 105 | self.b1_sysroot = os.path.join(b1_build_root, 'var/cache/edb/chromeos') |
| 106 | b1_profiles = '/board1-overlay/profiles' |
| 107 | |
| 108 | base_directory = os.path.join(b1_profiles, 'base') |
| 109 | base_parent = os.path.join(base_directory, 'parent') |
| 110 | p1_directory = os.path.join(b1_profiles, 'profile1') |
| 111 | p1_parent = os.path.join(p1_directory, 'parent') |
| 112 | p2_directory = os.path.join(b1_profiles, 'profile2') |
| 113 | p2_parent = os.path.join(p2_directory, 'parent') |
| 114 | |
| 115 | # Contents to write to the corresponding file. |
| 116 | |
| 117 | # self.profile_override is assumed to be a profile name in testGetProfile. |
| 118 | # Update code there if this changes. |
| 119 | self.profile_override = 'profile1' |
| 120 | path_contents = { |
| 121 | b1_board_setup: 'ARCH="arch"\nBOARD_OVERLAY="/board1-overlay"', |
| 122 | self.b1_sysroot: 'PROFILE_OVERRIDE="%s"' % self.profile_override, |
| 123 | base_parent: 'base parent contents', |
| 124 | p1_parent: 'profile1 parent contents', |
| 125 | p2_parent: 'profile2 parent contents', |
| 126 | } |
| 127 | |
Mike Frysinger | 0bdbc10 | 2019-06-13 15:27:29 -0400 | [diff] [blame] | 128 | for filepath, contents in path_contents.items(): |
Alex Klein | a2ceb19 | 2018-08-17 11:19:32 -0600 | [diff] [blame] | 129 | osutils.WriteFile(self._TempdirPath(filepath), contents) |
| 130 | |
Sloan Johnson | a85640f | 2021-10-01 22:32:40 +0000 | [diff] [blame^] | 131 | # make.conf needs to exist to correctly read back config. |
| 132 | unittest_lib.create_stub_make_conf(self._TempdirPath(b1_build_root)) |
| 133 | |
Alex Klein | a2ceb19 | 2018-08-17 11:19:32 -0600 | [diff] [blame] | 134 | # Mapping between profile argument and the expected parent contents. |
| 135 | self.profile_expected_parent = { |
| 136 | 'base': path_contents[base_parent], |
| 137 | 'profile1': path_contents[p1_parent], |
| 138 | 'profile2': path_contents[p2_parent], |
| 139 | } |
| 140 | |
| 141 | # Mapping between the profile argument and the profile's directory. |
| 142 | self.profile_directory = { |
| 143 | 'base': base_directory, |
| 144 | 'profile1': p1_directory, |
| 145 | 'profile2': p2_directory, |
| 146 | } |
| 147 | |
| 148 | # The make profile directory from which parent files are read. |
| 149 | self.board1_make_profile = '/build/board1/etc/portage/make.profile' |
| 150 | |
| 151 | self.board1 = cros_choose_profile.Board(board_root=b1_build_root) |
| 152 | |
| 153 | osutils.SafeSymlink(self._TempdirPath(p1_directory), |
| 154 | self._TempdirPath(self.board1_make_profile)) |
| 155 | |
| 156 | def tearDown(self): |
| 157 | # Reset the prefix. |
| 158 | cros_choose_profile.PathPrefixDecorator.prefix = None |
| 159 | |
| 160 | def _TempdirPath(self, path): |
| 161 | """Join the tempdir base path to the given path.""" |
| 162 | # lstrip leading / to prevent it returning the path without the tempdir. |
| 163 | return os.path.join(self.tempdir, path.lstrip(os.sep)) |
| 164 | |
| 165 | def testChooseProfile(self): |
| 166 | """ChooseProfile tests: verify profiles are properly chosen.""" |
| 167 | b1_parent_path = self._TempdirPath(os.path.join(self.board1_make_profile, |
| 168 | 'parent')) |
| 169 | # Verify initial state - profile1. |
| 170 | self.assertEqual(self.profile_expected_parent['profile1'], |
| 171 | osutils.ReadFile(b1_parent_path)) |
| 172 | |
Mike Frysinger | 0bdbc10 | 2019-06-13 15:27:29 -0400 | [diff] [blame] | 173 | for profile_name, parent in self.profile_expected_parent.items(): |
Alex Klein | a2ceb19 | 2018-08-17 11:19:32 -0600 | [diff] [blame] | 174 | # Call ChooseProfile for the given profile and check contents as specified |
| 175 | # by self.profile_expected_parent (built in setUp). |
| 176 | |
| 177 | profile_dir = self.profile_directory[profile_name] |
| 178 | profile = cros_choose_profile.Profile(profile_name, profile_dir, |
| 179 | profile_name) |
| 180 | |
| 181 | # Test the profile changing. |
| 182 | cros_choose_profile.ChooseProfile(self.board1, profile) |
| 183 | self.assertEqual(parent, osutils.ReadFile(b1_parent_path)) |
| 184 | |
| 185 | # Test the profile staying the same. |
| 186 | cros_choose_profile.ChooseProfile(self.board1, profile) |
| 187 | self.assertEqual(parent, osutils.ReadFile(b1_parent_path)) |
| 188 | |
Alex Klein | a2ceb19 | 2018-08-17 11:19:32 -0600 | [diff] [blame] | 189 | def testGetProfile(self): |
| 190 | """Test each profile parameter type behaves as expected when fetched.""" |
| 191 | # pylint: disable=protected-access |
| 192 | # Test an invalid profile name. |
| 193 | args = commandline.ArgumentNamespace(profile='doesnotexist') |
| 194 | self.assertRaises(cros_choose_profile.ProfileDirectoryNotFoundError, |
| 195 | cros_choose_profile._GetProfile, args, self.board1) |
| 196 | |
| 197 | # Profile values for following tests. |
| 198 | profile_name = self.profile_override |
| 199 | profile_path = self._TempdirPath(self.profile_directory[profile_name]) |
| 200 | |
| 201 | # Test using the profile name. |
| 202 | args = commandline.ArgumentNamespace(profile=profile_name) |
| 203 | profile = cros_choose_profile._GetProfile(args, self.board1) |
| 204 | self.assertEqual(profile_name, profile.name) |
| 205 | self.assertEqual(profile_path, profile.directory) |
| 206 | self.assertEqual(profile_name, profile.override) |
| 207 | |
| 208 | # Test using the profile path. |
| 209 | args = commandline.ArgumentNamespace(profile=profile_path) |
| 210 | profile = cros_choose_profile._GetProfile(args, self.board1) |
| 211 | self.assertEqual(profile_name, profile.name) |
| 212 | self.assertEqual(profile_path, profile.directory) |
| 213 | self.assertEqual(profile_path, profile.override) |
| 214 | |
| 215 | # Test using PROFILE_OVERRIDE. |
| 216 | args = commandline.ArgumentNamespace(profile=None) |
| 217 | profile = cros_choose_profile._GetProfile(args, self.board1) |
| 218 | self.assertEqual(profile_name, profile.name) |
| 219 | self.assertEqual(profile_path, profile.directory) |
| 220 | self.assertEqual(self.profile_override, profile.override) |
| 221 | |
| 222 | # No override value, using default 'base'. |
| 223 | osutils.WriteFile(self._TempdirPath(self.b1_sysroot), '') |
| 224 | args = commandline.ArgumentNamespace(profile=None) |
| 225 | profile = cros_choose_profile._GetProfile(opts=args, board=self.board1) |
| 226 | self.assertEqual('base', profile.name) |
| 227 | self.assertEqual(self._TempdirPath(self.profile_directory['base']), |
| 228 | profile.directory) |
| 229 | self.assertIsNone(profile.override) |