| // 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 |