xref: /aosp_15_r20/external/autotest/client/common_lib/global_config_unittest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1#!/usr/bin/python3
2
3import collections
4import six
5import unittest
6from unittest.mock import patch
7
8import common
9
10from autotest_lib.client.common_lib import autotemp
11from autotest_lib.client.common_lib import global_config
12from autotest_lib.client.common_lib import lsbrelease_utils
13
14
15global_config_ini_contents = """
16[SECTION_A]
17value_1: 6.0
18value_2: hello
19value_3: true
20value_4: FALSE
21value_5: tRuE
22value_6: falsE
23
24[SECTION_B]
25value_1: -5
26value_2: 2.3
27value_3: 0
28value_4: 7
29
30[SECTION_C]
31value_1: nobody@localhost
32
33[SECTION_D]
34value_1: 1
35
36[SECTION_E]
37value_1: 1
38value_2: 2
39value_a: A
40random: 1
41wireless_ssid_1.2.3.4/24: ssid_1
42wireless_ssid_4.3.2.1/16: ssid_2
43
44[SECTION_F]
45value_7: %sexample
46value_8: %%sexample
47value_9: %%\(example\)
48value_10: %\(branch\)s
49value_11: %%\(branch\)s
50
51"""
52
53
54moblab_config_ini_contents = """
55[SECTION_C]
56value_1: moblab@remotehost
57
58[SECTION_D]
59value_1: 2
60"""
61
62shadow_config_ini_contents = """
63[SECTION_C]
64value_1: somebody@remotehost
65"""
66
67
68def create_config_files():
69    """Create config files to be used for test."""
70    global_temp = autotemp.tempfile("global", ".ini", text=True)
71    with open(global_temp.name, 'w') as gt:
72        gt.write(global_config_ini_contents)
73
74    moblab_temp = autotemp.tempfile("moblab", ".ini", text=True)
75    with open(moblab_temp.name, 'w') as mt:
76        mt.write(moblab_config_ini_contents)
77
78    shadow_temp = autotemp.tempfile("shadow", ".ini", text=True)
79    with open(shadow_temp.name, 'w') as st:
80        st.write(shadow_config_ini_contents)
81
82    return (global_temp, shadow_temp, moblab_temp)
83
84
85class global_config_test(unittest.TestCase):
86    """Test class"""
87    # grab the singelton
88    conf = global_config.global_config
89
90    def setUp(self):
91        """Setup config files for test."""
92        super(global_config_test, self).setUp()
93        # set the config files to our test files
94        (self.global_temp, self.shadow_temp,
95                self.moblab_temp) = create_config_files()
96
97        self.conf.set_config_files(self.global_temp.name, self.shadow_temp.name,
98                                   self.moblab_temp.name)
99
100
101    def tearDown(self):
102        """Cleanup and reset config settings."""
103        self.shadow_temp.clean()
104        self.moblab_temp.clean()
105        self.global_temp.clean()
106        self.conf.set_config_files(global_config.DEFAULT_CONFIG_FILE,
107                                   global_config.DEFAULT_SHADOW_FILE,
108                                   global_config.DEFAULT_MOBLAB_FILE)
109
110
111    def test_float(self):
112        """Test converting float value."""
113        val = self.conf.get_config_value("SECTION_A", "value_1", float)
114        self.assertEquals(type(val), float)
115        self.assertEquals(val, 6.0)
116
117
118    def test_int(self):
119        """Test converting int value."""
120        val = self.conf.get_config_value("SECTION_B", "value_1", int)
121        self.assertEquals(type(val), int)
122        self.assertTrue(val < 0)
123        val = self.conf.get_config_value("SECTION_B", "value_3", int)
124        self.assertEquals(val, 0)
125        val = self.conf.get_config_value("SECTION_B", "value_4", int)
126        self.assertTrue(val > 0)
127
128
129    def test_string(self):
130        """Test converting string value."""
131        val = self.conf.get_config_value("SECTION_A", "value_2")
132        self.assertTrue(isinstance(val, six.string_types))
133        self.assertEquals(val, "hello")
134
135
136    def setIsMoblab(self, value):
137        """Set lsbrelease_utils.is_moblab result.
138
139        @param value: Value to have lsbrelease_utils.is_moblab to return.
140        """
141        patcher = patch.object(lsbrelease_utils, 'is_moblab')
142        is_moblab = patcher.start()
143        self.addCleanup(patcher.stop)
144        is_moblab.return_value = value
145
146    def test_override_non_moblab(self):
147        """Test value overriding works in non-moblab setup."""
148        self.setIsMoblab(False)
149
150        self.conf.reset_config_values()
151
152        # Confirm shadow config overrides global config.
153        val = self.conf.get_config_value("SECTION_C", "value_1")
154        self.assertEquals(val, "somebody@remotehost")
155
156        # Confirm moblab config should be ignored in non-moblab environment..
157        val = self.conf.get_config_value("SECTION_D", "value_1")
158        self.assertEquals(val, "1")
159
160
161    def test_override_moblab(self):
162        """Test value overriding works in moblab setup."""
163        self.setIsMoblab(True)
164
165        self.conf.reset_config_values()
166
167        # Confirm shadow config overrides both moblab and global config.
168        val = self.conf.get_config_value("SECTION_C", "value_1")
169        self.assertEquals(val, "somebody@remotehost")
170
171        # Confirm moblab config should override global config in moblab.
172        val = self.conf.get_config_value("SECTION_D", "value_1")
173        self.assertEquals(val, "2")
174
175
176    def test_exception(self):
177        """Test exception to be raised on invalid config value."""
178        error = 0
179        try:
180            val = self.conf.get_config_value("SECTION_B", "value_2", int)
181        except:
182            error = 1
183        self.assertEquals(error, 1)
184
185
186    def test_boolean(self):
187        """Test converting boolean value."""
188        val = self.conf.get_config_value("SECTION_A", "value_3", bool)
189        self.assertEquals(val, True)
190        val = self.conf.get_config_value("SECTION_A", "value_4", bool)
191        self.assertEquals(val, False)
192        val = self.conf.get_config_value("SECTION_A", "value_5", bool)
193        self.assertEquals(val, True)
194        val = self.conf.get_config_value("SECTION_A", "value_6", bool)
195        self.assertEquals(val, False)
196
197
198    def test_special(self):
199        """Test converting special instances of '%, %%, %s, %%(), %()'."""
200        val7 = self.conf.get_config_value("SECTION_F", "value_7")
201        val8 = self.conf.get_config_value("SECTION_F", "value_8")
202        val9 = self.conf.get_config_value("SECTION_F", "value_9")
203        val10 = self.conf.get_config_value("SECTION_F", "value_10")
204        val11 = self.conf.get_config_value("SECTION_F", "value_11")
205
206        # This is the same parsing done within dev_server and other libs...
207        val10 = (val10.replace('\\', '') % {'branch': 'test_str'})
208        val11 = (val11.replace('\\', '') % {'branch': 'test_str'})
209
210        self.assertEquals(val7, '%sexample')
211        self.assertEquals(val8, '%sexample')
212        self.assertEquals(val9, '%\(example\)')
213        self.assertEquals(val10, 'test_str')
214        self.assertEquals(val11, 'test_str')
215
216    def test_defaults(self):
217        """Test default value works."""
218        val = self.conf.get_config_value("MISSING", "foo", float, 3.6)
219        self.assertEquals(val, 3.6)
220        val = self.conf.get_config_value("SECTION_A", "novalue", str, "default")
221        self.assertEquals(val, "default")
222
223
224    def test_fallback_key(self):
225        """Test fallback value works."""
226        val = self.conf.get_config_value_with_fallback(
227                "SECTION_A", "value_3", "value_4", bool)
228        self.assertEquals(val, True)
229
230        val = self.conf.get_config_value_with_fallback(
231                "SECTION_A", "not_existing", "value_4", bool)
232        self.assertEquals(val, False)
233
234        val = self.conf.get_config_value_with_fallback(
235                "SECTION_A", "not_existing", "value_4",
236                fallback_section='SECTION_B')
237        self.assertEquals(val, '7')
238
239        self.assertRaises(
240                Exception, self.conf.get_config_value_with_fallback,
241                "SECTION_A", "not_existing", "also_not_existing", bool)
242
243
244    def test_get_config_value_regex(self):
245        """Test get_config_value_regex works."""
246        configs = self.conf.get_config_value_regex('SECTION_E', 'value_\d+',
247                                                   int)
248        self.assertEquals(configs, {'value_1': 1, 'value_2': 2})
249        configs = self.conf.get_config_value_regex('SECTION_E', 'value_.*')
250        self.assertEquals(configs, {'value_1': '1', 'value_2': '2',
251                                    'value_a': 'A'})
252        configs = self.conf.get_config_value_regex('SECTION_E',
253                                                   'wireless_ssid_.*')
254        self.assertEquals(configs, {'wireless_ssid_1.2.3.4/24': 'ssid_1',
255                                    'wireless_ssid_4.3.2.1/16': 'ssid_2'})
256
257
258    def test_get_section_as_dict(self):
259        """Test get_section_as_dict."""
260        got = self.conf.get_section_as_dict('SECTION_D')
261        self.assertEqual(got, collections.OrderedDict([('value_1', '1')]))
262
263
264    def test_get_section_as_dict_missing(self):
265        """Test get_section_as_dict with missing section."""
266        got = self.conf.get_section_as_dict('FOOBAR')
267        self.assertEqual(got, collections.OrderedDict())
268
269
270# this is so the test can be run in standalone mode
271if __name__ == '__main__':
272    """Main"""
273    unittest.main()
274