Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/cm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ set(TARGET_PREFIX ${TARGET_PREFIX}_cm)
# ######################################################################################################################

add_subdirectory(app)
add_subdirectory(uidgidpool)
46 changes: 46 additions & 0 deletions src/cm/uidgidpool/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#
# Copyright (C) 2025 EPAM Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#

# ######################################################################################################################
# Target name
# ######################################################################################################################

set(TARGET_NAME uidgidpool)

# ######################################################################################################################
# Sources
# ######################################################################################################################

set(SOURCES uidgidpool.cpp)

# ######################################################################################################################
# Libraries
# ######################################################################################################################

set(LIBRARIES aos::common::logger aoscommon)

# ######################################################################################################################
# Target
# ######################################################################################################################

add_module(
TARGET_NAME
${TARGET_NAME}
STACK_USAGE
${AOS_STACK_USAGE}
SOURCES
${SOURCES}
LIBRARIES
${LIBRARIES}
)

# ######################################################################################################################
# Tests
# ######################################################################################################################

if(WITH_TEST)
add_subdirectory(tests)
endif()
33 changes: 33 additions & 0 deletions src/cm/uidgidpool/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#
# Copyright (C) 2025 EPAM Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#

set(TARGET_NAME uidgidpool_test)

# ######################################################################################################################
# Sources
# ######################################################################################################################

set(SOURCES uidgidpool.cpp)

# ######################################################################################################################
# Libraries
# ######################################################################################################################

set(LIBRARIES ${TARGET_NAMESPACE}::uidgidpool aostestcore aostestutils GTest::gmock_main)

# ######################################################################################################################
# Target
# ######################################################################################################################

add_test(
TARGET_NAME
${TARGET_NAME}
LOG_MODULE
SOURCES
${SOURCES}
LIBRARIES
${LIBRARIES}
)
94 changes: 94 additions & 0 deletions src/cm/uidgidpool/tests/uidgidpool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2024 EPAM Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <gtest/gtest.h>

#include <aos/test/log.hpp>

#include <cm/uidgidpool/uidgidpool.hpp>

using namespace testing;

namespace aos::cm::uidgidpool {

/***********************************************************************************************************************
* Suite
**********************************************************************************************************************/

class UIDGIDPoolTest : public Test {
public:
void SetUp() override { test::InitLog(); }
};

/***********************************************************************************************************************
* Tests
**********************************************************************************************************************/

TEST_F(UIDGIDPoolTest, uidPool)
{
UIDPool uidPool;

auto [uid, err] = uidPool.GetFreeID();
ASSERT_EQ(err, ErrorEnum::eNone);
ASSERT_EQ(uid, 5000);

err = uidPool.LockID(5001);
ASSERT_EQ(err, ErrorEnum::eNone);

err = uidPool.LockID(5001);
ASSERT_EQ(err, ErrorEnum::eFailed);

err = uidPool.LockID(0);
ASSERT_EQ(err, ErrorEnum::eOutOfRange);

err = uidPool.LockID(std::numeric_limits<size_t>::max());
ASSERT_EQ(err, ErrorEnum::eOutOfRange);

Tie(uid, err) = uidPool.GetFreeID();
ASSERT_EQ(err, ErrorEnum::eNone);
ASSERT_EQ(uid, 5002);

err = uidPool.ReleaseID(5001);
ASSERT_EQ(err, ErrorEnum::eNone);

Tie(uid, err) = uidPool.GetFreeID();
ASSERT_EQ(err, ErrorEnum::eNone);
ASSERT_EQ(uid, 5001);
}

TEST_F(UIDGIDPoolTest, gidPool)
{
GIDPool gidPool;

auto [uid, err] = gidPool.GetFreeID();
ASSERT_EQ(err, ErrorEnum::eNone);
ASSERT_EQ(uid, 5000);

err = gidPool.LockID(5001);
ASSERT_EQ(err, ErrorEnum::eNone);

err = gidPool.LockID(5001);
ASSERT_EQ(err, ErrorEnum::eFailed);

err = gidPool.LockID(0);
ASSERT_EQ(err, ErrorEnum::eOutOfRange);

err = gidPool.LockID(std::numeric_limits<size_t>::max());
ASSERT_EQ(err, ErrorEnum::eOutOfRange);

Tie(uid, err) = gidPool.GetFreeID();
ASSERT_EQ(err, ErrorEnum::eNone);
ASSERT_EQ(uid, 5002);

err = gidPool.ReleaseID(5001);
ASSERT_EQ(err, ErrorEnum::eNone);

Tie(uid, err) = gidPool.GetFreeID();
ASSERT_EQ(err, ErrorEnum::eNone);
ASSERT_EQ(uid, 5001);
}

} // namespace aos::cm::uidgidpool
113 changes: 113 additions & 0 deletions src/cm/uidgidpool/uidgidpool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright (C) 2025 EPAM Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <grp.h>
#include <pwd.h>
#include <sys/types.h>

#include <common/logger/logmodule.hpp>

#include "uidgidpool.hpp"

namespace aos::cm::uidgidpool {

/***********************************************************************************************************************
* IdentifierPool
**********************************************************************************************************************/

/***********************************************************************************************************************
* Public
**********************************************************************************************************************/

RetWithError<size_t> IdentifierPool::GetFreeID()
{
std::lock_guard lock {mMutex};

LOG_DBG() << "Getting free identifier from pool";

for (size_t id = cIdsRangeBegin; id < cIdsRangeEnd; id++) {
if (mLockedIds.find(id) != mLockedIds.end()) {
continue;
}

if (!IdIsValid(id)) {
continue;

Check warning on line 37 in src/cm/uidgidpool/uidgidpool.cpp

View check run for this annotation

Codecov / codecov/patch

src/cm/uidgidpool/uidgidpool.cpp#L37

Added line #L37 was not covered by tests
}

mLockedIds.insert(id);

return RetWithError<size_t>(id);
}

return {{}, ErrorEnum::eNotFound};

Check warning on line 45 in src/cm/uidgidpool/uidgidpool.cpp

View check run for this annotation

Codecov / codecov/patch

src/cm/uidgidpool/uidgidpool.cpp#L45

Added line #L45 was not covered by tests
}

Error IdentifierPool::LockID(size_t id)
{
std::lock_guard lock {mMutex};

LOG_DBG() << "Lock identifier" << Log::Field("id", id);

if (id < cIdsRangeBegin || id >= cIdsRangeEnd) {
return ErrorEnum::eOutOfRange;
}

if (mLockedIds.find(id) != mLockedIds.end()) {
return ErrorEnum::eFailed;
}

mLockedIds.insert(id);

return ErrorEnum::eNone;
}

Error IdentifierPool::ReleaseID(size_t id)
{
std::lock_guard lock {mMutex};

LOG_DBG() << "Release identifier" << Log::Field("id", id);

auto it = mLockedIds.find(id);
if (it == mLockedIds.end()) {
return ErrorEnum::eNotFound;

Check warning on line 75 in src/cm/uidgidpool/uidgidpool.cpp

View check run for this annotation

Codecov / codecov/patch

src/cm/uidgidpool/uidgidpool.cpp#L75

Added line #L75 was not covered by tests
}

mLockedIds.erase(it);

return ErrorEnum::eNone;
}

/***********************************************************************************************************************
* UIDPool
**********************************************************************************************************************/

/***********************************************************************************************************************
* Private
**********************************************************************************************************************/

bool UIDPool::IdIsValid(size_t id)
{
auto passwd = getpwuid(static_cast<uid_t>(id));

return passwd == nullptr;
}

/***********************************************************************************************************************
* GIDPool
**********************************************************************************************************************/

/***********************************************************************************************************************
* Private
**********************************************************************************************************************/

bool GIDPool::IdIsValid(size_t id)
{
auto group = getgrgid(static_cast<gid_t>(id));

return group == nullptr;
}

} // namespace aos::cm::uidgidpool
Loading
Loading