summaryrefslogtreecommitdiffstats
path: root/container-search/src/test/java/com/yahoo/fs4/test/PacketDecoderTestCase.java
blob: d2bdf2327ff2a9b028be0ffb2953dbfd961b6aeb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.fs4.test;

import com.yahoo.fs4.BasicPacket;
import com.yahoo.fs4.BufferTooSmallException;
import com.yahoo.fs4.ErrorPacket;
import com.yahoo.fs4.PacketDecoder;
import com.yahoo.fs4.PacketDecoder.DecodedPacket;
import com.yahoo.fs4.QueryResultPacket;
import org.junit.Test;

import java.nio.ByteBuffer;

import static org.junit.Assert.*;


/**
 * Tests the PacketDecoder
 *
 * @author Bjørn Borud
 */
public class PacketDecoderTestCase {

    static byte[] queryResultPacketData
        = new byte[] {0,0,0,104,
                      0,0,0,217-256,
                      0,0,0,1,
                      0,0,0,0,
                      0,0,0,2,
                      0,0,0,0,0,0,0,5,
                      0x40,0x39,0,0,0,0,0,0,
                      0,0,0,111,
                      0,0,0,97,
                      0,0,0,3, 1,1,1,1,1,1,1,1,1,1,1,1, 0x40,0x37,0,0,0,0,0,23, 0,0,0,7, 0,0,0,36,
                      0,0,0,4, 2,2,2,2,2,2,2,2,2,2,2,2, 0x40,0x35,0,0,0,0,0,21, 0,0,0,8, 0,0,0,37};
    static int len = queryResultPacketData.length;

    /**
     * In this testcase we have exactly one packet which fills the
     * entire buffer
     */
    @Test
    public void testOnePacket () throws BufferTooSmallException {
        ByteBuffer data = ByteBuffer.allocate(len);
        data.put(queryResultPacketData);
        data.flip();

        // not really necessary for testing, but these help visualize
        // the state the buffer should be in so a reader of this test
        // will not have to
        assertEquals(0, data.position());
        assertEquals(len, data.limit());
        assertEquals(len, data.capacity());
        assertEquals(data.limit(), data.capacity());

        PacketDecoder.DecodedPacket p = PacketDecoder.extractPacket(data);
        assertTrue(p.packet instanceof QueryResultPacket);

        // now the buffer should have position == capacity == limit
        assertEquals(len, data.position());
        assertEquals(len, data.limit());
        assertEquals(len, data.capacity());

        // next call to decode on same bufer should result
        // in null and buffer should be reset for writing.
        p = PacketDecoder.extractPacket(data);
        assertTrue(p == null);

        // make sure the buffer is now ready for reading
        assertEquals(0, data.position());
        assertEquals(len, data.limit());
        assertEquals(len, data.capacity());
    }

    /**
     * In this testcase we only have 3 bytes so we can't
     * even determine the size of the packet.
     */
    @Test
    public void testThreeBytesPacket () throws BufferTooSmallException  {
        ByteBuffer data = ByteBuffer.allocate(len);
        data.put(queryResultPacketData, 0, 3);
        data.flip();

        // packetLength() should return -1 since we don't even have
        // the size of the packet
        assertEquals(-1, PacketDecoder.packetLength(data));

        // since we can't determine the size we don't get a packet.
        // the buffer should now be at offset 3 so we can read more
        // data and limit should be set to capacity
        PacketDecoder.DecodedPacket p = PacketDecoder.extractPacket(data);
        assertTrue(p == null);
        assertEquals(3, data.position());
        assertEquals(len, data.limit());
        assertEquals(len, data.capacity());
    }

    /**
     * In this testcase we have a partial packet and room for
     * more data
     */
    @Test
    public void testPartialWithMoreRoom () throws BufferTooSmallException  {
        ByteBuffer data = ByteBuffer.allocate(len);
        data.put(queryResultPacketData, 0, 10);
        data.flip();

        PacketDecoder.DecodedPacket p = PacketDecoder.extractPacket(data);
        assertTrue(p == null);

    }

    /**
     * In this testcase we have one and a half packet
     */
    @Test
    public void testOneAndAHalfPackets () throws BufferTooSmallException {
        int half = len / 2;
        ByteBuffer data = ByteBuffer.allocate(len + half);
        data.put(queryResultPacketData);
        data.put(queryResultPacketData, 0, half);
        assertEquals((len + half), data.position());
        data.flip();

        // the first packet we should be able to extract just fine
        BasicPacket p1 = PacketDecoder.extractPacket(data).packet;
        assertTrue(p1 instanceof QueryResultPacket);

        PacketDecoder.DecodedPacket p2 = PacketDecoder.extractPacket(data);
        assertTrue(p2 == null);

        // at this point the buffer should be ready for more
        // reading so position should be at the end and limit
        // should be at capacity
        assertEquals(half, data.position());
        assertEquals(data.capacity(), data.limit());
    }

    /**
     * Test the case where the buffer is too small for the
     * packet
     */
    @Test
    public void testTooSmallBufferForPacket () {
        ByteBuffer data = ByteBuffer.allocate(10);
        data.put(queryResultPacketData, 0, 10);
        data.flip();

        try {
            PacketDecoder.extractPacket(data);
            fail();
        }
        catch (BufferTooSmallException e) {

        }
    }

    @Test
    public void testErrorPacket() throws BufferTooSmallException {
        ByteBuffer b = ByteBuffer.allocate(100);
        b.putInt(0);
        b.putInt(203);
        b.putInt(1);
        b.putInt(37);
        b.putInt(5);
        b.put(new byte[] { (byte) 'n', (byte) 'a', (byte) 'l', (byte) 'l', (byte) 'e' });
        b.putInt(0, b.position() - 4);
        b.flip();
        DecodedPacket p = PacketDecoder.extractPacket(b);
        ErrorPacket e = (ErrorPacket) p.packet;
        assertEquals("nalle (37)", e.toString());
        assertEquals(203, e.getCode());
        assertEquals(37, e.getErrorCode());
        b = ByteBuffer.allocate(100);
        // warn if encoding support is added untested
        e.encode(b);
        b.position(0);
        assertEquals(4, b.getInt());
        assertEquals(203, b.getInt());
        assertFalse(b.hasRemaining());
    }

}