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 <flag 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 <flag 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 <flag 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 <flag name="dist" contexts="ci"/> 71 72 <!-- selected if x context requested --> 73 <flag 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 83 84class ConfigTest(unittest.TestCase): 85 """unittest for Config.""" 86 87 def testConfigFilenameNone(self): 88 cfg = config.factory(None) 89 self.assertIsNone(cfg) 90 91 def testAvailableBuildTargets(self): 92 with tempfile.NamedTemporaryFile('w+t') as test_config: 93 test_config.write(_TEST_CONFIG_XML) 94 test_config.flush() 95 cfg = config.factory(test_config.name) 96 self.assertListEqual( 97 cfg.get_available_build_targets(), 98 # Sorted; not in document order. 99 [ 100 'android_target_1', 101 'android_target_2', 102 'android_target_3', 103 'build_target_2', 104 'no_goals_target', 105 'some_target', 106 ]) 107 108 def testBuildTargetTags(self): 109 with tempfile.NamedTemporaryFile('w+t') as test_config: 110 test_config.write(_TEST_CONFIG_XML) 111 test_config.flush() 112 cfg = config.factory(test_config.name) 113 114 self.assertSetEqual(cfg.get_tags('android_target_1'), set()) 115 self.assertSetEqual( 116 cfg.get_tags('android_target_2'), set(['cool', 'hot', 'warm'])) 117 self.assertSetEqual( 118 cfg.get_tags('build_target_2'), set(['cool', 'hot', 'dry'])) 119 self.assertSetEqual(cfg.get_tags('android_target_3'), set()) 120 121 self.assertFalse(cfg.has_tag('android_target_1', 'cool')) 122 self.assertFalse(cfg.has_tag('android_target_1', 'hot')) 123 self.assertFalse(cfg.has_tag('android_target_1', 'meh')) 124 125 self.assertTrue(cfg.has_tag('android_target_2', 'cool')) 126 self.assertTrue(cfg.has_tag('android_target_2', 'hot')) 127 self.assertFalse(cfg.has_tag('android_target_2', 'meh')) 128 129 self.assertTrue(cfg.has_tag('build_target_2', 'cool')) 130 self.assertTrue(cfg.has_tag('build_target_2', 'hot')) 131 self.assertFalse(cfg.has_tag('build_target_2', 'meh')) 132 133 self.assertFalse(cfg.has_tag('android_target_3', 'cool')) 134 self.assertFalse(cfg.has_tag('android_target_3', 'hot')) 135 self.assertFalse(cfg.has_tag('android_target_3', 'meh')) 136 137 def testBuildTargetToAndroidTarget(self): 138 with tempfile.NamedTemporaryFile('w+t') as test_config: 139 test_config.write(_TEST_CONFIG_XML) 140 test_config.flush() 141 cfg = config.factory(test_config.name) 142 143 # Test that build_target android_target_1 -> android_target_1. 144 self.assertEqual( 145 cfg.get_build_config_android_target('android_target_1'), 146 'android_target_1') 147 148 # Test that build_target android_target_2 -> android_target_2. 149 self.assertEqual( 150 cfg.get_build_config_android_target('android_target_2'), 151 'android_target_2') 152 153 # Test that build_target build_target_2 -> android_target_2. 154 self.assertEqual( 155 cfg.get_build_config_android_target('build_target_2'), 156 'android_target_2') 157 158 # Test overriding android_target property 159 self.assertEqual( 160 cfg.get_build_config_android_target('some_target'), 161 'android_target_4') 162 163 def testBuildTargetToBuildGoalsAndFlags(self): 164 with tempfile.NamedTemporaryFile('w+t') as test_config: 165 test_config.write(_TEST_CONFIG_XML) 166 test_config.flush() 167 cfg = config.factory(test_config.name) 168 169 self.assertEqual(cfg.get_build_goals('android_target_1'), ['droid']) 170 self.assertEqual(cfg.get_build_flags('android_target_1'), ['dist']) 171 172 self.assertEqual( 173 cfg.get_build_goals('android_target_2'), 174 ['common_goal', 'droid', 'goal_for_android_target_2']) 175 self.assertEqual(cfg.get_build_flags('android_target_2'), ['dist']) 176 177 self.assertEqual( 178 cfg.get_build_goals('build_target_2'), ['common_goal', 'droid']) 179 self.assertEqual(cfg.get_build_flags('build_target_2'), ['VAR=a']) 180 181 # Test empty goals 182 self.assertEqual(cfg.get_build_goals('no_goals_target'), []) 183 184 def testBuildTargetToBuildGoalsAndFlagsWithContexts(self): 185 with tempfile.NamedTemporaryFile('w+t') as test_config: 186 test_config.write(_TEST_CONTEXTS_CONFIG_XML) 187 test_config.flush() 188 cfg = config.factory(test_config.name) 189 190 # Test that when contexts is the default (empty), we select only the 191 # "always" goals. 192 193 build_goals = cfg.get_build_goals('test_target') 194 self.assertEqual(build_goals, ['droid', 'always']) 195 196 # Test that when contexts is explicitly empty, we select only the 197 # "always" goals. 198 199 build_goals = cfg.get_build_goals('test_target', set()) 200 self.assertEqual(build_goals, ['droid', 'always']) 201 202 # Similarly, test that when contexts is doesn't match any goal_contexts, 203 # we select only the "always" goals. 204 205 build_goals = cfg.get_build_goals('test_target', set('no_matchy')) 206 self.assertEqual(build_goals, ['droid', 'always']) 207 208 # Test that when contexts is set(['x']), we select the "always" goals and 209 # the x goals. 210 211 build_goals = cfg.get_build_goals('test_target', set(['x'])) 212 build_flags = cfg.get_build_flags('test_target', set(['x'])) 213 214 self.assertEqual(build_goals, ['droid', 'always', 'extra_goal']) 215 self.assertEqual(build_flags, ['VAR=value']) 216 217 # Test that when requested_contexts is set(['ci', 'x']), we select the 218 # "always" goals, the ci goals, and the x goals. 219 220 build_goals = cfg.get_build_goals('test_target', set(['ci', 'x'])) 221 build_flags = cfg.get_build_flags('test_target', set(['ci', 'x'])) 222 223 self.assertEqual(build_goals, ['droid', 'always', 'extra_goal']) 224 self.assertEqual(build_flags, ['dist', 'VAR=value']) 225 226 def testAllowReadWriteAll(self): 227 with tempfile.NamedTemporaryFile('w+t') as test_config: 228 test_config.write("""<?xml version="1.0" encoding="UTF-8" ?> 229 <config> 230 <target name="target_allowed" allow_readwrite_all="true"> 231 <build_config> 232 <goal name="droid"/> 233 </build_config> 234 <allow_readwrite_all/> 235 </target> 236 <target name="target_not_allowed"> 237 <build_config> 238 <goal name="droid"/> 239 </build_config> 240 </target> 241 <target name="target_also_not_allowed" allow_readwrite_all="false"> 242 <build_config> 243 <goal name="droid"/> 244 </build_config> 245 </target> 246 </config>""") 247 test_config.flush() 248 cfg = config.factory(test_config.name) 249 250 self.assertTrue(cfg.get_allow_readwrite_all('target_allowed')) 251 252 self.assertFalse(cfg.get_allow_readwrite_all('target_not_allowed')) 253 254 self.assertFalse(cfg.get_allow_readwrite_all('target_also_not_allowed')) 255 256 def testAllowedProjectsFile(self): 257 with tempfile.NamedTemporaryFile('w+t') as test_config: 258 test_config.write( 259 '<?xml version="1.0" encoding="UTF-8" ?>' 260 '<config>' 261 ' <target name="target_name">' 262 ' <build_config allowed_projects_file="path/to/default/build/config/allowed_projects.xml">' 263 ' <goal name="build_goal"/>' 264 ' </build_config>' 265 ' <build_config name="has_allowed_projects_file" allowed_projects_file="path/to/named/build/config/allowed_projects.xml">' 266 ' <goal name="build_goal"/>' 267 ' </build_config>' 268 ' <build_config name="no_allowed_projects_file">' 269 ' <goal name="build_goal"/>' 270 ' </build_config>' 271 ' </target>' 272 '</config>') 273 test_config.flush() 274 cfg = config.factory(test_config.name) 275 276 self.assertEqual( 277 cfg.get_allowed_projects_file('target_name'), 278 'path/to/default/build/config/allowed_projects.xml') 279 self.assertEqual( 280 cfg.get_allowed_projects_file('has_allowed_projects_file'), 281 'path/to/named/build/config/allowed_projects.xml') 282 self.assertIsNone( 283 cfg.get_allowed_projects_file('no_allowed_projects_file')) 284 285 def testMergeConfig(self): 286 with tempfile.NamedTemporaryFile('w+t') as test_config: 287 test_config.write(_TEST_CONFIG_XML) 288 test_config.flush() 289 cfg = config.factory(test_config.name) 290 291 bc_at2 = cfg.get_build_config('android_target_2') 292 self.assertDictEqual( 293 bc_at2.configurations, { 294 'fmc_framework_images': 'image1,image2', 295 'fmc_misc_info_keys': 'misc_info_keys.txt' 296 }) 297 298 bc_bt2 = cfg.get_build_config('build_target_2') 299 self.assertDictEqual( 300 bc_bt2.configurations, { 301 'fmc_framework_images': 'bt1,bt2', 302 'fmc_misc_info_keys': 'misc_info_keys_2.txt' 303 }) 304 305 306if __name__ == '__main__': 307 unittest.main() 308