| # Copyright (c) 2013 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 logging |
| import pprint |
| |
| import common |
| from autotest_lib.server.cros.faft.config import DEFAULTS |
| |
| |
| 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 default values from DEFAULTS.py which is found within |
| the config package and the overrides come from module files named |
| the same (Link.py, ...) as the value passed in via |
| 'platform' (e.g. Link, Stumpy, ...). Note we consider the platform name |
| case insensitive and by convention platform override files should be |
| lowercase. |
| |
| The DEFAULTS module must exist and contain a class named 'Values'. |
| |
| The override module is optional. If it exists, it must contain a 'Values' |
| class. That class can inherit any other override's Values class. |
| |
| Attribute requests will first be searched through the overrides (if it |
| exists) and then through the defaults. |
| |
| @attribute platform: string containing the platform name being tested. |
| """ |
| |
| def __init__(self, platform=None): |
| """Initialize an object with FAFT settings. |
| |
| Initialize a list of objects that will be searched, in order, for |
| the requested config attribute. |
| |
| @param platform: string containing the platform name being tested. |
| """ |
| self.platform = platform |
| # Defaults must always exist. |
| self._precedence_list = [DEFAULTS.Values()] |
| # Overrides are optional, and not an error. |
| try: |
| config_name = platform.rsplit('_', 1)[-1].lower().replace("-", "_") |
| overrides = __import__(config_name, globals(), locals()) |
| overrides = overrides.Values() |
| # Add overrides to the first position in the list |
| self._precedence_list.insert(0, overrides) |
| except ImportError: |
| logging.debug("No config overrides found for platform: %s.", |
| platform) |
| logging.debug(str(self)) |
| |
| def __getattr__(self, name): |
| """Search through every object (first in overrides then in defaults) |
| for the first occurrence of the requested attribute (name) and |
| return that. Else raise AttributeError. |
| |
| @param name: string with attribute being searched for. Should not be |
| an empty string or None. |
| """ |
| for cfg_obj in self._precedence_list: |
| if hasattr(cfg_obj, name): |
| return getattr(cfg_obj, name) |
| raise AttributeError("No value exists for attribute (%s)" % name) |
| |
| def _filtered_attribute_list(self): |
| """Return a sorted(set) containing all attributes from all objects with |
| attributes starting with __ being filtered out.""" |
| filtered_attributes = set() |
| for cfg_obj in self._precedence_list: |
| filtered_attributes.update([name for name in dir(cfg_obj) if |
| not name.startswith('__')]) |
| return sorted(filtered_attributes) |
| |
| def __str__(self): |
| str_list = [] |
| str_list.append("--[ Raw FAFT Config Dump ]--------------------------") |
| for cfg_obj in self._precedence_list: |
| str_list.append("%s -> %s\n" % (cfg_obj, |
| pprint.pformat(dir(cfg_obj)))) |
| str_list.append("--[ Resolved FAFT Config Values ]-------------------") |
| for attr in self._filtered_attribute_list(): |
| str_list.append("%s = %s" % (attr, getattr(self, attr))) |
| str_list.append("---------------------------------------------------") |
| return "\n".join(str_list) |