| Ken Chen | d27d6c9 | 2021-10-21 22:18:59 +0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2018 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include <algorithm> | 
|  | 18 | #include <cstdint> | 
|  | 19 | #include <utility> | 
|  | 20 |  | 
|  | 21 | #include <gtest/gtest.h> | 
|  | 22 |  | 
|  | 23 | #include "netdutils/MemBlock.h" | 
|  | 24 | #include "netdutils/Slice.h" | 
|  | 25 |  | 
|  | 26 | namespace android { | 
|  | 27 | namespace netdutils { | 
|  | 28 |  | 
|  | 29 | namespace { | 
|  | 30 |  | 
|  | 31 | constexpr unsigned DNS_PACKET_SIZE = 512; | 
|  | 32 | constexpr int ARBITRARY_VALUE = 0x55; | 
|  | 33 |  | 
|  | 34 | MemBlock makeArbitraryMemBlock(size_t len) { | 
|  | 35 | MemBlock result(len); | 
|  | 36 | // Do some fictional work before returning. | 
|  | 37 | for (Slice slice = result.get(); !slice.empty(); slice = drop(slice, 1)) { | 
|  | 38 | slice.base()[0] = ARBITRARY_VALUE; | 
|  | 39 | } | 
|  | 40 | return result; | 
|  | 41 | } | 
|  | 42 |  | 
|  | 43 | void checkAllZeros(Slice slice) { | 
|  | 44 | for (; !slice.empty(); slice = drop(slice, 1)) { | 
|  | 45 | EXPECT_EQ(0U, slice.base()[0]); | 
|  | 46 | } | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | void checkArbitraryMemBlock(const MemBlock& block, size_t expectedSize) { | 
|  | 50 | Slice slice = block.get(); | 
|  | 51 | EXPECT_EQ(expectedSize, slice.size()); | 
|  | 52 | EXPECT_NE(nullptr, slice.base()); | 
|  | 53 | for (; !slice.empty(); slice = drop(slice, 1)) { | 
|  | 54 | EXPECT_EQ(ARBITRARY_VALUE, slice.base()[0]); | 
|  | 55 | } | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | void checkHelloMello(Slice dest, Slice src) { | 
|  | 59 | EXPECT_EQ('h', dest.base()[0]); | 
|  | 60 | EXPECT_EQ('e', dest.base()[1]); | 
|  | 61 | EXPECT_EQ('l', dest.base()[2]); | 
|  | 62 | EXPECT_EQ('l', dest.base()[3]); | 
|  | 63 | EXPECT_EQ('o', dest.base()[4]); | 
|  | 64 |  | 
|  | 65 | src.base()[0] = 'm'; | 
|  | 66 | EXPECT_EQ('h', dest.base()[0]); | 
|  | 67 | } | 
|  | 68 |  | 
|  | 69 | }  // namespace | 
|  | 70 |  | 
|  | 71 | TEST(MemBlockTest, Empty) { | 
|  | 72 | MemBlock empty; | 
|  | 73 | EXPECT_TRUE(empty.get().empty()); | 
|  | 74 | EXPECT_EQ(nullptr, empty.get().base()); | 
|  | 75 | } | 
|  | 76 |  | 
|  | 77 | TEST(MemBlockTest, ExplicitZero) { | 
|  | 78 | MemBlock zero(0); | 
|  | 79 | EXPECT_TRUE(zero.get().empty()); | 
|  | 80 | EXPECT_EQ(nullptr, zero.get().base()); | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | TEST(MemBlockTest, BasicAllocation) { | 
|  | 84 | MemBlock dnsPacket(DNS_PACKET_SIZE); | 
|  | 85 | Slice slice = dnsPacket.get(); | 
|  | 86 | EXPECT_EQ(DNS_PACKET_SIZE, slice.size()); | 
|  | 87 | // Verify the space is '\0'-initialized. | 
|  | 88 | ASSERT_NO_FATAL_FAILURE(checkAllZeros(slice)); | 
|  | 89 | EXPECT_NE(nullptr, slice.base()); | 
|  | 90 | } | 
|  | 91 |  | 
|  | 92 | TEST(MemBlockTest, MoveConstruction) { | 
|  | 93 | MemBlock block(makeArbitraryMemBlock(DNS_PACKET_SIZE)); | 
|  | 94 | ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE)); | 
|  | 95 | } | 
|  | 96 |  | 
|  | 97 | TEST(MemBlockTest, MoveAssignmentOrConstruction) { | 
|  | 98 | MemBlock block = makeArbitraryMemBlock(DNS_PACKET_SIZE); | 
|  | 99 | ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE)); | 
|  | 100 | } | 
|  | 101 |  | 
|  | 102 | TEST(MemBlockTest, StdMoveAssignment) { | 
|  | 103 | constexpr unsigned SIZE = 10; | 
|  | 104 |  | 
|  | 105 | MemBlock block; | 
|  | 106 | EXPECT_TRUE(block.get().empty()); | 
|  | 107 | EXPECT_EQ(nullptr, block.get().base()); | 
|  | 108 |  | 
|  | 109 | { | 
|  | 110 | MemBlock block2 = makeArbitraryMemBlock(SIZE); | 
|  | 111 | EXPECT_EQ(SIZE, block2.get().size()); | 
|  | 112 | // More fictional work. | 
|  | 113 | for (unsigned i = 0; i < SIZE; i++) { | 
|  | 114 | block2.get().base()[i] = i; | 
|  | 115 | } | 
|  | 116 | block = std::move(block2); | 
|  | 117 | } | 
|  | 118 |  | 
|  | 119 | EXPECT_EQ(SIZE, block.get().size()); | 
|  | 120 | for (unsigned i = 0; i < SIZE; i++) { | 
|  | 121 | EXPECT_EQ(i, block.get().base()[i]); | 
|  | 122 | } | 
|  | 123 | } | 
|  | 124 |  | 
|  | 125 | TEST(MemBlockTest, ConstructionFromSlice) { | 
|  | 126 | uint8_t data[] = {'h', 'e', 'l', 'l', 'o'}; | 
|  | 127 | Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0]))); | 
|  | 128 |  | 
|  | 129 | MemBlock dataCopy(dataSlice); | 
|  | 130 | ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy.get(), dataSlice)); | 
|  | 131 | } | 
|  | 132 |  | 
|  | 133 | TEST(MemBlockTest, ImplicitCastToSlice) { | 
|  | 134 | uint8_t data[] = {'h', 'e', 'l', 'l', 'o'}; | 
|  | 135 | Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0]))); | 
|  | 136 |  | 
|  | 137 | MemBlock dataCopy(dataSlice.size()); | 
|  | 138 | // NOTE: no explicit MemBlock::get(). | 
|  | 139 | // Verify the space is '\0'-initialized. | 
|  | 140 | ASSERT_NO_FATAL_FAILURE(checkAllZeros(dataCopy)); | 
|  | 141 | copy(dataCopy, dataSlice); | 
|  | 142 | ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy, dataSlice)); | 
|  | 143 | } | 
|  | 144 |  | 
|  | 145 | }  // namespace netdutils | 
|  | 146 | }  // namespace android |