blob: 0e6733fbff7510f20a388e58da4e5fb657b39d57 [file] [log] [blame]
Brian Silverman395d6252013-09-13 20:58:14 -07001// Copyright 2012 Google Inc. All Rights Reserved.
2// Author: charliehotel@google.com (Christopher Hoover)
3//
4// Tests for Buffer.
5
6#include "../gbuffer.h"
7
8#include <stdint.h>
9#include <limits>
10
11#include <boost/scoped_ptr.hpp>
12#include <gtest/gtest.h>
13
14#define GG_LONGLONG(x) x##LL
15#define GG_ULONGLONG(x) x##ULL
16#define ARRAYSIZE(x) (static_cast<int>(sizeof(x)/sizeof(x[0])))
17
18namespace glibusb {
19namespace {
20
21typedef ::testing::Types<int8_t, int16_t, int32_t, int64_t,
22 uint8_t, uint16_t, uint32_t, uint64_t> AllIntegerTypes;
23
24// Tests that a newly constructed buffer is empty.
25TEST(BufferTest, EmptyBufferLength) {
26 Buffer buffer;
27 EXPECT_EQ(0, buffer.Length());
28}
29
30// Tests clearing.
31TEST(BufferTest, EmptyBufferClear) {
32 Buffer buffer;
33 buffer.Append(uint8_t(1));
34 buffer.Clear();
35 EXPECT_EQ(0, buffer.Length());
36}
37
38// Tests resizing.
39TEST(BufferTest, EmptyBufferResize) {
40 Buffer buffer;
41 const int kSize = 100;
42 buffer.Resize(kSize);
43 EXPECT_EQ(kSize, buffer.Length());
44}
45
46// Tests getting a pointer on an empty buffer.
47TEST(BufferTest, EmptyBufferGetPointer) {
48 Buffer buffer;
49 void *p;
50 const void *cp;
51 p = buffer.GetBufferPointer(0);
52 EXPECT_EQ(NULL, p);
53 cp = buffer.GetBufferPointer(0);
54 EXPECT_EQ(NULL, cp);
55 p = buffer.GetBufferPointer(0, 0);
56 EXPECT_EQ(NULL, p);
57 cp = buffer.GetBufferPointer(0, 0);
58 EXPECT_EQ(NULL, cp);
59}
60
61// Tests getting a pointer on an empty buffer.
62TEST(BufferTest, ConstEmptyBufferGetPointer) {
63 const Buffer buffer;
64 const void *cp;
65 cp = buffer.GetBufferPointer(0);
66 EXPECT_EQ(NULL, cp);
67 cp = buffer.GetBufferPointer(0, 0);
68 EXPECT_EQ(NULL, cp);
69}
70
71
72// Tests Get on an empty buffer.
73template <typename T>
74class EmptyBufferGetDeathTest : public ::testing::Test {
75 public:
76 void Check() {
77 Buffer buffer;
78 T value;
79 EXPECT_DEATH(buffer.Get(0, &value), "Check failed");
80 }
81};
82
83// Tests Get for all types on an empty bufer.
84TYPED_TEST_CASE(EmptyBufferGetDeathTest, AllIntegerTypes);
85TYPED_TEST(EmptyBufferGetDeathTest, Check) {
86 this->Check();
87}
88
89
90// Tests Put on an empty buffer.
91template <typename T>
92class EmptyBufferPutDeathTest : public ::testing::Test {
93 public:
94 void Check() {
95 Buffer buffer;
96 T value(0);
97 EXPECT_DEATH(buffer.Put(0, value), "Check failed");
98 }
99};
100
101// Tests Put for all types on an empty bufer.
102TYPED_TEST_CASE(EmptyBufferPutDeathTest, AllIntegerTypes);
103TYPED_TEST(EmptyBufferPutDeathTest, Check) {
104 this->Check();
105}
106
107
108// Tests getting a string on an empty buffer.
109TEST(BufferDeathTest, EmptyBufferGetString) {
110 Buffer buffer;
111 std::string s;
112 EXPECT_DEATH(buffer.Get(0, &s), "Check failed");
113}
114
115
116// Tests removing the header from an empty buffer.
117TEST(BufferDeathTest, EmptyBufferRemoveHeader) {
118 Buffer buffer;
119 buffer.RemoveHeader(0);
120 EXPECT_EQ(0, buffer.Length());
121 EXPECT_DEATH(buffer.RemoveHeader(1), "Check failed");
122}
123
124
125// Tests adding a header of size 0.
126TEST(BufferTest, EmptyBufferAddHeader) {
127 Buffer buffer;
128 buffer.AddHeader(0);
129 EXPECT_EQ(0, buffer.Length());
130}
131
132
133// Tests adding a header of size > 0.
134TEST(BufferTest, EmptyBufferAddHeader2) {
135 Buffer buffer;
136 const int kSize = 100;
137 buffer.AddHeader(kSize);
138 EXPECT_EQ(kSize, buffer.Length());
139}
140
141
142// Tests copying an empty buffer.
143TEST(BufferTest, EmptyBufferCopy) {
144 Buffer buffer;
145 Buffer buffer2;
146 buffer2.Append(uint8_t(1));
147 buffer2.Copy(buffer);
148 EXPECT_EQ(0, buffer2.Length());
149}
150
151// Tests dumping an empty buffer.
152TEST(BufferTest, EmptyBufferDump) {
153 Buffer buffer;
154 std::string s = buffer.Dump();
155 EXPECT_EQ("", s);
156}
157
158
159// Tests slicing an empty buffer.
160TEST(BufferTest, EmptyBufferSlice) {
161 Buffer buffer;
162 boost::scoped_ptr<Buffer> slice(buffer.MakeSlice(0, 0));
163 EXPECT_EQ(slice->Length(), 0);
164}
165
166
167// Tests Get, Put and Append for signed and unsigned integers.
168template <typename T>
169class PutGetAppendIntegerTest : public ::testing::Test {
170 public:
171 void Check() {
172 static const T kValues[] = {
173 std::numeric_limits<T>::max(),
174 T(0),
175 std::numeric_limits<T>::min()
176 };
177
178 for (int i = 0; i < ARRAYSIZE(kValues); ++i) {
179 const T kValue = kValues[i];
180
181 // Tests Put - Get
182 {
183 Buffer buffer;
184 buffer.Resize(sizeof(T));
185 buffer.Put(0, kValue);
186 T check;
187 buffer.Get(0, &check);
188 EXPECT_EQ(kValue, check);
189 }
190
191 // Tests Append - Get
192 {
193 Buffer buffer;
194 buffer.Append(kValue);
195 T check;
196 buffer.Get(0, &check);
197 EXPECT_EQ(kValue, check);
198 }
199 }
200 }
201};
202
203// Tests Get, Put and Append for all signed integers.
204TYPED_TEST_CASE(PutGetAppendIntegerTest, AllIntegerTypes);
205TYPED_TEST(PutGetAppendIntegerTest, Check) {
206 this->Check();
207}
208
209const uint8_t kDeadBeef[] = {
210 0xef, 0xbe, 0xad, 0xde
211};
212
213// Test harness for a buffer construct from "C" data.
214class ConstructedFromDataBufferTest : public testing::Test {
215 protected:
216 void SetUp() {
217 buffer.reset(new Buffer(kDeadBeef, sizeof(kDeadBeef)));
218 }
219
220 boost::scoped_ptr<Buffer> buffer;
221};
222
223typedef ConstructedFromDataBufferTest ConstructedFromDataBufferDeathTest;
224
225// Tests constructing a buffer from "C" data.
226TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataBufferLength) {
227 EXPECT_EQ(sizeof(kDeadBeef), buffer->Length());
228}
229
230// Tests that a buffer constructed from "C" data contains the right
231// data.
232TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataByteAccess) {
233 for (int i = 0; i < ARRAYSIZE(kDeadBeef); ++i) {
234 uint8_t u8;
235 buffer->Get(i, &u8);
236 EXPECT_EQ(kDeadBeef[i], u8);
237 }
238}
239
240// Tests clearing.
241TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataClear) {
242 buffer->Clear();
243 EXPECT_EQ(0, buffer->Length());
244}
245
246// Tests resizing.
247TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataResize) {
248 const int kSize = 100;
249 buffer->Resize(kSize);
250 EXPECT_EQ(kSize, buffer->Length());
251}
252
253// Tests that getting a pointer works.
254TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataGetPointer) {
255 void *p;
256 const void *cp;
257 p = buffer->GetBufferPointer(0);
258 EXPECT_EQ(NULL, p);
259 cp = buffer->GetBufferPointer(0);
260 EXPECT_EQ(NULL, cp);
261 p = buffer->GetBufferPointer(0, 0);
262 EXPECT_EQ(NULL, p);
263 cp = buffer->GetBufferPointer(0, 0);
264 EXPECT_EQ(NULL, cp);
265
266 p = buffer->GetBufferPointer(2);
267 EXPECT_TRUE(p != NULL);
268 EXPECT_EQ(kDeadBeef[0], *static_cast<uint8_t *>(p));
269 EXPECT_EQ(kDeadBeef[1], *(static_cast<uint8_t *>(p) + 1));
270 cp = buffer->GetBufferPointer(2);
271 EXPECT_TRUE(p != NULL);
272 EXPECT_EQ(kDeadBeef[0], *static_cast<uint8_t *>(p));
273 EXPECT_EQ(kDeadBeef[1], *(static_cast<uint8_t *>(p) + 1));
274
275 p = buffer->GetBufferPointer(1, 2);
276 EXPECT_TRUE(p != NULL);
277 EXPECT_EQ(kDeadBeef[1], *static_cast<uint8_t *>(p));
278 EXPECT_EQ(kDeadBeef[2], *(static_cast<uint8_t *>(p) + 1));
279 cp = buffer->GetBufferPointer(1, 2);
280 EXPECT_TRUE(p != NULL);
281 EXPECT_EQ(kDeadBeef[1], *static_cast<uint8_t *>(p));
282 EXPECT_EQ(kDeadBeef[2], *(static_cast<uint8_t *>(p) + 1));
283
284 const Buffer &const_buffer(*buffer);
285 cp = const_buffer.GetBufferPointer(1, 2);
286 EXPECT_TRUE(p != NULL);
287 EXPECT_EQ(kDeadBeef[1], *static_cast<uint8_t *>(p));
288 EXPECT_EQ(kDeadBeef[2], *(static_cast<uint8_t *>(p) + 1));
289}
290
291// Tests that Get{S,U}{8,16,32,64} work on zero.
292TEST(BufferTest, GetZero) {
293 boost::scoped_ptr<Buffer> buffer(new Buffer());
294 for (int i = 0; i < 8; ++i) {
295 buffer->Append(uint8_t(0));
296 }
297 int8_t s8;
298 uint8_t u8;
299 int16_t s16;
300 uint16_t u16;
301 int32_t s32;
302 uint32_t u32;
303 int64_t s64;
304 uint64_t u64;
305 buffer->Get(0, &s8);
306 EXPECT_EQ(0, s8);
307 buffer->Get(0, &u8);
308 EXPECT_EQ(0, u8);
309 buffer->Get(0, &s16);
310 EXPECT_EQ(0, s16);
311 buffer->Get(0, &u16);
312 EXPECT_EQ(0, u16);
313 buffer->Get(0, &s32);
314 EXPECT_EQ(0, s32);
315 buffer->Get(0, &u32);
316 EXPECT_EQ(0, u32);
317 buffer->Get(0, &s64);
318 EXPECT_EQ(0, s64);
319 buffer->Get(0, &u64);
320 EXPECT_EQ(0, u64);
321}
322
323// Tests that GetU{8,16,32,64} work.
324TEST(BufferTest, GetUXX) {
325 boost::scoped_ptr<Buffer> buffer(new Buffer());
326 buffer->Append(uint8_t(0x88));
327 buffer->Append(uint8_t(0x77));
328 buffer->Append(uint8_t(0x66));
329 buffer->Append(uint8_t(0x55));
330 buffer->Append(uint8_t(0x44));
331 buffer->Append(uint8_t(0x33));
332 buffer->Append(uint8_t(0x22));
333 buffer->Append(uint8_t(0x11));
334 uint8_t u8;
335 uint16_t u16;
336 uint32_t u32;
337 uint64_t u64;
338 buffer->Get(0, &u8);
339 EXPECT_EQ(0x88, u8);
340 buffer->Get(0, &u16);
341 EXPECT_EQ(0x7788, u16);
342 buffer->Get(0, &u32);
343 EXPECT_EQ(0x55667788, u32);
344 buffer->Get(0, &u64);
345 EXPECT_EQ(GG_ULONGLONG(0x1122334455667788), u64);
346}
347
348// Tests that GetS{8,16,32,64} work for positive values.
349TEST(BufferTest, GetSXXPositive) {
350 boost::scoped_ptr<Buffer> buffer(new Buffer());
351 buffer->Append(uint8_t(0x08));
352 buffer->Append(uint8_t(0x07));
353 buffer->Append(uint8_t(0x06));
354 buffer->Append(uint8_t(0x05));
355 buffer->Append(uint8_t(0x04));
356 buffer->Append(uint8_t(0x03));
357 buffer->Append(uint8_t(0x02));
358 buffer->Append(uint8_t(0x01));
359 int8_t s8;
360 int16_t s16;
361 int32_t s32;
362 int64_t s64;
363 buffer->Get(0, &s8);
364 EXPECT_EQ(0x08, s8);
365 buffer->Get(0, &s16);
366 EXPECT_EQ(0x0708, s16);
367 buffer->Get(0, &s32);
368 EXPECT_EQ(0x05060708, s32);
369 buffer->Get(0, &s64);
370 EXPECT_EQ(GG_ULONGLONG(0x0102030405060708), s64);
371}
372
373// Tests that GetS{8,16,32,64} work for negative values.
374TEST(BufferTest, GetSXXNegative) {
375 boost::scoped_ptr<Buffer> buffer(new Buffer());
376 buffer->Append(uint8_t(0xF8));
377 buffer->Append(uint8_t(0xF7));
378 buffer->Append(uint8_t(0x06));
379 buffer->Append(uint8_t(0xF5));
380 buffer->Append(uint8_t(0x04));
381 buffer->Append(uint8_t(0x03));
382 buffer->Append(uint8_t(0x02));
383 buffer->Append(uint8_t(0xF1));
384
385 // Calculate directly the the signed (2's complement) value that we
386 // should expect.
387 const int8_t kExpected8 = 0xF8 - 0xFF - 1;
388 int8_t s8;
389 buffer->Get(0, &s8);
390 EXPECT_EQ(kExpected8, s8);
391
392 const int16_t kExpected16 = 0xF7F8 - 0xFFFF - 1;
393 int16_t s16;
394 buffer->Get(0, &s16);
395 EXPECT_EQ(kExpected16, s16);
396
397 const int32_t kExpected32 = 0xF506F7F8 - 0xFFFFFFFF - 1;
398 int32_t s32;
399 buffer->Get(0, &s32);
400 EXPECT_EQ(kExpected32, s32);
401
402 const int64_t kExpected64 = (GG_LONGLONG(0xF1020304F506F7F8) -
403 GG_LONGLONG(0xFFFFFFFFFFFFFFFF) -
404 GG_LONGLONG(1));
405 int64_t s64;
406 buffer->Get(0, &s64);
407 EXPECT_EQ(kExpected64, s64);
408}
409
410// Tests that getting a string works.
411TEST_F(ConstructedFromDataBufferDeathTest, ConstructedFromDataGetString) {
412 std::string s;
413 EXPECT_DEATH(buffer->Get(0, &s), "Check failed");
414 buffer->Append(uint8_t(0));
415 Buffer::size_type n = buffer->Get(0, &s);
416 EXPECT_STREQ("\xEF\xBE\xAD\xDE", s.c_str());
417 EXPECT_EQ(4, n);
418 n = buffer->Get(1, &s);
419 EXPECT_STREQ("\xBE\xAD\xDE", s.c_str());
420 EXPECT_EQ(4, n);
421}
422
423// Tests removing a header.
424TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataRemoveHeader) {
425 buffer->RemoveHeader(0);
426 EXPECT_EQ(sizeof(kDeadBeef), buffer->Length());
427 buffer->RemoveHeader(2);
428 EXPECT_EQ(sizeof(kDeadBeef) - 2, buffer->Length());
429 uint16_t u16;
430 buffer->Get(0, &u16);
431 EXPECT_EQ(0xdead, u16);
432}
433
434// Tests adding a zero-length header.
435TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataAddHeader) {
436 buffer->AddHeader(0);
437 EXPECT_EQ(sizeof(kDeadBeef), buffer->Length());
438}
439
440// Tests adding a header of size > 0.
441TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataAddHeader2) {
442 const int kSize = 100;
443 buffer->AddHeader(kSize);
444 EXPECT_EQ(sizeof(kDeadBeef) + kSize, buffer->Length());
445 uint32_t u32;
446 buffer->Get(kSize, &u32);
447 EXPECT_EQ(0xdeadbeef, u32);
448}
449
450// Tests copying.
451TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataCopy) {
452 buffer->Append(uint8_t(0));
453 std::string s;
454 buffer->Get(0, &s);
455
456 Buffer buffer2;
457 buffer2.Copy(*buffer);
458 std::string s2;
459 buffer2.Get(0, &s2);
460
461 EXPECT_STREQ(s.c_str(), s2.c_str());
462}
463
464// Tests dumping.
465TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataDump) {
466 const char kExpected[] =
467 "0x00000000: ef be ad de | ....\n";
468 std::string s = buffer->Dump();
469 EXPECT_STREQ(kExpected, s.c_str());
470}
471
472// Tests emtpy slicing.
473TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataSlice) {
474 boost::scoped_ptr<Buffer> slice(buffer->MakeSlice(0, 0));
475 EXPECT_EQ(slice->Length(), 0);
476}
477
478// Tests slicing.
479TEST_F(ConstructedFromDataBufferTest, ConstructedFromDataSlice2) {
480 boost::scoped_ptr<Buffer> slice(buffer->MakeSlice(0, 2));
481 EXPECT_EQ(slice->Length(), 2);
482 uint16_t u16;
483 slice->Get(0, &u16);
484 EXPECT_EQ(0xbeef, u16);
485}
486
487// Tests dumping.
488TEST(BufferTest, DumpTest) {
489 const char kData[] = "Hello";
490 const char kExpected[] =
491 "0x00000000: 48 65 6c 6c 6f 00 "
492 " | Hello.\n";
493 Buffer buffer(kData, sizeof(kData));
494 std::string s = buffer.Dump();
495 EXPECT_STREQ(kExpected, s.c_str());
496}
497
498#if 0
499// Tests writing to a file.
500TEST(BufferTest, FileTest) {
501 const char kData[] = "Hello";
502 Buffer buffer(kData, sizeof(kData));
503 string out;
504 FileCloser file(MutableStringFile("file", &out,
505 DO_NOT_TAKE_OWNERSHIP,
506 DO_NOT_ALLOW_MMAP));
507 buffer.WriteOrDie(file.get());
508 EXPECT_STREQ(kData, out.c_str());
509}
510
511TEST(BufferTest, WritePathOrDieTest) {
512 const char kData[] = "Hello";
513 Buffer buffer(kData, sizeof(kData));
514 buffer.WriteToPathOrDie("/dev/null");
515}
516#endif
517
518// Tests appending.
519TEST(BufferTest, AppendBuffer) {
520 const char kData1[] = "Hello ";
521 const char kData2[] = "World";
522 Buffer buffer1(kData1, sizeof(kData1) - 1);
523 EXPECT_EQ(sizeof(kData1) - 1, buffer1.Length());
524 Buffer buffer2(kData2, sizeof(kData2));
525 EXPECT_EQ(sizeof(kData2), buffer2.Length());
526 Buffer buffer;
527 EXPECT_EQ(0, buffer.Length());
528 buffer.Append(Buffer());
529 buffer.Append(buffer1);
530 buffer.Append(buffer2);
531 std::string s;
532 buffer.Get(0, &s);
533 EXPECT_STREQ("Hello World", s.c_str());
534}
535
536// Tests operator==
537TEST(Buffer, OpEqualTrue) {
538 Buffer b1;
539 Buffer b2;
540 EXPECT_EQ(b1, b2);
541 b1.Append(uint8_t(1));
542 b2.Append(uint8_t(1));
543 EXPECT_EQ(b1, b2);
544}
545
546// Tests operator==
547TEST(Buffer, OpEqualFalse) {
548 Buffer empty;
549 Buffer b1;
550 Buffer b2;
551 Buffer b12;
552 b1.Append(uint8_t(1));
553 b2.Append(uint8_t(2));
554 b12.Append(uint8_t(1));
555 b12.Append(uint8_t(2));
556 EXPECT_NE(empty, b1);
557 EXPECT_NE(b1, empty);
558 EXPECT_NE(b1, b2);
559 EXPECT_NE(b1, b12);
560 EXPECT_NE(b12, b1);
561}
562
563TEST(Buffer, Dump) {
564 Buffer b;
565 b.Append(uint8_t(1));
566 std::string s = b.Dump();
567}
568
569} // namespace
570} // namespace glibusb