blob: b0c90084f81c66df2c624ca49c2a1abf7987f291 [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 platform_json.py
"""
import collections
import io
import json
import os
import sys
import tempfile
import unittest
import platform_json
MOCK_CONSOLIDATED_JSON_CONTENTS = \
'''{
"DEFAULTS": {
"platform": null,
"parent": null,
"field1": 5,
"field2": 5,
"field3": 5,
"field4": 5,
"fieldArray": [
"elem5"
]
},
"my_platform": {
"platform": "my_platform",
"parent": "my_parent",
"field1": 1,
"fieldArray": [
"elem1",
"elem2"
],
"models": {
"my_model": {
"field1": 4
},
"my_model2": {
"field2": 4
}
}
},
"my_parent": {
"platform": "my_parent",
"parent": "my_grandparent",
"field1": 2,
"field2": 2
},
"my_grandparent": {
"platform": "my_grandparent",
"field1": 3,
"field2": 3,
"field3": 3
}
}'''
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:
platform_json.main(argv)
return capture_io.getvalue()
finally:
capture_io.close()
sys.stdout = original_stdout
class AbstractMockConfigTestCase(object):
"""Parent class to handle setup and teardown of mock configs."""
def setUp(self): # pylint:disable=invalid-name
"""Write mock JSON to a temporary file"""
_, self.mock_filepath = tempfile.mkstemp()
with open(self.mock_filepath, 'w') as mock_file:
mock_file.write(MOCK_CONSOLIDATED_JSON_CONTENTS)
def tearDown(self): # pylint:disable=invalid-name
"""Destroy the mock JSON file"""
os.remove(self.mock_filepath)
class InheritanceTestCase(AbstractMockConfigTestCase, unittest.TestCase):
"""Ensure that all levels of inheritance are handled correctly"""
def runTest(self): # pylint:disable=invalid-name
"""Load platform config and check that it looks correct"""
consolidated_json = platform_json.load_consolidated_json(
self.mock_filepath)
my_platform = platform_json.calculate_config('my_platform',
None,
consolidated_json)
self.assertEqual(my_platform['field1'], 1) # No inheritance
self.assertEqual(my_platform['field2'], 2) # Direct inheritance
self.assertEqual(my_platform['field3'], 3) # Recursive inheritance
self.assertEqual(my_platform['field4'], 5) # Inherit from DEFAULTS
my_model = platform_json.calculate_config('my_platform',
'my_model',
consolidated_json)
self.assertEqual(my_model['field1'], 4) # Model override
self.assertEqual(my_model['field2'], 2) # Everything else is the same
self.assertEqual(my_model['field3'], 3)
self.assertEqual(my_model['field4'], 5)
class EndToEndPlatformTestCase(AbstractMockConfigTestCase, unittest.TestCase):
"""End-to-end testing for specifying the platform name."""
def runTest(self): # pylint: disable=invalid-name
"""Main test logic"""
# Basic platform specification
argv = ['my_platform', '-c', self.mock_filepath]
expected_json = collections.OrderedDict({
'platform': 'my_platform',
'parent': 'my_parent',
'field1': 1,
'field2': 2,
'field3': 3,
'field4': 5,
'fieldArray': [
'elem1',
'elem2',
],
})
expected_output = json.dumps(expected_json, indent=4) + '\n'
self.assertEqual(_run_main(argv), expected_output)
# Condensed output
argv.append('--condense-output')
expected_output = json.dumps(expected_json, indent=None)
self.assertEqual(_run_main(argv), expected_output)
# Non-existent platform should raise an error
argv = ['fake_platform', '-c', self.mock_filepath]
with self.assertRaises(platform_json.PlatformNotFoundError):
_run_main(argv)
class EndToEndFieldTestCase(AbstractMockConfigTestCase, unittest.TestCase):
"""End-to-end testing for specifying the field name."""
def runTest(self): # pylint: disable=invalid-name
"""Main test logic"""
# Basic field specification
argv = ['my_platform', '-f', 'field1', '-c', self.mock_filepath]
self.assertEqual(_run_main(argv), '1\n')
# Condensed output should yield no newline
argv.append('--condense-output')
self.assertEqual(_run_main(argv), '1')
# Non-existent field should raise an error
argv = ['my_platform', '-f', 'fake_field', '-c', self.mock_filepath]
with self.assertRaises(platform_json.FieldNotFoundError):
_run_main(argv)
if __name__ == '__main__':
unittest.main()