• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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