Skip to content

Commit

Permalink
fix(server): Added validation logic for duplicated link config names (#…
Browse files Browse the repository at this point in the history
…478)

Signed-off-by: Florian Fürstenberg <[email protected]>
  • Loading branch information
Florian Fürstenberg committed Dec 13, 2024
1 parent a91762d commit 6f717b6
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
55 changes: 55 additions & 0 deletions crates/wadm-types/src/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ pub async fn validate_manifest(manifest: &Manifest) -> Result<Vec<ValidationFail
failures.extend(validate_policies(manifest));
failures.extend(ensure_no_custom_traits(manifest));
failures.extend(validate_component_properties(manifest));
failures.extend(validate_link_configs(manifest));
Ok(failures)
}

Expand Down Expand Up @@ -678,6 +679,60 @@ pub fn validate_component_properties(application: &Manifest) -> Vec<ValidationFa
failures
}

/// Validates link configs in a WADM application manifest.
///
/// At present this can check for:
/// - all config names are unique
///
pub fn validate_link_configs(manifest: &Manifest) -> Vec<ValidationFailure> {
let mut failures = Vec::new();
let mut link_config_names = HashSet::new();
for link_trait in manifest.links() {
if let TraitProperty::Link(LinkProperty {
name: _name,
namespace: _namespace,
package: _package,
interfaces: _interfaces,
target,
source,
..
}) = &link_trait.properties {
for config in target.config.iter() {
// Check if config name is unique
if !link_config_names.insert((
config.name.clone(),
)) {
failures.push(ValidationFailure::new(
ValidationFailureLevel::Error,
format!(
"Duplicate link config name found: '{}'",
config.name
),
));
}
}

if let Some(source) = source {
for config in source.config.iter() {
// Check if config name is unique
if !link_config_names.insert((
config.name.clone(),
)) {
failures.push(ValidationFailure::new(
ValidationFailureLevel::Error,
format!(
"Duplicate link config name found: '{}'",
config.name
),
));
}
}
}
}
};
failures
}

/// This function validates that a key/value pair is a valid OAM label. It's using fairly
/// basic validation rules to ensure that the manifest isn't doing anything horribly wrong. Keeping
/// this function free of regex is intentional to keep this code functional but simple.
Expand Down
23 changes: 23 additions & 0 deletions tests/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,26 @@ async fn validate_policy() -> Result<()> {
assert!(failures.valid(), "manifest is valid");
Ok(())
}

/// Ensure that we can detect duplicated link config names
#[tokio::test]
async fn validate_link_config_names() -> Result<()> {
let (_manifest, failures) =
validate_manifest_file("./tests/fixtures/manifests/duplicate_link_config_names.wadm.yaml")
.await
.context("failed to validate manifest")?;
let expected_errors = 3;
assert!(
!failures.is_empty()
&& failures
.iter()
.all(|f| f.level == ValidationFailureLevel::Error)
&& failures.len() == expected_errors,
"expected {} errors because manifest contains {} duplicated link config names, instead {} errors were found", expected_errors, expected_errors, failures.len().to_string()
);
assert!(
!failures.valid(),
"manifest should be invalid (duplicated link config names lead to a dead loop)"
);
Ok(())
}

0 comments on commit 6f717b6

Please sign in to comment.