Split documentation into three folders: Architecture, Testing and Installation. Rework and expand architecture.md alongside interfaces.md Split all parts to do with testing from Architecture md's into Test md's Add parameter to ExamResultGenerator node documentation
6.3 KiB
ConfigManager (assignments::one::ConfigManager)
Overview
The ConfigManager class is used to be able to store configuration values in a TOML file making it
possible to change project settings without the need of recompiling the codebase.
The toml++ library is used to parse TOML configuration
files and provides type-safe access to configuration parameters. It is automatically installed
using the FetchContent_Declare macro inside of the CMakeLists.txt.
Implementation Details
Dependencies
- toml++: Modern header-only C++17 TOML parser and serializer
- rclcpp: ROS2 C++ client library for logging
- filesystem: C++17 filesystem library for file operations
- DatabaseConfig: Custom data structure for database configuration
Key Components
Constructor
ConfigManager(rclcpp::Logger logger)
- Initializes the configuration manager making use of a ROS2 logger
- Calls
find_config_file()andload_config()for automatic setup - Automatically attempts to locate and load configuration from a list of pre-defined paths.
Configuration Loading
bool load_config(const std::string& config_file_path)
Returns
trueon successful load,falseon failure
- Uses
toml::parse_file() - Loads TOML configuration from specified file path
- Validates file existence before attempting to parse
- Error handling for:
- File not found errors
- TOML parsing errors
- General I/O exceptions
- Updates internal
loaded_state flag
std::string find_config_file() const
Returns first found configuration file path Returns empty string if no configuration file is found
- Automatically searches for configuration files in predefined locations
- Search paths (in order):
std::vector<std::string> default_config_paths_ = {
"config.toml",
"./src/config.toml",
"../config.toml",
"../../config.toml",
"../../../config.toml",
"../../../../config.toml",
"/etc/ros2_grade_calculator/config.toml"
};
Configuration Access
std::optional<DatabaseConfig> get_database_config() const
Returns
std::optional<DatabaseConfig>for safe null handling Returnsstd::nulloptif:
- Configuration is not loaded
- Database section is missing
- Parsing fails due to invalid format
- Calls
parse_database_config()for actual parsing
bool is_loaded() const
Returns
trueif configuration has been successfully loaded and parsed
- Getter for configuration load status
- Used by other components to verify configuration availability
Configuration Parsing
DatabaseConfig parse_database_config(const toml::table& config) const
- parser for database configuration section
- Extracts all database-related parameters with defaults
Default Values and Fallbacks
- host:
"localhost"- Local database server - port:
5432- Standard PostgreSQL port - dbname:
"grades"- Application-specific database - user:
"postgres"- Default PostgreSQL user - password:
"postgres"- Default PostgreSQL password - timeout:
30seconds - connection timeout - ssl:
false- Disabled by default for development - min_connections:
1- Minimal connection pool - max_connections:
10- connection pool limit
Logging
- Uses ROS2 logger with
[CFG]prefix for configuration operations - Includes file paths in log messages
Usage Examples
Automatic Configuration Loading
// ConfigManager automatically finds and loads configuration
ConfigManager config_manager(node->get_logger());
if (config_manager.is_loaded()) {
auto db_config = config_manager.get_database_config();
if (db_config.has_value()) {
// Use database configuration
DatabaseManager db_manager(db_config.value());
}
}
Configuration File Format
Example complete TOML configuration:
# Database connection settings
[database]
host = "localhost"
port = 5432
dbname = "grades"
user = "postgres"
password = "postgres"
timeout = 30
ssl = false
[database.pool]
min_connections = 1
max_connections = 10
Unit Tests
Unit tests for ConfigManager are implemented in src/g2_2025_grade_calculator_pkg/test/ConfigManager.test.cpp using Google Test and ROS2 test utilities. The tests use temporary TOML files to validate configuration loading and parsing functionality.
Test Cases
1. ConstructorTest
Description: Verifies that ConfigManager can be created with a ROS2 logger without crashing.
- Test Action: Create ConfigManager instance with ROS2 logger
- Expected Result: Instance created successfully without exceptions
2. LoadValidConfigTest
Description: Tests loading of valid TOML configuration files with proper parsing.
- Test Action:
- Create temporary TOML file with valid configuration
- Call
load_config()with file path
- Expected Result:
- Returns
true is_loaded()returnstrue
- Returns
3. LoadInvalidFileTest
Description: Tests error handling when attempting to load non-existent configuration files.
- Test Action: Call
load_config()with non-existent file path - Expected Result:
- Returns
false is_loaded()returnsfalse
- Returns
4. DatabaseConfigParsingTest
Description: Tests complete database configuration parsing with all parameters.
- Test Configuration:
[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 - Expected Result: All configuration values parsed correctly with proper types
5. DatabaseConfigWithoutPoolTest
Description: Tests default values when optional pool section is missing from configuration.
- Test Configuration:
[database] host = "localhost" port = 5432 dbname = "grades" user = "postgres" password = "postgres" - Expected Result:
- Main database config parsed correctly
- Default pool values:
min_connections = 1,max_connections = 10
6. GetConfigWithoutLoadingTest
Description: Tests behavior when attempting to access configuration before loading any file.
- Test Action: Call
get_database_config()without loading configuration - Expected Result:
- Returns
std::nullopt is_loaded()returnsfalse
- Returns