xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp (revision f38cfdabd1ec53eb4278e02af98a76620f33e260)
1 //===-------- SimplePackedSerializationTest.cpp - Test SPS scheme ---------===//
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 #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
10 #include "llvm/ExecutionEngine/Orc/LLVMSPSSerializers.h"
11 #include "gtest/gtest.h"
12 
13 using namespace llvm;
14 using namespace llvm::orc::shared;
15 
16 TEST(SimplePackedSerializationTest, SPSOutputBuffer) {
17   constexpr unsigned NumBytes = 8;
18   char Buffer[NumBytes];
19   char Zero = 0;
20   SPSOutputBuffer OB(Buffer, NumBytes);
21 
22   // Expect that we can write NumBytes of content.
23   for (unsigned I = 0; I != NumBytes; ++I) {
24     char C = I;
25     EXPECT_TRUE(OB.write(&C, 1));
26   }
27 
28   // Expect an error when we attempt to write an extra byte.
29   EXPECT_FALSE(OB.write(&Zero, 1));
30 
31   // Check that the buffer contains the expected content.
32   for (unsigned I = 0; I != NumBytes; ++I)
33     EXPECT_EQ(Buffer[I], (char)I);
34 }
35 
36 TEST(SimplePackedSerializationTest, SPSInputBuffer) {
37   char Buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
38   SPSInputBuffer IB(Buffer, sizeof(Buffer));
39 
40   char C;
41   for (unsigned I = 0; I != sizeof(Buffer); ++I) {
42     EXPECT_TRUE(IB.read(&C, 1));
43     EXPECT_EQ(C, (char)I);
44   }
45 
46   EXPECT_FALSE(IB.read(&C, 1));
47 }
48 
49 template <typename SPSTagT, typename T>
50 static void spsSerializationRoundTrip(const T &Value) {
51   using BST = SPSSerializationTraits<SPSTagT, T>;
52 
53   size_t Size = BST::size(Value);
54   auto Buffer = std::make_unique<char[]>(Size);
55   SPSOutputBuffer OB(Buffer.get(), Size);
56 
57   EXPECT_TRUE(BST::serialize(OB, Value));
58 
59   SPSInputBuffer IB(Buffer.get(), Size);
60 
61   T DSValue;
62   EXPECT_TRUE(BST::deserialize(IB, DSValue));
63 
64   EXPECT_EQ(Value, DSValue)
65       << "Incorrect value after serialization/deserialization round-trip";
66 }
67 
68 template <typename T> static void testFixedIntegralTypeSerialization() {
69   spsSerializationRoundTrip<T, T>(0);
70   spsSerializationRoundTrip<T, T>(static_cast<T>(1));
71   if (std::is_signed<T>::value) {
72     spsSerializationRoundTrip<T, T>(static_cast<T>(-1));
73     spsSerializationRoundTrip<T, T>(std::numeric_limits<T>::min());
74   }
75   spsSerializationRoundTrip<T, T>(std::numeric_limits<T>::max());
76 }
77 
78 TEST(SimplePackedSerializationTest, BoolSerialization) {
79   spsSerializationRoundTrip<bool, bool>(true);
80   spsSerializationRoundTrip<bool, bool>(false);
81 }
82 
83 TEST(SimplePackedSerializationTest, CharSerialization) {
84   spsSerializationRoundTrip<char, char>((char)0x00);
85   spsSerializationRoundTrip<char, char>((char)0xAA);
86   spsSerializationRoundTrip<char, char>((char)0xFF);
87 }
88 
89 TEST(SimplePackedSerializationTest, Int8Serialization) {
90   testFixedIntegralTypeSerialization<int8_t>();
91 }
92 
93 TEST(SimplePackedSerializationTest, UInt8Serialization) {
94   testFixedIntegralTypeSerialization<uint8_t>();
95 }
96 
97 TEST(SimplePackedSerializationTest, Int16Serialization) {
98   testFixedIntegralTypeSerialization<int16_t>();
99 }
100 
101 TEST(SimplePackedSerializationTest, UInt16Serialization) {
102   testFixedIntegralTypeSerialization<uint16_t>();
103 }
104 
105 TEST(SimplePackedSerializationTest, Int32Serialization) {
106   testFixedIntegralTypeSerialization<int32_t>();
107 }
108 
109 TEST(SimplePackedSerializationTest, UInt32Serialization) {
110   testFixedIntegralTypeSerialization<uint32_t>();
111 }
112 
113 TEST(SimplePackedSerializationTest, Int64Serialization) {
114   testFixedIntegralTypeSerialization<int64_t>();
115 }
116 
117 TEST(SimplePackedSerializationTest, UInt64Serialization) {
118   testFixedIntegralTypeSerialization<uint64_t>();
119 }
120 
121 TEST(SimplePackedSerializationTest, SequenceSerialization) {
122   std::vector<int32_t> V({1, 2, -47, 139});
123   spsSerializationRoundTrip<SPSSequence<int32_t>>(V);
124 }
125 
126 TEST(SimplePackedSerializationTest, StringViewCharSequenceSerialization) {
127   const char *HW = "Hello, world!";
128   spsSerializationRoundTrip<SPSString>(StringRef(HW));
129 }
130 
131 TEST(SimplePackedSerializationTest, StdTupleSerialization) {
132   std::tuple<int32_t, std::string, bool> P(42, "foo", true);
133   spsSerializationRoundTrip<SPSTuple<int32_t, SPSString, bool>>(P);
134 }
135 
136 TEST(SimplePackedSerializationTest, StdPairSerialization) {
137   std::pair<int32_t, std::string> P(42, "foo");
138   spsSerializationRoundTrip<SPSTuple<int32_t, SPSString>>(P);
139 }
140 
141 TEST(SimplePackedSerializationTest, ArgListSerialization) {
142   using BAL = SPSArgList<bool, int32_t, SPSString>;
143 
144   bool Arg1 = true;
145   int32_t Arg2 = 42;
146   std::string Arg3 = "foo";
147 
148   size_t Size = BAL::size(Arg1, Arg2, Arg3);
149   auto Buffer = std::make_unique<char[]>(Size);
150   SPSOutputBuffer OB(Buffer.get(), Size);
151 
152   EXPECT_TRUE(BAL::serialize(OB, Arg1, Arg2, Arg3));
153 
154   SPSInputBuffer IB(Buffer.get(), Size);
155 
156   bool ArgOut1;
157   int32_t ArgOut2;
158   std::string ArgOut3;
159 
160   EXPECT_TRUE(BAL::deserialize(IB, ArgOut1, ArgOut2, ArgOut3));
161 
162   EXPECT_EQ(Arg1, ArgOut1);
163   EXPECT_EQ(Arg2, ArgOut2);
164   EXPECT_EQ(Arg3, ArgOut3);
165 }
166 
167 TEST(SimplePackedSerialization, StringMap) {
168   StringMap<int32_t> M({{"A", 1}, {"B", 2}});
169   spsSerializationRoundTrip<SPSSequence<SPSTuple<SPSString, int32_t>>>(M);
170 }
171 
172 TEST(SimplePackedSerializationTest, ArrayRef) {
173   constexpr unsigned BufferSize = 6 + 8; // "hello\0" + sizeof(uint64_t)
174   ArrayRef<char> HelloOut = "hello";
175   char Buffer[BufferSize];
176   memset(Buffer, 0, BufferSize);
177 
178   SPSOutputBuffer OB(Buffer, BufferSize);
179   EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, HelloOut));
180 
181   ArrayRef<char> HelloIn;
182   SPSInputBuffer IB(Buffer, BufferSize);
183   EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, HelloIn));
184 
185   // Output should be copied to buffer.
186   EXPECT_NE(HelloOut.data(), Buffer);
187 
188   // Input should reference buffer.
189   EXPECT_LT(HelloIn.data() - Buffer, BufferSize);
190 }
191