WifiNativeTest.java revision 0fcb06473cbe2824e401a80c0520bb1c14ed8f41
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 315} 316