Implement PostgreSQL Installer Module for Rhai #6
@ -168,6 +168,20 @@ pub fn install_postgres(
|
||||
// Build the image name
|
||||
let image = format!("postgres:{}", config.version);
|
||||
|
||||
// Pull the PostgreSQL image to ensure we have the latest version
|
||||
println!("Pulling PostgreSQL image: {}...", image);
|
||||
let pull_result = Command::new("nerdctl")
|
||||
.args(&["pull", &image])
|
||||
.output()
|
||||
.map_err(|e| PostgresInstallerError::IoError(e))?;
|
||||
|
||||
if !pull_result.status.success() {
|
||||
return Err(PostgresInstallerError::NerdctlError(format!(
|
||||
"Failed to pull PostgreSQL image: {}",
|
||||
String::from_utf8_lossy(&pull_result.stderr)
|
||||
)));
|
||||
}
|
||||
|
||||
// Create the container
|
||||
let mut container = Container::new(&config.container_name).map_err(|e| {
|
||||
PostgresInstallerError::NerdctlError(format!("Failed to create container: {}", e))
|
||||
|
@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
||||
#[cfg(test)]
|
||||
@ -134,6 +135,234 @@ mod postgres_client_tests {
|
||||
|
||||
// Integration tests that require a real PostgreSQL server
|
||||
// These tests will be skipped if PostgreSQL is not available
|
||||
#[cfg(test)]
|
||||
mod postgres_installer_tests {
|
||||
use super::*;
|
||||
use crate::virt::nerdctl::Container;
|
||||
|
||||
#[test]
|
||||
fn test_postgres_installer_config() {
|
||||
// Test default configuration
|
||||
let config = PostgresInstallerConfig::default();
|
||||
assert_eq!(config.container_name, "postgres");
|
||||
assert_eq!(config.version, "latest");
|
||||
assert_eq!(config.port, 5432);
|
||||
assert_eq!(config.username, "postgres");
|
||||
assert_eq!(config.password, "postgres");
|
||||
assert_eq!(config.data_dir, None);
|
||||
assert_eq!(config.env_vars.len(), 0);
|
||||
assert_eq!(config.persistent, true);
|
||||
|
||||
// Test builder pattern
|
||||
let config = PostgresInstallerConfig::new()
|
||||
.container_name("my-postgres")
|
||||
.version("15")
|
||||
.port(5433)
|
||||
.username("testuser")
|
||||
.password("testpass")
|
||||
.data_dir("/tmp/pgdata")
|
||||
.env_var("POSTGRES_INITDB_ARGS", "--encoding=UTF8")
|
||||
.persistent(false);
|
||||
|
||||
assert_eq!(config.container_name, "my-postgres");
|
||||
assert_eq!(config.version, "15");
|
||||
assert_eq!(config.port, 5433);
|
||||
assert_eq!(config.username, "testuser");
|
||||
assert_eq!(config.password, "testpass");
|
||||
assert_eq!(config.data_dir, Some("/tmp/pgdata".to_string()));
|
||||
assert_eq!(config.env_vars.len(), 1);
|
||||
assert_eq!(
|
||||
config.env_vars.get("POSTGRES_INITDB_ARGS").unwrap(),
|
||||
"--encoding=UTF8"
|
||||
);
|
||||
assert_eq!(config.persistent, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_postgres_installer_error() {
|
||||
// Test IoError
|
||||
let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "File not found");
|
||||
let installer_error = PostgresInstallerError::IoError(io_error);
|
||||
assert!(format!("{}", installer_error).contains("I/O error"));
|
||||
|
||||
// Test NerdctlError
|
||||
let nerdctl_error = PostgresInstallerError::NerdctlError("Container not found".to_string());
|
||||
assert!(format!("{}", nerdctl_error).contains("Nerdctl error"));
|
||||
|
||||
// Test PostgresError
|
||||
let postgres_error =
|
||||
PostgresInstallerError::PostgresError("Database not found".to_string());
|
||||
assert!(format!("{}", postgres_error).contains("PostgreSQL error"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_postgres_with_defaults() {
|
||||
// This is a unit test that doesn't actually install PostgreSQL
|
||||
// It just tests the configuration and error handling
|
||||
|
||||
// Test with default configuration
|
||||
let config = PostgresInstallerConfig::default();
|
||||
|
||||
// We expect this to fail because nerdctl is not available
|
||||
let result = install_postgres(config);
|
||||
assert!(result.is_err());
|
||||
|
||||
// Check that the error is a NerdctlError or IoError
|
||||
match result {
|
||||
Err(PostgresInstallerError::NerdctlError(_)) => {
|
||||
// This is fine, we expected a NerdctlError
|
||||
}
|
||||
Err(PostgresInstallerError::IoError(_)) => {
|
||||
// This is also fine, we expected an error
|
||||
}
|
||||
_ => panic!("Expected NerdctlError or IoError"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_postgres_with_custom_config() {
|
||||
// Test with custom configuration
|
||||
let config = PostgresInstallerConfig::new()
|
||||
.container_name("test-postgres")
|
||||
.version("15")
|
||||
.port(5433)
|
||||
.username("testuser")
|
||||
.password("testpass")
|
||||
.data_dir("/tmp/pgdata")
|
||||
.env_var("POSTGRES_INITDB_ARGS", "--encoding=UTF8")
|
||||
.persistent(true);
|
||||
|
||||
// We expect this to fail because nerdctl is not available
|
||||
let result = install_postgres(config);
|
||||
assert!(result.is_err());
|
||||
|
||||
// Check that the error is a NerdctlError or IoError
|
||||
match result {
|
||||
Err(PostgresInstallerError::NerdctlError(_)) => {
|
||||
// This is fine, we expected a NerdctlError
|
||||
}
|
||||
Err(PostgresInstallerError::IoError(_)) => {
|
||||
// This is also fine, we expected an error
|
||||
}
|
||||
_ => panic!("Expected NerdctlError or IoError"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_create_database() {
|
||||
// Create a mock container
|
||||
// In a real test, we would use mockall to create a mock container
|
||||
// But for this test, we'll just test the error handling
|
||||
|
||||
// We expect this to fail because the container is not running
|
||||
let result = create_database(
|
||||
&Container {
|
||||
name: "test-postgres".to_string(),
|
||||
container_id: None,
|
||||
image: Some("postgres:15".to_string()),
|
||||
config: HashMap::new(),
|
||||
ports: Vec::new(),
|
||||
volumes: Vec::new(),
|
||||
env_vars: HashMap::new(),
|
||||
network: None,
|
||||
network_aliases: Vec::new(),
|
||||
cpu_limit: None,
|
||||
memory_limit: None,
|
||||
memory_swap_limit: None,
|
||||
cpu_shares: None,
|
||||
restart_policy: None,
|
||||
health_check: None,
|
||||
detach: false,
|
||||
snapshotter: None,
|
||||
},
|
||||
"testdb",
|
||||
);
|
||||
|
||||
assert!(result.is_err());
|
||||
|
||||
// Check that the error is a PostgresError
|
||||
match result {
|
||||
Err(PostgresInstallerError::PostgresError(msg)) => {
|
||||
assert!(msg.contains("Container is not running"));
|
||||
}
|
||||
_ => panic!("Expected PostgresError"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_execute_sql() {
|
||||
// Create a mock container
|
||||
// In a real test, we would use mockall to create a mock container
|
||||
// But for this test, we'll just test the error handling
|
||||
|
||||
// We expect this to fail because the container is not running
|
||||
let result = execute_sql(
|
||||
&Container {
|
||||
name: "test-postgres".to_string(),
|
||||
container_id: None,
|
||||
image: Some("postgres:15".to_string()),
|
||||
config: HashMap::new(),
|
||||
ports: Vec::new(),
|
||||
volumes: Vec::new(),
|
||||
env_vars: HashMap::new(),
|
||||
network: None,
|
||||
network_aliases: Vec::new(),
|
||||
cpu_limit: None,
|
||||
memory_limit: None,
|
||||
memory_swap_limit: None,
|
||||
cpu_shares: None,
|
||||
restart_policy: None,
|
||||
health_check: None,
|
||||
detach: false,
|
||||
snapshotter: None,
|
||||
},
|
||||
"testdb",
|
||||
"SELECT 1",
|
||||
);
|
||||
|
||||
assert!(result.is_err());
|
||||
|
||||
// Check that the error is a PostgresError
|
||||
match result {
|
||||
Err(PostgresInstallerError::PostgresError(msg)) => {
|
||||
assert!(msg.contains("Container is not running"));
|
||||
}
|
||||
_ => panic!("Expected PostgresError"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_postgres_running() {
|
||||
// Create a mock container
|
||||
// In a real test, we would use mockall to create a mock container
|
||||
// But for this test, we'll just test the error handling
|
||||
|
||||
// We expect this to return false because the container is not running
|
||||
let result = is_postgres_running(&Container {
|
||||
name: "test-postgres".to_string(),
|
||||
container_id: None,
|
||||
image: Some("postgres:15".to_string()),
|
||||
config: HashMap::new(),
|
||||
ports: Vec::new(),
|
||||
volumes: Vec::new(),
|
||||
env_vars: HashMap::new(),
|
||||
network: None,
|
||||
network_aliases: Vec::new(),
|
||||
cpu_limit: None,
|
||||
memory_limit: None,
|
||||
memory_swap_limit: None,
|
||||
cpu_shares: None,
|
||||
restart_policy: None,
|
||||
health_check: None,
|
||||
detach: false,
|
||||
snapshotter: None,
|
||||
});
|
||||
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(result.unwrap(), false);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod postgres_integration_tests {
|
||||
use super::*;
|
||||
|
Loading…
Reference in New Issue
Block a user