• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Lint as: python2, python3
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""File containing class to build all available ap_configurators."""
7
8import logging
9
10from . import common
11from autotest_lib.client.common_lib.cros.network import ap_constants
12from autotest_lib.server import site_utils
13from autotest_lib.server.cros import ap_config
14from autotest_lib.server.cros.ap_configurators import ap_cartridge
15from autotest_lib.server.cros.ap_configurators import ap_spec
16from autotest_lib.server.cros.ap_configurators import static_ap_configurator
17from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
18
19
20class APConfiguratorFactory(object):
21    """Class that instantiates all available APConfigurators.
22
23    @attribute CONFIGURATOR_MAP: a dict of strings, mapping to model-specific
24                                 APConfigurator objects.
25    @attribute BANDS: a string, bands supported by an AP.
26    @attribute MODES: a string, 802.11 modes supported by an AP.
27    @attribute SECURITIES: a string, security methods supported by an AP.
28    @attribute HOSTNAMES: a string, AP hostname.
29    @attribute ap_list: a list of APConfigurator objects.
30    @attribute ap_config: an APConfiguratorConfig object.
31    """
32
33
34    BANDS = 'bands'
35    MODES = 'modes'
36    SECURITIES = 'securities'
37    HOSTNAMES = 'hostnames'
38
39
40    def __init__(self, ap_test_type, spec=None):
41        webdriver_ready = False
42        self.ap_list = []
43        self.test_type = ap_test_type
44        for ap in ap_config.get_ap_list():
45            self.ap_list.append(static_ap_configurator.StaticAPConfigurator(ap))
46
47
48    def _get_aps_by_visibility(self, visible=True):
49        """Returns all configurators that support setting visibility.
50
51        @param visibility = True if SSID should be visible; False otherwise.
52
53        @returns aps: a set of APConfigurators"""
54        if visible:
55            return set(self.ap_list)
56
57        return set([ap for ap in self.ap_list if ap.is_visibility_supported()])
58
59
60    def _get_aps_by_mode(self, band, mode):
61        """Returns all configurators that support a given 802.11 mode.
62
63        @param band: an 802.11 band.
64        @param mode: an 802.11 modes.
65
66        @returns aps: a set of APConfigurators.
67        """
68        if not mode:
69            return set(self.ap_list)
70
71        aps = []
72        for ap in self.ap_list:
73            modes = ap.get_supported_modes()
74            for d in modes:
75                if d['band'] == band and mode in d['modes']:
76                    aps.append(ap)
77        return set(aps)
78
79
80    def _get_aps_by_security(self, security):
81        """Returns all configurators that support a given security mode.
82
83        @param security: the security type
84
85        @returns aps: a set of APConfigurators.
86        """
87
88        if not security:
89            return set(self.ap_list)
90
91        aps = []
92        for ap in self.ap_list:
93            if ap.is_security_mode_supported(security):
94                aps.append(ap)
95        return set(aps)
96
97
98    def _get_aps_by_band(self, band, channel=None):
99        """Returns all APs that support a given band.
100
101        @param band: the band desired.
102
103        @returns aps: a set of APConfigurators.
104        """
105        if not band:
106            return set(self.ap_list)
107
108        aps = []
109        for ap in self.ap_list:
110            bands_and_channels = ap.get_supported_bands()
111            for d in bands_and_channels:
112                if channel:
113                    if d['band'] == band and channel in d['channels']:
114                        aps.append(ap)
115                elif d['band'] == band:
116                    aps.append(ap)
117        return set(aps)
118
119
120    def get_aps_by_hostnames(self, hostnames, ap_list=None):
121        """Returns specific APs by host name.
122
123        @param hostnames: a list of strings, AP's wan_hostname defined in the AP
124                          configuration file.
125        @param ap_list: a list of APConfigurator objects.
126
127        @return a list of APConfigurators.
128        """
129        if ap_list == None:
130            ap_list = self.ap_list
131
132        aps = []
133        for ap in ap_list:
134            if ap.host_name in hostnames:
135                logging.info('Found AP by hostname %s', ap.host_name)
136                aps.append(ap)
137
138        return aps
139
140
141    def _get_aps_by_configurator_type(self, configurator_type, ap_list):
142        """Returns APs that match the given configurator type.
143
144        @param configurator_type: the type of configurtor to return.
145        @param ap_list: a list of APConfigurator objects.
146
147        @return a list of APConfigurators.
148        """
149        aps = []
150        for ap in ap_list:
151            if ap.configurator_type == configurator_type:
152                aps.append(ap)
153
154        return aps
155
156
157    def get_ap_configurators_by_spec(self, spec=None, pre_configure=False):
158        """Returns available configurators meeting spec.
159
160        @param spec: a validated ap_spec object
161        @param pre_configure: boolean, True to set all of the configuration
162                              options for the APConfigurator object using the
163                              given ap_spec; False otherwise.  An ap_spec must
164                              be passed for this to have any effect.
165        @returns aps: a list of APConfigurator objects
166        """
167        if not spec:
168            return self.ap_list
169
170        # APSpec matching is exact. With AFE deprecated and AP's lock mechanism
171        # in datastore, there is no need to check spec.hostnames by location.
172        # If a hostname is passed, the capabilities of a given configurator
173        # match everything in the APSpec. This helps to prevent failures during
174        # the pre-scan phase.
175        aps = self._get_aps_by_band(spec.band, channel=spec.channel)
176        aps &= self._get_aps_by_mode(spec.band, spec.mode)
177        aps &= self._get_aps_by_security(spec.security)
178        aps &= self._get_aps_by_visibility(spec.visible)
179        matching_aps = list(aps)
180
181        if spec.configurator_type != ap_spec.CONFIGURATOR_ANY:
182            matching_aps = self._get_aps_by_configurator_type(
183                           spec.configurator_type, matching_aps)
184        if spec.hostnames is not None:
185            matching_aps = self.get_aps_by_hostnames(spec.hostnames,
186                                                     ap_list=matching_aps)
187        if pre_configure:
188            for ap in matching_aps:
189                ap.set_using_ap_spec(spec)
190        return matching_aps
191
192
193    def turn_off_all_routers(self, broken_pdus):
194        """Powers down all of the routers.
195
196        @param broken_pdus: list of bad/offline PDUs.
197        """
198        ap_power_cartridge = ap_cartridge.APCartridge()
199        for ap in self.ap_list:
200            ap.power_down_router()
201            ap_power_cartridge.push_configurator(ap)
202        ap_power_cartridge.run_configurators(broken_pdus)
203