blob: 9073e8dcf7df258a22581ce87b3b272d3280fbee [file]
// Copyright 2024 The Pigweed Authors
//
// 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
//
// https://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 "pw_allocator/block/result.h"
#include <array>
#include <cstddef>
#include "pw_allocator/block/basic.h"
#include "pw_status/status.h"
#include "pw_unit_test/framework.h"
namespace {
using ::pw::Status;
struct FakeBlock : public ::pw::allocator::BasicBlock<FakeBlock> {
static constexpr size_t DefaultAlignment() { return 1; }
static constexpr size_t BlockOverhead() { return 0; }
static constexpr size_t MinInnerSize() { return 0; }
size_t OuterSizeUnchecked() const { return 1; }
};
using BlockResult = ::pw::allocator::BlockResult<FakeBlock>;
const std::array<Status, 17> kStatuses = {
pw::OkStatus(),
Status::Cancelled(),
Status::Unknown(),
Status::InvalidArgument(),
Status::DeadlineExceeded(),
Status::NotFound(),
Status::AlreadyExists(),
Status::PermissionDenied(),
Status::ResourceExhausted(),
Status::FailedPrecondition(),
Status::Aborted(),
Status::OutOfRange(),
Status::Unimplemented(),
Status::Internal(),
Status::Unavailable(),
Status::DataLoss(),
Status::Unauthenticated(),
};
const std::array<BlockResult::Prev, 4> kPrevs = {
BlockResult::Prev::kUnchanged,
BlockResult::Prev::kSplitNew,
BlockResult::Prev::kResizedSmaller,
BlockResult::Prev::kResizedLarger,
};
const std::array<BlockResult::Next, 4> kNexts = {
BlockResult::Next::kUnchanged,
BlockResult::Next::kSplitNew,
BlockResult::Next::kResized,
BlockResult::Next::kMerged,
};
const std::array<size_t, 4> kSizes = {
0,
1,
8,
(1U << 10) - 1,
};
TEST(BlockResultTest, ConstructWithBlockOnly) {
FakeBlock block;
BlockResult result(&block);
EXPECT_EQ(result.block(), &block);
EXPECT_EQ(result.status(), pw::OkStatus());
EXPECT_EQ(result.prev(), BlockResult::Prev::kUnchanged);
EXPECT_EQ(result.next(), BlockResult::Next::kUnchanged);
EXPECT_EQ(result.size(), 0U);
}
TEST(BlockResultTest, ConstructWithBlockAndStatus) {
FakeBlock block;
for (const auto& status : kStatuses) {
BlockResult result(&block, status);
EXPECT_EQ(result.block(), &block);
EXPECT_EQ(result.status(), status);
EXPECT_EQ(result.prev(), BlockResult::Prev::kUnchanged);
EXPECT_EQ(result.next(), BlockResult::Next::kUnchanged);
EXPECT_EQ(result.size(), 0U);
}
}
TEST(BlockResultTest, ConstructWithBlockAndPrev) {
FakeBlock block;
for (const auto& prev : kPrevs) {
BlockResult result(&block, prev);
EXPECT_EQ(result.block(), &block);
EXPECT_EQ(result.status(), pw::OkStatus());
EXPECT_EQ(result.prev(), prev);
EXPECT_EQ(result.next(), BlockResult::Next::kUnchanged);
EXPECT_EQ(result.size(), 0U);
}
}
TEST(BlockResultTest, ConstructWithBlockPrevAndSize) {
FakeBlock block;
for (const auto& prev : kPrevs) {
for (const auto& size : kSizes) {
BlockResult result(&block, prev, size);
EXPECT_EQ(result.block(), &block);
EXPECT_EQ(result.status(), pw::OkStatus());
EXPECT_EQ(result.prev(), prev);
EXPECT_EQ(result.next(), BlockResult::Next::kUnchanged);
EXPECT_EQ(result.size(), size);
}
}
}
TEST(BlockResultTest, ConstructWithBlockAndNext) {
FakeBlock block;
for (const auto& next : kNexts) {
BlockResult result(&block, next);
EXPECT_EQ(result.block(), &block);
EXPECT_EQ(result.status(), pw::OkStatus());
EXPECT_EQ(result.prev(), BlockResult::Prev::kUnchanged);
EXPECT_EQ(result.next(), next);
EXPECT_EQ(result.size(), 0U);
}
}
TEST(BlockResultTest, ConstructWithBlockPrevAndNext) {
FakeBlock block;
for (const auto& prev : kPrevs) {
for (const auto& next : kNexts) {
BlockResult result(&block, prev, next);
EXPECT_EQ(result.block(), &block);
EXPECT_EQ(result.status(), pw::OkStatus());
EXPECT_EQ(result.prev(), prev);
EXPECT_EQ(result.next(), next);
EXPECT_EQ(result.size(), 0U);
}
}
}
TEST(BlockResultTest, ConstructWithBlockPrevNextAndSize) {
FakeBlock block;
for (const auto& prev : kPrevs) {
for (const auto& next : kNexts) {
for (const auto& size : kSizes) {
BlockResult result(&block, prev, next, size);
EXPECT_EQ(result.block(), &block);
EXPECT_EQ(result.status(), pw::OkStatus());
EXPECT_EQ(result.prev(), prev);
EXPECT_EQ(result.next(), next);
EXPECT_EQ(result.size(), size);
}
}
}
}
} // namespace