blob: 39ed050798a2545dab55ca2221853c92a3bd0ad2 [file] [log] [blame]
Greg Edelston64fdc2e2020-11-19 15:04:18 -07001#!/usr/bin/env python3
2# Copyright 2020 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""
7Unit tests for query_by_field.py
8
9"""
10
11import io
12import sys
13import unittest
14
15import platform_json_unittest
16import query_by_field
17
18
19def _run_main(argv):
20 """Run platform_json.main(argv), capturing and returning stdout."""
21 original_stdout = sys.stdout
22 capture_io = io.StringIO()
23 sys.stdout = capture_io
24 try:
25 query_by_field.main(argv)
26 return capture_io.getvalue()
27 finally:
28 capture_io.close()
29 sys.stdout = original_stdout
30
31
32class SingleOperatorTestCase(platform_json_unittest.AbstractMockConfigTestCase,
33 unittest.TestCase):
34 """Test-case for using a single operator of each type."""
35 def runTest(self): # pylint: disable=invalid-name
36 """Test each operator in isolation."""
37 # Equality operator ('=')
38 argv = ['field1=5', '-c', self.mock_filepath]
39 expected = 'DEFAULTS\n'
40 self.assertEqual(_run_main(argv), expected)
41
42 # Inequality operator ('!=')
43 argv = ['field1!=5', '-c', self.mock_filepath]
44 expected = 'my_platform\nmy_parent\nmy_grandparent\n'
45 self.assertEqual(_run_main(argv), expected)
46
Greg Edelstonb3efad22020-11-24 11:09:39 -070047 # Array membership operator (':')
48 argv = ['fieldArray:elem2', '-c', self.mock_filepath]
49 expected = 'my_platform\n'
50 self.assertEqual(_run_main(argv), expected)
51
Greg Edelston6f4f2602020-11-25 16:36:11 -070052 # Array non-membership operator ('!:')
Greg Edelstonb3efad22020-11-24 11:09:39 -070053 argv = ['fieldArray!:elem5', '-c', self.mock_filepath]
54 expected = 'my_platform\n'
55 self.assertEqual(_run_main(argv), expected)
56
Greg Edelston6f4f2602020-11-25 16:36:11 -070057 # Numeric less-than operator ('<')
58 argv = ['field1<2', '-c', self.mock_filepath]
59 expected = 'my_platform (except my_model)\n'
60 self.assertEqual(_run_main(argv), expected)
61
62 # Numeric less-than-or-equal operator ('<=')
63 argv = ['field1<=2', '-c', self.mock_filepath]
64 expected = 'my_platform (except my_model)\nmy_parent\n'
65 self.assertEqual(_run_main(argv), expected)
66
67 # Numeric greater-than operator ('>')
68 argv = ['field1>4', '-c', self.mock_filepath]
69 expected = 'DEFAULTS\n'
70 self.assertEqual(_run_main(argv), expected)
71
72 # Numeric greater-than-or-equal operator ('>=')
73 argv = ['field1>=4', '-c', self.mock_filepath]
74 expected = 'DEFAULTS\nmy_platform (only my_model)\n'
75 self.assertEqual(_run_main(argv), expected)
76
Greg Edelstonb3efad22020-11-24 11:09:39 -070077
78class OperatorTypeMismatchTestCase(platform_json_unittest.AbstractMockConfigTestCase,
79 unittest.TestCase):
80 """Test-case for exceptions being raised for operator-type mismatches."""
81 def runTest(self): # pylint: disable=invalid-name
82 """Test each operator which can have invalid types."""
83 # Array operators only make sense with array fields.
84 for operator in (':', '!:'):
85 query = 'field1%s1' % operator
86 argv = [query, '-c', self.mock_filepath]
87 with self.assertRaises(query_by_field.NotIterableError):
88 _run_main(argv)
89
Greg Edelston6f4f2602020-11-25 16:36:11 -070090 # Numeric operators only make sense with numeric fields.
91 for operator in ('<', '<=', '>', '>='):
92 config_value_is_array = 'fieldArray%s1'
93 config_value_is_string = 'platform%s1'
94 expected_value_is_string = 'field1%sfoo'
95 for fmt in (config_value_is_array, config_value_is_string,
96 expected_value_is_string):
97 query = fmt % operator
98 argv = [query, '-c', self.mock_filepath]
99 with self.assertRaises(query_by_field.NotNumericError):
100 _run_main(argv)
101
Greg Edelston64fdc2e2020-11-19 15:04:18 -0700102
103class MultipleOperatorsTestCase(platform_json_unittest.AbstractMockConfigTestCase,
104 unittest.TestCase):
105 """Test-case for using multiple operators."""
106 def runTest(self): # pylint: disable=invalid-name
107 """Test using multiple operators."""
108 argv = ['field1!=1', 'field1!=4', '-c', self.mock_filepath]
109 expected = 'DEFAULTS\nmy_parent\nmy_grandparent\n'
110 self.assertEqual(_run_main(argv), expected)
111
112
113class ModelExceptionsTestCase(platform_json_unittest.AbstractMockConfigTestCase,
114 unittest.TestCase):
115 """Test-case for when model overrides change whether a platform matches."""
116 def runTest(self): # pylint: disable=invalid-name
117 """Test all variants of model exceptions."""
118 # Check for when a platform does not match, except for one model
119 argv = ['field1=4', '-c', self.mock_filepath]
120 expected = 'my_platform (only my_model)\n'
121 self.assertEqual(_run_main(argv), expected)
122
123 # Check for when a platform matches, except for one model
124 argv = ['field1=1', '-c', self.mock_filepath]
125 expected = 'my_platform (except my_model)\n'
126 self.assertEqual(_run_main(argv), expected)
127
128 # Check for multiple model exceptions
129 argv = ['field1=1', 'field2=2', '-c', self.mock_filepath]
130 expected = 'my_platform (except my_model, my_model2)\n'
131 self.assertEqual(_run_main(argv), expected)
132
133
134class NoMatchesTestCase(platform_json_unittest.AbstractMockConfigTestCase,
135 unittest.TestCase):
136 """Test-case for when no platforms match the query."""
137 def runTest(self): #pylint: disable=invalid-name
138 """Run script with a bogus query."""
139 argv = ['field1=1337', '-c', self.mock_filepath]
140 expected = 'No platforms matched.\n'
141 self.assertEqual(_run_main(argv), expected)
142
143
144if __name__ == '__main__':
145 unittest.main()