10198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline/*
20198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline * Copyright (C) 2018 The Android Open Source Project
30198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline *
40198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline * Licensed under the Apache License, Version 2.0 (the "License");
50198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline * you may not use this file except in compliance with the License.
60198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline * You may obtain a copy of the License at
70198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline *
80198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline *      http://www.apache.org/licenses/LICENSE-2.0
90198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline *
100198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline * Unless required by applicable law or agreed to in writing, software
110198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline * distributed under the License is distributed on an "AS IS" BASIS,
120198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline * See the License for the specific language governing permissions and
140198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline * limitations under the License.
150198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline */
160198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
170198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline#include <algorithm>
180198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline#include <cstdint>
190198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline#include <utility>
200198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
210198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline#include <gtest/gtest.h>
220198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
230198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline#include "netdutils/MemBlock.h"
240198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline#include "netdutils/Slice.h"
250198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
260198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Klinenamespace android {
270198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Klinenamespace netdutils {
280198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
290198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Klinenamespace {
300198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
31ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Klineconstexpr unsigned DNS_PACKET_SIZE = 512;
320198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Klineconstexpr int ARBITRARY_VALUE = 0x55;
330198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
340198ef5cd67b74a4e67a485a03c1c12c815aa32bErik KlineMemBlock makeArbitraryMemBlock(size_t len) {
350198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    MemBlock result(len);
360198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    // Do some fictional work before returning.
37ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Kline    for (Slice slice = result.get(); !slice.empty(); slice = drop(slice, 1)) {
38ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Kline        slice.base()[0] = ARBITRARY_VALUE;
390198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    }
400198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    return result;
410198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
420198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
430198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Klinevoid checkAllZeros(Slice slice) {
44ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Kline    for (; !slice.empty(); slice = drop(slice, 1)) {
45ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Kline        EXPECT_EQ(0U, slice.base()[0]);
460198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    }
470198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
480198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
490198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Klinevoid checkArbitraryMemBlock(const MemBlock& block, size_t expectedSize) {
500198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    Slice slice = block.get();
510198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ(expectedSize, slice.size());
520198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_NE(nullptr, slice.base());
53ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Kline    for (; !slice.empty(); slice = drop(slice, 1)) {
54ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Kline        EXPECT_EQ(ARBITRARY_VALUE, slice.base()[0]);
550198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    }
560198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
570198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
580198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Klinevoid checkHelloMello(Slice dest, Slice src) {
590198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ('h', dest.base()[0]);
600198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ('e', dest.base()[1]);
610198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ('l', dest.base()[2]);
620198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ('l', dest.base()[3]);
630198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ('o', dest.base()[4]);
640198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
650198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    src.base()[0] = 'm';
660198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ('h', dest.base()[0]);
670198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
680198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
690198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}  // namespace
700198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
710198ef5cd67b74a4e67a485a03c1c12c815aa32bErik KlineTEST(MemBlockTest, Empty) {
720198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    MemBlock empty;
730198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_TRUE(empty.get().empty());
740198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ(nullptr, empty.get().base());
750198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
760198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
770198ef5cd67b74a4e67a485a03c1c12c815aa32bErik KlineTEST(MemBlockTest, ExplicitZero) {
780198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    MemBlock zero(0);
790198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_TRUE(zero.get().empty());
800198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ(nullptr, zero.get().base());
810198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
820198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
830198ef5cd67b74a4e67a485a03c1c12c815aa32bErik KlineTEST(MemBlockTest, BasicAllocation) {
840198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    MemBlock dnsPacket(DNS_PACKET_SIZE);
850198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    Slice slice = dnsPacket.get();
860198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ(DNS_PACKET_SIZE, slice.size());
870198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    // Verify the space is '\0'-initialized.
880198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    ASSERT_NO_FATAL_FAILURE(checkAllZeros(slice));
890198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_NE(nullptr, slice.base());
900198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
910198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
920198ef5cd67b74a4e67a485a03c1c12c815aa32bErik KlineTEST(MemBlockTest, MoveConstruction) {
930198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    MemBlock block(makeArbitraryMemBlock(DNS_PACKET_SIZE));
940198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE));
950198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
960198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
970198ef5cd67b74a4e67a485a03c1c12c815aa32bErik KlineTEST(MemBlockTest, MoveAssignmentOrConstruction) {
980198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    MemBlock block = makeArbitraryMemBlock(DNS_PACKET_SIZE);
990198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE));
1000198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
1010198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
1020198ef5cd67b74a4e67a485a03c1c12c815aa32bErik KlineTEST(MemBlockTest, StdMoveAssignment) {
103ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Kline    constexpr unsigned SIZE = 10;
1040198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
1050198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    MemBlock block;
1060198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_TRUE(block.get().empty());
1070198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ(nullptr, block.get().base());
1080198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
1090198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    {
1100198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline        MemBlock block2 = makeArbitraryMemBlock(SIZE);
1110198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline        EXPECT_EQ(SIZE, block2.get().size());
1120198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline        // More fictional work.
113ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Kline        for (unsigned i = 0; i < SIZE; i++) {
1140198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline            block2.get().base()[i] = i;
1150198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline        }
1160198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline        block = std::move(block2);
1170198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    }
1180198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
1190198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    EXPECT_EQ(SIZE, block.get().size());
120ce4842e4186fdcdc0bed8221c216c26780acf2c1Erik Kline    for (unsigned i = 0; i < SIZE; i++) {
1210198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline        EXPECT_EQ(i, block.get().base()[i]);
1220198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    }
1230198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
1240198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
1250198ef5cd67b74a4e67a485a03c1c12c815aa32bErik KlineTEST(MemBlockTest, ConstructionFromSlice) {
1260198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    uint8_t data[] = {'h', 'e', 'l', 'l', 'o'};
1270198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0])));
1280198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
1290198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    MemBlock dataCopy(dataSlice);
1300198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy.get(), dataSlice));
1310198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
1320198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
1330198ef5cd67b74a4e67a485a03c1c12c815aa32bErik KlineTEST(MemBlockTest, ImplicitCastToSlice) {
1340198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    uint8_t data[] = {'h', 'e', 'l', 'l', 'o'};
1350198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0])));
1360198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
1370198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    MemBlock dataCopy(dataSlice.size());
1380198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    // NOTE: no explicit MemBlock::get().
1390198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    // Verify the space is '\0'-initialized.
1400198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    ASSERT_NO_FATAL_FAILURE(checkAllZeros(dataCopy));
1410198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    copy(dataCopy, dataSlice);
1420198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline    ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy, dataSlice));
1430198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}
1440198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline
1450198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}  // namespace netdutils
1460198ef5cd67b74a4e67a485a03c1c12c815aa32bErik Kline}  // namespace android
147