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
TEST(SimplePackedSerializationTest,SPSOutputBuffer)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
TEST(SimplePackedSerializationTest,SPSInputBuffer)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>
blobSerializationRoundTrip(const T & Value)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
testFixedIntegralTypeSerialization()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
TEST(SimplePackedSerializationTest,BoolSerialization)80 TEST(SimplePackedSerializationTest, BoolSerialization) {
81 blobSerializationRoundTrip<bool, bool>(true);
82 blobSerializationRoundTrip<bool, bool>(false);
83 }
84
TEST(SimplePackedSerializationTest,CharSerialization)85 TEST(SimplePackedSerializationTest, CharSerialization) {
86 blobSerializationRoundTrip<char, char>((char)0x00);
87 blobSerializationRoundTrip<char, char>((char)0xAA);
88 blobSerializationRoundTrip<char, char>((char)0xFF);
89 }
90
TEST(SimplePackedSerializationTest,Int8Serialization)91 TEST(SimplePackedSerializationTest, Int8Serialization) {
92 testFixedIntegralTypeSerialization<int8_t>();
93 }
94
TEST(SimplePackedSerializationTest,UInt8Serialization)95 TEST(SimplePackedSerializationTest, UInt8Serialization) {
96 testFixedIntegralTypeSerialization<uint8_t>();
97 }
98
TEST(SimplePackedSerializationTest,Int16Serialization)99 TEST(SimplePackedSerializationTest, Int16Serialization) {
100 testFixedIntegralTypeSerialization<int16_t>();
101 }
102
TEST(SimplePackedSerializationTest,UInt16Serialization)103 TEST(SimplePackedSerializationTest, UInt16Serialization) {
104 testFixedIntegralTypeSerialization<uint16_t>();
105 }
106
TEST(SimplePackedSerializationTest,Int32Serialization)107 TEST(SimplePackedSerializationTest, Int32Serialization) {
108 testFixedIntegralTypeSerialization<int32_t>();
109 }
110
TEST(SimplePackedSerializationTest,UInt32Serialization)111 TEST(SimplePackedSerializationTest, UInt32Serialization) {
112 testFixedIntegralTypeSerialization<uint32_t>();
113 }
114
TEST(SimplePackedSerializationTest,Int64Serialization)115 TEST(SimplePackedSerializationTest, Int64Serialization) {
116 testFixedIntegralTypeSerialization<int64_t>();
117 }
118
TEST(SimplePackedSerializationTest,UInt64Serialization)119 TEST(SimplePackedSerializationTest, UInt64Serialization) {
120 testFixedIntegralTypeSerialization<uint64_t>();
121 }
122
TEST(SimplePackedSerializationTest,SequenceSerialization)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
TEST(SimplePackedSerializationTest,StringViewCharSequenceSerialization)128 TEST(SimplePackedSerializationTest, StringViewCharSequenceSerialization) {
129 const char *HW = "Hello, world!";
130 blobSerializationRoundTrip<SPSString, std::string_view>(std::string_view(HW));
131 }
132
TEST(SimplePackedSerializationTest,SpanSerialization)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
TEST(SimplePackedSerializationTest,StdPairSerialization)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
TEST(SimplePackedSerializationTest,StdOptionalNoValueSerialization)163 TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) {
164 std::optional<int64_t> NoValue;
165 blobSerializationRoundTrip<SPSOptional<int64_t>>(NoValue);
166 }
167
TEST(SimplePackedSerializationTest,StdOptionalValueSerialization)168 TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) {
169 std::optional<int64_t> Value(42);
170 blobSerializationRoundTrip<SPSOptional<int64_t>>(Value);
171 }
172
TEST(SimplePackedSerializationTest,ArgListSerialization)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