xref: /llvm-project/llvm/unittests/ExecutionEngine/Orc/SimplePackedSerializationTest.cpp (revision a0a51a805fdbe9d6a0f87d3746c39111d95cfb8b)
14eb9fe2eSLang Hames //===-------- SimplePackedSerializationTest.cpp - Test SPS scheme ---------===//
24eb9fe2eSLang Hames //
34eb9fe2eSLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44eb9fe2eSLang Hames // See https://llvm.org/LICENSE.txt for license information.
54eb9fe2eSLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64eb9fe2eSLang Hames //
74eb9fe2eSLang Hames //===----------------------------------------------------------------------===//
84eb9fe2eSLang Hames 
94eb9fe2eSLang Hames #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
104eb9fe2eSLang Hames #include "gtest/gtest.h"
114eb9fe2eSLang Hames 
124eb9fe2eSLang Hames using namespace llvm;
134eb9fe2eSLang Hames using namespace llvm::orc::shared;
144eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,SPSOutputBuffer)154eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, SPSOutputBuffer) {
164eb9fe2eSLang Hames   constexpr unsigned NumBytes = 8;
174eb9fe2eSLang Hames   char Buffer[NumBytes];
184eb9fe2eSLang Hames   char Zero = 0;
194eb9fe2eSLang Hames   SPSOutputBuffer OB(Buffer, NumBytes);
204eb9fe2eSLang Hames 
214eb9fe2eSLang Hames   // Expect that we can write NumBytes of content.
224eb9fe2eSLang Hames   for (unsigned I = 0; I != NumBytes; ++I) {
234eb9fe2eSLang Hames     char C = I;
244eb9fe2eSLang Hames     EXPECT_TRUE(OB.write(&C, 1));
254eb9fe2eSLang Hames   }
264eb9fe2eSLang Hames 
274eb9fe2eSLang Hames   // Expect an error when we attempt to write an extra byte.
284eb9fe2eSLang Hames   EXPECT_FALSE(OB.write(&Zero, 1));
294eb9fe2eSLang Hames 
304eb9fe2eSLang Hames   // Check that the buffer contains the expected content.
314eb9fe2eSLang Hames   for (unsigned I = 0; I != NumBytes; ++I)
324eb9fe2eSLang Hames     EXPECT_EQ(Buffer[I], (char)I);
334eb9fe2eSLang Hames }
344eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,SPSInputBuffer)354eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, SPSInputBuffer) {
364eb9fe2eSLang Hames   char Buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
374eb9fe2eSLang Hames   SPSInputBuffer IB(Buffer, sizeof(Buffer));
384eb9fe2eSLang Hames 
394eb9fe2eSLang Hames   char C;
404eb9fe2eSLang Hames   for (unsigned I = 0; I != sizeof(Buffer); ++I) {
414eb9fe2eSLang Hames     EXPECT_TRUE(IB.read(&C, 1));
424eb9fe2eSLang Hames     EXPECT_EQ(C, (char)I);
434eb9fe2eSLang Hames   }
444eb9fe2eSLang Hames 
454eb9fe2eSLang Hames   EXPECT_FALSE(IB.read(&C, 1));
464eb9fe2eSLang Hames }
474eb9fe2eSLang Hames 
484eb9fe2eSLang Hames template <typename SPSTagT, typename T>
spsSerializationRoundTrip(const T & Value)4976d6a8dfSLang Hames static void spsSerializationRoundTrip(const T &Value) {
504eb9fe2eSLang Hames   using BST = SPSSerializationTraits<SPSTagT, T>;
514eb9fe2eSLang Hames 
524eb9fe2eSLang Hames   size_t Size = BST::size(Value);
534eb9fe2eSLang Hames   auto Buffer = std::make_unique<char[]>(Size);
544eb9fe2eSLang Hames   SPSOutputBuffer OB(Buffer.get(), Size);
554eb9fe2eSLang Hames 
564eb9fe2eSLang Hames   EXPECT_TRUE(BST::serialize(OB, Value));
574eb9fe2eSLang Hames 
584eb9fe2eSLang Hames   SPSInputBuffer IB(Buffer.get(), Size);
594eb9fe2eSLang Hames 
604eb9fe2eSLang Hames   T DSValue;
614eb9fe2eSLang Hames   EXPECT_TRUE(BST::deserialize(IB, DSValue));
624eb9fe2eSLang Hames 
634eb9fe2eSLang Hames   EXPECT_EQ(Value, DSValue)
644eb9fe2eSLang Hames       << "Incorrect value after serialization/deserialization round-trip";
654eb9fe2eSLang Hames }
664eb9fe2eSLang Hames 
testFixedIntegralTypeSerialization()674eb9fe2eSLang Hames template <typename T> static void testFixedIntegralTypeSerialization() {
6876d6a8dfSLang Hames   spsSerializationRoundTrip<T, T>(0);
6976d6a8dfSLang Hames   spsSerializationRoundTrip<T, T>(static_cast<T>(1));
706aa050a6SNathan James   if (std::is_signed_v<T>) {
7176d6a8dfSLang Hames     spsSerializationRoundTrip<T, T>(static_cast<T>(-1));
7276d6a8dfSLang Hames     spsSerializationRoundTrip<T, T>(std::numeric_limits<T>::min());
734eb9fe2eSLang Hames   }
7476d6a8dfSLang Hames   spsSerializationRoundTrip<T, T>(std::numeric_limits<T>::max());
754eb9fe2eSLang Hames }
764eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,BoolSerialization)774eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, BoolSerialization) {
7876d6a8dfSLang Hames   spsSerializationRoundTrip<bool, bool>(true);
7976d6a8dfSLang Hames   spsSerializationRoundTrip<bool, bool>(false);
804eb9fe2eSLang Hames }
814eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,CharSerialization)824eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, CharSerialization) {
8376d6a8dfSLang Hames   spsSerializationRoundTrip<char, char>((char)0x00);
8476d6a8dfSLang Hames   spsSerializationRoundTrip<char, char>((char)0xAA);
8576d6a8dfSLang Hames   spsSerializationRoundTrip<char, char>((char)0xFF);
864eb9fe2eSLang Hames }
874eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,Int8Serialization)884eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, Int8Serialization) {
894eb9fe2eSLang Hames   testFixedIntegralTypeSerialization<int8_t>();
904eb9fe2eSLang Hames }
914eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,UInt8Serialization)924eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, UInt8Serialization) {
934eb9fe2eSLang Hames   testFixedIntegralTypeSerialization<uint8_t>();
944eb9fe2eSLang Hames }
954eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,Int16Serialization)964eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, Int16Serialization) {
974eb9fe2eSLang Hames   testFixedIntegralTypeSerialization<int16_t>();
984eb9fe2eSLang Hames }
994eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,UInt16Serialization)1004eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, UInt16Serialization) {
1014eb9fe2eSLang Hames   testFixedIntegralTypeSerialization<uint16_t>();
1024eb9fe2eSLang Hames }
1034eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,Int32Serialization)1044eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, Int32Serialization) {
1054eb9fe2eSLang Hames   testFixedIntegralTypeSerialization<int32_t>();
1064eb9fe2eSLang Hames }
1074eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,UInt32Serialization)1084eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, UInt32Serialization) {
1094eb9fe2eSLang Hames   testFixedIntegralTypeSerialization<uint32_t>();
1104eb9fe2eSLang Hames }
1114eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,Int64Serialization)1124eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, Int64Serialization) {
1134eb9fe2eSLang Hames   testFixedIntegralTypeSerialization<int64_t>();
1144eb9fe2eSLang Hames }
1154eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,UInt64Serialization)1164eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, UInt64Serialization) {
1174eb9fe2eSLang Hames   testFixedIntegralTypeSerialization<uint64_t>();
1184eb9fe2eSLang Hames }
1194eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,SequenceSerialization)1204eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, SequenceSerialization) {
1214eb9fe2eSLang Hames   std::vector<int32_t> V({1, 2, -47, 139});
12276d6a8dfSLang Hames   spsSerializationRoundTrip<SPSSequence<int32_t>>(V);
1234eb9fe2eSLang Hames }
1244eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,StringViewCharSequenceSerialization)1254eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, StringViewCharSequenceSerialization) {
1264eb9fe2eSLang Hames   const char *HW = "Hello, world!";
12776d6a8dfSLang Hames   spsSerializationRoundTrip<SPSString>(StringRef(HW));
1284eb9fe2eSLang Hames }
1294eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,StdTupleSerialization)1301e5e1beeSLang Hames TEST(SimplePackedSerializationTest, StdTupleSerialization) {
1311e5e1beeSLang Hames   std::tuple<int32_t, std::string, bool> P(42, "foo", true);
1321e5e1beeSLang Hames   spsSerializationRoundTrip<SPSTuple<int32_t, SPSString, bool>>(P);
1331e5e1beeSLang Hames }
1341e5e1beeSLang Hames 
TEST(SimplePackedSerializationTest,StdPairSerialization)1354eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, StdPairSerialization) {
1364eb9fe2eSLang Hames   std::pair<int32_t, std::string> P(42, "foo");
13776d6a8dfSLang Hames   spsSerializationRoundTrip<SPSTuple<int32_t, SPSString>>(P);
1384eb9fe2eSLang Hames }
1394eb9fe2eSLang Hames 
TEST(SimplePackedSerializationTest,StdOptionalNoValueSerialization)140*a0a51a80SLang Hames TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) {
141*a0a51a80SLang Hames   std::optional<int64_t> NoValue;
142*a0a51a80SLang Hames   spsSerializationRoundTrip<SPSOptional<int64_t>>(NoValue);
143*a0a51a80SLang Hames }
144*a0a51a80SLang Hames 
TEST(SimplePackedSerializationTest,StdOptionalValueSerialization)145*a0a51a80SLang Hames TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) {
146*a0a51a80SLang Hames   std::optional<int64_t> Value(42);
147*a0a51a80SLang Hames   spsSerializationRoundTrip<SPSOptional<int64_t>>(Value);
148*a0a51a80SLang Hames }
149*a0a51a80SLang Hames 
TEST(SimplePackedSerializationTest,ArgListSerialization)1504eb9fe2eSLang Hames TEST(SimplePackedSerializationTest, ArgListSerialization) {
1514eb9fe2eSLang Hames   using BAL = SPSArgList<bool, int32_t, SPSString>;
1524eb9fe2eSLang Hames 
1534eb9fe2eSLang Hames   bool Arg1 = true;
1544eb9fe2eSLang Hames   int32_t Arg2 = 42;
1554eb9fe2eSLang Hames   std::string Arg3 = "foo";
1564eb9fe2eSLang Hames 
1574eb9fe2eSLang Hames   size_t Size = BAL::size(Arg1, Arg2, Arg3);
1584eb9fe2eSLang Hames   auto Buffer = std::make_unique<char[]>(Size);
1594eb9fe2eSLang Hames   SPSOutputBuffer OB(Buffer.get(), Size);
1604eb9fe2eSLang Hames 
1614eb9fe2eSLang Hames   EXPECT_TRUE(BAL::serialize(OB, Arg1, Arg2, Arg3));
1624eb9fe2eSLang Hames 
1634eb9fe2eSLang Hames   SPSInputBuffer IB(Buffer.get(), Size);
1644eb9fe2eSLang Hames 
1654eb9fe2eSLang Hames   bool ArgOut1;
1664eb9fe2eSLang Hames   int32_t ArgOut2;
1674eb9fe2eSLang Hames   std::string ArgOut3;
1684eb9fe2eSLang Hames 
1694eb9fe2eSLang Hames   EXPECT_TRUE(BAL::deserialize(IB, ArgOut1, ArgOut2, ArgOut3));
1704eb9fe2eSLang Hames 
1714eb9fe2eSLang Hames   EXPECT_EQ(Arg1, ArgOut1);
1724eb9fe2eSLang Hames   EXPECT_EQ(Arg2, ArgOut2);
1734eb9fe2eSLang Hames   EXPECT_EQ(Arg3, ArgOut3);
1744eb9fe2eSLang Hames }
175bb5f97e3SLang Hames 
TEST(SimplePackedSerialization,StringMap)176bb5f97e3SLang Hames TEST(SimplePackedSerialization, StringMap) {
177bb5f97e3SLang Hames   StringMap<int32_t> M({{"A", 1}, {"B", 2}});
17876d6a8dfSLang Hames   spsSerializationRoundTrip<SPSSequence<SPSTuple<SPSString, int32_t>>>(M);
179bb5f97e3SLang Hames }
180f38cfdabSLang Hames 
TEST(SimplePackedSerializationTest,ArrayRef)181f38cfdabSLang Hames TEST(SimplePackedSerializationTest, ArrayRef) {
182f38cfdabSLang Hames   constexpr unsigned BufferSize = 6 + 8; // "hello\0" + sizeof(uint64_t)
183f38cfdabSLang Hames   ArrayRef<char> HelloOut = "hello";
184f38cfdabSLang Hames   char Buffer[BufferSize];
185f38cfdabSLang Hames   memset(Buffer, 0, BufferSize);
186f38cfdabSLang Hames 
187f38cfdabSLang Hames   SPSOutputBuffer OB(Buffer, BufferSize);
188f38cfdabSLang Hames   EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, HelloOut));
189f38cfdabSLang Hames 
190f38cfdabSLang Hames   ArrayRef<char> HelloIn;
191f38cfdabSLang Hames   SPSInputBuffer IB(Buffer, BufferSize);
192f38cfdabSLang Hames   EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, HelloIn));
193f38cfdabSLang Hames 
194f38cfdabSLang Hames   // Output should be copied to buffer.
195f38cfdabSLang Hames   EXPECT_NE(HelloOut.data(), Buffer);
196f38cfdabSLang Hames 
197f38cfdabSLang Hames   // Input should reference buffer.
198f38cfdabSLang Hames   EXPECT_LT(HelloIn.data() - Buffer, BufferSize);
199f38cfdabSLang Hames }
20067220c2aSLang Hames 
TEST(SimplePackedSerializationTest,ArrayRefEmpty)20167220c2aSLang Hames TEST(SimplePackedSerializationTest, ArrayRefEmpty) {
20267220c2aSLang Hames   // Make sure that empty ArrayRefs serialize and deserialize as expected.
20367220c2aSLang Hames   // Empty ArrayRefs should not succeed even when the data field is null, and
20467220c2aSLang Hames   // should deserialize to a default-constructed ArrayRef, not a pointer into
20567220c2aSLang Hames   // the stream.
20667220c2aSLang Hames   constexpr unsigned BufferSize = sizeof(uint64_t);
20767220c2aSLang Hames   char Buffer[BufferSize];
20867220c2aSLang Hames   memset(Buffer, 0, BufferSize);
20967220c2aSLang Hames 
21067220c2aSLang Hames   ArrayRef<char> AOut;
21167220c2aSLang Hames   SPSOutputBuffer OB(Buffer, BufferSize);
21267220c2aSLang Hames   EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, AOut));
21367220c2aSLang Hames 
21467220c2aSLang Hames   ArrayRef<char> AIn;
21567220c2aSLang Hames   SPSInputBuffer IB(Buffer, BufferSize);
21667220c2aSLang Hames   EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, AIn));
21767220c2aSLang Hames 
21867220c2aSLang Hames   EXPECT_EQ(AIn.data(), nullptr);
21967220c2aSLang Hames   EXPECT_EQ(AIn.size(), 0U);
22067220c2aSLang Hames }
22194e6d267SLang Hames 
TEST(SimplePackedSerializationTest,StringRefEmpty)22294e6d267SLang Hames TEST(SimplePackedSerializationTest, StringRefEmpty) {
22394e6d267SLang Hames   // Make sure that empty StringRefs serialize and deserialize as expected.
22494e6d267SLang Hames   // Empty StringRefs should not succeed even when the data field is null, and
22594e6d267SLang Hames   // should deserialize to a default-constructed StringRef, not a pointer into
22694e6d267SLang Hames   // the stream.
22794e6d267SLang Hames   constexpr unsigned BufferSize = sizeof(uint64_t);
22894e6d267SLang Hames   char Buffer[BufferSize];
22994e6d267SLang Hames   memset(Buffer, 0, BufferSize);
23094e6d267SLang Hames 
23194e6d267SLang Hames   StringRef SROut;
23294e6d267SLang Hames   SPSOutputBuffer OB(Buffer, BufferSize);
23394e6d267SLang Hames   EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, SROut));
23494e6d267SLang Hames 
23594e6d267SLang Hames   StringRef SRIn;
23694e6d267SLang Hames   SPSInputBuffer IB(Buffer, BufferSize);
23794e6d267SLang Hames   EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, SRIn));
23894e6d267SLang Hames 
23994e6d267SLang Hames   EXPECT_EQ(SRIn.data(), nullptr);
24094e6d267SLang Hames   EXPECT_EQ(SRIn.size(), 0U);
24194e6d267SLang Hames }
242