You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
5.6 KiB
130 lines
5.6 KiB
# 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 logging
|
|
import os
|
|
|
|
import common
|
|
from autotest_lib.client.common_lib import error
|
|
|
|
|
|
# Path to the local checkout of the fw-testing-configs repo
|
|
_CONFIG_DIR = os.path.abspath(os.path.join(
|
|
os.path.dirname(os.path.realpath(__file__)), os.pardir,
|
|
'fw-testing-configs'))
|
|
_CONSOLIDATED_JSON_BASENAME = 'CONSOLIDATED.json'
|
|
|
|
|
|
def _consolidated_json_fp():
|
|
"""Get the absolute path to CONSOLIDATED.json."""
|
|
return os.path.join(_CONFIG_DIR, _CONSOLIDATED_JSON_BASENAME)
|
|
|
|
|
|
class Config(object):
|
|
"""Configuration for FAFT tests.
|
|
|
|
This object is meant to be the interface to all configuration required
|
|
by FAFT tests, including device specific overrides.
|
|
|
|
It gets the values from the JSON files in _CONFIG_DIR.
|
|
Default values are declared in the DEFAULTS.json.
|
|
Platform-specific overrides come from <platform>.json.
|
|
If the platform has model-specific overrides, then those take precedence
|
|
over the platform's config.
|
|
If the platform inherits overrides from a parent platform, then the child
|
|
platform's overrides take precedence over the parent's.
|
|
|
|
@ivar platform: string containing the board name being tested.
|
|
@ivar model: string containing the model name being tested
|
|
"""
|
|
|
|
def __init__(self, platform, model=None):
|
|
"""Initialize an object with FAFT settings.
|
|
Load JSON in order of importance (model, platform, parent/s, DEFAULTS).
|
|
|
|
@param platform: The name of the platform being tested.
|
|
"""
|
|
self._precedence_list = []
|
|
self._precedence_names = []
|
|
with open(_consolidated_json_fp()) as f:
|
|
consolidated_json = json.load(f)
|
|
# Load the most specific JSON config possible by splitting `platform`
|
|
# at '_'/'-' and reversing ([::-1]). For example, veyron_minnie should
|
|
# load minnie.json. octopus_fleex should look for fleex.json. It
|
|
# doesn't exist, so instead it loads octopus.json.
|
|
platform = platform.lower().replace('-', '_')
|
|
for p in platform.rsplit('_')[::-1]:
|
|
logging.debug('Looking for %s config', p)
|
|
if p in consolidated_json:
|
|
logging.info('Found %s config', p)
|
|
self.platform = p
|
|
break
|
|
else:
|
|
self.platform = platform
|
|
if self.platform in consolidated_json:
|
|
platform_config = consolidated_json[self.platform]
|
|
seen_platforms = [self.platform]
|
|
self._add_cfg_to_precedence(self.platform, platform_config)
|
|
model_configs = platform_config.get('models', {})
|
|
model_config = model_configs.get(model, None)
|
|
if model_config is not None:
|
|
self._add_cfg_to_precedence(
|
|
'MODEL:%s' % model, model_config, prepend=True)
|
|
logging.debug('Using model override for %s', model)
|
|
parent_platform = self._precedence_list[-1].get('parent', None)
|
|
while parent_platform is not None:
|
|
if parent_platform in seen_platforms:
|
|
loop = ' -> '.join(seen_platforms + [parent_platform])
|
|
raise error.TestError('fw-testing-configs for platform %s '
|
|
'contains an inheritance loop: %s' % (
|
|
self.platform, loop))
|
|
parent_config = consolidated_json[parent_platform]
|
|
seen_platforms.append(parent_platform)
|
|
self._add_cfg_to_precedence(parent_platform, parent_config)
|
|
parent_platform = self._precedence_list[-1].get('parent', None)
|
|
else:
|
|
logging.debug('Platform %s not found in %s. Using DEFAULTS.',
|
|
self.platform, consolidated_json)
|
|
default_config = consolidated_json['DEFAULTS']
|
|
self._add_cfg_to_precedence('DEFAULTS', default_config)
|
|
|
|
# Set attributes
|
|
all_attributes = self._precedence_list[-1].keys()
|
|
self.attributes = {}
|
|
self.attributes['platform'] = self.platform
|
|
for attribute in all_attributes:
|
|
if attribute.endswith('.DOC') or attribute == 'models':
|
|
continue
|
|
for config_dict in self._precedence_list:
|
|
if attribute in config_dict:
|
|
self.attributes[attribute] = config_dict[attribute]
|
|
break
|
|
|
|
def _add_cfg_to_precedence(self, cfg_name, cfg, prepend=False):
|
|
"""Add a configuration to self._precedence_list.
|
|
|
|
@ivar cfg_name: The name of the config.
|
|
@ivar cfg: The config dict.
|
|
@ivar prepend: If true, add to the beginning of self._precedence_list.
|
|
Otherwise, add it to the end.
|
|
"""
|
|
position = 0 if prepend else len(self._precedence_list)
|
|
self._precedence_list.insert(position, cfg)
|
|
self._precedence_names.insert(position, cfg_name)
|
|
|
|
def __getattr__(self, attr):
|
|
if attr in self.attributes:
|
|
return self.attributes[attr]
|
|
raise AttributeError('FAFT config has no attribute named %s' % attr)
|
|
|
|
def __str__(self):
|
|
str_list = []
|
|
str_list.append('----------[ FW Testing Config Variables ]----------')
|
|
str_list.append('--- Precedence list: %s ---' % self._precedence_names)
|
|
for attr in sorted(self.attributes):
|
|
str_list.append(' %s: %s' % (attr, self.attributes[attr]))
|
|
str_list.append('---------------------------------------------------')
|
|
return '\n'.join(str_list)
|