1# Copyright 2020 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Test config.""" 15 16import tempfile 17import unittest 18from . import config 19 20_TEST_CONFIG_XML = """<config> 21 <target name="android_target_1"> 22 <build_config> 23 <goal name="droid"/> 24 <goal name="dist"/> 25 </build_config> 26 </target> 27 <target name="android_target_2" tags="cool,hot"> 28 <config name="fmc_framework_images" value="image1,image2"/> 29 <config name="fmc_misc_info_keys" value="misc_info_keys.txt"/> 30 <goal name="common_goal"/> 31 <build_config tags="warm"> 32 <goal name="droid"/> 33 <goal name="dist"/> 34 <goal name="goal_for_android_target_2"/> 35 </build_config> 36 <build_config name="build_target_2" tags="dry"> 37 <config name="fmc_framework_images" value="bt1,bt2"/> 38 <config name="fmc_misc_info_keys" value="misc_info_keys_2.txt"/> 39 <goal name="droid"/> 40 <goal name="VAR=a"/> 41 </build_config> 42 </target> 43 <target name="android_target_3" tags=""> 44 <build_config> 45 <goal name="droid"/> 46 </build_config> 47 </target> 48 <target name="some_target" android_target="android_target_4"> 49 <goal name="droid"/> 50 <build_config> 51 </build_config> 52 </target> 53 <target name="no_goals_target"> 54 <build_config/> 55 </target> 56</config> 57""" 58 59_TEST_CONTEXTS_CONFIG_XML = """<config> 60 <target name="test_target"> 61 <build_config> 62 63 <!-- no contexts attribute: always selected --> 64 <goal name="droid"/> 65 66 <!-- empty contexts attribute: always selected --> 67 <goal name="always" contexts=""/> 68 69 <!-- selected if ci context requested --> 70 <goal name="dist" contexts="ci"/> 71 72 <!-- selected if x context requested --> 73 <goal name="VAR=value" contexts="x"/> 74 75 <!-- selected if ci or x context requested --> 76 <goal name="extra_goal" contexts="ci,x"/> 77 78 </build_config> 79 </target> 80</config> 81""" 82 83class ConfigTest(unittest.TestCase): 84 """unittest for Config.""" 85 86 def testConfigFilenameNone(self): 87 cfg = config.factory(None) 88 self.assertIsNone(cfg) 89 90 def testAvailableBuildTargets(self): 91 with tempfile.NamedTemporaryFile('w+t') as test_config: 92 test_config.write(_TEST_CONFIG_XML) 93 test_config.flush() 94 cfg = config.factory(test_config.name) 95 self.assertListEqual( 96 cfg.get_available_build_targets(), 97 # Sorted; not in document order. 98 [ 99 'android_target_1', 100 'android_target_2', 101 'android_target_3', 102 'build_target_2', 103 'no_goals_target', 104 'some_target', 105 ]) 106 107 def testBuildTargetTags(self): 108 with tempfile.NamedTemporaryFile('w+t') as test_config: 109 test_config.write(_TEST_CONFIG_XML) 110 test_config.flush() 111 cfg = config.factory(test_config.name) 112 113 self.assertSetEqual(cfg.get_tags('android_target_1'), set()) 114 self.assertSetEqual( 115 cfg.get_tags('android_target_2'), set(['cool', 'hot', 'warm'])) 116 self.assertSetEqual( 117 cfg.get_tags('build_target_2'), set(['cool', 'hot', 'dry'])) 118 self.assertSetEqual(cfg.get_tags('android_target_3'), set()) 119 120 self.assertFalse(cfg.has_tag('android_target_1', 'cool')) 121 self.assertFalse(cfg.has_tag('android_target_1', 'hot')) 122 self.assertFalse(cfg.has_tag('android_target_1', 'meh')) 123 124 self.assertTrue(cfg.has_tag('android_target_2', 'cool')) 125 self.assertTrue(cfg.has_tag('android_target_2', 'hot')) 126 self.assertFalse(cfg.has_tag('android_target_2', 'meh')) 127 128 self.assertTrue(cfg.has_tag('build_target_2', 'cool')) 129 self.assertTrue(cfg.has_tag('build_target_2', 'hot')) 130 self.assertFalse(cfg.has_tag('build_target_2', 'meh')) 131 132 self.assertFalse(cfg.has_tag('android_target_3', 'cool')) 133 self.assertFalse(cfg.has_tag('android_target_3', 'hot')) 134 self.assertFalse(cfg.has_tag('android_target_3', 'meh')) 135 136 def testBuildTargetToAndroidTarget(self): 137 with tempfile.NamedTemporaryFile('w+t') as test_config: 138 test_config.write(_TEST_CONFIG_XML) 139 test_config.flush() 140 cfg = config.factory(test_config.name) 141 142 # Test that build_target android_target_1 -> android_target_1. 143 self.assertEqual( 144 cfg.get_build_config_android_target('android_target_1'), 145 'android_target_1') 146 147 # Test that build_target android_target_2 -> android_target_2. 148 self.assertEqual( 149 cfg.get_build_config_android_target('android_target_2'), 150 'android_target_2') 151 152 # Test that build_target build_target_2 -> android_target_2. 153 self.assertEqual( 154 cfg.get_build_config_android_target('build_target_2'), 155 'android_target_2') 156 157 # Test overriding android_target property 158 self.assertEqual( 159 cfg.get_build_config_android_target('some_target'), 160 'android_target_4') 161 162 def testBuildTargetToBuildGoals(self): 163 with tempfile.NamedTemporaryFile('w+t') as test_config: 164 test_config.write(_TEST_CONFIG_XML) 165 test_config.flush() 166 cfg = config.factory(test_config.name) 167 168 # Test that build_target android_target_1 has goals droid and dist. 169 self.assertEqual( 170 cfg.get_build_goals('android_target_1'), 171 ['droid', 'dist']) 172 173 # Test that build_target android_target_2 has goals droid, dist, and 174 # goal_for_android_target_2. 175 self.assertEqual( 176 cfg.get_build_goals('android_target_2'), 177 ['common_goal', 'droid', 'dist', 'goal_for_android_target_2']) 178 179 # Test that build_target build_target_2 has goals droid and VAR=a. 180 self.assertEqual( 181 cfg.get_build_goals('build_target_2'), 182 ['common_goal', 'droid', 'VAR=a']) 183 184 # Test empty goals 185 self.assertEqual(cfg.get_build_goals('no_goals_target'),[]) 186 187 def testBuildTargetToBuildGoalsWithContexts(self): 188 with tempfile.NamedTemporaryFile('w+t') as test_config: 189 test_config.write(_TEST_CONTEXTS_CONFIG_XML) 190 test_config.flush() 191 cfg = config.factory(test_config.name) 192 193 # Test that when contexts is the default (empty), we select only the 194 # "always" goals. 195 196 build_goals = cfg.get_build_goals('test_target') 197 self.assertEqual(build_goals, ['droid', 'always']) 198 199 # Test that when contexts is explicitly empty, we select only the 200 # "always" goals. 201 202 build_goals = cfg.get_build_goals('test_target', set()) 203 self.assertEqual(build_goals, ['droid', 'always']) 204 205 # Similarly, test that when contexts is doesn't match any goal_contexts, 206 # we select only the "always" goals. 207 208 build_goals = cfg.get_build_goals('test_target', set('no_matchy')) 209 self.assertEqual(build_goals, ['droid', 'always']) 210 211 # Test that when contexts is set(['x']), we select the "always" goals and 212 # the x goals. 213 214 build_goals = cfg.get_build_goals('test_target', set(['x'])) 215 216 self.assertEqual( 217 build_goals, 218 ['droid', 'always', 'VAR=value', 'extra_goal']) 219 220 # Test that when requested_contexts is set(['ci', 'x']), we select the 221 # "always" goals, the ci goals, and the x goals. 222 223 build_goals = cfg.get_build_goals('test_target', set(['ci', 'x'])) 224 225 self.assertEqual( 226 build_goals, 227 ['droid', 'always', 'dist', 'VAR=value', 'extra_goal']) 228 229 def testAllowReadWriteAll(self): 230 with tempfile.NamedTemporaryFile('w+t') as test_config: 231 test_config.write("""<?xml version="1.0" encoding="UTF-8" ?> 232 <config> 233 <target name="target_allowed" allow_readwrite_all="true"> 234 <build_config> 235 <goal name="droid"/> 236 </build_config> 237 <allow_readwrite_all/> 238 </target> 239 <target name="target_not_allowed"> 240 <build_config> 241 <goal name="droid"/> 242 </build_config> 243 </target> 244 <target name="target_also_not_allowed" allow_readwrite_all="false"> 245 <build_config> 246 <goal name="droid"/> 247 </build_config> 248 </target> 249 </config>""") 250 test_config.flush() 251 cfg = config.factory(test_config.name) 252 253 self.assertTrue(cfg.get_allow_readwrite_all('target_allowed')) 254 255 self.assertFalse(cfg.get_allow_readwrite_all('target_not_allowed')) 256 257 self.assertFalse(cfg.get_allow_readwrite_all('target_also_not_allowed')) 258 259 def testAllowedProjectsFile(self): 260 with tempfile.NamedTemporaryFile('w+t') as test_config: 261 test_config.write( 262 '<?xml version="1.0" encoding="UTF-8" ?>' 263 '<config>' 264 ' <target name="target_name">' 265 ' <build_config allowed_projects_file="path/to/default/build/config/allowed_projects.xml">' 266 ' <goal name="build_goal"/>' 267 ' </build_config>' 268 ' <build_config name="has_allowed_projects_file" allowed_projects_file="path/to/named/build/config/allowed_projects.xml">' 269 ' <goal name="build_goal"/>' 270 ' </build_config>' 271 ' <build_config name="no_allowed_projects_file">' 272 ' <goal name="build_goal"/>' 273 ' </build_config>' 274 ' </target>' 275 '</config>') 276 test_config.flush() 277 cfg = config.factory(test_config.name) 278 279 self.assertEqual( 280 cfg.get_allowed_projects_file('target_name'), 281 'path/to/default/build/config/allowed_projects.xml') 282 self.assertEqual( 283 cfg.get_allowed_projects_file('has_allowed_projects_file'), 284 'path/to/named/build/config/allowed_projects.xml') 285 self.assertIsNone( 286 cfg.get_allowed_projects_file('no_allowed_projects_file')) 287 288 def testMergeConfig(self): 289 with tempfile.NamedTemporaryFile('w+t') as test_config: 290 test_config.write(_TEST_CONFIG_XML) 291 test_config.flush() 292 cfg = config.factory(test_config.name) 293 294 bc_at2 = cfg.get_build_config('android_target_2') 295 self.assertDictEqual(bc_at2.configurations, { 296 'fmc_framework_images': 'image1,image2', 297 'fmc_misc_info_keys': 'misc_info_keys.txt' 298 }) 299 300 bc_bt2 = cfg.get_build_config('build_target_2') 301 self.assertDictEqual(bc_bt2.configurations, { 302 'fmc_framework_images': 'bt1,bt2', 303 'fmc_misc_info_keys': 'misc_info_keys_2.txt' 304 }) 305 306if __name__ == '__main__': 307 unittest.main() 308