blob: 39ed050798a2545dab55ca2221853c92a3bd0ad2 [file] [log] [blame]
#!/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()