1 /*
2 * Copyright (c) 2021 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 "tlv_ut.h"
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19
20 using namespace testing::ext;
21 using namespace testing;
22
23 namespace Hdc {
24 #define MAX_BUFFER_SIZE (1 * 1024 * 1024 * 1024)
25 class HdcTLVTest : public testing::Test {
26 public:
27 static void SetUpTestCase(void);
28 static void TearDownTestCase(void);
29 void SetUp();
30 void TearDown();
31 private:
32 uint8_t *BuildTlv(const std::vector<uint32_t> tags,
33 const std::vector<uint32_t> sizes, uint8_t val, uint32_t &tlvsize) const;
34
TlvSize(uint32_t len)35 uint32_t TlvSize(uint32_t len) { return len + TLV_HEAD_SIZE; }
36 };
37
SetUpTestCase()38 void HdcTLVTest::SetUpTestCase()
39 {
40 }
41
TearDownTestCase()42 void HdcTLVTest::TearDownTestCase() {}
43
SetUp()44 void HdcTLVTest::SetUp() {}
45
TearDown()46 void HdcTLVTest::TearDown() {}
47
BuildTlv(const std::vector<uint32_t> tags,const std::vector<uint32_t> sizes,uint8_t val,uint32_t & tlvsize) const48 uint8_t *HdcTLVTest::BuildTlv(const std::vector<uint32_t> tags,
49 const std::vector<uint32_t> sizes,
50 uint8_t val,
51 uint32_t &tlvsize) const
52 {
53 if (tags.size() != sizes.size() || tags.empty()) {
54 WRITE_LOG(LOG_WARN, "not valid size: %u, %u", tags.size(), sizes.size());
55 return nullptr;
56 }
57 tlvsize = 0;
58 for (auto size : sizes) {
59 tlvsize += TLV_HEAD_SIZE;
60 tlvsize += size;
61 }
62
63 if (tlvsize == 0 || tlvsize > MAX_BUFFER_SIZE) {
64 WRITE_LOG(LOG_WARN, "invalid size 0");
65 return nullptr;
66 }
67 uint8_t *tlv = new (std::nothrow) uint8_t[tlvsize];
68 if (tlv == nullptr) {
69 WRITE_LOG(LOG_WARN, "not enough memory %u", tlvsize);
70 tlvsize = 0;
71 return nullptr;
72 }
73 uint32_t pos = 0;
74 int i = 0;
75 for (; pos < tlvsize && i < tags.size(); i++) {
76 *(uint32_t *)(tlv + pos) = tags[i];
77 *(uint32_t *)(tlv + pos + sizeof(tags[i])) = sizes[i];
78
79 pos += TLV_HEAD_SIZE;
80 if (memset_s(tlv + pos, tlvsize - pos, val, sizes[i]) != 0) {
81 tlvsize = 0;
82 delete[] tlv;
83 return nullptr;
84 }
85 pos += sizes[i];
86 }
87
88 return tlv;
89 }
90
91 HWTEST_F(HdcTLVTest, TlvBuf_Constructor_001, TestSize.Level0)
92 {
93 TlvBuf tb;
94 ASSERT_EQ(tb.GetBufSize(), 0);
95 }
96
97 HWTEST_F(HdcTLVTest, TlvBuf_Constructor_002, TestSize.Level0)
98 {
99 std::set<uint32_t> validtags = { 1, 2, 3 };
100 TlvBuf tb(validtags);
101 ASSERT_EQ(tb.GetBufSize(), 0);
102 }
103
104 HWTEST_F(HdcTLVTest, TlvBuf_Constructor_003, TestSize.Level0)
105 {
106 std::vector<uint32_t> tags = { 1 };
107 std::vector<uint32_t> sizes = { 1 };
108 uint32_t tlvsize = 0;
109 uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);
110 ASSERT_NE(tlv, nullptr);
111
112 TlvBuf tb(tlv, tlvsize);
113 ASSERT_EQ(tb.GetBufSize(), tlvsize);
114
115 delete[] tlv;
116 }
117
118 HWTEST_F(HdcTLVTest, TlvBuf_Constructor_004, TestSize.Level0)
119 {
120 std::set<uint32_t> validtags = { 1, 2, 3 };
121
122 std::vector<uint32_t> tags = { 1 };
123 std::vector<uint32_t> sizes = { 1 };
124 uint32_t tlvsize = 0;
125 uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);
126 ASSERT_NE(tlv, nullptr);
127
128 TlvBuf tb(tlv, tlvsize, validtags);
129 ASSERT_EQ(tb.GetBufSize(), tlvsize);
130
131 delete[] tlv;
132 }
133
134 HWTEST_F(HdcTLVTest, TlvBuf_Constructor_005, TestSize.Level0)
135 {
136 std::set<uint32_t> validtags = { 1, 2, 3 };
137
138 std::vector<uint32_t> tags = { 1 };
139 std::vector<uint32_t> sizes = { TLV_VALUE_MAX_LEN + 1 };
140 uint32_t tlvsize = 0;
141 uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);
142 ASSERT_NE(tlv, nullptr);
143
144 TlvBuf tb(tlv, tlvsize, validtags);
145 ASSERT_EQ(tb.GetBufSize(), 0);
146
147 delete[] tlv;
148 }
149
150 HWTEST_F(HdcTLVTest, TlvBuf_Clear_001, TestSize.Level0)
151 {
152 std::vector<uint32_t> tags = { 1 };
153 std::vector<uint32_t> sizes = { 1 };
154 uint32_t tlvsize = 0;
155 uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);
156 ASSERT_NE(tlv, nullptr);
157
158 TlvBuf tb(tlv, tlvsize);
159 ASSERT_EQ(tb.GetBufSize(), tlvsize);
160 tb.Clear();
161 ASSERT_EQ(tb.GetBufSize(), 0);
162
163 delete[] tlv;
164 }
165
166 HWTEST_F(HdcTLVTest, TlvBuf_Append_001, TestSize.Level0)
167 {
168 uint8_t val[10] = { 0xAC };
169 TlvBuf tb;
170 ASSERT_EQ(tb.GetBufSize(), 0);
171
172 ASSERT_EQ(tb.Append(1, sizeof(val), val), true);
173 ASSERT_EQ(tb.GetBufSize(), TlvSize(sizeof(val)));
174
175 // duplicate, append failed, nothing changed
176 ASSERT_EQ(tb.Append(1, sizeof(val), val), false);
177 ASSERT_EQ(tb.GetBufSize(), TlvSize(sizeof(val)));
178
179 ASSERT_EQ(tb.Append(2, sizeof(val), val), true);
180 ASSERT_EQ(tb.GetBufSize(), TlvSize(sizeof(val)) * 2);
181 }
182
183 HWTEST_F(HdcTLVTest, TlvBuf_Append_002, TestSize.Level0)
184 {
185 uint32_t tag = 1;
186 string val = "hello world!";
187 TlvBuf tb;
188 ASSERT_EQ(tb.GetBufSize(), 0);
189
190 ASSERT_EQ(tb.Append(tag, val), true);
191 ASSERT_EQ(tb.GetBufSize(), TlvSize(val.size()));
192 }
193
194 HWTEST_F(HdcTLVTest, TlvBuf_Append_003, TestSize.Level0)
195 {
196 TlvBuf tb;
197
198 ASSERT_EQ(tb.Append(1, 0, nullptr), false);
199 ASSERT_EQ(tb.GetBufSize(), 0);
200
201 ASSERT_EQ(tb.Append(1, TLV_VALUE_MAX_LEN + 1, nullptr), false);
202 ASSERT_EQ(tb.GetBufSize(), 0);
203
204 ASSERT_EQ(tb.Append(1, TLV_VALUE_MAX_LEN, nullptr), false);
205 ASSERT_EQ(tb.GetBufSize(), 0);
206 }
207
208 HWTEST_F(HdcTLVTest, TlvBuf_CopyToBuf_001, TestSize.Level0)
209 {
210 uint32_t tag = 1;
211 const uint32_t len = 10;
212 uint8_t val[len] = { 0xAC };
213 TlvBuf tb;
214 ASSERT_EQ(tb.GetBufSize(), 0);
215
216 ASSERT_EQ(tb.Append(tag, len, val), true);
217 uint32_t size = tb.GetBufSize();
218 ASSERT_EQ(size, TlvSize(len));
219
220 uint8_t *buf = new (std::nothrow) uint8_t[size];
221 ASSERT_EQ(tb.CopyToBuf(buf, size - 1), false);
222 ASSERT_EQ(tb.CopyToBuf(nullptr, size), false);
223
224 ASSERT_EQ(tb.CopyToBuf(buf, size), true);
225 ASSERT_EQ(*(uint32_t *)buf, tag);
226 ASSERT_EQ(*(uint32_t *)(buf + sizeof(tag)), len);
227 ASSERT_EQ(memcmp(buf + TLV_HEAD_SIZE, val, len), 0);
228 }
229
230 HWTEST_F(HdcTLVTest, TlvBuf_FindTlv_001, TestSize.Level0)
231 {
232 uint32_t tag = 1;
233 const uint32_t len = 10;
234 uint8_t val[len] = { 0xAC };
235 TlvBuf tb;
236 ASSERT_EQ(tb.GetBufSize(), 0);
237
238 ASSERT_EQ(tb.Append(tag, len, val), true);
239 ASSERT_EQ(tb.GetBufSize(), TlvSize(len));
240
241 uint32_t ftag = 2;
242 uint32_t flen = 1;
243 uint8_t *fval = nullptr;
244 ASSERT_EQ(tb.FindTlv(ftag, flen, fval), false);
245 ASSERT_EQ(fval, nullptr);
246 ftag = 1;
247 ASSERT_EQ(tb.FindTlv(ftag, flen, fval), true);
248 ASSERT_EQ(flen, len);
249 ASSERT_EQ(memcmp(fval, val, len), 0);
250
251 delete[] fval;
252 }
253
254 HWTEST_F(HdcTLVTest, TlvBuf_FindTlv_002, TestSize.Level0)
255 {
256 uint32_t tag = 1;
257 string val = "hello world!";
258 TlvBuf tb;
259 ASSERT_EQ(tb.GetBufSize(), 0);
260
261 ASSERT_EQ(tb.Append(tag, val), true);
262 ASSERT_EQ(tb.GetBufSize(), TlvSize(val.size()));
263
264 string fval;
265 ASSERT_EQ(tb.FindTlv(tag, fval), true);
266 ASSERT_EQ(val, fval);
267 }
268
269 HWTEST_F(HdcTLVTest, TlvBuf_ContainInvalidTag_001, TestSize.Level0)
270 {
271 std::set<uint32_t> validtags = { 1, 2, 3 };
272 std::vector<uint32_t> tags = { 1, 2, 3 };
273 std::vector<uint32_t> sizes = { 4, 4, 4 };
274 uint32_t tlvsize = 0;
275 uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);
276 ASSERT_NE(tlv, nullptr);
277 TlvBuf tb(tlv, tlvsize, validtags);
278 ASSERT_EQ(tb.GetBufSize(), tlvsize);
279
280 ASSERT_EQ(tb.ContainInvalidTag(), false);
281
282 uint32_t tag = 5;
283 const uint32_t len = 10;
284 uint8_t val[len] = { 0xAC };
285 ASSERT_EQ(tb.Append(tag, len, val), true);
286 ASSERT_EQ(tb.ContainInvalidTag(), true);
287
288 delete[] tlv;
289 }
290
291 HWTEST_F(HdcTLVTest, TlvBuf_ContainInvalidTag_002, TestSize.Level0)
292 {
293 std::set<uint32_t> validtags = { 1, 2 };
294 std::vector<uint32_t> tags = { 1, 2, 3 };
295 std::vector<uint32_t> sizes = { 4, 4, 4 };
296 uint32_t tlvsize = 0;
297 uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);
298 ASSERT_NE(tlv, nullptr);
299 TlvBuf tb(tlv, tlvsize, validtags);
300 ASSERT_EQ(tb.GetBufSize(), tlvsize);
301
302 ASSERT_EQ(tb.ContainInvalidTag(), true);
303
304 delete[] tlv;
305 }
306
307 HWTEST_F(HdcTLVTest, TlvBuf_Display_001, TestSize.Level0)
308 {
309 std::vector<uint32_t> tags = { 1 };
310 std::vector<uint32_t> sizes = { 1 };
311 uint32_t tlvsize = 0;
312 uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);
313 ASSERT_NE(tlv, nullptr);
314
315 TlvBuf tb(tlv, tlvsize);
316 ASSERT_EQ(tb.GetBufSize(), tlvsize);
317 tb.Display();
318
319 delete[] tlv;
320 }
321
322 } // namespace Hdc
323