feat(Config,Database): Add tests

This commit is contained in:
2025-10-02 13:17:41 +02:00
parent 057968d5ac
commit fe8dc6ceba
4 changed files with 250 additions and 15 deletions

View File

@@ -8,13 +8,13 @@ endif()
# external packages
include(FetchContent)
FetchContent_Declare(
fetchcontent_declare(
tomlplusplus
GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
GIT_TAG v3.4.0
)
FetchContent_MakeAvailable(tomlplusplus)
fetchcontent_makeavailable(tomlplusplus)
# find dependencies
find_package(ament_cmake REQUIRED)
@@ -64,7 +64,7 @@ add_executable(retake_scheduler
)
ament_target_dependencies(retake_scheduler rclcpp g2_2025_interfaces)
install (
install(
TARGETS
exam_result_generator
final_grade_determinator
@@ -75,15 +75,39 @@ install (
)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# comment the line when a copyright and license is added to all source files
set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# comment the line when this package is in a git repo and when
# a copyright and license is added to all source files
set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
find_package(ament_cmake_gtest REQUIRED)
# Add gtest for ConfigManager
ament_add_gtest(${PROJECT_NAME}_test_config_manager
test/ConfigManager.test.cpp
src/config/ConfigManager.cpp
)
target_include_directories(${PROJECT_NAME}_test_config_manager PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
ament_target_dependencies(${PROJECT_NAME}_test_config_manager
rclcpp
)
target_link_libraries(${PROJECT_NAME}_test_config_manager
tomlplusplus::tomlplusplus
)
# Add gtest for DatabaseManager
ament_add_gtest(${PROJECT_NAME}_test_database_manager
test/DatabaseManager.test.cpp
src/database/DatabaseManager.cpp
src/config/ConfigManager.cpp
)
target_include_directories(${PROJECT_NAME}_test_database_manager PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
ament_target_dependencies(${PROJECT_NAME}_test_database_manager
rclcpp
g2_2025_interfaces
)
target_link_libraries(${PROJECT_NAME}_test_database_manager
pqxx pq tomlplusplus::tomlplusplus
)
endif()
ament_package()

View File

@@ -12,9 +12,6 @@
<depend>rclcpp</depend>
<depend>g2_2025_interfaces</depend>
<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>
<export>
<build_type>ament_cmake</build_type>
</export>

View File

@@ -0,0 +1,135 @@
#include <filesystem>
#include <fstream>
#include <gtest/gtest.h>
#include <rclcpp/rclcpp.hpp>
#include "config/ConfigManager.hpp"
using namespace assignments::one;
static const std::string TEST_CONFIG_CONTENT = R"(
[database]
host = "test_host"
port = 1234
dbname = "test_db"
user = "test_user"
password = "test_password"
timeout = 60
ssl = true
[database.pool]
min_connections = 2
max_connections = 20
)";
static const std::string TEST_CONFIG_NO_POOL_CONTENT = R"(
[database]
host = "localhost"
port = 5432
dbname = "grades"
user = "postgres"
password = "postgres"
)";
class ConfigManagerTest : public ::testing::Test {
protected:
void SetUp() override {
rclcpp::init(0, nullptr);
node_ = std::make_shared<rclcpp::Node>("test_config_node");
}
void TearDown() override {
// Clean up temporary files
if (std::filesystem::exists(temp_config_file_)) {
std::filesystem::remove(temp_config_file_);
}
node_.reset();
rclcpp::shutdown();
}
void create_temp_config_file() {
temp_config_file_ = "test_config.toml";
std::ofstream file(temp_config_file_);
file << TEST_CONFIG_CONTENT;
file.close();
}
std::shared_ptr<rclcpp::Node> node_;
std::string temp_config_file_;
};
TEST_F(ConfigManagerTest, ConstructorTest) {
// Test ConfigManager can be constructed with logger
ConfigManager config_manager(node_->get_logger());
// Constructor should not crash
SUCCEED();
}
TEST_F(ConfigManagerTest, LoadValidConfigTest) {
create_temp_config_file();
ConfigManager config_manager(node_->get_logger());
bool result = config_manager.load_config(temp_config_file_);
EXPECT_TRUE(result);
EXPECT_TRUE(config_manager.is_loaded());
}
TEST_F(ConfigManagerTest, LoadInvalidFileTest) {
ConfigManager config_manager(node_->get_logger());
bool result = config_manager.load_config("non_existent_file.toml");
EXPECT_FALSE(result);
EXPECT_FALSE(config_manager.is_loaded());
}
TEST_F(ConfigManagerTest, DatabaseConfigParsingTest) {
create_temp_config_file();
ConfigManager config_manager(node_->get_logger());
config_manager.load_config(temp_config_file_);
auto db_config = config_manager.get_database_config();
ASSERT_TRUE(db_config.has_value());
EXPECT_EQ(db_config->host, "test_host");
EXPECT_EQ(db_config->port, 1234);
EXPECT_EQ(db_config->dbname, "test_db");
EXPECT_EQ(db_config->user, "test_user");
EXPECT_EQ(db_config->password, "test_password");
EXPECT_EQ(db_config->timeout, 60);
EXPECT_TRUE(db_config->ssl);
EXPECT_EQ(db_config->min_connections, 2);
EXPECT_EQ(db_config->max_connections, 20);
}
TEST_F(ConfigManagerTest, DatabaseConfigWithoutPoolTest) {
// Create config without pool section
std::ofstream file("test_config_no_pool.toml");
file << TEST_CONFIG_NO_POOL_CONTENT;
file.close();
ConfigManager config_manager(node_->get_logger());
config_manager.load_config("test_config_no_pool.toml");
auto db_config = config_manager.get_database_config();
ASSERT_TRUE(db_config.has_value());
EXPECT_EQ(db_config->host, "localhost");
EXPECT_EQ(db_config->port, 5432);
EXPECT_EQ(db_config->min_connections, 1); // default
EXPECT_EQ(db_config->max_connections, 10); // default
std::filesystem::remove("test_config_no_pool.toml");
}
TEST_F(ConfigManagerTest, GetConfigWithoutLoadingTest) {
ConfigManager config_manager(node_->get_logger());
auto db_config = config_manager.get_database_config();
EXPECT_FALSE(db_config.has_value());
EXPECT_FALSE(config_manager.is_loaded());
}

View File

@@ -0,0 +1,79 @@
#include <gtest/gtest.h>
#include <rclcpp/rclcpp.hpp>
#include "database/DatabaseManager.hpp"
#include "database/StudentCourse.hpp"
using namespace assignments::one;
class DatabaseManagerTest : public ::testing::Test {
protected:
void SetUp() override {
rclcpp::init(0, nullptr);
node_ = std::make_shared<rclcpp::Node>("test_db_node");
db_manager_ = std::make_unique<DatabaseManager>(node_->get_logger());
}
void TearDown() override {
db_manager_.reset();
node_.reset();
rclcpp::shutdown();
}
std::shared_ptr<rclcpp::Node> node_;
std::unique_ptr<DatabaseManager> db_manager_;
};
TEST_F(DatabaseManagerTest, ConstructorTest) {
// Test DatabaseManager can be constructed
ASSERT_NE(db_manager_, nullptr);
}
TEST_F(DatabaseManagerTest, ConnectionStatusTest) {
bool status = db_manager_->is_connected();
EXPECT_TRUE(status == true || status == false);
}
TEST_F(DatabaseManagerTest, QueuePendingCombinationsTest) {
auto combinations = db_manager_->queue_pending_combinations();
EXPECT_GE(combinations.size(), 0);
}
TEST_F(DatabaseManagerTest, StoreExamResultTest) {
bool result = db_manager_->store_exam_result("TestStudent", "TestCourse", 85);
EXPECT_TRUE(result == true || result == false);
}
TEST_F(DatabaseManagerTest, EnrollStudentTest) {
StudentCourse sc;
sc.student_name = "TestStudent";
sc.course_name = "TestCourse";
bool result = db_manager_->enroll_student_into_course(sc);
EXPECT_TRUE(result == true || result == false);
}
TEST_F(DatabaseManagerTest, GetFinalGradeTest) {
StudentCourse sc;
sc.student_name = "NonExistentStudent";
sc.course_name = "NonExistentCourse";
int grade = db_manager_->get_final_course_grade(sc);
EXPECT_EQ(grade, -1);
}
TEST_F(DatabaseManagerTest, StoreFinalResultTest) {
StudentCourse sc;
sc.student_name = "TestStudent";
sc.course_name = "TestCourse";
bool result = db_manager_->store_final_course_result(sc, 3, 75);
EXPECT_TRUE(result == true || result == false);
}