• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 <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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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