/* * Copyright (c) 2021-2022 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #define ALLOCATION_CHECKS #include #undef ALLOCATION_CHECKS #include #include namespace transport { namespace core { class PacketAllocatorTest : public ::testing::Test { protected: static inline const std::size_t default_size = 2048; static inline const std::size_t default_n_buffer = 1024; static inline const std::size_t counter = 1024; static inline const std::size_t total_packets = 1024 * counter; // Get fixed block allocator_ of 1024 buffers of size 2048 bytes PacketAllocatorTest() : allocator_(PacketManager<>::getInstance()) { // You can do set-up work for each test here. } virtual ~PacketAllocatorTest() { // You can do clean-up work that doesn't throw exceptions here. } // If the constructor and destructor are not enough for setting up // and cleaning up each test, you can define the following methods: virtual void SetUp() {} virtual void TearDown() {} static bool pointerIsAligned(const void *pointer, size_t byte_count) { return uintptr_t(pointer) % byte_count == 0; } template void allocationTest(Args &&...args) { // Create packet auto packet = allocator_.getPacket(std::forward(args)...); // Check boundaries LOG(INFO) << "packet size: " << sizeof(*packet) + sizeof(packet) << std::endl; EXPECT_LE(sizeof(*packet) + sizeof(packet) + sizeof(std::max_align_t), sizeof(PacketManager<>::PacketStorage::packet_and_shared_ptr)); } PacketManager<> &allocator_; }; TEST_F(PacketAllocatorTest, ContentObjectAllocation) { allocationTest(HICN_PACKET_FORMAT_IPV4_TCP); } TEST_F(PacketAllocatorTest, InterestAllocation) { allocationTest(HICN_PACKET_FORMAT_IPV4_TCP); } // TEST_F(PacketAllocatorTest, MemBufAllocation) { // allocationTest<::utils::MemBuf>(); // } TEST_F(PacketAllocatorTest, CheckAllocationIsCorrect) { // Create packet auto packet = allocator_.getPacket(HICN_PACKET_FORMAT_IPV4_TCP); // Address of actual buffer uint8_t *buffer_address = packet->writableData(); // Address of packet uint8_t *packet_address = reinterpret_cast(packet.get()); uint8_t *start_address = buffer_address - sizeof(PacketManager<>::PacketStorage::packet_and_shared_ptr); // Check memory was allocated on correct positions EXPECT_TRUE(pointerIsAligned(start_address, alignof(std::max_align_t))); EXPECT_TRUE(packet_address > start_address && packet_address < buffer_address); EXPECT_TRUE(pointerIsAligned(buffer_address, alignof(std::max_align_t))); EXPECT_THAT(std::size_t(buffer_address - start_address), testing::Eq(sizeof( PacketManager<>::PacketStorage::packet_and_shared_ptr))); } TEST_F(PacketAllocatorTest, CheckAllocationSpeed) { // Check time needed to allocate 1 million packeauto &packet_manager = auto &packet_manager = core::PacketManager<>::getInstance(); // Send 1 million packets std::array packets; auto t0 = utils::SteadyTime::now(); std::size_t sum = 0; for (std::size_t j = 0; j < counter; j++) { for (std::size_t i = 0; i < counter; i++) { packets[i] = packet_manager.getMemBuf(); sum++; } } auto t1 = utils::SteadyTime::now(); auto delta = utils::SteadyTime::getDurationUs(t0, t1); auto rate = double(sum) * 1000000.0 / double(delta.count()); LOG(INFO) << "rate: " << rate << " packets/s"; } } // namespace core } // namespace transport