diff --git a/Cargo.lock b/Cargo.lock index 7102f94187..e25723ff17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5797,6 +5797,7 @@ dependencies = [ "spin-app", "spin-loader", "spin-manifest", + "spin-testing", "spin-trigger", "tempfile", "tokio", diff --git a/crates/oci/Cargo.toml b/crates/oci/Cargo.toml index 84eb53dccd..c60fb61331 100644 --- a/crates/oci/Cargo.toml +++ b/crates/oci/Cargo.toml @@ -27,3 +27,5 @@ tokio-util = "0.7.9" tracing = { workspace = true } walkdir = "2.3" +[dev-dependencies] +spin-testing = { path = "../testing" } diff --git a/crates/oci/src/client.rs b/crates/oci/src/client.rs index d98a3858bd..7bfb439b01 100644 --- a/crates/oci/src/client.rs +++ b/crates/oci/src/client.rs @@ -504,7 +504,6 @@ fn digest_from_url(manifest_url: &str) -> Option { } // TODO: good use case for DeployableApp addition in cloud-plugin? (Well, would want to move into spin to avoid circular deps) -// TODO: add test async fn layer_count(locked: LockedApp) -> Result { let mut layer_count = 0; for c in locked.components { @@ -539,4 +538,59 @@ mod test { digest ); } + + #[tokio::test] + async fn can_get_layer_count() { + use spin_app::locked::LockedComponent; + + let working_dir = tempfile::tempdir().unwrap(); + let source_dir = working_dir.path().join("foo"); + let _ = tokio::fs::create_dir(source_dir.as_path()).await; + let file_path = source_dir.join("bar"); + let _ = tokio::fs::File::create(file_path.as_path()).await; + + let tests: Vec<(Vec, usize)> = [ + ( + spin_testing::from_json!([{ + "id": "test-component", + "source": { + "content_type": "application/wasm", + "digest": "test-source", + }, + }]), + 1, + ), + ( + spin_testing::from_json!([{ + "id": "test-component", + "source": { + "content_type": "application/wasm", + "digest": "test-source", + }, + "files": [ + { + "source": format!("file://{}", file_path.to_str().unwrap()), + "path": "" + } + ] + }]), + 2, + ), + ] + .to_vec(); + + for (components, expected) in tests { + let triggers = Default::default(); + let metadata = Default::default(); + let variables = Default::default(); + let locked = LockedApp { + spin_lock_version: spin_app::locked::FixedVersion, + components, + triggers, + metadata, + variables, + }; + assert_eq!(expected, layer_count(locked).await.unwrap()); + } + } } diff --git a/crates/testing/src/lib.rs b/crates/testing/src/lib.rs index 5901ac8ab1..55e37a8e78 100644 --- a/crates/testing/src/lib.rs +++ b/crates/testing/src/lib.rs @@ -39,6 +39,7 @@ pub fn init_tracing() { } // Convenience wrapper for deserializing from literal JSON +#[macro_export] macro_rules! from_json { ($($json:tt)+) => { serde_json::from_value(serde_json::json!($($json)+)).expect("valid json")