1 /*
2   Copyright (c) DataStax, Inc.
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 #include <gtest/gtest.h>
18 
19 #include "decoder.hpp"
20 #include "logger.hpp"
21 
22 using namespace datastax;
23 using namespace datastax::internal;
24 using namespace datastax::internal::core;
25 
26 // Testing decoder class to expose protected testing methods
27 class TestDecoder : public Decoder {
28 public:
TestDecoder(const char * input,size_t length,ProtocolVersion protocol_version=ProtocolVersion::highest_supported ())29   TestDecoder(const char* input, size_t length,
30               ProtocolVersion protocol_version = ProtocolVersion::highest_supported())
31       : Decoder(input, length, protocol_version) {}
32 
buffer() const33   inline const char* buffer() const { return Decoder::buffer(); }
remaining() const34   inline size_t remaining() const { return Decoder::remaining(); }
35 };
36 
37 class DecoderUnitTest : public testing::Test {
38 public:
SetUp()39   void SetUp() {
40     failure_logged_ = false;
41     warning_logged_ = false;
42     cass_log_set_level(CASS_LOG_WARN);
43     Logger::set_callback(DecoderUnitTest::log, NULL);
44   }
45 
log(const CassLogMessage * message,void * data)46   static void log(const CassLogMessage* message, void* data) {
47     std::string function = message->function;
48     if (message->severity == CASS_LOG_ERROR && function.find("Decoder::") != std::string::npos) {
49       failure_logged_ = true;
50     } else if (message->severity == CASS_LOG_WARN &&
51                function.find("Decoder::") != std::string::npos) {
52       warning_logged_ = true;
53     }
54   }
55 
56   static bool warning_logged_;
57   static bool failure_logged_;
58 };
59 
60 bool DecoderUnitTest::failure_logged_ = false;
61 bool DecoderUnitTest::warning_logged_ = false;
62 
TEST_F(DecoderUnitTest,DecodeByte)63 TEST_F(DecoderUnitTest, DecodeByte) {
64   const char input[2] = { -1, 0 };
65   TestDecoder decoder(input, 2);
66   uint8_t value = 0;
67 
68   // SUCCESS
69   ASSERT_TRUE(decoder.decode_byte(value));
70   ASSERT_EQ(&input[1], decoder.buffer());
71   ASSERT_EQ(1ul, decoder.remaining());
72   ASSERT_EQ(std::numeric_limits<uint8_t>::max(), value);
73   ASSERT_TRUE(decoder.decode_byte(value));
74   ASSERT_EQ(0ul, decoder.remaining());
75   ASSERT_EQ(std::numeric_limits<uint8_t>::min(), value);
76 
77   // FAIL
78   ASSERT_FALSE(decoder.decode_byte(value));
79   ASSERT_TRUE(failure_logged_);
80 }
81 
TEST_F(DecoderUnitTest,AsByte)82 TEST_F(DecoderUnitTest, AsByte) {
83   const char input[1] = { -1 };
84   TestDecoder decoder(input, 1);
85   uint8_t value = 0;
86 
87   // SUCCESS
88   for (int i = 0; i < 10; ++i) {
89     ASSERT_TRUE(decoder.as_byte(&value));
90     ASSERT_EQ(&input[0], decoder.buffer());
91     ASSERT_EQ(1ul, decoder.remaining());
92     ASSERT_EQ(std::numeric_limits<uint8_t>::max(), value);
93   }
94 
95   // Decode byte to finish decoding buffer
96   ASSERT_TRUE(decoder.decode_byte(value));
97 
98   // FAIL
99   ASSERT_FALSE(decoder.as_byte(&value));
100   ASSERT_TRUE(failure_logged_);
101 }
102 
TEST_F(DecoderUnitTest,AsBool)103 TEST_F(DecoderUnitTest, AsBool) {
104   const char input[2] = { 0, 1 };
105   TestDecoder decoder(input, 2);
106   bool value = false;
107 
108   // SUCCESS (false)
109   for (int i = 0; i < 10; ++i) {
110     ASSERT_TRUE(decoder.as_bool(&value));
111     ASSERT_EQ(&input[0], decoder.buffer());
112     ASSERT_EQ(2ul, decoder.remaining());
113     ASSERT_FALSE(value);
114   }
115 
116   // Decode byte to move to next bool in buffer
117   uint8_t byte_value = 0;
118   ASSERT_TRUE(decoder.decode_byte(byte_value));
119 
120   // SUCCESS (true)
121   for (int i = 0; i < 10; ++i) {
122     ASSERT_TRUE(decoder.as_bool(&value));
123     ASSERT_EQ(&input[1], decoder.buffer());
124     ASSERT_EQ(1ul, decoder.remaining());
125     ASSERT_TRUE(value);
126   }
127 
128   // Decode byte to finish decoding buffer
129   ASSERT_TRUE(decoder.decode_byte(byte_value));
130 
131   // FAIL
132   ASSERT_FALSE(decoder.as_bool(&value));
133   ASSERT_TRUE(failure_logged_);
134 }
135 
TEST_F(DecoderUnitTest,DecodeInt8)136 TEST_F(DecoderUnitTest, DecodeInt8) {
137   const char input[2] = { -128, 127 };
138   TestDecoder decoder(input, 2);
139   int8_t value = 0;
140 
141   // SUCCESS
142   ASSERT_TRUE(decoder.decode_int8(value));
143   ASSERT_EQ(&input[1], decoder.buffer());
144   ASSERT_EQ(1ul, decoder.remaining());
145   ASSERT_EQ(std::numeric_limits<int8_t>::min(), value);
146   ASSERT_TRUE(decoder.decode_int8(value));
147   ASSERT_EQ(0ul, decoder.remaining());
148   ASSERT_EQ(std::numeric_limits<int8_t>::max(), value);
149 
150   // FAIL
151   ASSERT_FALSE(decoder.decode_int8(value));
152   ASSERT_TRUE(failure_logged_);
153 }
154 
TEST_F(DecoderUnitTest,AsInt8)155 TEST_F(DecoderUnitTest, AsInt8) {
156   const char input[1] = { -128 };
157   TestDecoder decoder(input, 1);
158   int8_t value = 0;
159 
160   // SUCCESS
161   for (int i = 0; i < 10; ++i) {
162     ASSERT_TRUE(decoder.as_int8(&value));
163     ASSERT_EQ(&input[0], decoder.buffer());
164     ASSERT_EQ(1ul, decoder.remaining());
165     ASSERT_EQ(std::numeric_limits<int8_t>::min(), value);
166   }
167 
168   // Decode int8 to finish decoding buffer
169   int8_t int8_value = 0;
170   ASSERT_TRUE(decoder.decode_int8(int8_value));
171 
172   // FAIL
173   ASSERT_FALSE(decoder.as_int8(&value));
174   ASSERT_TRUE(failure_logged_);
175 }
176 
TEST_F(DecoderUnitTest,DecodeUInt16)177 TEST_F(DecoderUnitTest, DecodeUInt16) {
178   const char input[4] = { -1, -1, 0, 0 };
179   TestDecoder decoder(input, 4);
180   uint16_t value = 0;
181 
182   // SUCCESS
183   ASSERT_TRUE(decoder.decode_uint16(value));
184   ASSERT_EQ(&input[2], decoder.buffer());
185   ASSERT_EQ(2ul, decoder.remaining());
186   ASSERT_EQ(std::numeric_limits<uint16_t>::max(), value);
187   ASSERT_TRUE(decoder.decode_uint16(value));
188   ASSERT_EQ(0ul, decoder.remaining());
189   ASSERT_EQ(std::numeric_limits<uint16_t>::min(), value);
190 
191   // FAIL
192   ASSERT_FALSE(decoder.decode_uint16(value));
193   ASSERT_TRUE(failure_logged_);
194 }
195 
TEST_F(DecoderUnitTest,DecodeInt16)196 TEST_F(DecoderUnitTest, DecodeInt16) {
197   const char input[4] = { -128, 0, 127, -1 };
198   TestDecoder decoder(input, 4);
199   int16_t value = 0;
200 
201   // SUCCESS
202   ASSERT_TRUE(decoder.decode_int16(value));
203   ASSERT_EQ(&input[2], decoder.buffer());
204   ASSERT_EQ(2ul, decoder.remaining());
205   ASSERT_EQ(std::numeric_limits<int16_t>::min(), value);
206   ASSERT_TRUE(decoder.decode_int16(value));
207   ASSERT_EQ(0ul, decoder.remaining());
208   ASSERT_EQ(std::numeric_limits<int16_t>::max(), value);
209 
210   // FAIL
211   ASSERT_FALSE(decoder.decode_int16(value));
212   ASSERT_TRUE(failure_logged_);
213 }
214 
TEST_F(DecoderUnitTest,AsInt16)215 TEST_F(DecoderUnitTest, AsInt16) {
216   const char input[2] = { -128, 0 };
217   TestDecoder decoder(input, 2);
218   int16_t value = 0;
219 
220   // SUCCESS
221   for (int i = 0; i < 10; ++i) {
222     ASSERT_TRUE(decoder.as_int16(&value));
223     ASSERT_EQ(&input[0], decoder.buffer());
224     ASSERT_EQ(2ul, decoder.remaining());
225     ASSERT_EQ(std::numeric_limits<int16_t>::min(), value);
226   }
227 
228   // Decode int16 to finish decoding buffer
229   int16_t int16_value = 0;
230   ASSERT_TRUE(decoder.decode_int16(int16_value));
231 
232   // FAIL
233   ASSERT_FALSE(decoder.as_int16(&value));
234   ASSERT_TRUE(failure_logged_);
235 }
236 
TEST_F(DecoderUnitTest,DecodeUInt32)237 TEST_F(DecoderUnitTest, DecodeUInt32) {
238   const char input[8] = { -1, -1, -1, -1, 0, 0, 0, 0 };
239   TestDecoder decoder(input, 8);
240   uint32_t value = 0;
241 
242   // SUCCESS
243   ASSERT_TRUE(decoder.decode_uint32(value));
244   ASSERT_EQ(&input[4], decoder.buffer());
245   ASSERT_EQ(4ul, decoder.remaining());
246   ASSERT_EQ(std::numeric_limits<uint32_t>::max(), value);
247   ASSERT_TRUE(decoder.decode_uint32(value));
248   ASSERT_EQ(std::numeric_limits<uint32_t>::min(), value);
249   ASSERT_EQ(0ul, decoder.remaining());
250 
251   // FAIL
252   ASSERT_FALSE(decoder.decode_uint32(value));
253   ASSERT_TRUE(failure_logged_);
254 }
255 
TEST_F(DecoderUnitTest,AsUInt32)256 TEST_F(DecoderUnitTest, AsUInt32) {
257   const char input[4] = { -1, -1, -1, -1 };
258   TestDecoder decoder(input, 4);
259   uint32_t value = 0;
260 
261   // SUCCESS
262   for (int i = 0; i < 10; ++i) {
263     ASSERT_TRUE(decoder.as_uint32(&value));
264     ASSERT_EQ(&input[0], decoder.buffer());
265     ASSERT_EQ(std::numeric_limits<uint32_t>::max(), value);
266   }
267 
268   // Decode uint32 to finish decoding buffer
269   uint32_t uint32_value = 0;
270   ASSERT_TRUE(decoder.decode_uint32(uint32_value));
271 
272   // FAIL
273   ASSERT_FALSE(decoder.as_uint32(&value));
274   ASSERT_TRUE(failure_logged_);
275 }
276 
TEST_F(DecoderUnitTest,DecodeInt32)277 TEST_F(DecoderUnitTest, DecodeInt32) {
278   const char input[8] = { -128, 0, 0, 0, 127, -1, -1, -1 };
279   TestDecoder decoder(input, 8);
280   int32_t value = 0;
281 
282   // SUCCESS
283   ASSERT_TRUE(decoder.decode_int32(value));
284   ASSERT_EQ(&input[4], decoder.buffer());
285   ASSERT_EQ(4ul, decoder.remaining());
286   ASSERT_EQ(std::numeric_limits<int32_t>::min(), value);
287   ASSERT_TRUE(decoder.decode_int32(value));
288   ASSERT_EQ(0ul, decoder.remaining());
289   ASSERT_EQ(std::numeric_limits<int32_t>::max(), value);
290 
291   // FAIL
292   ASSERT_FALSE(decoder.decode_int32(value));
293   ASSERT_TRUE(failure_logged_);
294 }
295 
TEST_F(DecoderUnitTest,AsInt32)296 TEST_F(DecoderUnitTest, AsInt32) {
297   const char input[4] = { -128, 0, 0, 0 };
298   TestDecoder decoder(input, 4);
299   int32_t value = 0;
300 
301   // SUCCESS
302   for (int i = 0; i < 10; ++i) {
303     ASSERT_TRUE(decoder.as_int32(&value));
304     ASSERT_EQ(&input[0], decoder.buffer());
305     ASSERT_EQ(4ul, decoder.remaining());
306     ASSERT_EQ(std::numeric_limits<int32_t>::min(), value);
307   }
308 
309   // Decode int32 to finish decoding buffer
310   int32_t int32_value = 0;
311   ASSERT_TRUE(decoder.decode_int32(int32_value));
312 
313   // FAIL
314   ASSERT_FALSE(decoder.as_int32(&value));
315   ASSERT_TRUE(failure_logged_);
316 }
317 
TEST_F(DecoderUnitTest,DecodeInt64)318 TEST_F(DecoderUnitTest, DecodeInt64) {
319   const char input[16] = { -128, 0, 0, 0, 0, 0, 0, 0, 127, -1, -1, -1, -1, -1, -1, -1 };
320   TestDecoder decoder(input, 16);
321   int64_t value = 0;
322 
323   // SUCCESS
324   ASSERT_TRUE(decoder.decode_int64(value));
325   ASSERT_EQ(&input[8], decoder.buffer());
326   ASSERT_EQ(8ul, decoder.remaining());
327   ASSERT_EQ(std::numeric_limits<int64_t>::min(), value);
328   ASSERT_TRUE(decoder.decode_int64(value));
329   ASSERT_EQ(0ul, decoder.remaining());
330   ASSERT_EQ(std::numeric_limits<int64_t>::max(), value);
331 
332   // FAIL
333   ASSERT_FALSE(decoder.decode_int64(value));
334   ASSERT_TRUE(failure_logged_);
335 }
336 
TEST_F(DecoderUnitTest,AsInt64)337 TEST_F(DecoderUnitTest, AsInt64) {
338   const char input[8] = { -128, 0, 0, 0, 0, 0, 0, 0 };
339   TestDecoder decoder(input, 8);
340   cass_int64_t value = 0;
341 
342   // SUCCESS
343   for (int i = 0; i < 10; ++i) {
344     ASSERT_TRUE(decoder.as_int64(&value));
345     ASSERT_EQ(&input[0], decoder.buffer());
346     ASSERT_EQ(8ul, decoder.remaining());
347     ASSERT_EQ(std::numeric_limits<cass_int64_t>::min(), value);
348   }
349 
350   // Decode in64 to finish decoding buffer
351   int64_t int64_value = 0;
352   ASSERT_TRUE(decoder.decode_int64(int64_value));
353 
354   // FAIL
355   ASSERT_FALSE(decoder.as_int64(&value));
356   ASSERT_TRUE(failure_logged_);
357 }
358 
TEST_F(DecoderUnitTest,DecodeFloat)359 TEST_F(DecoderUnitTest, DecodeFloat) {
360   const char input[8] = { 0, -128, 0, 0, 127, 127, -1, -1 };
361   TestDecoder decoder(input, 8);
362   float value = 0;
363 
364   // SUCCESS
365   ASSERT_TRUE(decoder.decode_float(value));
366   ASSERT_EQ(&input[4], decoder.buffer());
367   ASSERT_EQ(4ul, decoder.remaining());
368   ASSERT_EQ(std::numeric_limits<float>::min(), value);
369   ASSERT_TRUE(decoder.decode_float(value));
370   ASSERT_EQ(0ul, decoder.remaining());
371   ASSERT_EQ(std::numeric_limits<float>::max(), value);
372 
373   // FAIL
374   ASSERT_FALSE(decoder.decode_float(value));
375   ASSERT_TRUE(failure_logged_);
376 }
377 
TEST_F(DecoderUnitTest,AsFloat)378 TEST_F(DecoderUnitTest, AsFloat) {
379   const char input[4] = { 0, -128, 0, 0 };
380   TestDecoder decoder(input, 4);
381   float value = 0.0f;
382 
383   // SUCCESS
384   for (int i = 0; i < 10; ++i) {
385     ASSERT_TRUE(decoder.as_float(&value));
386     ASSERT_EQ(&input[0], decoder.buffer());
387     ASSERT_EQ(4ul, decoder.remaining());
388     ASSERT_EQ(std::numeric_limits<float>::min(), value);
389   }
390 
391   // Decode int32 to finish decoding buffer
392   float float_value = 0;
393   ASSERT_TRUE(decoder.decode_float(float_value));
394 
395   // FAIL
396   ASSERT_FALSE(decoder.as_float(&value));
397   ASSERT_TRUE(failure_logged_);
398 }
399 
TEST_F(DecoderUnitTest,DecodeDouble)400 TEST_F(DecoderUnitTest, DecodeDouble) {
401   const char input[16] = { 0, 16, 0, 0, 0, 0, 0, 0, 127, -17, -1, -1, -1, -1, -1, -1 };
402   TestDecoder decoder(input, 16);
403   double value = 0;
404 
405   // SUCCESS
406   ASSERT_TRUE(decoder.decode_double(value));
407   ASSERT_EQ(&input[8], decoder.buffer());
408   ASSERT_EQ(8ul, decoder.remaining());
409   ASSERT_EQ(std::numeric_limits<double>::min(), value);
410   ASSERT_TRUE(decoder.decode_double(value));
411   ASSERT_EQ(0ul, decoder.remaining());
412   ASSERT_EQ(std::numeric_limits<double>::max(), value);
413 
414   // FAIL
415   ASSERT_FALSE(decoder.decode_double(value));
416   ASSERT_TRUE(failure_logged_);
417 }
418 
TEST_F(DecoderUnitTest,AsDouble)419 TEST_F(DecoderUnitTest, AsDouble) {
420   const char input[8] = { 0, 16, 0, 0, 0, 0, 0, 0 };
421   TestDecoder decoder(input, 8);
422   double value = 0.0;
423 
424   // SUCCESS
425   for (int i = 0; i < 10; ++i) {
426     ASSERT_TRUE(decoder.as_double(&value));
427     ASSERT_EQ(&input[0], decoder.buffer());
428     ASSERT_EQ(8ul, decoder.remaining());
429     ASSERT_EQ(std::numeric_limits<double>::min(), value);
430   }
431 
432   // Decode int64 to finish decoding buffer
433   double double_value = 0;
434   ASSERT_TRUE(decoder.decode_double(double_value));
435 
436   // FAIL
437   ASSERT_FALSE(decoder.as_double(&value));
438   ASSERT_TRUE(failure_logged_);
439 }
440 
TEST_F(DecoderUnitTest,DecodeString)441 TEST_F(DecoderUnitTest, DecodeString) {
442   const char input[17] = { 0, 8, 68, 97, 116, 97, 83, 116, 97, 120, // DataStax
443                            0, 5, 67, 47, 67,  43, 43 };             // C/C++
444   TestDecoder decoder(input, 17);
445   const char* value = NULL;
446   size_t value_size = 0;
447 
448   // SUCCESS
449   ASSERT_TRUE(decoder.decode_string(&value, value_size));
450   ASSERT_EQ(&input[10], decoder.buffer());
451   ASSERT_EQ(7ul, decoder.remaining());
452   ASSERT_EQ(8ul, value_size);
453   ASSERT_STREQ("DataStax", std::string(value, value_size).c_str());
454   ASSERT_TRUE(decoder.decode_string(&value, value_size));
455   ASSERT_EQ(0ul, decoder.remaining());
456   ASSERT_EQ(5ul, value_size);
457   ASSERT_STREQ("C/C++", std::string(value, value_size).c_str());
458 
459   // FAIL
460   ASSERT_FALSE(decoder.decode_string(&value, value_size));
461   ASSERT_TRUE(failure_logged_);
462 }
463 
TEST_F(DecoderUnitTest,DecodeStringRef)464 TEST_F(DecoderUnitTest, DecodeStringRef) {
465   const char input[17] = { 0, 8, 68, 97, 116, 97, 83, 116, 97, 120, // DataStax
466                            0, 5, 67, 47, 67,  43, 43 };             // C/C++
467   TestDecoder decoder(input, 17);
468   StringRef value;
469 
470   // SUCCESS
471   ASSERT_TRUE(decoder.decode_string(&value));
472   ASSERT_EQ(&input[10], decoder.buffer());
473   ASSERT_EQ(7ul, decoder.remaining());
474   ASSERT_EQ(8ul, value.size());
475   ASSERT_STREQ("DataStax", std::string(value.data(), value.size()).c_str());
476   ASSERT_TRUE(decoder.decode_string(&value));
477   ASSERT_EQ(0ul, decoder.remaining());
478   ASSERT_EQ(5ul, value.size());
479   ASSERT_STREQ("C/C++", std::string(value.data(), value.size()).c_str());
480 
481   // FAIL
482   ASSERT_FALSE(decoder.decode_string(&value));
483   ASSERT_TRUE(failure_logged_);
484 }
485 
TEST_F(DecoderUnitTest,DecodeLongString)486 TEST_F(DecoderUnitTest, DecodeLongString) {
487   const char input[21] = { 0, 0, 0, 8, 68, 97, 116, 97, 83, 116, 97, 120, // DataStax
488                            0, 0, 0, 5, 67, 47, 67,  43, 43 };             // C/C++
489   TestDecoder decoder(input, 21);
490   const char* value = NULL;
491   size_t value_size = 0;
492 
493   // SUCCESS
494   ASSERT_TRUE(decoder.decode_long_string(&value, value_size));
495   ASSERT_EQ(&input[12], decoder.buffer());
496   ASSERT_EQ(9ul, decoder.remaining());
497   ASSERT_EQ(8ul, value_size);
498   ASSERT_STREQ("DataStax", std::string(value, value_size).c_str());
499   ASSERT_TRUE(decoder.decode_long_string(&value, value_size));
500   ASSERT_EQ(0ul, decoder.remaining());
501   ASSERT_EQ(5ul, value_size);
502   ASSERT_STREQ("C/C++", std::string(value, value_size).c_str());
503 
504   // FAIL
505   ASSERT_FALSE(decoder.decode_long_string(&value, value_size));
506   ASSERT_TRUE(failure_logged_);
507 }
508 
TEST_F(DecoderUnitTest,DecodeBytes)509 TEST_F(DecoderUnitTest, DecodeBytes) {
510   const char input[21] = { 0, 0, 0, 8, 68, 97, 116, 97, 83, 116, 97, 120, // DataStax
511                            0, 0, 0, 5, 67, 47, 67,  43, 43 };             // C/C++
512   TestDecoder decoder(input, 21);
513   const char* value = NULL;
514   size_t value_size = 0;
515 
516   // SUCCESS
517   ASSERT_TRUE(decoder.decode_bytes(&value, value_size));
518   ASSERT_EQ(&input[12], decoder.buffer());
519   ASSERT_EQ(9ul, decoder.remaining());
520   ASSERT_EQ(8ul, value_size);
521   for (int i = 0; i < 8; ++i) {
522     ASSERT_EQ(input[i + 4], value[i]);
523   }
524   ASSERT_TRUE(decoder.decode_bytes(&value, value_size));
525   ASSERT_EQ(0ul, decoder.remaining());
526   ASSERT_EQ(5ul, value_size);
527   for (int i = 0; i < 5; ++i) {
528     ASSERT_EQ(input[i + 16], value[i]);
529   }
530 
531   // FAIL
532   ASSERT_FALSE(decoder.decode_bytes(&value, value_size));
533   ASSERT_TRUE(failure_logged_);
534 }
535 
TEST_F(DecoderUnitTest,DecodeBytesRef)536 TEST_F(DecoderUnitTest, DecodeBytesRef) {
537   const char input[21] = { 0, 0, 0, 8, 68, 97, 116, 97, 83, 116, 97, 120, // DataStax
538                            0, 0, 0, 5, 67, 47, 67,  43, 43 };             // C/C++
539   TestDecoder decoder(input, 21);
540   StringRef value;
541 
542   // SUCCESS
543   ASSERT_TRUE(decoder.decode_bytes(&value));
544   ASSERT_EQ(&input[12], decoder.buffer());
545   ASSERT_EQ(9ul, decoder.remaining());
546   ASSERT_EQ(8ul, value.size());
547   for (int i = 0; i < 8; ++i) {
548     ASSERT_EQ(input[i + 4], value.data()[i]);
549   }
550   ASSERT_TRUE(decoder.decode_bytes(&value));
551   ASSERT_EQ(0ul, decoder.remaining());
552   ASSERT_EQ(5ul, value.size());
553   for (int i = 0; i < 5; ++i) {
554     ASSERT_EQ(input[i + 16], value.data()[i]);
555   }
556 
557   // FAIL
558   ASSERT_FALSE(decoder.decode_bytes(&value));
559   ASSERT_TRUE(failure_logged_);
560 }
561 
TEST_F(DecoderUnitTest,DecodeInetAddress)562 TEST_F(DecoderUnitTest, DecodeInetAddress) {
563   const char input[30] = {
564     4,  127, 0, 0, 1, 0, 0, 35, 82, // 127.0.0.1:9042
565     16, 0,   0, 0, 0, 0, 0, 0,  0,  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 35, 82
566   }; // [::1]:9042
567   TestDecoder decoder(input, 30);
568   Address value;
569 
570   // SUCCESS
571   ASSERT_TRUE(decoder.decode_inet(&value));
572   ASSERT_EQ(&input[9], decoder.buffer());
573   ASSERT_EQ(21ul, decoder.remaining());
574   ASSERT_STREQ("127.0.0.1:9042", value.to_string(true).c_str());
575   ASSERT_TRUE(decoder.decode_inet(&value));
576   ASSERT_EQ(0ul, decoder.remaining());
577   ASSERT_STREQ("[::1]:9042", value.to_string(true).c_str());
578 
579   // FAIL
580   ASSERT_FALSE(decoder.decode_inet(&value));
581   ASSERT_TRUE(failure_logged_);
582 }
583 
TEST_F(DecoderUnitTest,DecodeInetStruct)584 TEST_F(DecoderUnitTest, DecodeInetStruct) {
585   const char input[22] = { 4,  127, 0, 0, 1,                                       // 127.0.0.1
586                            16, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; // [::1]
587   TestDecoder decoder(input, 22);
588   CassInet value;
589 
590   // SUCCESS
591   ASSERT_TRUE(decoder.decode_inet(&value));
592   ASSERT_EQ(&input[5], decoder.buffer());
593   ASSERT_EQ(17ul, decoder.remaining());
594   for (int i = 0; i < value.address_length; ++i) {
595     uint8_t byte = 0;
596     decode_byte(&input[i + 1], byte);
597     ASSERT_EQ(byte, value.address[i]);
598   }
599   ASSERT_TRUE(decoder.decode_inet(&value));
600   ASSERT_EQ(0ul, decoder.remaining());
601   for (int i = 0; i < value.address_length; ++i) {
602     uint8_t byte = 0;
603     decode_byte(&input[i + 6], byte);
604     ASSERT_EQ(byte, value.address[i]);
605   }
606 
607   // FAIL
608   ASSERT_FALSE(decoder.decode_inet(&value));
609   ASSERT_TRUE(failure_logged_);
610 }
611 
TEST_F(DecoderUnitTest,AsInetIPv4)612 TEST_F(DecoderUnitTest, AsInetIPv4) {
613   const char input[4] = { 127, 0, 0, 1 }; // 127.0.0.1
614   TestDecoder decoder(input, 4);
615   CassInet value;
616 
617   // SUCCESS (IPv4)
618   for (int i = 0; i < 10; ++i) {
619     ASSERT_TRUE(decoder.as_inet(4, &value));
620     ASSERT_EQ(&input[0], decoder.buffer());
621     ASSERT_EQ(4ul, decoder.remaining());
622     for (int j = 0; j < value.address_length; ++j) {
623       uint8_t byte = 0;
624       decode_byte(&input[j], byte);
625       ASSERT_EQ(byte, value.address[j]);
626     }
627   }
628   ASSERT_FALSE(failure_logged_);
629 }
630 
TEST_F(DecoderUnitTest,AsInetIPv6)631 TEST_F(DecoderUnitTest, AsInetIPv6) {
632   const char input[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; // [::1]
633   TestDecoder decoder(input, 16);
634   CassInet value;
635 
636   // SUCCESS (IPv6)
637   for (int i = 0; i < 10; ++i) {
638     ASSERT_TRUE(decoder.as_inet(16, &value));
639     ASSERT_EQ(&input[0], decoder.buffer());
640     ASSERT_EQ(16ul, decoder.remaining());
641     for (int j = 0; j < value.address_length; ++j) {
642       uint8_t byte = 0;
643       decode_byte(&input[j], byte);
644       ASSERT_EQ(byte, value.address[j]);
645     }
646   }
647   ASSERT_FALSE(failure_logged_);
648 }
649 
TEST_F(DecoderUnitTest,DecodeStringMap)650 TEST_F(DecoderUnitTest, DecodeStringMap) {
651   const char input[38] = { 0, 2, 0,   7,  99,  111, 109, 112, 97,  110, 121, // key = company
652                            0, 8, 68,  97, 116, 97,  83,  116, 97,  120,      // value = DataStax
653                            0, 8, 108, 97, 110, 103, 117, 97,  103, 101,      // key = language
654                            0, 5, 67,  47, 67,  43,  43 };                    // value = C/C++
655   TestDecoder decoder(input, 38);
656   Map<String, String> value;
657 
658   // SUCCESS
659   ASSERT_TRUE(decoder.decode_string_map(value));
660   ASSERT_EQ(&input[38], decoder.buffer());
661   ASSERT_EQ(0ul, decoder.remaining());
662   ASSERT_EQ(2ul, value.size());
663   ASSERT_STREQ("DataStax", value["company"].c_str());
664   ASSERT_STREQ("C/C++", value["language"].c_str());
665 
666   // FAIL
667   ASSERT_FALSE(decoder.decode_string_map(value));
668   ASSERT_TRUE(failure_logged_);
669 }
670 
TEST_F(DecoderUnitTest,DecodeStringlistVector)671 TEST_F(DecoderUnitTest, DecodeStringlistVector) {
672   const char input[19] = { 0, 2, 0,  8,  68, 97, 116, 97, 83, 116, 97, 120, // DataStax
673                            0, 5, 67, 47, 67, 43, 43 };                      // C/C++
674   TestDecoder decoder(input, 19);
675   Vector<String> value;
676 
677   // SUCCESS
678   ASSERT_TRUE(decoder.decode_stringlist(value));
679   ASSERT_EQ(&input[19], decoder.buffer());
680   ASSERT_EQ(0ul, decoder.remaining());
681   ASSERT_EQ(2ul, value.size());
682   ASSERT_STREQ("DataStax", value[0].c_str());
683   ASSERT_STREQ("C/C++", value[1].c_str());
684 
685   // FAIL
686   ASSERT_FALSE(decoder.decode_stringlist(value));
687   ASSERT_TRUE(failure_logged_);
688 }
689 
TEST_F(DecoderUnitTest,DecodeStringlistStringRefVec)690 TEST_F(DecoderUnitTest, DecodeStringlistStringRefVec) {
691   const char input[19] = { 0, 2, 0,  8,  68, 97, 116, 97, 83, 116, 97, 120, // DataStax
692                            0, 5, 67, 47, 67, 43, 43 };                      // C/C++
693   TestDecoder decoder(input, 19);
694   StringRefVec value;
695 
696   // SUCCESS
697   ASSERT_TRUE(decoder.decode_stringlist(value));
698   ASSERT_EQ(&input[19], decoder.buffer());
699   ASSERT_EQ(0ul, decoder.remaining());
700   ASSERT_EQ(2ul, value.size());
701   ASSERT_STREQ("DataStax", std::string(value[0].data(), value[0].size()).c_str());
702   ASSERT_STREQ("C/C++", std::string(value[1].data(), value[1].size()).c_str());
703 
704   // FAIL
705   ASSERT_FALSE(decoder.decode_stringlist(value));
706   ASSERT_TRUE(failure_logged_);
707 }
708 
TEST_F(DecoderUnitTest,AsStringlist)709 TEST_F(DecoderUnitTest, AsStringlist) {
710   const char input[19] = { 0, 2, 0,  8,  68, 97, 116, 97, 83, 116, 97, 120, // DataStax
711                            0, 5, 67, 47, 67, 43, 43 };                      // C/C++
712   TestDecoder decoder(input, 19);
713   StringRefVec value;
714 
715   // SUCCESS
716   for (int i = 0; i < 10; ++i) {
717     ASSERT_TRUE(decoder.as_stringlist(value));
718     ASSERT_EQ(&input[0], decoder.buffer());
719     ASSERT_EQ(19ul, decoder.remaining());
720     ASSERT_EQ(2ul, value.size());
721     ASSERT_STREQ("DataStax", std::string(value[0].data(), value[0].size()).c_str());
722     ASSERT_STREQ("C/C++", std::string(value[1].data(), value[1].size()).c_str());
723   }
724 
725   // Decode stringlist to finish decoding buffer
726   ASSERT_TRUE(decoder.decode_stringlist(value));
727 
728   // FAIL
729   ASSERT_FALSE(decoder.as_stringlist(value));
730   ASSERT_TRUE(failure_logged_);
731 }
732 
TEST_F(DecoderUnitTest,DecodeStringMultiMap)733 TEST_F(DecoderUnitTest, DecodeStringMultiMap) {
734   const char input[58] = { 0, 1, 0,  7,   100, 114, 105, 118, 101, 114, 115, // key = drivers
735                            0, 7, 0,  5,   67,  47,  67,  43,  43,            // C/C++
736                            0, 2, 67, 35,                                     // C#
737                            0, 4, 74, 97,  118, 97,                           // Java
738                            0, 7, 78, 111, 100, 101, 46,  106, 115,           // Node.js
739                            0, 3, 80, 72,  80,                                // PHP
740                            0, 6, 80, 121, 116, 104, 111, 110,                // Python
741                            0, 4, 82, 117, 98,  121 };                        // Ruby
742   TestDecoder decoder(input, 58);
743   StringMultimap value;
744 
745   // SUCCESS
746   ASSERT_TRUE(decoder.decode_string_multimap(value));
747   ASSERT_EQ(&input[58], decoder.buffer());
748   ASSERT_EQ(0ul, decoder.remaining());
749   ASSERT_EQ(1ul, value.size());
750   Vector<String> values = value["drivers"];
751   ASSERT_EQ(7ul, values.size());
752   ASSERT_STREQ("C/C++", std::string(values[0].data(), values[0].size()).c_str());
753   ASSERT_STREQ("C#", std::string(values[1].data(), values[1].size()).c_str());
754   ASSERT_STREQ("Java", std::string(values[2].data(), values[2].size()).c_str());
755   ASSERT_STREQ("Node.js", std::string(values[3].data(), values[3].size()).c_str());
756   ASSERT_STREQ("PHP", std::string(values[4].data(), values[4].size()).c_str());
757   ASSERT_STREQ("Python", std::string(values[5].data(), values[5].size()).c_str());
758   ASSERT_STREQ("Ruby", std::string(values[6].data(), values[6].size()).c_str());
759 
760   // FAIL
761   ASSERT_FALSE(decoder.decode_string_multimap(value));
762   ASSERT_TRUE(failure_logged_);
763 }
764 
TEST_F(DecoderUnitTest,DecodeOption)765 TEST_F(DecoderUnitTest, DecodeOption) {
766   const char input[14] = { 0, 1,                                            // ASCII
767                            0, 0, 0, 8, 68, 97, 116, 97, 83, 116, 97, 120 }; // Custom = DataStax
768   TestDecoder decoder(input, 14);
769   uint16_t type;
770   const char* class_name = NULL;
771   size_t class_name_size = 0;
772 
773   // SUCCESS
774   ASSERT_TRUE(decoder.decode_option(type, &class_name, class_name_size));
775   ASSERT_EQ(&input[2], decoder.buffer());
776   ASSERT_EQ(12ul, decoder.remaining());
777   ASSERT_EQ(CASS_VALUE_TYPE_ASCII, type);
778   ASSERT_TRUE(decoder.decode_option(type, &class_name, class_name_size));
779   ASSERT_EQ(0ul, decoder.remaining());
780   ASSERT_EQ(CASS_VALUE_TYPE_CUSTOM, type);
781   ASSERT_STREQ("DataStax", std::string(class_name, class_name_size).c_str());
782   ASSERT_EQ(8ul, class_name_size);
783 
784   // FAIL
785   ASSERT_FALSE(decoder.decode_option(type, &class_name, class_name_size));
786   ASSERT_TRUE(failure_logged_);
787 }
788 
TEST_F(DecoderUnitTest,DecodeUuid)789 TEST_F(DecoderUnitTest, DecodeUuid) {
790   const char input[32] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
791                            0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 };
792   TestDecoder decoder(input, 32);
793   CassUuid value;
794 
795   // SUCCESS
796   ASSERT_TRUE(decoder.decode_uuid(&value));
797   ASSERT_EQ(&input[16], decoder.buffer());
798   ASSERT_EQ(16ul, decoder.remaining());
799   ASSERT_EQ(std::numeric_limits<uint64_t>::max(), value.clock_seq_and_node);
800   ASSERT_EQ(std::numeric_limits<uint64_t>::max(), value.time_and_version);
801   ASSERT_TRUE(decoder.decode_uuid(&value));
802   ASSERT_EQ(0ul, decoder.remaining());
803   ASSERT_EQ(std::numeric_limits<uint64_t>::min(), value.clock_seq_and_node);
804   ASSERT_EQ(std::numeric_limits<uint64_t>::min(), value.time_and_version);
805 
806   // FAIL
807   ASSERT_FALSE(decoder.decode_uuid(&value));
808   ASSERT_TRUE(failure_logged_);
809 }
810 
TEST_F(DecoderUnitTest,AsDecimal)811 TEST_F(DecoderUnitTest, AsDecimal) {
812   const char input[8] = { 0, 0, 0, 4, 0, 1, 2, 3 };
813   TestDecoder decoder(input, 8);
814   const uint8_t* value = NULL;
815   size_t value_size = 0;
816   int32_t value_scale = 0;
817 
818   // SUCCESS
819   for (int i = 0; i < 10; ++i) {
820     ASSERT_TRUE(decoder.as_decimal(&value, &value_size, &value_scale));
821     ASSERT_EQ(&input[0], decoder.buffer());
822     ASSERT_EQ(8ul, decoder.remaining());
823     for (size_t j = 0; j < value_size; ++j) {
824       uint8_t byte = 0;
825       decode_byte(&input[j + sizeof(int32_t)], byte);
826       ASSERT_EQ(byte, value[j]);
827     }
828   }
829 
830   // Decode some bytes in the decimal to increment the buffer
831   for (int i = 0; i < 4; ++i) {
832     uint8_t byte = 0;
833     ASSERT_TRUE(decoder.decode_byte(byte));
834   }
835 
836   // FAIL
837   ASSERT_FALSE(decoder.as_decimal(&value, &value_size, &value_scale));
838   ASSERT_TRUE(failure_logged_);
839 }
840 
TEST_F(DecoderUnitTest,AsDuration)841 TEST_F(DecoderUnitTest, AsDuration) {
842   const char input[4] = { 2, 4, 6, -127 }; // 1, 2, 3 (zig zag encoding)
843   TestDecoder decoder(input, 4);
844   int32_t months = 0;
845   int32_t days = 0;
846   int64_t nanos = 0;
847 
848   // SUCCESS
849   for (int i = 0; i < 10; ++i) {
850     ASSERT_TRUE(decoder.as_duration(&months, &days, &nanos));
851     ASSERT_EQ(&input[0], decoder.buffer());
852     ASSERT_EQ(4ul, decoder.remaining());
853     ASSERT_EQ(1, months);
854     ASSERT_EQ(2, days);
855     ASSERT_EQ(3, nanos);
856   }
857 
858   // Decode three bytes in the duration to increment to the next duration
859   for (int i = 0; i < 3; ++i) {
860     uint8_t byte = 0;
861     ASSERT_TRUE(decoder.decode_byte(byte));
862   }
863 
864   // FAIL
865   ASSERT_FALSE(decoder.as_duration(&months, &days, &nanos));
866   ASSERT_TRUE(failure_logged_);
867 }
868 
TEST_F(DecoderUnitTest,DecodeCustomPayload)869 TEST_F(DecoderUnitTest, DecodeCustomPayload) {
870   const char input[21] = { 0, 1, 0, 8, 68, 97, 116, 97, 83, 116, 97, 120, // DataStax
871                            0, 0, 0, 5, 67, 47, 67,  43, 43 };             // C/C++
872   TestDecoder decoder(input, 21);
873   CustomPayloadVec value;
874 
875   // SUCCESS
876   ASSERT_TRUE(decoder.decode_custom_payload(value));
877   ASSERT_EQ(0ul, decoder.remaining());
878   ASSERT_EQ(1ul, value.size());
879   ASSERT_EQ(8ul, value[0].name.size());
880   ASSERT_STREQ("DataStax", std::string(value[0].name.data(), value[0].name.size()).c_str());
881   ASSERT_EQ(5ul, value[0].value.size());
882   for (int i = 0; i < 5; ++i) {
883     ASSERT_EQ(input[i + 16], value[0].value.data()[i]);
884   }
885 
886   // FAIL
887   ASSERT_FALSE(decoder.decode_custom_payload(value));
888   ASSERT_TRUE(failure_logged_);
889 }
890 
TEST_F(DecoderUnitTest,DecodeFailures)891 TEST_F(DecoderUnitTest, DecodeFailures) {
892   const char input[4] = { 0, 0, 0, 42 };
893   TestDecoder decoder(input, 4, 1);
894   FailureVec value;
895   int32_t value_size = 0;
896 
897   // SUCCESS
898   ASSERT_TRUE(decoder.decode_failures(value, value_size));
899   ASSERT_EQ(0ul, decoder.remaining());
900   ASSERT_EQ(0ul, value.size());
901   ASSERT_EQ(42, value_size);
902 
903   // FAIL
904   ASSERT_FALSE(decoder.decode_failures(value, value_size));
905   ASSERT_TRUE(failure_logged_);
906 }
907 
TEST_F(DecoderUnitTest,DecodeFailuresWithVector)908 TEST_F(DecoderUnitTest, DecodeFailuresWithVector) {
909   const char input[30] = { 0, 0, 0,  2, 4, 127, 0, 0, 1,                               // 127.0.0.1
910                            0, 1, 16, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // [::1] [02]
911                            0, 2 };
912   TestDecoder decoder(input, 30, 5);
913   FailureVec value;
914   int32_t value_size = 0;
915 
916   // SUCCESS
917   ASSERT_TRUE(decoder.decode_failures(value, value_size));
918   ASSERT_EQ(0ul, decoder.remaining());
919   ASSERT_EQ(2ul, value.size());
920   ASSERT_EQ(2, value_size);
921   for (int i = 0; i < value[0].endpoint.address_length; ++i) {
922     uint8_t byte;
923     decode_byte(&input[i + 5], byte);
924     ASSERT_EQ(byte, value[0].endpoint.address[i]);
925   }
926   ASSERT_EQ(1ul, value[0].failurecode);
927   for (int i = 0; i < value[1].endpoint.address_length; ++i) {
928     uint8_t byte;
929     decode_byte(&input[i + 12], byte);
930     ASSERT_EQ(byte, value[1].endpoint.address[i]);
931   }
932   ASSERT_EQ(2ul, value[1].failurecode);
933 
934   // FAIL
935   ASSERT_FALSE(decoder.decode_failures(value, value_size));
936   ASSERT_TRUE(failure_logged_);
937 }
938 
TEST_F(DecoderUnitTest,DecodeWriteType)939 TEST_F(DecoderUnitTest, DecodeWriteType) {
940   const char input[67] = { 0,  6,  83, 73, 77, 80, 76, 69, // SIMPLE
941                            0,  5,  66, 65, 84, 67, 72,     // BATCH
942                            0,  14, 85, 78, 76, 79, 71, 71, 69, 68, 95,
943                            66, 65, 84, 67, 72,                         // UNLOGGED_BATCH
944                            0,  7,  67, 79, 85, 78, 84, 69, 82,         // COUNTER
945                            0,  9,  66, 65, 84, 67, 72, 95, 76, 79, 71, // BATCH_LOG
946                            0,  3,  67, 65, 83,                         // CAS
947                            0,  4,  86, 73, 69, 87,                     // VIEW
948                            0,  3,  67, 68, 67 };                       // CDC
949   TestDecoder decoder(input, 67);
950   CassWriteType value;
951 
952   // SUCCESS
953   ASSERT_TRUE(decoder.decode_write_type(value));
954   ASSERT_EQ(59ul, decoder.remaining());
955   ASSERT_EQ(CASS_WRITE_TYPE_SIMPLE, value);
956   ASSERT_TRUE(decoder.decode_write_type(value));
957   ASSERT_EQ(52ul, decoder.remaining());
958   ASSERT_EQ(CASS_WRITE_TYPE_BATCH, value);
959   ASSERT_TRUE(decoder.decode_write_type(value));
960   ASSERT_EQ(36ul, decoder.remaining());
961   ASSERT_EQ(CASS_WRITE_TYPE_UNLOGGED_BATCH, value);
962   ASSERT_TRUE(decoder.decode_write_type(value));
963   ASSERT_EQ(27ul, decoder.remaining());
964   ASSERT_EQ(CASS_WRITE_TYPE_COUNTER, value);
965   ASSERT_TRUE(decoder.decode_write_type(value));
966   ASSERT_EQ(16ul, decoder.remaining());
967   ASSERT_EQ(CASS_WRITE_TYPE_BATCH_LOG, value);
968   ASSERT_TRUE(decoder.decode_write_type(value));
969   ASSERT_EQ(11ul, decoder.remaining());
970   ASSERT_EQ(CASS_WRITE_TYPE_CAS, value);
971   ASSERT_TRUE(decoder.decode_write_type(value));
972   ASSERT_EQ(5ul, decoder.remaining());
973   ASSERT_EQ(CASS_WRITE_TYPE_VIEW, value);
974   ASSERT_TRUE(decoder.decode_write_type(value));
975   ASSERT_EQ(0ul, decoder.remaining());
976   ASSERT_EQ(CASS_WRITE_TYPE_CDC, value);
977 
978   // FAIL
979   ASSERT_FALSE(decoder.decode_write_type(value));
980   ASSERT_EQ(CASS_WRITE_TYPE_UNKNOWN, value);
981   ASSERT_TRUE(failure_logged_);
982 }
983 
TEST_F(DecoderUnitTest,DecodeWarnings)984 TEST_F(DecoderUnitTest, DecodeWarnings) {
985   const char input[38] = { 0,   2,   0,   16,  87,  97,  114, 110, 105, 110,
986                            103, 32,  78,  117, 109, 98,  101, 114, 32,  49, // Warning Number 1
987                            0,   16,  87,  97,  114, 110, 105, 110, 103, 32,
988                            78,  117, 109, 98,  101, 114, 32,  50 }; // Warning Number 2
989   TestDecoder decoder(input, 38);
990   WarningVec value;
991 
992   // SUCCESS
993   ASSERT_TRUE(decoder.decode_warnings(value));
994   ASSERT_EQ(0ul, decoder.remaining());
995   ASSERT_EQ(2ul, value.size());
996   ASSERT_STREQ("Warning Number 1", std::string(value[0].data(), value[0].size()).c_str());
997   ASSERT_STREQ("Warning Number 2", std::string(value[1].data(), value[1].size()).c_str());
998 
999   // FAIL
1000   ASSERT_FALSE(decoder.decode_warnings(value));
1001   ASSERT_TRUE(failure_logged_);
1002 }
1003