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.assertEquals;
20import static org.junit.Assert.assertTrue;
21
22import android.test.suitebuilder.annotation.SmallTest;
23
24import org.junit.Test;
25
26import java.nio.BufferUnderflowException;
27import java.nio.ByteBuffer;
28import java.nio.ByteOrder;
29import java.nio.charset.StandardCharsets;
30
31/**
32 * Unit tests for {@link com.android.server.wifi.ByteBufferReader}.
33 */
34@SmallTest
35public class ByteBufferReaderTest {
36    /**
37     * Verify that BufferUnderflowException will be thrown when reading an integer from a buffer
38     * that contained less data than needed.
39     *
40     * @throws Exception
41     */
42    @Test(expected = BufferUnderflowException.class)
43    public void readIntegerWithBufferUnderflow() throws Exception {
44        byte[] data = new byte[1];
45        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
46        ByteBufferReader.readInteger(buffer, buffer.order(), 2);
47    }
48
49    /**
50     * Verify that IllegalArgumentException will be thrown when reading an integer that exceeds
51     * the maximum integer size.
52     *
53     * @throws Exception
54     */
55    @Test(expected = IllegalArgumentException.class)
56    public void readIntegerExceedingMaximumLength() throws Exception {
57        int length = ByteBufferReader.MAXIMUM_INTEGER_SIZE + 1;
58        byte[] data = new byte[length];
59        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
60        ByteBufferReader.readInteger(buffer, buffer.order(), length);
61    }
62
63    /**
64     * Verify that IllegalArgumentException will be thrown when reading an integer with size
65     * less than the minimum.
66     *
67     * @throws Exception
68     */
69    @Test(expected = IllegalArgumentException.class)
70    public void readIntegerLessThanMinimumLength() throws Exception {
71        int length = ByteBufferReader.MINIMUM_INTEGER_SIZE - 1;
72        byte[] data = new byte[length];
73        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
74        ByteBufferReader.readInteger(buffer, buffer.order(), length);
75    }
76
77    /**
78     * Verify that the expected integer value is returned when reading an integer with minimum
79     * integer size.
80     *
81     * @throws Exception
82     */
83    @Test
84    public void readIntegerWithMinimumSize() throws Exception {
85        byte[] data = new byte[] {0x1};
86        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
87        assertEquals(1, ByteBufferReader.readInteger(buffer, buffer.order(),
88                ByteBufferReader.MINIMUM_INTEGER_SIZE));
89    }
90
91    /**
92     * Verify that the expected integer value is returned when reading an integer with maximum
93     * integer size.
94     *
95     * @throws Exception
96     */
97    @Test
98    public void readIntegerWithMaximumSize() throws Exception {
99        byte[] data = new byte[] {0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11};
100
101        // Little Endian parsing.
102        ByteBuffer leBuffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
103        long leValue = 0x110000000000001fL;
104        assertEquals(leValue, ByteBufferReader.readInteger(leBuffer, leBuffer.order(),
105                ByteBufferReader.MAXIMUM_INTEGER_SIZE));
106
107        // Big Endian parsing.
108        ByteBuffer beBuffer = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN);
109        long beValue = 0x1f00000000000011L;
110        assertEquals(beValue, ByteBufferReader.readInteger(beBuffer, beBuffer.order(),
111                ByteBufferReader.MAXIMUM_INTEGER_SIZE));
112    }
113
114    /**
115     * Verify that NegativeArraySizeException will be thrown when attempting to read a string with
116     * negative size.
117     *
118     * @throws Exception
119     */
120    @Test(expected = NegativeArraySizeException.class)
121    public void readStringWithNegativeSize() throws Exception {
122        ByteBufferReader.readString(ByteBuffer.wrap(new byte[10]), -1, StandardCharsets.US_ASCII);
123    }
124
125    /**
126     * Verify that an empty String will be returned when reading a string with zero size.
127     *
128     * @throws Exception
129     */
130    @Test
131    public void readStringWithZeroSize() throws Exception {
132        String str = ByteBufferReader.readString(
133                ByteBuffer.wrap(new byte[10]), 0, StandardCharsets.US_ASCII);
134        assertTrue(str.isEmpty());
135    }
136
137    /**
138     * Verify that the expected string value is returned when reading a string from a buffer that
139     * contained a valid string.
140     *
141     * @throws Exception
142     */
143    @Test
144    public void readString() throws Exception {
145        String expectedValue = "Hello World";
146        ByteBuffer buffer = ByteBuffer.wrap(expectedValue.getBytes(StandardCharsets.US_ASCII));
147        String actualValue = ByteBufferReader.readString(
148                buffer, buffer.remaining(), StandardCharsets.US_ASCII);
149        assertEquals(expectedValue, actualValue);
150    }
151
152    /**
153     * Verify that the expected string value is returned when reading a buffer that contained the
154     * size of the string and the string value.
155     *
156     * @throws Exception
157     */
158    @Test
159    public void readStringWithByteLength() throws Exception {
160        String expectedValue = "Hello World";
161        ByteBuffer buffer = ByteBuffer.allocate(expectedValue.length() + 1);
162        buffer.put((byte) expectedValue.length());
163        buffer.put(expectedValue.getBytes(StandardCharsets.US_ASCII));
164        // Rewind the buffer's position to the beginning for reading.
165        buffer.position(0);
166        String actualValue =
167                ByteBufferReader.readStringWithByteLength(buffer, StandardCharsets.US_ASCII);
168        assertEquals(expectedValue, actualValue);
169    }
170}
171