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
<T
>::value
) {
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
, ArgListSerialization
) {
141 using BAL
= SPSArgList
<bool, int32_t, SPSString
>;
145 std::string Arg3
= "foo";
147 size_t Size
= BAL::size(Arg1
, Arg2
, Arg3
);
148 auto Buffer
= std::make_unique
<char[]>(Size
);
149 SPSOutputBuffer
OB(Buffer
.get(), Size
);
151 EXPECT_TRUE(BAL::serialize(OB
, Arg1
, Arg2
, Arg3
));
153 SPSInputBuffer
IB(Buffer
.get(), Size
);
159 EXPECT_TRUE(BAL::deserialize(IB
, ArgOut1
, ArgOut2
, ArgOut3
));
161 EXPECT_EQ(Arg1
, ArgOut1
);
162 EXPECT_EQ(Arg2
, ArgOut2
);
163 EXPECT_EQ(Arg3
, ArgOut3
);
166 TEST(SimplePackedSerialization
, StringMap
) {
167 StringMap
<int32_t> M({{"A", 1}, {"B", 2}});
168 spsSerializationRoundTrip
<SPSSequence
<SPSTuple
<SPSString
, int32_t>>>(M
);
171 TEST(SimplePackedSerializationTest
, ArrayRef
) {
172 constexpr unsigned BufferSize
= 6 + 8; // "hello\0" + sizeof(uint64_t)
173 ArrayRef
<char> HelloOut
= "hello";
174 char Buffer
[BufferSize
];
175 memset(Buffer
, 0, BufferSize
);
177 SPSOutputBuffer
OB(Buffer
, BufferSize
);
178 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::serialize(OB
, HelloOut
));
180 ArrayRef
<char> HelloIn
;
181 SPSInputBuffer
IB(Buffer
, BufferSize
);
182 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::deserialize(IB
, HelloIn
));
184 // Output should be copied to buffer.
185 EXPECT_NE(HelloOut
.data(), Buffer
);
187 // Input should reference buffer.
188 EXPECT_LT(HelloIn
.data() - Buffer
, BufferSize
);
191 TEST(SimplePackedSerializationTest
, ArrayRefEmpty
) {
192 // Make sure that empty ArrayRefs serialize and deserialize as expected.
193 // Empty ArrayRefs should not succeed even when the data field is null, and
194 // should deserialize to a default-constructed ArrayRef, not a pointer into
196 constexpr unsigned BufferSize
= sizeof(uint64_t);
197 char Buffer
[BufferSize
];
198 memset(Buffer
, 0, BufferSize
);
201 SPSOutputBuffer
OB(Buffer
, BufferSize
);
202 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::serialize(OB
, AOut
));
205 SPSInputBuffer
IB(Buffer
, BufferSize
);
206 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::deserialize(IB
, AIn
));
208 EXPECT_EQ(AIn
.data(), nullptr);
209 EXPECT_EQ(AIn
.size(), 0U);
212 TEST(SimplePackedSerializationTest
, StringRefEmpty
) {
213 // Make sure that empty StringRefs serialize and deserialize as expected.
214 // Empty StringRefs should not succeed even when the data field is null, and
215 // should deserialize to a default-constructed StringRef, not a pointer into
217 constexpr unsigned BufferSize
= sizeof(uint64_t);
218 char Buffer
[BufferSize
];
219 memset(Buffer
, 0, BufferSize
);
222 SPSOutputBuffer
OB(Buffer
, BufferSize
);
223 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::serialize(OB
, SROut
));
226 SPSInputBuffer
IB(Buffer
, BufferSize
);
227 EXPECT_TRUE(SPSArgList
<SPSSequence
<char>>::deserialize(IB
, SRIn
));
229 EXPECT_EQ(SRIn
.data(), nullptr);
230 EXPECT_EQ(SRIn
.size(), 0U);