From c0105657725bc2fc593f5679fec15a665dcc719a Mon Sep 17 00:00:00 2001 From: Mykola Solianko Date: Mon, 12 Jan 2026 14:13:56 +0200 Subject: [PATCH] spaceallocator: fix Resize to properly free and allocate space Signed-off-by: Mykola Solianko --- .../spaceallocator/itf/spaceallocator.hpp | 9 ++++ .../common/spaceallocator/spaceallocator.hpp | 35 +++++++++++++++ .../spaceallocator/tests/spaceallocator.cpp | 45 ++++++++++++++++++- .../common/tests/mocks/spaceallocatormock.hpp | 1 + 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/core/common/spaceallocator/itf/spaceallocator.hpp b/src/core/common/spaceallocator/itf/spaceallocator.hpp index f000d4974..62a36dc91 100644 --- a/src/core/common/spaceallocator/itf/spaceallocator.hpp +++ b/src/core/common/spaceallocator/itf/spaceallocator.hpp @@ -91,6 +91,15 @@ class SpaceAllocatorItf { */ virtual void FreeSpace(size_t size) = 0; + /** + * Resizes space. + * + * @param oldSize old size. + * @param newSize new size. + * @return Error. + */ + virtual Error ResizeSpace(size_t oldSize, size_t newSize) = 0; + /** * Adds outdated item. * diff --git a/src/core/common/spaceallocator/spaceallocator.hpp b/src/core/common/spaceallocator/spaceallocator.hpp index 111518a90..77604f3ef 100644 --- a/src/core/common/spaceallocator/spaceallocator.hpp +++ b/src/core/common/spaceallocator/spaceallocator.hpp @@ -58,6 +58,10 @@ class Space : public SpaceItf { */ Error Resize(size_t size) override { + if (auto err = mAllocator->ResizeSpace(mSize, size); !err.IsNone()) { + return err; + } + mSize = size; return ErrorEnum::eNone; @@ -432,6 +436,8 @@ class SpaceAllocator : public SpaceAllocatorItf, public SpaceAllocatorStorage { } if (err = mPartition->Allocate(size); !err.IsNone()) { + Free(size); + return {nullptr, err}; } @@ -451,6 +457,35 @@ class SpaceAllocator : public SpaceAllocatorItf, public SpaceAllocatorStorage { mPartition->Free(size); } + /** + * Resizes space. + * + * @param oldSize old size. + * @param newSize new size. + * @return Error. + */ + Error ResizeSpace(size_t oldSize, size_t newSize) override + { + if (oldSize == newSize) { + return ErrorEnum::eNone; + } + + Free(oldSize); + mPartition->Free(oldSize); + + if (auto err = Allocate(newSize); !err.IsNone()) { + return err; + } + + if (auto err = mPartition->Allocate(newSize); !err.IsNone()) { + Free(newSize); + + return err; + } + + return ErrorEnum::eNone; + } + /** * Allocates done. * diff --git a/src/core/common/spaceallocator/tests/spaceallocator.cpp b/src/core/common/spaceallocator/tests/spaceallocator.cpp index 4f7c68231..7f5438fc8 100644 --- a/src/core/common/spaceallocator/tests/spaceallocator.cpp +++ b/src/core/common/spaceallocator/tests/spaceallocator.cpp @@ -20,7 +20,12 @@ namespace aos::spaceallocator { class SpaceallocatorTest : public Test { protected: - void TearDown() { fs::RemoveAll(mPath); } + void TearDown() + { + // Clear global partition state between tests + SpaceAllocator<1>::mPartitions.Clear(); + fs::RemoveAll(mPath); + } StrictMock mPlatformFS; StrictMock mRemover; @@ -292,4 +297,42 @@ TEST_F(SpaceallocatorTest, PartLimit) ASSERT_TRUE(mSpaceAllocator.Close().IsNone()); } +TEST_F(SpaceallocatorTest, ResizeSpace) +{ + SpaceAllocator<5> mSpaceAllocator; + + EXPECT_CALL(mPlatformFS, GetMountPoint(mPath)) + .WillOnce(Return(RetWithError>(mMountPoint, ErrorEnum::eNone))); + + EXPECT_CALL(mPlatformFS, GetTotalSize(mMountPoint)) + .WillOnce(Return(RetWithError(mTotalSize, ErrorEnum::eNone))); + + ASSERT_TRUE(mSpaceAllocator.Init(mPath, mPlatformFS, mLimit).IsNone()); + + EXPECT_CALL(mPlatformFS, GetAvailableSize(mMountPoint)) + .WillOnce(Return(RetWithError(mTotalSize, ErrorEnum::eNone))); + + const size_t initialSize = 256 * cKilobyte; + + auto [space, err] = mSpaceAllocator.AllocateSpace(initialSize); + ASSERT_TRUE(err.IsNone()); + ASSERT_NE(space.Get(), nullptr); + ASSERT_EQ(space->Size(), initialSize); + + const size_t newSize = 512 * cKilobyte; + ASSERT_TRUE(space->Resize(newSize).IsNone()); + ASSERT_EQ(space->Size(), newSize); + + const size_t smallerSize = 128 * cKilobyte; + ASSERT_TRUE(space->Resize(smallerSize).IsNone()); + ASSERT_EQ(space->Size(), smallerSize); + + ASSERT_TRUE(space->Resize(smallerSize).IsNone()); + ASSERT_EQ(space->Size(), smallerSize); + + EXPECT_TRUE(space->Accept().IsNone()); + + ASSERT_TRUE(mSpaceAllocator.Close().IsNone()); +} + } // namespace aos::spaceallocator diff --git a/src/core/common/tests/mocks/spaceallocatormock.hpp b/src/core/common/tests/mocks/spaceallocatormock.hpp index 1c36d3a73..436fb3bac 100644 --- a/src/core/common/tests/mocks/spaceallocatormock.hpp +++ b/src/core/common/tests/mocks/spaceallocatormock.hpp @@ -39,6 +39,7 @@ class SpaceAllocatorMock : public SpaceAllocatorItf { public: MOCK_METHOD(RetWithError>, AllocateSpace, (size_t size), (override)); MOCK_METHOD(void, FreeSpace, (size_t size), (override)); + MOCK_METHOD(Error, ResizeSpace, (size_t oldSize, size_t newSize), (override)); MOCK_METHOD(Error, AddOutdatedItem, (const String& id, const Time& timestamp), (override)); MOCK_METHOD(Error, RestoreOutdatedItem, (const String& id), (override)); MOCK_METHOD(Error, AllocateDone, (), (override));