WifiNativeTest.java revision e6d7f23569585f8f0fb02adbef992d3f1430db44
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 */
16
17package com.android.server.wifi;
18
19import static org.junit.Assert.assertArrayEquals;
20import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.assertFalse;
22import static org.junit.Assert.assertTrue;
23import static org.mockito.Mockito.anyInt;
24import static org.mockito.Mockito.anyString;
25import static org.mockito.Mockito.eq;
26import static org.mockito.Mockito.mock;
27import static org.mockito.Mockito.spy;
28import static org.mockito.Mockito.verify;
29import static org.mockito.Mockito.when;
30
31import android.net.wifi.IApInterface;
32import android.net.wifi.IClientInterface;
33import android.net.wifi.IWificond;
34import android.test.suitebuilder.annotation.SmallTest;
35
36import org.junit.Before;
37import org.junit.Test;
38
39import java.lang.reflect.Constructor;
40import java.util.Arrays;
41import java.util.HashMap;
42import java.util.HashSet;
43import java.util.Map;
44import java.util.Set;
45import java.util.TreeSet;
46import java.util.regex.Pattern;
47
48/**
49 * Unit tests for {@link com.android.server.wifi.WifiNative}.
50 */
51@SmallTest
52public class WifiNativeTest {
53    private static final int NETWORK_ID = 0;
54    private static final String NETWORK_EXTRAS_VARIABLE = "test";
55    private static final Map<String, String> NETWORK_EXTRAS_VALUES = new HashMap<>();
56    static {
57        NETWORK_EXTRAS_VALUES.put("key1", "value1");
58        NETWORK_EXTRAS_VALUES.put("key2", "value2");
59    }
60    private static final String NETWORK_EXTRAS_SERIALIZED =
61            "\"%7B%22key1%22%3A%22value1%22%2C%22key2%22%3A%22value2%22%7D\"";
62
63    private static final long FATE_REPORT_DRIVER_TIMESTAMP_USEC = 12345;
64    private static final byte[] FATE_REPORT_FRAME_BYTES = new byte[] {
65            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 0, 1, 2, 3, 4, 5, 6, 7};
66    private static final WifiNative.TxFateReport TX_FATE_REPORT = new WifiNative.TxFateReport(
67            WifiLoggerHal.TX_PKT_FATE_SENT,
68            FATE_REPORT_DRIVER_TIMESTAMP_USEC,
69            WifiLoggerHal.FRAME_TYPE_ETHERNET_II,
70            FATE_REPORT_FRAME_BYTES
71    );
72    private static final WifiNative.RxFateReport RX_FATE_REPORT = new WifiNative.RxFateReport(
73            WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID,
74            FATE_REPORT_DRIVER_TIMESTAMP_USEC,
75            WifiLoggerHal.FRAME_TYPE_ETHERNET_II,
76            FATE_REPORT_FRAME_BYTES
77    );
78    private static final FrameTypeMapping[] FRAME_TYPE_MAPPINGS = new FrameTypeMapping[] {
79            new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_UNKNOWN, "unknown", "N/A"),
80            new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, "data", "Ethernet"),
81            new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_80211_MGMT, "802.11 management",
82                    "802.11 Mgmt"),
83            new FrameTypeMapping((byte) 42, "42", "N/A")
84    };
85    private static final FateMapping[] TX_FATE_MAPPINGS = new FateMapping[] {
86            new FateMapping(WifiLoggerHal.TX_PKT_FATE_ACKED, "acked"),
87            new FateMapping(WifiLoggerHal.TX_PKT_FATE_SENT, "sent"),
88            new FateMapping(WifiLoggerHal.TX_PKT_FATE_FW_QUEUED, "firmware queued"),
89            new FateMapping(WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID,
90                    "firmware dropped (invalid frame)"),
91            new FateMapping(
92                    WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS,  "firmware dropped (no bufs)"),
93            new FateMapping(
94                    WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, "firmware dropped (other)"),
95            new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, "driver queued"),
96            new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID,
97                    "driver dropped (invalid frame)"),
98            new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS,
99                    "driver dropped (no bufs)"),
100            new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER, "driver dropped (other)"),
101            new FateMapping((byte) 42, "42")
102    };
103    private static final FateMapping[] RX_FATE_MAPPINGS = new FateMapping[] {
104            new FateMapping(WifiLoggerHal.RX_PKT_FATE_SUCCESS, "success"),
105            new FateMapping(WifiLoggerHal.RX_PKT_FATE_FW_QUEUED, "firmware queued"),
106            new FateMapping(
107                    WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, "firmware dropped (filter)"),
108            new FateMapping(WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID,
109                    "firmware dropped (invalid frame)"),
110            new FateMapping(
111                    WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS, "firmware dropped (no bufs)"),
112            new FateMapping(
113                    WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER, "firmware dropped (other)"),
114            new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED, "driver queued"),
115            new FateMapping(
116                    WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER, "driver dropped (filter)"),
117            new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID,
118                    "driver dropped (invalid frame)"),
119            new FateMapping(
120                    WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS, "driver dropped (no bufs)"),
121            new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER, "driver dropped (other)"),
122            new FateMapping((byte) 42, "42")
123    };
124    private static final WifiNative.SignalPollResult SIGNAL_POLL_RESULT =
125            new WifiNative.SignalPollResult() {{
126                currentRssi = -60;
127                txBitrate = 12;
128                associationFrequency = 5240;
129            }};
130    private static final WifiNative.TxPacketCounters PACKET_COUNTERS_RESULT =
131            new WifiNative.TxPacketCounters() {{
132                txSucceeded = 2000;
133                txFailed = 120;
134            }};
135
136    private static final Set<Integer> SCAN_FREQ_SET =
137            new HashSet<Integer>() {{
138                add(2410);
139                add(2450);
140                add(5050);
141                add(5200);
142            }};
143    private static final Set<String> SCAN_HIDDEN_NETWORK_SSID_SET =
144            new HashSet<String>() {{
145                // These SSIDs should be quoted.
146                add("\"hiddenAP1\"");
147                add("\"hiddenAP2\"");
148            }};
149
150    private WifiNative mWifiNative;
151
152    @Before
153    public void setUp() throws Exception {
154        final Constructor<WifiNative> wifiNativeConstructor =
155                WifiNative.class.getDeclaredConstructor(String.class, Boolean.TYPE);
156        wifiNativeConstructor.setAccessible(true);
157        mWifiNative = spy(wifiNativeConstructor.newInstance("test", true));
158    }
159
160    /**
161     * Verifies that setNetworkExtra() correctly writes a serialized and URL-encoded JSON object.
162     */
163    @Test
164    public void testSetNetworkExtra() {
165        when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString())).thenReturn(true);
166        assertTrue(mWifiNative.setNetworkExtra(NETWORK_ID, NETWORK_EXTRAS_VARIABLE,
167                NETWORK_EXTRAS_VALUES));
168        verify(mWifiNative).setNetworkVariable(NETWORK_ID, NETWORK_EXTRAS_VARIABLE,
169                NETWORK_EXTRAS_SERIALIZED);
170    }
171
172    /**
173     * Verifies that getNetworkExtra() correctly reads a serialized and URL-encoded JSON object.
174     */
175    @Test
176    public void testGetNetworkExtra() {
177        when(mWifiNative.getNetworkVariable(NETWORK_ID, NETWORK_EXTRAS_VARIABLE))
178                .thenReturn(NETWORK_EXTRAS_SERIALIZED);
179        final Map<String, String> actualValues =
180                mWifiNative.getNetworkExtra(NETWORK_ID, NETWORK_EXTRAS_VARIABLE);
181        assertEquals(NETWORK_EXTRAS_VALUES, actualValues);
182    }
183
184    /**
185     * Verifies that TxFateReport's constructor sets all of the TxFateReport fields.
186     */
187    @Test
188    public void testTxFateReportCtorSetsFields() {
189        WifiNative.TxFateReport fateReport = new WifiNative.TxFateReport(
190                WifiLoggerHal.TX_PKT_FATE_SENT,  // non-zero value
191                FATE_REPORT_DRIVER_TIMESTAMP_USEC,
192                WifiLoggerHal.FRAME_TYPE_ETHERNET_II,  // non-zero value
193                FATE_REPORT_FRAME_BYTES
194        );
195        assertEquals(WifiLoggerHal.TX_PKT_FATE_SENT, fateReport.mFate);
196        assertEquals(FATE_REPORT_DRIVER_TIMESTAMP_USEC, fateReport.mDriverTimestampUSec);
197        assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, fateReport.mFrameType);
198        assertArrayEquals(FATE_REPORT_FRAME_BYTES, fateReport.mFrameBytes);
199    }
200
201    /**
202     * Verifies that RxFateReport's constructor sets all of the RxFateReport fields.
203     */
204    @Test
205    public void testRxFateReportCtorSetsFields() {
206        WifiNative.RxFateReport fateReport = new WifiNative.RxFateReport(
207                WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID,  // non-zero value
208                FATE_REPORT_DRIVER_TIMESTAMP_USEC,
209                WifiLoggerHal.FRAME_TYPE_ETHERNET_II,  // non-zero value
210                FATE_REPORT_FRAME_BYTES
211        );
212        assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID, fateReport.mFate);
213        assertEquals(FATE_REPORT_DRIVER_TIMESTAMP_USEC, fateReport.mDriverTimestampUSec);
214        assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, fateReport.mFrameType);
215        assertArrayEquals(FATE_REPORT_FRAME_BYTES, fateReport.mFrameBytes);
216    }
217
218    /**
219     * Verifies the hashCode methods for HiddenNetwork and PnoNetwork classes
220     */
221    @Test
222    public void testHashCode() {
223        WifiNative.HiddenNetwork hiddenNet1 = new WifiNative.HiddenNetwork();
224        hiddenNet1.ssid = new String("sametext");
225
226        WifiNative.HiddenNetwork hiddenNet2 = new WifiNative.HiddenNetwork();
227        hiddenNet2.ssid = new String("sametext");
228
229        assertTrue(hiddenNet1.equals(hiddenNet2));
230        assertEquals(hiddenNet1.hashCode(), hiddenNet2.hashCode());
231
232        WifiNative.PnoNetwork pnoNet1 = new WifiNative.PnoNetwork();
233        pnoNet1.ssid = new String("sametext");
234        pnoNet1.flags = 2;
235        pnoNet1.auth_bit_field = 4;
236
237        WifiNative.PnoNetwork pnoNet2 = new WifiNative.PnoNetwork();
238        pnoNet2.ssid = new String("sametext");
239        pnoNet2.flags = 2;
240        pnoNet2.auth_bit_field = 4;
241
242        assertTrue(pnoNet1.equals(pnoNet2));
243        assertEquals(pnoNet1.hashCode(), pnoNet2.hashCode());
244    }
245
246    // Support classes for test{Tx,Rx}FateReportToString.
247    private static class FrameTypeMapping {
248        byte mTypeNumber;
249        String mExpectedTypeText;
250        String mExpectedProtocolText;
251        FrameTypeMapping(byte typeNumber, String expectedTypeText, String expectedProtocolText) {
252            this.mTypeNumber = typeNumber;
253            this.mExpectedTypeText = expectedTypeText;
254            this.mExpectedProtocolText = expectedProtocolText;
255        }
256    }
257    private static class FateMapping {
258        byte mFateNumber;
259        String mExpectedText;
260        FateMapping(byte fateNumber, String expectedText) {
261            this.mFateNumber = fateNumber;
262            this.mExpectedText = expectedText;
263        }
264    }
265
266    /**
267     * Verifies that FateReport.getTableHeader() prints the right header.
268     */
269    @Test
270    public void testFateReportTableHeader() {
271        final String header = WifiNative.FateReport.getTableHeader();
272        assertEquals(
273                "\nTime usec        Walltime      Direction  Fate                              "
274                + "Protocol      Type                     Result\n"
275                + "---------        --------      ---------  ----                              "
276                + "--------      ----                     ------\n", header);
277    }
278
279    /**
280     * Verifies that TxFateReport.toTableRowString() includes the information we care about.
281     */
282    @Test
283    public void testTxFateReportToTableRowString() {
284        WifiNative.TxFateReport fateReport = TX_FATE_REPORT;
285        assertTrue(
286                fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
287                    FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
288                            + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
289                            + "TX "  // direction
290                            + "sent "  // fate
291                            + "Ethernet "  // type
292                            + "N/A "  // protocol
293                            + "N/A"  // result
294                )
295        );
296
297        for (FrameTypeMapping frameTypeMapping : FRAME_TYPE_MAPPINGS) {
298            fateReport = new WifiNative.TxFateReport(
299                    WifiLoggerHal.TX_PKT_FATE_SENT,
300                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
301                    frameTypeMapping.mTypeNumber,
302                    FATE_REPORT_FRAME_BYTES
303            );
304            assertTrue(
305                    fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
306                            FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
307                                    + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
308                                    + "TX "  // direction
309                                    + "sent "  // fate
310                                    + frameTypeMapping.mExpectedProtocolText + " "  // type
311                                    + "N/A "  // protocol
312                                    + "N/A"  // result
313                    )
314            );
315        }
316
317        for (FateMapping fateMapping : TX_FATE_MAPPINGS) {
318            fateReport = new WifiNative.TxFateReport(
319                    fateMapping.mFateNumber,
320                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
321                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
322                    FATE_REPORT_FRAME_BYTES
323            );
324            assertTrue(
325                    fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
326                            FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
327                                    + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
328                                    + "TX "  // direction
329                                    + Pattern.quote(fateMapping.mExpectedText) + " "  // fate
330                                    + "802.11 Mgmt "  // type
331                                    + "N/A "  // protocol
332                                    + "N/A"  // result
333                    )
334            );
335        }
336    }
337
338    /**
339     * Verifies that TxFateReport.toVerboseStringWithPiiAllowed() includes the information we care
340     * about.
341     */
342    @Test
343    public void testTxFateReportToVerboseStringWithPiiAllowed() {
344        WifiNative.TxFateReport fateReport = TX_FATE_REPORT;
345
346        String verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
347        assertTrue(verboseFateString.contains("Frame direction: TX"));
348        assertTrue(verboseFateString.contains("Frame timestamp: 12345"));
349        assertTrue(verboseFateString.contains("Frame fate: sent"));
350        assertTrue(verboseFateString.contains("Frame type: data"));
351        assertTrue(verboseFateString.contains("Frame protocol: Ethernet"));
352        assertTrue(verboseFateString.contains("Frame protocol type: N/A"));
353        assertTrue(verboseFateString.contains("Frame length: 16"));
354        assertTrue(verboseFateString.contains(
355                "61 62 63 64 65 66 67 68 00 01 02 03 04 05 06 07")); // hex dump
356        // TODO(quiche): uncomment this, once b/27975149 is fixed.
357        // assertTrue(verboseFateString.contains("abcdefgh........"));  // hex dump
358
359        for (FrameTypeMapping frameTypeMapping : FRAME_TYPE_MAPPINGS) {
360            fateReport = new WifiNative.TxFateReport(
361                    WifiLoggerHal.TX_PKT_FATE_SENT,
362                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
363                    frameTypeMapping.mTypeNumber,
364                    FATE_REPORT_FRAME_BYTES
365            );
366            verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
367            assertTrue(verboseFateString.contains("Frame type: "
368                    + frameTypeMapping.mExpectedTypeText));
369        }
370
371        for (FateMapping fateMapping : TX_FATE_MAPPINGS) {
372            fateReport = new WifiNative.TxFateReport(
373                    fateMapping.mFateNumber,
374                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
375                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
376                    FATE_REPORT_FRAME_BYTES
377            );
378            verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
379            assertTrue(verboseFateString.contains("Frame fate: " + fateMapping.mExpectedText));
380        }
381    }
382
383    /**
384     * Verifies that RxFateReport.toTableRowString() includes the information we care about.
385     */
386    @Test
387    public void testRxFateReportToTableRowString() {
388        WifiNative.RxFateReport fateReport = RX_FATE_REPORT;
389        assertTrue(
390                fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
391                        FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
392                                + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
393                                + "RX "  // direction
394                                + Pattern.quote("firmware dropped (invalid frame) ")  // fate
395                                + "Ethernet "  // type
396                                + "N/A "  // protocol
397                                + "N/A"  // result
398                )
399        );
400
401        // FrameTypeMappings omitted, as they're the same as for TX.
402
403        for (FateMapping fateMapping : RX_FATE_MAPPINGS) {
404            fateReport = new WifiNative.RxFateReport(
405                    fateMapping.mFateNumber,
406                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
407                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
408                    FATE_REPORT_FRAME_BYTES
409            );
410            assertTrue(
411                    fateReport.toTableRowString().replaceAll("\\s+", " ").trim().matches(
412                            FATE_REPORT_DRIVER_TIMESTAMP_USEC + " "  // timestamp
413                                    + "\\d{2}:\\d{2}:\\d{2}\\.\\d{3} "  // walltime
414                                    + "RX "  // direction
415                                    + Pattern.quote(fateMapping.mExpectedText) + " " // fate
416                                    + "802.11 Mgmt "  // type
417                                    + "N/A " // protocol
418                                    + "N/A"  // result
419                    )
420            );
421        }
422    }
423
424    /**
425     * Verifies that RxFateReport.toVerboseStringWithPiiAllowed() includes the information we care
426     * about.
427     */
428    @Test
429    public void testRxFateReportToVerboseStringWithPiiAllowed() {
430        WifiNative.RxFateReport fateReport = RX_FATE_REPORT;
431
432        String verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
433        assertTrue(verboseFateString.contains("Frame direction: RX"));
434        assertTrue(verboseFateString.contains("Frame timestamp: 12345"));
435        assertTrue(verboseFateString.contains("Frame fate: firmware dropped (invalid frame)"));
436        assertTrue(verboseFateString.contains("Frame type: data"));
437        assertTrue(verboseFateString.contains("Frame protocol: Ethernet"));
438        assertTrue(verboseFateString.contains("Frame protocol type: N/A"));
439        assertTrue(verboseFateString.contains("Frame length: 16"));
440        assertTrue(verboseFateString.contains(
441                "61 62 63 64 65 66 67 68 00 01 02 03 04 05 06 07")); // hex dump
442        // TODO(quiche): uncomment this, once b/27975149 is fixed.
443        // assertTrue(verboseFateString.contains("abcdefgh........"));  // hex dump
444
445        // FrameTypeMappings omitted, as they're the same as for TX.
446
447        for (FateMapping fateMapping : RX_FATE_MAPPINGS) {
448            fateReport = new WifiNative.RxFateReport(
449                    fateMapping.mFateNumber,
450                    FATE_REPORT_DRIVER_TIMESTAMP_USEC,
451                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
452                    FATE_REPORT_FRAME_BYTES
453            );
454            verboseFateString = fateReport.toVerboseStringWithPiiAllowed();
455            assertTrue(verboseFateString.contains("Frame fate: " + fateMapping.mExpectedText));
456        }
457    }
458
459    /**
460     * Verifies that startPktFateMonitoring returns false when HAL is not started.
461     */
462    @Test
463    public void testStartPktFateMonitoringReturnsFalseWhenHalIsNotStarted() {
464        assertFalse(mWifiNative.isHalStarted());
465        assertFalse(mWifiNative.startPktFateMonitoring());
466    }
467
468    /**
469     * Verifies that getTxPktFates returns error when HAL is not started.
470     */
471    @Test
472    public void testGetTxPktFatesReturnsErrorWhenHalIsNotStarted() {
473        WifiNative.TxFateReport[] fateReports = null;
474        assertFalse(mWifiNative.isHalStarted());
475        assertFalse(mWifiNative.getTxPktFates(fateReports));
476    }
477
478    /**
479     * Verifies that getRxPktFates returns error when HAL is not started.
480     */
481    @Test
482    public void testGetRxPktFatesReturnsErrorWhenHalIsNotStarted() {
483        WifiNative.RxFateReport[] fateReports = null;
484        assertFalse(mWifiNative.isHalStarted());
485        assertFalse(mWifiNative.getRxPktFates(fateReports));
486    }
487
488    // TODO(quiche): Add tests for the success cases (when HAL has been started). Specifically:
489    // - testStartPktFateMonitoringCallsHalIfHalIsStarted()
490    // - testGetTxPktFatesCallsHalIfHalIsStarted()
491    // - testGetRxPktFatesCallsHalIfHalIsStarted()
492    //
493    // Adding these tests is difficult to do at the moment, because we can't mock out the HAL
494    // itself. Also, we can't mock out the native methods, because those methods are private.
495    // b/28005116.
496
497    /** Verifies that getDriverStateDumpNative returns null when HAL is not started. */
498    @Test
499    public void testGetDriverStateDumpReturnsNullWhenHalIsNotStarted() {
500        assertEquals(null, mWifiNative.getDriverStateDump());
501    }
502
503    // TODO(b/28005116): Add test for the success case of getDriverStateDump().
504
505    /**
506     * Verifies that setupDriverForClientMode() calls underlying WificondControl.
507     */
508    @Test
509    public void testSetupDriverForClientMode() {
510        WificondControl wificondControl = mock(WificondControl.class);
511        IWificond wificond = mock(IWificond.class);
512        IClientInterface clientInterface = mock(IClientInterface.class);
513
514        when(wificondControl.setupDriverForClientMode()).thenReturn(clientInterface);
515        mWifiNative.setWificondControl(wificondControl);
516
517        IClientInterface returnedClientInterface = mWifiNative.setupDriverForClientMode();
518        assertEquals(clientInterface, returnedClientInterface);
519        verify(wificondControl).setupDriverForClientMode();
520        verify(mWifiNative).startHal(eq(true));
521    }
522
523    /**
524     * Verifies that setupDriverForClientMode() returns null when underlying WificondControl
525     * call fails.
526     */
527    @Test
528    public void testSetupDriverForClientModeError() {
529        WificondControl wificondControl = mock(WificondControl.class);
530        IWificond wificond = mock(IWificond.class);
531
532        when(wificondControl.setupDriverForClientMode()).thenReturn(null);
533        mWifiNative.setWificondControl(wificondControl);
534
535        IClientInterface returnedClientInterface = mWifiNative.setupDriverForClientMode();
536        assertEquals(null, returnedClientInterface);
537        verify(wificondControl).setupDriverForClientMode();
538    }
539
540    /**
541     * Verifies that setupDriverForSoftApMode() calls underlying WificondControl.
542     */
543    @Test
544    public void testSetupDriverForSoftApMode() {
545        WificondControl wificondControl = mock(WificondControl.class);
546        IWificond wificond = mock(IWificond.class);
547        IApInterface apInterface = mock(IApInterface.class);
548
549        when(wificondControl.setupDriverForSoftApMode()).thenReturn(apInterface);
550        mWifiNative.setWificondControl(wificondControl);
551
552        IApInterface returnedApInterface = mWifiNative.setupDriverForSoftApMode();
553        assertEquals(apInterface, returnedApInterface);
554        verify(wificondControl).setupDriverForSoftApMode();
555        verify(mWifiNative).startHal(eq(false));
556    }
557
558    /**
559     * Verifies that setupDriverForSoftApMode() returns null when underlying WificondControl
560     * call fails.
561     */
562    @Test
563    public void testSetupDriverForSoftApModeError() {
564        WificondControl wificondControl = mock(WificondControl.class);
565        IWificond wificond = mock(IWificond.class);
566
567        when(wificondControl.setupDriverForSoftApMode()).thenReturn(null);
568        mWifiNative.setWificondControl(wificondControl);
569
570        IApInterface returnedApInterface = mWifiNative.setupDriverForSoftApMode();
571        assertEquals(null, returnedApInterface);
572        verify(wificondControl).setupDriverForSoftApMode();
573    }
574
575    /**
576     * Verifies that enableSupplicant() calls underlying WificondControl.
577     */
578    @Test
579    public void testEnableSupplicant() {
580        WificondControl wificondControl = mock(WificondControl.class);
581        IWificond wificond = mock(IWificond.class);
582
583        mWifiNative.setWificondControl(wificondControl);
584
585        mWifiNative.enableSupplicant();
586        verify(wificondControl).enableSupplicant();
587    }
588
589    /**
590     * Verifies that disableSupplicant() calls underlying WificondControl.
591     */
592    @Test
593    public void testDisableSupplicant() {
594        WificondControl wificondControl = mock(WificondControl.class);
595        IWificond wificond = mock(IWificond.class);
596
597        mWifiNative.setWificondControl(wificondControl);
598
599        mWifiNative.disableSupplicant();
600        verify(wificondControl).disableSupplicant();
601    }
602
603    /**
604     * Verifies that tearDownInterfaces() calls underlying WificondControl.
605     */
606    @Test
607    public void testTearDownInterfaces() {
608        WificondControl wificondControl = mock(WificondControl.class);
609
610        when(wificondControl.tearDownInterfaces()).thenReturn(true);
611        mWifiNative.setWificondControl(wificondControl);
612
613        assertTrue(mWifiNative.tearDownInterfaces());
614        verify(wificondControl).tearDownInterfaces();
615    }
616
617    /**
618     * Verifies that signalPoll() calls underlying WificondControl.
619     */
620    @Test
621    public void testSignalPoll() throws Exception {
622        WificondControl wificondControl = mock(WificondControl.class);
623
624        when(wificondControl.signalPoll()).thenReturn(SIGNAL_POLL_RESULT);
625        mWifiNative.setWificondControl(wificondControl);
626
627        assertEquals(SIGNAL_POLL_RESULT, mWifiNative.signalPoll());
628        verify(wificondControl).signalPoll();
629    }
630
631    /**
632     * Verifies that getTxPacketCounters() calls underlying WificondControl.
633     */
634    @Test
635    public void testGetTxPacketCounters() throws Exception {
636        WificondControl wificondControl = mock(WificondControl.class);
637
638        when(wificondControl.getTxPacketCounters()).thenReturn(PACKET_COUNTERS_RESULT);
639        mWifiNative.setWificondControl(wificondControl);
640
641        assertEquals(PACKET_COUNTERS_RESULT, mWifiNative.getTxPacketCounters());
642        verify(wificondControl).getTxPacketCounters();
643    }
644
645    /**
646     * Verifies that scan() calls underlying WificondControl.
647     */
648    @Test
649    public void testScan() throws Exception {
650        WificondControl wificondControl = mock(WificondControl.class);
651
652        mWifiNative.setWificondControl(wificondControl);
653
654        mWifiNative.scan(SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET);
655        verify(wificondControl).scan(SCAN_FREQ_SET, SCAN_HIDDEN_NETWORK_SSID_SET);
656    }
657
658    /**
659     * Verifies that the ANQP query command is correctly created.
660     */
661    @Test
662    public void testbuildAnqpQueryCommandWithOnlyHsSubtypes() {
663        String bssid = "34:12:ac:45:21:12";
664        Set<Integer> anqpIds = new TreeSet<>();
665        Set<Integer> hs20Subtypes = new TreeSet<>(Arrays.asList(3, 7));
666
667        String expectedCommand = "HS20_ANQP_GET " + bssid + " 3,7";
668        assertEquals(expectedCommand,
669                WifiNative.buildAnqpQueryCommand(bssid, anqpIds, hs20Subtypes));
670    }
671
672    /**
673     * Verifies that the ANQP query command is correctly created.
674     */
675    @Test
676    public void testbuildAnqpQueryCommandWithMixedTypes() {
677        String bssid = "34:12:ac:45:21:12";
678        Set<Integer> anqpIds = new TreeSet<>(Arrays.asList(1, 2, 5));
679        Set<Integer> hs20Subtypes = new TreeSet<>(Arrays.asList(3, 7));
680
681        String expectedCommand = "ANQP_GET " + bssid + " 1,2,5,hs20:3,hs20:7";
682        assertEquals(expectedCommand,
683                WifiNative.buildAnqpQueryCommand(bssid, anqpIds, hs20Subtypes));
684    }
685}
686