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