1 /*
2  * Copyright 2018, OpenCensus Authors
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 io.opencensus.common;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import java.nio.ByteBuffer;
22 import java.nio.ByteOrder;
23 import org.junit.Rule;
24 import org.junit.Test;
25 import org.junit.rules.ExpectedException;
26 import org.junit.runner.RunWith;
27 import org.junit.runners.JUnit4;
28 
29 /** Unit tests for {@link ServerStatsEncoding}. */
30 @RunWith(JUnit4.class)
31 public class ServerStatsEncodingTest {
32 
33   @Rule public final ExpectedException thrown = ExpectedException.none();
34 
35   @Test
encodeDecodeTest()36   public void encodeDecodeTest() throws ServerStatsDeserializationException {
37     ServerStats serverStatsToBeEncoded = null;
38     ServerStats serverStatsDecoded = null;
39     byte[] serialized = null;
40 
41     serverStatsToBeEncoded = ServerStats.create(31, 22, (byte) 1);
42     serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded);
43     serverStatsDecoded = ServerStatsEncoding.parseBytes(serialized);
44     assertThat(serverStatsDecoded).isEqualTo(serverStatsToBeEncoded);
45 
46     serverStatsToBeEncoded = ServerStats.create(0, 22, (byte) 0);
47     serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded);
48     serverStatsDecoded = ServerStatsEncoding.parseBytes(serialized);
49     assertThat(serverStatsDecoded).isEqualTo(serverStatsToBeEncoded);
50 
51     serverStatsToBeEncoded = ServerStats.create(450, 0, (byte) 0);
52     serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded);
53     serverStatsDecoded = ServerStatsEncoding.parseBytes(serialized);
54     assertThat(serverStatsDecoded).isEqualTo(serverStatsToBeEncoded);
55   }
56 
57   @Test
skipUnknownFieldTest()58   public void skipUnknownFieldTest() throws ServerStatsDeserializationException {
59     ServerStats serverStatsToBeEncoded = null;
60     ServerStats serverStatsDecoded = null;
61     byte[] serialized = null;
62 
63     serverStatsToBeEncoded = ServerStats.create(31, 22, (byte) 1);
64     serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded);
65 
66     // Add new field at the end.
67     byte[] serializedExpanded = new byte[serialized.length + 9];
68     System.arraycopy(serialized, 0, serializedExpanded, 0, serialized.length);
69     final ByteBuffer bb = ByteBuffer.wrap(serializedExpanded);
70     bb.order(ByteOrder.LITTLE_ENDIAN);
71     bb.position(serialized.length);
72     bb.put((byte) 255);
73     bb.putLong(0L);
74     byte[] newSerialized = bb.array();
75 
76     serverStatsDecoded = ServerStatsEncoding.parseBytes(newSerialized);
77     assertThat(serverStatsDecoded).isEqualTo(serverStatsToBeEncoded);
78   }
79 
80   @Test
negativeLbLatencyValueTest()81   public void negativeLbLatencyValueTest() throws ServerStatsDeserializationException {
82     ServerStats serverStatsToBeEncoded = null;
83     ServerStats serverStatsDecoded = null;
84     byte[] serialized = null;
85 
86     serverStatsToBeEncoded = ServerStats.create(31, 22, (byte) 1);
87     serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded);
88 
89     // update serialized byte[] with negative value for lbLatency.
90     final ByteBuffer bb = ByteBuffer.wrap(serialized);
91     bb.order(ByteOrder.LITTLE_ENDIAN);
92     bb.position(2);
93     bb.putLong(-100L);
94 
95     byte[] newSerialized = bb.array();
96     thrown.expect(ServerStatsDeserializationException.class);
97     thrown.expectMessage("Serialized ServiceStats contains invalid values");
98     ServerStatsEncoding.parseBytes(newSerialized);
99   }
100 
101   @Test
negativeServerLatencyValueTest()102   public void negativeServerLatencyValueTest() throws ServerStatsDeserializationException {
103     ServerStats serverStatsToBeEncoded = null;
104     ServerStats serverStatsDecoded = null;
105     byte[] serialized = null;
106 
107     serverStatsToBeEncoded = ServerStats.create(31, 22, (byte) 1);
108     serialized = ServerStatsEncoding.toBytes(serverStatsToBeEncoded);
109 
110     // update serialized byte[] with negative value for serviceLatency.
111     final ByteBuffer bb = ByteBuffer.wrap(serialized);
112     bb.order(ByteOrder.LITTLE_ENDIAN);
113     bb.position(11);
114     bb.putLong(-101L);
115 
116     byte[] newSerialized = bb.array();
117     thrown.expect(ServerStatsDeserializationException.class);
118     thrown.expectMessage("Serialized ServiceStats contains invalid values");
119     ServerStatsEncoding.parseBytes(newSerialized);
120   }
121 
122   @Test
emptySerializedBuffer()123   public void emptySerializedBuffer() throws ServerStatsDeserializationException {
124     final ByteBuffer bb = ByteBuffer.allocate(0);
125     bb.order(ByteOrder.LITTLE_ENDIAN);
126 
127     byte[] newSerialized = bb.array();
128     thrown.expect(ServerStatsDeserializationException.class);
129     thrown.expectMessage("Serialized ServerStats buffer is empty");
130     ServerStatsEncoding.parseBytes(newSerialized);
131   }
132 
133   @Test
invalidNegativeVersion()134   public void invalidNegativeVersion() throws ServerStatsDeserializationException {
135     final ByteBuffer bb = ByteBuffer.allocate(10);
136     bb.order(ByteOrder.LITTLE_ENDIAN);
137     bb.put((byte) -1);
138     byte[] newSerialized = bb.array();
139     thrown.expect(ServerStatsDeserializationException.class);
140     thrown.expectMessage("Invalid ServerStats version: -1");
141     ServerStatsEncoding.parseBytes(newSerialized);
142   }
143 
144   @Test
invalidCompatibleVersion()145   public void invalidCompatibleVersion() throws ServerStatsDeserializationException {
146     final ByteBuffer bb = ByteBuffer.allocate(10);
147     bb.order(ByteOrder.LITTLE_ENDIAN);
148     bb.put((byte) (ServerStatsEncoding.CURRENT_VERSION + 1));
149     byte[] newSerialized = bb.array();
150     thrown.expect(ServerStatsDeserializationException.class);
151     thrown.expectMessage(
152         "Invalid ServerStats version: " + (ServerStatsEncoding.CURRENT_VERSION + 1));
153     ServerStatsEncoding.parseBytes(newSerialized);
154   }
155 }
156