1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "serializer/serializer.h"
17 #include <gtest/gtest.h>
18
19 namespace panda {
20
21 class SerializatorTest : public testing::Test {
22 protected:
SetUp()23 void SetUp()
24 {
25 buffer.resize(0);
26 }
27 std::vector<uint8_t> buffer;
28 };
29
30 template <typename T>
SerializerTypeToBuffer(const T & type,std::vector<uint8_t> & buffer,size_t ret_val)31 void SerializerTypeToBuffer(const T &type, /* out */ std::vector<uint8_t> &buffer, size_t ret_val)
32 {
33 auto ret = serializer::TypeToBuffer(type, buffer);
34 ASSERT_TRUE(ret);
35 ASSERT_EQ(ret.Value(), ret_val);
36 }
37
38 template <typename T>
SerializerBufferToType(const std::vector<uint8_t> & buffer,T & type,size_t ret_val)39 void SerializerBufferToType(const std::vector<uint8_t> &buffer, /* out */ T &type, size_t ret_val)
40 {
41 auto ret = serializer::BufferToType(buffer.data(), buffer.size(), type);
42 ASSERT_TRUE(ret);
43 ASSERT_EQ(ret.Value(), ret_val);
44 }
45
46 template <typename T>
DoTest(T value,int ret_val)47 void DoTest(T value, int ret_val)
48 {
49 constexpr const int64_t IMM_FOUR = 4;
50 T a = value;
51 T b;
52 std::vector<uint8_t> buffer;
53 SerializerTypeToBuffer(a, buffer, ret_val);
54 buffer.resize(IMM_FOUR * buffer.size());
55 SerializerBufferToType(buffer, b, ret_val);
56 ASSERT_EQ(a, value);
57 ASSERT_EQ(b, value);
58 ASSERT_EQ(a, b);
59 }
60
61 template <typename T>
TestPod(T value)62 void TestPod(T value)
63 {
64 static_assert(std::is_pod<T>::value, "Type is not supported");
65
66 DoTest(value, sizeof(value));
67 }
68
69 struct PodStruct {
70 uint8_t a;
71 int16_t b;
72 uint32_t c;
73 int64_t d;
74 float e;
75 long double f;
76 };
operator ==(const PodStruct & lhs,const PodStruct & rhs)77 bool operator==(const PodStruct &lhs, const PodStruct &rhs)
78 {
79 return lhs.a == rhs.a && lhs.b == rhs.b && lhs.c == rhs.c && lhs.d == rhs.d && lhs.e == rhs.e && lhs.f == rhs.f;
80 }
81
TEST_F(SerializatorTest,TestPodTypes)82 TEST_F(SerializatorTest, TestPodTypes)
83 {
84 TestPod<uint8_t>(0xac);
85 TestPod<uint16_t>(0xc0de);
86 TestPod<uint32_t>(0x123f567f);
87 TestPod<uint64_t>(0xff12345789103c4b);
88
89 TestPod<int8_t>(0x1c);
90 TestPod<int16_t>(0x1ebd);
91 TestPod<int32_t>(0xfe52567f);
92 TestPod<int64_t>(0xff1234fdec57891b);
93
94 TestPod<float>(0.234664);
95 TestPod<double>(22345.3453453);
96 TestPod<long double>(99453.64345);
97
98 TestPod<PodStruct>({0xff, -23458, 10345893, -98343451, -3.54634, 1.44e6});
99 }
100
TEST_F(SerializatorTest,TestString)101 TEST_F(SerializatorTest, TestString)
102 {
103 DoTest<std::string>({}, 4);
104 DoTest<std::string>("", 4);
105 DoTest<std::string>("Hello World!", 4 + 12);
106 DoTest<std::string>("1", 4 + 1);
107 DoTest<std::string>({}, 4);
108 }
109
TEST_F(SerializatorTest,TestVectorPod)110 TEST_F(SerializatorTest, TestVectorPod)
111 {
112 DoTest<std::vector<uint8_t>>({1, 2, 3, 4}, 4 + 1 * 4);
113 DoTest<std::vector<uint16_t>>({143, 452, 334}, 4 + 2 * 3);
114 DoTest<std::vector<uint32_t>>({15434, 4564562, 33453, 43456, 346346}, 4 + 5 * 4);
115 DoTest<std::vector<uint64_t>>({14345665644345, 34645345465}, 4 + 8 * 2);
116 DoTest<std::vector<char>>({}, 4 + 1 * 0);
117 }
118
TEST_F(SerializatorTest,TestUnorderedMap1)119 TEST_F(SerializatorTest, TestUnorderedMap1)
120 {
121 using Map = std::unordered_map<uint32_t, uint16_t>;
122 DoTest<Map>(
123 {
124 {12343526, 23424},
125 {3, 234356},
126 {45764746, 4},
127 },
128 4 + 3 * (4 + 2));
129 }
130
TEST_F(SerializatorTest,TestUnorderedMap2)131 TEST_F(SerializatorTest, TestUnorderedMap2)
132 {
133 using Map = std::unordered_map<std::string, std::string>;
134 DoTest<Map>(
135 {
136 {"one", {}},
137 {"two", "123"},
138 {"three", ""},
139 {"", {}},
140 },
141 4 + 4 + 3 + 4 + 0 + 4 + 3 + 4 + 3 + 4 + 5 + 4 + 0 + 4 + 0 + 4 + 0);
142 }
143
TEST_F(SerializatorTest,TestUnorderedMap3)144 TEST_F(SerializatorTest, TestUnorderedMap3)
145 {
146 using Map = std::unordered_map<std::string, std::vector<uint32_t>>;
147 DoTest<Map>(
148 {
149 {"one", {}},
150 {"two", {1, 2, 3, 4}},
151 {"three", {9, 34, 45335}},
152 {"", {}},
153 },
154 4 + 4 + 3 + 4 + 4 * 0 + 4 + 3 + 4 + 4 * 4 + 4 + 5 + 4 + 4 * 3 + 4 + 0 + 4 + 4 * 0);
155 }
156
157 struct TestStruct {
158 uint8_t a;
159 uint16_t b;
160 uint32_t c;
161 uint64_t d;
162 std::string e;
163 std::vector<int> f;
164 };
operator ==(const TestStruct & lhs,const TestStruct & rhs)165 bool operator==(const TestStruct &lhs, const TestStruct &rhs)
166 {
167 return lhs.a == rhs.a && lhs.b == rhs.b && lhs.c == rhs.c && lhs.d == rhs.d && lhs.e == rhs.e && lhs.f == rhs.f;
168 }
169
TEST_F(SerializatorTest,TestStruct)170 TEST_F(SerializatorTest, TestStruct)
171 {
172 TestStruct test_struct {1, 2, 3, 4, "Liza", {8, 9, 5}};
173 unsigned test_ret = 1 + 2 + 4 + 8 + 4 + 4 + 4 + sizeof(int) * 3;
174
175 TestStruct a = test_struct;
176 TestStruct b;
177 ASSERT_EQ(serializer::StructToBuffer<6>(a, buffer), true);
178 buffer.resize(4 * buffer.size());
179 auto ret = serializer::RawBufferToStruct<6>(buffer.data(), buffer.size(), b);
180 ASSERT_TRUE(ret.HasValue());
181 ASSERT_EQ(ret.Value(), test_ret);
182 ASSERT_EQ(a, test_struct);
183 ASSERT_EQ(b, test_struct);
184 ASSERT_EQ(a, b);
185 }
186
187 } // namespace panda
188