1 | //===-- simple_packed_serialization_test.cpp ------------------------------===// |
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 | // This file is a part of the ORC runtime. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "simple_packed_serialization.h" |
14 | #include "simple_packed_serialization_utils.h" |
15 | #include "gtest/gtest.h" |
16 | |
17 | using namespace __orc_rt; |
18 | |
19 | TEST(SimplePackedSerializationTest, SPSOutputBuffer) { |
20 | constexpr unsigned NumBytes = 8; |
21 | char Buffer[NumBytes]; |
22 | char Zero = 0; |
23 | SPSOutputBuffer OB(Buffer, NumBytes); |
24 | |
25 | // Expect that we can write NumBytes of content. |
26 | for (unsigned I = 0; I != NumBytes; ++I) { |
27 | char C = I; |
28 | EXPECT_TRUE(OB.write(Data: &C, Size: 1)); |
29 | } |
30 | |
31 | // Expect an error when we attempt to write an extra byte. |
32 | EXPECT_FALSE(OB.write(Data: &Zero, Size: 1)); |
33 | |
34 | // Check that the buffer contains the expected content. |
35 | for (unsigned I = 0; I != NumBytes; ++I) |
36 | EXPECT_EQ(Buffer[I], (char)I); |
37 | } |
38 | |
39 | TEST(SimplePackedSerializationTest, SPSInputBuffer) { |
40 | char Buffer[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; |
41 | SPSInputBuffer IB(Buffer, sizeof(Buffer)); |
42 | |
43 | char C; |
44 | for (unsigned I = 0; I != sizeof(Buffer); ++I) { |
45 | EXPECT_TRUE(IB.read(Data: &C, Size: 1)); |
46 | EXPECT_EQ(C, (char)I); |
47 | } |
48 | |
49 | EXPECT_FALSE(IB.read(Data: &C, Size: 1)); |
50 | } |
51 | |
52 | template <typename T> static void testFixedIntegralTypeSerialization() { |
53 | blobSerializationRoundTrip<T, T>(0); |
54 | blobSerializationRoundTrip<T, T>(static_cast<T>(1)); |
55 | if (std::is_signed<T>::value) { |
56 | blobSerializationRoundTrip<T, T>(static_cast<T>(-1)); |
57 | blobSerializationRoundTrip<T, T>(std::numeric_limits<T>::min()); |
58 | } |
59 | blobSerializationRoundTrip<T, T>(std::numeric_limits<T>::max()); |
60 | } |
61 | |
62 | TEST(SimplePackedSerializationTest, BoolSerialization) { |
63 | blobSerializationRoundTrip<bool, bool>(Value: true); |
64 | blobSerializationRoundTrip<bool, bool>(Value: false); |
65 | } |
66 | |
67 | TEST(SimplePackedSerializationTest, CharSerialization) { |
68 | blobSerializationRoundTrip<char, char>(Value: (char)0x00); |
69 | blobSerializationRoundTrip<char, char>(Value: (char)0xAA); |
70 | blobSerializationRoundTrip<char, char>(Value: (char)0xFF); |
71 | } |
72 | |
73 | TEST(SimplePackedSerializationTest, Int8Serialization) { |
74 | testFixedIntegralTypeSerialization<int8_t>(); |
75 | } |
76 | |
77 | TEST(SimplePackedSerializationTest, UInt8Serialization) { |
78 | testFixedIntegralTypeSerialization<uint8_t>(); |
79 | } |
80 | |
81 | TEST(SimplePackedSerializationTest, Int16Serialization) { |
82 | testFixedIntegralTypeSerialization<int16_t>(); |
83 | } |
84 | |
85 | TEST(SimplePackedSerializationTest, UInt16Serialization) { |
86 | testFixedIntegralTypeSerialization<uint16_t>(); |
87 | } |
88 | |
89 | TEST(SimplePackedSerializationTest, Int32Serialization) { |
90 | testFixedIntegralTypeSerialization<int32_t>(); |
91 | } |
92 | |
93 | TEST(SimplePackedSerializationTest, UInt32Serialization) { |
94 | testFixedIntegralTypeSerialization<uint32_t>(); |
95 | } |
96 | |
97 | TEST(SimplePackedSerializationTest, Int64Serialization) { |
98 | testFixedIntegralTypeSerialization<int64_t>(); |
99 | } |
100 | |
101 | TEST(SimplePackedSerializationTest, UInt64Serialization) { |
102 | testFixedIntegralTypeSerialization<uint64_t>(); |
103 | } |
104 | |
105 | TEST(SimplePackedSerializationTest, SequenceSerialization) { |
106 | std::vector<int32_t> V({1, 2, -47, 139}); |
107 | blobSerializationRoundTrip<SPSSequence<int32_t>, std::vector<int32_t>>(Value: V); |
108 | } |
109 | |
110 | TEST(SimplePackedSerializationTest, StringViewCharSequenceSerialization) { |
111 | const char *HW = "Hello, world!" ; |
112 | blobSerializationRoundTrip<SPSString, std::string_view>(Value: std::string_view(HW)); |
113 | } |
114 | |
115 | TEST(SimplePackedSerializationTest, SpanSerialization) { |
116 | const char Data[] = {3, 2, 1, 0, 1, 2, 3}; // Span should handle nulls. |
117 | span<const char> OutS(Data, sizeof(Data)); |
118 | |
119 | size_t Size = SPSArgList<SPSSequence<char>>::size(Arg: OutS); |
120 | auto Buffer = std::make_unique<char[]>(num: Size); |
121 | SPSOutputBuffer OB(Buffer.get(), Size); |
122 | |
123 | EXPECT_TRUE(SPSArgList<SPSSequence<char>>::serialize(OB, Arg: OutS)); |
124 | |
125 | SPSInputBuffer IB(Buffer.get(), Size); |
126 | |
127 | span<const char> InS; |
128 | |
129 | EXPECT_TRUE(SPSArgList<SPSSequence<char>>::deserialize(IB, Arg&: InS)); |
130 | |
131 | // Check that the serialized and deserialized values match. |
132 | EXPECT_EQ(InS.size(), OutS.size()); |
133 | EXPECT_EQ(memcmp(s1: OutS.data(), s2: InS.data(), n: InS.size()), 0); |
134 | |
135 | // Check that the span points directly to the input buffer. |
136 | EXPECT_EQ(InS.data(), Buffer.get() + sizeof(uint64_t)); |
137 | } |
138 | |
139 | TEST(SimplePackedSerializationTest, StdTupleSerialization) { |
140 | std::tuple<int32_t, std::string, bool> P(42, "foo" , true); |
141 | blobSerializationRoundTrip<SPSTuple<int32_t, SPSString, bool>>(Value: P); |
142 | } |
143 | |
144 | TEST(SimplePackedSerializationTest, StdPairSerialization) { |
145 | std::pair<int32_t, std::string> P(42, "foo" ); |
146 | blobSerializationRoundTrip<SPSTuple<int32_t, SPSString>, |
147 | std::pair<int32_t, std::string>>(Value: P); |
148 | } |
149 | |
150 | TEST(SimplePackedSerializationTest, StdOptionalNoValueSerialization) { |
151 | std::optional<int64_t> NoValue; |
152 | blobSerializationRoundTrip<SPSOptional<int64_t>>(Value: NoValue); |
153 | } |
154 | |
155 | TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) { |
156 | std::optional<int64_t> Value(42); |
157 | blobSerializationRoundTrip<SPSOptional<int64_t>>(Value); |
158 | } |
159 | |
160 | TEST(SimplePackedSerializationTest, ArgListSerialization) { |
161 | using BAL = SPSArgList<bool, int32_t, SPSString>; |
162 | |
163 | bool Arg1 = true; |
164 | int32_t Arg2 = 42; |
165 | std::string Arg3 = "foo" ; |
166 | |
167 | size_t Size = BAL::size(Arg: Arg1, Args: Arg2, Args: Arg3); |
168 | auto Buffer = std::make_unique<char[]>(num: Size); |
169 | SPSOutputBuffer OB(Buffer.get(), Size); |
170 | |
171 | EXPECT_TRUE(BAL::serialize(OB, Arg: Arg1, Args: Arg2, Args: Arg3)); |
172 | |
173 | SPSInputBuffer IB(Buffer.get(), Size); |
174 | |
175 | bool ArgOut1; |
176 | int32_t ArgOut2; |
177 | std::string ArgOut3; |
178 | |
179 | EXPECT_TRUE(BAL::deserialize(IB, Arg&: ArgOut1, Args&: ArgOut2, Args&: ArgOut3)); |
180 | |
181 | EXPECT_EQ(Arg1, ArgOut1); |
182 | EXPECT_EQ(Arg2, ArgOut2); |
183 | EXPECT_EQ(Arg3, ArgOut3); |
184 | } |
185 | |