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