1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2022. 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
16 #include <fcntl.h>
17 #include <cmath>
18 #include <cstdio>
19 #include <string>
20 #include <vector>
21
22 #include <gtest/gtest.h>
23
24 #include "ringbuffer.h"
25
26 using namespace testing::ext;
27
28 namespace {
29 constexpr int32_t BUFFER_SIZE = 1 * 1024 * 1024;
30 const std::string READ_FILE_NAME = "/data/local/tmp/hiebpfreadtest.txt";
31 const std::string WRITE_FILE_NAME = "/data/local/tmp/hiebpfwritetest.txt";
32 constexpr int FILE_MODE = 0777;
33 } // namespace
34
35 namespace OHOS {
36 namespace Developtools {
37 namespace Hiebpf {
38 class RingbufferTest : public ::testing::Test {
39 public:
SetUpTestCase()40 static void SetUpTestCase() {};
TearDownTestCase()41 static void TearDownTestCase()
42 {
43 if (access(READ_FILE_NAME.c_str(), F_OK) == 0) {
44 std::string cmd = "rm " + READ_FILE_NAME;
45 system(cmd.c_str());
46 }
47 if (access(WRITE_FILE_NAME.c_str(), F_OK) == 0) {
48 std::string cmd = "rm " + WRITE_FILE_NAME;
49 system(cmd.c_str());
50 }
51 }
52
SetUp()53 void SetUp() {}
TearDown()54 void TearDown() {}
55 };
56
57 /**
58 * @tc.name: RingbufferByte
59 * @tc.desc: Test Ringbuffer DEFAULT
60 * @tc.type: FUNC
61 */
HWTEST_F(RingbufferTest, RingbufferDefault, TestSize.Level1)62 HWTEST_F(RingbufferTest, RingbufferDefault, TestSize.Level1)
63 {
64 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::B_ALIGN_SHIFT};
65 auto ringBuffer = std::make_unique<RingBuffer>(0, memAlign);
66 ASSERT_TRUE(ringBuffer != nullptr);
67 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
68 ASSERT_EQ(ringBuffer->bufSize_, RingBuffer::BufferSize::DEFAULT_SIZE);
69 }
70
71 /**
72 * @tc.name: RingbufferByte
73 * @tc.desc: Test Ringbuffer B_ALIGN_SHIFT
74 * @tc.type: FUNC
75 */
HWTEST_F(RingbufferTest, RingbufferByte, TestSize.Level1)76 HWTEST_F(RingbufferTest, RingbufferByte, TestSize.Level1)
77 {
78 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::B_ALIGN_SHIFT};
79 auto ringBuffer = std::make_unique<RingBuffer>(BUFFER_SIZE, memAlign);
80 ASSERT_TRUE(ringBuffer != nullptr);
81 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
82 EXPECT_EQ(ringBuffer->bufSize_, BUFFER_SIZE);
83
84 const size_t size = 263; // 100000111
85 ringBuffer = std::make_unique<RingBuffer>(size, memAlign);
86 ASSERT_TRUE(ringBuffer != nullptr);
87 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
88 EXPECT_EQ(ringBuffer->bufSize_, size);
89 }
90
91 /**
92 * @tc.name: RingbufferHalfWord
93 * @tc.desc: Test Ringbuffer H_ALIGN_SHIFT
94 * @tc.type: FUNC
95 */
HWTEST_F(RingbufferTest, RingbufferHalfWord, TestSize.Level1)96 HWTEST_F(RingbufferTest, RingbufferHalfWord, TestSize.Level1)
97 {
98 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::H_ALIGN_SHIFT};
99 auto ringBuffer = std::make_unique<RingBuffer>(BUFFER_SIZE, memAlign);
100 ASSERT_TRUE(ringBuffer != nullptr);
101 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
102 EXPECT_EQ(ringBuffer->bufSize_, BUFFER_SIZE);
103
104 const size_t size = 263; // 100000111
105 const int bit = RingBuffer::MemAlignShift::H_ALIGN_SHIFT;
106 const size_t expectSize = (pow(2, bit)) * (size >> bit); // 2*131(10000011)
107 ringBuffer = std::make_unique<RingBuffer>(size, memAlign);
108 ASSERT_TRUE(ringBuffer != nullptr);
109 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
110 EXPECT_EQ(ringBuffer->bufSize_, expectSize);
111 }
112
113 /**
114 * @tc.name: RingbufferWord
115 * @tc.desc: Test Ringbuffer W_ALIGN_SHIFT
116 * @tc.type: FUNC
117 */
HWTEST_F(RingbufferTest, RingbufferWord, TestSize.Level1)118 HWTEST_F(RingbufferTest, RingbufferWord, TestSize.Level1)
119 {
120 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::W_ALIGN_SHIFT};
121 auto ringBuffer = std::make_unique<RingBuffer>(BUFFER_SIZE, memAlign);
122 ASSERT_TRUE(ringBuffer != nullptr);
123 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
124 EXPECT_EQ(ringBuffer->bufSize_, BUFFER_SIZE);
125
126 const size_t size = 263; // 100000111
127 const int bit = RingBuffer::MemAlignShift::W_ALIGN_SHIFT;
128 const size_t expectSize = (pow(2, bit)) * (size >> bit); // 4*65(10000011)
129 ringBuffer = std::make_unique<RingBuffer>(size, memAlign);
130 ASSERT_TRUE(ringBuffer != nullptr);
131 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
132 EXPECT_EQ(ringBuffer->bufSize_, expectSize);
133 }
134
135 /**
136 * @tc.name: RingbufferDoubleWord
137 * @tc.desc: Test Ringbuffer D_ALIGN_SHIFT
138 * @tc.type: FUNC
139 */
HWTEST_F(RingbufferTest, RingbufferDoubleWord, TestSize.Level1)140 HWTEST_F(RingbufferTest, RingbufferDoubleWord, TestSize.Level1)
141 {
142 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::D_ALIGN_SHIFT};
143 auto ringBuffer = std::make_unique<RingBuffer>(BUFFER_SIZE, memAlign);
144 ASSERT_TRUE(ringBuffer != nullptr);
145 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
146 EXPECT_EQ(ringBuffer->bufSize_, BUFFER_SIZE);
147
148 const size_t size = 263; // 100000111
149 const int bit = RingBuffer::MemAlignShift::D_ALIGN_SHIFT;
150 const size_t expectSize = (pow(2, bit)) * (size >> bit); // 8*32(1000001)
151 ringBuffer = std::make_unique<RingBuffer>(size, memAlign);
152 ASSERT_TRUE(ringBuffer != nullptr);
153 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
154 EXPECT_EQ(ringBuffer->bufSize_, expectSize);
155 }
156
157 /**
158 * @tc.name: Capacity
159 * @tc.desc: Test Ringbuffer Capacity
160 * @tc.type: FUNC
161 */
HWTEST_F(RingbufferTest, Capacity, TestSize.Level1)162 HWTEST_F(RingbufferTest, Capacity, TestSize.Level1)
163 {
164 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::B_ALIGN_SHIFT};
165 auto ringBuffer = std::make_unique<RingBuffer>(BUFFER_SIZE, memAlign);
166 ASSERT_TRUE(ringBuffer != nullptr);
167 EXPECT_EQ(ringBuffer->Capacity(), BUFFER_SIZE);
168 }
169
170 /**
171 * @tc.name: ReadAndWrite
172 * @tc.desc: Test Ringbuffer Read and Write
173 * @tc.type: FUNC
174 */
HWTEST_F(RingbufferTest, ReadAndWrite, TestSize.Level1)175 HWTEST_F(RingbufferTest, ReadAndWrite, TestSize.Level1)
176 {
177 int readFd = open(READ_FILE_NAME.c_str(), O_CREAT | O_RDWR, FILE_MODE);
178 ASSERT_GT(readFd, 0);
179 std::string testStr = "this is hiebpf test file";
180 for (int i = testStr.size(); i < RingBuffer::BufferSize::DEFAULT_SIZE - 1; i++) {
181 testStr += "1";
182 }
183 int bytes = write(readFd, testStr.data(), testStr.size());
184 EXPECT_EQ(bytes, testStr.size());
185 close(readFd);
186
187 readFd = open(READ_FILE_NAME.c_str(), O_CREAT | O_RDWR, FILE_MODE);
188 ASSERT_GT(readFd, 0);
189 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::B_ALIGN_SHIFT};
190 auto ringBuffer = std::make_unique<RingBuffer>(1, memAlign);
191 ASSERT_TRUE(ringBuffer != nullptr);
192 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
193 EXPECT_EQ(ringBuffer->bufSize_, RingBuffer::BufferSize::DEFAULT_SIZE);
194
195 size_t ret = ringBuffer->Read(-1, 1);
196 EXPECT_EQ(ret, -1);
197 ret = ringBuffer->Read(readFd, 0);
198 EXPECT_EQ(ret, 0);
199 const int expectBytes = 20;
200 auto len = ringBuffer->Read(readFd, expectBytes);
201 EXPECT_EQ(len, expectBytes);
202 close(readFd);
203
204 int writeFd = open(WRITE_FILE_NAME.c_str(), O_CREAT | O_RDWR, FILE_MODE);
205 ASSERT_GT(writeFd, 0);
206
207 ret = ringBuffer->Write(-1, 1);
208 EXPECT_EQ(ret, -1);
209 ret = ringBuffer->Write(writeFd, len);
210 EXPECT_EQ(ret, len);
211 close(writeFd);
212
213 // The data length is greater than the buffer size, need to splitte read.
214 readFd = open(READ_FILE_NAME.c_str(), O_CREAT | O_RDWR, FILE_MODE);
215 ASSERT_GT(readFd, 0);
216 len = ringBuffer->Read(readFd, bytes);
217 EXPECT_EQ(len, bytes);
218 close(readFd);
219
220 writeFd = open(WRITE_FILE_NAME.c_str(), O_CREAT | O_RDWR, FILE_MODE);
221 ASSERT_GT(writeFd, 0);
222 ret = ringBuffer->Write(writeFd, len);
223 EXPECT_EQ(ret, len);
224 close(writeFd);
225 }
226
227 /**
228 * @tc.name: PutAndWriteChar
229 * @tc.desc: Test Ringbuffer Put and Write(char)
230 * @tc.type: FUNC
231 */
HWTEST_F(RingbufferTest, PutAndWriteChar, TestSize.Level1)232 HWTEST_F(RingbufferTest, PutAndWriteChar, TestSize.Level1)
233 {
234 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::B_ALIGN_SHIFT};
235 auto ringBuffer = std::make_unique<RingBuffer>(1, memAlign);
236 ASSERT_TRUE(ringBuffer != nullptr);
237 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
238 EXPECT_EQ(ringBuffer->bufSize_, RingBuffer::BufferSize::DEFAULT_SIZE);
239
240 std::string testStr = "this is hiebpf test file";
241 size_t ret = ringBuffer->Put(nullptr, 1);
242 EXPECT_EQ(ret, -1);
243 ret = ringBuffer->Put(testStr.c_str(), 0);
244 EXPECT_EQ(ret, 0);
245 auto len = ringBuffer->Put(testStr.c_str(), testStr.size());
246 EXPECT_EQ(len, testStr.size());
247 EXPECT_EQ(ringBuffer->tail_, testStr.size());
248
249 int writeFd = open(WRITE_FILE_NAME.c_str(), O_CREAT | O_RDWR, FILE_MODE);
250 ASSERT_GT(writeFd, 0);
251
252 ret = ringBuffer->Write(-1, 1);
253 EXPECT_EQ(ret, -1);
254 ret = ringBuffer->Write(writeFd, len);
255 EXPECT_EQ(ret, len);
256 close(writeFd);
257 }
258
259 /**
260 * @tc.name: PutAndWriteStr
261 * @tc.desc: Test Ringbuffer Put and Write(str)
262 * @tc.type: FUNC
263 */
HWTEST_F(RingbufferTest, PutAndWriteStr, TestSize.Level1)264 HWTEST_F(RingbufferTest, PutAndWriteStr, TestSize.Level1)
265 {
266 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::B_ALIGN_SHIFT};
267 auto ringBuffer = std::make_unique<RingBuffer>(0, memAlign);
268 ASSERT_TRUE(ringBuffer != nullptr);
269 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
270 EXPECT_EQ(ringBuffer->bufSize_, RingBuffer::BufferSize::DEFAULT_SIZE);
271
272 size_t ret = ringBuffer->Put("");
273 EXPECT_EQ(ret, -1);
274 ret = ringBuffer->Put("\0");
275 EXPECT_EQ(ret, -1);
276 std::string testStr = "this is hiebpf test file";
277 auto len = ringBuffer->Put(testStr);
278 EXPECT_EQ(len, testStr.size());
279
280 int writeFd = open(WRITE_FILE_NAME.c_str(), O_CREAT | O_RDWR, FILE_MODE);
281 ASSERT_GT(writeFd, 0);
282
283 ret = ringBuffer->Write(-1, 1);
284 EXPECT_EQ(ret, -1);
285 ret = ringBuffer->Write(writeFd, len);
286 EXPECT_EQ(ret, len);
287 close(writeFd);
288 }
289
290 /**
291 * @tc.name: PutAndGetStr
292 * @tc.desc: Test Ringbuffer Put and Get(str)
293 * @tc.type: FUNC
294 */
HWTEST_F(RingbufferTest, PutAndGetStr, TestSize.Level1)295 HWTEST_F(RingbufferTest, PutAndGetStr, TestSize.Level1)
296 {
297 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::B_ALIGN_SHIFT};
298 auto ringBuffer = std::make_unique<RingBuffer>(0, memAlign);
299 ASSERT_TRUE(ringBuffer != nullptr);
300 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
301 EXPECT_EQ(ringBuffer->bufSize_, RingBuffer::BufferSize::DEFAULT_SIZE);
302
303 std::string testStr = "this is hiebpf test file";
304 auto len = ringBuffer->Put(testStr);
305 EXPECT_EQ(len, testStr.size());
306
307 std::vector<char> buff;
308 buff.resize(testStr.size() + 1);
309 len = ringBuffer->Get(nullptr, 1);
310 EXPECT_EQ(len, 0);
311 len = ringBuffer->Get(buff.data(), 0);
312 EXPECT_EQ(len, 0);
313 len = ringBuffer->Get(buff.data(), RingBuffer::BufferSize::DEFAULT_SIZE + 1);
314 EXPECT_EQ(len, 0);
315 len = ringBuffer->Get(buff.data(), testStr.size());
316 EXPECT_EQ(len, testStr.size());
317
318 // need to splitte data
319 for (int i = testStr.size() + 1; i < RingBuffer::BufferSize::DEFAULT_SIZE; i++) {
320 testStr += "1";
321 }
322 len = ringBuffer->Put(testStr);
323 EXPECT_EQ(len, testStr.size());
324 buff.resize(testStr.size() + 1);
325 len = ringBuffer->Get(buff.data(), testStr.size());
326 EXPECT_EQ(len, testStr.size());
327
328 // The data length is greater than the buffer size, need to resize.
329 testStr += "11111111";
330 len = ringBuffer->Put(testStr);
331 EXPECT_EQ(len, testStr.size());
332 buff.resize(testStr.size() + 1);
333 len = ringBuffer->Get(buff.data(), testStr.size());
334 EXPECT_EQ(len, testStr.size());
335 }
336
337 /**
338 * @tc.name: Allocate
339 * @tc.desc: Test Ringbuffer Allocate
340 * @tc.type: FUNC
341 */
HWTEST_F(RingbufferTest, Allocate, TestSize.Level1)342 HWTEST_F(RingbufferTest, Allocate, TestSize.Level1)
343 {
344 auto ringBuffer = std::make_unique<RingBuffer>(BUFFER_SIZE, RingBuffer::MemAlignShift::B_ALIGN_SHIFT);
345 ASSERT_TRUE(ringBuffer != nullptr);
346 EXPECT_EQ(ringBuffer->bufSize_, BUFFER_SIZE);
347 auto newBuffer = ringBuffer->Allocate(1);
348 ASSERT_TRUE(newBuffer != nullptr);
349
350 ringBuffer = std::make_unique<RingBuffer>(BUFFER_SIZE, RingBuffer::MemAlignShift::H_ALIGN_SHIFT);
351 ASSERT_TRUE(ringBuffer != nullptr);
352 EXPECT_EQ(ringBuffer->bufSize_, BUFFER_SIZE);
353 newBuffer = ringBuffer->Allocate(1);
354 ASSERT_TRUE(newBuffer != nullptr);
355
356 ringBuffer = std::make_unique<RingBuffer>(BUFFER_SIZE, RingBuffer::MemAlignShift::W_ALIGN_SHIFT);
357 ASSERT_TRUE(ringBuffer != nullptr);
358 EXPECT_EQ(ringBuffer->bufSize_, BUFFER_SIZE);
359 newBuffer = ringBuffer->Allocate(1);
360 ASSERT_TRUE(newBuffer != nullptr);
361
362 ringBuffer = std::make_unique<RingBuffer>(BUFFER_SIZE, RingBuffer::MemAlignShift::D_ALIGN_SHIFT);
363 ASSERT_TRUE(ringBuffer != nullptr);
364 EXPECT_EQ(ringBuffer->bufSize_, BUFFER_SIZE);
365 newBuffer = ringBuffer->Allocate(1);
366 ASSERT_TRUE(newBuffer != nullptr);
367 }
368
369 /**
370 * @tc.name: Peek
371 * @tc.desc: Test Ringbuffer Peek
372 * @tc.type: FUNC
373 */
HWTEST_F(RingbufferTest, Peek, TestSize.Level1)374 HWTEST_F(RingbufferTest, Peek, TestSize.Level1)
375 {
376 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::B_ALIGN_SHIFT};
377 auto ringBuffer = std::make_unique<RingBuffer>(1, memAlign);
378 ASSERT_TRUE(ringBuffer != nullptr);
379 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
380
381 uint32_t expectNum = 0;
382 auto ret = ringBuffer->Peek(&expectNum); // ringBuffer no data
383 EXPECT_EQ(ret, -1);
384
385 uint32_t num = 4294967295;
386 char* ptr = reinterpret_cast<char *>(&num);
387 auto len = ringBuffer->Put(ptr, sizeof(ptr));
388 EXPECT_EQ(len, sizeof(ptr));
389
390 ret = ringBuffer->Peek(&expectNum);
391 EXPECT_EQ(ret, 0);
392 EXPECT_EQ(num, expectNum);
393
394 // need to splitte data
395 for (int i = sizeof(ptr) + 1; i < RingBuffer::BufferSize::DEFAULT_SIZE - 1; i++) {
396 len = ringBuffer->Put("2", 1);
397 EXPECT_EQ(len, 1);
398 }
399 len = ringBuffer->Put("3");
400 EXPECT_EQ(len, 1);
401 const int size = RingBuffer::BufferSize::DEFAULT_SIZE - 1;
402 char buff[size + 1] = {0};
403 ret = ringBuffer->Get(buff, size);
404 EXPECT_STRNE(buff, "");
405 EXPECT_EQ(ret, size);
406 len = ringBuffer->Put(ptr, sizeof(ptr));
407 EXPECT_EQ(len, sizeof(ptr));
408
409 expectNum = 0;
410 ret = ringBuffer->Peek(&expectNum);
411 EXPECT_EQ(ret, 0);
412 EXPECT_EQ(num, expectNum);
413 }
414
415 /**
416 * @tc.name: Resize
417 * @tc.desc: Test Ringbuffer Resize
418 * @tc.type: FUNC
419 */
HWTEST_F(RingbufferTest, Resize, TestSize.Level1)420 HWTEST_F(RingbufferTest, Resize, TestSize.Level1)
421 {
422 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::B_ALIGN_SHIFT};
423 auto ringBuffer = std::make_unique<RingBuffer>(1, memAlign);
424 ASSERT_TRUE(ringBuffer != nullptr);
425 ASSERT_TRUE(ringBuffer->buffer_ != nullptr);
426 ASSERT_EQ(ringBuffer->bufSize_, RingBuffer::BufferSize::DEFAULT_SIZE);
427
428 auto oldSize = ringBuffer->bufSize_;
429 auto ret = ringBuffer->Resize();
430 EXPECT_EQ(ret, 0);
431 ASSERT_EQ(ringBuffer->bufSize_, oldSize << 1);
432
433 // data splitted
434 std::string putStr = "";
435 std::string testStr = "222222";
436 std::string destStr = "this is hiebpf test file";
437 const int size = destStr.length();
438 ret = ringBuffer->Put(destStr);
439 EXPECT_EQ(ret, size);
440 while (putStr.size() < (ringBuffer->bufSize_ - size - 1)) {
441 putStr += "1";
442 }
443 ret = ringBuffer->Put(putStr.c_str());
444 EXPECT_EQ(ret, putStr.size());
445 char buff[size + 1];
446 memset_s(buff, sizeof(buff), 0, sizeof(buff));
447 ret = ringBuffer->Get(buff, size);
448 EXPECT_EQ(ret, size);
449 EXPECT_STREQ(buff, destStr.c_str());
450 ret = ringBuffer->Put(testStr);
451 EXPECT_EQ(ret, testStr.size());
452
453 oldSize = ringBuffer->bufSize_;
454 ret = ringBuffer->Resize();
455 EXPECT_EQ(ret, 0);
456 ASSERT_EQ(ringBuffer->bufSize_, oldSize << 1);
457 }
458 } // namespace Hiebpf
459 } // namespace Developtools
460 } // namespace OHOS
461