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