//===-- simple_packed_serialization_test.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file is a part of the ORC runtime. // //===----------------------------------------------------------------------===// #include "simple_packed_serialization.h" #include "gtest/gtest.h" using namespace __orc_rt; TEST(SimplePackedSerializationTest, SPSOutputBuffer) { constexpr unsigned NumBytes = 8; char Buffer[NumBytes]; char Zero = 0; SPSOutputBuffer OB(Buffer, NumBytes); // Expect that we can write NumBytes of content. for (unsigned I = 0; I != NumBytes; ++I) { char C = I; EXPECT_TRUE(OB.write(&C, 1)); } // Expect an error when we attempt to write an extra byte. EXPECT_FALSE(OB.write(&Zero, 1)); // Check that the buffer contains the expected content. for (unsigned I = 0; I != NumBytes; ++I) EXPECT_EQ(Buffer[I], (char)I); } TEST(SimplePackedSerializationTest, SPSInputBuffer) { char Buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; SPSInputBuffer IB(Buffer, sizeof(Buffer)); char C; for (unsigned I = 0; I != sizeof(Buffer); ++I) { EXPECT_TRUE(IB.read(&C, 1)); EXPECT_EQ(C, (char)I); } EXPECT_FALSE(IB.read(&C, 1)); } template static void blobSerializationRoundTrip(const T &Value) { using BST = SPSSerializationTraits; size_t Size = BST::size(Value); auto Buffer = std::make_unique(Size); SPSOutputBuffer OB(Buffer.get(), Size); EXPECT_TRUE(BST::serialize(OB, Value)); SPSInputBuffer IB(Buffer.get(), Size); T DSValue; EXPECT_TRUE(BST::deserialize(IB, DSValue)); EXPECT_EQ(Value, DSValue) << "Incorrect value after serialization/deserialization round-trip"; } template static void testFixedIntegralTypeSerialization() { blobSerializationRoundTrip(0); blobSerializationRoundTrip(static_cast(1)); if (std::is_signed::value) { blobSerializationRoundTrip(static_cast(-1)); blobSerializationRoundTrip(std::numeric_limits::min()); } blobSerializationRoundTrip(std::numeric_limits::max()); } TEST(SimplePackedSerializationTest, BoolSerialization) { blobSerializationRoundTrip(true); blobSerializationRoundTrip(false); } TEST(SimplePackedSerializationTest, CharSerialization) { blobSerializationRoundTrip((char)0x00); blobSerializationRoundTrip((char)0xAA); blobSerializationRoundTrip((char)0xFF); } TEST(SimplePackedSerializationTest, Int8Serialization) { testFixedIntegralTypeSerialization(); } TEST(SimplePackedSerializationTest, UInt8Serialization) { testFixedIntegralTypeSerialization(); } TEST(SimplePackedSerializationTest, Int16Serialization) { testFixedIntegralTypeSerialization(); } TEST(SimplePackedSerializationTest, UInt16Serialization) { testFixedIntegralTypeSerialization(); } TEST(SimplePackedSerializationTest, Int32Serialization) { testFixedIntegralTypeSerialization(); } TEST(SimplePackedSerializationTest, UInt32Serialization) { testFixedIntegralTypeSerialization(); } TEST(SimplePackedSerializationTest, Int64Serialization) { testFixedIntegralTypeSerialization(); } TEST(SimplePackedSerializationTest, UInt64Serialization) { testFixedIntegralTypeSerialization(); } TEST(SimplePackedSerializationTest, SequenceSerialization) { std::vector V({1, 2, -47, 139}); blobSerializationRoundTrip, std::vector>(V); } TEST(SimplePackedSerializationTest, StringViewCharSequenceSerialization) { const char *HW = "Hello, world!"; blobSerializationRoundTrip(std::string_view(HW)); } TEST(SimplePackedSerializationTest, SpanSerialization) { const char Data[] = {3, 2, 1, 0, 1, 2, 3}; // Span should handle nulls. span OutS(Data, sizeof(Data)); size_t Size = SPSArgList>::size(OutS); auto Buffer = std::make_unique(Size); SPSOutputBuffer OB(Buffer.get(), Size); EXPECT_TRUE(SPSArgList>::serialize(OB, OutS)); SPSInputBuffer IB(Buffer.get(), Size); span InS; EXPECT_TRUE(SPSArgList>::deserialize(IB, InS)); // Check that the serialized and deserialized values match. EXPECT_EQ(InS.size(), OutS.size()); EXPECT_EQ(memcmp(OutS.data(), InS.data(), InS.size()), 0); // Check that the span points directly to the input buffer. EXPECT_EQ(InS.data(), Buffer.get() + sizeof(uint64_t)); } TEST(SimplePackedSerializationTest, StdPairSerialization) { std::pair P(42, "foo"); blobSerializationRoundTrip, std::pair>(P); } TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) { std::optional NoValue; blobSerializationRoundTrip>(NoValue); } TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) { std::optional Value(42); blobSerializationRoundTrip>(Value); } TEST(SimplePackedSerializationTest, ArgListSerialization) { using BAL = SPSArgList; bool Arg1 = true; int32_t Arg2 = 42; std::string Arg3 = "foo"; size_t Size = BAL::size(Arg1, Arg2, Arg3); auto Buffer = std::make_unique(Size); SPSOutputBuffer OB(Buffer.get(), Size); EXPECT_TRUE(BAL::serialize(OB, Arg1, Arg2, Arg3)); SPSInputBuffer IB(Buffer.get(), Size); bool ArgOut1; int32_t ArgOut2; std::string ArgOut3; EXPECT_TRUE(BAL::deserialize(IB, ArgOut1, ArgOut2, ArgOut3)); EXPECT_EQ(Arg1, ArgOut1); EXPECT_EQ(Arg2, ArgOut2); EXPECT_EQ(Arg3, ArgOut3); }