1 //===-------- SimplePackedSerializationTest.cpp - Test SPS scheme ---------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
10 #include "gtest/gtest.h"
13 using namespace llvm::orc::shared
;
15 TEST(SimplePackedSerializationTest
, SPSOutputBuffer
) {
16 constexpr unsigned NumBytes
= 8;
17 char Buffer
[NumBytes
];
19 SPSOutputBuffer
OB(Buffer
, NumBytes
);
21 // Expect that we can write NumBytes of content.
22 for (unsigned I
= 0; I
!= NumBytes
; ++I
) {
24 EXPECT_TRUE(OB
.write(&C
, 1));
27 // Expect an error when we attempt to write an extra byte.
28 EXPECT_FALSE(OB
.write(&Zero
, 1));
30 // Check that the buffer contains the expected content.
31 for (unsigned I
= 0; I
!= NumBytes
; ++I
)
32 EXPECT_EQ(Buffer
[I
], (char)I
);
35 TEST(SimplePackedSerializationTest
, SPSInputBuffer
) {
36 char Buffer
[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
37 SPSInputBuffer
IB(Buffer
, sizeof(Buffer
));
40 for (unsigned I
= 0; I
!= sizeof(Buffer
); ++I
) {
41 EXPECT_TRUE(IB
.read(&C
, 1));
42 EXPECT_EQ(C
, (char)I
);
45 EXPECT_FALSE(IB
.read(&C
, 1));
48 template <typename SPSTagT
, typename T
>
49 static void spsSerializationRoundTrip(const T
&Value
) {
50 using BST
= SPSSerializationTraits
<SPSTagT
, T
>;
52 size_t Size
= BST::size(Value
);
53 auto Buffer
= std::make_unique
<char[]>(Size
);
54 SPSOutputBuffer
OB(Buffer
.get(), Size
);
56 EXPECT_TRUE(BST::serialize(OB
, Value
));
58 SPSInputBuffer
IB(Buffer
.get(), Size
);
61 EXPECT_TRUE(BST::deserialize(IB
, DSValue
));
63 EXPECT_EQ(Value
, DSValue
)
64 << "Incorrect value after serialization/deserialization round-trip";
67 template <typename T
> static void testFixedIntegralTypeSerialization() {
68 spsSerializationRoundTrip
<T
, T
>(0);
69 spsSerializationRoundTrip
<T
, T
>(static_cast<T
>(1));
70 if (std::is_signed_v
<T
>) {
71 spsSerializationRoundTrip
<T
, T
>(static_cast<T
>(-1));
72 spsSerializationRoundTrip
<T
, T
>(std::numeric_limits
<T
>::min());
74 spsSerializationRoundTrip
<T
, T
>(std::numeric_limits
<T
>::max());
77 TEST(SimplePackedSerializationTest
, BoolSerialization
) {
78 spsSerializationRoundTrip
<bool, bool>(true);
79 spsSerializationRoundTrip
<bool, bool>(false);
82 TEST(SimplePackedSerializationTest
, CharSerialization
) {
83 spsSerializationRoundTrip
<char, char>((char)0x00);
84 spsSerializationRoundTrip
<char, char>((char)0xAA);
85 spsSerializationRoundTrip
<char, char>((char)0xFF);
88 TEST(SimplePackedSerializationTest
, Int8Serialization
) {
89 testFixedIntegralTypeSerialization
<int8_t>();
92 TEST(SimplePackedSerializationTest
, UInt8Serialization
) {
93 testFixedIntegralTypeSerialization
<uint8_t>();
96 TEST(SimplePackedSerializationTest
, Int16Serialization
) {
97 testFixedIntegralTypeSerialization
<int16_t>();
100 TEST(SimplePackedSerializationTest
, UInt16Serialization
) {
101 testFixedIntegralTypeSerialization
<uint16_t>();
104 TEST(SimplePackedSerializationTest
, Int32Serialization
) {
105 testFixedIntegralTypeSerialization
<int32_t>();
108 TEST(SimplePackedSerializationTest
, UInt32Serialization
) {
109 testFixedIntegralTypeSerialization
<uint32_t>();
112 TEST(SimplePackedSerializationTest
, Int64Serialization
) {
113 testFixedIntegralTypeSerialization
<int64_t>();
116 TEST(SimplePackedSerializationTest
, UInt64Serialization
) {
117 testFixedIntegralTypeSerialization
<uint64_t>();
120 TEST(SimplePackedSerializationTest
, SequenceSerialization
) {
121 std::vector
<int32_t> V({1, 2, -47, 139});
122 spsSerializationRoundTrip
<SPSSequence
<int32_t>>(V
);
125 TEST(SimplePackedSerializationTest
, StringViewCharSequenceSerialization
) {
126 const char *HW
= "Hello, world!";
127 spsSerializationRoundTrip
<SPSString
>(StringRef(HW
));
130 TEST(SimplePackedSerializationTest
, StdTupleSerialization
) {
131 std::tuple
<int32_t, std::string
, bool> P(42, "foo", true);
132 spsSerializationRoundTrip
<SPSTuple
<int32_t, SPSString
, bool>>(P
);
135 TEST(SimplePackedSerializationTest
, StdPairSerialization
) {
136 std::pair
<int32_t, std::string
> P(42, "foo");
137 spsSerializationRoundTrip
<SPSTuple
<int32_t, SPSString
>>(P
);
140 TEST(SimplePackedSerializationTest
, StdOptionalNoValueSerialization
) {
141 std::optional
<int64_t> NoValue
;
142 spsSerializationRoundTrip
<SPSOptional
<int64_t>>(NoValue
);
145 TEST(SimplePackedSerializationTest
, StdOptionalValueSerialization
) {
146 std::optional
<int64_t> Value(42);
147 spsSerializationRoundTrip
<SPSOptional
<int64_t>>(Value
);
150 TEST(SimplePackedSerializationTest
, ArgListSerialization
) {
151 using BAL
= SPSArgList
<bool, int32_t, SPSString
>;
155 std::string Arg3
= "foo";
157 size_t Size
= BAL::size(Arg1
, Arg2
, Arg3
);
158 auto Buffer
= std::make_unique
<char[]>(Size
);
159 SPSOutputBuffer
OB(Buffer
.get(), Size
);
161 EXPECT_TRUE(BAL::serialize(OB
, Arg1
, Arg2
, Arg3
));
163 SPSInputBuffer
IB(Buffer
.get(), Size
);
169 EXPECT_TRUE(BAL::deserialize(IB
, ArgOut1
, ArgOut2
, ArgOut3
));
171 EXPECT_EQ(Arg1
, ArgOut1
);
172 EXPECT_EQ(Arg2
, ArgOut2
);
173 EXPECT_EQ(Arg3
, ArgOut3
);
176 TEST(SimplePackedSerialization
, StringMap
) {
177 StringMap
<int32_t> M({{"A", 1}, {"B", 2}});
178 spsSerializationRoundTrip
<SPSSequence
<SPSTuple
<SPSString
, int32_t>>>(M
);
181 TEST(SimplePackedSerializationTest
, ArrayRef
) {
182 constexpr unsigned BufferSize
= 6 + 8; // "hello\0" + sizeof(uint64_t)
183 ArrayRef
<char> HelloOut
= "hello";
184 char Buffer
[BufferSize
];
185 memset(Buffer
, 0, BufferSize
);
187 SPSOutputBuffer
OB(Buffer
, BufferSize
);
188 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::serialize(OB
, HelloOut
));
190 ArrayRef
<char> HelloIn
;
191 SPSInputBuffer
IB(Buffer
, BufferSize
);
192 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::deserialize(IB
, HelloIn
));
194 // Output should be copied to buffer.
195 EXPECT_NE(HelloOut
.data(), Buffer
);
197 // Input should reference buffer.
198 EXPECT_LT(HelloIn
.data() - Buffer
, BufferSize
);
201 TEST(SimplePackedSerializationTest
, ArrayRefEmpty
) {
202 // Make sure that empty ArrayRefs serialize and deserialize as expected.
203 // Empty ArrayRefs should not succeed even when the data field is null, and
204 // should deserialize to a default-constructed ArrayRef, not a pointer into
206 constexpr unsigned BufferSize
= sizeof(uint64_t);
207 char Buffer
[BufferSize
];
208 memset(Buffer
, 0, BufferSize
);
211 SPSOutputBuffer
OB(Buffer
, BufferSize
);
212 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::serialize(OB
, AOut
));
215 SPSInputBuffer
IB(Buffer
, BufferSize
);
216 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::deserialize(IB
, AIn
));
218 EXPECT_EQ(AIn
.data(), nullptr);
219 EXPECT_EQ(AIn
.size(), 0U);
222 TEST(SimplePackedSerializationTest
, StringRefEmpty
) {
223 // Make sure that empty StringRefs serialize and deserialize as expected.
224 // Empty StringRefs should not succeed even when the data field is null, and
225 // should deserialize to a default-constructed StringRef, not a pointer into
227 constexpr unsigned BufferSize
= sizeof(uint64_t);
228 char Buffer
[BufferSize
];
229 memset(Buffer
, 0, BufferSize
);
232 SPSOutputBuffer
OB(Buffer
, BufferSize
);
233 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::serialize(OB
, SROut
));
236 SPSInputBuffer
IB(Buffer
, BufferSize
);
237 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::deserialize(IB
, SRIn
));
239 EXPECT_EQ(SRIn
.data(), nullptr);
240 EXPECT_EQ(SRIn
.size(), 0U);