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