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 17 package android.net.wifi.aware; 18 19 import static org.hamcrest.core.IsEqual.equalTo; 20 21 import androidx.test.filters.SmallTest; 22 23 import org.junit.Rule; 24 import org.junit.Test; 25 import org.junit.rules.ErrorCollector; 26 27 import java.nio.BufferOverflowException; 28 import java.util.ArrayList; 29 import java.util.List; 30 31 32 /** 33 * Unit test harness for TlvBufferUtils class. 34 */ 35 @SmallTest 36 public class TlvBufferUtilsTest { 37 @Rule 38 public ErrorCollector collector = new ErrorCollector(); 39 40 /* 41 * TlvBufferUtils Tests 42 */ 43 44 @Test testTlvBuild()45 public void testTlvBuild() { 46 TlvBufferUtils.TlvConstructor tlv11 = new TlvBufferUtils.TlvConstructor(1, 1); 47 tlv11.allocate(15); 48 tlv11.putByte(0, (byte) 2); 49 tlv11.putByteArray(2, new byte[] { 50 0, 1, 2 }); 51 52 collector.checkThat("tlv11-correct-construction", 53 tlv11.getArray(), equalTo(new byte[]{0, 1, 2, 2, 3, 0, 1, 2})); 54 55 TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1); 56 tlv01.allocate(15); 57 tlv01.putByte(0, (byte) 2); 58 tlv01.putByteArray(2, new byte[] { 59 0, 1, 2 }); 60 61 collector.checkThat("tlv01-correct-construction", 62 tlv01.getArray(), equalTo(new byte[] {1, 2, 3, 0, 1, 2 })); 63 64 collector.checkThat("tlv11-valid", 65 TlvBufferUtils.isValid(tlv11.getArray(), 1, 1), 66 equalTo(true)); 67 collector.checkThat("tlv01-valid", 68 TlvBufferUtils.isValid(tlv01.getArray(), 0, 1), 69 equalTo(true)); 70 } 71 72 /** 73 * Validate that re-using a TLV by any of the reallocation method resets it completely. 74 */ 75 @Test testTlvReuse()76 public void testTlvReuse() { 77 TlvBufferUtils.TlvConstructor tlv = new TlvBufferUtils.TlvConstructor(1, 1); 78 79 tlv.allocate(10); 80 tlv.putByte(0, (byte) 2); 81 tlv.putByte(1, (byte) 104); 82 83 collector.checkThat("initial", tlv.getArray(), equalTo(new byte[]{0, 1, 2, 1, 1, 104})); 84 85 tlv.allocate(8); 86 tlv.putByte(5, (byte) 7); 87 collector.checkThat("re-alloc", tlv.getArray(), equalTo(new byte[]{5, 1, 7})); 88 } 89 90 /** 91 * Verify that can build a valid TLV from a List of byte[]. 92 */ 93 @Test testTlvListOperations()94 public void testTlvListOperations() { 95 byte[] entry1 = { 1, 2, 3 }; 96 byte[] entry2 = { 4, 5 }; 97 byte[] entry3 = new byte[0]; 98 List<byte[]> data = new ArrayList<>(); 99 data.add(entry1); 100 data.add(entry2); 101 data.add(entry3); 102 data.add(null); // zero-length should work 103 104 TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1); 105 tlv01.allocateAndPut(data); 106 byte[] tlvData = tlv01.getArray(); 107 List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, tlvData).toList(); 108 109 collector.checkThat("tlvData-correct-length", tlvData.length, 110 equalTo(entry1.length + 1 + entry2.length + 1 + entry3.length + 1 + 1)); 111 collector.checkThat("parsedList-correct-length", parsedList.size(), equalTo(4)); 112 collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(entry1)); 113 collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(entry2)); 114 collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(entry3)); 115 collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0])); 116 } 117 118 /** 119 * Verify that can parse a (correctly formatted) byte array to a list. 120 */ 121 @Test testTlvParseToList()122 public void testTlvParseToList() { 123 byte[] validTlv01 = { 0, 1, 55, 2, 33, 66, 0 }; 124 125 List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, validTlv01).toList(); 126 127 collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(new byte[0])); 128 collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(new byte[] { 55 })); 129 collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(new byte[] { 33, 66 })); 130 collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0])); 131 } 132 133 /** 134 * Verify that an exception is thrown when trying to parse an invalid array. 135 */ 136 @Test(expected = BufferOverflowException.class) testTlvParseToListError()137 public void testTlvParseToListError() { 138 byte[] invalidTlv01 = { 0, 1, 55, 2, 55, 66, 3 }; // bad data 139 140 List<byte[]> data = new TlvBufferUtils.TlvIterable(0, 1, invalidTlv01).toList(); 141 } 142 143 /** 144 * Validate the API which places raw bytes into the TLV (without a TL structure). 145 */ 146 @Test testRawPuts()147 public void testRawPuts() { 148 TlvBufferUtils.TlvConstructor tlv = new TlvBufferUtils.TlvConstructor(1, 1); 149 150 tlv.allocate(10); 151 tlv.putByte(0, (byte) 2); 152 tlv.putRawByte((byte) 55); 153 tlv.putByte(1, (byte) 104); 154 tlv.putRawByteArray(new byte[]{66, 77}); 155 156 collector.checkThat("data", tlv.getArray(), 157 equalTo(new byte[]{0, 1, 2, 55, 1, 1, 104, 66, 77})); 158 } 159 160 @Test testTlvIterate()161 public void testTlvIterate() { 162 final String ascii = "ABC"; 163 final String nonAscii = "何かもっと複雑な"; 164 165 TlvBufferUtils.TlvConstructor tlv22 = new TlvBufferUtils.TlvConstructor(2, 2); 166 tlv22.allocate(18); 167 tlv22.putInt(0, 2); 168 tlv22.putShort(2, (short) 3); 169 tlv22.putZeroLengthElement(55); 170 171 TlvBufferUtils.TlvIterable tlv22It = new TlvBufferUtils.TlvIterable(2, 2, tlv22.getArray()); 172 int count = 0; 173 for (TlvBufferUtils.TlvElement tlv : tlv22It) { 174 if (count == 0) { 175 collector.checkThat("tlv22-correct-iteration-mType", tlv.type, equalTo(0)); 176 collector.checkThat("tlv22-correct-iteration-mLength", tlv.length, equalTo(4)); 177 collector.checkThat("tlv22-correct-iteration-DATA", tlv.getInt(), equalTo(2)); 178 } else if (count == 1) { 179 collector.checkThat("tlv22-correct-iteration-mType", tlv.type, equalTo(2)); 180 collector.checkThat("tlv22-correct-iteration-mLength", tlv.length, equalTo(2)); 181 collector.checkThat("tlv22-correct-iteration-DATA", (int) tlv.getShort(), 182 equalTo(3)); 183 } else if (count == 2) { 184 collector.checkThat("tlv22-correct-iteration-mType", tlv.type, equalTo(55)); 185 collector.checkThat("tlv22-correct-iteration-mLength", tlv.length, equalTo(0)); 186 } else { 187 collector.checkThat("Invalid number of iterations in loop - tlv22", true, 188 equalTo(false)); 189 } 190 ++count; 191 } 192 if (count != 3) { 193 collector.checkThat("Invalid number of iterations outside loop - tlv22", true, 194 equalTo(false)); 195 } 196 197 TlvBufferUtils.TlvConstructor tlv02 = new TlvBufferUtils.TlvConstructor(0, 2); 198 tlv02.allocate(100); 199 tlv02.putByte(0, (byte) 2); 200 tlv02.putString(0, ascii); 201 tlv02.putString(0, nonAscii); 202 tlv02.putByteArray(0, new byte[]{5, 4, 3, 2, 1}); 203 204 TlvBufferUtils.TlvIterable tlv02It = new TlvBufferUtils.TlvIterable(0, 2, tlv02.getArray()); 205 count = 0; 206 for (TlvBufferUtils.TlvElement tlv : tlv02It) { 207 if (count == 0) { 208 collector.checkThat("tlv02-correct-iteration-mLength", tlv.length, equalTo(1)); 209 collector.checkThat("tlv02-correct-iteration-DATA", (int) tlv.getByte(), 210 equalTo(2)); 211 } else if (count == 1) { 212 collector.checkThat("tlv02-correct-iteration-mLength", tlv.length, 213 equalTo(ascii.length())); 214 collector.checkThat("tlv02-correct-iteration-DATA", tlv.getString().equals(ascii), 215 equalTo(true)); 216 } else if (count == 2) { 217 collector.checkThat("tlv02-correct-iteration-mLength", tlv.length, 218 equalTo(nonAscii.getBytes().length)); 219 collector.checkThat("tlv02-correct-iteration-DATA", 220 tlv.getString().equals(nonAscii), equalTo(true)); 221 } else if (count == 3) { 222 collector.checkThat("tlv02-correct-iteration-mLength", tlv.length, 223 equalTo(5)); 224 collector.checkThat("tlv02-correct-iteration-DATA", tlv.getRawData(), 225 equalTo(new byte[]{5, 4, 3, 2, 1})); 226 } else { 227 collector.checkThat("Invalid number of iterations in loop - tlv02", true, 228 equalTo(false)); 229 } 230 ++count; 231 } 232 collector.checkThat("Invalid number of iterations outside loop - tlv02", count, 233 equalTo(4)); 234 235 collector.checkThat("tlv22-valid", 236 TlvBufferUtils.isValid(tlv22.getArray(), 2, 2), 237 equalTo(true)); 238 collector.checkThat("tlv02-valid", 239 TlvBufferUtils.isValid(tlv02.getArray(), 0, 2), 240 equalTo(true)); 241 } 242 243 @Test(expected = IllegalArgumentException.class) testTlvInvalidSizeT1L0()244 public void testTlvInvalidSizeT1L0() { 245 TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 0); 246 } 247 248 @Test(expected = IllegalArgumentException.class) testTlvInvalidSizeTm3L2()249 public void testTlvInvalidSizeTm3L2() { 250 TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(-3, 2); 251 } 252 253 @Test(expected = IllegalArgumentException.class) testTlvInvalidSizeT1Lm2()254 public void testTlvInvalidSizeT1Lm2() { 255 TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, -2); 256 } 257 258 @Test(expected = IllegalArgumentException.class) testTlvInvalidSizeT1L3()259 public void testTlvInvalidSizeT1L3() { 260 TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(1, 3); 261 } 262 263 @Test(expected = IllegalArgumentException.class) testTlvInvalidSizeT3L1()264 public void testTlvInvalidSizeT3L1() { 265 TlvBufferUtils.TlvConstructor tlv10 = new TlvBufferUtils.TlvConstructor(3, 1); 266 } 267 268 @Test(expected = IllegalArgumentException.class) testTlvItInvalidSizeT1L0()269 public void testTlvItInvalidSizeT1L0() { 270 final byte[] testTlv = { 271 0, 1, 2 }; 272 final int testLength = 3; 273 TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 0, testTlv); 274 } 275 276 @Test(expected = IllegalArgumentException.class) testTlvItInvalidSizeTm3L2()277 public void testTlvItInvalidSizeTm3L2() { 278 final byte[] testTlv = { 279 0, 1, 2 }; 280 final int testLength = 3; 281 TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(-3, 2, testTlv); 282 } 283 284 @Test(expected = IllegalArgumentException.class) testTlvItInvalidSizeT1Lm2()285 public void testTlvItInvalidSizeT1Lm2() { 286 final byte[] testTlv = { 287 0, 1, 2 }; 288 final int testLength = 3; 289 TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, -2, testTlv); 290 } 291 292 @Test(expected = IllegalArgumentException.class) testTlvItInvalidSizeT1L3()293 public void testTlvItInvalidSizeT1L3() { 294 final byte[] testTlv = { 295 0, 1, 2 }; 296 final int testLength = 3; 297 TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(1, 3, testTlv); 298 } 299 300 @Test(expected = IllegalArgumentException.class) testTlvItInvalidSizeT3L1()301 public void testTlvItInvalidSizeT3L1() { 302 final byte[] testTlv = { 303 0, 1, 2 }; 304 final int testLength = 3; 305 TlvBufferUtils.TlvIterable tlvIt10 = new TlvBufferUtils.TlvIterable(3, 1, testTlv); 306 } 307 308 /** 309 * Validate that a malformed byte array fails the TLV validity test. 310 */ 311 @Test testTlvInvalidByteArray()312 public void testTlvInvalidByteArray() { 313 TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1); 314 tlv01.allocate(15); 315 tlv01.putByte(0, (byte) 2); 316 tlv01.putByteArray(2, new byte[]{0, 1, 2}); 317 318 byte[] array = tlv01.getArray(); 319 array[0] = 10; 320 321 collector.checkThat("tlv01-invalid", 322 TlvBufferUtils.isValid(array, 0, 1), equalTo(false)); 323 } 324 } 325