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