WifiStressTest.java revision 93ca011c60c140facb5a790c25a882a384460a86
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 com.android.connectivitymanagertest.ConnectivityManagerStressTestRunner;
20import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
21
22import android.content.Context;
23import android.net.ConnectivityManager;
24import android.net.NetworkInfo.State;
25import android.net.wifi.ScanResult;
26import android.net.wifi.WifiConfiguration;
27import android.net.wifi.WifiConfiguration.IpAssignment;
28import android.net.wifi.WifiConfiguration.KeyMgmt;
29import android.net.wifi.WifiConfiguration.ProxySettings;
30import android.net.wifi.WifiManager;
31import android.os.Environment;
32import android.os.PowerManager;
33import android.os.SystemClock;
34import android.provider.Settings;
35import android.test.ActivityInstrumentationTestCase2;
36import android.test.suitebuilder.annotation.LargeTest;
37
38import android.util.Log;
39
40import java.io.BufferedWriter;
41import java.io.File;
42import java.io.FileWriter;
43import java.io.IOException;
44import java.util.List;
45
46/**
47 * Stress Wi-Fi connection, scanning and reconnection after sleep.
48 *
49 * To run this stress test suite, type
50 * adb shell am instrument -e class com.android.connectivitymanagertest.stress.WifiStressTest
51 *                  -w com.android.connectivitymanagertest/.ConnectivityManagerStressTestRunner
52 */
53public class WifiStressTest
54    extends ActivityInstrumentationTestCase2<ConnectivityManagerTestActivity> {
55    private final static String TAG = "WifiStressTest";
56
57    /**
58     * Wi-Fi idle time for default sleep policy
59     */
60    private final static long WIFI_IDLE_MS = 5 * 1000;
61
62    /**
63     * The delay for Wi-Fi to get into idle, after screen off + WIFI_IDEL_MS + WIFI_IDLE_DELAY
64     * the Wi-Fi should be in idle mode and device should be in cellular mode.
65     */
66    private final static long WIFI_IDLE_DELAY = 3 * 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 PowerManager.WakeLock wl = null;
77    private BufferedWriter mOutputWriter = null;
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        wl = null;
94        mOutputWriter = new BufferedWriter(new FileWriter(new File(
95                Environment.getExternalStorageDirectory(), OUTPUT_FILE), true));
96        if (!mAct.mWifiManager.isWifiEnabled()) {
97            if (!mAct.enableWifi()) {
98                tearDown();
99                fail("enable wifi failed.");
100            }
101            sleep(ConnectivityManagerTestActivity.SHORT_TIMEOUT,
102                    "Interruped while waiting for wifi on");
103        }
104    }
105
106    @Override
107    public void tearDown() throws Exception {
108        log("tearDown()");
109        if ((wl != null) && wl.isHeld()) {
110            wl.release();
111        }
112        if (mOutputWriter != null) {
113            mOutputWriter.close();
114        }
115        super.tearDown();
116    }
117
118    private void writeOutput(String s) {
119        log("write message: " + s);
120        if (mOutputWriter == null) {
121            log("no writer attached to file " + OUTPUT_FILE);
122            return;
123        }
124        try {
125            mOutputWriter.write(s + "\n");
126            mOutputWriter.flush();
127        } catch (IOException e) {
128            log("failed to write output.");
129        }
130    }
131
132    private void turnScreenOff() {
133        log("Turn screen off");
134        if (wl != null) {
135            log("release wake lock");
136            wl.release();
137        }
138        PowerManager pm =
139            (PowerManager) mRunner.getContext().getSystemService(Context.POWER_SERVICE);
140        pm.goToSleep(SystemClock.uptimeMillis() + 50);
141    }
142
143    private void turnScreenOn() {
144        log("Turn screen on");
145        PowerManager pm =
146            (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
147        wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
148                "wifiStressTest");
149        wl.acquire();
150    }
151
152    public void log(String message) {
153        Log.v(TAG, message);
154    }
155
156    private void sleep(long sometime, String errorMsg) {
157        try {
158            Thread.sleep(sometime);
159        } catch (InterruptedException e) {
160            fail(errorMsg);
161        }
162    }
163
164    /**
165     *  Stress Wifi Scanning
166     *  TODO: test the scanning quality for each frequency band
167     */
168    @LargeTest
169    public void testWifiScanning() {
170        int scanTimeSum = 0;
171        int i;
172        int ssidAppearInScanResultsCount = 0; // count times of given ssid appear in scan results.
173        for (i = 0; i < mScanIterations; i++) {
174            log("testWifiScanning: iteration: " + i);
175            int averageScanTime = 0;
176            if (i > 0) {
177                averageScanTime = scanTimeSum/i;
178            }
179            writeOutput(String.format("iteration %d out of %d",
180                    i, mScanIterations));
181            writeOutput(String.format("average scanning time is %d", averageScanTime));
182            writeOutput(String.format("ssid appear %d out of %d scan iterations",
183                    ssidAppearInScanResultsCount, i));
184            long startTime = System.currentTimeMillis();
185            mAct.scanResultAvailable = false;
186            assertTrue("start scan failed", mAct.mWifiManager.startScanActive());
187            while (true) {
188                if ((System.currentTimeMillis() - startTime) >
189                ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT) {
190                    fail("Wifi scanning takes more than " +
191                            ConnectivityManagerTestActivity.WIFI_SCAN_TIMEOUT + " ms");
192                }
193                synchronized(mAct) {
194                    try {
195                        mAct.wait(ConnectivityManagerTestActivity.WAIT_FOR_SCAN_RESULT);
196                    } catch (InterruptedException e) {
197                        e.printStackTrace();
198                    }
199                    if (mAct.scanResultAvailable) {
200                        long scanTime = (System.currentTimeMillis() - startTime);
201                        scanTimeSum += scanTime;
202                        break;
203                    }
204                }
205            }
206            if ((mAct.mWifiManager.getScanResults() == null) ||
207                    (mAct.mWifiManager.getScanResults().size() <= 0)) {
208                fail("Scan results are empty ");
209            }
210
211            List<ScanResult> netList = mAct.mWifiManager.getScanResults();
212            if (netList != null) {
213                log("size of scan result list: " + netList.size());
214                for (int s = 0; s < netList.size(); s++) {
215                    ScanResult sr= netList.get(s);
216                    log(String.format("scan result for %s is: %s", sr.SSID, sr.toString()));
217                    log(String.format("signal level for %s is %d ", sr.SSID, sr.level));
218                    if (sr.SSID.equals(mSsid)) {
219                        ssidAppearInScanResultsCount += 1;
220                        log("Number of times " + mSsid + " appear in the scan list: " +
221                                ssidAppearInScanResultsCount);
222                        break;
223                    }
224                }
225            }
226        }
227        if (i == mScanIterations) {
228            writeOutput(String.format("iteration %d out of %d",
229                    i, mScanIterations));
230            writeOutput(String.format("average scanning time is %d", scanTimeSum/mScanIterations));
231            writeOutput(String.format("ssid appear %d out of %d scan iterations",
232                    ssidAppearInScanResultsCount, mScanIterations));
233        }
234    }
235
236    // Stress Wifi reconnection to secure net after sleep
237    @LargeTest
238    public void testWifiReconnectionAfterSleep() {
239        int value = Settings.System.getInt(mRunner.getContext().getContentResolver(),
240                Settings.System.WIFI_SLEEP_POLICY, -1);
241        if (value < 0) {
242            Settings.System.putInt(mRunner.getContext().getContentResolver(),
243                    Settings.System.WIFI_SLEEP_POLICY, Settings.System.WIFI_SLEEP_POLICY_DEFAULT);
244            log("set wifi sleep policy to default value");
245        }
246        Settings.Secure.putLong(mRunner.getContext().getContentResolver(),
247                Settings.Secure.WIFI_IDLE_MS, WIFI_IDLE_MS);
248
249        // Connect to a Wi-Fi network
250        turnScreenOn();
251        WifiConfiguration config = new WifiConfiguration();
252        config.SSID = mSsid;
253        config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
254        if (mPassword.matches("[0-9A-Fa-f]{64}")) {
255            config.preSharedKey = mPassword;
256        } else {
257            config.preSharedKey = '"' + mPassword + '"';
258        }
259        config.ipAssignment = IpAssignment.DHCP;
260        config.proxySettings = ProxySettings.NONE;
261
262        assertTrue("Failed to connect to Wi-Fi network: " + mSsid,
263                mAct.connectToWifiWithConfiguration(config));
264        assertTrue(mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
265                ConnectivityManagerTestActivity.SHORT_TIMEOUT));
266        assertTrue(mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
267                ConnectivityManagerTestActivity.LONG_TIMEOUT));
268        int i;
269        for (i = 0; i < mReconnectIterations; i++) {
270            // 1. Put device into sleep
271            // 2. Wait for the device to sleep for sometime, very 3G is connected
272            // 3. Wake up the device
273            writeOutput(String.format("iteration %d out of %d",
274                    i, mReconnectIterations));
275            log("iteration: " + i);
276            turnScreenOff();
277            PowerManager pm =
278                (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
279            assertFalse(pm.isScreenOn());
280            sleep(WIFI_IDLE_MS + WIFI_IDLE_DELAY, "Interruped while wait for wifi to be idle");
281            assertTrue("Wait for Wi-Fi to idle timeout",
282                    mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.DISCONNECTED,
283                    ConnectivityManagerTestActivity.SHORT_TIMEOUT));
284            assertTrue("Wait for cellular connection timeout",
285                    mAct.waitForNetworkState(ConnectivityManager.TYPE_MOBILE, State.CONNECTED,
286                    ConnectivityManagerTestActivity.LONG_TIMEOUT));
287            sleep(mWifiSleepTime + WIFI_IDLE_DELAY, "Interrupted while device is in sleep mode");
288            // Turn screen on again
289            turnScreenOn();
290            assertTrue("Wait for Wi-Fi enable timeout after wake up",
291                    mAct.waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
292                    ConnectivityManagerTestActivity.SHORT_TIMEOUT));
293            assertTrue("Wait for Wi-Fi connection timeout after wake up",
294                    mAct.waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
295                    ConnectivityManagerTestActivity.LONG_TIMEOUT));
296        }
297        if (i == mReconnectIterations) {
298            writeOutput(String.format("iteration %d out of %d",
299                    i, mReconnectIterations));
300        }
301    }
302}
303