| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * 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 <algorithm> |
| #include <cstdint> |
| #include <utility> |
| |
| #include <gtest/gtest.h> |
| |
| #include "netdutils/MemBlock.h" |
| #include "netdutils/Slice.h" |
| |
| namespace android { |
| namespace netdutils { |
| |
| namespace { |
| |
| constexpr unsigned DNS_PACKET_SIZE = 512; |
| constexpr int ARBITRARY_VALUE = 0x55; |
| |
| MemBlock makeArbitraryMemBlock(size_t len) { |
| MemBlock result(len); |
| // Do some fictional work before returning. |
| for (Slice slice = result.get(); !slice.empty(); slice = drop(slice, 1)) { |
| slice.base()[0] = ARBITRARY_VALUE; |
| } |
| return result; |
| } |
| |
| void checkAllZeros(Slice slice) { |
| for (; !slice.empty(); slice = drop(slice, 1)) { |
| EXPECT_EQ(0U, slice.base()[0]); |
| } |
| } |
| |
| void checkArbitraryMemBlock(const MemBlock& block, size_t expectedSize) { |
| Slice slice = block.get(); |
| EXPECT_EQ(expectedSize, slice.size()); |
| EXPECT_NE(nullptr, slice.base()); |
| for (; !slice.empty(); slice = drop(slice, 1)) { |
| EXPECT_EQ(ARBITRARY_VALUE, slice.base()[0]); |
| } |
| } |
| |
| void checkHelloMello(Slice dest, Slice src) { |
| EXPECT_EQ('h', dest.base()[0]); |
| EXPECT_EQ('e', dest.base()[1]); |
| EXPECT_EQ('l', dest.base()[2]); |
| EXPECT_EQ('l', dest.base()[3]); |
| EXPECT_EQ('o', dest.base()[4]); |
| |
| src.base()[0] = 'm'; |
| EXPECT_EQ('h', dest.base()[0]); |
| } |
| |
| } // namespace |
| |
| TEST(MemBlockTest, Empty) { |
| MemBlock empty; |
| EXPECT_TRUE(empty.get().empty()); |
| EXPECT_EQ(nullptr, empty.get().base()); |
| } |
| |
| TEST(MemBlockTest, ExplicitZero) { |
| MemBlock zero(0); |
| EXPECT_TRUE(zero.get().empty()); |
| EXPECT_EQ(nullptr, zero.get().base()); |
| } |
| |
| TEST(MemBlockTest, BasicAllocation) { |
| MemBlock dnsPacket(DNS_PACKET_SIZE); |
| Slice slice = dnsPacket.get(); |
| EXPECT_EQ(DNS_PACKET_SIZE, slice.size()); |
| // Verify the space is '\0'-initialized. |
| ASSERT_NO_FATAL_FAILURE(checkAllZeros(slice)); |
| EXPECT_NE(nullptr, slice.base()); |
| } |
| |
| TEST(MemBlockTest, MoveConstruction) { |
| MemBlock block(makeArbitraryMemBlock(DNS_PACKET_SIZE)); |
| ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE)); |
| } |
| |
| TEST(MemBlockTest, MoveAssignmentOrConstruction) { |
| MemBlock block = makeArbitraryMemBlock(DNS_PACKET_SIZE); |
| ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE)); |
| } |
| |
| TEST(MemBlockTest, StdMoveAssignment) { |
| constexpr unsigned SIZE = 10; |
| |
| MemBlock block; |
| EXPECT_TRUE(block.get().empty()); |
| EXPECT_EQ(nullptr, block.get().base()); |
| |
| { |
| MemBlock block2 = makeArbitraryMemBlock(SIZE); |
| EXPECT_EQ(SIZE, block2.get().size()); |
| // More fictional work. |
| for (unsigned i = 0; i < SIZE; i++) { |
| block2.get().base()[i] = i; |
| } |
| block = std::move(block2); |
| } |
| |
| EXPECT_EQ(SIZE, block.get().size()); |
| for (unsigned i = 0; i < SIZE; i++) { |
| EXPECT_EQ(i, block.get().base()[i]); |
| } |
| } |
| |
| TEST(MemBlockTest, ConstructionFromSlice) { |
| uint8_t data[] = {'h', 'e', 'l', 'l', 'o'}; |
| Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0]))); |
| |
| MemBlock dataCopy(dataSlice); |
| ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy.get(), dataSlice)); |
| } |
| |
| TEST(MemBlockTest, ImplicitCastToSlice) { |
| uint8_t data[] = {'h', 'e', 'l', 'l', 'o'}; |
| Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0]))); |
| |
| MemBlock dataCopy(dataSlice.size()); |
| // NOTE: no explicit MemBlock::get(). |
| // Verify the space is '\0'-initialized. |
| ASSERT_NO_FATAL_FAILURE(checkAllZeros(dataCopy)); |
| copy(dataCopy, dataSlice); |
| ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy, dataSlice)); |
| } |
| |
| } // namespace netdutils |
| } // namespace android |