| #!/usr/bin/env python3 |
| # Copyright 2020 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """ |
| Unit tests for query_by_field.py |
| |
| """ |
| |
| import io |
| import sys |
| import unittest |
| |
| import platform_json_unittest |
| import query_by_field |
| |
| |
| def _run_main(argv): |
| """Run platform_json.main(argv), capturing and returning stdout.""" |
| original_stdout = sys.stdout |
| capture_io = io.StringIO() |
| sys.stdout = capture_io |
| try: |
| query_by_field.main(argv) |
| return capture_io.getvalue() |
| finally: |
| capture_io.close() |
| sys.stdout = original_stdout |
| |
| |
| class SingleOperatorTestCase(platform_json_unittest.AbstractMockConfigTestCase, |
| unittest.TestCase): |
| """Test-case for using a single operator of each type.""" |
| def runTest(self): # pylint: disable=invalid-name |
| """Test each operator in isolation.""" |
| # Equality operator ('=') |
| argv = ['field1=5', '-c', self.mock_filepath] |
| expected = 'DEFAULTS\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| # Inequality operator ('!=') |
| argv = ['field1!=5', '-c', self.mock_filepath] |
| expected = 'my_platform\nmy_parent\nmy_grandparent\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| # Array membership operator (':') |
| argv = ['fieldArray:elem2', '-c', self.mock_filepath] |
| expected = 'my_platform\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| # Array non-membership operator ('!:') |
| argv = ['fieldArray!:elem5', '-c', self.mock_filepath] |
| expected = 'my_platform\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| # Numeric less-than operator ('<') |
| argv = ['field1<2', '-c', self.mock_filepath] |
| expected = 'my_platform (except my_model)\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| # Numeric less-than-or-equal operator ('<=') |
| argv = ['field1<=2', '-c', self.mock_filepath] |
| expected = 'my_platform (except my_model)\nmy_parent\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| # Numeric greater-than operator ('>') |
| argv = ['field1>4', '-c', self.mock_filepath] |
| expected = 'DEFAULTS\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| # Numeric greater-than-or-equal operator ('>=') |
| argv = ['field1>=4', '-c', self.mock_filepath] |
| expected = 'DEFAULTS\nmy_platform (only my_model)\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| |
| class OperatorTypeMismatchTestCase(platform_json_unittest.AbstractMockConfigTestCase, |
| unittest.TestCase): |
| """Test-case for exceptions being raised for operator-type mismatches.""" |
| def runTest(self): # pylint: disable=invalid-name |
| """Test each operator which can have invalid types.""" |
| # Array operators only make sense with array fields. |
| for operator in (':', '!:'): |
| query = 'field1%s1' % operator |
| argv = [query, '-c', self.mock_filepath] |
| with self.assertRaises(query_by_field.NotIterableError): |
| _run_main(argv) |
| |
| # Numeric operators only make sense with numeric fields. |
| for operator in ('<', '<=', '>', '>='): |
| config_value_is_array = 'fieldArray%s1' |
| config_value_is_string = 'platform%s1' |
| expected_value_is_string = 'field1%sfoo' |
| for fmt in (config_value_is_array, config_value_is_string, |
| expected_value_is_string): |
| query = fmt % operator |
| argv = [query, '-c', self.mock_filepath] |
| with self.assertRaises(query_by_field.NotNumericError): |
| _run_main(argv) |
| |
| |
| class MultipleOperatorsTestCase(platform_json_unittest.AbstractMockConfigTestCase, |
| unittest.TestCase): |
| """Test-case for using multiple operators.""" |
| def runTest(self): # pylint: disable=invalid-name |
| """Test using multiple operators.""" |
| argv = ['field1!=1', 'field1!=4', '-c', self.mock_filepath] |
| expected = 'DEFAULTS\nmy_parent\nmy_grandparent\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| |
| class ModelExceptionsTestCase(platform_json_unittest.AbstractMockConfigTestCase, |
| unittest.TestCase): |
| """Test-case for when model overrides change whether a platform matches.""" |
| def runTest(self): # pylint: disable=invalid-name |
| """Test all variants of model exceptions.""" |
| # Check for when a platform does not match, except for one model |
| argv = ['field1=4', '-c', self.mock_filepath] |
| expected = 'my_platform (only my_model)\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| # Check for when a platform matches, except for one model |
| argv = ['field1=1', '-c', self.mock_filepath] |
| expected = 'my_platform (except my_model)\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| # Check for multiple model exceptions |
| argv = ['field1=1', 'field2=2', '-c', self.mock_filepath] |
| expected = 'my_platform (except my_model, my_model2)\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| |
| class NoMatchesTestCase(platform_json_unittest.AbstractMockConfigTestCase, |
| unittest.TestCase): |
| """Test-case for when no platforms match the query.""" |
| def runTest(self): #pylint: disable=invalid-name |
| """Run script with a bogus query.""" |
| argv = ['field1=1337', '-c', self.mock_filepath] |
| expected = 'No platforms matched.\n' |
| self.assertEqual(_run_main(argv), expected) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |