blob: 0856b80db80d17a921db844068d6930268efbcc2 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2020 The ChromiumOS Authors
# 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()