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