| # Copyright 2019 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. |
| |
| import json |
| import os |
| import tempfile |
| import unittest |
| |
| import config |
| |
| |
| class CanLoadDefaultTestCase(unittest.TestCase): |
| """Ensure that configs can load the default JSON""" |
| |
| def runTest(self): |
| """Main test logic""" |
| platform = "foo" |
| cfg = config.Config(platform) |
| self.assertIsInstance(cfg.has_keyboard, bool) |
| |
| |
| class _MockConfigTestCaseBaseClass(unittest.TestCase): |
| """ |
| Base class which handles the setup/teardown of mock config files. |
| |
| Sub-classes should declare a class attribute, mock_configs, |
| as a dict representing all platforms to be written as JSON files. |
| This class writes those JSON files during setUp() and deletes them |
| during tearDown(). |
| During runTest(), sub-classes can create config.Config instances by name |
| and run assertions as normal. |
| |
| """ |
| |
| mock_configs = None |
| |
| def setUp(self): |
| """Set up a tempfile containing the test data""" |
| if self.mock_configs is None: |
| return |
| |
| # Setup mock config._get_config_dir(), but remember the original. |
| self.mock_config_dir = tempfile.mkdtemp() |
| self.original_get_config_dir = config._get_config_dir |
| config._get_config_dir = lambda: self.mock_config_dir |
| |
| # Write mock config files. |
| self.mock_config_files = [] |
| for platform in self.mock_configs: |
| mock_config_file = os.path.join(self.mock_config_dir, |
| '%s.json' % platform) |
| with open(mock_config_file, 'w') as f: |
| json.dump(self.mock_configs[platform], f) |
| self.mock_config_files.append(mock_config_file) |
| |
| def tearDown(self): |
| """After tests are complete, delete the tempfile""" |
| if self.mock_configs is None: |
| return |
| for tf in self.mock_config_files: |
| os.remove(tf) |
| os.rmdir(self.mock_config_dir) |
| config._get_config_dir = self.original_get_config_dir |
| |
| |
| class InheritanceTestCase(_MockConfigTestCaseBaseClass): |
| """Ensure that platforms inherit attributes correctly""" |
| |
| mock_configs = { |
| 'DEFAULTS': { |
| 'no_override': 'default', |
| 'parent_override': 'default', |
| 'child_override': 'default', |
| 'both_override': 'default', |
| 'parent': None |
| }, |
| 'childboard': { |
| 'child_override': 'child', |
| 'both_override': 'child', |
| 'parent': 'parentboard' |
| }, |
| 'parentboard': { |
| 'parent_override': 'parent', |
| 'both_override': 'parent' |
| } |
| } |
| |
| def runTest(self): |
| """ |
| Verify that the following situations resolve correctly: |
| A platform that inherit some overridess from another platform |
| A platform that does not inherit from another platform |
| A platform not found in the config file |
| """ |
| child_config = config.Config('childboard') |
| #print(child_config) |
| self.assertEqual(child_config.no_override, 'default') |
| self.assertEqual(child_config.parent_override, 'parent') |
| self.assertEqual(child_config.child_override, 'child') |
| self.assertEqual(child_config.both_override, 'child') |
| with self.assertRaises(AttributeError): |
| child_config.foo # pylint: disable=pointless-statement |
| |
| parent_config = config.Config('parentboard') |
| self.assertEqual(parent_config.no_override, 'default') |
| self.assertEqual(parent_config.parent_override, 'parent') |
| self.assertEqual(parent_config.child_override, 'default') |
| self.assertEqual(parent_config.both_override, 'parent') |
| |
| foo_config = config.Config('foo') |
| self.assertEqual(foo_config.no_override, 'default') |
| self.assertEqual(foo_config.parent_override, 'default') |
| self.assertEqual(foo_config.child_override, 'default') |
| self.assertEqual(foo_config.both_override, 'default') |
| |
| # While we're here, verify that str(config) doesn't break |
| str(child_config) # pylint: disable=pointless-statement |
| |
| |
| class ModelOverrideTestCase(_MockConfigTestCaseBaseClass): |
| """Verify that models of boards inherit overrides with proper precedence""" |
| mock_configs = { |
| 'parentboard': { |
| 'attr1': 'parent_attr1', |
| 'attr2': 'parent_attr2', |
| 'models': { |
| 'modelA': { |
| 'attr1': 'parent_modelA_attr1' |
| } |
| } |
| }, |
| 'childboard': { |
| 'parent': 'parentboard', |
| 'attr1': 'child_attr1', |
| 'models': { |
| 'modelA': { |
| 'attr1': 'child_modelA_attr1' |
| } |
| } |
| }, |
| 'DEFAULTS': { |
| 'models': None, |
| 'attr1': 'default', |
| 'attr2': 'default' |
| } |
| } |
| |
| def runTest(self): |
| """Run assertions on test data""" |
| child_config = config.Config('childboard') |
| child_modelA_config = config.Config('childboard', 'modelA') |
| child_modelB_config = config.Config('childboard', 'modelB') |
| parent_config = config.Config('parentboard') |
| parent_modelA_config = config.Config('parentboard', 'modelA') |
| parent_modelB_config = config.Config('parentboard', 'modelB') |
| |
| self.assertEqual(child_config.attr1, 'child_attr1') |
| self.assertEqual(child_config.attr2, 'parent_attr2') |
| self.assertEqual(child_modelA_config.attr1, 'child_modelA_attr1') |
| self.assertEqual(child_modelA_config.attr2, 'parent_attr2') |
| self.assertEqual(child_modelB_config.attr1, 'child_attr1') |
| self.assertEqual(child_modelB_config.attr2, 'parent_attr2') |
| self.assertEqual(parent_config.attr1, 'parent_attr1') |
| self.assertEqual(parent_config.attr2, 'parent_attr2') |
| self.assertEqual(parent_modelA_config.attr1, 'parent_modelA_attr1') |
| self.assertEqual(parent_modelA_config.attr2, 'parent_attr2') |
| self.assertEqual(parent_modelB_config.attr1, 'parent_attr1') |
| self.assertEqual(parent_modelB_config.attr2, 'parent_attr2') |
| |
| |
| class PlatformNamesTestCase(unittest.TestCase): |
| """Ensure that each config has a correct 'platform' attribute""" |
| |
| def runTest(self): |
| """ |
| For each JSON config file (except DEFAULTS), verify that there is an |
| attribute 'platform' whose value exactly matches the file's basename. |
| For example, rambi.json should contain {'platform': 'rambi'} |
| """ |
| for filename in os.listdir(config._CONFIG_DIR): |
| filepath = os.path.join(config._CONFIG_DIR, filename) |
| platform_name, ext = os.path.splitext(filename) |
| if ext != '.json' or platform_name == 'DEFAULTS': |
| continue |
| with open(filepath) as f: |
| d = json.load(f) |
| self.assertIn('platform', d, |
| msg='JSON file %s did not contain platform attribute' \ |
| % filepath) |
| self.assertEqual(platform_name, d['platform'], |
| msg='JSON file %s contained mismatched platform %s' \ |
| % (filepath, d['platform'])) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |