| # -*- coding: utf-8 -*- |
| # Copyright 2015 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. |
| |
| """Unittests for config.""" |
| |
| from __future__ import print_function |
| |
| import copy |
| import pickle |
| import json |
| |
| from chromite.lib import config_lib |
| from chromite.lib import cros_test_lib |
| |
| # pylint: disable=protected-access |
| |
| |
| def MockBuildConfig(): |
| """Create a BuildConfig object for convenient testing pleasure.""" |
| site_config = MockSiteConfig() |
| return site_config['amd64-generic-paladin'] |
| |
| |
| def MockSiteConfig(): |
| """Create a SiteConfig object for convenient testing pleasure. |
| |
| Shared amoung a number of unittest files, so be careful if changing it. |
| """ |
| result = config_lib.SiteConfig() |
| |
| # Add a single, simple build config. |
| result.Add( |
| 'amd64-generic-paladin', |
| boards=['amd64-generic'], |
| display_label='MockLabel', |
| build_type='paladin', |
| chrome_sdk=True, |
| chrome_sdk_build_chrome=False, |
| description='Commit Queue', |
| doc='http://mock_url/', |
| image_test=True, |
| images=['base', 'test'], |
| important=True, |
| manifest_version=True, |
| prebuilts='public', |
| upload_standalone_images=False, |
| vm_tests=[config_lib.VMTestConfig('smoke_suite')], |
| ) |
| |
| return result |
| |
| |
| def AssertSiteIndependentParameters(site_config): |
| """Helper function to test that SiteConfigs contain site-independent values. |
| |
| Args: |
| site_config: A SiteConfig object. |
| |
| Returns: |
| A boolean. True if the config contained all site-independent values. |
| False otherwise. |
| """ |
| # Enumerate the necessary site independent parameter keys. |
| # All keys must be documented. |
| # TODO (msartori): Fill in this list. |
| site_independent_params = [ |
| ] |
| |
| site_params = site_config.params |
| return all([x in site_params for x in site_independent_params]) |
| |
| |
| class _CustomObject(object): |
| """Simple object. For testing deepcopy.""" |
| |
| def __init__(self, x): |
| self.x = x |
| |
| def __eq__(self, other): |
| return self.x == other.x |
| |
| |
| class _CustomObjectWithSlots(object): |
| """Simple object with slots. For testing deepcopy.""" |
| |
| __slots__ = ['x'] |
| |
| def __init__(self, x): |
| self.x = x |
| |
| def __eq__(self, other): |
| return self.x == other.x |
| |
| |
| class BuildConfigClassTest(cros_test_lib.TestCase): |
| """BuildConfig tests.""" |
| |
| def setUp(self): |
| self.fooConfig = config_lib.BuildConfig(name='foo', foo=1) |
| self.barConfig = config_lib.BuildConfig(name='bar', bar=2) |
| self.deepConfig = config_lib.BuildConfig( |
| name='deep', nested=[1, 2, 3], deep=3, |
| child_configs=[self.fooConfig, self.barConfig]) |
| |
| def testAppendUseflags(self): |
| base_config = config_lib.BuildConfig(useflags=[]) |
| inherited_config_1 = base_config.derive( |
| useflags=config_lib.append_useflags( |
| ['foo', 'bar', '-baz'])) |
| inherited_config_2 = inherited_config_1.derive( |
| useflags=config_lib.append_useflags(['-bar', 'baz'])) |
| self.assertEqual(base_config.useflags, []) |
| self.assertEqual(inherited_config_1.useflags, ['-baz', 'bar', 'foo']) |
| self.assertEqual(inherited_config_2.useflags, ['-bar', 'baz', 'foo']) |
| |
| def testMockSiteConfig(self): |
| """Make sure Mock generator fucntion doesn't crash.""" |
| site_config = MockSiteConfig() |
| self.assertIsNotNone(site_config) |
| |
| build_config = MockBuildConfig() |
| self.assertIsNotNone(build_config) |
| |
| def testValueAccess(self): |
| self.assertEqual(self.fooConfig.name, 'foo') |
| self.assertEqual(self.fooConfig.name, self.fooConfig['name']) |
| |
| self.assertRaises(AttributeError, getattr, self.fooConfig, 'foobar') |
| |
| def testApplyEmpty(self): |
| orig = self.fooConfig.deepcopy() |
| |
| # Do nothing. |
| self.fooConfig.apply() |
| self.assertEqual(self.fooConfig, orig) |
| |
| def testApplyValues(self): |
| # Apply simple values.. |
| self.fooConfig.apply(a=1, b=2) |
| self.assertEqual(self.fooConfig, dict(name='foo', foo=1, a=1, b=2)) |
| |
| def testApplyBuildConfig(self): |
| # Apply a BuildConfig. |
| self.fooConfig.apply(self.barConfig) |
| self.assertEqual(self.fooConfig, dict(name='bar', foo=1, bar=2)) |
| |
| def testApplyMixed(self): |
| # Apply simple values.. |
| config = config_lib.BuildConfig() |
| config.apply(self.fooConfig, self.barConfig, a=1, b=2, bar=3) |
| self.assertEqual(config, dict(name='bar', foo=1, bar=3, a=1, b=2)) |
| |
| def testDeriveMixed(self): |
| config = config_lib.BuildConfig() |
| result = config.derive(self.fooConfig, self.barConfig, a=1, b=2, bar=3) |
| |
| self.assertIsNot(config, result) |
| self.assertEqual(config, dict()) |
| self.assertEqual(result, dict(name='bar', foo=1, bar=3, a=1, b=2)) |
| |
| def testApplyCallable(self): |
| # Callable that adds a configurable amount. |
| def append(x): |
| return lambda base: base + ' ' + x |
| |
| site_config = config_lib.SiteConfig() |
| |
| site_config.AddTemplate('add1', foo=append('one')) |
| site_config.AddTemplate('add2', foo=append('two')) |
| site_config.AddTemplate('fixed', foo='fixed') |
| |
| site_config.AddTemplate('derived', |
| site_config.templates.add1) |
| |
| site_config.AddTemplate('stacked', |
| site_config.templates.add1, |
| site_config.templates.add2) |
| |
| site_config.AddTemplate('stackedDeep', |
| site_config.templates.fixed, |
| site_config.templates.add1, |
| site_config.templates.add1, |
| site_config.templates.add1, |
| foo=append('deep')) |
| |
| site_config.AddTemplate('stackedDeeper', |
| site_config.templates.stacked, |
| site_config.templates.stackedDeep, |
| foo=append('deeper')) |
| |
| base = config_lib.BuildConfig(foo='base') |
| |
| # Basic apply. |
| result = base.derive(site_config.templates.add1) |
| self.assertEqual(result.foo, 'base one') |
| |
| # Callable template + local callable. |
| result = base.derive(site_config.templates.add1, foo=append('local')) |
| self.assertEqual(result.foo, 'base one local') |
| |
| # Callable template + local fixed. |
| result = base.derive(site_config.templates.add1, foo='local') |
| self.assertEqual(result.foo, 'local') |
| |
| # Derived template. |
| result = base.derive(site_config.templates.derived) |
| self.assertEqual(result.foo, 'base one') |
| |
| # Template with fixed override after stacking template (all callable magic |
| # should disappear). |
| result = base.derive(site_config.templates.fixed) |
| self.assertEqual(result.foo, 'fixed') |
| |
| # Template with stacked. |
| result = base.derive(site_config.templates.stacked) |
| self.assertEqual(result.foo, 'base one two') |
| |
| # Callables on top of fixed from template. |
| result = base.derive(site_config.templates.stackedDeep) |
| self.assertEqual(result.foo, 'fixed one one one deep') |
| |
| # Just get crazy with it. |
| result = base.derive(site_config.templates.stackedDeeper) |
| self.assertEqual(result.foo, 'fixed one one one deep deeper') |
| |
| # Ensure objects derived from weren't modified. |
| self.assertEqual(base.foo, 'base') |
| self.assertEqual(site_config.templates.fixed.foo, 'fixed') |
| |
| def AssertDeepCopy(self, obj1, obj2, obj3): |
| """Assert that |obj3| is a deep copy of |obj1|. |
| |
| Args: |
| obj1: Object that was copied. |
| obj2: A true deep copy of obj1 (produced using copy.deepcopy). |
| obj3: The purported deep copy of obj1. |
| """ |
| # Check whether the item was copied by deepcopy. If so, then it |
| # must have been copied by our algorithm as well. |
| if obj1 is not obj2: |
| self.assertIsNot(obj1, obj3) |
| |
| # Assert the three items are all equal. |
| self.assertEqual(obj1, obj2) |
| self.assertEqual(obj1, obj3) |
| |
| if isinstance(obj1, (tuple, list)): |
| # Copy tuples and lists item by item. |
| # pylint: disable=consider-using-enumerate |
| for i in range(len(obj1)): |
| self.AssertDeepCopy(obj1[i], obj2[i], obj3[i]) |
| elif isinstance(obj1, set): |
| # Compare sorted versions of the set. |
| self.AssertDeepCopy(list(sorted(obj1)), list(sorted(obj2)), |
| list(sorted(obj3))) |
| elif isinstance(obj1, dict): |
| # Copy dicts item by item. |
| for k in obj1: |
| self.AssertDeepCopy(obj1[k], obj2[k], obj3[k]) |
| elif hasattr(obj1, '__dict__'): |
| # Make sure the dicts are copied. |
| self.AssertDeepCopy(obj1.__dict__, obj2.__dict__, obj3.__dict__) |
| elif hasattr(obj1, '__slots__'): |
| # Make sure the slots are copied. |
| for attr in obj1.__slots__: |
| self.AssertDeepCopy(getattr(obj1, attr), getattr(obj2, attr), |
| getattr(obj3, attr)) |
| else: |
| # This should be an object that copy.deepcopy didn't copy (probably an |
| # immutable object.) If not, the test needs to be updated to handle this |
| # kind of object. |
| self.assertIs(obj1, obj2) |
| |
| def testDeepCopy(self): |
| """Test that we deep copy correctly.""" |
| for cfg in [self.fooConfig, self.barConfig, self.deepConfig]: |
| self.AssertDeepCopy(cfg, copy.deepcopy(cfg), cfg.deepcopy()) |
| |
| def testAssertDeepCopy(self): |
| """Test that we test deep copy correctly.""" |
| test1 = ['foo', 'bar', ['hey']] |
| tests = [test1, |
| set([tuple(x) for x in test1]), |
| dict(zip([tuple(x) for x in test1], test1)), |
| _CustomObject(test1), |
| _CustomObjectWithSlots(test1)] |
| |
| for x in tests + [[tests]]: |
| copy_x = copy.deepcopy(x) |
| self.AssertDeepCopy(x, copy_x, copy.deepcopy(x)) |
| self.AssertDeepCopy(x, copy_x, pickle.loads(pickle.dumps(x, -1))) |
| self.assertRaises(AssertionError, self.AssertDeepCopy, x, |
| copy_x, x) |
| if not isinstance(x, set): |
| self.assertRaises(AssertionError, self.AssertDeepCopy, x, |
| copy_x, copy.copy(x)) |
| |
| def testPickle(self): |
| bc1 = MockBuildConfig() |
| bc2 = pickle.loads(pickle.dumps(bc1)) |
| |
| self.assertEqual(bc1.boards, bc2.boards) |
| self.assertEqual(bc1.name, bc2.name) |
| |
| |
| class GetSiteParamsTest(cros_test_lib.TestCase): |
| """Tests for the return value from config_lib.GetSiteParams().""" |
| |
| def testAttributeAccess(self): |
| """Test that dot-accessor works correctly.""" |
| site_params = config_lib.GetSiteParams() |
| |
| # Ensure our test key is not in site_params. |
| self.assertNotIn('foo', site_params) |
| |
| # Test that we raise when accessing a non-existent value. |
| # pylint: disable=pointless-statement |
| with self.assertRaises(AttributeError): |
| site_params.foo |
| |
| # Test the dot-accessor. |
| site_params.update({'foo': 'bar'}) |
| self.assertEqual('bar', site_params.foo) |
| |
| |
| class SiteConfigTest(cros_test_lib.TestCase): |
| """Config tests.""" |
| |
| @staticmethod |
| def _callable(x): |
| return x + ' extended' |
| |
| def setUp(self): |
| self.complex_defaults = { |
| 'value': 'default', |
| } |
| |
| # Construct our test config. |
| site_config = config_lib.SiteConfig(defaults=self.complex_defaults) |
| |
| site_config.AddTemplate('match', value='default') |
| site_config.AddTemplate('template', value='template') |
| site_config.AddTemplate('mixin', value='mixin') |
| site_config.AddTemplate('unused', value='unused') |
| site_config.AddTemplate('callable', value=self._callable) |
| |
| default = site_config.Add('default') |
| |
| default_with_override = site_config.Add( |
| 'default_with_override', |
| value='override') |
| |
| site_config.AddWithoutTemplate( |
| 'default_with_mixin', |
| site_config.templates.mixin) |
| |
| site_config.AddWithoutTemplate( |
| 'mixin_with_override', |
| site_config.templates.mixin, |
| value='override') |
| |
| site_config.Add( |
| 'default_with_template', |
| site_config.templates.template) |
| |
| site_config.Add( |
| 'template_with_override', |
| site_config.templates.template, |
| value='override') |
| |
| site_config.Add( |
| 'template_with_mixin', |
| site_config.templates.template, |
| site_config.templates.mixin) |
| |
| site_config.Add( |
| 'template_with_mixin_override', |
| site_config.templates.template, |
| site_config.templates.mixin, |
| value='override') |
| |
| site_config.Add( |
| 'match', |
| value='default') |
| |
| site_config.Add( |
| 'template_back_to_default', |
| site_config.templates.template, |
| value='default') |
| |
| site_config.Add( |
| 'calling', |
| site_config.templates.callable) |
| |
| site_config.Add( |
| 'vm_tests', |
| vm_tests=[config_lib.VMTestConfig('vm_suite')], |
| vm_tests_override=[config_lib.VMTestConfig('vm_override')]) |
| |
| site_config.Add( |
| 'hw_tests', |
| hw_tests=[config_lib.HWTestConfig('hw_suite')], |
| hw_tests_override=[config_lib.HWTestConfig('hw_override')]) |
| |
| site_config.Add( |
| 'tast_vm_tests', |
| tast_vm_tests=[config_lib.TastVMTestConfig('tast_vm_suite', |
| ['(!disabled)'])]) |
| |
| site_config.AddGroup( |
| 'parent', |
| default, |
| default_with_override) |
| |
| self.site_config = site_config |
| |
| def testAddedContents(self): |
| """Verify that our complex config looks like we expect, before saving.""" |
| expected = { |
| 'default': { |
| '_template': None, |
| 'name': 'default', |
| 'value': 'default', |
| }, |
| 'default_with_override': { |
| '_template': None, |
| 'name': 'default_with_override', |
| 'value': 'override', |
| }, |
| 'default_with_mixin': { |
| '_template': None, |
| 'name': 'default_with_mixin', |
| 'value': 'mixin', |
| }, |
| 'mixin_with_override': { |
| '_template': None, |
| 'name': 'mixin_with_override', |
| 'value': 'override', |
| }, |
| 'default_with_template': { |
| '_template': 'template', |
| 'name': 'default_with_template', |
| 'value': 'template', |
| }, |
| 'template_with_override': { |
| '_template': 'template', |
| 'name': 'template_with_override', |
| 'value': 'override' |
| }, |
| 'template_with_mixin': { |
| '_template': 'template', |
| 'name': 'template_with_mixin', |
| 'value': 'mixin', |
| }, |
| 'template_with_mixin_override': { |
| '_template': 'template', |
| 'name': 'template_with_mixin_override', |
| 'value': 'override' |
| }, |
| 'calling': { |
| '_template': 'callable', |
| 'name': 'calling', |
| 'value': 'default extended', |
| }, |
| 'match': { |
| '_template': None, |
| 'name': 'match', |
| 'value': 'default', |
| }, |
| 'template_back_to_default': { |
| '_template': 'template', |
| 'name': 'template_back_to_default', |
| 'value': 'default', |
| }, |
| 'vm_tests': { |
| '_template': None, |
| 'name': 'vm_tests', |
| 'vm_tests': [config_lib.VMTestConfig('vm_suite')], |
| 'vm_tests_override': [config_lib.VMTestConfig('vm_override')], |
| }, |
| 'hw_tests': { |
| '_template': None, |
| 'name': 'hw_tests', |
| 'hw_tests': [config_lib.HWTestConfig('hw_suite')], |
| 'hw_tests_override': [config_lib.HWTestConfig('hw_override')], |
| }, |
| 'tast_vm_tests': { |
| '_template': None, |
| 'name': 'tast_vm_tests', |
| 'tast_vm_tests': [ |
| config_lib.TastVMTestConfig('tast_vm_suite', ['(!disabled)'])], |
| }, |
| 'parent': { |
| '_template': None, |
| 'name': 'parent', |
| 'value': 'default', |
| }, |
| } |
| |
| # Make sure our expected build configs exist. |
| self.assertCountEqual(list(self.site_config), list(expected)) |
| |
| # Make sure each one contains |
| self.longMessage = True |
| for name in expected: |
| self.assertDictContainsSubset(expected[name], |
| self.site_config[name], |
| name) |
| |
| # Special handling for child configs. |
| |
| children = self.site_config['parent'].child_configs |
| self.assertEqual(len(children), 2) |
| self.assertDictContainsSubset( |
| { |
| '_template': None, |
| 'name': 'default', |
| 'value': 'default', |
| 'grouped': True, |
| }, |
| children[0]) |
| |
| self.assertDictContainsSubset( |
| { |
| '_template': None, |
| 'name': 'default_with_override', |
| 'value': 'override', |
| 'grouped': True, |
| }, |
| children[1]) |
| |
| def testAddErrors(self): |
| """Test the SiteConfig.Add behavior.""" |
| self.site_config.Add('foo') |
| |
| # Test we can't add the 'foo' config again. |
| with self.assertRaises(AssertionError): |
| self.site_config.Add('foo') |
| |
| # Create a template without using AddTemplate so the site config doesn't |
| # know about it. |
| fake_template = config_lib.BuildConfig( |
| name='fake_template', _template='fake_template') |
| |
| with self.assertRaises(AssertionError): |
| self.site_config.Add('bar', fake_template) |
| |
| def testTemplateAttr(self): |
| """Test the SiteConfig.templates.name behavior.""" |
| template1 = self.site_config.AddTemplate('template1', value='template') |
| template2 = self.site_config.AddTemplate('template2', value='template') |
| |
| self.assertIs(template1, self.site_config.templates.template1) |
| self.assertIs(template2, self.site_config.templates.template2) |
| |
| # Try to fetch a non-existent template. |
| with self.assertRaises(AttributeError): |
| # pylint: disable=pointless-statement |
| self.site_config.templates.no_such_template |
| # pylint: enable=pointless-statement |
| |
| def testAddForBoards(self): |
| per_board = { |
| 'foo': config_lib.BuildConfig(value='foo'), |
| 'bar': config_lib.BuildConfig(value='bar'), |
| 'multiboard': config_lib.BuildConfig(boards=['foo', 'bar']), |
| } |
| |
| # Test the minimal invocation. |
| self.site_config.AddForBoards( |
| 'minimal', |
| ['foo', 'bar'], |
| ) |
| |
| self.assertIn('foo-minimal', self.site_config) |
| self.assertEqual(self.site_config['foo-minimal'].boards, ['foo']) |
| self.assertEqual(self.site_config['bar-minimal'].boards, ['bar']) |
| |
| # Test a partial set of per-board values specified. |
| self.site_config.AddForBoards( |
| 'partial_per_board', |
| ['foo', 'no_per'], |
| per_board, |
| ) |
| |
| self.assertIn('foo-partial_per_board', self.site_config) |
| self.assertIn('no_per-partial_per_board', self.site_config) |
| self.assertEqual(self.site_config['foo-partial_per_board'].value, 'foo') |
| |
| # Test all boards with per_board values specified, and test we can |
| # override board listing in per_board values. |
| self.site_config.AddForBoards( |
| 'per_board', |
| ['foo', 'bar', 'multiboard'], |
| per_board, |
| ) |
| |
| self.assertEqual(self.site_config['foo-per_board'].value, 'foo') |
| self.assertEqual(self.site_config['bar-per_board'].value, 'bar') |
| self.assertEqual(self.site_config['multiboard-per_board'].boards, |
| ['foo', 'bar']) |
| |
| # Test using a template |
| self.site_config.AddForBoards( |
| 'template', |
| ['foo', 'bar'], |
| None, |
| self.site_config.templates.template, |
| ) |
| |
| self.assertEqual(self.site_config['foo-template'].value, 'template') |
| |
| # Test a template, and a mixin. |
| self.site_config.AddForBoards( |
| 'mixin', |
| ['foo', 'bar'], |
| None, |
| self.site_config.templates.template, |
| self.site_config.templates.mixin, |
| ) |
| |
| self.assertEqual(self.site_config['foo-mixin'].value, 'mixin') |
| |
| # Test a template, and a mixin, and a per-board. |
| self.site_config.AddForBoards( |
| 'mixin_per_board', |
| ['foo', 'bar'], |
| per_board, |
| self.site_config.templates.template, |
| self.site_config.templates.mixin, |
| ) |
| |
| self.assertEqual(self.site_config['foo-mixin_per_board'].value, 'foo') |
| |
| # Test a template, and a mixin, and a per-board, and an override. |
| self.site_config.AddForBoards( |
| 'override', |
| ['foo', 'bar'], |
| per_board, |
| self.site_config.templates.template, |
| self.site_config.templates.mixin, |
| value='override', |
| ) |
| |
| self.assertEqual(self.site_config['foo-override'].value, 'override') |
| |
| def _verifyLoadSave(self, site_config): |
| """Make sure that we can save and re-load a site.""" |
| config_str = site_config.SaveConfigToString() |
| loaded = config_lib.LoadConfigFromString(config_str) |
| |
| # |
| # BUG ALERT ON TEST FAILURE |
| # |
| # assertDictEqual can correctly compare these structs for equivalence, but |
| # has a bug when displaying differences on failure. The embedded |
| # HWTestConfig values are correctly compared, but ALWAYS display as |
| # different, if something else triggers a failure. |
| # |
| |
| # This for loop is to make differences easier to find/read. |
| self.longMessage = True |
| for name in site_config: |
| self.assertDictEqual(loaded[name], site_config[name], name) |
| |
| # This includes templates and the default build config. |
| self.assertEqual(site_config, loaded) |
| |
| loaded_str = loaded.SaveConfigToString() |
| |
| self.assertEqual(config_str, loaded_str) |
| |
| # Cycle through save load again, just for completeness. |
| loaded2 = config_lib.LoadConfigFromString(loaded_str) |
| loaded2_str = loaded2.SaveConfigToString() |
| self.assertEqual(loaded_str, loaded2_str) |
| |
| # Make sure we can dump long content without crashing. |
| self.assertNotEqual(site_config.DumpExpandedConfigToString(), '') |
| self.assertNotEqual(loaded.DumpExpandedConfigToString(), '') |
| self.assertNotEqual(loaded.DumpConfigCsv(), '') |
| |
| return loaded |
| |
| def testSaveLoadEmpty(self): |
| """Create, save, and reload an empty config.""" |
| site_config = config_lib.SiteConfig() |
| |
| loaded = self._verifyLoadSave(site_config) |
| |
| self.assertEqual(list(loaded), []) |
| self.assertEqual(list(loaded._templates), []) |
| self.assertDictEqual( |
| loaded.GetDefault(), config_lib.DefaultSettings()) |
| |
| def testSaveLoadComplex(self): |
| """Create, save, and reload an complex config.""" |
| # Verify it. |
| loaded = self._verifyLoadSave(self.site_config) |
| |
| # Verify default build config |
| expected_defaults = config_lib.DefaultSettings() |
| expected_defaults.update(self.complex_defaults) |
| self.assertDictEqual(loaded.GetDefault(), expected_defaults) |
| |
| # Ensure that expected templates are present. |
| self.assertCountEqual(list(loaded.templates), |
| ['template', 'callable']) |
| |
| def testTemplatesToSave(self): |
| def _invert(x): |
| return not x |
| |
| config = config_lib.SiteConfig() |
| config.AddTemplate('base', foo=True, important=False) |
| config.AddTemplate('callable', important=_invert) |
| config.AddTemplate('unused', bar=True) |
| config.Add('build1', config.templates.base, var=1) |
| config.Add('build2', var=2) |
| config.Add('build3', config.templates.base, var=3) |
| config.Add('build4', config.templates.callable, var=4) |
| |
| self.assertCountEqual( |
| config.templates, |
| { |
| 'base': {'_template': 'base', 'foo': True, 'important': False}, |
| 'callable': {'_template': 'callable', 'important': _invert}, |
| 'unused': {'_template': 'unused', 'bar': True}, |
| } |
| ) |
| |
| results = config._MarshalTemplates() |
| |
| self.assertCountEqual( |
| results, |
| { |
| 'base': {'_template': 'base', 'foo': True}, |
| 'callable': {'_template': 'callable', 'important': True}, |
| } |
| ) |
| |
| |
| class SiteConfigFindTests(cros_test_lib.TestCase): |
| """Tests related to Find helpers on SiteConfig.""" |
| |
| def testGetBoardsMockConfig(self): |
| site_config = MockSiteConfig() |
| self.assertEqual( |
| site_config.GetBoards(), |
| set(['amd64-generic'])) |
| |
| def testGetBoardsComplexConfig(self): |
| site_config = MockSiteConfig() |
| site_config.Add('build_a', boards=['foo_board']) |
| site_config.Add('build_b', boards=['bar_board']) |
| site_config.Add('build_c', boards=['foo_board', 'car_board']) |
| |
| self.assertEqual( |
| site_config.GetBoards(), |
| set(['amd64-generic', 'foo_board', 'bar_board', 'car_board'])) |
| |
| def testGetSlaveConfigMapForMasterAll(self): |
| """Test GetSlaveConfigMapForMaster, GetSlavesForMaster all slaves.""" |
| |
| site_config = MockSiteConfig() |
| master = site_config.Add('master', master=True, manifest_version=True, |
| slave_configs=['slave_a', 'slave_b']) |
| slave_a = site_config.Add('slave_a', important=True) |
| slave_b = site_config.Add('slave_b', important=False) |
| site_config.Add('other') |
| |
| results_map = site_config.GetSlaveConfigMapForMaster(master, |
| important_only=False) |
| results_slaves = site_config.GetSlavesForMaster(master, |
| important_only=False) |
| |
| self.assertEqual(results_map, {'slave_a': slave_a, 'slave_b': slave_b}) |
| self.assertCountEqual(results_slaves, [slave_a, slave_b]) |
| |
| def testGetSlaveConfigMapForMasterImportant(self): |
| """Test GetSlaveConfigMapForMaster, GetSlavesForMaster important only.""" |
| |
| site_config = MockSiteConfig() |
| master = site_config.Add('master', master=True, manifest_version=True, |
| slave_configs=['slave_a', 'slave_b']) |
| slave_a = site_config.Add('slave_a', important=True) |
| site_config.Add('slave_b', important=False) |
| site_config.Add('other') |
| |
| results_map = site_config.GetSlaveConfigMapForMaster(master) |
| results_slaves = site_config.GetSlavesForMaster(master) |
| |
| self.assertEqual(results_map, {'slave_a': slave_a}) |
| self.assertCountEqual(results_slaves, [slave_a]) |
| |
| |
| class GetConfigTests(cros_test_lib.TestCase): |
| """Tests related to SiteConfig.GetConfig().""" |
| |
| def testGetConfigCaching(self): |
| """Test that config_lib.GetConfig() caches it's results correctly.""" |
| config_a = config_lib.GetConfig() |
| config_b = config_lib.GetConfig() |
| |
| # Ensure that we get a SiteConfig, and that the result is cached. |
| self.assertIsInstance(config_a, config_lib.SiteConfig) |
| self.assertIs(config_a, config_b) |
| |
| |
| class GEBuildConfigTests(cros_test_lib.TestCase): |
| """Test GE build config related methods.""" |
| |
| def setUp(self): |
| self._fake_ge_build_config_json = """ |
| { |
| "metadata_version": "1.0", |
| "reference_board_unified_builds": [ |
| { |
| "name": "reef", |
| "reference_board_name": "reef", |
| "builder": "RELEASE", |
| "experimental": true, |
| "arch": "X86_INTERNAL", |
| "models" : [ |
| { |
| "board_name": "reef" |
| }, |
| { |
| "board_name": "pyro" |
| } |
| ] |
| } |
| ], |
| "boards": [ |
| { |
| "name": "reef", |
| "configs": [ |
| { |
| "builder": "RELEASE", |
| "experimental": false, |
| "leader_board": true, |
| "board_group": "reef", |
| "arch": "X86_INTERNAL" |
| } |
| ] |
| } |
| ] |
| } |
| """ |
| self._fake_ge_build_config = json.loads(self._fake_ge_build_config_json) |
| |
| def testGetArchBoardDict(self): |
| """Test GetArchBoardDict.""" |
| ge_build_config = config_lib.LoadGEBuildConfigFromFile() |
| arch_board_dict = config_lib.GetArchBoardDict(ge_build_config) |
| self.assertIsNotNone(arch_board_dict) |
| |
| def testGetArchBoardDictUnifiedBuilds(self): |
| """Test GetArchBoardDict.""" |
| arch_board_dict = config_lib.GetArchBoardDict(self._fake_ge_build_config) |
| self.assertIsNotNone(arch_board_dict) |
| self.assertIs(1, len(arch_board_dict[config_lib.CONFIG_X86_INTERNAL])) |
| |
| def testGetUnifiedBuildConfigAllBuilds(self): |
| uni_builds = config_lib.GetUnifiedBuildConfigAllBuilds( |
| self._fake_ge_build_config) |
| self.assertEqual(1, len(uni_builds)) |
| |
| def testGetUnifiedBuildConfigAllBuildsWithNoBuilds(self): |
| uni_builds = config_lib.GetUnifiedBuildConfigAllBuilds({}) |
| self.assertEqual(0, len(uni_builds)) |