WifiStressTest.java revision 678979748585c5903125a404e448ad6c111dedad
1/* 2 * Copyright (C) 2010, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.connectivitymanagertest.stress; 18 19import android.content.Context; 20import android.net.ConnectivityManager; 21import android.net.NetworkInfo.State; 22import android.net.wifi.ScanResult; 23import android.net.wifi.WifiConfiguration; 24import android.net.wifi.WifiConfiguration.IpAssignment; 25import android.net.wifi.WifiConfiguration.KeyMgmt; 26import android.net.wifi.WifiConfiguration.ProxySettings; 27import android.net.wifi.WifiManager; 28import android.os.Environment; 29import android.os.PowerManager; 30import android.os.SystemClock; 31import android.provider.Settings; 32import android.view.KeyEvent; 33import android.test.suitebuilder.annotation.LargeTest; 34import android.util.Log; 35 36import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner; 37import com.android.connectivitymanagertest.ConnectivityManagerTestBase; 38 39import java.io.BufferedWriter; 40import java.io.File; 41import java.io.FileWriter; 42import java.io.IOException; 43import java.util.List; 44 45/** 46 * Stress Wi-Fi connection, scanning and reconnection after sleep. 47 * 48 * To run this stress test suite, type 49 * adb shell am instrument -e class com.android.connectivitymanagertest.stress.WifiStressTest 50 * -w com.android.connectivitymanagertest/.ConnectivityManagerStressTestRunner 51 */ 52public class WifiStressTest 53 extends ConnectivityManagerTestBase { 54 private final static String TAG = "WifiStressTest"; 55 56 private final static long SCREEN_OFF_TIMER = 500; //500ms 57 /** 58 * Wi-Fi idle time for default sleep policy 59 */ 60 private final static long WIFI_IDLE_MS = 60 * 1000; 61 62 /** 63 * Delay after issuing wifi shutdown. 64 * The framework keep driver up for at leat 2 minutes to avoid problems 65 * that a quick shutdown could cause on wext driver and protentially 66 * on cfg based driver 67 */ 68 private final static long WIFI_SHUTDOWN_DELAY = 2 * 60 * 1000; 69 70 private final static String OUTPUT_FILE = "WifiStressTestOutput.txt"; 71 private int mReconnectIterations; 72 private int mWifiSleepTime; 73 private int mScanIterations; 74 private String mSsid; 75 private String mPassword; 76 private ConnectivityManagerStressTestRunner mRunner; 77 private BufferedWriter mOutputWriter = null; 78 private boolean mWifiOnlyFlag; 79 80 @Override 81 public void setUp() throws Exception { 82 super.setUp(); 83 84 mRunner = (ConnectivityManagerStressTestRunner) getInstrumentation(); 85 mReconnectIterations = mRunner.mReconnectIterations; 86 mSsid = mRunner.mReconnectSsid; 87 mPassword = mRunner.mReconnectPassword; 88 mScanIterations = mRunner.mScanIterations; 89 mWifiSleepTime = mRunner.mSleepTime; 90 mWifiOnlyFlag = mRunner.mWifiOnlyFlag; 91 log(String.format("mReconnectIterations(%d), mSsid(%s), mPassword(%s)," 92 + "mScanIterations(%d), mWifiSleepTime(%d)", mReconnectIterations, mSsid, 93 mPassword, mScanIterations, mWifiSleepTime)); 94 mOutputWriter = new BufferedWriter(new FileWriter(new File( 95 Environment.getExternalStorageDirectory(), OUTPUT_FILE), true)); 96 turnScreenOn(); 97 if (!mWifiManager.isWifiEnabled()) { 98 log("Enable wi-fi before stress tests."); 99 if (!enableWifi()) { 100 tearDown(); 101 fail("enable wifi failed."); 102 } 103 sleep(SHORT_TIMEOUT, "Interruped while waiting for wifi on"); 104 } 105 } 106 107 @Override 108 public void tearDown() throws Exception { 109 log("tearDown()"); 110 if (mOutputWriter != null) { 111 mOutputWriter.close(); 112 } 113 super.tearDown(); 114 } 115 116 private void writeOutput(String s) { 117 log("write message: " + s); 118 if (mOutputWriter == null) { 119 log("no writer attached to file " + OUTPUT_FILE); 120 return; 121 } 122 try { 123 mOutputWriter.write(s + "\n"); 124 mOutputWriter.flush(); 125 } catch (IOException e) { 126 log("failed to write output."); 127 } 128 } 129 130 public void log(String message) { 131 Log.v(TAG, message); 132 } 133 134 private void sleep(long sometime, String errorMsg) { 135 try { 136 Thread.sleep(sometime); 137 } catch (InterruptedException e) { 138 fail(errorMsg); 139 } 140 } 141 142 /** 143 * Stress Wifi Scanning 144 * TODO: test the scanning quality for each frequency band 145 */ 146 @LargeTest 147 public void testWifiScanning() { 148 int scanTimeSum = 0; 149 int i; 150 int ssidAppearInScanResultsCount = 0; // count times of given ssid appear in scan results. 151 for (i = 0; i < mScanIterations; i++) { 152 log("testWifiScanning: iteration: " + i); 153 int averageScanTime = 0; 154 if (i > 0) { 155 averageScanTime = scanTimeSum/i; 156 } 157 writeOutput(String.format("iteration %d out of %d", 158 i, mScanIterations)); 159 writeOutput(String.format("average scanning time is %d", averageScanTime)); 160 writeOutput(String.format("ssid appear %d out of %d scan iterations", 161 ssidAppearInScanResultsCount, i)); 162 long startTime = SystemClock.uptimeMillis(); 163 scanResultAvailable = false; 164 assertTrue("start scan failed", mWifiManager.startScan()); 165 while (true) { 166 if ((SystemClock.uptimeMillis() - startTime) > 167 WIFI_SCAN_TIMEOUT) { 168 fail("Wifi scanning takes more than " + WIFI_SCAN_TIMEOUT + " ms"); 169 } 170 synchronized(this) { 171 try { 172 wait(WAIT_FOR_SCAN_RESULT); 173 } catch (InterruptedException e) { 174 e.printStackTrace(); 175 } 176 if (scanResultAvailable) { 177 long scanTime = (SystemClock.uptimeMillis() - startTime); 178 scanTimeSum += scanTime; 179 break; 180 } 181 } 182 } 183 if ((mWifiManager.getScanResults() == null) || 184 (mWifiManager.getScanResults().size() <= 0)) { 185 fail("Scan results are empty "); 186 } 187 188 List<ScanResult> netList = mWifiManager.getScanResults(); 189 if (netList != null) { 190 log("size of scan result list: " + netList.size()); 191 for (int s = 0; s < netList.size(); s++) { 192 ScanResult sr= netList.get(s); 193 log(String.format("scan result for %s is: %s", sr.SSID, sr.toString())); 194 log(String.format("signal level for %s is %d ", sr.SSID, sr.level)); 195 if (sr.SSID.equals(mSsid)) { 196 ssidAppearInScanResultsCount += 1; 197 log("Number of times " + mSsid + " appear in the scan list: " + 198 ssidAppearInScanResultsCount); 199 break; 200 } 201 } 202 } 203 } 204 if (i == mScanIterations) { 205 writeOutput(String.format("iteration %d out of %d", 206 i, mScanIterations)); 207 writeOutput(String.format("average scanning time is %d", scanTimeSum/mScanIterations)); 208 writeOutput(String.format("ssid appear %d out of %d scan iterations", 209 ssidAppearInScanResultsCount, mScanIterations)); 210 } 211 } 212 213 // Stress Wifi reconnection to secure net after sleep 214 @LargeTest 215 public void testWifiReconnectionAfterSleep() { 216 int value = Settings.Global.getInt(mRunner.getContext().getContentResolver(), 217 Settings.Global.WIFI_SLEEP_POLICY, -1); 218 log("wifi sleep policy is: " + value); 219 if (value != Settings.Global.WIFI_SLEEP_POLICY_DEFAULT) { 220 Settings.Global.putInt(mRunner.getContext().getContentResolver(), 221 Settings.Global.WIFI_SLEEP_POLICY, Settings.Global.WIFI_SLEEP_POLICY_DEFAULT); 222 log("set wifi sleep policy to default value"); 223 } 224 Settings.Global.putLong(mRunner.getContext().getContentResolver(), 225 Settings.Global.WIFI_IDLE_MS, WIFI_IDLE_MS); 226 227 // Connect to a Wi-Fi network 228 WifiConfiguration config = new WifiConfiguration(); 229 config.SSID = mSsid; 230 config.allowedKeyManagement.set(KeyMgmt.WPA_PSK); 231 if (mPassword.matches("[0-9A-Fa-f]{64}")) { 232 config.preSharedKey = mPassword; 233 } else { 234 config.preSharedKey = '"' + mPassword + '"'; 235 } 236 config.ipAssignment = IpAssignment.DHCP; 237 config.proxySettings = ProxySettings.NONE; 238 239 assertTrue("Failed to connect to Wi-Fi network: " + mSsid, 240 connectToWifiWithConfiguration(config)); 241 assertTrue(waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 242 SHORT_TIMEOUT)); 243 assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED, 244 WIFI_CONNECTION_TIMEOUT)); 245 // Run ping test to verify the data connection 246 assertTrue("Wi-Fi is connected, but no data connection.", pingTest(null)); 247 248 int i; 249 long sum = 0; 250 for (i = 0; i < mReconnectIterations; i++) { 251 // 1. Put device into sleep mode 252 // 2. Wait for the device to sleep for sometime, verify wi-fi is off and mobile is on. 253 // 3. Maintain the sleep mode for some time, 254 // 4. Verify the Wi-Fi is still off, and data is on 255 // 5. Wake up the device, verify Wi-Fi is enabled and connected. 256 writeOutput(String.format("iteration %d out of %d", 257 i, mReconnectIterations)); 258 log("iteration: " + i); 259 turnScreenOff(); 260 // Use clock time since boot for intervals. 261 long start = SystemClock.uptimeMillis(); 262 PowerManager pm = 263 (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE); 264 while (pm.isScreenOn() && ((SystemClock.uptimeMillis() - start) < SCREEN_OFF_TIMER)) { 265 sleep(100, "wait for screen off"); 266 } 267 assertFalse(pm.isScreenOn()); 268 sleep(WIFI_IDLE_MS + WIFI_SHUTDOWN_DELAY, "Interruped while wait for wifi to be idle"); 269 assertTrue("Wait for Wi-Fi to idle timeout", 270 waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED, 271 6 * SHORT_TIMEOUT)); 272 if (!mWifiOnlyFlag) { 273 // use long timeout as the pppd startup may take several retries. 274 assertTrue("Wait for cellular connection timeout", 275 waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED, 276 2 * LONG_TIMEOUT)); 277 } 278 sleep(mWifiSleepTime, "Interrupted while device is in sleep mode"); 279 // Verify the wi-fi is still off and data connection is on 280 assertEquals("Wi-Fi is reconnected", State.DISCONNECTED, 281 mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getState()); 282 283 if (!mWifiOnlyFlag) { 284 assertEquals("Cellular connection is down", State.CONNECTED, 285 mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState()); 286 assertTrue("Mobile is connected, but no data connection.", pingTest(null)); 287 } 288 289 // Turn screen on again 290 turnScreenOn(); 291 // Wait for 2 seconds for the lock screen 292 sleep(2 * 1000, "wait 2 seconds for lock screen"); 293 // Disable lock screen by inject menu key event 294 mRunner.sendKeyDownUpSync(KeyEvent.KEYCODE_MENU); 295 296 // Measure the time for Wi-Fi to get connected 297 long startTime = SystemClock.uptimeMillis(); 298 assertTrue("Wait for Wi-Fi enable timeout after wake up", 299 waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 300 SHORT_TIMEOUT)); 301 assertTrue("Wait for Wi-Fi connection timeout after wake up", 302 waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED, 303 WIFI_CONNECTION_TIMEOUT)); 304 long connectionTime = SystemClock.uptimeMillis() - startTime; 305 sum += connectionTime; 306 log("average reconnection time is: " + sum/(i+1)); 307 308 assertTrue("Reconnect to Wi-Fi network, but no data connection.", pingTest(null)); 309 } 310 if (i == mReconnectIterations) { 311 writeOutput(String.format("iteration %d out of %d", 312 i, mReconnectIterations)); 313 } 314 } 315} 316