WifiNativeTest.java revision d0cb2fae195ebb9f658095667f3c7b7b8d69a204
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.spy;
26import static org.mockito.Mockito.verify;
27import static org.mockito.Mockito.when;
28
29import android.test.suitebuilder.annotation.SmallTest;
30
31import org.junit.Before;
32import org.junit.Test;
33
34import java.lang.reflect.Constructor;
35import java.util.HashMap;
36import java.util.Map;
37
38/**
39 * Unit tests for {@link com.android.server.wifi.WifiNative}.
40 */
41@SmallTest
42public class WifiNativeTest {
43    private static final int NETWORK_ID = 0;
44    private static final String NETWORK_EXTRAS_VARIABLE = "test";
45    private static final Map<String, String> NETWORK_EXTRAS_VALUES = new HashMap<>();
46    static {
47        NETWORK_EXTRAS_VALUES.put("key1", "value1");
48        NETWORK_EXTRAS_VALUES.put("key2", "value2");
49    }
50    private static final String NETWORK_EXTRAS_SERIALIZED =
51            "\"%7B%22key2%22%3A%22value2%22%2C%22key1%22%3A%22value1%22%7D\"";
52
53    private WifiNative mWifiNative;
54
55    @Before
56    public void setUp() throws Exception {
57        final Constructor<WifiNative> wifiNativeConstructor =
58                WifiNative.class.getDeclaredConstructor(String.class, Boolean.TYPE);
59        wifiNativeConstructor.setAccessible(true);
60        mWifiNative = spy(wifiNativeConstructor.newInstance("test", true));
61    }
62
63    /**
64     * Verifies that setNetworkExtra() correctly writes a serialized and URL-encoded JSON object.
65     */
66    @Test
67    public void testSetNetworkExtra() {
68        when(mWifiNative.setNetworkVariable(anyInt(), anyString(), anyString())).thenReturn(true);
69        assertTrue(mWifiNative.setNetworkExtra(NETWORK_ID, NETWORK_EXTRAS_VARIABLE,
70                NETWORK_EXTRAS_VALUES));
71        verify(mWifiNative).setNetworkVariable(NETWORK_ID, NETWORK_EXTRAS_VARIABLE,
72                NETWORK_EXTRAS_SERIALIZED);
73    }
74
75    /**
76     * Verifies that getNetworkExtra() correctly reads a serialized and URL-encoded JSON object.
77     */
78    @Test
79    public void testGetNetworkExtra() {
80        when(mWifiNative.getNetworkVariable(NETWORK_ID, NETWORK_EXTRAS_VARIABLE))
81                .thenReturn(NETWORK_EXTRAS_SERIALIZED);
82        final Map<String, String> actualValues =
83                mWifiNative.getNetworkExtra(NETWORK_ID, NETWORK_EXTRAS_VARIABLE);
84        assertEquals(NETWORK_EXTRAS_VALUES, actualValues);
85    }
86
87    /**
88     * Verifies that TxFateReport's constructor sets all of the TxFateReport fields.
89     */
90    @Test
91    public void testTxFateReportCtorSetsFields() {
92        long driverTimestampUSec = 12345;
93        byte[] frameBytes = new byte[] {'a', 'b', 0, 'c'};
94        WifiNative.TxFateReport fateReport = new WifiNative.TxFateReport(
95                WifiLoggerHal.TX_PKT_FATE_SENT,  // non-zero value
96                driverTimestampUSec,
97                WifiLoggerHal.FRAME_TYPE_ETHERNET_II,  // non-zero value
98                frameBytes
99        );
100        assertEquals(WifiLoggerHal.TX_PKT_FATE_SENT, fateReport.mFate);
101        assertEquals(driverTimestampUSec, fateReport.mDriverTimestampUSec);
102        assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, fateReport.mFrameType);
103        assertArrayEquals(frameBytes, fateReport.mFrameBytes);
104    }
105
106    /**
107     * Verifies that RxFateReport's constructor sets all of the RxFateReport fields.
108     */
109    @Test
110    public void testRxFateReportCtorSetsFields() {
111        long driverTimestampUSec = 12345;
112        byte[] frameBytes = new byte[] {'a', 'b', 0, 'c'};
113        WifiNative.RxFateReport fateReport = new WifiNative.RxFateReport(
114                WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID,  // non-zero value
115                driverTimestampUSec,
116                WifiLoggerHal.FRAME_TYPE_ETHERNET_II,  // non-zero value
117                frameBytes
118        );
119        assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID, fateReport.mFate);
120        assertEquals(driverTimestampUSec, fateReport.mDriverTimestampUSec);
121        assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, fateReport.mFrameType);
122        assertArrayEquals(frameBytes, fateReport.mFrameBytes);
123    }
124
125    // Support classes for test{Tx,Rx}FateReportToString.
126    private static class FrameTypeMapping {
127        byte mTypeNumber;
128        String mExpectedText;
129        FrameTypeMapping(byte typeNumber, String expectedText) {
130            this.mTypeNumber = typeNumber;
131            this.mExpectedText = expectedText;
132        }
133    }
134    private static class FateMapping {
135        byte mFateNumber;
136        String mExpectedText;
137        FateMapping(byte fateNumber, String expectedText) {
138            this.mFateNumber = fateNumber;
139            this.mExpectedText = expectedText;
140        }
141    }
142
143    /**
144     * Verifies that TxFateReport.toString() includes the information we care about.
145     */
146    @Test
147    public void testTxFateReportToString() {
148        long driverTimestampUSec = 12345;
149        byte[] frameBytes = new byte[] {
150                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 0, 1, 2, 3, 4, 5, 6, 7};
151        WifiNative.TxFateReport fateReport = new WifiNative.TxFateReport(
152                WifiLoggerHal.TX_PKT_FATE_SENT,
153                driverTimestampUSec,
154                WifiLoggerHal.FRAME_TYPE_ETHERNET_II,
155                frameBytes
156        );
157
158        String fateString = fateReport.toString();
159        assertTrue(fateString.contains("Frame direction: TX"));
160        assertTrue(fateString.contains("Frame timestamp: 12345"));
161        assertTrue(fateString.contains("Frame fate: sent"));
162        assertTrue(fateString.contains("Frame type: data"));
163        assertTrue(fateString.contains("Frame length: 16"));
164        assertTrue(fateString.contains(
165                "61 62 63 64 65 66 67 68 00 01 02 03 04 05 06 07")); // hex dump
166        // TODO(quiche): uncomment this, once b/27975149 is fixed.
167        // assertTrue(fateString.contains("abcdefgh........"));  // hex dump
168
169        FrameTypeMapping[] frameTypeMappings = new FrameTypeMapping[] {
170                new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_UNKNOWN, "unknown"),
171                new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, "data"),
172                new FrameTypeMapping(WifiLoggerHal.FRAME_TYPE_80211_MGMT, "802.11 management"),
173                new FrameTypeMapping((byte) 42, "42")
174        };
175        for (FrameTypeMapping frameTypeMapping : frameTypeMappings) {
176            fateReport = new WifiNative.TxFateReport(
177                    WifiLoggerHal.TX_PKT_FATE_SENT,
178                    driverTimestampUSec,
179                    frameTypeMapping.mTypeNumber,
180                    frameBytes
181            );
182            assertTrue(fateReport.toString().contains(
183                    "Frame type: " + frameTypeMapping.mExpectedText));
184        }
185
186        FateMapping[] fateMappings = new FateMapping[] {
187                new FateMapping(WifiLoggerHal.TX_PKT_FATE_ACKED, "acked"),
188                new FateMapping(WifiLoggerHal.TX_PKT_FATE_SENT, "sent"),
189                new FateMapping(WifiLoggerHal.TX_PKT_FATE_FW_QUEUED, "firmware queued"),
190                new FateMapping(WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID,
191                        "firmware dropped (invalid frame)"),
192                new FateMapping(
193                        WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS,  "firmware dropped (no bufs)"),
194                new FateMapping(
195                        WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, "firmware dropped (other)"),
196                new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, "driver queued"),
197                new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID,
198                        "driver dropped (invalid frame)"),
199                new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS,
200                        "driver dropped (no bufs)"),
201                new FateMapping(WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER, "driver dropped (other)"),
202                new FateMapping((byte) 42, "42")
203        };
204        for (FateMapping fateMapping : fateMappings) {
205            fateReport = new WifiNative.TxFateReport(
206                    fateMapping.mFateNumber,
207                    driverTimestampUSec,
208                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
209                    frameBytes
210            );
211            assertTrue(fateReport.toString().contains("Frame fate: " + fateMapping.mExpectedText));
212        }
213    }
214
215    /**
216     * Verifies that RxFateReport.toString() includes the information we care about.
217     */
218    @Test
219    public void testRxFateReportToString() {
220        long driverTimestampUSec = 67890;
221        byte[] frameBytes = new byte[] {
222                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 0, 1, 2, 3, 4, 5, 6, 7};
223        WifiNative.RxFateReport fateReport = new WifiNative.RxFateReport(
224                WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID,
225                driverTimestampUSec,
226                WifiLoggerHal.FRAME_TYPE_ETHERNET_II,
227                frameBytes
228        );
229
230        String fateString = fateReport.toString();
231        assertTrue(fateString.contains("Frame direction: RX"));
232        assertTrue(fateString.contains("Frame timestamp: 67890"));
233        assertTrue(fateString.contains("Frame fate: firmware dropped (invalid frame)"));
234        assertTrue(fateString.contains("Frame type: data"));
235        assertTrue(fateString.contains("Frame length: 16"));
236        assertTrue(fateString.contains(
237                "61 62 63 64 65 66 67 68 00 01 02 03 04 05 06 07")); // hex dump
238        // TODO(quiche): uncomment this, once b/27975149 is fixed.
239        // assertTrue(fateString.contains("abcdefgh........"));  // hex dump
240
241        // FrameTypeMappings omitted, as they're the same as for TX.
242
243        FateMapping[] fateMappings = new FateMapping[] {
244                new FateMapping(WifiLoggerHal.RX_PKT_FATE_SUCCESS, "success"),
245                new FateMapping(WifiLoggerHal.RX_PKT_FATE_FW_QUEUED, "firmware queued"),
246                new FateMapping(
247                        WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, "firmware dropped (filter)"),
248                new FateMapping(WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID,
249                        "firmware dropped (invalid frame)"),
250                new FateMapping(
251                        WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS, "firmware dropped (no bufs)"),
252                new FateMapping(
253                        WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER, "firmware dropped (other)"),
254                new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED, "driver queued"),
255                new FateMapping(
256                        WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER, "driver dropped (filter)"),
257                new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID,
258                        "driver dropped (invalid frame)"),
259                new FateMapping(
260                        WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS, "driver dropped (no bufs)"),
261                new FateMapping(WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER, "driver dropped (other)"),
262                new FateMapping((byte) 42, "42")
263        };
264        for (FateMapping fateMapping : fateMappings) {
265            fateReport = new WifiNative.RxFateReport(
266                    fateMapping.mFateNumber,
267                    driverTimestampUSec,
268                    WifiLoggerHal.FRAME_TYPE_80211_MGMT,
269                    frameBytes
270            );
271            assertTrue(fateReport.toString().contains("Frame fate: " + fateMapping.mExpectedText));
272        }
273    }
274
275
276    /**
277     * Verifies that startPktFateMonitoring returns false when HAL is not started.
278     */
279    @Test
280    public void testStartPktFateMonitoringReturnsFalseWhenHalIsNotStarted() {
281        assertFalse(mWifiNative.isHalStarted());
282        assertFalse(mWifiNative.startPktFateMonitoring());
283    }
284
285    /**
286     * Verifies that getTxPktFates returns error when HAL is not started.
287     */
288    @Test
289    public void testGetTxPktFatesReturnsErrorWhenHalIsNotStarted() {
290        WifiNative.TxFateReport[] fateReports = null;
291        assertFalse(mWifiNative.isHalStarted());
292        assertFalse(mWifiNative.getTxPktFates(fateReports));
293    }
294
295    /**
296     * Verifies that getRxPktFates returns error when HAL is not started.
297     */
298    @Test
299    public void testGetRxPktFatesReturnsErrorWhenHalIsNotStarted() {
300        WifiNative.RxFateReport[] fateReports = null;
301        assertFalse(mWifiNative.isHalStarted());
302        assertFalse(mWifiNative.getRxPktFates(fateReports));
303    }
304
305    // TODO(quiche): Add tests for the success cases (when HAL has been started). Specifically:
306    // - testStartPktFateMonitoringCallsHalIfHalIsStarted()
307    // - testGetTxPktFatesCallsHalIfHalIsStarted()
308    // - testGetRxPktFatesCallsHalIfHalIsStarted()
309    //
310    // Adding these tests is difficult to do at the moment, because we can't mock out the HAL
311    // itself. Also, we can't mock out the native methods, because those methods are private.
312    // b/28005116.
313
314    /** Verifies that getDriverStateDumpNative returns null when HAL is not started. */
315    @Test
316    public void testGetDriverStateDumpReturnsNullWhenHalIsNotStarted() {
317        assertEquals(null, mWifiNative.getDriverStateDump());
318    }
319
320    // TODO(b/28005116): Add test for the success case of getDriverStateDump().
321}
322