🚀Transform your business with AI-powered process optimization
Technical Specifications
⚙️ Configuration Management
🧪 Test-Driven Development Plan

Configuration Management Test Plan

This comprehensive test plan follows Test-Driven Development (TDD) principles to ensure systematic testing of all Configuration Management functionalities. The plan covers unit tests, integration tests, performance tests, security tests, and end-to-end scenarios.

Test-Driven Development Strategy

TDD Cycle Implementation

Red-Green-Refactor Cycle:

  1. Red: Write failing tests first
  2. Green: Write minimal code to make tests pass
  3. Refactor: Improve code while keeping tests green

Test Pyramid Structure

Unit Test Specifications

1. Configuration Discovery Tests

1.1 Discovery Engine Tests

#[cfg(test)]
mod discovery_engine_tests {
    use super::*;
    use std::path::PathBuf;
    use tempfile::TempDir;
    use tokio::fs;
 
    #[tokio::test]
    async fn test_current_directory_discovery_toml_priority() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let config_dir = temp_dir.path();
        
        // Create multiple format files
        fs::write(config_dir.join("test-module.toml"), "[section]\nkey = \"toml_value\"").await.unwrap();
        fs::write(config_dir.join("test-module.yaml"), "section:\n  key: yaml_value").await.unwrap();
        fs::write(config_dir.join("test-module.json"), r#"{"section": {"key": "json_value"}}"#).await.unwrap();
        
        let handler = CurrentDirectoryHandler::new(vec![
            ConfigurationFormat::Toml,
            ConfigurationFormat::Yaml,
            ConfigurationFormat::Json,
        ]);
        
        // Act
        let result = handler.discover("test-module").await.unwrap();
        
        // Assert
        assert!(result.is_some());
        let files = result.unwrap();
        assert_eq!(files.len(), 1);
        assert_eq!(files[0].format, ConfigurationFormat::Toml);
        assert!(files[0].path.ends_with("test-module.toml"));
    }
 
    #[tokio::test]
    async fn test_discovery_chain_priority_order() {
        // Arrange
        let discovery = ConfigurationDiscovery::builder()
            .build()
            .unwrap();
        
        // Act & Assert - Test that current directory has highest priority
        // Implementation would test the full chain
    }
 
    #[tokio::test]
    async fn test_home_directory_discovery() {
        // Test ~/.sindhan directory discovery
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_environment_directory_discovery() {
        // Test SINDHAN_CONFIG_DIR environment variable
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_discovery_with_no_files_returns_default() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let handler = CurrentDirectoryHandler::new(vec![ConfigurationFormat::Toml]);
        
        // Act
        let result = handler.discover("nonexistent-module").await.unwrap();
        
        // Assert
        assert!(result.is_none());
    }
 
    #[tokio::test]
    async fn test_custom_search_path_discovery() {
        // Test custom search paths added via builder
        // Arrange, Act, Assert pattern
    }
}

1.2 File Format Detection Tests

#[cfg(test)]
mod format_detection_tests {
    use super::*;
 
    #[test]
    fn test_toml_format_detection() {
        // Arrange
        let toml_content = r#"
[database]
host = "localhost"
port = 5432
"#;
        let parser = TomlParser::new();
        
        // Act
        let can_parse = parser.can_parse(toml_content);
        
        // Assert
        assert!(can_parse);
    }
 
    #[test]
    fn test_yaml_format_detection() {
        // Arrange
        let yaml_content = r#"
database:
  host: localhost
  port: 5432
"#;
        let parser = YamlParser::new();
        
        // Act
        let can_parse = parser.can_parse(yaml_content);
        
        // Assert
        assert!(can_parse);
    }
 
    #[test]
    fn test_json_format_detection() {
        // Arrange
        let json_content = r#"
{
  "database": {
    "host": "localhost",
    "port": 5432
  }
}
"#;
        let parser = JsonParser::new();
        
        // Act
        let can_parse = parser.can_parse(json_content);
        
        // Assert
        assert!(can_parse);
    }
 
    #[test]
    fn test_format_detection_priority() {
        // Test that format detection follows priority order
        let factory = FormatParserFactory::new();
        // Test implementation
    }
}

2. Configuration Parsing Tests

2.1 TOML Parser Tests

#[cfg(test)]
mod toml_parser_tests {
    use super::*;
    use serde::{Deserialize, Serialize};
 
    #[derive(Debug, Deserialize, Serialize, PartialEq)]
    struct TestConfig {
        database: DatabaseConfig,
        logging: LoggingConfig,
    }
 
    #[derive(Debug, Deserialize, Serialize, PartialEq)]
    struct DatabaseConfig {
        host: String,
        port: u16,
        ssl: bool,
    }
 
    #[derive(Debug, Deserialize, Serialize, PartialEq)]
    struct LoggingConfig {
        level: String,
        file: Option<String>,
    }
 
    #[tokio::test]
    async fn test_parse_valid_toml() {
        // Arrange
        let toml_content = r#"
[database]
host = "localhost"
port = 5432
ssl = true
 
[logging]
level = "info"
file = "/var/log/app.log"
"#;
        let parser = TomlParser::new();
        
        // Act
        let result: Result<TestConfig> = parser.parse(toml_content).await;
        
        // Assert
        assert!(result.is_ok());
        let config = result.unwrap();
        assert_eq!(config.database.host, "localhost");
        assert_eq!(config.database.port, 5432);
        assert!(config.database.ssl);
        assert_eq!(config.logging.level, "info");
        assert_eq!(config.logging.file, Some("/var/log/app.log".to_string()));
    }
 
    #[tokio::test]
    async fn test_parse_invalid_toml_syntax() {
        // Arrange
        let invalid_toml = r#"
[database
host = "localhost"
"#;
        let parser = TomlParser::new();
        
        // Act
        let result: Result<TestConfig> = parser.parse(invalid_toml).await;
        
        // Assert
        assert!(result.is_err());
        let error_message = result.unwrap_err().to_string();
        assert!(error_message.contains("Failed to parse TOML"));
    }
 
    #[tokio::test]
    async fn test_parse_missing_required_fields() {
        // Test parsing with missing required fields
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_parse_type_mismatch() {
        // Test parsing with type mismatches
        // Arrange, Act, Assert pattern
    }
}

2.2 YAML Parser Tests

#[cfg(test)]
mod yaml_parser_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_parse_valid_yaml() {
        // Arrange
        let yaml_content = r#"
database:
  host: localhost
  port: 5432
  ssl: true
logging:
  level: info
  file: /var/log/app.log
"#;
        let parser = YamlParser::new();
        
        // Act
        let result: Result<TestConfig> = parser.parse(yaml_content).await;
        
        // Assert
        assert!(result.is_ok());
        // Additional assertions...
    }
 
    #[tokio::test]
    async fn test_parse_yaml_with_arrays() {
        // Test YAML arrays parsing
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_parse_yaml_with_null_values() {
        // Test YAML null values
        // Arrange, Act, Assert pattern
    }
}

2.3 JSON Parser Tests

#[cfg(test)]
mod json_parser_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_parse_valid_json() {
        // Similar structure to TOML/YAML tests
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_parse_json_with_nested_objects() {
        // Test deeply nested JSON structures
        // Arrange, Act, Assert pattern
    }
}

3. Configuration Merging Tests

3.1 Deep Merge Strategy Tests

#[cfg(test)]
mod deep_merge_tests {
    use super::*;
 
    #[test]
    fn test_deep_merge_nested_objects() {
        // Arrange
        let base_config = TestConfig {
            database: DatabaseConfig {
                host: "localhost".to_string(),
                port: 5432,
                ssl: false,
            },
            logging: LoggingConfig {
                level: "warn".to_string(),
                file: None,
            },
        };
 
        let override_config = TestConfig {
            database: DatabaseConfig {
                host: "remote".to_string(),
                port: 5432, // Same value
                ssl: true,  // Override
            },
            logging: LoggingConfig {
                level: "warn".to_string(), // Same value
                file: Some("/var/log/override.log".to_string()), // New value
            },
        };
 
        let strategy = DeepMergeStrategy;
 
        // Act
        let result = strategy.merge(base_config, override_config).unwrap();
 
        // Assert
        assert_eq!(result.database.host, "remote");
        assert_eq!(result.database.port, 5432);
        assert!(result.database.ssl);
        assert_eq!(result.logging.level, "warn");
        assert_eq!(result.logging.file, Some("/var/log/override.log".to_string()));
    }
 
    #[test]
    fn test_deep_merge_array_handling() {
        // Test array merging behavior
        // Arrange, Act, Assert pattern
    }
 
    #[test]
    fn test_deep_merge_null_values() {
        // Test null value handling
        // Arrange, Act, Assert pattern
    }
}

3.2 Shallow Merge Strategy Tests

#[cfg(test)]
mod shallow_merge_tests {
    use super::*;
 
    #[test]
    fn test_shallow_merge_replaces_entire_sections() {
        // Test that shallow merge replaces entire sections
        // Arrange, Act, Assert pattern
    }
}

3.3 Array Append Strategy Tests

#[cfg(test)]
mod array_append_tests {
    use super::*;
 
    #[test]
    fn test_array_append_combines_arrays() {
        // Test array combination behavior
        // Arrange, Act, Assert pattern
    }
}

4. Validation Tests

4.1 Validation Pipeline Tests

#[cfg(test)]
mod validation_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_required_field_validation_success() {
        // Arrange
        let config = TestConfig {
            database: DatabaseConfig {
                host: "localhost".to_string(),
                port: 5432,
                ssl: true,
            },
            logging: LoggingConfig {
                level: "info".to_string(),
                file: None,
            },
        };
 
        let validator = RequiredFieldValidator::new("database.host".to_string());
 
        // Act
        let result = validator.validate(&config);
 
        // Assert
        assert!(result.is_ok());
        let validation_result = result.unwrap();
        assert_eq!(validation_result.severity, ValidationSeverity::Info);
    }
 
    #[tokio::test]
    async fn test_required_field_validation_failure() {
        // Test missing required field
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_range_validation_within_bounds() {
        // Arrange
        let config = TestConfig {
            database: DatabaseConfig {
                host: "localhost".to_string(),
                port: 5432,
                ssl: true,
            },
            logging: LoggingConfig {
                level: "info".to_string(),
                file: None,
            },
        };
 
        let validator = RangeValidator::new("database.port".to_string(), 1.0, 65535.0);
 
        // Act
        let result = validator.validate(&config);
 
        // Assert
        assert!(result.is_ok());
        let validation_result = result.unwrap();
        assert_eq!(validation_result.severity, ValidationSeverity::Info);
    }
 
    #[tokio::test]
    async fn test_range_validation_out_of_bounds() {
        // Test value outside allowed range
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_validation_pipeline_multiple_rules() {
        // Test multiple validation rules in pipeline
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_validation_pipeline_early_termination() {
        // Test pipeline behavior on critical errors
        // Arrange, Act, Assert pattern
    }
}

5. Schema Manager Tests

5.1 Schema Discovery Tests

#[cfg(test)]
mod schema_discovery_tests {
    use super::*;
    use tempfile::TempDir;
    use tokio::fs;
 
    #[tokio::test]
    async fn test_schema_discovery_priority_order() {
        // Arrange - Create schemas in multiple locations
        let temp_dir = TempDir::new().unwrap();
        let project_schema_dir = temp_dir.path().join("schemas");
        let user_schema_dir = temp_dir.path().join(".sindhan/schemas");
        let system_schema_dir = temp_dir.path().join("system/schemas");
        
        fs::create_dir_all(&project_schema_dir).await.unwrap();
        fs::create_dir_all(&user_schema_dir).await.unwrap();
        fs::create_dir_all(&system_schema_dir).await.unwrap();
        
        // Create different schemas with priority conflicts
        fs::write(project_schema_dir.join("test-module.schema.toml"), r#"
[schema]
name = "test-module"
version = "1.0.0"
description = "Project Schema"
 
[config.priority]
type = "string"
default = "project"
"#).await.unwrap();
        
        fs::write(user_schema_dir.join("test-module.schema.toml"), r#"
[schema]
name = "test-module"
version = "1.1.0"
description = "User Schema"
 
[config.priority]
type = "string"
default = "user"
"#).await.unwrap();
        
        fs::write(system_schema_dir.join("test-module.schema.toml"), r#"
[schema]
name = "test-module"
version = "1.2.0"
description = "System Schema"
 
[config.priority]
type = "string"
default = "system"
"#).await.unwrap();
        
        std::env::set_var("SINDHAN_SCHEMA_DIR", system_schema_dir.parent().unwrap());
        
        let discovery = SchemaDiscoveryEngine::builder()
            .add_project_search_path(project_schema_dir.parent().unwrap().to_path_buf())
            .add_user_search_path(user_schema_dir.parent().unwrap().to_path_buf())
            .build()
            .unwrap();
        
        // Act
        let discovered_files = discovery.discover_schema_files("test-module").await.unwrap();
        
        // Assert - Project schema should have highest priority
        assert!(!discovered_files.is_empty());
        let primary_schema = discovered_files.iter().min_by_key(|f| f.priority).unwrap();
        assert_eq!(primary_schema.source, SchemaSource::Project);
        
        // Cleanup
        std::env::remove_var("SINDHAN_SCHEMA_DIR");
    }
    
    #[tokio::test]
    async fn test_schema_format_precedence() {
        // Arrange - Create multiple format schemas
        let temp_dir = TempDir::new().unwrap();
        let schema_dir = temp_dir.path().join("schemas");
        fs::create_dir_all(&schema_dir).await.unwrap();
        
        // Create schemas in different formats
        fs::write(schema_dir.join("test-module.schema.toml"), "# TOML schema").await.unwrap();
        fs::write(schema_dir.join("test-module.schema.yaml"), "# YAML schema").await.unwrap();
        fs::write(schema_dir.join("test-module.schema.json"), "# JSON schema").await.unwrap();
        
        let discovery = SchemaDiscoveryEngine::builder()
            .add_project_search_path(schema_dir.parent().unwrap().to_path_buf())
            .build()
            .unwrap();
        
        // Act
        let discovered_files = discovery.discover_schema_files("test-module").await.unwrap();
        
        // Assert - TOML should be preferred
        assert!(!discovered_files.is_empty());
        let primary_schema = discovered_files.iter().min_by_key(|f| f.priority).unwrap();
        assert_eq!(primary_schema.format, SchemaFormat::Toml);
    }
    
    #[tokio::test]
    async fn test_embedded_schema_fallback() {
        // Arrange - No external schemas, should fall back to embedded
        let discovery = SchemaDiscoveryEngine::builder()
            .enable_embedded_schemas(true)
            .build()
            .unwrap();
        
        // Act
        let discovered_files = discovery.discover_schema_files("agent-identity").await.unwrap();
        
        // Assert - Should find embedded schema
        assert!(!discovered_files.is_empty());
        let embedded_schema = discovered_files.iter().find(|f| f.source == SchemaSource::Embedded).unwrap();
        assert!(embedded_schema.path.to_string_lossy().starts_with("embedded://"));
    }
    
    #[tokio::test]
    async fn test_schema_discovery_with_custom_naming() {
        // Test various module naming conventions
        let test_cases = vec![
            ("agent-identity", "agent-identity.schema.toml"),
            ("agent_identity", "agent-identity.schema.toml"),
            ("AgentIdentity", "agent-identity.schema.toml"),
            ("sindhan::agent::identity", "agent-identity.schema.toml"),
        ];
        
        for (module_name, expected_file) in test_cases {
            // Test module name resolution
            let resolved_name = SchemaDiscoveryEngine::resolve_module_name(module_name);
            assert_eq!(resolved_name, "agent-identity");
        }
    }
}

5.2 Schema Loading and Validation Tests

#[cfg(test)]
mod schema_loading_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_schema_loading_with_metadata() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let schema_path = temp_dir.path().join("test-module.schema.toml");
        
        let schema_content = r#"
[schema]
name = "test-module"
version = "1.2.0"
compatible_versions = ["^1.0.0"]
description = "Test Module Schema"
author = "Sindhan AI Platform"
created = "2024-01-15T10:30:00Z"
last_modified = "2024-03-20T14:45:00Z"
tags = ["test", "module"]
 
[schema.dependencies]
required_schemas = ["global"]
optional_schemas = ["logging"]
 
[config.database]
type = "object"
required = true
description = "Database configuration"
 
[config.database.fields.host]
type = "string"
required = true
default = "localhost"
validation = "hostname"
description = "Database host"
"#;
        fs::write(&schema_path, schema_content).await.unwrap();
        
        let loader = SchemaLoader::new();
        
        // Act
        let schema_definition = loader.load_schema_file(&schema_path).await.unwrap();
        
        // Assert
        assert_eq!(schema_definition.metadata.name, "test-module");
        assert_eq!(schema_definition.metadata.version.to_string(), "1.2.0");
        assert_eq!(schema_definition.metadata.dependencies.required_schemas, vec!["global"]);
        assert!(schema_definition.config_structure.sections.contains_key("database"));
    }
    
    #[tokio::test]
    async fn test_schema_inheritance_processing() {
        // Arrange - Create parent and child schemas
        let temp_dir = TempDir::new().unwrap();
        let schema_dir = temp_dir.path().join("schemas");
        fs::create_dir_all(&schema_dir).await.unwrap();
        
        // Parent schema
        fs::write(schema_dir.join("base.schema.toml"), r#"
[schema]
name = "base"
version = "1.0.0"
description = "Base Schema"
 
[config.common]
type = "object"
required = true
 
[config.common.fields.name]
type = "string"
required = true
default = "default-name"
 
[config.common.fields.enabled]
type = "boolean"
default = true
"#).await.unwrap();
        
        // Child schema with inheritance
        fs::write(schema_dir.join("child.schema.toml"), r#"
[schema]
name = "child"
version = "1.0.0"
description = "Child Schema"
 
[schema.inheritance]
parent_schema = "base"
override_mode = "deep_merge"
 
[config.common.fields.version]
type = "string"
required = true
default = "1.0.0"
 
[config.specific]
type = "object"
required = true
 
[config.specific.fields.feature]
type = "boolean"
default = false
"#).await.unwrap();
        
        let schema_manager = SchemaManager::new(
            SchemaDiscoveryEngine::builder()
                .add_project_search_path(schema_dir.parent().unwrap().to_path_buf())
                .build().unwrap(),
            SchemaLoader::new(),
            SchemaValidator::new(),
        );
        
        // Act
        let final_schema = schema_manager.load_schema("child").await.unwrap();
        
        // Assert - Should have merged parent and child schemas
        assert!(final_schema.config_structure.sections.contains_key("common"));
        assert!(final_schema.config_structure.sections.contains_key("specific"));
        
        let common_section = &final_schema.config_structure.sections["common"];
        assert!(common_section.fields.contains_key("name"));     // From parent
        assert!(common_section.fields.contains_key("enabled"));  // From parent
        assert!(common_section.fields.contains_key("version"));  // From child
    }
    
    #[tokio::test]
    async fn test_schema_validation_errors() {
        // Arrange - Invalid schema content
        let temp_dir = TempDir::new().unwrap();
        let schema_path = temp_dir.path().join("invalid.schema.toml");
        
        let invalid_schema = r#"
[schema]
# Missing required name field
version = "1.0.0"
 
[config.invalid_field]
type = "unsupported_type"
"#;
        fs::write(&schema_path, invalid_schema).await.unwrap();
        
        let loader = SchemaLoader::new();
        
        // Act
        let result = loader.load_schema_file(&schema_path).await;
        
        // Assert
        assert!(result.is_err());
        let error_message = result.unwrap_err().to_string();
        assert!(error_message.contains("schema validation failed") || error_message.contains("missing required field"));
    }
    
    #[tokio::test]
    async fn test_schema_dependency_resolution() {
        // Arrange - Schema with dependencies
        let temp_dir = TempDir::new().unwrap();
        let schema_dir = temp_dir.path().join("schemas");
        fs::create_dir_all(&schema_dir).await.unwrap();
        
        // Dependency schema
        fs::write(schema_dir.join("logging.schema.toml"), r#"
[schema]
name = "logging"
version = "1.0.0"
description = "Logging Schema"
 
[config.logging]
type = "object"
required = true
 
[config.logging.fields.level]
type = "enum"
values = ["debug", "info", "warn", "error"]
default = "info"
"#).await.unwrap();
        
        // Main schema with dependency
        fs::write(schema_dir.join("main.schema.toml"), r#"
[schema]
name = "main"
version = "1.0.0"
description = "Main Schema"
 
[schema.dependencies]
required_schemas = ["logging"]
 
[config.app]
type = "object"
required = true
 
[config.app.fields.name]
type = "string"
default = "my-app"
"#).await.unwrap();
        
        let schema_manager = SchemaManager::new(
            SchemaDiscoveryEngine::builder()
                .add_project_search_path(schema_dir.parent().unwrap().to_path_buf())
                .build().unwrap(),
            SchemaLoader::new(),
            SchemaValidator::new(),
        );
        
        // Act
        let schema = schema_manager.load_schema("main").await.unwrap();
        
        // Assert - Dependencies should be resolved
        assert_eq!(schema.metadata.dependencies.required_schemas, vec!["logging"]);
        // Dependency validation would be done by the validator
    }
}

5.3 Schema Cache Tests

#[cfg(test)]
mod schema_cache_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_schema_caching_behavior() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let schema_path = temp_dir.path().join("schemas/cached-module.schema.toml");
        fs::create_dir_all(schema_path.parent().unwrap()).await.unwrap();
        
        fs::write(&schema_path, r#"
[schema]
name = "cached-module"
version = "1.0.0"
description = "Cached Schema"
 
[config.test]
type = "string"
default = "original"
"#).await.unwrap();
        
        let schema_manager = SchemaManager::new(
            SchemaDiscoveryEngine::builder()
                .add_project_search_path(temp_dir.path().to_path_buf())
                .build().unwrap(),
            SchemaLoader::new(),
            SchemaValidator::new(),
        );
        
        // Act - First load
        let start_time = std::time::Instant::now();
        let schema1 = schema_manager.load_schema("cached-module").await.unwrap();
        let first_load_time = start_time.elapsed();
        
        // Act - Second load (should be cached)
        let start_time = std::time::Instant::now();
        let schema2 = schema_manager.load_schema("cached-module").await.unwrap();
        let second_load_time = start_time.elapsed();
        
        // Assert
        assert_eq!(schema1.metadata.name, schema2.metadata.name);
        assert!(second_load_time < first_load_time); // Cached should be faster
    }
    
    #[tokio::test]
    async fn test_schema_cache_invalidation() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let schema_path = temp_dir.path().join("schemas/invalidation-test.schema.toml");
        fs::create_dir_all(schema_path.parent().unwrap()).await.unwrap();
        
        let original_content = r#"
[schema]
name = "invalidation-test"
version = "1.0.0"
description = "Original Schema"
 
[config.value]
type = "string"
default = "original"
"#;
        fs::write(&schema_path, original_content).await.unwrap();
        
        let schema_manager = SchemaManager::new(
            SchemaDiscoveryEngine::builder()
                .add_project_search_path(temp_dir.path().to_path_buf())
                .build().unwrap(),
            SchemaLoader::new(),
            SchemaValidator::new(),
        );
        
        // Act - Load original
        let original_schema = schema_manager.load_schema("invalidation-test").await.unwrap();
        
        // Simulate cache expiration by waiting
        tokio::time::sleep(tokio::time::Duration::from_millis(400)).await;
        
        // Update schema file
        let updated_content = r#"
[schema]
name = "invalidation-test"
version = "1.1.0"
description = "Updated Schema"
 
[config.value]
type = "string"
default = "updated"
"#;
        fs::write(&schema_path, updated_content).await.unwrap();
        
        // Act - Load again (cache should be invalidated)
        let updated_schema = schema_manager.load_schema("invalidation-test").await.unwrap();
        
        // Assert
        assert_eq!(original_schema.metadata.version.to_string(), "1.0.0");
        assert_eq!(updated_schema.metadata.version.to_string(), "1.1.0");
    }
}

6. Hot Reload Tests

6.1 File System Monitoring Tests

#[cfg(test)]
mod hot_reload_tests {
    use super::*;
    use std::sync::Arc;
    use tokio::sync::Notify;
    use std::time::Duration;
 
    #[tokio::test]
    async fn test_configuration_file_modification_detection() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let config_path = temp_dir.path().join("hot-reload-test.toml");
        
        let initial_content = r#"
[database]
host = "localhost"
port = 5432
ssl = false
 
[logging]
level = "info"
"#;
        fs::write(&config_path, initial_content).await.unwrap();
        
        let change_notifier = Arc::new(Notify::new());
        let change_notifier_clone = change_notifier.clone();
        
        let hot_reload_manager = HotReloadManager::new(
            vec![temp_dir.path().to_path_buf()],
            Box::new(move |change_event| {
                let notifier = change_notifier_clone.clone();
                Box::pin(async move {
                    println!("Configuration change detected: {:?}", change_event);
                    notifier.notify_one();
                    Ok(())
                })
            })
        ).await.unwrap();
        
        // Act - Modify configuration file
        let updated_content = r#"
[database]
host = "localhost"
port = 5432
ssl = true  # Changed from false to true
 
[logging]
level = "debug"  # Changed from info to debug
"#;
        fs::write(&config_path, updated_content).await.unwrap();
        
        // Wait for change detection
        tokio::time::timeout(Duration::from_secs(5), change_notifier.notified())
            .await
            .expect("Change should be detected within 5 seconds");
        
        // Assert - Verification happens through the callback
        assert!(true); // If we reach here, change was detected
    }
    
    #[tokio::test]
    async fn test_configuration_hot_reload_validation() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let config_path = temp_dir.path().join("validation-test.toml");
        
        let valid_content = r#"
[database]
host = "localhost"
port = 5432
ssl = true
"#;
        fs::write(&config_path, valid_content).await.unwrap();
        
        let config_manager = ConfigurationManager::<TestConfigSchema>::builder()
            .with_discovery(ConfigurationDiscovery::builder()
                .add_search_path(temp_dir.path().to_path_buf())
                .enable_hot_reload()
                .build().unwrap()
            )
            .build()
            .await
            .unwrap();
        
        // Load initial configuration
        config_manager.load_configuration().await.unwrap();
        
        // Act - Update with invalid configuration
        let invalid_content = r#"
[database]
host = "localhost"
port = 99999  # Invalid port number
ssl = "invalid_boolean"  # Invalid boolean value
"#;
        fs::write(&config_path, invalid_content).await.unwrap();
        
        // Wait for hot reload attempt
        tokio::time::sleep(Duration::from_millis(500)).await;
        
        // Assert - Configuration should remain unchanged due to validation failure
        let current_config = config_manager.get_configuration().await;
        assert_eq!(current_config.database.port, 5432); // Should still be original value
        assert!(current_config.database.ssl); // Should still be original value
    }
    
    #[tokio::test]
    async fn test_hot_reload_rollback_on_error() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let config_path = temp_dir.path().join("rollback-test.toml");
        
        let working_content = r#"
[database]
host = "localhost"
port = 5432
ssl = true
 
[logging]
level = "info"
"#;
        fs::write(&config_path, working_content).await.unwrap();
        
        let mut error_observer = MockConfigurationObserver::new();
        
        let config_manager = ConfigurationManager::<TestConfigSchema>::builder()
            .with_discovery(ConfigurationDiscovery::builder()
                .add_search_path(temp_dir.path().to_path_buf())
                .enable_hot_reload()
                .build().unwrap()
            )
            .add_observer(Arc::new(error_observer.clone()))
            .build()
            .await
            .unwrap();
        
        // Load initial configuration
        config_manager.load_configuration().await.unwrap();
        let original_config = config_manager.get_configuration().await;
        
        // Act - Update with syntactically invalid configuration
        let broken_content = r#"
[database
host = "localhost"  # Missing closing bracket
port = 5432
"#;
        fs::write(&config_path, broken_content).await.unwrap();
        
        // Wait for hot reload attempt and rollback
        tokio::time::sleep(Duration::from_millis(1000)).await;
        
        // Assert - Configuration should be rolled back to previous working state
        let current_config = config_manager.get_configuration().await;
        assert_eq!(current_config.database.host, original_config.database.host);
        assert_eq!(current_config.database.port, original_config.database.port);
        
        // Check that error was reported to observer
        let notifications = error_observer.get_notifications().await;
        assert!(!notifications.is_empty());
    }
    
    #[tokio::test]
    async fn test_hot_reload_performance_impact() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let config_path = temp_dir.path().join("performance-test.toml");
        
        let initial_content = r#"
[database]
host = "localhost"
port = 5432
"#;
        fs::write(&config_path, initial_content).await.unwrap();
        
        let config_manager = ConfigurationManager::<TestConfigSchema>::builder()
            .with_discovery(ConfigurationDiscovery::builder()
                .add_search_path(temp_dir.path().to_path_buf())
                .enable_hot_reload()
                .build().unwrap()
            )
            .build()
            .await
            .unwrap();
        
        config_manager.load_configuration().await.unwrap();
        
        // Measure baseline configuration access performance
        let start_time = std::time::Instant::now();
        for _ in 0..1000 {
            let _ = config_manager.get_configuration().await;
        }
        let baseline_duration = start_time.elapsed();
        
        // Act - Trigger multiple hot reloads
        for i in 0..10 {
            let content = format!(r#"
[database]
host = "localhost"
port = {}
"#, 5432 + i);
            fs::write(&config_path, content).await.unwrap();
            tokio::time::sleep(Duration::from_millis(100)).await;
        }
        
        // Measure performance after hot reloads
        let start_time = std::time::Instant::now();
        for _ in 0..1000 {
            let _ = config_manager.get_configuration().await;
        }
        let post_reload_duration = start_time.elapsed();
        
        // Assert - Performance should not be significantly degraded
        let performance_ratio = post_reload_duration.as_nanos() as f64 / baseline_duration.as_nanos() as f64;
        assert!(performance_ratio < 2.0, "Hot reload should not degrade performance by more than 2x");
    }
    
    #[tokio::test]
    async fn test_hot_reload_concurrency_safety() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let config_path = temp_dir.path().join("concurrency-test.toml");
        
        let initial_content = r#"
[database]
host = "localhost"
port = 5432
"#;
        fs::write(&config_path, initial_content).await.unwrap();
        
        let config_manager = Arc::new(
            ConfigurationManager::<TestConfigSchema>::builder()
                .with_discovery(ConfigurationDiscovery::builder()
                    .add_search_path(temp_dir.path().to_path_buf())
                    .enable_hot_reload()
                    .build().unwrap()
                )
                .build()
                .await
                .unwrap()
        );
        
        config_manager.load_configuration().await.unwrap();
        
        // Act - Spawn multiple concurrent tasks accessing configuration during reloads
        let mut handles = Vec::new();
        
        // Concurrent configuration readers
        for i in 0..5 {
            let manager = config_manager.clone();
            let handle = tokio::spawn(async move {
                for _ in 0..100 {
                    let config = manager.get_configuration().await;
                    assert_eq!(config.database.host, "localhost");
                    tokio::time::sleep(Duration::from_millis(10)).await;
                }
                i
            });
            handles.push(handle);
        }
        
        // Concurrent configuration updater
        let config_path_clone = config_path.clone();
        let update_handle = tokio::spawn(async move {
            for i in 0..20 {
                let content = format!(r#"
[database]
host = "localhost"
port = {}
ssl = {}
"#, 5432 + i, i % 2 == 0);
                fs::write(&config_path_clone, content).await.unwrap();
                tokio::time::sleep(Duration::from_millis(50)).await;
            }
        });
        
        // Assert - All tasks should complete without errors
        for handle in handles {
            handle.await.unwrap();
        }
        update_handle.await.unwrap();
    }
    
    #[tokio::test]
    async fn test_schema_hot_reload() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let schema_path = temp_dir.path().join("schemas/hot-reload-schema.schema.toml");
        let config_path = temp_dir.path().join("hot-reload-schema.toml");
        
        fs::create_dir_all(schema_path.parent().unwrap()).await.unwrap();
        
        let initial_schema = r#"
[schema]
name = "hot-reload-schema"
version = "1.0.0"
description = "Initial Schema"
 
[config.database]
type = "object"
required = true
 
[config.database.fields.host]
type = "string"
required = true
default = "localhost"
"#;
        fs::write(&schema_path, initial_schema).await.unwrap();
        
        let initial_config = r#"
[database]
host = "localhost"
"#;
        fs::write(&config_path, initial_config).await.unwrap();
        
        let schema_manager = SchemaManager::new(
            SchemaDiscoveryEngine::builder()
                .add_project_search_path(temp_dir.path().to_path_buf())
                .enable_hot_reload()
                .build().unwrap(),
            SchemaLoader::new(),
            SchemaValidator::new(),
        );
        
        // Load initial schema
        let original_schema = schema_manager.load_schema("hot-reload-schema").await.unwrap();
        assert_eq!(original_schema.metadata.version.to_string(), "1.0.0");
        
        // Act - Update schema file
        let updated_schema = r#"
[schema]
name = "hot-reload-schema"
version = "1.1.0"
description = "Updated Schema"
 
[config.database]
type = "object"
required = true
 
[config.database.fields.host]
type = "string"
required = true
default = "localhost"
 
[config.database.fields.port]
type = "integer"
required = false
default = 5432
"#;
        fs::write(&schema_path, updated_schema).await.unwrap();
        
        // Wait for schema hot reload
        tokio::time::sleep(Duration::from_millis(500)).await;
        
        // Act - Load schema again (should get updated version)
        let reloaded_schema = schema_manager.load_schema("hot-reload-schema").await.unwrap();
        
        // Assert
        assert_eq!(reloaded_schema.metadata.version.to_string(), "1.1.0");
        assert!(reloaded_schema.config_structure.sections["database"]
            .fields.contains_key("port")); // New field should be present
    }
}

6.2 Hot Reload Integration Tests

#[cfg(test)]
mod hot_reload_integration_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_end_to_end_hot_reload_workflow() {
        // Arrange - Complete hot reload setup
        let temp_dir = TempDir::new().unwrap();
        let schema_dir = temp_dir.path().join("schemas");
        let config_path = temp_dir.path().join("e2e-test.toml");
        
        fs::create_dir_all(&schema_dir).await.unwrap();
        
        // Create schema
        fs::write(schema_dir.join("e2e-test.schema.toml"), r#"
[schema]
name = "e2e-test"
version = "1.0.0"
description = "End-to-End Test Schema"
 
[config.server]
type = "object"
required = true
 
[config.server.fields.host]
type = "string"
default = "localhost"
 
[config.server.fields.port]
type = "integer"
default = 8080
range = { min = 1, max = 65535 }
 
[config.server.fields.enabled]
type = "boolean"
default = true
"#).await.unwrap();
        
        // Create initial configuration
        fs::write(&config_path, r#"
[server]
host = "localhost"
port = 8080
enabled = true
"#).await.unwrap();
        
        let change_events = Arc::new(tokio::sync::Mutex::new(Vec::new()));
        let change_events_clone = change_events.clone();
        
        // Create configuration manager with hot reload
        let config_manager = ConfigurationManager::<E2ETestConfigSchema>::builder()
            .with_discovery(ConfigurationDiscovery::builder()
                .add_search_path(temp_dir.path().to_path_buf())
                .enable_hot_reload()
                .build().unwrap()
            )
            .add_observer(Arc::new(TestConfigurationObserver::new(change_events_clone)))
            .build()
            .await
            .unwrap();
        
        // Load initial configuration
        config_manager.load_configuration().await.unwrap();
        let initial_config = config_manager.get_configuration().await;
        assert_eq!(initial_config.server.port, 8080);
        
        // Act - Stage 1: Valid configuration update
        fs::write(&config_path, r#"
[server]
host = "0.0.0.0"
port = 9090
enabled = true
"#).await.unwrap();
        
        // Wait for hot reload
        tokio::time::sleep(Duration::from_millis(1000)).await;
        
        let updated_config = config_manager.get_configuration().await;
        assert_eq!(updated_config.server.host, "0.0.0.0");
        assert_eq!(updated_config.server.port, 9090);
        
        // Act - Stage 2: Invalid configuration update (should be rejected)
        fs::write(&config_path, r#"
[server]
host = "0.0.0.0"
port = 99999  # Invalid port
enabled = "not_a_boolean"  # Invalid boolean
"#).await.unwrap();
        
        // Wait for hot reload attempt
        tokio::time::sleep(Duration::from_millis(1000)).await;
        
        // Configuration should remain unchanged
        let current_config = config_manager.get_configuration().await;
        assert_eq!(current_config.server.host, "0.0.0.0");  // From previous valid update
        assert_eq!(current_config.server.port, 9090);       // From previous valid update
        
        // Act - Stage 3: Fix configuration
        fs::write(&config_path, r#"
[server]
host = "127.0.0.1"
port = 3000
enabled = false
"#).await.unwrap();
        
        // Wait for hot reload
        tokio::time::sleep(Duration::from_millis(1000)).await;
        
        let final_config = config_manager.get_configuration().await;
        assert_eq!(final_config.server.host, "127.0.0.1");
        assert_eq!(final_config.server.port, 3000);
        assert!(!final_config.server.enabled);
        
        // Assert - Check change events were recorded
        let events = change_events.lock().await;
        assert!(events.len() >= 2); // At least 2 successful changes
    }
    
    #[tokio::test]
    async fn test_hot_reload_with_multiple_configuration_files() {
        // Test hot reload behavior with hierarchical configuration merging
        // Arrange, Act, Assert pattern for complex scenarios
        todo!("Implement multi-file hot reload test");
    }
    
    #[tokio::test]
    async fn test_hot_reload_resource_cleanup() {
        // Test that hot reload properly cleans up resources
        // Arrange, Act, Assert pattern for resource management
        todo!("Implement resource cleanup test");
    }
}

7. Configuration Manager Tests

5.1 Configuration Loading Tests

#[cfg(test)]
mod configuration_manager_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_load_configuration_success() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        let config_path = temp_dir.path().join("test-module.toml");
        
        let config_content = r#"
[database]
host = "localhost"
port = 5432
ssl = true
 
[logging]
level = "info"
"#;
        fs::write(&config_path, config_content).await.unwrap();
 
        let discovery = ConfigurationDiscovery::builder()
            .add_search_path(temp_dir.path().to_path_buf())
            .build()
            .unwrap();
 
        let manager = ConfigurationManager::<TestConfigSchema>::builder()
            .with_discovery(ConfigurationDiscovery::builder())
            .build()
            .await
            .unwrap();
 
        // Act
        let result = manager.load_configuration().await;
 
        // Assert
        assert!(result.is_ok());
        let config = manager.get_configuration().await;
        assert_eq!(config.database.host, "localhost");
    }
 
    #[tokio::test]
    async fn test_load_configuration_validation_failure() {
        // Test configuration loading with validation failures
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_update_configuration_success() {
        // Test configuration updates
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_configuration_observer_notifications() {
        // Test observer pattern notifications
        // Arrange, Act, Assert pattern
    }
}

8. Builder Pattern Tests

6.1 Configuration Discovery Builder Tests

#[cfg(test)]
mod builder_tests {
    use super::*;
 
    #[test]
    fn test_discovery_builder_default_configuration() {
        // Arrange & Act
        let discovery = ConfigurationDiscovery::builder()
            .build()
            .unwrap();
 
        // Assert
        assert_eq!(discovery.discovery_chain.len(), 3); // Current, Home, Environment
    }
 
    #[test]
    fn test_discovery_builder_custom_search_paths() {
        // Arrange & Act
        let discovery = ConfigurationDiscovery::builder()
            .add_search_path(PathBuf::from("/custom/path1"))
            .add_search_path(PathBuf::from("/custom/path2"))
            .build()
            .unwrap();
 
        // Assert
        assert_eq!(discovery.discovery_chain.len(), 5); // 3 default + 2 custom
    }
 
    #[test]
    fn test_discovery_builder_format_precedence() {
        // Test custom format precedence
        // Arrange, Act, Assert pattern
    }
 
    #[test]
    fn test_configuration_manager_builder() {
        // Test configuration manager builder
        // Arrange, Act, Assert pattern
    }
}

Integration Test Specifications

1. End-to-End Configuration Flow Tests

#[cfg(test)]
mod integration_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_complete_configuration_workflow() {
        // Arrange
        let temp_dir = TempDir::new().unwrap();
        
        // Create configuration files in different locations
        let current_dir = temp_dir.path().join("current");
        let home_dir = temp_dir.path().join("home/.sindhan");
        let env_dir = temp_dir.path().join("env");
        
        fs::create_dir_all(&current_dir).await.unwrap();
        fs::create_dir_all(&home_dir).await.unwrap();
        fs::create_dir_all(&env_dir).await.unwrap();
 
        // Create base configuration in environment directory
        fs::write(env_dir.join("test-module.toml"), r#"
[database]
host = "env-host"
port = 5432
ssl = false
 
[logging]
level = "warn"
"#).await.unwrap();
 
        // Create override configuration in home directory
        fs::write(home_dir.join("test-module.toml"), r#"
[database]
ssl = true
 
[logging]
level = "info"
file = "/home/user/app.log"
"#).await.unwrap();
 
        // Set environment variable
        std::env::set_var("SINDHAN_CONFIG_DIR", env_dir.to_str().unwrap());
 
        let discovery = ConfigurationDiscovery::builder()
            .add_search_path(current_dir)
            .build()
            .unwrap();
 
        let manager = ConfigurationManager::<TestConfigSchema>::builder()
            .with_discovery(ConfigurationDiscovery::builder())
            .build()
            .await
            .unwrap();
 
        // Act
        manager.load_configuration().await.unwrap();
        let config = manager.get_configuration().await;
 
        // Assert - Home directory should override environment directory
        assert_eq!(config.database.host, "env-host"); // From env
        assert_eq!(config.database.port, 5432); // From env
        assert!(config.database.ssl); // Overridden by home
        assert_eq!(config.logging.level, "info"); // Overridden by home
        assert_eq!(config.logging.file, Some("/home/user/app.log".to_string())); // From home
 
        // Cleanup
        std::env::remove_var("SINDHAN_CONFIG_DIR");
    }
 
    #[tokio::test]
    async fn test_configuration_hot_reload() {
        // Test hot-reload functionality
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_external_configuration_adapter() {
        // Test external configuration source integration
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_encrypted_configuration_decorator() {
        // Test encryption decorator integration
        // Arrange, Act, Assert pattern
    }
}

2. Cross-Module Integration Tests

#[cfg(test)]
mod cross_module_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_multiple_module_configurations() {
        // Test loading configurations for multiple modules
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_shared_configuration_sections() {
        // Test shared configuration between modules
        // Arrange, Act, Assert pattern
    }
}

Performance Test Specifications

1. Configuration Loading Performance Tests

#[cfg(test)]
mod performance_tests {
    use super::*;
    use std::time::Instant;
 
    #[tokio::test]
    async fn test_large_configuration_loading_performance() {
        // Arrange
        let large_config = generate_large_configuration(10000); // 10k entries
        let temp_dir = TempDir::new().unwrap();
        let config_path = temp_dir.path().join("large-config.toml");
        fs::write(&config_path, large_config).await.unwrap();
 
        let discovery = ConfigurationDiscovery::builder()
            .add_search_path(temp_dir.path().to_path_buf())
            .build()
            .unwrap();
 
        // Act
        let start = Instant::now();
        let result = discovery.discover_files("large-config").await;
        let duration = start.elapsed();
 
        // Assert
        assert!(result.is_ok());
        assert!(duration.as_millis() < 100); // Should load within 100ms
    }
 
    #[tokio::test]
    async fn test_concurrent_configuration_access() {
        // Test concurrent access performance
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_memory_usage_large_configurations() {
        // Test memory usage with large configurations
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_configuration_caching_performance() {
        // Test caching performance benefits
        // Arrange, Act, Assert pattern
    }
 
    fn generate_large_configuration(size: usize) -> String {
        let mut config = String::new();
        for i in 0..size {
            config.push_str(&format!("key_{} = \"value_{}\"\n", i, i));
        }
        config
    }
}

2. Memory Usage Tests

#[cfg(test)]
mod memory_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_memory_leak_detection() {
        // Test for memory leaks during configuration operations
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_configuration_cleanup() {
        // Test proper cleanup of configuration resources
        // Arrange, Act, Assert pattern
    }
}

Security Test Specifications

1. Configuration Security Tests

#[cfg(test)]
mod security_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_encrypted_field_handling() {
        // Arrange
        let config = TestConfig {
            database: DatabaseConfig {
                host: "localhost".to_string(),
                port: 5432,
                ssl: true,
            },
            logging: LoggingConfig {
                level: "info".to_string(),
                file: Some("secret-path".to_string()),
            },
        };
 
        let manager = Arc::new(ConfigurationManager::<TestConfigSchema>::builder()
            .build()
            .await
            .unwrap());
 
        let encrypted_decorator = EncryptedConfigurationDecorator::new(
            manager,
            vec![0u8; 32], // Test encryption key
            vec!["logging.file".to_string()],
        );
 
        // Act
        encrypted_decorator.update_configuration(config).await.unwrap();
        let retrieved_config = encrypted_decorator.get_configuration().await.unwrap();
 
        // Assert
        assert_eq!(retrieved_config.logging.file, Some("secret-path".to_string()));
    }
 
    #[tokio::test]
    async fn test_configuration_access_control() {
        // Test access control mechanisms
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_sensitive_data_detection() {
        // Test automatic sensitive data detection
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_configuration_tampering_detection() {
        // Test configuration integrity verification
        // Arrange, Act, Assert pattern
    }
}

2. Input Validation Security Tests

#[cfg(test)]
mod input_validation_security_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_malicious_configuration_rejection() {
        // Test rejection of malicious configuration inputs
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_path_traversal_prevention() {
        // Test prevention of path traversal attacks
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_configuration_size_limits() {
        // Test configuration size limit enforcement
        // Arrange, Act, Assert pattern
    }
}

Error Handling and Edge Case Tests

1. Error Handling Tests

#[cfg(test)]
mod error_handling_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_file_not_found_error_handling() {
        // Arrange
        let discovery = ConfigurationDiscovery::builder().build().unwrap();
 
        // Act
        let result = discovery.discover_files("nonexistent-module").await;
 
        // Assert
        assert!(result.is_ok());
        let files = result.unwrap();
        assert_eq!(files.len(), 1);
        assert_eq!(files[0].source, DiscoverySource::Default);
    }
 
    #[tokio::test]
    async fn test_permission_denied_error_handling() {
        // Test handling of permission denied errors
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_corrupted_configuration_handling() {
        // Test handling of corrupted configuration files
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_network_failure_handling() {
        // Test handling of network failures for external sources
        // Arrange, Act, Assert pattern
    }
}

2. Edge Case Tests

#[cfg(test)]
mod edge_case_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_empty_configuration_file() {
        // Test handling of empty configuration files
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_very_large_configuration_values() {
        // Test handling of very large configuration values
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_unicode_configuration_content() {
        // Test handling of Unicode content in configurations
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_circular_configuration_references() {
        // Test detection and handling of circular references
        // Arrange, Act, Assert pattern
    }
}

Compatibility and Platform Tests

1. Cross-Platform Tests

#[cfg(test)]
mod platform_tests {
    use super::*;
 
    #[tokio::test]
    #[cfg(target_os = "windows")]
    async fn test_windows_path_handling() {
        // Test Windows-specific path handling
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    #[cfg(target_os = "macos")]
    async fn test_macos_path_handling() {
        // Test macOS-specific path handling
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    #[cfg(target_os = "linux")]
    async fn test_linux_path_handling() {
        // Test Linux-specific path handling
        // Arrange, Act, Assert pattern
    }
}

2. Format Compatibility Tests

#[cfg(test)]
mod format_compatibility_tests {
    use super::*;
 
    #[tokio::test]
    async fn test_toml_version_compatibility() {
        // Test TOML version compatibility
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_yaml_version_compatibility() {
        // Test YAML version compatibility
        // Arrange, Act, Assert pattern
    }
 
    #[tokio::test]
    async fn test_json_standard_compliance() {
        // Test JSON standard compliance
        // Arrange, Act, Assert pattern
    }
}

Test Utilities and Helpers

1. Test Data Generators

pub mod test_utils {
    use super::*;
 
    pub fn create_test_config() -> TestConfig {
        TestConfig {
            database: DatabaseConfig {
                host: "localhost".to_string(),
                port: 5432,
                ssl: true,
            },
            logging: LoggingConfig {
                level: "info".to_string(),
                file: None,
            },
        }
    }
 
    pub fn create_temp_config_file(dir: &Path, name: &str, content: &str) -> PathBuf {
        let file_path = dir.join(name);
        std::fs::write(&file_path, content).unwrap();
        file_path
    }
 
    pub async fn create_test_discovery() -> ConfigurationDiscovery {
        ConfigurationDiscovery::builder()
            .build()
            .unwrap()
    }
 
    pub async fn create_test_manager() -> ConfigurationManager<TestConfigSchema> {
        ConfigurationManager::<TestConfigSchema>::builder()
            .build()
            .await
            .unwrap()
    }
}

2. Mock Objects

pub mod mocks {
    use super::*;
 
    pub struct MockDiscoveryHandler {
        pub discovery_result: Option<Vec<DiscoveredFile>>,
        pub should_error: bool,
    }
 
    #[async_trait]
    impl DiscoveryHandler for MockDiscoveryHandler {
        async fn discover(&self, _module_name: &str) -> Result<Option<Vec<DiscoveredFile>>> {
            if self.should_error {
                Err(anyhow::anyhow!("Mock discovery error"))
            } else {
                Ok(self.discovery_result.clone())
            }
        }
 
        fn priority(&self) -> u8 { 1 }
        fn name(&self) -> &'static str { "Mock" }
    }
 
    pub struct MockConfigurationParser {
        pub parse_result: Result<serde_json::Value>,
        pub can_parse_result: bool,
    }
 
    #[async_trait]
    impl ConfigurationParser for MockConfigurationParser {
        async fn parse<T>(&self, _content: &str) -> Result<T>
        where
            T: for<'de> Deserialize<'de>
        {
            match &self.parse_result {
                Ok(value) => serde_json::from_value(value.clone())
                    .context("Mock parser conversion failed"),
                Err(e) => Err(anyhow::anyhow!("Mock parser error: {}", e)),
            }
        }
 
        fn format(&self) -> ConfigurationFormat {
            ConfigurationFormat::Json
        }
 
        fn can_parse(&self, _content: &str) -> bool {
            self.can_parse_result
        }
    }
 
    pub struct MockObserver {
        pub change_notifications: Arc<RwLock<Vec<ConfigurationChange>>>,
    }
 
    impl MockObserver {
        pub fn new() -> Self {
            Self {
                change_notifications: Arc::new(RwLock::new(Vec::new())),
            }
        }
 
        pub async fn get_notifications(&self) -> Vec<ConfigurationChange> {
            self.change_notifications.read().await.clone()
        }
    }
 
    #[async_trait]
    impl ConfigurationObserver for MockObserver {
        async fn on_configuration_changed(&self, change: ConfigurationChange) -> Result<()> {
            let mut notifications = self.change_notifications.write().await;
            notifications.push(change);
            Ok(())
        }
 
        async fn on_validation_failed(&self, _error: ValidationError) -> Result<()> {
            Ok(())
        }
 
        async fn on_reload_completed(&self, _success: bool) -> Result<()> {
            Ok(())
        }
    }
}

Test Execution Strategy

1. Test Organization

// tests/lib.rs
mod unit_tests {
    mod discovery_tests;
    mod parser_tests;
    mod validation_tests;
    mod merge_strategy_tests;
    mod builder_tests;
}
 
mod integration_tests {
    mod end_to_end_tests;
    mod cross_module_tests;
    mod external_integration_tests;
}
 
mod performance_tests {
    mod loading_performance_tests;
    mod memory_usage_tests;
    mod concurrency_tests;
}
 
mod security_tests {
    mod encryption_tests;
    mod access_control_tests;
    mod input_validation_tests;
}
 
mod compatibility_tests {
    mod platform_tests;
    mod format_tests;
    mod version_tests;
}

2. Test Configuration

# Cargo.toml test configuration
[package]
name = "sindhan-config"
version = "0.1.0"
edition = "2021"
 
[dependencies]
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
toml = "0.8"
serde_yaml = "0.9"
anyhow = "1.0"
async-trait = "0.1"
dirs = "5.0"
uuid = { version = "1.0", features = ["v4"] }
chrono = { version = "0.4", features = ["serde"] }
base64 = "0.21"
reqwest = { version = "0.11", features = ["json"] }
 
[dev-dependencies]
tempfile = "3.0"
mockall = "0.11"
proptest = "1.0"
criterion = "0.5"
 
[[bench]]
name = "configuration_benchmarks"
harness = false
 
[features]
default = []
test-utils = []

3. Continuous Integration Configuration

# .github/workflows/test.yml
name: Test Suite
 
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]
 
jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        rust: [stable, beta, nightly]
 
    steps:
    - uses: actions/checkout@v4
    
    - name: Install Rust
      uses: actions-rs/toolchain@v1
      with:
        toolchain: ${{ matrix.rust }}
        override: true
        components: rustfmt, clippy
 
    - name: Run tests
      uses: actions-rs/cargo@v1
      with:
        command: test
        args: --all-features --verbose
 
    - name: Run integration tests
      uses: actions-rs/cargo@v1
      with:
        command: test
        args: --test '*' --all-features
 
    - name: Run benchmarks
      uses: actions-rs/cargo@v1
      with:
        command: bench
 
    - name: Check formatting
      uses: actions-rs/cargo@v1
      with:
        command: fmt
        args: -- --check
 
    - name: Run clippy
      uses: actions-rs/cargo@v1
      with:
        command: clippy
        args: --all-features -- -D warnings
 
  coverage:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    
    - name: Install Rust
      uses: actions-rs/toolchain@v1
      with:
        toolchain: stable
        override: true
 
    - name: Install cargo-tarpaulin
      uses: actions-rs/install@v0.1
      with:
        crate: cargo-tarpaulin
        version: latest
 
    - name: Generate code coverage
      run: cargo tarpaulin --verbose --all-features --workspace --timeout 120 --out Xml
 
    - name: Upload to codecov.io
      uses: codecov/codecov-action@v3
      with:
        file: cobertura.xml
        fail_ci_if_error: true

Test Coverage Requirements

Coverage Targets

  • Unit Tests: 90%+ line coverage
  • Integration Tests: 80%+ feature coverage
  • Security Tests: 100% critical path coverage
  • Performance Tests: All major operations benchmarked

Test Quality Metrics

  • Test Reliability: 99.9% pass rate
  • Test Performance: < 5 minutes for full suite
  • Test Maintainability: Tests updated with code changes
  • Test Documentation: All test purposes documented

Test Execution Commands

# Run all tests
cargo test
 
# Run specific test categories
cargo test unit_tests
cargo test integration_tests
cargo test performance_tests
cargo test security_tests
 
# Run tests with coverage
cargo tarpaulin --all-features
 
# Run benchmarks
cargo bench
 
# Run tests in release mode
cargo test --release
 
# Run tests with specific features
cargo test --features "test-utils"
 
# Run tests with verbose output
cargo test -- --nocapture
 
# Run specific test
cargo test test_discovery_chain_priority_order

This comprehensive test plan ensures systematic testing of all Configuration Management functionalities following TDD principles, providing confidence in the system's reliability, security, and performance across all supported platforms and use cases.