1 // Copyright 2014 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <string> 6 7 #include <brillo/any.h> 8 #include <gtest/gtest.h> 9 10 using brillo::internal_details::Buffer; 11 using brillo::GetTypeTag; 12 13 TEST(Buffer, Empty) { 14 Buffer buffer; 15 EXPECT_TRUE(buffer.IsEmpty()); 16 EXPECT_EQ(Buffer::kExternal, buffer.storage_); 17 EXPECT_EQ(nullptr, buffer.GetDataPtr()); 18 } 19 20 TEST(Buffer, Store_Int) { 21 Buffer buffer; 22 buffer.Assign(2); 23 EXPECT_FALSE(buffer.IsEmpty()); 24 EXPECT_EQ(Buffer::kContained, buffer.storage_); 25 EXPECT_STREQ(GetTypeTag<int>(), buffer.GetDataPtr()->GetTypeTag()); 26 } 27 28 TEST(Buffer, Store_Double) { 29 Buffer buffer; 30 buffer.Assign(2.3); 31 EXPECT_FALSE(buffer.IsEmpty()); 32 EXPECT_EQ(Buffer::kContained, buffer.storage_); 33 EXPECT_STREQ(GetTypeTag<double>(), buffer.GetDataPtr()->GetTypeTag()); 34 } 35 36 TEST(Buffer, Store_Pointers) { 37 Buffer buffer; 38 // nullptr 39 buffer.Assign(nullptr); 40 EXPECT_FALSE(buffer.IsEmpty()); 41 EXPECT_EQ(Buffer::kContained, buffer.storage_); 42 EXPECT_STREQ(GetTypeTag<std::nullptr_t>(), 43 buffer.GetDataPtr()->GetTypeTag()); 44 45 // char * 46 buffer.Assign("abcd"); 47 EXPECT_FALSE(buffer.IsEmpty()); 48 EXPECT_EQ(Buffer::kContained, buffer.storage_); 49 EXPECT_STREQ(GetTypeTag<const char*>(), buffer.GetDataPtr()->GetTypeTag()); 50 51 // pointer to non-trivial object 52 class NonTrivial { 53 public: 54 virtual ~NonTrivial() {} 55 } non_trivial; 56 buffer.Assign(&non_trivial); 57 EXPECT_FALSE(buffer.IsEmpty()); 58 EXPECT_EQ(Buffer::kContained, buffer.storage_); 59 EXPECT_STREQ(GetTypeTag<NonTrivial*>(), buffer.GetDataPtr()->GetTypeTag()); 60 } 61 62 TEST(Buffer, Store_NonTrivialObjects) { 63 class NonTrivial { 64 public: 65 virtual ~NonTrivial() {} 66 } non_trivial; 67 Buffer buffer; 68 buffer.Assign(non_trivial); 69 EXPECT_FALSE(buffer.IsEmpty()); 70 EXPECT_EQ(Buffer::kExternal, buffer.storage_); 71 EXPECT_STREQ(GetTypeTag<NonTrivial>(), buffer.GetDataPtr()->GetTypeTag()); 72 } 73 74 TEST(Buffer, Store_Objects) { 75 Buffer buffer; 76 77 struct Small { 78 double d; 79 } small = {}; 80 buffer.Assign(small); 81 EXPECT_FALSE(buffer.IsEmpty()); 82 EXPECT_EQ(Buffer::kContained, buffer.storage_); 83 EXPECT_STREQ(GetTypeTag<Small>(), buffer.GetDataPtr()->GetTypeTag()); 84 85 struct Large { 86 char c[20]; 87 } large = {}; 88 buffer.Assign(large); 89 EXPECT_FALSE(buffer.IsEmpty()); 90 EXPECT_EQ(Buffer::kExternal, buffer.storage_); 91 EXPECT_STREQ(GetTypeTag<Large>(), buffer.GetDataPtr()->GetTypeTag()); 92 } 93 94 TEST(Buffer, Copy) { 95 Buffer buffer1; 96 Buffer buffer2; 97 98 buffer1.Assign(30); 99 buffer1.CopyTo(&buffer2); 100 EXPECT_FALSE(buffer1.IsEmpty()); 101 EXPECT_FALSE(buffer2.IsEmpty()); 102 EXPECT_STREQ(GetTypeTag<int>(), buffer1.GetDataPtr()->GetTypeTag()); 103 EXPECT_STREQ(GetTypeTag<int>(), buffer2.GetDataPtr()->GetTypeTag()); 104 EXPECT_EQ(30, buffer1.GetData<int>()); 105 EXPECT_EQ(30, buffer2.GetData<int>()); 106 107 buffer1.Assign(std::string("abc")); 108 buffer1.CopyTo(&buffer2); 109 EXPECT_FALSE(buffer1.IsEmpty()); 110 EXPECT_FALSE(buffer2.IsEmpty()); 111 EXPECT_STREQ(GetTypeTag<std::string>(), buffer1.GetDataPtr()->GetTypeTag()); 112 EXPECT_STREQ(GetTypeTag<std::string>(), buffer2.GetDataPtr()->GetTypeTag()); 113 EXPECT_EQ("abc", buffer1.GetData<std::string>()); 114 EXPECT_EQ("abc", buffer2.GetData<std::string>()); 115 } 116 117 TEST(Buffer, Move) { 118 // Move operations essentially leave the source object in a state that is 119 // guaranteed to be safe for reuse or destruction. There is no other explicit 120 // guarantees on the exact state of the source after move (e.g. that the 121 // source Any will be Empty after the move is complete). 122 Buffer buffer1; 123 Buffer buffer2; 124 125 buffer1.Assign(30); 126 buffer1.MoveTo(&buffer2); 127 // Contained types aren't flushed, so the source Any doesn't become empty. 128 // The contained value is just moved, but for scalars this just copies 129 // the data and any retains the actual type. 130 EXPECT_FALSE(buffer1.IsEmpty()); 131 EXPECT_FALSE(buffer2.IsEmpty()); 132 EXPECT_STREQ(GetTypeTag<int>(), buffer2.GetDataPtr()->GetTypeTag()); 133 EXPECT_EQ(30, buffer2.GetData<int>()); 134 135 buffer1.Assign(std::string("abc")); 136 buffer1.MoveTo(&buffer2); 137 // External types are moved by just moving the pointer value from src to dest. 138 // This will make the source object effectively "Empty". 139 EXPECT_TRUE(buffer1.IsEmpty()); 140 EXPECT_FALSE(buffer2.IsEmpty()); 141 EXPECT_STREQ(GetTypeTag<std::string>(), buffer2.GetDataPtr()->GetTypeTag()); 142 EXPECT_EQ("abc", buffer2.GetData<std::string>()); 143 } 144