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
makeArbitraryMemBlock(size_t len)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
checkAllZeros(Slice slice)43 void checkAllZeros(Slice slice) {
44 for (; !slice.empty(); slice = drop(slice, 1)) {
45 EXPECT_EQ(0U, slice.base()[0]);
46 }
47 }
48
checkArbitraryMemBlock(const MemBlock & block,size_t expectedSize)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
checkHelloMello(Slice dest,Slice src)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
TEST(MemBlockTest,Empty)71 TEST(MemBlockTest, Empty) {
72 MemBlock empty;
73 EXPECT_TRUE(empty.get().empty());
74 EXPECT_EQ(nullptr, empty.get().base());
75 }
76
TEST(MemBlockTest,ExplicitZero)77 TEST(MemBlockTest, ExplicitZero) {
78 MemBlock zero(0);
79 EXPECT_TRUE(zero.get().empty());
80 EXPECT_EQ(nullptr, zero.get().base());
81 }
82
TEST(MemBlockTest,BasicAllocation)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
TEST(MemBlockTest,MoveConstruction)92 TEST(MemBlockTest, MoveConstruction) {
93 MemBlock block(makeArbitraryMemBlock(DNS_PACKET_SIZE));
94 ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE));
95 }
96
TEST(MemBlockTest,MoveAssignmentOrConstruction)97 TEST(MemBlockTest, MoveAssignmentOrConstruction) {
98 MemBlock block = makeArbitraryMemBlock(DNS_PACKET_SIZE);
99 ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE));
100 }
101
TEST(MemBlockTest,StdMoveAssignment)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
TEST(MemBlockTest,ConstructionFromSlice)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
TEST(MemBlockTest,ImplicitCastToSlice)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
147