// 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 #include #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 { 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; const std::array 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 kPrevs = { BlockResult::Prev::kUnchanged, BlockResult::Prev::kSplitNew, BlockResult::Prev::kResizedSmaller, BlockResult::Prev::kResizedLarger, }; const std::array kNexts = { BlockResult::Next::kUnchanged, BlockResult::Next::kSplitNew, BlockResult::Next::kResized, BlockResult::Next::kMerged, }; const std::array 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