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.hotspot2.anqp;
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.util.ArrayList;
30import java.util.List;
31
32/**
33 * Unit tests for {@link com.android.server.wifi.hotspot2.anqp.HSConnectionCapabilityElement}.
34 */
35@SmallTest
36public class HSConnectionCapabilityElementTest {
37    private static final ProtocolPortTuple TEST_TUPLE1 =
38            new ProtocolPortTuple(1, 2, ProtocolPortTuple.PROTO_STATUS_CLOSED);
39    private static final ProtocolPortTuple TEST_TUPLE2 =
40            new ProtocolPortTuple(3, 4, ProtocolPortTuple.PROTO_STATUS_OPEN);
41
42    /**
43     * Helper function for writing a ProtocolPortTuple into a buffer.
44     *
45     * @param buffer The buffer to write to
46     * @param tuple The tuple to write
47     */
48    private void appendProtocolPortTuple(ByteBuffer buffer, ProtocolPortTuple tuple) {
49        buffer.put((byte) tuple.getProtocol());
50        buffer.putShort((short) tuple.getPort());
51        buffer.put((byte) tuple.getStatus());
52    }
53
54    /**
55     * Helper function for generating a buffer with test data.
56     *
57     * @param tuples Tuples to put in the buffer
58     * @return {@link ByteBuffer}
59     */
60    private ByteBuffer getTestBuffer(ProtocolPortTuple[] tuples) {
61        ByteBuffer buffer = ByteBuffer.allocate(tuples.length * ProtocolPortTuple.RAW_BYTE_SIZE)
62                .order(ByteOrder.LITTLE_ENDIAN);
63        for (ProtocolPortTuple tuple : tuples) {
64            appendProtocolPortTuple(buffer, tuple);
65        }
66        buffer.position(0);
67        return buffer;
68    }
69
70    /**
71     * Verify that a HSConnectionCapabilityElement with an empty status list will be returned
72     * when parsing an empty buffer.
73     *
74     * @throws Exception
75     */
76    @Test
77    public void parseEmptyBuffer() throws Exception {
78        HSConnectionCapabilityElement element =
79                HSConnectionCapabilityElement.parse(ByteBuffer.allocate(0));
80        assertTrue(element.getStatusList().isEmpty());
81    }
82
83    /**
84     * Verify that BufferUnderflowException will be thrown when parsing a buffer without
85     * the complete tuple data (missing status field).
86     *
87     * @throws Exception
88     */
89    @Test(expected = BufferUnderflowException.class)
90    public void parseBufferWithLessThanMinimumSize() throws Exception {
91        ByteBuffer buffer = ByteBuffer.allocate(ProtocolPortTuple.RAW_BYTE_SIZE - 1);
92        buffer.put(new byte[ProtocolPortTuple.RAW_BYTE_SIZE - 1]);
93        buffer.position(0);
94        HSConnectionCapabilityElement.parse(buffer);
95    }
96
97    /**
98     * Verify that BufferUnderflowException will be thrown when parsing a buffer that contained
99     * incomplete bytes for a tuple.
100     *
101     * @throws Exception
102     */
103    @Test(expected = BufferUnderflowException.class)
104    public void parseBufferWithIncompleteTupleBytes() throws Exception {
105        // Construct a buffer which will contained a tuple and an extra byte at the end.
106        ByteBuffer buffer = ByteBuffer.allocate(ProtocolPortTuple.RAW_BYTE_SIZE + 1);
107        appendProtocolPortTuple(buffer, TEST_TUPLE1);
108        buffer.put((byte) 0);
109        buffer.position(0);
110        HSConnectionCapabilityElement.parse(buffer);
111    }
112
113    /**
114     * Verify that the expected HSConnectionCapabilityElement is returned when parsing
115     * a buffer containing the test data.
116     *
117     * @throws Exception
118     */
119    @Test
120    public void parseBufferWithTestData() throws Exception {
121        ByteBuffer buffer = getTestBuffer(new ProtocolPortTuple[] {TEST_TUPLE1, TEST_TUPLE2});
122
123        // Setup expected element.
124        List<ProtocolPortTuple> tupleList = new ArrayList<>();
125        tupleList.add(TEST_TUPLE1);
126        tupleList.add(TEST_TUPLE2);
127        HSConnectionCapabilityElement expected = new HSConnectionCapabilityElement(tupleList);
128
129        assertEquals(expected, HSConnectionCapabilityElement.parse(buffer));
130    }
131}
132