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