• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6import pprint
7
8import common
9from autotest_lib.server.cros.faft.config import DEFAULTS
10
11
12class Config(object):
13    """Configuration for FAFT tests.
14
15    This object is meant to be the interface to all configuration required
16    by FAFT tests, including device specific overrides.
17
18    It gets the default values from DEFAULTS.py which is found within
19    the config package and the overrides come from module files named
20    the same (Link.py, ...) as the value passed in via
21    'platform' (e.g. Link, Stumpy, ...). Note we consider the platform name
22    case insensitive and by convention platform override files should be
23    lowercase.
24
25    The DEFAULTS module must exist and contain a class named 'Values'.
26
27    The override module is optional. If it exists, it must contain a 'Values'
28    class. That class can inherit any other override's Values class.
29
30    Attribute requests will first be searched through the overrides (if it
31    exists) and then through the defaults.
32
33    @attribute platform: string containing the platform name being tested.
34    """
35
36    def __init__(self, platform=None):
37        """Initialize an object with FAFT settings.
38
39        Initialize a list of objects that will be searched, in order, for
40        the requested config attribute.
41
42        @param platform: string containing the platform name being tested.
43        """
44        self.platform = platform
45        # Defaults must always exist.
46        self._precedence_list = [DEFAULTS.Values()]
47        # Overrides are optional, and not an error.
48        try:
49            config_name = platform.rsplit('_', 1)[-1].lower().replace("-", "_")
50            overrides = __import__(config_name, globals(), locals())
51            overrides = overrides.Values()
52            # Add overrides to the first position in the list
53            self._precedence_list.insert(0, overrides)
54        except ImportError:
55            logging.debug("No config overrides found for platform: %s.",
56                          platform)
57        logging.debug(str(self))
58
59    def __getattr__(self, name):
60        """Search through every object (first in overrides then in defaults)
61        for the first occurrence of the requested attribute (name) and
62        return that. Else raise AttributeError.
63
64        @param name: string with attribute being searched for. Should not be
65            an empty string or None.
66        """
67        for cfg_obj in self._precedence_list:
68            if hasattr(cfg_obj, name):
69                return getattr(cfg_obj, name)
70        raise AttributeError("No value exists for attribute (%s)" % name)
71
72    def _filtered_attribute_list(self):
73        """Return a sorted(set) containing all attributes from all objects with
74        attributes starting with __ being filtered out."""
75        filtered_attributes = set()
76        for cfg_obj in self._precedence_list:
77            filtered_attributes.update([name for name in dir(cfg_obj) if
78                                                not name.startswith('__')])
79        return sorted(filtered_attributes)
80
81    def __str__(self):
82        str_list = []
83        str_list.append("--[ Raw FAFT Config Dump ]--------------------------")
84        for cfg_obj in self._precedence_list:
85            str_list.append("%s -> %s\n" % (cfg_obj,
86                                            pprint.pformat(dir(cfg_obj))))
87        str_list.append("--[ Resolved FAFT Config Values ]-------------------")
88        for attr in self._filtered_attribute_list():
89            str_list.append("%s = %s" % (attr, getattr(self, attr)))
90        str_list.append("---------------------------------------------------")
91        return "\n".join(str_list)
92