242 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"10#include "gtest/gtest.h"11 12using namespace llvm;13using namespace llvm::orc::shared;14 15TEST(SimplePackedSerializationTest, SPSOutputBuffer) {16 constexpr unsigned NumBytes = 8;17 char Buffer[NumBytes];18 char Zero = 0;19 SPSOutputBuffer OB(Buffer, NumBytes);20 21 // Expect that we can write NumBytes of content.22 for (unsigned I = 0; I != NumBytes; ++I) {23 char C = I;24 EXPECT_TRUE(OB.write(&C, 1));25 }26 27 // Expect an error when we attempt to write an extra byte.28 EXPECT_FALSE(OB.write(&Zero, 1));29 30 // Check that the buffer contains the expected content.31 for (unsigned I = 0; I != NumBytes; ++I)32 EXPECT_EQ(Buffer[I], (char)I);33}34 35TEST(SimplePackedSerializationTest, SPSInputBuffer) {36 char Buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};37 SPSInputBuffer IB(Buffer, sizeof(Buffer));38 39 char C;40 for (unsigned I = 0; I != sizeof(Buffer); ++I) {41 EXPECT_TRUE(IB.read(&C, 1));42 EXPECT_EQ(C, (char)I);43 }44 45 EXPECT_FALSE(IB.read(&C, 1));46}47 48template <typename SPSTagT, typename T>49static void spsSerializationRoundTrip(const T &Value) {50 using BST = SPSSerializationTraits<SPSTagT, T>;51 52 size_t Size = BST::size(Value);53 auto Buffer = std::make_unique<char[]>(Size);54 SPSOutputBuffer OB(Buffer.get(), Size);55 56 EXPECT_TRUE(BST::serialize(OB, Value));57 58 SPSInputBuffer IB(Buffer.get(), Size);59 60 T DSValue;61 EXPECT_TRUE(BST::deserialize(IB, DSValue));62 63 EXPECT_EQ(Value, DSValue)64 << "Incorrect value after serialization/deserialization round-trip";65}66 67template <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());73 }74 spsSerializationRoundTrip<T, T>(std::numeric_limits<T>::max());75}76 77TEST(SimplePackedSerializationTest, BoolSerialization) {78 spsSerializationRoundTrip<bool, bool>(true);79 spsSerializationRoundTrip<bool, bool>(false);80}81 82TEST(SimplePackedSerializationTest, CharSerialization) {83 spsSerializationRoundTrip<char, char>((char)0x00);84 spsSerializationRoundTrip<char, char>((char)0xAA);85 spsSerializationRoundTrip<char, char>((char)0xFF);86}87 88TEST(SimplePackedSerializationTest, Int8Serialization) {89 testFixedIntegralTypeSerialization<int8_t>();90}91 92TEST(SimplePackedSerializationTest, UInt8Serialization) {93 testFixedIntegralTypeSerialization<uint8_t>();94}95 96TEST(SimplePackedSerializationTest, Int16Serialization) {97 testFixedIntegralTypeSerialization<int16_t>();98}99 100TEST(SimplePackedSerializationTest, UInt16Serialization) {101 testFixedIntegralTypeSerialization<uint16_t>();102}103 104TEST(SimplePackedSerializationTest, Int32Serialization) {105 testFixedIntegralTypeSerialization<int32_t>();106}107 108TEST(SimplePackedSerializationTest, UInt32Serialization) {109 testFixedIntegralTypeSerialization<uint32_t>();110}111 112TEST(SimplePackedSerializationTest, Int64Serialization) {113 testFixedIntegralTypeSerialization<int64_t>();114}115 116TEST(SimplePackedSerializationTest, UInt64Serialization) {117 testFixedIntegralTypeSerialization<uint64_t>();118}119 120TEST(SimplePackedSerializationTest, SequenceSerialization) {121 std::vector<int32_t> V({1, 2, -47, 139});122 spsSerializationRoundTrip<SPSSequence<int32_t>>(V);123}124 125TEST(SimplePackedSerializationTest, StringViewCharSequenceSerialization) {126 const char *HW = "Hello, world!";127 spsSerializationRoundTrip<SPSString>(StringRef(HW));128}129 130TEST(SimplePackedSerializationTest, StdTupleSerialization) {131 std::tuple<int32_t, std::string, bool> P(42, "foo", true);132 spsSerializationRoundTrip<SPSTuple<int32_t, SPSString, bool>>(P);133}134 135TEST(SimplePackedSerializationTest, StdPairSerialization) {136 std::pair<int32_t, std::string> P(42, "foo");137 spsSerializationRoundTrip<SPSTuple<int32_t, SPSString>>(P);138}139 140TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) {141 std::optional<int64_t> NoValue;142 spsSerializationRoundTrip<SPSOptional<int64_t>>(NoValue);143}144 145TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) {146 std::optional<int64_t> Value(42);147 spsSerializationRoundTrip<SPSOptional<int64_t>>(Value);148}149 150TEST(SimplePackedSerializationTest, ArgListSerialization) {151 using BAL = SPSArgList<bool, int32_t, SPSString>;152 153 bool Arg1 = true;154 int32_t Arg2 = 42;155 std::string Arg3 = "foo";156 157 size_t Size = BAL::size(Arg1, Arg2, Arg3);158 auto Buffer = std::make_unique<char[]>(Size);159 SPSOutputBuffer OB(Buffer.get(), Size);160 161 EXPECT_TRUE(BAL::serialize(OB, Arg1, Arg2, Arg3));162 163 SPSInputBuffer IB(Buffer.get(), Size);164 165 bool ArgOut1;166 int32_t ArgOut2;167 std::string ArgOut3;168 169 EXPECT_TRUE(BAL::deserialize(IB, ArgOut1, ArgOut2, ArgOut3));170 171 EXPECT_EQ(Arg1, ArgOut1);172 EXPECT_EQ(Arg2, ArgOut2);173 EXPECT_EQ(Arg3, ArgOut3);174}175 176TEST(SimplePackedSerialization, StringMap) {177 StringMap<int32_t> M({{"A", 1}, {"B", 2}});178 spsSerializationRoundTrip<SPSSequence<SPSTuple<SPSString, int32_t>>>(M);179}180 181TEST(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);186 187 SPSOutputBuffer OB(Buffer, BufferSize);188 EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, HelloOut));189 190 ArrayRef<char> HelloIn;191 SPSInputBuffer IB(Buffer, BufferSize);192 EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, HelloIn));193 194 // Output should be copied to buffer.195 EXPECT_NE(HelloOut.data(), Buffer);196 197 // Input should reference buffer.198 EXPECT_LT(HelloIn.data() - Buffer, BufferSize);199}200 201TEST(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, and204 // should deserialize to a default-constructed ArrayRef, not a pointer into205 // the stream.206 constexpr unsigned BufferSize = sizeof(uint64_t);207 char Buffer[BufferSize];208 memset(Buffer, 0, BufferSize);209 210 ArrayRef<char> AOut;211 SPSOutputBuffer OB(Buffer, BufferSize);212 EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, AOut));213 214 ArrayRef<char> AIn;215 SPSInputBuffer IB(Buffer, BufferSize);216 EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, AIn));217 218 EXPECT_EQ(AIn.data(), nullptr);219 EXPECT_EQ(AIn.size(), 0U);220}221 222TEST(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, and225 // should deserialize to a default-constructed StringRef, not a pointer into226 // the stream.227 constexpr unsigned BufferSize = sizeof(uint64_t);228 char Buffer[BufferSize];229 memset(Buffer, 0, BufferSize);230 231 StringRef SROut;232 SPSOutputBuffer OB(Buffer, BufferSize);233 EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, SROut));234 235 StringRef SRIn;236 SPSInputBuffer IB(Buffer, BufferSize);237 EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, SRIn));238 239 EXPECT_EQ(SRIn.data(), nullptr);240 EXPECT_EQ(SRIn.size(), 0U);241}242