Skip to content

Commit

Permalink
feat(AgentRegistration): added a new constructor to be able to inject…
Browse files Browse the repository at this point in the history
… an AgentInfo object. The AgentRegistration UTs has also been fixed.
  • Loading branch information
Nicogp committed Feb 10, 2025
1 parent c57581e commit aa8aa7f
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 33 deletions.
21 changes: 21 additions & 0 deletions src/agent/include/agent_registration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ namespace agent_registration
const std::string& dbFolderPath,
std::string verificationMode);

///@brief Constructor for the AgentRegistration class.
///
/// @param httpClient The HTTP client to use for communication.
/// @param url The server URL.
/// @param user The user's username.
/// @param password The user's password.
/// @param key The agent's key.
/// @param name The agent's name.
/// @param dbFolderPath The path to the database folder.
/// @param verificationMode The connection verification mode.
/// @param agentInfo The agent's information object.
AgentRegistration(std::unique_ptr<http_client::IHttpClient> httpClient,
std::string url,
std::string user,
std::string password,
const std::string& key,
const std::string& name,
const std::string& dbFolderPath,
std::string verificationMode,
AgentInfo agentInfo);

/// @brief Registers the agent with the manager.
///
/// @return True if the registration was successful, false otherwise.
Expand Down
26 changes: 24 additions & 2 deletions src/agent/src/agent_registration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,31 @@ namespace agent_registration
const std::string& name,
const std::string& dbFolderPath,
std::string verificationMode)
: AgentRegistration(
std::move(httpClient),
std::move(url),
std::move(user),
std::move(password),
key,
name,
dbFolderPath,
std::move(verificationMode),
AgentInfo(
dbFolderPath, [this]() { return m_sysInfo.os(); }, [this]() { return m_sysInfo.networks(); }, true))
{
}

AgentRegistration::AgentRegistration(std::unique_ptr<http_client::IHttpClient> httpClient,
std::string url,
std::string user,
std::string password,
const std::string& key,
const std::string& name,
[[maybe_unused]] const std::string& dbFolderPath,
std::string verificationMode,
AgentInfo agentInfo)
: m_httpClient(std::move(httpClient))
, m_agentInfo(
dbFolderPath, [this]() { return m_sysInfo.os(); }, [this]() { return m_sysInfo.networks(); }, true)
, m_agentInfo(std::move(agentInfo))
, m_serverUrl(std::move(url))
, m_user(std::move(user))
, m_password(std::move(password))
Expand Down
6 changes: 4 additions & 2 deletions src/agent/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ endif()

add_executable(agent_registration_test agent_registration_test.cpp)
configure_target(agent_registration_test)
target_include_directories(agent_registration_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../src
${CMAKE_CURRENT_SOURCE_DIR}/../agent_info/src)
target_include_directories(agent_registration_test PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../src
${CMAKE_CURRENT_SOURCE_DIR}/../agent_info/src
${CMAKE_CURRENT_SOURCE_DIR}/../persistence/tests/mocks)
target_link_libraries(agent_registration_test PRIVATE Agent Persistence GTest::gmock GTest::gtest)
add_test(NAME AgentRegistrationTest COMMAND agent_registration_test)

Expand Down
135 changes: 106 additions & 29 deletions src/agent/tests/agent_registration_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <ihttp_client.hpp>

#include "../http_client/tests/mocks/mock_http_client.hpp"
#include <mocks_persistence.hpp>

#include <boost/asio.hpp>
#include <nlohmann/json.hpp>
Expand All @@ -20,32 +21,63 @@ class RegisterTest : public ::testing::Test
protected:
void SetUp() override
{
auto mockPersistencePtr = std::make_unique<MockPersistence>();
mockPersistence = mockPersistencePtr.get();

SetConstructorPersistenceExpectCalls();

SysInfo sysInfo;
agent = std::make_unique<AgentInfo>(
".",
[&sysInfo]() mutable { return sysInfo.os(); },
[&sysInfo]() mutable { return sysInfo.networks(); },
true);
[sysInfo]() mutable { return sysInfo.os(); },
[sysInfo]() mutable { return sysInfo.networks(); },
true,
std::make_shared<AgentInfoPersistance>("db_path", std::move(mockPersistencePtr)));

agent->SetKey("4GhT7uFm1zQa9c2Vb7Lk8pYsX0WqZrNj");
agent->SetName("agent_name");
agent->Save();
}

void SetConstructorPersistenceExpectCalls()
{
EXPECT_CALL(*mockPersistence, TableExists("agent_info")).WillOnce(testing::Return(true));
EXPECT_CALL(*mockPersistence, TableExists("agent_group")).WillOnce(testing::Return(true));
EXPECT_CALL(*mockPersistence, GetCount("agent_info", testing::_, testing::_))
.WillOnce(testing::Return(0))
.WillOnce(testing::Return(0));
EXPECT_CALL(*mockPersistence, Insert("agent_info", testing::_)).Times(1);
}

void SetAgentInfoSaveExpectCalls()
{
// Mock for: m_persistence->ResetToDefault();
EXPECT_CALL(*mockPersistence, DropTable("agent_info")).Times(1);
EXPECT_CALL(*mockPersistence, DropTable("agent_group")).Times(1);
EXPECT_CALL(*mockPersistence, CreateTable(testing::_, testing::_)).Times(2);
EXPECT_CALL(*mockPersistence, GetCount("agent_info", testing::_, testing::_)).WillOnce(testing::Return(0));
EXPECT_CALL(*mockPersistence, Insert(testing::_, testing::_)).Times(1);

// Mock for: m_persistence->SetName(m_name); m_persistence->SetKey(m_key); m_persistence->SetUUID(m_uuid);
EXPECT_CALL(*mockPersistence, Update("agent_info", testing::_, testing::_, testing::_)).Times(3);

// Mock for: m_persistence->SetGroups(m_groups);
EXPECT_CALL(*mockPersistence, BeginTransaction()).Times(1);
EXPECT_CALL(*mockPersistence, Remove("agent_group", testing::_, testing::_)).Times(1);
EXPECT_CALL(*mockPersistence, CommitTransaction(testing::_)).Times(1);
}

std::unique_ptr<AgentInfo> agent;
std::unique_ptr<agent_registration::AgentRegistration> registration;
MockPersistence* mockPersistence = nullptr;
};

TEST_F(RegisterTest, RegistrationTestSuccess)
{
AgentInfoPersistance agentInfoPersistance(".");
agentInfoPersistance.ResetToDefault();

auto mockHttpClient = std::make_unique<MockHttpClient>();
auto mockHttpClientPtr = mockHttpClient.get();

registration = std::make_unique<agent_registration::AgentRegistration>(
std::move(mockHttpClient), "https://localhost:55000", "user", "password", "", "", ".", "full");
std::move(mockHttpClient), "https://localhost:55000", "user", "password", "", "", ".", "full", *agent);

// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
std::tuple<int, std::string> expectedResponse1 {200, R"({"data":{"token":"token"}})"};
Expand All @@ -59,15 +91,15 @@ TEST_F(RegisterTest, RegistrationTestSuccess)
.WillOnce(testing::Return(expectedResponse2));

// NOLINTNEXTLINE(cppcoreguidelines-init-variables)

SetAgentInfoSaveExpectCalls();

const bool res = registration->Register();
ASSERT_TRUE(res);
}

TEST_F(RegisterTest, RegistrationFailsIfAuthenticationFails)
{
AgentInfoPersistance agentInfoPersistance(".");
agentInfoPersistance.ResetToDefault();

auto mockHttpClient = std::make_unique<MockHttpClient>();
auto mockHttpClientPtr = mockHttpClient.get();

Expand All @@ -78,7 +110,8 @@ TEST_F(RegisterTest, RegistrationFailsIfAuthenticationFails)
"4GhT7uFm1zQa9c2Vb7Lk8pYsX0WqZrNj",
"agent_name",
".",
"certificate");
"certificate",
*agent);

// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
std::tuple<int, std::string> expectedResponse {401, ""};
Expand All @@ -92,9 +125,6 @@ TEST_F(RegisterTest, RegistrationFailsIfAuthenticationFails)

TEST_F(RegisterTest, RegistrationFailsIfServerResponseIsNotOk)
{
AgentInfoPersistance agentInfoPersistance(".");
agentInfoPersistance.ResetToDefault();

auto mockHttpClient = std::make_unique<MockHttpClient>();
auto mockHttpClientPtr = mockHttpClient.get();

Expand All @@ -105,7 +135,8 @@ TEST_F(RegisterTest, RegistrationFailsIfServerResponseIsNotOk)
"4GhT7uFm1zQa9c2Vb7Lk8pYsX0WqZrNj",
"agent_name",
".",
"none");
"none",
*agent);

// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
std::tuple<int, std::string> expectedResponse1 {200, R"({"data":{"token":"token"}})"};
Expand All @@ -125,16 +156,18 @@ TEST_F(RegisterTest, RegistrationFailsIfServerResponseIsNotOk)

TEST_F(RegisterTest, RegisteringWithoutAKeyGeneratesOneAutomatically)
{
AgentInfoPersistance agentInfoPersistance(".");
agentInfoPersistance.ResetToDefault();

EXPECT_TRUE(agentInfoPersistance.GetKey().empty());

auto mockHttpClient = std::make_unique<MockHttpClient>();
auto mockHttpClientPtr = mockHttpClient.get();

registration = std::make_unique<agent_registration::AgentRegistration>(
std::move(mockHttpClient), "https://localhost:55000", "user", "password", "", "agent_name", ".", "full");
registration = std::make_unique<agent_registration::AgentRegistration>(std::move(mockHttpClient),
"https://localhost:55000",
"user",
"password",
"",
"agent_name",
".",
"full",
*agent);

// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
std::tuple<int, std::string> expectedResponse1 {200, R"({"data":{"token":"token"}})"};
Expand All @@ -148,10 +181,53 @@ TEST_F(RegisterTest, RegisteringWithoutAKeyGeneratesOneAutomatically)
.WillOnce(testing::Return(expectedResponse2));

// NOLINTNEXTLINE(cppcoreguidelines-init-variables)

// Mock for: m_persistence->ResetToDefault();
EXPECT_CALL(*mockPersistence, DropTable("agent_info")).Times(1);
EXPECT_CALL(*mockPersistence, DropTable("agent_group")).Times(1);
EXPECT_CALL(*mockPersistence, CreateTable(testing::_, testing::_)).Times(2);
EXPECT_CALL(*mockPersistence, GetCount("agent_info", testing::_, testing::_)).WillOnce(testing::Return(0));
EXPECT_CALL(*mockPersistence, Insert(testing::_, testing::_)).Times(1);

// Mock for: m_persistence->SetName(m_name); m_persistence->SetKey(m_key); m_persistence->SetUUID(m_uuid);
testing::InSequence seq;
EXPECT_CALL(*mockPersistence,
Update(testing::Eq("agent_info"),
testing::AllOf(
testing::SizeIs(1),
testing::Contains(testing::AllOf(testing::Field(&column::ColumnValue::Value, "agent_name"),
testing::Field(&column::ColumnName::Name, "name")))),
testing::_,
testing::_))
.Times(1);

EXPECT_CALL(*mockPersistence,
Update(testing::Eq("agent_info"),
testing::AllOf(testing::SizeIs(1),
testing::Contains(testing::AllOf(
testing::Field(&column::ColumnValue::Value, testing::Not(testing::Eq(""))),
testing::Field(&column::ColumnName::Name, "key")))),
testing::_,
testing::_))
.Times(1);

EXPECT_CALL(*mockPersistence,
Update(testing::Eq("agent_info"),
testing::AllOf(testing::SizeIs(1),
testing::Contains(testing::AllOf(
testing::Field(&column::ColumnValue::Value, testing::Not(testing::Eq(""))),
testing::Field(&column::ColumnName::Name, "uuid")))),
testing::_,
testing::_))
.Times(1);

// Mock for: m_persistence->SetGroups(m_groups);
EXPECT_CALL(*mockPersistence, BeginTransaction()).Times(1);
EXPECT_CALL(*mockPersistence, Remove("agent_group", testing::_, testing::_)).Times(1);
EXPECT_CALL(*mockPersistence, CommitTransaction(testing::_)).Times(1);

const bool res = registration->Register();
ASSERT_TRUE(res);

EXPECT_FALSE(agentInfoPersistance.GetKey().empty());
}

TEST_F(RegisterTest, RegistrationTestFailWithBadKey)
Expand All @@ -165,14 +241,15 @@ TEST_F(RegisterTest, RegistrationTestFailWithBadKey)
"badKey",
"agent_name",
".",
"full"),
"full",
*agent),
std::invalid_argument);
}

TEST_F(RegisterTest, RegistrationTestFailWithHttpClientError)
{
ASSERT_THROW(agent_registration::AgentRegistration(
nullptr, "https://localhost:55000", "user", "password", "", "agent_name", ".", "full"),
nullptr, "https://localhost:55000", "user", "password", "", "agent_name", ".", "full", *agent),
std::runtime_error);
}

Expand All @@ -182,7 +259,7 @@ TEST_F(RegisterTest, AuthenticateWithUserPassword_Success)
auto mockHttpClientPtr = mockHttpClient.get();

registration = std::make_unique<agent_registration::AgentRegistration>(
std::move(mockHttpClient), "https://localhost:55000", "user", "password", "", "", ".", "full");
std::move(mockHttpClient), "https://localhost:55000", "user", "password", "", "", ".", "full", *agent);

// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
std::tuple<int, std::string> expectedResponse {200, R"({"data":{"token":"valid_token"}})"};
Expand All @@ -203,7 +280,7 @@ TEST_F(RegisterTest, AuthenticateWithUserPassword_Failure)
auto mockHttpClientPtr = mockHttpClient.get();

registration = std::make_unique<agent_registration::AgentRegistration>(
std::move(mockHttpClient), "https://localhost:55000", "user", "password", "", "", ".", "full");
std::move(mockHttpClient), "https://localhost:55000", "user", "password", "", "", ".", "full", *agent);

// NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
std::tuple<int, std::string> expectedResponse {401, ""};
Expand Down

0 comments on commit aa8aa7f

Please sign in to comment.