Home | History | Annotate | Download | only in stress
      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 
     17 package com.android.connectivitymanagertest.stress;
     18 
     19 import android.app.Activity;
     20 import android.content.Context;
     21 import android.net.ConnectivityManager;
     22 import android.net.NetworkInfo;
     23 import android.net.NetworkInfo.State;
     24 import android.net.wifi.ScanResult;
     25 import android.net.wifi.WifiConfiguration;
     26 import android.net.wifi.WifiManager;
     27 import android.os.Bundle;
     28 import android.os.Environment;
     29 import android.os.PowerManager;
     30 import android.os.SystemClock;
     31 import android.provider.Settings;
     32 import android.test.suitebuilder.annotation.LargeTest;
     33 import android.util.Log;
     34 
     35 import com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
     36 import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
     37 import com.android.connectivitymanagertest.WifiConfigurationHelper;
     38 
     39 import java.io.BufferedWriter;
     40 import java.io.File;
     41 import java.io.FileWriter;
     42 import java.io.IOException;
     43 import 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  */
     52 public class WifiStressTest extends ConnectivityManagerTestBase {
     53     private final static long SCREEN_OFF_TIMER = 500; //500ms
     54     /**
     55      * Wi-Fi idle time for default sleep policy
     56      */
     57     private final static long WIFI_IDLE_MS = 15 * 1000;
     58 
     59     /**
     60      * Delay after issuing wifi shutdown.
     61      * The framework keep driver up for at leat 2 minutes to avoid problems
     62      * that a quick shutdown could cause on wext driver and protentially
     63      * on cfg based driver
     64      */
     65     private final static long WIFI_SHUTDOWN_DELAY = 2 * 60 * 1000;
     66 
     67     private final static String OUTPUT_FILE = "WifiStressTestOutput.txt";
     68     private int mReconnectIterations;
     69     private long mWifiSleepTime;
     70     private int mScanIterations;
     71     private String mSsid;
     72     private String mPassword;
     73     private ConnectivityManagerStressTestRunner mRunner;
     74     private BufferedWriter mOutputWriter = null;
     75     private boolean mWifiOnlyFlag;
     76 
     77     public WifiStressTest() {
     78         super(WifiStressTest.class.getSimpleName());
     79     }
     80 
     81     @Override
     82     protected void setUp() throws Exception {
     83         super.setUp();
     84 
     85         mRunner = (ConnectivityManagerStressTestRunner) getInstrumentation();
     86         mReconnectIterations = mRunner.getReconnectIterations();
     87         mSsid = mRunner.getReconnectSsid();
     88         mPassword = mRunner.getReconnectPassword();
     89         mScanIterations = mRunner.getScanIterations();
     90         mWifiSleepTime = mRunner.getSleepTime();
     91         mWifiOnlyFlag = mRunner.isWifiOnly();
     92         logv(String.format("mReconnectIterations(%d), mSsid(%s), mPassword(%s),"
     93             + "mScanIterations(%d), mWifiSleepTime(%d)", mReconnectIterations, mSsid,
     94             mPassword, mScanIterations, mWifiSleepTime));
     95         mOutputWriter = new BufferedWriter(new FileWriter(new File(
     96                 Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
     97         turnScreenOn();
     98         if (!mWifiManager.isWifiEnabled()) {
     99             logv("Enable wi-fi before stress tests.");
    100             if (!enableWifi()) {
    101                 tearDown();
    102                 fail("enable wifi failed.");
    103             }
    104             sleep(SHORT_TIMEOUT, "Interruped while waiting for wifi on");
    105         }
    106     }
    107 
    108     @Override
    109     protected void tearDown() throws Exception {
    110         logv("tearDown()");
    111         if (mOutputWriter != null) {
    112             mOutputWriter.close();
    113         }
    114         super.tearDown();
    115     }
    116 
    117     private void writeOutput(String s) {
    118         logv("write message: " + s);
    119         if (mOutputWriter == null) {
    120             logv("no writer attached to file " + OUTPUT_FILE);
    121             return;
    122         }
    123         try {
    124             mOutputWriter.write(s + "\n");
    125             mOutputWriter.flush();
    126         } catch (IOException e) {
    127             logv("failed to write output.");
    128         }
    129     }
    130 
    131     private void sleep(long sometime, String errorMsg) {
    132         try {
    133             Thread.sleep(sometime);
    134         } catch (InterruptedException e) {
    135             fail(errorMsg);
    136         }
    137     }
    138 
    139     /**
    140      *  Stress Wifi Scanning
    141      *  TODO: test the scanning quality for each frequency band
    142      */
    143     @LargeTest
    144     public void testWifiScanning() {
    145         long scanTimeSum = 0, i, averageScanTime = -1;
    146         int ssidAppearInScanResultsCount = 0; // count times of given ssid appear in scan results.
    147         for (i = 1; i <= mScanIterations; i++) {
    148             logv("testWifiScanning: iteration: " + i);
    149             averageScanTime = scanTimeSum / i;
    150             writeOutput(String.format("iteration %d out of %d", i, mScanIterations));
    151             writeOutput(String.format("average scanning time is %d", averageScanTime));
    152             writeOutput(String.format("ssid appear %d out of %d scan iterations",
    153                     ssidAppearInScanResultsCount, i));
    154             List<ScanResult> scanResultLocal = null;
    155             // wait for a scan result
    156             long start = 0;
    157             synchronized (mWifiScanResultLock) {
    158                 start = SystemClock.uptimeMillis();
    159                 assertTrue("start scan failed", mWifiManager.startScan());
    160                 try {
    161                     mWifiScanResultLock.wait(WAIT_FOR_SCAN_RESULT);
    162                 } catch (InterruptedException e) {
    163                     // ignore
    164                 }
    165                 scanTimeSum += SystemClock.uptimeMillis() - start;
    166                 // save the scan result while in lock
    167                 scanResultLocal = mLastScanResult;
    168             }
    169             if (scanResultLocal == null || scanResultLocal.isEmpty()) {
    170                 fail("Scan results are empty ");
    171             }
    172             logv("size of scan result list: " + scanResultLocal.size());
    173             for (ScanResult sr : scanResultLocal) {
    174                 logv(String.format("scan result: " + sr.toString()));
    175                 if (mSsid.equals(sr.SSID)) {
    176                     ssidAppearInScanResultsCount += 1;
    177                     break;
    178                 }
    179             }
    180         }
    181         Bundle result = new Bundle();
    182         result.putLong("actual-iterations", i - 1);
    183         result.putLong("avg-scan-time", averageScanTime);
    184         result.putInt("ap-discovered", ssidAppearInScanResultsCount);
    185         getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result);
    186         if (i == mScanIterations + 1) {
    187             writeOutput(String.format("iteration %d out of %d", i - 1, mScanIterations));
    188             writeOutput(String.format("average scanning time is %d", scanTimeSum / (i - 1)));
    189             writeOutput(String.format("ssid appear %d out of %d scan iterations",
    190                     ssidAppearInScanResultsCount, i - 1));
    191         }
    192     }
    193 
    194     // Stress Wifi reconnection to secure net after sleep
    195     @LargeTest
    196     public void testWifiReconnectionAfterSleep() {
    197         // set always scan to false
    198         Settings.Global.putInt(mRunner.getContext().getContentResolver(),
    199                 Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
    200         // set wifi sleep policy to never on while in sleep
    201         Settings.Global.putInt(mRunner.getContext().getContentResolver(),
    202                 Settings.Global.WIFI_SLEEP_POLICY, Settings.Global.WIFI_SLEEP_POLICY_DEFAULT);
    203         // set idle timeout for wifi to 15s
    204         Settings.Global.putLong(mRunner.getContext().getContentResolver(),
    205                 Settings.Global.WIFI_IDLE_MS, WIFI_IDLE_MS);
    206 
    207         WifiConfiguration config;
    208         if (mPassword == null) {
    209             config = WifiConfigurationHelper.createOpenConfig(mSsid);
    210         } else {
    211             config = WifiConfigurationHelper.createPskConfig(mSsid, mPassword);
    212         }
    213 
    214         assertTrue("Failed to connect to Wi-Fi network: " + mSsid,
    215                 connectToWifiWithConfiguration(config));
    216         assertTrue("wifi not connected", waitForNetworkState(ConnectivityManager.TYPE_WIFI,
    217                 State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
    218         // Run ping test to verify the data connection
    219         assertTrue("Wi-Fi is connected, but no data connection.", pingTest());
    220 
    221         long i, sum = 0, avgReconnectTime = 0;
    222         for (i = 1; i <= mReconnectIterations; i++) {
    223             // 1. Put device into sleep mode
    224             // 2. Wait for the device to sleep for sometime, verify wi-fi is off and mobile is on.
    225             // 3. Maintain the sleep mode for some time,
    226             // 4. Verify the Wi-Fi is still off, and data is on
    227             // 5. Wake up the device, verify Wi-Fi is enabled and connected.
    228             writeOutput(String.format("iteration %d out of %d",
    229                     i, mReconnectIterations));
    230             logv("iteration: " + i);
    231             turnScreenOff();
    232             // Use clock time since boot for intervals.
    233             long start = SystemClock.uptimeMillis();
    234             PowerManager pm =
    235                 (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
    236             while (pm.isInteractive() &&
    237                     ((SystemClock.uptimeMillis() - start) < SCREEN_OFF_TIMER)) {
    238                 SystemClock.sleep(100);
    239             }
    240             assertFalse("screen still on", pm.isInteractive());
    241             // wait for WiFi timeout
    242             SystemClock.sleep(WIFI_IDLE_MS + WIFI_SHUTDOWN_DELAY);
    243             // below check temporarily disabled due to bug in ConnectivityManager return
    244 //            assertTrue("Wait for Wi-Fi to idle timeout",
    245 //                    waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
    246 //                    6 * SHORT_TIMEOUT));
    247             if (mWifiOnlyFlag) {
    248                 assertTrue("expected wifi disconnect, still has active connection",
    249                         waitUntilNoActiveNetworkConnection(2 * LONG_TIMEOUT));
    250             } else {
    251                 // use long timeout as the pppd startup may take several retries.
    252                 assertTrue("no fallback on mobile or wifi didn't disconnect",
    253                         waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
    254                         2 * LONG_TIMEOUT));
    255             }
    256             SystemClock.sleep(mWifiSleepTime);
    257             // verify the wi-fi is still off and either we have no connectivity or fallback on mobile
    258             if (mWifiOnlyFlag) {
    259                 NetworkInfo ni = mCm.getActiveNetworkInfo();
    260                 if (ni != null) {
    261                     Log.e(mLogTag, "has active network while in wifi sleep: " + ni.toString());
    262                     fail("active network detected");
    263                 }
    264             } else {
    265                 assertEquals("mobile not connected", State.CONNECTED,
    266                         mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState());
    267                 assertTrue("no connectivity over mobile", pingTest());
    268             }
    269 
    270             // Turn screen on again
    271             turnScreenOn();
    272             // Measure the time for Wi-Fi to get connected
    273             long startTime = SystemClock.uptimeMillis();
    274             assertTrue("screen on: wifi not enabled before timeout",
    275                     waitForWifiState(WifiManager.WIFI_STATE_ENABLED, SHORT_TIMEOUT));
    276             assertTrue("screen on: wifi not connected before timeout",
    277                     waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
    278                     LONG_TIMEOUT));
    279             long connectionTime = SystemClock.uptimeMillis() - startTime;
    280             sum += connectionTime;
    281             avgReconnectTime = sum / i;
    282             logv("average reconnection time is: " + avgReconnectTime);
    283 
    284             assertTrue("Reconnect to Wi-Fi network, but no data connection.", pingTest());
    285         }
    286         Bundle result = new Bundle();
    287         result.putLong("actual-iterations", i - 1);
    288         result.putLong("avg-reconnect-time", avgReconnectTime);
    289         getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, result);
    290         if (i == mReconnectIterations + 1) {
    291             writeOutput(String.format("iteration %d out of %d",
    292                     i - 1, mReconnectIterations));
    293         }
    294     }
    295 }
    296