289 lines
9.8 KiB
Rust
289 lines
9.8 KiB
Rust
|
|
// Integration tests for platform-config multi-source schema resolution
|
|||
|
|
|
|||
|
|
use std::fs;
|
|||
|
|
use std::path::PathBuf;
|
|||
|
|
|
|||
|
|
use platform_config::{deployment::load_deployment_mode, ExtensionSchemaCache, PlatformStartup};
|
|||
|
|
use tempfile::TempDir;
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_deployment_mode_load() {
|
|||
|
|
// This test requires deployment-mode.ncl to exist
|
|||
|
|
match load_deployment_mode() {
|
|||
|
|
Ok(config) => {
|
|||
|
|
assert!(
|
|||
|
|
config.config.is_object(),
|
|||
|
|
"Deployment config should be a JSON object"
|
|||
|
|
);
|
|||
|
|
println!("✓ Deployment mode loaded successfully");
|
|||
|
|
}
|
|||
|
|
Err(e) => {
|
|||
|
|
eprintln!("ℹ Deployment mode not found (expected in CI): {}", e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_platform_startup_initialization() {
|
|||
|
|
match load_deployment_mode() {
|
|||
|
|
Ok(config) => {
|
|||
|
|
let startup = PlatformStartup::new(&config.config);
|
|||
|
|
assert!(
|
|||
|
|
startup.is_ok(),
|
|||
|
|
"PlatformStartup initialization should succeed"
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
let startup = startup.unwrap();
|
|||
|
|
let enabled = startup.enabled_services();
|
|||
|
|
println!("✓ Enabled services: {:?}", enabled);
|
|||
|
|
|
|||
|
|
// Should have at least vault_service and orchestrator
|
|||
|
|
assert!(
|
|||
|
|
!enabled.is_empty(),
|
|||
|
|
"At least one service should be enabled"
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
Err(e) => {
|
|||
|
|
eprintln!("ℹ Deployment mode not found (expected in CI): {}", e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_service_dependencies_validation() {
|
|||
|
|
match load_deployment_mode() {
|
|||
|
|
Ok(config) => {
|
|||
|
|
let startup = PlatformStartup::new(&config.config);
|
|||
|
|
assert!(startup.is_ok(), "PlatformStartup should initialize");
|
|||
|
|
|
|||
|
|
let startup = startup.unwrap();
|
|||
|
|
|
|||
|
|
// Validate orchestrator dependencies (should depend on vault_service)
|
|||
|
|
let result = startup.validate_dependencies("orchestrator");
|
|||
|
|
|
|||
|
|
// This will pass if vault_service is enabled, or fail if not
|
|||
|
|
// Both are valid outcomes depending on deployment config
|
|||
|
|
match result {
|
|||
|
|
Ok(()) => println!("✓ Orchestrator dependencies validated"),
|
|||
|
|
Err(e) => println!("ℹ Orchestrator dependency check: {}", e),
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
Err(e) => {
|
|||
|
|
eprintln!("ℹ Deployment mode not found (expected in CI): {}", e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_startup_order_calculation() {
|
|||
|
|
match load_deployment_mode() {
|
|||
|
|
Ok(config) => {
|
|||
|
|
let startup = PlatformStartup::new(&config.config);
|
|||
|
|
assert!(startup.is_ok(), "PlatformStartup should initialize");
|
|||
|
|
|
|||
|
|
let startup = startup.unwrap();
|
|||
|
|
let order = startup.get_startup_order();
|
|||
|
|
assert!(order.is_ok(), "Startup order calculation should succeed");
|
|||
|
|
|
|||
|
|
let order = order.unwrap();
|
|||
|
|
println!("✓ Startup order: {:?}", order);
|
|||
|
|
|
|||
|
|
// vault_service should come before orchestrator (if both enabled)
|
|||
|
|
let vault_idx = order.iter().position(|s| s == "vault_service");
|
|||
|
|
let orch_idx = order.iter().position(|s| s == "orchestrator");
|
|||
|
|
|
|||
|
|
if let (Some(v), Some(o)) = (vault_idx, orch_idx) {
|
|||
|
|
assert!(v < o, "vault_service should start before orchestrator");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
Err(e) => {
|
|||
|
|
eprintln!("ℹ Deployment mode not found (expected in CI): {}", e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_extension_schema_cache_creation() {
|
|||
|
|
let temp_dir = TempDir::new().unwrap();
|
|||
|
|
let cache = ExtensionSchemaCache::new(temp_dir.path().to_path_buf());
|
|||
|
|
|
|||
|
|
assert!(
|
|||
|
|
cache.is_ok(),
|
|||
|
|
"ExtensionSchemaCache should create successfully"
|
|||
|
|
);
|
|||
|
|
println!("✓ Extension schema cache created");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_extension_discovery_and_import_paths() {
|
|||
|
|
let temp_dir = TempDir::new().unwrap();
|
|||
|
|
let cache = ExtensionSchemaCache::new(temp_dir.path().to_path_buf()).unwrap();
|
|||
|
|
|
|||
|
|
// Create mock extension structure
|
|||
|
|
let ext_dir = temp_dir.path().join("hetzner@1.0.0");
|
|||
|
|
let schemas_dir = ext_dir.join("schemas");
|
|||
|
|
fs::create_dir_all(&schemas_dir).unwrap();
|
|||
|
|
fs::write(schemas_dir.join("main.ncl"), "{}").unwrap();
|
|||
|
|
|
|||
|
|
// List extensions
|
|||
|
|
let extensions = cache.list_cached_extensions().unwrap();
|
|||
|
|
assert_eq!(extensions.len(), 1, "Should find hetzner extension");
|
|||
|
|
assert_eq!(extensions[0].name, "hetzner");
|
|||
|
|
assert_eq!(extensions[0].version, "1.0.0");
|
|||
|
|
|
|||
|
|
// Get import paths
|
|||
|
|
let import_paths = cache.build_import_paths().unwrap();
|
|||
|
|
assert_eq!(import_paths.len(), 1, "Should have one import path");
|
|||
|
|
assert!(import_paths[0].exists(), "Import path should exist");
|
|||
|
|
|
|||
|
|
println!("✓ Extension discovery successful");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_multiple_extension_versions() {
|
|||
|
|
let temp_dir = TempDir::new().unwrap();
|
|||
|
|
let cache = ExtensionSchemaCache::new(temp_dir.path().to_path_buf()).unwrap();
|
|||
|
|
|
|||
|
|
// Create multiple versions of same extension
|
|||
|
|
for version in &["1.0.0", "1.1.0", "2.0.0"] {
|
|||
|
|
let ext_dir = temp_dir.path().join(format!("aws@{}", version));
|
|||
|
|
let schemas_dir = ext_dir.join("schemas");
|
|||
|
|
fs::create_dir_all(&schemas_dir).unwrap();
|
|||
|
|
fs::write(schemas_dir.join("main.ncl"), "{}").unwrap();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let extensions = cache.list_cached_extensions().unwrap();
|
|||
|
|
assert_eq!(extensions.len(), 3, "Should find all AWS versions");
|
|||
|
|
|
|||
|
|
// Test exact version matching
|
|||
|
|
let path = cache.get_extension_path("aws", Some("1.1.0"));
|
|||
|
|
assert!(path.is_some(), "Should find exact version");
|
|||
|
|
assert!(path.unwrap().ends_with("aws@1.1.0/schemas"));
|
|||
|
|
|
|||
|
|
// Test latest version (first found)
|
|||
|
|
let path = cache.get_extension_path("aws", None);
|
|||
|
|
assert!(path.is_some(), "Should find at least one version");
|
|||
|
|
|
|||
|
|
println!("✓ Multiple extension versions handled correctly");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_multi_extension_import_paths() {
|
|||
|
|
let temp_dir = TempDir::new().unwrap();
|
|||
|
|
let cache = ExtensionSchemaCache::new(temp_dir.path().to_path_buf()).unwrap();
|
|||
|
|
|
|||
|
|
// Create multiple extensions
|
|||
|
|
for (name, version) in &[("hetzner", "1.0.0"), ("aws", "2.1.0"), ("upcloud", "1.5.0")] {
|
|||
|
|
let ext_dir = temp_dir.path().join(format!("{}@{}", name, version));
|
|||
|
|
let schemas_dir = ext_dir.join("schemas");
|
|||
|
|
fs::create_dir_all(&schemas_dir).unwrap();
|
|||
|
|
fs::write(schemas_dir.join("main.ncl"), "{}").unwrap();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let extensions = cache.list_cached_extensions().unwrap();
|
|||
|
|
assert_eq!(extensions.len(), 3, "Should find all extensions");
|
|||
|
|
|
|||
|
|
let import_paths = cache.build_import_paths().unwrap();
|
|||
|
|
assert_eq!(import_paths.len(), 3, "Should have three import paths");
|
|||
|
|
|
|||
|
|
// All paths should exist
|
|||
|
|
for path in &import_paths {
|
|||
|
|
assert!(path.exists(), "Import path should exist: {:?}", path);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
println!("✓ Multi-extension import paths: {:?}", import_paths);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_git_repo_structure_in_startup() {
|
|||
|
|
match load_deployment_mode() {
|
|||
|
|
Ok(config) => {
|
|||
|
|
// Just verify that the git config is present in deployment-mode
|
|||
|
|
let git_config = config.config.get("git");
|
|||
|
|
assert!(
|
|||
|
|
git_config.is_some(),
|
|||
|
|
"Git configuration should be in deployment-mode.ncl"
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
let schemas = git_config.unwrap().get("schemas_repo");
|
|||
|
|
let configs = git_config.unwrap().get("configs_repo");
|
|||
|
|
|
|||
|
|
assert!(schemas.is_some(), "schemas_repo should be defined");
|
|||
|
|
assert!(configs.is_some(), "configs_repo should be defined");
|
|||
|
|
|
|||
|
|
// Verify essential fields
|
|||
|
|
let schemas = schemas.unwrap();
|
|||
|
|
assert!(schemas.get("url").is_some(), "URL should be defined");
|
|||
|
|
assert!(
|
|||
|
|
schemas.get("cache_dir").is_some(),
|
|||
|
|
"cache_dir should be defined"
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
println!("✓ Git repo structure validated");
|
|||
|
|
}
|
|||
|
|
Err(e) => {
|
|||
|
|
eprintln!("ℹ Deployment mode not found (expected in CI): {}", e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_nickel_import_path_priority() {
|
|||
|
|
// This test verifies that the NICKEL_IMPORT_PATH priority system works
|
|||
|
|
// (actual priority order is tested via functional tests, not unit tests)
|
|||
|
|
|
|||
|
|
let home = std::env::var("HOME").unwrap_or_else(|_| "/tmp".to_string());
|
|||
|
|
|
|||
|
|
// Priority 1: Extension schemas
|
|||
|
|
let ext_cache = PathBuf::from(format!("{}/.cache/provisioning/extensions", home));
|
|||
|
|
if ext_cache.exists() {
|
|||
|
|
println!("✓ Extension cache dir exists: {:?}", ext_cache);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Priority 2: Git schemas
|
|||
|
|
let schemas_cache = PathBuf::from(format!("{}/.cache/provisioning/schemas", home));
|
|||
|
|
if schemas_cache.exists() {
|
|||
|
|
println!("✓ Schemas cache dir exists: {:?}", schemas_cache);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Priority 3: Git configs
|
|||
|
|
let configs_cache = PathBuf::from(format!("{}/.cache/provisioning/configs", home));
|
|||
|
|
if configs_cache.exists() {
|
|||
|
|
println!("✓ Configs cache dir exists: {:?}", configs_cache);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Priority 4: Local provisioning/schemas
|
|||
|
|
if PathBuf::from("provisioning/schemas").exists() {
|
|||
|
|
println!("✓ Local schemas dir exists");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
println!("✓ NICKEL_IMPORT_PATH cache structure verified");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_service_enabled_checking() {
|
|||
|
|
match load_deployment_mode() {
|
|||
|
|
Ok(config) => {
|
|||
|
|
let startup = PlatformStartup::new(&config.config);
|
|||
|
|
assert!(startup.is_ok());
|
|||
|
|
|
|||
|
|
let startup = startup.unwrap();
|
|||
|
|
|
|||
|
|
// Core services should be checkable
|
|||
|
|
for service in &["orchestrator", "vault_service"] {
|
|||
|
|
let enabled = startup.is_service_enabled(service);
|
|||
|
|
println!(
|
|||
|
|
" • {}: {}",
|
|||
|
|
service,
|
|||
|
|
if enabled { "enabled" } else { "disabled" }
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
println!("✓ Service enablement checking works");
|
|||
|
|
}
|
|||
|
|
Err(e) => {
|
|||
|
|
eprintln!("ℹ Deployment mode not found (expected in CI): {}", e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|