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.access_point import setup_ap 28from acts.controllers.ap_lib import hostapd_constants 29from acts.controllers.ap_lib import hostapd_security 30from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device 31from acts_contrib.test_utils.abstract_devices.wlan_device_lib.AbstractDeviceWlanDeviceBaseTest import AbstractDeviceWlanDeviceBaseTest 32from acts_contrib.test_utils.fuchsia import utils 33from acts_contrib.test_utils.tel.tel_test_utils import setup_droid_properties 34from acts.utils import rand_ascii_str 35 36 37class ConnectionStressTest(AbstractDeviceWlanDeviceBaseTest): 38 # Default number of test iterations here. 39 # Override using parameter in config file. 40 # Eg: "connection_stress_test_iterations": "50" 41 num_of_iterations = 10 42 channel_2G = hostapd_constants.AP_DEFAULT_CHANNEL_2G 43 channel_5G = hostapd_constants.AP_DEFAULT_CHANNEL_5G 44 45 def setup_class(self): 46 super().setup_class() 47 self.ssid = rand_ascii_str(10) 48 self.fd = self.fuchsia_devices[0] 49 self.dut = create_wlan_device(self.fd) 50 self.ap = self.access_points[0] 51 self.num_of_iterations = int( 52 self.user_params.get("connection_stress_test_iterations", 53 self.num_of_iterations)) 54 self.log.info('iterations: %d' % self.num_of_iterations) 55 56 def teardown_test(self): 57 self.dut.reset_wifi() 58 self.ap.stop_all_aps() 59 60 def on_fail(self, test_name, begin_time): 61 super().on_fail(test_name, begin_time) 62 self.ap.stop_all_aps() 63 64 def start_ap(self, profile, channel, security=None): 65 """Starts an Access Point 66 67 Args: 68 profile: Profile name such as 'whirlwind' 69 channel: Channel to operate on 70 """ 71 self.log.info('Profile: %s, Channel: %d' % (profile, channel)) 72 setup_ap(access_point=self.ap, 73 profile_name=profile, 74 channel=channel, 75 ssid=self.ssid, 76 security=security) 77 78 def connect_disconnect(self, 79 ap_config, 80 ssid=None, 81 password=None, 82 negative_test=False): 83 """Helper to start an AP, connect DUT to it and disconnect 84 85 Args: 86 ap_config: Dictionary contaning profile name and channel 87 ssid: ssid to connect to 88 password: password for the ssid to connect to 89 """ 90 security_mode = ap_config.get('security_mode', None) 91 target_security = hostapd_constants.SECURITY_STRING_TO_DEFAULT_TARGET_SECURITY.get( 92 security_mode, None) 93 94 if security_mode: 95 security_profile = hostapd_security.Security( 96 security_mode=ap_config['security_mode'], 97 password=ap_config['password']) 98 else: 99 security_profile = None 100 101 # Start AP 102 self.start_ap(ap_config['profile'], 103 ap_config['channel'], 104 security=security_profile) 105 106 failed = False 107 # Connect and Disconnect several times 108 for x in range(0, self.num_of_iterations): 109 if not ssid: 110 ssid = self.ssid 111 if negative_test: 112 if not self.dut.associate(ssid, 113 target_pwd=password, 114 target_security=target_security): 115 self.log.info( 116 'Attempt %d. Did not associate as expected.' % x) 117 else: 118 self.log.error('Attempt %d. Negative test successfully ' 119 'associated. Fail.' % x) 120 failed = True 121 else: 122 # Connect 123 if self.dut.associate(ssid, target_pwd=password): 124 self.log.info('Attempt %d. Successfully associated' % x) 125 else: 126 self.log.error('Attempt %d. Failed to associate.' % x) 127 failed = True 128 # Disconnect 129 self.dut.disconnect() 130 131 # Wait a second before trying again 132 time.sleep(1) 133 134 # Stop AP 135 self.ap.stop_all_aps() 136 if failed: 137 raise signals.TestFailure( 138 'One or more association attempt failed.') 139 140 def test_whirlwind_2g(self): 141 self.connect_disconnect({ 142 'profile': 'whirlwind', 143 'channel': self.channel_2G, 144 'security_mode': None 145 }) 146 147 def test_whirlwind_5g(self): 148 self.connect_disconnect({ 149 'profile': 'whirlwind', 150 'channel': self.channel_5G, 151 'security_mode': None 152 }) 153 154 def test_whirlwind_11ab_2g(self): 155 self.connect_disconnect({ 156 'profile': 'whirlwind_11ab_legacy', 157 'channel': self.channel_2G, 158 'security_mode': None 159 }) 160 161 def test_whirlwind_11ab_5g(self): 162 self.connect_disconnect({ 163 'profile': 'whirlwind_11ab_legacy', 164 'channel': self.channel_5G, 165 'security_mode': None 166 }) 167 168 def test_whirlwind_11ag_2g(self): 169 self.connect_disconnect({ 170 'profile': 'whirlwind_11ag_legacy', 171 'channel': self.channel_2G, 172 'security_mode': None 173 }) 174 175 def test_whirlwind_11ag_5g(self): 176 self.connect_disconnect({ 177 'profile': 'whirlwind_11ag_legacy', 178 'channel': self.channel_5G, 179 'security_mode': None 180 }) 181 182 def test_wrong_ssid_whirlwind_2g(self): 183 self.connect_disconnect( 184 { 185 'profile': 'whirlwind', 186 'channel': self.channel_2G, 187 'security_mode': None 188 }, 189 ssid=rand_ascii_str(20), 190 negative_test=True) 191 192 def test_wrong_ssid_whirlwind_5g(self): 193 self.connect_disconnect( 194 { 195 'profile': 'whirlwind', 196 'channel': self.channel_5G, 197 'security_mode': None 198 }, 199 ssid=rand_ascii_str(20), 200 negative_test=True) 201 202 def test_wrong_password_whirlwind_2g(self): 203 self.connect_disconnect( 204 { 205 'profile': 'whirlwind', 206 'channel': self.channel_2G, 207 'security_mode': hostapd_constants.WPA2_STRING, 208 'password': rand_ascii_str(10) 209 }, 210 password=rand_ascii_str(20), 211 negative_test=True) 212 213 def test_wrong_password_whirlwind_5g(self): 214 self.connect_disconnect( 215 { 216 'profile': 'whirlwind', 217 'channel': self.channel_5G, 218 'security_mode': hostapd_constants.WPA2_STRING, 219 'password': rand_ascii_str(10) 220 }, 221 password=rand_ascii_str(20), 222 negative_test=True) 223