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