1/*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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#include <cstdlib>
16#include <limits>
17#include <vector>
18#include <gtest/gtest.h>
19
20#include "varint_encode.h"
21
22namespace OHOS {
23namespace Developtools {
24namespace Profiler {
25using namespace testing::ext;
26using namespace ProtoEncoder;
27
28class VarintEncodeUnittest : public ::testing::Test {
29public:
30    static void SetUpTestCase() {};
31    static void TearDownTestCase() {};
32
33    void SetUp() {};
34    void TearDown() {};
35
36    const uint32_t two = 2;
37    const uint32_t three = 3;
38    const uint32_t four = 4;
39};
40
41HWTEST_F(VarintEncodeUnittest, GetPackedVarintLenSize, TestSize.Level1)
42{
43    uint32_t len = 0;
44    uint32_t itemCount = 0;
45    uint32_t itemSize = sizeof(char);
46    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), (uint32_t)1);
47    EXPECT_EQ(len, (uint32_t)0);
48
49    itemSize = sizeof(int32_t);
50    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), (uint32_t)1);
51    EXPECT_EQ(len, itemCount * itemSize);
52
53    itemSize = sizeof(int64_t);
54    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), (uint32_t)1);
55    EXPECT_EQ(len, itemCount * itemSize);
56
57    itemSize = sizeof(char);
58    itemCount = VARINT_MAX_1BYTE;
59    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), (uint32_t)1);
60    EXPECT_EQ(len, itemCount * itemSize);
61
62    itemCount++;
63    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), two);
64    EXPECT_EQ(len, itemCount * itemSize);
65
66    itemCount = VARINT_MAX_2BYTE;
67    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), two);
68    EXPECT_EQ(len, itemCount * itemSize);
69
70    itemCount++;
71    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), three);
72    EXPECT_EQ(len, itemCount * itemSize);
73
74    itemCount = VARINT_MAX_3BYTE;
75    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), three);
76    EXPECT_EQ(len, itemCount * itemSize);
77
78    itemCount++;
79    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), four);
80    EXPECT_EQ(len, itemCount * itemSize);
81
82    itemCount = VARINT_MAX_4BYTE;
83    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), four);
84    EXPECT_EQ(len, itemCount * itemSize);
85
86    itemCount++;
87    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), (uint32_t)0);
88    EXPECT_EQ(len, itemCount * itemSize);
89
90    itemSize = sizeof(int32_t);
91    itemCount = VARINT_MAX_1BYTE / (itemSize + 1);
92    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), (uint32_t)1);
93    EXPECT_EQ(len, itemCount * (itemSize + 1));
94
95    itemCount++;
96    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), two);
97    EXPECT_EQ(len, itemCount * (itemSize + 1));
98
99    itemCount = VARINT_MAX_2BYTE / (itemSize + 1);
100    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), two);
101    EXPECT_EQ(len, itemCount * (itemSize + 1));
102
103    itemCount++;
104    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), three);
105    EXPECT_EQ(len, itemCount * (itemSize + 1));
106
107    itemCount = VARINT_MAX_3BYTE / (itemSize + 1);
108    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), three);
109    EXPECT_EQ(len, itemCount * (itemSize + 1));
110
111    itemCount++;
112    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), four);
113    EXPECT_EQ(len, itemCount * (itemSize + 1));
114
115    itemCount = VARINT_MAX_4BYTE / (itemSize + 1);
116    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), four);
117    EXPECT_EQ(len, itemCount * (itemSize + 1));
118
119    itemCount++;
120    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), (uint32_t)0);
121    EXPECT_EQ(len, itemCount * (itemSize + 1));
122
123    itemSize = sizeof(int64_t);
124    itemCount = VARINT_MAX_1BYTE / (itemSize + two);
125    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), (uint32_t)1);
126    EXPECT_EQ(len, itemCount * (itemSize + two));
127
128    itemCount++;
129    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), two);
130    EXPECT_EQ(len, itemCount * (itemSize + two));
131
132    itemCount = VARINT_MAX_2BYTE / (itemSize + two);
133    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), two);
134    EXPECT_EQ(len, itemCount * (itemSize + two));
135
136    itemCount++;
137    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), three);
138    EXPECT_EQ(len, itemCount * (itemSize + two));
139
140    itemCount = VARINT_MAX_3BYTE / (itemSize + two);
141    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), three);
142    EXPECT_EQ(len, itemCount * (itemSize + two));
143
144    itemCount++;
145    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), four);
146    EXPECT_EQ(len, itemCount * (itemSize + two));
147
148    itemCount = VARINT_MAX_4BYTE / (itemSize + two);
149    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), four);
150    EXPECT_EQ(len, itemCount * (itemSize + two));
151
152    itemCount++;
153    EXPECT_EQ(GetPackedVarintLenSize(itemCount, itemSize, len), (uint32_t)0);
154    EXPECT_EQ(len, itemCount * (itemSize + two));
155}
156
157HWTEST_F(VarintEncodeUnittest, EncodeZigZag, TestSize.Level1)
158{
159    int8_t signed8 = 0;
160    EXPECT_EQ(EncodeZigZag(signed8), (uint8_t)0);
161    signed8 = -1;
162    EXPECT_EQ(EncodeZigZag(signed8), (uint8_t)1);
163    signed8 = 1;
164    EXPECT_EQ(EncodeZigZag(signed8), (uint8_t)(signed8 * two));
165    std::srand(std::time(nullptr));
166    int rand = std::rand();
167    signed8 = static_cast<int8_t>(rand);
168    if (signed8 >= 0) {
169        // n are encoded as 2 * n
170        EXPECT_EQ(EncodeZigZag(signed8), (uint8_t)(signed8 * two));
171    } else {
172        // -n are encoded as 2 * n + 1
173        EXPECT_EQ(EncodeZigZag(signed8), (uint8_t)(-signed8 - 1 + -signed8));
174    }
175    signed8 = std::numeric_limits<int8_t>::min();
176    EXPECT_EQ(EncodeZigZag(signed8), std::numeric_limits<uint8_t>::max());
177    signed8 = std::numeric_limits<int8_t>::max();
178    EXPECT_EQ(EncodeZigZag(signed8), std::numeric_limits<uint8_t>::max() - 1);
179
180    int32_t signed32 = 0;
181    EXPECT_EQ(EncodeZigZag(signed32), (uint32_t)0);
182    signed32 = -1;
183    EXPECT_EQ(EncodeZigZag(signed32), (uint32_t)1);
184    signed32 = 1;
185    EXPECT_EQ(EncodeZigZag(signed32), (uint32_t)(signed32 * two));
186    std::srand(rand);
187    rand = std::rand();
188    signed32 = static_cast<int32_t>(rand);
189    if (signed32 >= 0) {
190        // n are encoded as 2 * n
191        EXPECT_EQ(EncodeZigZag(signed32), (uint32_t)(signed32 * two));
192    } else {
193        // -n are encoded as 2 * n + 1
194        EXPECT_EQ(EncodeZigZag(signed32), (uint32_t)(-signed32 - 1 + -signed32));
195    }
196    signed32 = std::numeric_limits<int32_t>::min();
197    EXPECT_EQ(EncodeZigZag(signed32), std::numeric_limits<uint32_t>::max());
198    signed32 = std::numeric_limits<int32_t>::max();
199    EXPECT_EQ(EncodeZigZag(signed32), std::numeric_limits<uint32_t>::max() - 1);
200
201    int64_t signed64 = 0;
202    EXPECT_EQ(EncodeZigZag(signed64), (uint64_t)0);
203    signed64 = -1;
204    EXPECT_EQ(EncodeZigZag(signed64), (uint64_t)1);
205    signed64 = 1;
206    EXPECT_EQ(EncodeZigZag(signed64), (uint64_t)(signed64 * two));
207    std::srand(rand);
208    rand = std::rand();
209    signed64 = static_cast<int64_t>(rand);
210    if (signed64 >= 0) {
211        // n are encoded as 2 * n
212        EXPECT_EQ(EncodeZigZag(signed64), (uint64_t)(signed64 * two));
213    } else {
214        // -n are encoded as 2 * n + 1
215        EXPECT_EQ(EncodeZigZag(signed64), (uint64_t)(-signed64 - 1 + -signed64));
216    }
217    signed64 = std::numeric_limits<int64_t>::min();
218    EXPECT_EQ(EncodeZigZag(signed64), std::numeric_limits<uint64_t>::max());
219    signed64 = std::numeric_limits<int64_t>::max();
220    EXPECT_EQ(EncodeZigZag(signed64), std::numeric_limits<uint64_t>::max() - 1);
221}
222
223bool CompareBytes(const uint8_t* a, const uint8_t* b, size_t size)
224{
225    for (size_t i = 0; i < size; i++) {
226        if (a[i] != b[i]) {
227            return false;
228        }
229    }
230    return true;
231}
232
233const uint8_t ENCODE_BYTES_MIN_BOOL[] = {0x00};
234const uint8_t ENCODE_BYTES_MAX_BOOL[] = {0x01};
235const uint8_t ENCODE_BYTES_MIN_S8[] = {0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01};
236const uint8_t ENCODE_BYTES_MAX_S8[] = {0x7F};
237const uint8_t ENCODE_BYTES_MIN_U8[] = {0x00};
238const uint8_t ENCODE_BYTES_MAX_U8[] = {0xFF, 0x01};
239const uint8_t ENCODE_BYTES_MIN_S32[] = {0x80, 0x80, 0x80, 0x80, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x01};
240const uint8_t ENCODE_BYTES_MAX_S32[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x07};
241const uint8_t ENCODE_BYTES_MIN_U32[] = {0x00};
242const uint8_t ENCODE_BYTES_MAX_U32[] = {0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
243const uint8_t ENCODE_BYTES_MIN_S64[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01};
244const uint8_t ENCODE_BYTES_MAX_S64[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F};
245const uint8_t ENCODE_BYTES_MIN_U64[] = {0x00};
246const uint8_t ENCODE_BYTES_MAX_U64[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01};
247
248HWTEST_F(VarintEncodeUnittest, EncodeVarint, TestSize.Level1)
249{
250    uint8_t buf[VARINT_ENCODE_MAX_SIZE] = {0};
251    bool b = std::numeric_limits<bool>::min();
252    EXPECT_EQ(EncodeVarint(buf, b), (uint32_t)sizeof(ENCODE_BYTES_MIN_BOOL));
253    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MIN_BOOL, sizeof(ENCODE_BYTES_MIN_BOOL)));
254    b = std::numeric_limits<bool>::max();
255    EXPECT_EQ(EncodeVarint(buf, b), (uint32_t)sizeof(ENCODE_BYTES_MAX_BOOL));
256    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MAX_BOOL, sizeof(ENCODE_BYTES_MAX_BOOL)));
257
258    int8_t s8 = std::numeric_limits<int8_t>::min();
259    EXPECT_EQ(EncodeVarint(buf, s8), (uint32_t)sizeof(ENCODE_BYTES_MIN_S8));
260    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MIN_S8, sizeof(ENCODE_BYTES_MIN_S8)));
261    s8 = std::numeric_limits<int8_t>::max();
262    EXPECT_EQ(EncodeVarint(buf, s8), (uint32_t)sizeof(ENCODE_BYTES_MAX_S8));
263    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MAX_S8, sizeof(ENCODE_BYTES_MAX_S8)));
264
265    uint8_t u8 = std::numeric_limits<uint8_t>::min();
266    EXPECT_EQ(EncodeVarint(buf, u8), (uint32_t)sizeof(ENCODE_BYTES_MIN_U8));
267    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MIN_U8, sizeof(ENCODE_BYTES_MIN_U8)));
268    u8 = std::numeric_limits<uint8_t>::max();
269    EXPECT_EQ(EncodeVarint(buf, u8), (uint32_t)sizeof(ENCODE_BYTES_MAX_U8));
270    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MAX_U8, sizeof(ENCODE_BYTES_MAX_U8)));
271
272    int32_t s32 = std::numeric_limits<int32_t>::min();
273    EXPECT_EQ(EncodeVarint(buf, s32), (uint32_t)sizeof(ENCODE_BYTES_MIN_S32));
274    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MIN_S32, sizeof(ENCODE_BYTES_MIN_S32)));
275    s32 = std::numeric_limits<int32_t>::max();
276    EXPECT_EQ(EncodeVarint(buf, s32), (uint32_t)sizeof(ENCODE_BYTES_MAX_S32));
277    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MAX_S32, sizeof(ENCODE_BYTES_MAX_S32)));
278
279    uint32_t u32 = std::numeric_limits<uint32_t>::min();
280    EXPECT_EQ(EncodeVarint(buf, u32), (uint32_t)sizeof(ENCODE_BYTES_MIN_U32));
281    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MIN_U32, sizeof(ENCODE_BYTES_MIN_U32)));
282    u32 = std::numeric_limits<uint32_t>::max();
283    EXPECT_EQ(EncodeVarint(buf, u32), (uint32_t)sizeof(ENCODE_BYTES_MAX_U32));
284    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MAX_U32, sizeof(ENCODE_BYTES_MAX_U32)));
285
286    int64_t s64 = std::numeric_limits<int64_t>::min();
287    EXPECT_EQ(EncodeVarint(buf, s64), (uint32_t)sizeof(ENCODE_BYTES_MIN_S64));
288    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MIN_S64, sizeof(ENCODE_BYTES_MIN_S64)));
289    s64 = std::numeric_limits<int64_t>::max();
290    EXPECT_EQ(EncodeVarint(buf, s64), (uint32_t)sizeof(ENCODE_BYTES_MAX_S64));
291    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MAX_S64, sizeof(ENCODE_BYTES_MAX_S64)));
292
293    uint64_t u64 = std::numeric_limits<uint64_t>::min();
294    EXPECT_EQ(EncodeVarint(buf, u64), (uint32_t)sizeof(ENCODE_BYTES_MIN_U64));
295    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MIN_U64, sizeof(ENCODE_BYTES_MIN_U64)));
296    u64 = std::numeric_limits<uint64_t>::max();
297    EXPECT_EQ(EncodeVarint(buf, u64), (uint32_t)sizeof(ENCODE_BYTES_MAX_U64));
298    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MAX_U64, sizeof(ENCODE_BYTES_MAX_U64)));
299}
300
301HWTEST_F(VarintEncodeUnittest, EncodeVarintPadding, TestSize.Level1)
302{
303    const uint8_t paddingByte = 0x80;
304    uint8_t buf[VARINT_ENCODE_MAX_SIZE] = {0};
305    uint64_t u64 = 1;
306    EncodeVarintPadding(buf, u64, VARINT_ENCODE_MAX_SIZE);
307    uint32_t i = 1;
308    while (i < VARINT_ENCODE_MAX_SIZE - 1) {
309        EXPECT_EQ(buf[i++], paddingByte);
310    }
311    EXPECT_EQ(buf[i], (uint8_t)0);
312
313    u64 = std::numeric_limits<uint64_t>::max();
314    EncodeVarintPadding(buf, u64, VARINT_ENCODE_MAX_SIZE);
315    EXPECT_TRUE(CompareBytes(buf, ENCODE_BYTES_MAX_U64, sizeof(ENCODE_BYTES_MAX_U64)));
316}
317} // namespace Profiler
318} // namespace Developtools
319} // namespace OHOS
320