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