WifiMetricsTest.java revision 1c50de232acb3d6148c454941a6b9a79e0663b81
1/*
2 * Copyright (C) 2016 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 */
16package com.android.server.wifi;
17
18import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.assertTrue;
20import static org.mockito.Mockito.*;
21
22import android.net.wifi.ScanResult;
23import android.net.wifi.WifiConfiguration;
24import android.test.suitebuilder.annotation.SmallTest;
25import android.util.Base64;
26
27import com.android.server.wifi.hotspot2.NetworkDetail;
28
29import org.junit.Before;
30import org.junit.Test;
31import org.mockito.Mock;
32import org.mockito.MockitoAnnotations;
33
34import java.io.ByteArrayOutputStream;
35import java.io.PrintWriter;
36import java.util.regex.Matcher;
37import java.util.regex.Pattern;
38
39/**
40 * Unit tests for {@link com.android.server.wifi.WifiMetrics}.
41 */
42@SmallTest
43public class WifiMetricsTest {
44
45    WifiMetrics mWifiMetrics;
46    WifiMetricsProto.WifiLog mDeserializedWifiMetrics;
47    @Mock Clock mClock;
48
49    @Before
50    public void setUp() throws Exception {
51        MockitoAnnotations.initMocks(this);
52        mDeserializedWifiMetrics = null;
53        when(mClock.elapsedRealtime()).thenReturn((long) 0);
54        mWifiMetrics = new WifiMetrics(mClock);
55    }
56
57    /**
58     * Test that startConnectionEvent and endConnectionEvent can be called repeatedly and out of
59     * order. Only tests no exception occurs. Creates 3 ConnectionEvents.
60     */
61    @Test
62    public void startAndEndConnectionEventSucceeds() throws Exception {
63        //Start and end Connection event
64        mWifiMetrics.startConnectionEvent(null, "RED",
65                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
66        mWifiMetrics.endConnectionEvent(
67                WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
68                WifiMetricsProto.ConnectionEvent.HLF_DHCP);
69        //end Connection event without starting one
70        mWifiMetrics.endConnectionEvent(
71                WifiMetrics.ConnectionEvent.FAILURE_AUTHENTICATION_FAILURE,
72                WifiMetricsProto.ConnectionEvent.HLF_DHCP);
73        //start two ConnectionEvents in a row
74        mWifiMetrics.startConnectionEvent(null, "BLUE",
75                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
76        mWifiMetrics.startConnectionEvent(null, "GREEN",
77                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
78    }
79
80    private static final long TEST_RECORD_DURATION_SEC = 12 * 60 * 60;
81    private static final long TEST_RECORD_DURATION_MILLIS = TEST_RECORD_DURATION_SEC * 1000;
82
83    /**
84     * Simulate how dumpsys gets the proto from mWifiMetrics, filter the proto bytes out and
85     * deserialize them into mDeserializedWifiMetrics
86     */
87    public void dumpProtoAndDeserialize() throws Exception {
88        ByteArrayOutputStream stream = new ByteArrayOutputStream();
89        PrintWriter writer = new PrintWriter(stream);
90        String[] args = new String[0];
91
92        when(mClock.elapsedRealtime()).thenReturn(TEST_RECORD_DURATION_MILLIS);
93        //Test proto dump, by passing in proto arg option
94        args = new String[]{WifiMetrics.PROTO_DUMP_ARG};
95        mWifiMetrics.dump(null, writer, args);
96        writer.flush();
97        Pattern pattern = Pattern.compile(
98                "(?<=WifiMetrics:\\n)([\\s\\S]*)(?=EndWifiMetrics)");
99        Matcher matcher = pattern.matcher(stream.toString());
100        assertTrue("Proto Byte string found in WifiMetrics.dump():\n" + stream.toString(),
101                matcher.find());
102        String protoByteString = matcher.group(1);
103        byte[] protoBytes = Base64.decode(protoByteString, Base64.DEFAULT);
104        mDeserializedWifiMetrics = WifiMetricsProto.WifiLog.parseFrom(protoBytes);
105    }
106
107    /** Verifies that dump() includes the expected header */
108    @Test
109    public void stateDumpIncludesHeader() throws Exception {
110        assertStringContains(getStateDump(), "WifiMetrics");
111    }
112
113    /** Verifies that dump() includes correct alert count when there are no alerts. */
114    @Test
115    public void stateDumpAlertCountIsCorrectWithNoAlerts() throws Exception {
116        assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=()");
117    }
118
119    /** Verifies that dump() includes correct alert count when there is one alert. */
120    @Test
121    public void stateDumpAlertCountIsCorrectWithOneAlert() throws Exception {
122        mWifiMetrics.incrementAlertReasonCount(1);
123        assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,1)");
124    }
125
126    /** Verifies that dump() includes correct alert count when there are multiple alerts. */
127    @Test
128    public void stateDumpAlertCountIsCorrectWithMultipleAlerts() throws Exception {
129        mWifiMetrics.incrementAlertReasonCount(1);
130        mWifiMetrics.incrementAlertReasonCount(1);
131        mWifiMetrics.incrementAlertReasonCount(16);
132        assertStringContains(getStateDump(), "mWifiLogProto.alertReasonCounts=(1,2),(16,1)");
133    }
134
135    @Test
136    public void testDumpProtoAndDeserialize() throws Exception {
137        setAndIncrementMetrics();
138        dumpProtoAndDeserialize();
139        assertDeserializedMetricsCorrect();
140    }
141
142    private static final int NUM_SAVED_NETWORKS = 1;
143    private static final int NUM_OPEN_NETWORKS = 2;
144    private static final int NUM_PERSONAL_NETWORKS = 3;
145    private static final int NUM_ENTERPRISE_NETWORKS = 5;
146    private static final boolean TEST_VAL_IS_LOCATION_ENABLED = true;
147    private static final boolean IS_SCANNING_ALWAYS_ENABLED = true;
148    private static final int NUM_NEWTORKS_ADDED_BY_USER = 13;
149    private static final int NUM_NEWTORKS_ADDED_BY_APPS = 17;
150    private static final int NUM_EMPTY_SCAN_RESULTS = 19;
151    private static final int NUM_NON_EMPTY_SCAN_RESULTS = 23;
152    private static final int NUM_SCAN_UNKNOWN = 1;
153    private static final int NUM_SCAN_SUCCESS = 2;
154    private static final int NUM_SCAN_FAILURE_INTERRUPTED = 3;
155    private static final int NUM_SCAN_FAILURE_INVALID_CONFIGURATION = 5;
156    private static final int NUM_WIFI_UNKNOWN_SCREEN_OFF = 3;
157    private static final int NUM_WIFI_UNKNOWN_SCREEN_ON = 5;
158    private static final int NUM_WIFI_ASSOCIATED_SCREEN_OFF = 7;
159    private static final int NUM_WIFI_ASSOCIATED_SCREEN_ON = 11;
160    private static final int NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD = 11;
161    private static final int NUM_CONNECTIVITY_WATCHDOG_PNO_BAD = 12;
162    private static final int NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD = 13;
163    private static final int NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD = 14;
164    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS = 1;
165    private static final int NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL = 2;
166    private static final int NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL = 3;
167    private static final int NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL = 4;
168    private static final int NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL = 5;
169    private static final int NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL = 6;
170    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION = 7;
171    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION = 8;
172    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP = 9;
173    private static final int NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER = 10;
174    private static final int NUM_LAST_RESORT_WATCHDOG_SUCCESSES = 5;
175    private static final int NUM_RSSI_LEVELS_TO_INCREMENT = 20;
176    private static final int FIRST_RSSI_LEVEL = -80;
177    /**
178     * Set simple metrics, increment others
179     */
180    public void setAndIncrementMetrics() throws Exception {
181        mWifiMetrics.setNumSavedNetworks(NUM_SAVED_NETWORKS);
182        mWifiMetrics.setNumOpenNetworks(NUM_OPEN_NETWORKS);
183        mWifiMetrics.setNumPersonalNetworks(NUM_PERSONAL_NETWORKS);
184        mWifiMetrics.setNumEnterpriseNetworks(NUM_ENTERPRISE_NETWORKS);
185        mWifiMetrics.setNumNetworksAddedByUser(NUM_NEWTORKS_ADDED_BY_USER);
186        mWifiMetrics.setNumNetworksAddedByApps(NUM_NEWTORKS_ADDED_BY_APPS);
187        mWifiMetrics.setIsLocationEnabled(TEST_VAL_IS_LOCATION_ENABLED);
188        mWifiMetrics.setIsScanningAlwaysEnabled(IS_SCANNING_ALWAYS_ENABLED);
189
190        for (int i = 0; i < NUM_EMPTY_SCAN_RESULTS; i++) {
191            mWifiMetrics.incrementEmptyScanResultCount();
192        }
193        for (int i = 0; i < NUM_NON_EMPTY_SCAN_RESULTS; i++) {
194            mWifiMetrics.incrementNonEmptyScanResultCount();
195        }
196        mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_UNKNOWN,
197                NUM_SCAN_UNKNOWN);
198        mWifiMetrics.incrementScanReturnEntry(WifiMetricsProto.WifiLog.SCAN_SUCCESS,
199                NUM_SCAN_SUCCESS);
200        mWifiMetrics.incrementScanReturnEntry(
201                WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED,
202                NUM_SCAN_FAILURE_INTERRUPTED);
203        mWifiMetrics.incrementScanReturnEntry(
204                WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION,
205                NUM_SCAN_FAILURE_INVALID_CONFIGURATION);
206        for (int i = 0; i < NUM_WIFI_UNKNOWN_SCREEN_OFF; i++) {
207            mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN,
208                    false);
209        }
210        for (int i = 0; i < NUM_WIFI_UNKNOWN_SCREEN_ON; i++) {
211            mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_UNKNOWN,
212                    true);
213        }
214        for (int i = 0; i < NUM_WIFI_ASSOCIATED_SCREEN_OFF; i++) {
215            mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED,
216                    false);
217        }
218        for (int i = 0; i < NUM_WIFI_ASSOCIATED_SCREEN_ON; i++) {
219            mWifiMetrics.incrementWifiSystemScanStateCount(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED,
220                    true);
221        }
222        for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD; i++) {
223            mWifiMetrics.incrementNumConnectivityWatchdogPnoGood();
224        }
225        for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_PNO_BAD; i++) {
226            mWifiMetrics.incrementNumConnectivityWatchdogPnoBad();
227        }
228        for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD; i++) {
229            mWifiMetrics.incrementNumConnectivityWatchdogBackgroundGood();
230        }
231        for (int i = 0; i < NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD; i++) {
232            mWifiMetrics.incrementNumConnectivityWatchdogBackgroundBad();
233        }
234        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS; i++) {
235            mWifiMetrics.incrementNumLastResortWatchdogTriggers();
236        }
237        mWifiMetrics.addCountToNumLastResortWatchdogBadAssociationNetworksTotal(
238                NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL);
239        mWifiMetrics.addCountToNumLastResortWatchdogBadAuthenticationNetworksTotal(
240                NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL);
241        mWifiMetrics.addCountToNumLastResortWatchdogBadDhcpNetworksTotal(
242                NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL);
243        mWifiMetrics.addCountToNumLastResortWatchdogBadOtherNetworksTotal(
244                NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL);
245        mWifiMetrics.addCountToNumLastResortWatchdogAvailableNetworksTotal(
246                NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL);
247        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION; i++) {
248            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAssociation();
249        }
250        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION; i++) {
251            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadAuthentication();
252        }
253        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP; i++) {
254            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadDhcp();
255        }
256        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER; i++) {
257            mWifiMetrics.incrementNumLastResortWatchdogTriggersWithBadOther();
258        }
259        for (int i = 0; i < NUM_LAST_RESORT_WATCHDOG_SUCCESSES; i++) {
260            mWifiMetrics.incrementNumLastResortWatchdogSuccesses();
261        }
262        for (int i = 0; i < NUM_RSSI_LEVELS_TO_INCREMENT; i++) {
263            for (int j = 0; j <= i; j++) {
264                mWifiMetrics.incrementRssiPollRssiCount(FIRST_RSSI_LEVEL + i);
265            }
266        }
267        // Test alert-reason clamping.
268        mWifiMetrics.incrementAlertReasonCount(WifiLoggerHal.WIFI_ALERT_REASON_MIN - 1);
269        mWifiMetrics.incrementAlertReasonCount(WifiLoggerHal.WIFI_ALERT_REASON_MAX + 1);
270        // Simple cases for alert reason.
271        mWifiMetrics.incrementAlertReasonCount(1);
272        mWifiMetrics.incrementAlertReasonCount(1);
273        mWifiMetrics.incrementAlertReasonCount(1);
274        mWifiMetrics.incrementAlertReasonCount(2);
275    }
276
277    /**
278     * Assert that values in deserializedWifiMetrics match those set in 'setAndIncrementMetrics'
279     */
280    public void assertDeserializedMetricsCorrect() throws Exception {
281        assertEquals("mDeserializedWifiMetrics.numSavedNetworks == NUM_SAVED_NETWORKS",
282                mDeserializedWifiMetrics.numSavedNetworks, NUM_SAVED_NETWORKS);
283        assertEquals("mDeserializedWifiMetrics.numOpenNetworks == NUM_OPEN_NETWORKS",
284                mDeserializedWifiMetrics.numOpenNetworks, NUM_OPEN_NETWORKS);
285        assertEquals("mDeserializedWifiMetrics.numPersonalNetworks == NUM_PERSONAL_NETWORKS",
286                mDeserializedWifiMetrics.numPersonalNetworks, NUM_PERSONAL_NETWORKS);
287        assertEquals("mDeserializedWifiMetrics.numEnterpriseNetworks "
288                        + "== NUM_ENTERPRISE_NETWORKS",
289                mDeserializedWifiMetrics.numEnterpriseNetworks, NUM_ENTERPRISE_NETWORKS);
290        assertEquals("mDeserializedWifiMetrics.numNetworksAddedByUser "
291                        + "== NUM_NEWTORKS_ADDED_BY_USER",
292                mDeserializedWifiMetrics.numNetworksAddedByUser, NUM_NEWTORKS_ADDED_BY_USER);
293        assertEquals("mDeserializedWifiMetrics.numNetworksAddedByApps "
294                        + "== NUM_NEWTORKS_ADDED_BY_APPS",
295                mDeserializedWifiMetrics.numNetworksAddedByApps, NUM_NEWTORKS_ADDED_BY_APPS);
296        assertEquals("mDeserializedWifiMetrics.isLocationEnabled == TEST_VAL_IS_LOCATION_ENABLED",
297                mDeserializedWifiMetrics.isLocationEnabled, TEST_VAL_IS_LOCATION_ENABLED);
298        assertEquals("mDeserializedWifiMetrics.isScanningAlwaysEnabled "
299                        + "== IS_SCANNING_ALWAYS_ENABLED",
300                mDeserializedWifiMetrics.isScanningAlwaysEnabled, IS_SCANNING_ALWAYS_ENABLED);
301        assertEquals("mDeserializedWifiMetrics.numEmptyScanResults == NUM_EMPTY_SCAN_RESULTS",
302                mDeserializedWifiMetrics.numEmptyScanResults, NUM_EMPTY_SCAN_RESULTS);
303        assertEquals("mDeserializedWifiMetrics.numNonEmptyScanResults == "
304                        + "NUM_NON_EMPTY_SCAN_RESULTS",
305                mDeserializedWifiMetrics.numNonEmptyScanResults, NUM_NON_EMPTY_SCAN_RESULTS);
306        assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_UNKNOWN,
307                NUM_SCAN_UNKNOWN);
308        assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_SUCCESS,
309                NUM_SCAN_SUCCESS);
310        assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_FAILURE_INTERRUPTED,
311                NUM_SCAN_FAILURE_INTERRUPTED);
312        assertScanReturnEntryEquals(WifiMetricsProto.WifiLog.SCAN_FAILURE_INVALID_CONFIGURATION,
313                NUM_SCAN_FAILURE_INVALID_CONFIGURATION);
314        assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, false,
315                NUM_WIFI_UNKNOWN_SCREEN_OFF);
316        assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_UNKNOWN, true,
317                NUM_WIFI_UNKNOWN_SCREEN_ON);
318        assertSystemStateEntryEquals(
319                WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, false, NUM_WIFI_ASSOCIATED_SCREEN_OFF);
320        assertSystemStateEntryEquals(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED, true,
321                NUM_WIFI_ASSOCIATED_SCREEN_ON);
322        assertEquals(mDeserializedWifiMetrics.numConnectivityWatchdogPnoGood,
323                NUM_CONNECTIVITY_WATCHDOG_PNO_GOOD);
324        assertEquals(mDeserializedWifiMetrics.numConnectivityWatchdogPnoBad,
325                NUM_CONNECTIVITY_WATCHDOG_PNO_BAD);
326        assertEquals(mDeserializedWifiMetrics.numConnectivityWatchdogBackgroundGood,
327                NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_GOOD);
328        assertEquals(mDeserializedWifiMetrics.numConnectivityWatchdogBackgroundBad,
329                NUM_CONNECTIVITY_WATCHDOG_BACKGROUND_BAD);
330        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS,
331                mDeserializedWifiMetrics.numLastResortWatchdogTriggers);
332        assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_ASSOCIATION_NETWORKS_TOTAL,
333                mDeserializedWifiMetrics.numLastResortWatchdogBadAssociationNetworksTotal);
334        assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_AUTHENTICATION_NETWORKS_TOTAL,
335                mDeserializedWifiMetrics.numLastResortWatchdogBadAuthenticationNetworksTotal);
336        assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_DHCP_NETWORKS_TOTAL,
337                mDeserializedWifiMetrics.numLastResortWatchdogBadDhcpNetworksTotal);
338        assertEquals(NUM_LAST_RESORT_WATCHDOG_BAD_OTHER_NETWORKS_TOTAL,
339                mDeserializedWifiMetrics.numLastResortWatchdogBadOtherNetworksTotal);
340        assertEquals(NUM_LAST_RESORT_WATCHDOG_AVAILABLE_NETWORKS_TOTAL,
341                mDeserializedWifiMetrics.numLastResortWatchdogAvailableNetworksTotal);
342        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_ASSOCIATION,
343                mDeserializedWifiMetrics.numLastResortWatchdogTriggersWithBadAssociation);
344        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_AUTHENTICATION,
345                mDeserializedWifiMetrics.numLastResortWatchdogTriggersWithBadAuthentication);
346        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_DHCP,
347                mDeserializedWifiMetrics.numLastResortWatchdogTriggersWithBadDhcp);
348        assertEquals(NUM_LAST_RESORT_WATCHDOG_TRIGGERS_WITH_BAD_OTHER,
349                mDeserializedWifiMetrics.numLastResortWatchdogTriggersWithBadOther);
350        assertEquals(NUM_LAST_RESORT_WATCHDOG_SUCCESSES,
351                mDeserializedWifiMetrics.numLastResortWatchdogSuccesses);
352        assertEquals(TEST_RECORD_DURATION_SEC,
353                mDeserializedWifiMetrics.recordDurationSec);
354        for (int i = 0; i < NUM_RSSI_LEVELS_TO_INCREMENT; i++) {
355            assertEquals(FIRST_RSSI_LEVEL + i, mDeserializedWifiMetrics.rssiPollRssiCount[i].rssi);
356            assertEquals(i + 1, mDeserializedWifiMetrics.rssiPollRssiCount[i].count);
357        }
358        assertEquals(2, mDeserializedWifiMetrics.alertReasonCount[0].count);  // Clamped reasons.
359        assertEquals(3, mDeserializedWifiMetrics.alertReasonCount[1].count);
360        assertEquals(1, mDeserializedWifiMetrics.alertReasonCount[2].count);
361        assertEquals(3, mDeserializedWifiMetrics.alertReasonCount.length);
362    }
363
364    /**
365     *  Assert deserialized metrics Scan Return Entry equals count
366     */
367    public void assertScanReturnEntryEquals(int returnCode, int count) {
368        for (int i = 0; i < mDeserializedWifiMetrics.scanReturnEntries.length; i++) {
369            if (mDeserializedWifiMetrics.scanReturnEntries[i].scanReturnCode == returnCode) {
370                assertEquals(mDeserializedWifiMetrics.scanReturnEntries[i].scanResultsCount, count);
371                return;
372            }
373        }
374        assertEquals(null, count);
375    }
376
377    /**
378     *  Assert deserialized metrics SystemState entry equals count
379     */
380    public void assertSystemStateEntryEquals(int state, boolean screenOn, int count) {
381        for (int i = 0; i < mDeserializedWifiMetrics.wifiSystemStateEntries.length; i++) {
382            if (mDeserializedWifiMetrics.wifiSystemStateEntries[i].wifiState == state
383                    && mDeserializedWifiMetrics.wifiSystemStateEntries[i].isScreenOn == screenOn) {
384                assertEquals(mDeserializedWifiMetrics.wifiSystemStateEntries[i].wifiStateCount,
385                        count);
386                return;
387            }
388        }
389        assertEquals(null, count);
390    }
391    /**
392     * Combination of all other WifiMetrics unit tests, an internal-integration test, or functional
393     * test
394     */
395    @Test
396    public void setMetricsSerializeDeserializeAssertMetricsSame() throws Exception {
397        setAndIncrementMetrics();
398        startAndEndConnectionEventSucceeds();
399        dumpProtoAndDeserialize();
400        assertDeserializedMetricsCorrect();
401        assertEquals("mDeserializedWifiMetrics.connectionEvent.length",
402                2, mDeserializedWifiMetrics.connectionEvent.length);
403        //<TODO> test individual connectionEvents for correctness,
404        // check scanReturnEntries & wifiSystemStateEntries counts and individual elements
405        // pending their implementation</TODO>
406    }
407
408    private static final String SSID = "red";
409    private static final int CONFIG_DTIM = 3;
410    private static final int NETWORK_DETAIL_WIFIMODE = 5;
411    private static final int NETWORK_DETAIL_DTIM = 7;
412    private static final int SCAN_RESULT_LEVEL = -30;
413    /**
414     * Test that WifiMetrics is correctly getting data from ScanDetail and WifiConfiguration
415     */
416    @Test
417    public void testScanDetailAndWifiConfigurationUsage() throws Exception {
418        //Setup mock configs and scan details
419        NetworkDetail networkDetail = mock(NetworkDetail.class);
420        when(networkDetail.getWifiMode()).thenReturn(NETWORK_DETAIL_WIFIMODE);
421        when(networkDetail.getSSID()).thenReturn(SSID);
422        when(networkDetail.getDtimInterval()).thenReturn(NETWORK_DETAIL_DTIM);
423        ScanResult scanResult = mock(ScanResult.class);
424        scanResult.level = SCAN_RESULT_LEVEL;
425        WifiConfiguration config = mock(WifiConfiguration.class);
426        config.SSID = "\"" + SSID + "\"";
427        config.dtimInterval = CONFIG_DTIM;
428        WifiConfiguration.NetworkSelectionStatus networkSelectionStat =
429                mock(WifiConfiguration.NetworkSelectionStatus.class);
430        when(networkSelectionStat.getCandidate()).thenReturn(scanResult);
431        when(config.getNetworkSelectionStatus()).thenReturn(networkSelectionStat);
432        ScanDetail scanDetail = mock(ScanDetail.class);
433        when(scanDetail.getNetworkDetail()).thenReturn(networkDetail);
434        when(scanDetail.getScanResult()).thenReturn(scanResult);
435
436        //Create a connection event using only the config
437        mWifiMetrics.startConnectionEvent(config, "Red",
438                WifiMetricsProto.ConnectionEvent.ROAM_NONE);
439        mWifiMetrics.endConnectionEvent(
440                WifiMetrics.ConnectionEvent.FAILURE_NONE,
441                WifiMetricsProto.ConnectionEvent.HLF_NONE);
442
443        //Create a connection event using the config and a scan detail
444        mWifiMetrics.startConnectionEvent(config, "Green",
445                WifiMetricsProto.ConnectionEvent.ROAM_NONE);
446        mWifiMetrics.setConnectionScanDetail(scanDetail);
447        mWifiMetrics.endConnectionEvent(
448                WifiMetrics.ConnectionEvent.FAILURE_NONE,
449                WifiMetricsProto.ConnectionEvent.HLF_NONE);
450
451        //Dump proto from mWifiMetrics and deserialize it to mDeserializedWifiMetrics
452        dumpProtoAndDeserialize();
453
454        //Check that the correct values are being flowed through
455        assertEquals(mDeserializedWifiMetrics.connectionEvent.length, 2);
456        assertEquals(mDeserializedWifiMetrics.connectionEvent[0].routerFingerprint.dtim,
457                CONFIG_DTIM);
458        assertEquals(mDeserializedWifiMetrics.connectionEvent[0].signalStrength, SCAN_RESULT_LEVEL);
459        assertEquals(mDeserializedWifiMetrics.connectionEvent[1].routerFingerprint.dtim,
460                NETWORK_DETAIL_DTIM);
461        assertEquals(mDeserializedWifiMetrics.connectionEvent[1].signalStrength,
462                SCAN_RESULT_LEVEL);
463        assertEquals(mDeserializedWifiMetrics.connectionEvent[1].routerFingerprint.routerTechnology,
464                NETWORK_DETAIL_WIFIMODE);
465    }
466
467    /**
468     * Test that WifiMetrics is being cleared after dumping via proto
469     */
470    @Test
471    public void testMetricsClearedAfterProtoRequested() throws Exception {
472        // Create 3 ConnectionEvents
473        mWifiMetrics.startConnectionEvent(null, "RED",
474                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
475        mWifiMetrics.endConnectionEvent(
476                WifiMetrics.ConnectionEvent.FAILURE_NONE,
477                WifiMetricsProto.ConnectionEvent.HLF_NONE);
478        mWifiMetrics.startConnectionEvent(null, "YELLOW",
479                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
480        mWifiMetrics.endConnectionEvent(
481                WifiMetrics.ConnectionEvent.FAILURE_NONE,
482                WifiMetricsProto.ConnectionEvent.HLF_NONE);
483        mWifiMetrics.startConnectionEvent(null, "GREEN",
484                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
485        mWifiMetrics.endConnectionEvent(
486                WifiMetrics.ConnectionEvent.FAILURE_NONE,
487                WifiMetricsProto.ConnectionEvent.HLF_NONE);
488        mWifiMetrics.startConnectionEvent(null, "ORANGE",
489                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
490        mWifiMetrics.endConnectionEvent(
491                WifiMetrics.ConnectionEvent.FAILURE_NONE,
492                WifiMetricsProto.ConnectionEvent.HLF_NONE);
493
494        //Dump proto and deserialize
495        //This should clear all the metrics in mWifiMetrics,
496        dumpProtoAndDeserialize();
497        //Check there are only 3 connection events
498        assertEquals(mDeserializedWifiMetrics.connectionEvent.length, 4);
499        assertEquals(mDeserializedWifiMetrics.rssiPollRssiCount.length, 0);
500        assertEquals(mDeserializedWifiMetrics.alertReasonCount.length, 0);
501
502        // Create 2 ConnectionEvents
503        mWifiMetrics.startConnectionEvent(null,  "BLUE",
504                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
505        mWifiMetrics.endConnectionEvent(
506                WifiMetrics.ConnectionEvent.FAILURE_NONE,
507                WifiMetricsProto.ConnectionEvent.HLF_NONE);
508        mWifiMetrics.startConnectionEvent(null, "RED",
509                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);
510        mWifiMetrics.endConnectionEvent(
511                WifiMetrics.ConnectionEvent.FAILURE_NONE,
512                WifiMetricsProto.ConnectionEvent.HLF_NONE);
513
514        //Dump proto and deserialize
515        dumpProtoAndDeserialize();
516        //Check there are only 2 connection events
517        assertEquals(mDeserializedWifiMetrics.connectionEvent.length, 2);
518    }
519
520    private void assertStringContains(
521            String actualString, String expectedSubstring) {
522        assertTrue("Expected text not found in: " + actualString,
523                actualString.contains(expectedSubstring));
524    }
525
526    private String getStateDump() {
527        ByteArrayOutputStream stream = new ByteArrayOutputStream();
528        PrintWriter writer = new PrintWriter(stream);
529        String[] args = new String[0];
530        mWifiMetrics.dump(null, writer, args);
531        writer.flush();
532        return stream.toString();
533    }
534}
535
536
537