xref: /aosp_15_r20/external/autotest/client/common_lib/control_data_unittest.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1#!/usr/bin/python3
2# pylint: disable-msg=C0111
3
4from __future__ import absolute_import
5from __future__ import division
6from __future__ import print_function
7
8import json
9import os
10import six
11from six.moves import range
12import unittest
13
14import common
15
16from autotest_lib.client.common_lib import control_data, autotemp
17
18
19ControlData = control_data.ControlData
20
21CONTROL = """
22AUTHOR = 'Author'
23DEPENDENCIES = "console, power"
24DOC = \"\"\"\
25doc stuff\"\"\"
26# EXPERIMENTAL should implicitly be False
27NAME = 'nA' "mE"
28RUN_VERIFY = False
29SYNC_COUNT = 2
30TIME='short'
31TEST_CLASS=u'Kernel'
32TEST_CATEGORY='Stress'
33TEST_TYPE='client'
34REQUIRE_SSP = False
35ATTRIBUTES = "suite:smoke, suite:bvt"
36SUITE = "suite-listed-only-in-suite-line"
37"""
38
39# Control data being wrapped into step* functions.
40WRAPPED_CONTROL = """
41def step_init():
42    step0()
43
44def step0():
45    AUTHOR = 'Author'
46    DEPENDENCIES = "console, power"
47    DOC = \"\"\"\
48    doc stuff\"\"\"
49    # EXPERIMENTAL should implicitly be False
50    NAME = 'nA' "mE"
51    RUN_VERIFY = False
52    SYNC_COUNT = 2
53    TIME='short'
54    TEST_CLASS=u'Kernel'
55    TEST_CATEGORY='Stress'
56    TEST_TYPE='client'
57    REQUIRE_SSP = False
58    ATTRIBUTES = "suite:smoke, suite:bvt"
59    SUITE = "suite-listed-only-in-suite-line"
60    MAX_RESULT_SIZE_KB = 20000
61
62step_init()
63"""
64
65
66class ControlDataTestCase(unittest.TestCase):
67    def setUp(self):
68        self._required_vars = control_data.REQUIRED_VARS
69        control_data.REQUIRED_VARS = set()
70
71
72    def tearDown(self):
73        control_data.REQUIRED_VARS = self._required_vars
74
75
76    def test_suite_tag_parts(self):
77        cd = ControlData({'suite': 'foo,bar'}, 'filename')
78        self.assertEqual(set(cd.suite_tag_parts), {'foo', 'bar'})
79
80
81    def test_suite_tag_parts_empty_for_non_suite(self):
82        cd = ControlData({}, 'filename')
83        self.assertEqual(cd.suite_tag_parts, [])
84
85
86
87class ParseControlTest(unittest.TestCase):
88    def setUp(self):
89        self.control_tmp = autotemp.tempfile(unique_id='control_unit',
90                                             text=True)
91        os.write(self.control_tmp.fd, str.encode(CONTROL))
92
93
94    def tearDown(self):
95        self.control_tmp.clean()
96
97
98    def test_parse_control(self):
99        cd = control_data.parse_control(self.control_tmp.name, True)
100        self.assertEqual(cd.author, "Author")
101        self.assertEqual(cd.dependencies, set(['console', 'power']))
102        self.assertEqual(cd.doc, "doc stuff")
103        self.assertEqual(cd.experimental, False)
104        self.assertEqual(cd.name, "nAmE")
105        self.assertEqual(cd.run_verify, False)
106        self.assertEqual(cd.sync_count, 2)
107        self.assertEqual(cd.time, "short")
108        self.assertEqual(cd.test_class, "kernel")
109        self.assertEqual(cd.test_category, "stress")
110        self.assertEqual(cd.test_type, "client")
111        self.assertEqual(cd.require_ssp, False)
112        self.assertEqual(cd.attributes, set(["suite:smoke", "suite:bvt"]))
113        self.assertEqual(cd.suite, "bvt,smoke,suite-listed-only-in-suite-line")
114
115
116class ParseWrappedControlTest(unittest.TestCase):
117    """Test control data can be retrieved from wrapped step functions."""
118    def setUp(self):
119        self.control_tmp = autotemp.tempfile(unique_id='wrapped_control_unit',
120                                             text=True)
121        os.write(self.control_tmp.fd, str.encode(WRAPPED_CONTROL))
122
123
124    def tearDown(self):
125        self.control_tmp.clean()
126
127
128    def test_parse_control(self):
129        cd = control_data.parse_control(self.control_tmp.name, True)
130        self.assertEqual(cd.author, "Author")
131        self.assertEqual(cd.dependencies, set(['console', 'power']))
132        self.assertEqual(cd.doc, "doc stuff")
133        self.assertEqual(cd.experimental, False)
134        self.assertEqual(cd.name, "nAmE")
135        self.assertEqual(cd.run_verify, False)
136        self.assertEqual(cd.sync_count, 2)
137        self.assertEqual(cd.time, "short")
138        self.assertEqual(cd.test_class, "kernel")
139        self.assertEqual(cd.test_category, "stress")
140        self.assertEqual(cd.test_type, "client")
141        self.assertEqual(cd.require_ssp, False)
142        self.assertEqual(cd.attributes, set(["suite:smoke", "suite:bvt"]))
143        self.assertEqual(cd.suite, "bvt,smoke,suite-listed-only-in-suite-line")
144        self.assertEqual(cd.max_result_size_KB, 20000)
145
146
147class ParseControlFileBugTemplate(unittest.TestCase):
148    def setUp(self):
149        self.control_tmp = autotemp.tempfile(unique_id='control_unit',
150                                             text=True)
151        self.bug_template = {
152            'owner': '[email protected]',
153            'labels': ['a', 'b'],
154            'status': None,
155            'summary': None,
156            'title': None,
157            'cc': ['a@something, b@something'],
158        }
159
160
161    def tearDown(self):
162        self.control_tmp.clean()
163
164
165    def insert_bug_template(self, control_file_string):
166        """Insert a bug template into the control file string.
167
168        @param control_file_string: A string of the control file contents
169            this test will run on.
170
171        @return: The control file string with the BUG_TEMPLATE line.
172        """
173        bug_template_line = 'BUG_TEMPLATE = %s' % json.dumps(self.bug_template)
174        return control_file_string + bug_template_line
175
176
177    def verify_bug_template(self, new_bug_template):
178        """Verify that the bug template given matches the original.
179
180        @param new_bug_template: A bug template pulled off parsing the
181            control file.
182
183        @raises AssetionError: If a value under a give key in the bug template
184            doesn't match the value in self.bug_template.
185        @raises KeyError: If a key in either bug template is missing.
186        """
187        for key, value in six.iteritems(new_bug_template):
188            self.assertEqual(value, self.bug_template[key])
189
190
191    def test_bug_template_parsing(self):
192        """Basic parsing test for a bug templates in a test control file."""
193        os.write(self.control_tmp.fd,
194                 str.encode(self.insert_bug_template(CONTROL)))
195        cd = control_data.parse_control(self.control_tmp.name, True)
196        self.verify_bug_template(cd.bug_template)
197
198
199    def test_bug_template_list(self):
200        """Test that lists in the bug template can handle other datatypes."""
201        self.bug_template['labels'].append({'foo': 'bar'})
202        os.write(self.control_tmp.fd,
203                 str.encode(self.insert_bug_template(CONTROL)))
204        cd = control_data.parse_control(self.control_tmp.name, True)
205        self.verify_bug_template(cd.bug_template)
206
207
208    def test_bad_template(self):
209        """Test that a bad bug template doesn't result in a bad control data."""
210        self.bug_template = 'foobarbug_template'
211        os.write(self.control_tmp.fd,
212                 str.encode(self.insert_bug_template(CONTROL)))
213        cd = control_data.parse_control(self.control_tmp.name, True)
214        self.assertFalse(hasattr(cd, 'bug_template'))
215
216
217class SetMethodTests(unittest.TestCase):
218    def setUp(self):
219        self.required_vars = control_data.REQUIRED_VARS
220        control_data.REQUIRED_VARS = set()
221
222
223    def tearDown(self):
224        control_data.REQUIRED_VARS = self.required_vars
225
226
227    def test_bool(self):
228        cd = ControlData({}, 'filename')
229        cd._set_bool('foo', 'False')
230        self.assertEqual(cd.foo, False)
231        cd._set_bool('foo', True)
232        self.assertEqual(cd.foo, True)
233        cd._set_bool('foo', 'FALSE')
234        self.assertEqual(cd.foo, False)
235        cd._set_bool('foo', 'true')
236        self.assertEqual(cd.foo, True)
237        self.assertRaises(ValueError, cd._set_bool, 'foo', '')
238        self.assertRaises(ValueError, cd._set_bool, 'foo', 1)
239        self.assertRaises(ValueError, cd._set_bool, 'foo', [])
240        self.assertRaises(ValueError, cd._set_bool, 'foo', None)
241
242
243    def test_int(self):
244        cd = ControlData({}, 'filename')
245        cd._set_int('foo', 0)
246        self.assertEqual(cd.foo, 0)
247        cd._set_int('foo', '0')
248        self.assertEqual(cd.foo, 0)
249        cd._set_int('foo', '-1', min=-2, max=10)
250        self.assertEqual(cd.foo, -1)
251        self.assertRaises(ValueError, cd._set_int, 'foo', 0, min=1)
252        self.assertRaises(ValueError, cd._set_int, 'foo', 1, max=0)
253        self.assertRaises(ValueError, cd._set_int, 'foo', 'x')
254        self.assertRaises(ValueError, cd._set_int, 'foo', '')
255        self.assertRaises(TypeError, cd._set_int, 'foo', None)
256
257
258    def test_set(self):
259        cd = ControlData({}, 'filename')
260        cd._set_set('foo', 'a')
261        self.assertEqual(cd.foo, set(['a']))
262        cd._set_set('foo', 'a,b,c')
263        self.assertEqual(cd.foo, set(['a', 'b', 'c']))
264        cd._set_set('foo', ' a , b , c     ')
265        self.assertEqual(cd.foo, set(['a', 'b', 'c']))
266        cd._set_set('foo', None)
267        self.assertEqual(cd.foo, set(['None']))
268
269
270    def test_string(self):
271        cd = ControlData({}, 'filename')
272        cd._set_string('foo', 'a')
273        self.assertEqual(cd.foo, 'a')
274        cd._set_string('foo', 'b')
275        self.assertEqual(cd.foo, 'b')
276        cd._set_string('foo', 'B')
277        self.assertEqual(cd.foo, 'B')
278        cd._set_string('foo', 1)
279        self.assertEqual(cd.foo, '1')
280        cd._set_string('foo', None)
281        self.assertEqual(cd.foo, 'None')
282        cd._set_string('foo', [])
283        self.assertEqual(cd.foo, '[]')
284
285
286    def test_option(self):
287        options = ['a', 'b']
288        cd = ControlData({}, 'filename')
289        cd._set_option('foo', 'a', options)
290        self.assertEqual(cd.foo, 'a')
291        cd._set_option('foo', 'b', options)
292        self.assertEqual(cd.foo, 'b')
293        cd._set_option('foo', 'B', options)
294        self.assertEqual(cd.foo, 'B')
295        self.assertRaises(ValueError, cd._set_option,
296                          'foo', 'x', options)
297        self.assertRaises(ValueError, cd._set_option,
298                          'foo', 1, options)
299        self.assertRaises(ValueError, cd._set_option,
300                          'foo', [], options)
301        self.assertRaises(ValueError, cd._set_option,
302                          'foo', None, options)
303
304
305    def test_set_attributes(self):
306        cd = ControlData({}, 'filename')
307        cd.set_attributes('suite:bvt')
308        self.assertEqual(cd.attributes, set(['suite:bvt']))
309
310
311    def test_get_test_time_index(self):
312        inputs = [time.upper() for time in
313                  ControlData.TEST_TIME_LIST]
314        time_min_index = [ControlData.get_test_time_index(time)
315                          for time in inputs]
316        expected_time_index = list(range(len(ControlData.TEST_TIME_LIST)))
317        self.assertEqual(time_min_index, expected_time_index)
318
319
320    def test_get_test_time_index_failure(self):
321        def fail():
322            """Test function to raise ControlVariableException exception
323            for invalid TIME setting."""
324            index = ControlData.get_test_time_index('some invalid TIME')
325
326        self.assertRaises(control_data.ControlVariableException, fail)
327
328
329# this is so the test can be run in standalone mode
330if __name__ == '__main__':
331    unittest.main()
332