1#!/usr/bin/env python3 2# 3# Copyright (C) 2018 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may not 6# use this file except in compliance with the License. You may obtain a copy of 7# the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations under 15# the License. 16""" 17Script for testing WiFi connection and disconnection in a loop 18 19""" 20from acts.base_test import BaseTestClass 21 22import os 23import uuid 24import time 25 26from acts import signals 27from acts.controllers.ap_lib import hostapd_constants 28from acts.controllers.ap_lib import hostapd_security 29from acts.test_utils.abstract_devices.utils_lib.wlan_utils import setup_ap 30from acts.test_utils.abstract_devices.utils_lib.wlan_utils import associate 31from acts.test_utils.abstract_devices.utils_lib.wlan_utils import disconnect 32from acts.test_utils.abstract_devices.wlan_device import create_wlan_device 33from acts.test_utils.fuchsia import utils 34from acts.test_utils.tel.tel_test_utils import setup_droid_properties 35from acts.utils import rand_ascii_str 36 37 38 39class ConnectionStressTest(BaseTestClass): 40 # Default number of test iterations here. 41 # Override using parameter in config file. 42 # Eg: "connection_stress_test_iterations": "50" 43 num_of_iterations = 10 44 channel_2G = hostapd_constants.AP_DEFAULT_CHANNEL_2G 45 channel_5G = hostapd_constants.AP_DEFAULT_CHANNEL_5G 46 47 def setup_class(self): 48 super().setup_class() 49 self.ssid = rand_ascii_str(10) 50 self.fd = self.fuchsia_devices[0] 51 self.dut = create_wlan_device(self.fd) 52 self.ap = self.access_points[0] 53 self.num_of_iterations = int( 54 self.user_params.get("connection_stress_test_iterations", 55 self.num_of_iterations)) 56 self.log.info('iterations: %d' % self.num_of_iterations) 57 58 def teardown_test(self): 59 self.dut.reset_wifi() 60 self.ap.stop_all_aps() 61 62 def start_ap(self, profile, channel, security=None): 63 """Starts an Access Point 64 65 Args: 66 profile: Profile name such as 'whirlwind' 67 channel: Channel to operate on 68 """ 69 self.log.info('Profile: %s, Channel: %d' % (profile, channel)) 70 setup_ap( 71 access_point=self.ap, 72 profile_name=profile, 73 channel=channel, 74 ssid=self.ssid, 75 security=security) 76 77 def connect_disconnect(self, 78 ap_config, 79 ssid=None, 80 password=None, 81 negative_test=False): 82 """Helper to start an AP, connect DUT to it and disconnect 83 84 Args: 85 ap_config: Dictionary contaning profile name and channel 86 ssid: ssid to connect to 87 password: password for the ssid to connect to 88 """ 89 # Start AP 90 self.start_ap(ap_config['profile'], 91 ap_config['channel'], 92 ap_config['security']) 93 94 failed = False 95 # Connect and Disconnect several times 96 for x in range(0, self.num_of_iterations): 97 if not ssid: 98 ssid = self.ssid 99 if negative_test: 100 if not associate(self.dut, ssid=ssid, password=password): 101 self.log.info('Attempt %d. Did not associate as expected.' 102 % x) 103 else: 104 self.log.error('Attempt %d. Negative test successfully ' 105 'associated. Fail.' % x) 106 failed = True 107 else: 108 # Connect 109 if associate(self.dut, ssid=ssid, password=password): 110 self.log.info('Attempt %d. Successfully associated' % x) 111 else: 112 self.log.error('Attempt %d. Failed to associate.' % x) 113 failed = True 114 # Disconnect 115 disconnect(self.dut) 116 117 # Wait a second before trying again 118 time.sleep(1) 119 120 # Stop AP 121 self.ap.stop_all_aps() 122 if failed: 123 raise signals.TestFailure('One or more association attempt failed.') 124 125 def test_whirlwind_2g(self): 126 self.connect_disconnect({ 127 'profile': 'whirlwind', 128 'channel': self.channel_2G, 129 'security': None 130 }) 131 132 def test_whirlwind_5g(self): 133 self.connect_disconnect({ 134 'profile': 'whirlwind', 135 'channel': self.channel_5G, 136 'security': None 137 }) 138 139 def test_whirlwind_11ab_2g(self): 140 self.connect_disconnect({ 141 'profile': 'whirlwind_11ab_legacy', 142 'channel': self.channel_2G, 143 'security': None 144 }) 145 146 def test_whirlwind_11ab_5g(self): 147 self.connect_disconnect({ 148 'profile': 'whirlwind_11ab_legacy', 149 'channel': self.channel_5G, 150 'security': None 151 }) 152 153 def test_whirlwind_11ag_2g(self): 154 self.connect_disconnect({ 155 'profile': 'whirlwind_11ag_legacy', 156 'channel': self.channel_2G, 157 'security': None 158 }) 159 160 def test_whirlwind_11ag_5g(self): 161 self.connect_disconnect({ 162 'profile': 'whirlwind_11ag_legacy', 163 'channel': self.channel_5G, 164 'security': None 165 }) 166 167 def test_wrong_ssid_whirlwind_2g(self): 168 self.connect_disconnect( 169 { 170 'profile': 'whirlwind', 171 'channel': self.channel_2G, 172 'security': None 173 }, 174 ssid=rand_ascii_str(20), 175 negative_test=True 176 ) 177 178 def test_wrong_ssid_whirlwind_5g(self): 179 self.connect_disconnect( 180 { 181 'profile': 'whirlwind', 182 'channel': self.channel_5G, 183 'security': None 184 }, 185 ssid=rand_ascii_str(20), 186 negative_test=True 187 ) 188 189 def test_wrong_password_whirlwind_2g(self): 190 self.connect_disconnect( 191 { 192 'profile': 'whirlwind', 193 'channel': self.channel_2G, 194 'security': hostapd_security.Security( 195 security_mode='wpa2', 196 password=rand_ascii_str(10)) 197 }, 198 password=rand_ascii_str(20), 199 negative_test=True 200 ) 201 202 def test_wrong_password_whirlwind_5g(self): 203 self.connect_disconnect( 204 { 205 'profile': 'whirlwind', 206 'channel': self.channel_5G, 207 'security': hostapd_security.Security( 208 security_mode='wpa2', 209 password=rand_ascii_str(10)) 210 }, 211 password=rand_ascii_str(20), 212 negative_test=True 213 )