Clean up
This commit is contained in:
parent
3f60b72c3b
commit
b414c05400
18 changed files with 905 additions and 985 deletions
|
|
@ -8,7 +8,6 @@ use tempfile::NamedTempFile;
|
|||
fn test_config_default_values() {
|
||||
let config = Config::default();
|
||||
|
||||
// Verify all default values are reasonable
|
||||
assert_eq!(config.schedule, "0 0 2 * * *");
|
||||
assert_eq!(
|
||||
config.update_strategy,
|
||||
|
|
@ -16,10 +15,8 @@ fn test_config_default_values() {
|
|||
);
|
||||
assert!(!config.dry_run);
|
||||
assert!(config.ignore_images.is_empty());
|
||||
// compose_paths should be a valid Vec (length check is always true for usize)
|
||||
let _paths_count = config.compose_paths.len();
|
||||
assert!(!config.compose_paths.is_empty());
|
||||
|
||||
// Should have default registries configured
|
||||
assert!(config.registries.contains_key("docker.io"));
|
||||
assert!(config.registries.contains_key("ghcr.io"));
|
||||
|
||||
|
|
@ -29,12 +26,10 @@ fn test_config_default_values() {
|
|||
|
||||
let ghcr_registry = &config.registries["ghcr.io"];
|
||||
assert_eq!(ghcr_registry.url, "https://ghcr.io");
|
||||
assert!(ghcr_registry.auth_token.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_config_from_different_file_formats() {
|
||||
// Test loading from a properly formatted YAML file
|
||||
fn test_config_from_yaml_file() {
|
||||
let valid_yaml = r#"
|
||||
compose_paths:
|
||||
- "./docker-compose.yml"
|
||||
|
|
@ -57,10 +52,7 @@ registries:
|
|||
temp_file.write_all(valid_yaml.as_bytes()).unwrap();
|
||||
temp_file.flush().unwrap();
|
||||
|
||||
let result = Config::load(temp_file.path().to_path_buf());
|
||||
assert!(result.is_ok(), "Should load valid YAML config");
|
||||
|
||||
let config = result.unwrap();
|
||||
let config = Config::load(temp_file.path().to_path_buf()).unwrap();
|
||||
assert_eq!(config.compose_paths.len(), 2);
|
||||
assert_eq!(config.schedule, "0 0 3 * * *");
|
||||
assert_eq!(config.update_strategy, UpdateStrategy::Latest);
|
||||
|
|
@ -74,45 +66,18 @@ registries:
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_config_with_invalid_yaml_syntax() {
|
||||
let invalid_yamls = [
|
||||
// Invalid YAML syntax
|
||||
r#"
|
||||
compose_paths:
|
||||
- "./docker-compose.yml"
|
||||
invalid_indent:
|
||||
schedule: "0 0 2 * * *"
|
||||
"#,
|
||||
// Invalid field types
|
||||
r#"
|
||||
compose_paths: "not an array"
|
||||
schedule: 123
|
||||
dry_run: "not a boolean"
|
||||
"#,
|
||||
// Completely invalid YAML
|
||||
r#"
|
||||
{ invalid yaml syntax [
|
||||
"#,
|
||||
];
|
||||
fn test_config_rejects_invalid_yaml() {
|
||||
let invalid_yaml = r#"{ invalid yaml syntax ["#;
|
||||
|
||||
for (i, invalid_yaml) in invalid_yamls.iter().enumerate() {
|
||||
let mut temp_file = NamedTempFile::new().unwrap();
|
||||
temp_file.write_all(invalid_yaml.as_bytes()).unwrap();
|
||||
temp_file.flush().unwrap();
|
||||
let mut temp_file = NamedTempFile::new().unwrap();
|
||||
temp_file.write_all(invalid_yaml.as_bytes()).unwrap();
|
||||
temp_file.flush().unwrap();
|
||||
|
||||
let result = Config::load(temp_file.path().to_path_buf());
|
||||
|
||||
// Should either fail gracefully or fall back to defaults
|
||||
if result.is_ok() {
|
||||
let config = result.unwrap();
|
||||
// If it succeeds, should have reasonable defaults
|
||||
assert!(
|
||||
!config.schedule.is_empty(),
|
||||
"Schedule should not be empty for test case {i}"
|
||||
);
|
||||
}
|
||||
// If it fails, that's also acceptable behavior for invalid YAML
|
||||
}
|
||||
let result = Config::load(temp_file.path().to_path_buf());
|
||||
assert!(
|
||||
result.is_err(),
|
||||
"Completely invalid YAML should fail to load"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -123,10 +88,6 @@ fn test_config_update_strategy_parsing() {
|
|||
"LatestPatchOfPreviousMinor",
|
||||
UpdateStrategy::LatestPatchOfPreviousMinor,
|
||||
),
|
||||
(
|
||||
"LatestPatchOfPreviousMinor",
|
||||
UpdateStrategy::LatestPatchOfPreviousMinor,
|
||||
),
|
||||
];
|
||||
|
||||
for (strategy_str, expected_strategy) in strategies {
|
||||
|
|
@ -142,19 +103,13 @@ update_strategy: "{strategy_str}"
|
|||
temp_file.write_all(yaml_config.as_bytes()).unwrap();
|
||||
temp_file.flush().unwrap();
|
||||
|
||||
let result = Config::load(temp_file.path().to_path_buf());
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"Should parse valid strategy: {strategy_str}"
|
||||
);
|
||||
|
||||
let config = result.unwrap();
|
||||
let config = Config::load(temp_file.path().to_path_buf()).unwrap();
|
||||
assert_eq!(config.update_strategy, expected_strategy);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_config_with_invalid_update_strategy() {
|
||||
fn test_config_rejects_invalid_update_strategy() {
|
||||
let yaml_config = r#"
|
||||
compose_paths: []
|
||||
schedule: "0 0 2 * * *"
|
||||
|
|
@ -166,15 +121,12 @@ update_strategy: "InvalidStrategy"
|
|||
temp_file.flush().unwrap();
|
||||
|
||||
let result = Config::load(temp_file.path().to_path_buf());
|
||||
|
||||
assert!(result.is_err(), "Should not parse invalid update strategy");
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_image_ignore_patterns_functionality() {
|
||||
// Test various ignore patterns
|
||||
fn test_image_ignore_patterns() {
|
||||
let test_cases = vec![
|
||||
// (ignore_pattern, image_to_test, should_be_ignored)
|
||||
("localhost", "localhost:5000/app:latest", true),
|
||||
("localhost", "nginx:latest", false),
|
||||
("127.0.0.1", "127.0.0.1:5000/app:latest", true),
|
||||
|
|
@ -182,6 +134,7 @@ fn test_image_ignore_patterns_functionality() {
|
|||
("ghcr.io", "ghcr.io/user/app:latest", true),
|
||||
("ghcr.io", "docker.io/nginx:latest", false),
|
||||
("test-", "test-app:latest", true),
|
||||
// "app-test:latest" does NOT contain "test-" (it has "test:" after the dash)
|
||||
("test-", "app-test:latest", false),
|
||||
];
|
||||
|
||||
|
|
@ -191,10 +144,13 @@ fn test_image_ignore_patterns_functionality() {
|
|||
..Config::default()
|
||||
};
|
||||
|
||||
let result = config.is_image_ignored(image_to_test);
|
||||
assert_eq!(
|
||||
result, should_be_ignored,
|
||||
"Pattern '{ignore_pattern}' with image '{image_to_test}' should be ignored: {should_be_ignored}"
|
||||
config.is_image_ignored(image_to_test),
|
||||
should_be_ignored,
|
||||
"Pattern '{}' with image '{}': expected ignored={}",
|
||||
ignore_pattern,
|
||||
image_to_test,
|
||||
should_be_ignored
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -211,31 +167,17 @@ fn test_multiple_ignore_patterns() {
|
|||
..Config::default()
|
||||
};
|
||||
|
||||
let test_cases = vec![
|
||||
("localhost:5000/app:latest", true),
|
||||
("127.0.0.1:5000/app:latest", true),
|
||||
("test-app:latest", true),
|
||||
("ghcr.io/user/app:latest", true),
|
||||
("docker.io/nginx:latest", false),
|
||||
("registry.example.com/app:latest", false),
|
||||
("app-test:latest", false),
|
||||
];
|
||||
|
||||
for (image, should_be_ignored) in test_cases {
|
||||
let result = config.is_image_ignored(image);
|
||||
assert_eq!(
|
||||
result, should_be_ignored,
|
||||
"Image '{image}' should be ignored: {should_be_ignored}"
|
||||
);
|
||||
}
|
||||
assert!(config.is_image_ignored("localhost:5000/app:latest"));
|
||||
assert!(config.is_image_ignored("127.0.0.1:5000/app:latest"));
|
||||
assert!(config.is_image_ignored("test-app:latest"));
|
||||
assert!(config.is_image_ignored("ghcr.io/user/app:latest"));
|
||||
assert!(!config.is_image_ignored("docker.io/nginx:latest"));
|
||||
assert!(!config.is_image_ignored("registry.example.com/app:latest"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_registry_configuration_validation() {
|
||||
// Test registry configs with various configurations
|
||||
fn test_registry_configuration() {
|
||||
let mut registries = HashMap::new();
|
||||
|
||||
// Registry with just URL
|
||||
registries.insert(
|
||||
"simple.registry.com".to_string(),
|
||||
RegistryConfig {
|
||||
|
|
@ -243,8 +185,6 @@ fn test_registry_configuration_validation() {
|
|||
auth_token: None,
|
||||
},
|
||||
);
|
||||
|
||||
// Registry with auth token
|
||||
registries.insert(
|
||||
"auth.registry.com".to_string(),
|
||||
RegistryConfig {
|
||||
|
|
@ -258,17 +198,13 @@ fn test_registry_configuration_validation() {
|
|||
..Config::default()
|
||||
};
|
||||
|
||||
// Verify registries are properly configured
|
||||
assert!(config.registries.contains_key("simple.registry.com"));
|
||||
assert!(config.registries.contains_key("auth.registry.com"));
|
||||
|
||||
let simple_registry = &config.registries["simple.registry.com"];
|
||||
assert_eq!(simple_registry.url, "https://simple.registry.com");
|
||||
assert!(simple_registry.auth_token.is_none());
|
||||
|
||||
let auth_registry = &config.registries["auth.registry.com"];
|
||||
assert_eq!(auth_registry.url, "https://auth.registry.com");
|
||||
assert_eq!(auth_registry.auth_token, Some("secret-token".to_string()));
|
||||
assert!(config.registries["simple.registry.com"]
|
||||
.auth_token
|
||||
.is_none());
|
||||
assert_eq!(
|
||||
config.registries["auth.registry.com"].auth_token,
|
||||
Some("secret-token".to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -284,36 +220,19 @@ registries: {}
|
|||
temp_file.write_all(yaml_config.as_bytes()).unwrap();
|
||||
temp_file.flush().unwrap();
|
||||
|
||||
let result = Config::load(temp_file.path().to_path_buf());
|
||||
|
||||
if result.is_ok() {
|
||||
let config = result.unwrap();
|
||||
assert!(config.compose_paths.is_empty());
|
||||
assert!(config.ignore_images.is_empty());
|
||||
// Empty schedule should either be rejected or have a default
|
||||
assert!(!config.schedule.is_empty() || config.schedule.is_empty()); // Either is acceptable
|
||||
}
|
||||
// If loading fails for empty schedule, that's also acceptable
|
||||
let config = Config::load(temp_file.path().to_path_buf()).unwrap();
|
||||
assert!(config.compose_paths.is_empty());
|
||||
assert!(config.ignore_images.is_empty());
|
||||
assert!(config.schedule.is_empty());
|
||||
assert!(config.registries.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_config_compose_paths_handling() {
|
||||
// Test various compose path configurations
|
||||
let test_cases = vec![
|
||||
// Single file path
|
||||
vec!["./docker-compose.yml"],
|
||||
// Multiple file paths
|
||||
vec!["./docker-compose.yml", "./docker-compose.override.yml"],
|
||||
// Directory paths
|
||||
vec!["./services/", "./environments/"],
|
||||
// Mixed paths
|
||||
vec!["./docker-compose.yml", "./services/", "./override.yml"],
|
||||
// Relative and absolute-looking paths
|
||||
vec![
|
||||
"docker-compose.yml",
|
||||
"/app/config/compose.yml",
|
||||
"../compose.yml",
|
||||
],
|
||||
];
|
||||
|
||||
for paths in test_cases {
|
||||
|
|
@ -334,13 +253,33 @@ schedule: "0 0 2 * * *"
|
|||
temp_file.write_all(yaml_config.as_bytes()).unwrap();
|
||||
temp_file.flush().unwrap();
|
||||
|
||||
let result = Config::load(temp_file.path().to_path_buf());
|
||||
assert!(result.is_ok(), "Should handle paths: {paths:?}");
|
||||
|
||||
let config = result.unwrap();
|
||||
let config = Config::load(temp_file.path().to_path_buf()).unwrap();
|
||||
assert_eq!(config.compose_paths.len(), paths.len());
|
||||
for (i, expected_path) in paths.iter().enumerate() {
|
||||
assert_eq!(config.compose_paths[i], PathBuf::from(expected_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_load_normalizes_empty_auth_token_to_none() {
|
||||
// An auth_token referencing an unset variable expands to "" and should be
|
||||
// treated as "no token" rather than an empty credential.
|
||||
let yaml_config = r#"
|
||||
compose_paths: []
|
||||
schedule: "0 0 2 * * *"
|
||||
registries:
|
||||
private.registry.com:
|
||||
url: "https://private.registry.com"
|
||||
auth_token: "${DCU_DEFINITELY_UNSET_TOKEN}"
|
||||
"#;
|
||||
|
||||
let mut temp_file = NamedTempFile::new().unwrap();
|
||||
temp_file.write_all(yaml_config.as_bytes()).unwrap();
|
||||
temp_file.flush().unwrap();
|
||||
|
||||
let config = Config::load(temp_file.path().to_path_buf()).unwrap();
|
||||
assert!(config.registries["private.registry.com"]
|
||||
.auth_token
|
||||
.is_none());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue