1# Copyright (c) 2012 The Chromium 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 5"""File containing class to build all available ap_configurators.""" 6 7import logging 8 9from autotest_lib.client.common_lib import global_config 10from autotest_lib.client.common_lib.cros.network import ap_constants 11from autotest_lib.server.cros import ap_config 12from autotest_lib.server.cros.ap_configurators import ap_cartridge 13from autotest_lib.server.cros.ap_configurators import ap_spec 14from autotest_lib.server.cros.dynamic_suite import frontend_wrappers 15 16CONFIG = global_config.global_config 17 18_DEFAULT_AUTOTEST_INSTANCE = CONFIG.get_config_value('SERVER', 'hostname', 19 type=str) 20 21class APConfiguratorFactory(object): 22 """Class that instantiates all available APConfigurators. 23 24 @attribute CONFIGURATOR_MAP: a dict of strings, mapping to model-specific 25 APConfigurator objects. 26 @attribute BANDS: a string, bands supported by an AP. 27 @attribute MODES: a string, 802.11 modes supported by an AP. 28 @attribute SECURITIES: a string, security methods supported by an AP. 29 @attribute HOSTNAMES: a string, AP hostname. 30 @attribute ap_list: a list of APConfigurator objects. 31 @attribute ap_config: an APConfiguratorConfig object. 32 """ 33 34 PREFIX='autotest_lib.server.cros.ap_configurators.' 35 CONFIGURATOR_MAP = { 36 'LinksysAPConfigurator': 37 [PREFIX + 'linksys_ap_configurator', 38 'LinksysAPConfigurator'], 39 'LinksysAP15Configurator': 40 [PREFIX + 'linksys_ap_15_configurator', 41 'LinksysAP15Configurator'], 42 'DLinkAPConfigurator': 43 [PREFIX + 'dlink_ap_configurator', 44 'DLinkAPConfigurator'], 45 'TrendnetAPConfigurator': 46 [PREFIX + 'trendnet_ap_configurator', 47 'TrendnetAPConfigurator'], 48 'Trendnet691grAPConfigurator': 49 [PREFIX + 'trendnet691gr_ap_configurator', 50 'Trendnet691grAPConfigurator'], 51 'Trendnet731brAPConfigurator': 52 [PREFIX + 'trendnet731br_ap_configurator', 53 'Trendnet731brAPConfigurator'], 54 'Trendnet432brpAPConfigurator': 55 [PREFIX + 'trendnet432brp_ap_configurator', 56 'Trendnet432brpAPConfigurator'], 57 'Trendnet692grAPConfigurator': 58 [PREFIX + 'trendnet692gr_ap_configurator', 59 'Trendnet692grAPConfigurator'], 60 'Trendnet654trAPConfigurator': 61 [PREFIX + 'trendnet654tr_ap_configurator', 62 'Trendnet654trAPConfigurator'], 63 'Trendnet812druAPConfigurator': 64 [PREFIX + 'trendnet812dru_ap_configurator', 65 'Trendnet812druAPConfigurator'], 66 'DLinkDIR655APConfigurator': 67 [PREFIX + 'dlink_dir655_ap_configurator', 68 'DLinkDIR655APConfigurator'], 69 'DLinkDWL2100APConfigurator': 70 [PREFIX + 'dlink_dwl2100_ap_configurator', 71 'DLinkDWL2100APConfigurator'], 72 'DLinkDIR300APConfigurator': 73 [PREFIX + 'dlink_dir300_ap_configurator', 74 'DLinkDIR300APConfigurator'], 75 'DLinkDIR505lAPConfigurator': 76 [PREFIX + 'dlink_dir505l_ap_configurator', 77 'DLinkDIR505lAPConfigurator'], 78 'BuffaloAPConfigurator': 79 [PREFIX + 'buffalo_ap_configurator', 80 'BuffaloAPConfigurator'], 81 'BuffalowzrAPConfigurator': 82 [PREFIX + 'buffalo_wzr_d1800h_ap_configurator', 83 'BuffalowzrAPConfigurator'], 84 'Buffaloag300hAPConfigurator': 85 [PREFIX + 'buffaloag300h_ap_configurator', 86 'Buffaloag300hAPConfigurator'], 87 'AsusAPConfigurator': 88 [PREFIX + 'asus_ap_configurator', 89 'AsusAPConfigurator'], 90 'AsusQISAPConfigurator': 91 [PREFIX + 'asus_qis_ap_configurator', 92 'AsusQISAPConfigurator'], 93 'Asus66RAPConfigurator': 94 [PREFIX + 'asus_ac66r_ap_configurator', 95 'Asus66RAPConfigurator'], 96 'Netgear3700APConfigurator': 97 [PREFIX + 'netgear3700_ap_configurator', 98 'Netgear3700APConfigurator'], 99 'Netgear3400APConfigurator': 100 [PREFIX + 'netgear3400_ap_configurator', 101 'Netgear3400APConfigurator'], 102 'NetgearR6200APConfigurator': 103 [PREFIX + 'netgearR6200_ap_configurator', 104 'NetgearR6200APConfigurator'], 105 'Netgear1000APConfigurator': 106 [PREFIX + 'netgear1000_ap_configurator', 107 'Netgear1000APConfigurator'], 108 'Netgear2000APConfigurator': 109 [PREFIX + 'netgear2000_ap_configurator', 110 'Netgear2000APConfigurator'], 111 'Netgear4300APConfigurator': 112 [PREFIX + 'netgear4300_ap_configurator', 113 'Netgear4300APConfigurator'], 114 'Netgear4500APConfigurator': 115 [PREFIX + 'netgear4500_ap_configurator', 116 'Netgear4500APConfigurator'], 117 'LinksyseDualBandAPConfigurator': 118 [PREFIX + 'linksyse_dual_band_configurator', 119 'LinksyseDualBandAPConfigurator'], 120 'Linksyse2000APConfigurator': 121 [PREFIX + 'linksyse2000_ap_configurator', 122 'Linksyse2000APConfigurator'], 123 'LinksyseWRT320APConfigurator': 124 [PREFIX + 'linksyswrt320_ap_configurator', 125 'LinksysWRT320APConfigurator'], 126 'Linksyse1500APConfigurator': 127 [PREFIX + 'linksyse1500_ap_configurator', 128 'Linksyse1500APConfigurator'], 129 'LinksysWRT54GS2APConfigurator': 130 [PREFIX + 'linksyswrt54gs2_ap_configurator', 131 'LinksysWRT54GS2APConfigurator'], 132 'LinksysWRT600APConfigurator': 133 [PREFIX + 'linksyswrt600_ap_configurator', 134 'LinksysWRT600APConfigurator'], 135 'LinksysM10APConfigurator': 136 [PREFIX + 'linksysm10_ap_configurator', 137 'LinksysM10APConfigurator'], 138 'LinksysWRT54GLAPConfigurator': 139 [PREFIX + 'linksyswrt54gl_ap_configurator', 140 'LinksysWRT54GLAPConfigurator'], 141 'LinksysWRT610NAPConfigurator': 142 [PREFIX + 'linksyswrt610n_ap_configurator', 143 'LinksysWRT610NAPConfigurator'], 144 'LinksysWRT120NAPConfigurator': 145 [PREFIX + 'linksyswrt120n_ap_configurator', 146 'LinksysWRT120NAPConfigurator'], 147 'LevelOneAPConfigurator': 148 [PREFIX + 'levelone_ap_configurator', 149 'LevelOneAPConfigurator'], 150 'NetgearDualBandAPConfigurator': 151 [PREFIX + 'netgear_WNDR_dual_band_configurator', 152 'NetgearDualBandAPConfigurator'], 153 'BelkinAPConfigurator': 154 [PREFIX + 'belkin_ap_configurator', 155 'BelkinAPConfigurator'], 156 'BelkinF5D7234APConfigurator': 157 [PREFIX + 'belkinF5D7234_ap_configurator', 158 'BelkinF5D7234APConfigurator'], 159 'BelkinF5D8236APConfigurator': 160 [PREFIX + 'belkinF5D8236_ap_configurator', 161 'BelkinF5D8236APConfigurator'], 162 'BelkinF6D4230APConfigurator': 163 [PREFIX + 'belkinF6D4230_ap_configurator', 164 'BelkinF6D4230APConfigurator'], 165 'BelkinF7DAPConfigurator': 166 [PREFIX + 'belkinF7D_ap_configurator', 167 'BelkinF7DAPConfigurator'], 168 'BelkinF9K1002v4APConfigurator': 169 [PREFIX + 'belkinF9k1002v4_ap_configurator', 170 'BelkinF9K1002v4APConfigurator'], 171 'BelkinF7D1301APConfigurator': 172 [PREFIX + 'belkinF7D1301_ap_configurator', 173 'BelkinF7D1301APConfigurator'], 174 'BelkinF9KAPConfigurator': 175 [PREFIX + 'belkinF9K_ap_configurator', 176 'BelkinF9KAPConfigurator'], 177 'BelkinF9K1001APConfigurator': 178 [PREFIX + 'belkinF9K1001_ap_configurator', 179 'BelkinF9K1001APConfigurator'], 180 'BelkinF9K1102APConfigurator': 181 [PREFIX + 'belkinF9K1102_ap_configurator', 182 'BelkinF9K1102APConfigurator'], 183 'BelkinF9K1103APConfigurator': 184 [PREFIX + 'belkinF9K1103_ap_configurator', 185 'BelkinF9K1103APConfigurator'], 186 'BelkinF9K1105APConfigurator': 187 [PREFIX + 'belkinF9K1105_ap_configurator', 188 'BelkinF9K1105APConfigurator'], 189 'BelkinF7D5301APConfigurator': 190 [PREFIX + 'belkinF7D5301_ap_configurator', 191 'BelkinF7D5301APConfigurator'], 192 'BelkinWRTRAPConfigurator': 193 [PREFIX + 'belkinWRTR_ap_configurator', 194 'BelkinWRTRAPConfigurator'], 195 'MediaLinkAPConfigurator': 196 [PREFIX + 'medialink_ap_configurator', 197 'MediaLinkAPConfigurator'], 198 'NetgearSingleBandAPConfigurator': 199 [PREFIX + 'netgear_single_band_configurator', 200 'NetgearSingleBandAPConfigurator'], 201 'DLinkwbr1310APConfigurator': 202 [PREFIX + 'dlinkwbr1310_ap_configurator', 203 'DLinkwbr1310APConfigurator'], 204 'Linksyse2100APConfigurator': 205 [PREFIX + 'linksyse2100_ap_configurator', 206 'Linksyse2100APConfigurator'], 207 'LinksyseSingleBandAPConfigurator': 208 [PREFIX + 'linksyse_single_band_configurator', 209 'LinksyseSingleBandAPConfigurator'], 210 'Linksyse2500APConfigurator': 211 [PREFIX + 'linksyse2500_ap_configurator', 212 'Linksyse2500APConfigurator'], 213 'WesternDigitalN600APConfigurator': 214 [PREFIX + 'westerndigitaln600_ap_configurator', 215 'WesternDigitalN600APConfigurator'], 216 'Linksyse1000APConfigurator': 217 [PREFIX + 'linksyse1000_ap_configurator', 218 'Linksyse1000APConfigurator'], 219 'LinksysWRT160APConfigurator': 220 [PREFIX + 'linksyswrt160_ap_configurator', 221 'LinksysWRT160APConfigurator'], 222 'Keeboxw150nrAPConfigurator': 223 [PREFIX + 'keeboxw150nr_ap_configurator', 224 'Keeboxw150nrAPConfigurator'], 225 'EdimaxAPConfigurator': 226 [PREFIX + 'edimax_ap_configurator', 227 'EdimaxAPConfigurator'], 228 'Edimax6475ndAPConfigurator': 229 [PREFIX + 'edimax6475nd_ap_configurator', 230 'Edimax6475ndAPConfigurator'], 231 'Edimax6428nsAPConfigurator': 232 [PREFIX + 'edimax6428ns_ap_configurator', 233 'Edimax6428nsAPConfigurator'], 234 'StaticAPConfigurator': 235 [PREFIX + 'static_ap_configurator', 236 'StaticAPConfigurator'], 237 } 238 239 BANDS = 'bands' 240 MODES = 'modes' 241 SECURITIES = 'securities' 242 HOSTNAMES = 'hostnames' 243 244 245 def __init__(self, ap_test_type, spec=None): 246 webdriver_ready = False 247 self.ap_list = [] 248 self.test_type = ap_test_type 249 for ap in ap_config.get_ap_list(ap_test_type): 250 module_name, configurator_class = \ 251 self.CONFIGURATOR_MAP[ap.get_class()] 252 module = __import__(module_name, fromlist=configurator_class) 253 configurator = module.__dict__[configurator_class] 254 self.ap_list.append(configurator(ap_config=ap)) 255 256 257 def _get_aps_by_visibility(self, visible=True): 258 """Returns all configurators that support setting visibility. 259 260 @param visibility = True if SSID should be visible; False otherwise. 261 262 @returns aps: a set of APConfigurators""" 263 if visible: 264 return set(self.ap_list) 265 266 return set(filter(lambda ap: ap.is_visibility_supported(), 267 self.ap_list)) 268 269 270 def _get_aps_by_mode(self, band, mode): 271 """Returns all configurators that support a given 802.11 mode. 272 273 @param band: an 802.11 band. 274 @param mode: an 802.11 modes. 275 276 @returns aps: a set of APConfigurators. 277 """ 278 if not mode: 279 return set(self.ap_list) 280 281 aps = [] 282 for ap in self.ap_list: 283 modes = ap.get_supported_modes() 284 for d in modes: 285 if d['band'] == band and mode in d['modes']: 286 aps.append(ap) 287 return set(aps) 288 289 290 def _get_aps_by_security(self, security): 291 """Returns all configurators that support a given security mode. 292 293 @param security: the security type 294 295 @returns aps: a set of APConfigurators. 296 """ 297 298 if not security: 299 return set(self.ap_list) 300 301 aps = [] 302 for ap in self.ap_list: 303 if ap.is_security_mode_supported(security): 304 aps.append(ap) 305 return set(aps) 306 307 308 def _get_aps_by_band(self, band, channel=None): 309 """Returns all APs that support a given band. 310 311 @param band: the band desired. 312 313 @returns aps: a set of APConfigurators. 314 """ 315 if not band: 316 return set(self.ap_list) 317 318 aps = [] 319 for ap in self.ap_list: 320 bands_and_channels = ap.get_supported_bands() 321 for d in bands_and_channels: 322 if channel: 323 if d['band'] == band and channel in d['channels']: 324 aps.append(ap) 325 elif d['band'] == band: 326 aps.append(ap) 327 return set(aps) 328 329 330 def get_aps_by_hostnames(self, hostnames, ap_list=None): 331 """Returns specific APs by host name. 332 333 @param hostnames: a list of strings, AP's wan_hostname defined in the AP 334 configuration file. 335 @param ap_list: a list of APConfigurator objects. 336 337 @return a list of APConfigurators. 338 """ 339 if ap_list == None: 340 ap_list = self.ap_list 341 342 aps = [] 343 for ap in ap_list: 344 if ap.host_name in hostnames: 345 logging.info('Found AP by hostname %s', ap.host_name) 346 aps.append(ap) 347 348 return aps 349 350 351 def _get_aps_by_configurator_type(self, configurator_type, ap_list): 352 """Returns APs that match the given configurator type. 353 354 @param configurator_type: the type of configurtor to return. 355 356 @return a list of APConfigurators. 357 """ 358 aps = [] 359 for ap in ap_list: 360 if ap.configurator_type == configurator_type: 361 aps.append(ap) 362 363 return aps 364 365 366 def _get_aps_by_lab_location(self, want_chamber_aps, ap_list): 367 """Returns APs that are inside or outside of the chaos/clique lab. 368 369 @param want_chamber_aps: True to select only APs in the chaos/clique 370 chamber. False to select APs outside of the chaos/clique chamber. 371 372 @return a list of APConfigurators 373 """ 374 aps = [] 375 afe = frontend_wrappers.RetryingAFE(server=_DEFAULT_AUTOTEST_INSTANCE, 376 timeout_min=10, 377 delay_sec=5) 378 if self.test_type == ap_constants.AP_TEST_TYPE_CHAOS: 379 ap_label = 'chaos_ap' 380 lab_label = 'chaos_chamber' 381 else: 382 ap_label = 'clique_ap' 383 lab_label = 'clique_chamber' 384 all_aps = set(afe.get_hostnames(label=ap_label)) 385 chamber_devices = set(afe.get_hostnames(label=lab_label)) 386 chamber_aps = all_aps.intersection(chamber_devices) 387 for ap in ap_list: 388 if want_chamber_aps and ap.host_name in chamber_aps: 389 aps.append(ap) 390 391 if not want_chamber_aps and ap.host_name not in chamber_aps: 392 aps.append(ap) 393 394 return aps 395 396 397 def get_ap_configurators_by_spec(self, spec=None, pre_configure=False): 398 """Returns available configurators meeting spec. 399 400 @param spec: a validated ap_spec object 401 @param pre_configure: boolean, True to set all of the configuration 402 options for the APConfigurator object using the 403 given ap_spec; False otherwise. An ap_spec must 404 be passed for this to have any effect. 405 @returns aps: a list of APConfigurator objects 406 """ 407 if not spec: 408 return self.ap_list 409 410 # APSpec matching is exact. With the exception of lab location, even 411 # if a hostname is passed the capabilities of a given configurator 412 # much match everything in the APSpec. This helps to prevent failures 413 # during the pre-scan phase. 414 aps = self._get_aps_by_band(spec.band, channel=spec.channel) 415 aps &= self._get_aps_by_mode(spec.band, spec.mode) 416 aps &= self._get_aps_by_security(spec.security) 417 aps &= self._get_aps_by_visibility(spec.visible) 418 matching_aps = list(aps) 419 # If APs hostnames are provided, assume the tester knows the location 420 # of the AP and skip AFE calls. 421 if spec.hostnames is None: 422 matching_aps = self._get_aps_by_lab_location(spec.lab_ap, 423 matching_aps) 424 425 if spec.configurator_type != ap_spec.CONFIGURATOR_ANY: 426 matching_aps = self._get_aps_by_configurator_type( 427 spec.configurator_type, matching_aps) 428 if spec.hostnames is not None: 429 matching_aps = self.get_aps_by_hostnames(spec.hostnames, 430 ap_list=matching_aps) 431 if pre_configure: 432 for ap in matching_aps: 433 ap.set_using_ap_spec(spec) 434 return matching_aps 435 436 437 def turn_off_all_routers(self): 438 """Powers down all of the routers.""" 439 ap_power_cartridge = ap_cartridge.APCartridge() 440 for ap in self.ap_list: 441 ap.power_down_router() 442 ap_power_cartridge.push_configurator(ap) 443 ap_power_cartridge.run_configurators() 444