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