#!/usr/bin/python2 # # 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 common from autotest_lib.client.common_lib import error from autotest_lib.server.cros.faft.utils 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._CONFIG_DIR, but remember the original. self.mock_config_dir = tempfile.mkdtemp() self.original_config_dir = config._CONFIG_DIR config._CONFIG_DIR = self.mock_config_dir # Write mock config file. with open(config._consolidated_json_fp(), 'w') as f: json.dump(self.mock_configs, f) def tearDown(self): """After tests are complete, delete the tempfile""" if self.mock_configs is None: return os.remove(config._consolidated_json_fp()) os.rmdir(self.mock_config_dir) config._CONFIG_DIR = self.original_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 DirectSelfInheritanceTestCase(_MockConfigTestCaseBaseClass): """Ensure that a config which inherits from itself raises an error.""" mock_configs = { 'selfloop': { 'parent': 'selfloop', }, } def runTest(self): """Run assertions on test data.""" with self.assertRaises(error.TestError): config.Config('selfloop') class IndirectSelfInheritanceTestCase(_MockConfigTestCaseBaseClass): """Ensure that configs which inherit from each other raise an error.""" mock_configs = { 'indirectloop1': { 'parent': 'indirectloop2', }, 'indirectloop2': { 'parent': 'indirectloop1', }, 'indirectloop3': { 'parent': 'indirectloop1', }, } def runTest(self): """Run assertions on test data.""" with self.assertRaises(error.TestError): config.Config('indirectloop1') with self.assertRaises(error.TestError): config.Config('indirectloop3') class FindMostSpecificConfigTestCase(_MockConfigTestCaseBaseClass): """Ensure that configs named like $BOARD-kernelnext load $BOARD.json.""" mock_configs = { 'DEFAULTS': {}, 'samus': {}, 'veyron': {}, 'minnie': {'parent': 'veyron'}, } def runTest(self): cfg = config.Config('samus-kernelnext') self.assertEqual(config.Config('samus-kernelnext').platform, 'samus') self.assertEqual(config.Config('samus-arc-r').platform, 'samus') self.assertEqual(config.Config('veyron_minnie').platform, 'minnie') self.assertEqual(config.Config('veyron_monroe').platform, 'veyron') self.assertEqual(config.Config('veyron_minnie-arc-r').platform, 'minnie') self.assertEqual(config.Config('veyron_monroe-arc-r').platform, 'veyron') if __name__ == '__main__': unittest.main()