Skip to content

Commit

Permalink
Validate unique component IDs in config (spinframework#340)
Browse files Browse the repository at this point in the history
  • Loading branch information
booklearner committed Apr 24, 2022
1 parent f9ce401 commit ffc1ed4
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
18 changes: 17 additions & 1 deletion crates/loader/src/local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub mod config;
#[cfg(test)]
mod tests;

use anyhow::{anyhow, Context, Result};
use anyhow::{anyhow, bail, Context, Result};
use config::{RawAppInformation, RawAppManifest, RawAppManifestAnyVersion, RawComponentManifest};
use futures::future;
use path_absolutize::Absolutize;
Expand Down Expand Up @@ -63,6 +63,20 @@ async fn prepare_any_version(
}
}

/// Iterates over a vector of RawComponentManifest structs and throws an error if any component ids are duplicated
fn error_on_duplicate_ids(components: Vec<RawComponentManifest>) -> Result<()> {
let mut ids: Vec<String> = Vec::new();
for c in components {
let id = c.id;
if ids.contains(&id) {
bail!("cannot have duplicate component IDs: {}", id);
} else {
ids.push(id);
}
}
Ok(())
}

/// Converts a raw application manifest into Spin configuration.
async fn prepare(
mut raw: RawAppManifest,
Expand All @@ -71,6 +85,8 @@ async fn prepare(
) -> Result<Application<CoreComponent>> {
let info = info(raw.info, &src);

error_on_duplicate_ids(raw.components.clone())?;

let mut config_root = raw.config.unwrap_or_default();
for component in &mut raw.components {
if let Some(config) = component.config.take() {
Expand Down
22 changes: 22 additions & 0 deletions crates/loader/src/local/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,25 @@ fn test_wagi_executor_with_custom_entrypoint() -> Result<()> {

Ok(())
}

#[tokio::test]
async fn test_duplicate_component_id_is_rejected() -> Result<()> {
const MANIFEST: &str = "tests/invalid-manifest-duplicate-id.toml";

let temp_dir = tempfile::tempdir()?;
let dir = temp_dir.path();
let app = from_file(MANIFEST, dir).await;

assert!(
app.is_err(),
"Expected component IDs to be unique, but there were duplicates"
);

let e = app.unwrap_err().to_string();
assert!(
e.contains("hello"),
"Expected error to contain duplicate component ID `hello`"
);

Ok(())
}
16 changes: 16 additions & 0 deletions crates/loader/tests/invalid-manifest-duplicate-id.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
spin_version = "1"
name = "spin-hello-world-duplicate"
version = "1.0.0"
trigger = { type = "http", base = "/" }

[[component]]
id = "hello"
source = "path/to/wasm/file.wasm"
[component.trigger]
route = "/hello"

[[component]]
id = "hello"
source = "path/to/wasm/file.wasm"
[component.trigger]
route = "/hello"

0 comments on commit ffc1ed4

Please sign in to comment.