1 //===-- simple_packed_serialization_test.cpp ------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of the ORC runtime. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "simple_packed_serialization.h" 14 #include "gtest/gtest.h" 15 16 using namespace __orc_rt; 17 18 TEST(SimplePackedSerializationTest, SPSOutputBuffer) { 19 constexpr unsigned NumBytes = 8; 20 char Buffer[NumBytes]; 21 char Zero = 0; 22 SPSOutputBuffer OB(Buffer, NumBytes); 23 24 // Expect that we can write NumBytes of content. 25 for (unsigned I = 0; I != NumBytes; ++I) { 26 char C = I; 27 EXPECT_TRUE(OB.write(&C, 1)); 28 } 29 30 // Expect an error when we attempt to write an extra byte. 31 EXPECT_FALSE(OB.write(&Zero, 1)); 32 33 // Check that the buffer contains the expected content. 34 for (unsigned I = 0; I != NumBytes; ++I) 35 EXPECT_EQ(Buffer[I], (char)I); 36 } 37 38 TEST(SimplePackedSerializationTest, SPSInputBuffer) { 39 char Buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; 40 SPSInputBuffer IB(Buffer, sizeof(Buffer)); 41 42 char C; 43 for (unsigned I = 0; I != sizeof(Buffer); ++I) { 44 EXPECT_TRUE(IB.read(&C, 1)); 45 EXPECT_EQ(C, (char)I); 46 } 47 48 EXPECT_FALSE(IB.read(&C, 1)); 49 } 50 51 template <typename SPSTagT, typename T> 52 static void blobSerializationRoundTrip(const T &Value) { 53 using BST = SPSSerializationTraits<SPSTagT, T>; 54 55 size_t Size = BST::size(Value); 56 auto Buffer = std::make_unique<char[]>(Size); 57 SPSOutputBuffer OB(Buffer.get(), Size); 58 59 EXPECT_TRUE(BST::serialize(OB, Value)); 60 61 SPSInputBuffer IB(Buffer.get(), Size); 62 63 T DSValue; 64 EXPECT_TRUE(BST::deserialize(IB, DSValue)); 65 66 EXPECT_EQ(Value, DSValue) 67 << "Incorrect value after serialization/deserialization round-trip"; 68 } 69 70 template <typename T> static void testFixedIntegralTypeSerialization() { 71 blobSerializationRoundTrip<T, T>(0); 72 blobSerializationRoundTrip<T, T>(static_cast<T>(1)); 73 if (std::is_signed<T>::value) { 74 blobSerializationRoundTrip<T, T>(static_cast<T>(-1)); 75 blobSerializationRoundTrip<T, T>(std::numeric_limits<T>::min()); 76 } 77 blobSerializationRoundTrip<T, T>(std::numeric_limits<T>::max()); 78 } 79 80 TEST(SimplePackedSerializationTest, BoolSerialization) { 81 blobSerializationRoundTrip<bool, bool>(true); 82 blobSerializationRoundTrip<bool, bool>(false); 83 } 84 85 TEST(SimplePackedSerializationTest, CharSerialization) { 86 blobSerializationRoundTrip<char, char>((char)0x00); 87 blobSerializationRoundTrip<char, char>((char)0xAA); 88 blobSerializationRoundTrip<char, char>((char)0xFF); 89 } 90 91 TEST(SimplePackedSerializationTest, Int8Serialization) { 92 testFixedIntegralTypeSerialization<int8_t>(); 93 } 94 95 TEST(SimplePackedSerializationTest, UInt8Serialization) { 96 testFixedIntegralTypeSerialization<uint8_t>(); 97 } 98 99 TEST(SimplePackedSerializationTest, Int16Serialization) { 100 testFixedIntegralTypeSerialization<int16_t>(); 101 } 102 103 TEST(SimplePackedSerializationTest, UInt16Serialization) { 104 testFixedIntegralTypeSerialization<uint16_t>(); 105 } 106 107 TEST(SimplePackedSerializationTest, Int32Serialization) { 108 testFixedIntegralTypeSerialization<int32_t>(); 109 } 110 111 TEST(SimplePackedSerializationTest, UInt32Serialization) { 112 testFixedIntegralTypeSerialization<uint32_t>(); 113 } 114 115 TEST(SimplePackedSerializationTest, Int64Serialization) { 116 testFixedIntegralTypeSerialization<int64_t>(); 117 } 118 119 TEST(SimplePackedSerializationTest, UInt64Serialization) { 120 testFixedIntegralTypeSerialization<uint64_t>(); 121 } 122 123 TEST(SimplePackedSerializationTest, SequenceSerialization) { 124 std::vector<int32_t> V({1, 2, -47, 139}); 125 blobSerializationRoundTrip<SPSSequence<int32_t>, std::vector<int32_t>>(V); 126 } 127 128 TEST(SimplePackedSerializationTest, StringViewCharSequenceSerialization) { 129 const char *HW = "Hello, world!"; 130 blobSerializationRoundTrip<SPSString, std::string_view>(std::string_view(HW)); 131 } 132 133 TEST(SimplePackedSerializationTest, SpanSerialization) { 134 const char Data[] = {3, 2, 1, 0, 1, 2, 3}; // Span should handle nulls. 135 span<const char> OutS(Data, sizeof(Data)); 136 137 size_t Size = SPSArgList<SPSSequence<char>>::size(OutS); 138 auto Buffer = std::make_unique<char[]>(Size); 139 SPSOutputBuffer OB(Buffer.get(), Size); 140 141 EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, OutS)); 142 143 SPSInputBuffer IB(Buffer.get(), Size); 144 145 span<const char> InS; 146 147 EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, InS)); 148 149 // Check that the serialized and deserialized values match. 150 EXPECT_EQ(InS.size(), OutS.size()); 151 EXPECT_EQ(memcmp(OutS.data(), InS.data(), InS.size()), 0); 152 153 // Check that the span points directly to the input buffer. 154 EXPECT_EQ(InS.data(), Buffer.get() + sizeof(uint64_t)); 155 } 156 157 TEST(SimplePackedSerializationTest, StdPairSerialization) { 158 std::pair<int32_t, std::string> P(42, "foo"); 159 blobSerializationRoundTrip<SPSTuple<int32_t, SPSString>, 160 std::pair<int32_t, std::string>>(P); 161 } 162 163 TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) { 164 std::optional<int64_t> NoValue; 165 blobSerializationRoundTrip<SPSOptional<int64_t>>(NoValue); 166 } 167 168 TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) { 169 std::optional<int64_t> Value(42); 170 blobSerializationRoundTrip<SPSOptional<int64_t>>(Value); 171 } 172 173 TEST(SimplePackedSerializationTest, ArgListSerialization) { 174 using BAL = SPSArgList<bool, int32_t, SPSString>; 175 176 bool Arg1 = true; 177 int32_t Arg2 = 42; 178 std::string Arg3 = "foo"; 179 180 size_t Size = BAL::size(Arg1, Arg2, Arg3); 181 auto Buffer = std::make_unique<char[]>(Size); 182 SPSOutputBuffer OB(Buffer.get(), Size); 183 184 EXPECT_TRUE(BAL::serialize(OB, Arg1, Arg2, Arg3)); 185 186 SPSInputBuffer IB(Buffer.get(), Size); 187 188 bool ArgOut1; 189 int32_t ArgOut2; 190 std::string ArgOut3; 191 192 EXPECT_TRUE(BAL::deserialize(IB, ArgOut1, ArgOut2, ArgOut3)); 193 194 EXPECT_EQ(Arg1, ArgOut1); 195 EXPECT_EQ(Arg2, ArgOut2); 196 EXPECT_EQ(Arg3, ArgOut3); 197 } 198