From 2ee46974184f4892303fc7e62c7f10ab91275681 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 3 Jul 2024 01:50:47 +0000 Subject: [PATCH 01/10] Bump rustls from 0.22.3 to 0.22.4 Bumps [rustls](https://github.com/rustls/rustls) from 0.22.3 to 0.22.4. - [Release notes](https://github.com/rustls/rustls/releases) - [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustls/rustls/compare/v/0.22.3...v/0.22.4) --- updated-dependencies: - dependency-name: rustls dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ crates/trigger-http/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 793face2a..35a9254d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3407,7 +3407,7 @@ dependencies = [ "http 0.2.12", "hyper 0.14.28", "log", - "rustls 0.22.3", + "rustls 0.22.4", "rustls-native-certs", "rustls-pki-types", "tokio", @@ -6622,9 +6622,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring", @@ -7966,7 +7966,7 @@ dependencies = [ "num_cpus", "outbound-http", "percent-encoding", - "rustls 0.22.3", + "rustls 0.22.4", "rustls-pemfile 2.1.2", "rustls-pki-types", "serde 1.0.197", @@ -8613,7 +8613,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.3", + "rustls 0.22.4", "rustls-pki-types", "tokio", ] @@ -9955,7 +9955,7 @@ dependencies = [ "http-body 1.0.0", "http-body-util", "hyper 1.2.0", - "rustls 0.22.3", + "rustls 0.22.4", "tokio", "tokio-rustls 0.25.0", "tracing", diff --git a/crates/trigger-http/Cargo.toml b/crates/trigger-http/Cargo.toml index 4bc4e6d16..79ce6c128 100644 --- a/crates/trigger-http/Cargo.toml +++ b/crates/trigger-http/Cargo.toml @@ -20,7 +20,7 @@ http-body-util = { workspace = true } indexmap = "1" outbound-http = { path = "../outbound-http" } percent-encoding = "2" -rustls = { version = "0.22.0" } +rustls = { version = "0.22.4" } rustls-pemfile = "2.1.2" rustls-pki-types = "1.7" serde = { version = "1.0", features = ["derive"] } From 50c9089a8862960f59a556957de0c00402c3ab4f Mon Sep 17 00:00:00 2001 From: itowlson Date: Wed, 17 Jul 2024 12:50:17 +1200 Subject: [PATCH 02/10] Common setups for test TemplateManagers Signed-off-by: itowlson --- crates/templates/src/manager.rs | 343 +++++++++----------------------- 1 file changed, 94 insertions(+), 249 deletions(-) diff --git a/crates/templates/src/manager.rs b/crates/templates/src/manager.rs index cfc1fa84f..fa8ff0a41 100644 --- a/crates/templates/src/manager.rs +++ b/crates/templates/src/manager.rs @@ -468,21 +468,64 @@ mod tests { PathBuf::from(crate_dir).join("tests") } + // A template manager in a temp dir. This exists to ensure the lifetime + // of the TempDir + struct TempManager { + temp_dir: tempfile::TempDir, + manager: TemplateManager, + } + + impl TempManager { + fn new() -> Self { + let temp_dir = tempdir().unwrap(); + let store = TemplateStore::new(temp_dir.path()); + let manager = TemplateManager { store }; + Self { temp_dir, manager } + } + + async fn new_with_this_repo_templates() -> Self { + let mgr = Self::new(); + mgr.install_this_repo_templates().await; + mgr + } + + async fn install_this_repo_templates(&self) -> InstallationResults { + let source = TemplateSource::File(project_root()); + self.manager + .install(&source, &InstallOptions::default(), &DiscardingReporter) + .await + .unwrap() + } + + async fn install_test_data_templates(&self) -> InstallationResults { + let source = TemplateSource::File(test_data_root()); + self.manager + .install(&source, &InstallOptions::default(), &DiscardingReporter) + .await + .unwrap() + } + + fn store_dir(&self) -> &Path { + self.temp_dir.path() + } + } + + impl std::ops::Deref for TempManager { + type Target = TemplateManager; + + fn deref(&self) -> &Self::Target { + &self.manager + } + } + const TPLS_IN_THIS: usize = 12; #[tokio::test] async fn can_install_into_new_directory() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - + let manager = TempManager::new(); assert_eq!(0, manager.list().await.unwrap().templates.len()); - - let install_result = manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + + let install_result = manager.install_this_repo_templates().await; assert_eq!(TPLS_IN_THIS, install_result.installed.len()); assert_eq!(0, install_result.skipped.len()); @@ -492,9 +535,7 @@ mod tests { #[tokio::test] async fn skips_bad_templates() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; + let manager = TempManager::new(); let temp_source = tempdir().unwrap(); let temp_source_tpls_dir = temp_source.path().join("templates"); @@ -525,15 +566,7 @@ mod tests { #[tokio::test] async fn can_list_all_templates_with_empty_tags() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let list_results = manager.list_with_tags(&[]).await.unwrap(); assert_eq!(0, list_results.skipped.len()); @@ -542,15 +575,7 @@ mod tests { #[tokio::test] async fn skips_when_all_tags_do_not_match() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let tags_to_match = vec!["c".to_string(), "unused_tag".to_string()]; @@ -561,15 +586,7 @@ mod tests { #[tokio::test] async fn can_list_templates_with_multiple_tags() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let tags_to_match = vec!["http".to_string(), "c".to_string()]; @@ -580,15 +597,7 @@ mod tests { #[tokio::test] async fn can_list_templates_with_case_insensitive_tags() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let list_results = manager.list_with_tags(&["C".to_string()]).await.unwrap(); assert_eq!(TPLS_IN_THIS - 1, list_results.skipped.len()); @@ -597,15 +606,7 @@ mod tests { #[tokio::test] async fn can_skip_templates_with_missing_tag() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let list_results = manager .list_with_tags(&["unused_tag".to_string()]) @@ -617,22 +618,14 @@ mod tests { #[tokio::test] async fn can_list_if_bad_dir_in_store() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - + let manager = TempManager::new(); assert_eq!(0, manager.list().await.unwrap().templates.len()); - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); - + manager.install_this_repo_templates().await; assert_eq!(TPLS_IN_THIS, manager.list().await.unwrap().templates.len()); assert_eq!(0, manager.list().await.unwrap().warnings.len()); - fs::create_dir(temp_dir.path().join("i-trip-you-up")).unwrap(); + fs::create_dir(manager.store_dir().join("i-trip-you-up")).unwrap(); let list_results = manager.list().await.unwrap(); assert_eq!(TPLS_IN_THIS, list_results.templates.len()); @@ -646,16 +639,9 @@ mod tests { #[tokio::test] async fn can_uninstall() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; assert_eq!(TPLS_IN_THIS, manager.list().await.unwrap().templates.len()); + manager.uninstall("http-rust").await.unwrap(); let installed = manager.list().await.unwrap(); @@ -666,15 +652,7 @@ mod tests { #[tokio::test] async fn can_install_if_some_already_exist() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; manager.uninstall("http-rust").await.unwrap(); manager.uninstall("http-go").await.unwrap(); assert_eq!( @@ -683,9 +661,7 @@ mod tests { ); let install_result = manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + .install_this_repo_templates().await; assert_eq!(2, install_result.installed.len()); assert_eq!(TPLS_IN_THIS - 2, install_result.skipped.len()); @@ -697,21 +673,14 @@ mod tests { #[tokio::test] async fn can_update_existing() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; manager.uninstall("http-rust").await.unwrap(); assert_eq!( TPLS_IN_THIS - 1, manager.list().await.unwrap().templates.len() ); + let source = TemplateSource::File(project_root()); let install_result = manager .install( &source, @@ -730,15 +699,7 @@ mod tests { #[tokio::test] async fn can_read_installed_template() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let template = manager.get("http-rust").unwrap().unwrap(); assert_eq!( @@ -755,15 +716,7 @@ mod tests { #[tokio::test] async fn can_run_template() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let template = manager.get("http-rust").unwrap().unwrap(); @@ -795,15 +748,7 @@ mod tests { #[tokio::test] async fn can_run_template_with_accept_defaults() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let template = manager.get("http-rust").unwrap().unwrap(); @@ -834,15 +779,11 @@ mod tests { #[tokio::test] async fn cannot_use_custom_filter_in_template() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(test_data_root()); + let manager = TempManager::new(); let install_results = manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + .install_test_data_templates() + .await; assert_eq!(1, install_results.skipped.len()); @@ -857,15 +798,7 @@ mod tests { #[tokio::test] async fn can_add_component_from_template() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let dest_temp_dir = tempdir().unwrap(); let application_dir = dest_temp_dir.path().join("multi"); @@ -962,20 +895,9 @@ mod tests { #[tokio::test] async fn can_add_variables_from_template() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source1 = TemplateSource::File(test_data_root()); - let source2 = TemplateSource::File(project_root()); // We will need some of the standard templates too - - manager - .install(&source1, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); - manager - .install(&source2, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new(); + manager.install_test_data_templates().await; + manager.install_this_repo_templates().await; // We will need some of the standard templates too let dest_temp_dir = tempdir().unwrap(); let application_dir = dest_temp_dir.path().join("spinvars"); @@ -1044,20 +966,9 @@ mod tests { #[tokio::test] async fn can_overwrite_existing_variables() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source1 = TemplateSource::File(test_data_root()); - let source2 = TemplateSource::File(project_root()); // We will need some of the standard templates too - - manager - .install(&source1, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); - manager - .install(&source2, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new(); + manager.install_test_data_templates().await; + manager.install_this_repo_templates().await; // We will need some of the standard templates too let dest_temp_dir = tempdir().unwrap(); let application_dir = dest_temp_dir.path().join("spinvars"); @@ -1147,15 +1058,7 @@ mod tests { #[tokio::test] async fn component_new_no_vcs() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let dest_temp_dir = tempdir().unwrap(); let application_dir = dest_temp_dir.path().join("no-vcs-new"); @@ -1189,15 +1092,7 @@ mod tests { #[tokio::test] async fn component_add_no_vcs() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let dest_temp_dir = tempdir().unwrap(); let application_dir = dest_temp_dir.path().join("no-vcs-add"); @@ -1264,15 +1159,7 @@ mod tests { #[tokio::test] async fn can_add_component_with_different_trigger() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let dest_temp_dir = tempdir().unwrap(); let application_dir = dest_temp_dir.path().join("multi"); @@ -1345,15 +1232,7 @@ mod tests { #[tokio::test] async fn cannot_add_component_that_does_not_match_manifest() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let dest_temp_dir = tempdir().unwrap(); let application_dir = dest_temp_dir.path().join("multi"); @@ -1405,15 +1284,7 @@ mod tests { #[tokio::test] async fn cannot_generate_over_existing_files_by_default() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let template = manager.get("http-rust").unwrap().unwrap(); @@ -1454,15 +1325,7 @@ mod tests { #[tokio::test] async fn can_generate_over_existing_files_if_so_configured() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(project_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new_with_this_repo_templates().await; let template = manager.get("http-rust").unwrap().unwrap(); @@ -1503,22 +1366,11 @@ mod tests { #[tokio::test] async fn cannot_new_a_component_only_template() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source1 = TemplateSource::File(test_data_root()); - let source2 = TemplateSource::File(project_root()); - - manager - .install(&source1, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); - manager - .install(&source2, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new(); + manager.install_test_data_templates().await; + manager.install_this_repo_templates().await; - let dummy_dir = temp_dir.path().join("dummy"); + let dummy_dir = manager.store_dir().join("dummy"); let manifest_path = dummy_dir.join("ignored_spin.toml"); let add_component = TemplateVariantInfo::AddComponent { manifest_path }; @@ -1537,15 +1389,8 @@ mod tests { #[tokio::test] async fn fails_on_unknown_filter() { - let temp_dir = tempdir().unwrap(); - let store = TemplateStore::new(temp_dir.path()); - let manager = TemplateManager { store }; - let source = TemplateSource::File(test_data_root()); - - manager - .install(&source, &InstallOptions::default(), &DiscardingReporter) - .await - .unwrap(); + let manager = TempManager::new(); + manager.install_test_data_templates().await; let template = manager.get("bad-non-existent-filter").unwrap().unwrap(); @@ -1557,7 +1402,7 @@ mod tests { let options = RunOptions { variant: crate::template::TemplateVariantInfo::NewApplication, output_path: output_dir.clone(), - name: "bad-filter-should-fail ".to_owned(), + name: "bad-filter-should-fail".to_owned(), values, accept_defaults: false, no_vcs: false, From a45e6f829fe1ab5887edca4f42f3721315a72b32 Mon Sep 17 00:00:00 2001 From: itowlson Date: Wed, 17 Jul 2024 13:57:21 +1200 Subject: [PATCH 03/10] Deduplicate template execution test code Signed-off-by: itowlson --- crates/templates/src/manager.rs | 424 +++++++++----------------------- 1 file changed, 112 insertions(+), 312 deletions(-) diff --git a/crates/templates/src/manager.rs b/crates/templates/src/manager.rs index fa8ff0a41..4ddc7271c 100644 --- a/crates/templates/src/manager.rs +++ b/crates/templates/src/manager.rs @@ -512,19 +512,67 @@ mod tests { impl std::ops::Deref for TempManager { type Target = TemplateManager; - + fn deref(&self) -> &Self::Target { &self.manager } } + // Constructs an options object to control how a template is run, with defaults. + // to save repeating the same thing over and over! By default, the options are: + // * Create a mew application + // * Dummy parameter values to satisfy the HTTP template + // * All other flags are false + // Use the `rest` callback to modify fields not given in the `name` and `output_path` + // arguments. For example, to create a RunOptions with `no_vcs` turned on, do: + // `run_options(name, path, |opts| { opts.no_vcs = true; })` + fn run_options( + name: impl AsRef, + output_path: impl AsRef, + rest: impl FnOnce(&mut RunOptions), + ) -> RunOptions { + let mut options = RunOptions { + variant: crate::template::TemplateVariantInfo::NewApplication, + name: name.as_ref().to_owned(), + output_path: output_path.as_ref().to_owned(), + values: dummy_values(), + accept_defaults: false, + no_vcs: false, + allow_overwrite: false, + }; + rest(&mut options); + options + } + + fn make_values( + values: impl IntoIterator, + ) -> HashMap { + values + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect() + } + + fn dummy_values() -> HashMap { + make_values([ + ("project-description", "dummy desc"), + ("http-path", "/dummy/dummy/dummy/..."), + ]) + } + + fn add_component_to(manifest_path: impl AsRef) -> crate::template::TemplateVariantInfo { + crate::template::TemplateVariantInfo::AddComponent { + manifest_path: manifest_path.as_ref().to_owned(), + } + } + const TPLS_IN_THIS: usize = 12; #[tokio::test] async fn can_install_into_new_directory() { let manager = TempManager::new(); assert_eq!(0, manager.list().await.unwrap().templates.len()); - + let install_result = manager.install_this_repo_templates().await; assert_eq!(TPLS_IN_THIS, install_result.installed.len()); assert_eq!(0, install_result.skipped.len()); @@ -660,8 +708,7 @@ mod tests { manager.list().await.unwrap().templates.len() ); - let install_result = manager - .install_this_repo_templates().await; + let install_result = manager.install_this_repo_templates().await; assert_eq!(2, install_result.installed.len()); assert_eq!(TPLS_IN_THIS - 2, install_result.skipped.len()); @@ -722,21 +769,8 @@ mod tests { let dest_temp_dir = tempdir().unwrap(); let output_dir = dest_temp_dir.path().join("myproj"); - let values = [ - ("project-description".to_owned(), "my desc".to_owned()), - ("http-path".to_owned(), "/path/...".to_owned()), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: output_dir.clone(), - name: "my project".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + + let options = run_options("my project", &output_dir, |_| {}); template.run(options).silent().await.unwrap(); @@ -754,16 +788,10 @@ mod tests { let dest_temp_dir = tempdir().unwrap(); let output_dir = dest_temp_dir.path().join("myproj"); - let values = HashMap::new(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: output_dir.clone(), - name: "my project".to_owned(), - values, - accept_defaults: true, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("my project", &output_dir, |opts| { + opts.values = HashMap::new(); + opts.accept_defaults = true; + }); template.run(options).silent().await.unwrap(); @@ -781,9 +809,7 @@ mod tests { async fn cannot_use_custom_filter_in_template() { let manager = TempManager::new(); - let install_results = manager - .install_test_data_templates() - .await; + let install_results = manager.install_test_data_templates().await; assert_eq!(1, install_results.skipped.len()); @@ -807,18 +833,9 @@ mod tests { { let template = manager.get("http-empty").unwrap().unwrap(); - let values = [("project-description".to_owned(), "my desc".to_owned())] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: application_dir.clone(), - name: "my multi project".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("my multi project", &application_dir, |opts| { + opts.values = make_values([("project-description", "my desc")]) + }); template.run(options).silent().await.unwrap(); } @@ -830,24 +847,9 @@ mod tests { { let template = manager.get("http-rust").unwrap().unwrap(); - let output_dir = "hello"; - let values = [ - ("project-description".to_owned(), "hello".to_owned()), - ("http-path".to_owned(), "/hello".to_owned()), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::AddComponent { - manifest_path: spin_toml_path.clone(), - }, - output_path: PathBuf::from(output_dir), - name: "hello".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("hello", "hello", |opts| { + opts.variant = add_component_to(&spin_toml_path); + }); template.run(options).silent().await.unwrap(); } @@ -856,24 +858,9 @@ mod tests { { let template = manager.get("http-rust").unwrap().unwrap(); - let output_dir = "encore"; - let values = [ - ("project-description".to_owned(), "hello 2".to_owned()), - ("http-path".to_owned(), "/hello-2".to_owned()), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::AddComponent { - manifest_path: spin_toml_path.clone(), - }, - output_path: PathBuf::from(output_dir), - name: "hello 2".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("hello 2", "encore", |opts| { + opts.variant = add_component_to(&spin_toml_path); + }); template.run(options).silent().await.unwrap(); } @@ -906,21 +893,7 @@ mod tests { { let template = manager.get("http-rust").unwrap().unwrap(); - let values = [ - ("project-description".to_owned(), "my desc".to_owned()), - ("http-path".to_owned(), "/...".to_owned()), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: application_dir.clone(), - name: "my various project".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("my various project", &application_dir, |_| {}); template.run(options).silent().await.unwrap(); } @@ -932,24 +905,10 @@ mod tests { { let template = manager.get("add-variables").unwrap().unwrap(); - let output_dir = "hello"; - let values = [( - "service-url".to_owned(), - "https://service.example.com".to_owned(), - )] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::AddComponent { - manifest_path: spin_toml_path.clone(), - }, - output_path: PathBuf::from(output_dir), - name: "insertvars".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("insertvars", "hello", |opts| { + opts.variant = add_component_to(&spin_toml_path); + opts.values = make_values([("service-url", "https://service.example.com")]) + }); template.run(options).silent().await.unwrap(); } @@ -977,21 +936,7 @@ mod tests { { let template = manager.get("http-rust").unwrap().unwrap(); - let values = [ - ("project-description".to_owned(), "my desc".to_owned()), - ("http-path".to_owned(), "/...".to_owned()), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: application_dir.clone(), - name: "my various project".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("my various project", &application_dir, |_| {}); template.run(options).silent().await.unwrap(); } @@ -1003,24 +948,10 @@ mod tests { { let template = manager.get("add-variables").unwrap().unwrap(); - let output_dir = "hello"; - let values = [( - "service-url".to_owned(), - "https://service.example.com".to_owned(), - )] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::AddComponent { - manifest_path: spin_toml_path.clone(), - }, - output_path: PathBuf::from(output_dir), - name: "insertvars".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("insertvars", "hello", |opts| { + opts.variant = add_component_to(&spin_toml_path); + opts.values = make_values([("service-url", "https://service.example.com")]); + }); template.run(options).silent().await.unwrap(); } @@ -1029,24 +960,10 @@ mod tests { { let template = manager.get("add-variables").unwrap().unwrap(); - let output_dir = "hello"; - let values = [( - "service-url".to_owned(), - "https://other.example.com".to_owned(), - )] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::AddComponent { - manifest_path: spin_toml_path.clone(), - }, - output_path: PathBuf::from(output_dir), - name: "insertvarsagain".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("insertvarsagain", "hello", |opts| { + opts.variant = add_component_to(&spin_toml_path); + opts.values = make_values([("service-url", "https://other.example.com")]); + }); template.run(options).silent().await.unwrap(); } @@ -1065,22 +982,9 @@ mod tests { let template = manager.get("http-rust").unwrap().unwrap(); - let values = [ - ("project-description".to_owned(), "my desc".to_owned()), - ("http-path".to_owned(), "/path/...".to_owned()), - ] - .into_iter() - .collect(); - - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: application_dir.clone(), - name: "no vcs new".to_owned(), - values, - accept_defaults: false, - no_vcs: true, - allow_overwrite: false, - }; + let options = run_options("no vcs new", &application_dir, |opts| { + opts.no_vcs = true; + }); template.run(options).silent().await.unwrap(); let gitignore = application_dir.join(".gitignore"); @@ -1101,18 +1005,10 @@ mod tests { { let template = manager.get("http-empty").unwrap().unwrap(); - let values = [("project-description".to_owned(), "my desc".to_owned())] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: application_dir.clone(), - name: "my multi project".to_owned(), - values, - accept_defaults: false, - no_vcs: true, - allow_overwrite: false, - }; + let options = run_options("my multi project", &application_dir, |opts| { + opts.values = make_values([("project-description", "my desc")]); + opts.no_vcs = true; + }); template.run(options).silent().await.unwrap(); } @@ -1127,26 +1023,10 @@ mod tests { { let template = manager.get("http-rust").unwrap().unwrap(); - let values = [ - ("project-description".to_owned(), "my desc".to_owned()), - ("http-path".to_owned(), "/path/...".to_owned()), - ] - .into_iter() - .collect(); - - let output_dir = "hello"; - - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::AddComponent { - manifest_path: spin_toml_path.clone(), - }, - output_path: PathBuf::from(output_dir), - name: "added_component".to_owned(), - values, - accept_defaults: false, - no_vcs: true, - allow_overwrite: false, - }; + let options = run_options("added_component", "hello", |opts| { + opts.variant = add_component_to(&spin_toml_path); + opts.no_vcs = true; + }); template.run(options).silent().await.unwrap(); } @@ -1168,28 +1048,13 @@ mod tests { { let template = manager.get("redis-rust").unwrap().unwrap(); - let values = [ - ("project-description".to_owned(), "my desc".to_owned()), - ( - "redis-address".to_owned(), - "redis://localhost:6379".to_owned(), - ), - ( - "redis-channel".to_owned(), - "the-horrible-knuckles".to_owned(), - ), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: application_dir.clone(), - name: "my multi project".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("my multi project", &application_dir, |opts| { + opts.values = make_values([ + ("project-description", "my desc"), + ("redis-address", "redis://localhost:6379"), + ("redis-channel", "the-horrible-knuckles"), + ]) + }); template.run(options).silent().await.unwrap(); } @@ -1201,24 +1066,9 @@ mod tests { { let template = manager.get("http-rust").unwrap().unwrap(); - let output_dir = "hello"; - let values = [ - ("project-description".to_owned(), "hello".to_owned()), - ("http-path".to_owned(), "/hello".to_owned()), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::AddComponent { - manifest_path: spin_toml_path.clone(), - }, - output_path: PathBuf::from(output_dir), - name: "hello".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("hello", "hello", |opts| { + opts.variant = add_component_to(&spin_toml_path); + }); template.run(options).silent().await.unwrap(); } @@ -1255,24 +1105,9 @@ mod tests { { let template = manager.get("http-rust").unwrap().unwrap(); - let output_dir = "hello"; - let values = [ - ("project-description".to_owned(), "hello".to_owned()), - ("http-path".to_owned(), "/hello".to_owned()), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::AddComponent { - manifest_path: spin_toml_path.clone(), - }, - output_path: PathBuf::from(output_dir), - name: "hello".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("hello", "hello", |opts| { + opts.variant = add_component_to(&spin_toml_path); + }); template .run(options) @@ -1295,21 +1130,7 @@ mod tests { let manifest_path = output_dir.join("spin.toml"); tokio::fs::write(&manifest_path, "cookies").await.unwrap(); - let values = [ - ("project-description".to_owned(), "my desc".to_owned()), - ("http-path".to_owned(), "/path/...".to_owned()), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: output_dir.clone(), - name: "my project".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("my project", &output_dir, |_| {}); template .run(options) @@ -1336,21 +1157,9 @@ mod tests { let manifest_path = output_dir.join("spin.toml"); tokio::fs::write(&manifest_path, "cookies").await.unwrap(); - let values = [ - ("project-description".to_owned(), "my desc".to_owned()), - ("http-path".to_owned(), "/path/...".to_owned()), - ] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: output_dir.clone(), - name: "my project".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: true, - }; + let options = run_options("my project", &output_dir, |opts| { + opts.allow_overwrite = true; + }); template .run(options) @@ -1396,18 +1205,9 @@ mod tests { let dest_temp_dir = tempdir().unwrap(); let output_dir = dest_temp_dir.path().join("myproj"); - let values = [("p1".to_owned(), "biscuits".to_owned())] - .into_iter() - .collect(); - let options = RunOptions { - variant: crate::template::TemplateVariantInfo::NewApplication, - output_path: output_dir.clone(), - name: "bad-filter-should-fail".to_owned(), - values, - accept_defaults: false, - no_vcs: false, - allow_overwrite: false, - }; + let options = run_options("bad-filter-should-fail", &output_dir, move |opts| { + opts.values = make_values([("p1", "biscuits")]); + }); let err = template .run(options) From bd6aaa6858bff7db72058be026d683f2dd6a8b0e Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Tue, 2 Jul 2024 15:39:59 +0200 Subject: [PATCH 04/10] Update conformance test version Signed-off-by: Ryan Levick --- Cargo.lock | 10 +++++----- tests/conformance-tests/src/main.rs | 7 ++++--- tests/integration.rs | 26 +++++++++++++------------- tests/runtime-tests/src/lib.rs | 7 ++++++- tests/testcases/mod.rs | 7 ++++--- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 304236d57..7af0a2de7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1496,7 +1496,7 @@ dependencies = [ [[package]] name = "conformance-tests" version = "0.1.0" -source = "git+https://github.com/fermyon/conformance-tests?branch=main#db0ee32a825561d35f884a246e1d390134d78823" +source = "git+https://github.com/fermyon/conformance-tests?branch=main#e846bcebdaaccb317e46387de4dbbc2e39a7199d" dependencies = [ "anyhow", "flate2", @@ -3355,7 +3355,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.6", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -5943,7 +5943,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" dependencies = [ "bytes", - "heck 0.5.0", + "heck 0.4.1", "itertools 0.12.1", "log", "multimap", @@ -8318,7 +8318,7 @@ dependencies = [ [[package]] name = "test-environment" version = "0.1.0" -source = "git+https://github.com/fermyon/conformance-tests?branch=main#db0ee32a825561d35f884a246e1d390134d78823" +source = "git+https://github.com/fermyon/conformance-tests?branch=main#e846bcebdaaccb317e46387de4dbbc2e39a7199d" dependencies = [ "anyhow", "fslock", @@ -8950,7 +8950,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", - "rand 0.8.5", + "rand 0.7.3", "static_assertions", ] diff --git a/tests/conformance-tests/src/main.rs b/tests/conformance-tests/src/main.rs index 28fd66b04..6c67433b9 100644 --- a/tests/conformance-tests/src/main.rs +++ b/tests/conformance-tests/src/main.rs @@ -14,12 +14,13 @@ fn run_test(test: conformance_tests::Test, spin_binary: &std::path::Path) -> any for precondition in test.config.preconditions { match precondition { conformance_tests::config::Precondition::HttpEcho => { - services.push("http-echo".into()); + services.push("http-echo"); } conformance_tests::config::Precondition::TcpEcho => { - services.push("tcp-echo".into()); + services.push("tcp-echo"); } - conformance_tests::config::Precondition::Redis => services.push("redis".into()), + conformance_tests::config::Precondition::Redis => services.push("redis"), + conformance_tests::config::Precondition::Mqtt => services.push("mqtt"), conformance_tests::config::Precondition::KeyValueStore(_) => {} conformance_tests::config::Precondition::Sqlite => {} } diff --git a/tests/integration.rs b/tests/integration.rs index d050bada6..19778fc30 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -109,7 +109,7 @@ mod integration_tests { spin_up_args: Vec::new(), app_type: SpinAppType::Redis, }, - ServicesConfig::new(vec!["redis".into()])?, + ServicesConfig::new(vec!["redis"])?, move |env| { let redis_port = env .services_mut() @@ -167,7 +167,7 @@ mod integration_tests { spin_up_args: Vec::new(), app_type: SpinAppType::Http, }, - ServicesConfig::new(vec!["jaeger".into()])?, + ServicesConfig::new(vec!["jaeger"])?, |env| { let otel_port = env .services_mut() @@ -480,7 +480,7 @@ Caused by: spin_up_args: vec!["--runtime-config-file".into(), "runtime_config.toml".into()], app_type: SpinAppType::Http, }, - ServicesConfig::new(vec!["vault".into()])?, + ServicesConfig::new(vec!["vault"])?, |env| { // Vault can take a few moments to be ready std::thread::sleep(std::time::Duration::from_secs(2)); @@ -730,7 +730,7 @@ Caused by: #[test] #[cfg(feature = "extern-dependencies-tests")] fn registry_works() -> anyhow::Result<()> { - let services = ServicesConfig::new(vec!["registry".into()])?; + let services = ServicesConfig::new(vec!["registry"])?; let spin_up_args = |env: &mut test_environment::TestEnvironment<()>| { let registry_url = format!( "localhost:{}/spin-e2e-tests/registry-works/v1", @@ -747,7 +747,7 @@ Caused by: ]) }; let mut env = super::testcases::bootstrap_smoke_test( - &services, + services, None, None, &[], @@ -786,7 +786,7 @@ Caused by: spin_up_args: Vec::new(), app_type: SpinAppType::Http, }, - ServicesConfig::new(vec!["http-echo".into()])?, + ServicesConfig::new(vec!["http-echo"])?, move |env| { let port = env .get_port(80)? @@ -810,7 +810,7 @@ Caused by: #[test] fn spin_up_gives_help_on_new_app() -> anyhow::Result<()> { - let mut env = test_environment::TestEnvironment::<()>::boot(&ServicesConfig::none())?; + let mut env = test_environment::TestEnvironment::<()>::boot(ServicesConfig::none())?; // We still don't see full help if there are no components. let toml_text = r#"spin_version = "1" @@ -848,7 +848,7 @@ route = "/..." #[test] fn spin_up_help_build_does_not_build() -> anyhow::Result<()> { - let mut env = test_environment::TestEnvironment::<()>::boot(&ServicesConfig::none())?; + let mut env = test_environment::TestEnvironment::<()>::boot(ServicesConfig::none())?; // We still don't see full help if there are no components. let toml_text = r#"spin_version = "1" @@ -891,7 +891,7 @@ route = "/..." #[cfg(not(target_os = "windows"))] #[test] fn test_spin_plugin_install_command() -> anyhow::Result<()> { - let env = test_environment::TestEnvironment::<()>::boot(&ServicesConfig::none())?; + let env = test_environment::TestEnvironment::<()>::boot(ServicesConfig::none())?; let path_to_test_dir = std::env::current_dir()?; let file_url = format!( @@ -1011,7 +1011,7 @@ route = "/..." #[cfg(not(target_os = "windows"))] #[test] fn test_cloud_plugin_autoinstall() -> anyhow::Result<()> { - let env = test_environment::TestEnvironment::<()>::boot(&ServicesConfig::none())?; + let env = test_environment::TestEnvironment::<()>::boot(ServicesConfig::none())?; let mut login = std::process::Command::new(spin_binary()); login @@ -1065,7 +1065,7 @@ route = "/..." }) .collect::>(); - let env = test_environment::TestEnvironment::<()>::boot(&ServicesConfig::none())?; + let env = test_environment::TestEnvironment::<()>::boot(ServicesConfig::none())?; env.copy_into(dir, ".")?; let mut build = std::process::Command::new(spin_binary()); @@ -1178,7 +1178,7 @@ route = "/..." spin_up_args: Vec::new(), app_type: SpinAppType::Http, }, - ServicesConfig::new(vec!["http-responses-from-file".into()])?, + ServicesConfig::new(vec!["http-responses-from-file"])?, move |env| { let service_url = format!( "http://localhost:{}", @@ -1366,7 +1366,7 @@ route = "/..." spin_up_args: Vec::new(), app_type: SpinAppType::Http, }, - ServicesConfig::new(vec!["http-echo".into()])?, + ServicesConfig::new(vec!["http-echo"])?, move |env| { let service_url = format!( "http://localhost:{}", diff --git a/tests/runtime-tests/src/lib.rs b/tests/runtime-tests/src/lib.rs index 1663d653c..560fdd851 100644 --- a/tests/runtime-tests/src/lib.rs +++ b/tests/runtime-tests/src/lib.rs @@ -271,7 +271,12 @@ impl RuntimeTest { fn services_config(config: &RuntimeTestConfig) -> anyhow::Result { let required_services = required_services(&config.test_path)?; - let services_config = ServicesConfig::new(required_services)?; + let services_config = ServicesConfig::new( + required_services + .iter() + .map(String::as_str) + .collect::>(), + )?; Ok(services_config) } diff --git a/tests/testcases/mod.rs b/tests/testcases/mod.rs index 72a9046a1..358518b51 100644 --- a/tests/testcases/mod.rs +++ b/tests/testcases/mod.rs @@ -181,7 +181,7 @@ pub fn http_smoke_test_template_with_route( expected_body: &str, ) -> anyhow::Result<()> { let mut env = bootstrap_smoke_test( - &ServicesConfig::none(), + ServicesConfig::none(), template_url, template_branch, plugins, @@ -214,7 +214,7 @@ pub fn redis_smoke_test_template( ) -> anyhow::Result<()> { use redis::Commands; let mut env = bootstrap_smoke_test( - &test_environment::services::ServicesConfig::new(vec!["redis".into()])?, + test_environment::services::ServicesConfig::new(vec!["redis"])?, template_url, template_branch, plugins, @@ -257,7 +257,7 @@ static TEMPLATE_MUTEX: std::sync::Mutex<()> = std::sync::Mutex::new(()); // TODO: refactor this function to not take so many arguments #[allow(clippy::too_many_arguments)] pub fn bootstrap_smoke_test( - services: &ServicesConfig, + services: ServicesConfig, template_url: Option<&str>, template_branch: Option<&str>, plugins: &[&str], @@ -310,6 +310,7 @@ pub fn bootstrap_smoke_test( "-o", ".", "--accept-defaults", + "--allow-overwrite", ]) .args(new_app_args(&mut env)?); env.run_in(&mut new_app)?; From 1c8fb60241d1e8c0701ca2d19d6212750f44181b Mon Sep 17 00:00:00 2001 From: itowlson Date: Mon, 22 Jul 2024 13:57:18 +1200 Subject: [PATCH 05/10] Break circular dependency between http and testing Signed-off-by: itowlson --- Cargo.lock | 5 ++--- Cargo.toml | 2 +- crates/http/Cargo.toml | 1 - tests/conformance-tests/Cargo.toml | 4 ++-- tests/runtime-tests/Cargo.toml | 2 +- tests/testing-framework/Cargo.toml | 2 +- 6 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7af0a2de7..ee4de0e13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1496,7 +1496,7 @@ dependencies = [ [[package]] name = "conformance-tests" version = "0.1.0" -source = "git+https://github.com/fermyon/conformance-tests?branch=main#e846bcebdaaccb317e46387de4dbbc2e39a7199d" +source = "git+https://github.com/fermyon/conformance-tests?rev=2bb3eb83467a9e9595fa0fd11d7a49fa0300b113#2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" dependencies = [ "anyhow", "flate2", @@ -7512,7 +7512,6 @@ dependencies = [ "serde 1.0.197", "spin-app", "spin-locked-app", - "spin-testing", "toml 0.8.14", "tracing", "wasmtime-wasi-http", @@ -8318,7 +8317,7 @@ dependencies = [ [[package]] name = "test-environment" version = "0.1.0" -source = "git+https://github.com/fermyon/conformance-tests?branch=main#e846bcebdaaccb317e46387de4dbbc2e39a7199d" +source = "git+https://github.com/fermyon/conformance-tests?rev=2bb3eb83467a9e9595fa0fd11d7a49fa0300b113#2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" dependencies = [ "anyhow", "fslock", diff --git a/Cargo.toml b/Cargo.toml index ea379bf18..b7451d1d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,7 +99,7 @@ redis = "0.24" runtime-tests = { path = "tests/runtime-tests" } test-components = { path = "tests/test-components" } test-codegen-macro = { path = "crates/test-codegen-macro" } -test-environment = { git = "https://github.com/fermyon/conformance-tests", branch = "main" } +test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } [build-dependencies] cargo-target-dep = { git = "https://github.com/fermyon/cargo-target-dep", rev = "482f269eceb7b1a7e8fc618bf8c082dd24979cf1" } diff --git a/crates/http/Cargo.toml b/crates/http/Cargo.toml index fc30406e5..4c993a13f 100644 --- a/crates/http/Cargo.toml +++ b/crates/http/Cargo.toml @@ -19,7 +19,6 @@ spin-app = { path = "../app", optional = true } spin-locked-app = { path = "../locked-app" } [dev-dependencies] -spin-testing = { path = "../testing" } toml = "0.8.2" [features] diff --git a/tests/conformance-tests/Cargo.toml b/tests/conformance-tests/Cargo.toml index 5c455f181..9d29361b2 100644 --- a/tests/conformance-tests/Cargo.toml +++ b/tests/conformance-tests/Cargo.toml @@ -11,8 +11,8 @@ rust-version.workspace = true [dependencies] anyhow = "1.0" testing-framework = { path = "../testing-framework" } -conformance-tests = { git = "https://github.com/fermyon/conformance-tests", branch = "main" } -test-environment = { git = "https://github.com/fermyon/conformance-tests", branch = "main" } +conformance-tests = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } +test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } [lints] workspace = true diff --git a/tests/runtime-tests/Cargo.toml b/tests/runtime-tests/Cargo.toml index de3cdc8a0..6376f946c 100644 --- a/tests/runtime-tests/Cargo.toml +++ b/tests/runtime-tests/Cargo.toml @@ -13,5 +13,5 @@ anyhow = "1.0" env_logger = "0.10.0" log = "0.4" testing-framework = { path = "../testing-framework" } -test-environment = { git = "https://github.com/fermyon/conformance-tests", branch = "main" } +test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } test-components = { path = "../test-components" } diff --git a/tests/testing-framework/Cargo.toml b/tests/testing-framework/Cargo.toml index 80d70d48e..7656f908c 100644 --- a/tests/testing-framework/Cargo.toml +++ b/tests/testing-framework/Cargo.toml @@ -13,7 +13,7 @@ nix = "0.26.1" regex = "1.10.2" reqwest = { workspace = true } temp-dir = "0.1.11" -test-environment = { git = "https://github.com/fermyon/conformance-tests", branch = "main" } +test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } spin-trigger-http = { path = "../../crates/trigger-http" } spin-http = { path = "../../crates/http" } spin-trigger = { path = "../../crates/trigger" } From 1193847619caf2feb925825079525ebe02f46ab2 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Mon, 22 Jul 2024 13:07:26 +0200 Subject: [PATCH 06/10] Fix CI issue in integration tests by updating conformance-test dependency Signed-off-by: Ryan Levick --- Cargo.lock | 4 ++-- Cargo.toml | 6 ++++-- tests/conformance-tests/Cargo.toml | 4 ++-- tests/runtime-tests/Cargo.toml | 2 +- tests/testing-framework/Cargo.toml | 2 +- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee4de0e13..7b178cb5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1496,7 +1496,7 @@ dependencies = [ [[package]] name = "conformance-tests" version = "0.1.0" -source = "git+https://github.com/fermyon/conformance-tests?rev=2bb3eb83467a9e9595fa0fd11d7a49fa0300b113#2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" +source = "git+https://github.com/fermyon/conformance-tests?rev=d2129a3fd73140a76c77f15a030a5273b37cbd11#d2129a3fd73140a76c77f15a030a5273b37cbd11" dependencies = [ "anyhow", "flate2", @@ -8317,7 +8317,7 @@ dependencies = [ [[package]] name = "test-environment" version = "0.1.0" -source = "git+https://github.com/fermyon/conformance-tests?rev=2bb3eb83467a9e9595fa0fd11d7a49fa0300b113#2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" +source = "git+https://github.com/fermyon/conformance-tests?rev=d2129a3fd73140a76c77f15a030a5273b37cbd11#d2129a3fd73140a76c77f15a030a5273b37cbd11" dependencies = [ "anyhow", "fslock", diff --git a/Cargo.toml b/Cargo.toml index b7451d1d5..eeef23326 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,7 +99,7 @@ redis = "0.24" runtime-tests = { path = "tests/runtime-tests" } test-components = { path = "tests/test-components" } test-codegen-macro = { path = "crates/test-codegen-macro" } -test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } +test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "d2129a3fd73140a76c77f15a030a5273b37cbd11" } [build-dependencies] cargo-target-dep = { git = "https://github.com/fermyon/cargo-target-dep", rev = "482f269eceb7b1a7e8fc618bf8c082dd24979cf1" } @@ -134,7 +134,9 @@ hyper = { version = "1.0.0", features = ["full"] } reqwest = { version = "0.12", features = ["stream", "blocking"] } tracing = { version = "0.1", features = ["log"] } -wasi-common-preview1 = { version = "22.0.0", package = "wasi-common", features = ["tokio"] } +wasi-common-preview1 = { version = "22.0.0", package = "wasi-common", features = [ + "tokio", +] } wasmtime = "22.0.0" wasmtime-wasi = "22.0.0" wasmtime-wasi-http = "22.0.0" diff --git a/tests/conformance-tests/Cargo.toml b/tests/conformance-tests/Cargo.toml index 9d29361b2..8f97d2b01 100644 --- a/tests/conformance-tests/Cargo.toml +++ b/tests/conformance-tests/Cargo.toml @@ -11,8 +11,8 @@ rust-version.workspace = true [dependencies] anyhow = "1.0" testing-framework = { path = "../testing-framework" } -conformance-tests = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } -test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } +conformance-tests = { git = "https://github.com/fermyon/conformance-tests", rev = "d2129a3fd73140a76c77f15a030a5273b37cbd11" } +test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "d2129a3fd73140a76c77f15a030a5273b37cbd11" } [lints] workspace = true diff --git a/tests/runtime-tests/Cargo.toml b/tests/runtime-tests/Cargo.toml index 6376f946c..6e0f7a7df 100644 --- a/tests/runtime-tests/Cargo.toml +++ b/tests/runtime-tests/Cargo.toml @@ -13,5 +13,5 @@ anyhow = "1.0" env_logger = "0.10.0" log = "0.4" testing-framework = { path = "../testing-framework" } -test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } +test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "d2129a3fd73140a76c77f15a030a5273b37cbd11" } test-components = { path = "../test-components" } diff --git a/tests/testing-framework/Cargo.toml b/tests/testing-framework/Cargo.toml index 7656f908c..a8caa973a 100644 --- a/tests/testing-framework/Cargo.toml +++ b/tests/testing-framework/Cargo.toml @@ -13,7 +13,7 @@ nix = "0.26.1" regex = "1.10.2" reqwest = { workspace = true } temp-dir = "0.1.11" -test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "2bb3eb83467a9e9595fa0fd11d7a49fa0300b113" } +test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "d2129a3fd73140a76c77f15a030a5273b37cbd11" } spin-trigger-http = { path = "../../crates/trigger-http" } spin-http = { path = "../../crates/http" } spin-trigger = { path = "../../crates/trigger" } From 3a12b68723536f3f07204a9e7b990f604b059725 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 17 Jul 2024 15:59:13 +0200 Subject: [PATCH 07/10] Run conformance tests as part of runtime tests Signed-off-by: Ryan Levick --- Cargo.lock | 2 + Cargo.toml | 2 + tests/conformance-tests/src/lib.rs | 59 +++++++++++++++++++ tests/conformance-tests/src/main.rs | 58 +----------------- .../tests/key-value-no-permission/error.txt | 1 - .../tests/key-value-no-permission/spin.toml | 13 ---- tests/runtime-tests/tests/key-value/spin.toml | 14 ----- .../services | 1 - .../spin.toml | 19 ------ .../tests/outbound-mqtt/services | 1 - .../tests/outbound-mqtt/spin.toml | 16 ----- .../outbound-redis-no-permission/error.txt | 1 - .../outbound-redis-no-permission/spin.toml | 14 ----- .../services | 1 - .../spin.toml | 18 ------ .../tests/outbound-redis/services | 1 - .../tests/outbound-redis/spin.toml | 15 ----- .../tests/sqlite-no-permission/error.txt | 1 - .../tests/sqlite-no-permission/spin.toml | 13 ---- tests/runtime-tests/tests/sqlite/spin.toml | 14 ----- .../services | 1 - .../spin.toml | 19 ------ .../tests/tcp-sockets-ip-range/services | 1 - .../tests/tcp-sockets-ip-range/spin.toml | 15 ----- .../tcp-sockets-no-ip-permission/error.txt | 1 - .../tcp-sockets-no-ip-permission/spin.toml | 16 ----- .../tcp-sockets-no-port-permission/error.txt | 1 - .../tcp-sockets-no-port-permission/spin.toml | 16 ----- .../runtime-tests/tests/tcp-sockets/services | 1 - .../runtime-tests/tests/tcp-sockets/spin.toml | 15 ----- tests/runtime-tests/tests/variables/spin.toml | 16 ----- tests/runtime.rs | 10 ++++ 32 files changed, 74 insertions(+), 302 deletions(-) create mode 100644 tests/conformance-tests/src/lib.rs delete mode 100644 tests/runtime-tests/tests/key-value-no-permission/error.txt delete mode 100644 tests/runtime-tests/tests/key-value-no-permission/spin.toml delete mode 100644 tests/runtime-tests/tests/key-value/spin.toml delete mode 100644 tests/runtime-tests/tests/outbound-mqtt-variable-permission/services delete mode 100644 tests/runtime-tests/tests/outbound-mqtt-variable-permission/spin.toml delete mode 100644 tests/runtime-tests/tests/outbound-mqtt/services delete mode 100644 tests/runtime-tests/tests/outbound-mqtt/spin.toml delete mode 100644 tests/runtime-tests/tests/outbound-redis-no-permission/error.txt delete mode 100644 tests/runtime-tests/tests/outbound-redis-no-permission/spin.toml delete mode 100644 tests/runtime-tests/tests/outbound-redis-variable-permission/services delete mode 100644 tests/runtime-tests/tests/outbound-redis-variable-permission/spin.toml delete mode 100644 tests/runtime-tests/tests/outbound-redis/services delete mode 100644 tests/runtime-tests/tests/outbound-redis/spin.toml delete mode 100644 tests/runtime-tests/tests/sqlite-no-permission/error.txt delete mode 100644 tests/runtime-tests/tests/sqlite-no-permission/spin.toml delete mode 100644 tests/runtime-tests/tests/sqlite/spin.toml delete mode 100644 tests/runtime-tests/tests/tcp-sockets-ip-range-variable-permission/services delete mode 100644 tests/runtime-tests/tests/tcp-sockets-ip-range-variable-permission/spin.toml delete mode 100644 tests/runtime-tests/tests/tcp-sockets-ip-range/services delete mode 100644 tests/runtime-tests/tests/tcp-sockets-ip-range/spin.toml delete mode 100644 tests/runtime-tests/tests/tcp-sockets-no-ip-permission/error.txt delete mode 100644 tests/runtime-tests/tests/tcp-sockets-no-ip-permission/spin.toml delete mode 100644 tests/runtime-tests/tests/tcp-sockets-no-port-permission/error.txt delete mode 100644 tests/runtime-tests/tests/tcp-sockets-no-port-permission/spin.toml delete mode 100644 tests/runtime-tests/tests/tcp-sockets/services delete mode 100644 tests/runtime-tests/tests/tcp-sockets/spin.toml delete mode 100644 tests/runtime-tests/tests/variables/spin.toml diff --git a/Cargo.lock b/Cargo.lock index 7b178cb5e..059b77d4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7328,6 +7328,8 @@ dependencies = [ "clearscreen", "comfy-table", "command-group", + "conformance", + "conformance-tests", "ctrlc", "dialoguer 0.10.4", "dirs 4.0.0", diff --git a/Cargo.toml b/Cargo.toml index eeef23326..8497b1e1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,6 +100,8 @@ runtime-tests = { path = "tests/runtime-tests" } test-components = { path = "tests/test-components" } test-codegen-macro = { path = "crates/test-codegen-macro" } test-environment = { git = "https://github.com/fermyon/conformance-tests", rev = "d2129a3fd73140a76c77f15a030a5273b37cbd11" } +conformance-tests = { git = "https://github.com/fermyon/conformance-tests", rev = "d2129a3fd73140a76c77f15a030a5273b37cbd11" } +conformance = { path = "tests/conformance-tests" } [build-dependencies] cargo-target-dep = { git = "https://github.com/fermyon/cargo-target-dep", rev = "482f269eceb7b1a7e8fc618bf8c082dd24979cf1" } diff --git a/tests/conformance-tests/src/lib.rs b/tests/conformance-tests/src/lib.rs new file mode 100644 index 000000000..fc64621a2 --- /dev/null +++ b/tests/conformance-tests/src/lib.rs @@ -0,0 +1,59 @@ +use anyhow::Context as _; +use testing_framework::runtimes::spin_cli::{SpinCli, SpinConfig}; + +/// Run a single conformance test against the supplied spin binary. +pub fn run_test( + test: conformance_tests::Test, + spin_binary: &std::path::Path, +) -> anyhow::Result<()> { + let mut services = Vec::new(); + for precondition in test.config.preconditions { + match precondition { + conformance_tests::config::Precondition::HttpEcho => { + services.push("http-echo"); + } + conformance_tests::config::Precondition::TcpEcho => { + services.push("tcp-echo"); + } + conformance_tests::config::Precondition::Redis => services.push("redis"), + conformance_tests::config::Precondition::Mqtt => services.push("mqtt"), + conformance_tests::config::Precondition::KeyValueStore(_) => {} + conformance_tests::config::Precondition::Sqlite => {} + } + } + let env_config = SpinCli::config( + SpinConfig { + binary_path: spin_binary.to_owned(), + spin_up_args: Vec::new(), + app_type: testing_framework::runtimes::SpinAppType::Http, + }, + test_environment::services::ServicesConfig::new(services)?, + move |e| { + let mut manifest = + test_environment::manifest_template::EnvTemplate::from_file(&test.manifest)?; + manifest.substitute(e, |_| None)?; + e.write_file("spin.toml", manifest.contents())?; + e.copy_into(&test.component, test.component.file_name().unwrap())?; + Ok(()) + }, + ); + let mut env = test_environment::TestEnvironment::up(env_config, |_| Ok(()))?; + for invocation in test.config.invocations { + let conformance_tests::config::Invocation::Http(mut invocation) = invocation; + invocation.request.substitute_from_env(&mut env)?; + let spin = env.runtime_mut(); + let actual = invocation + .request + .send(|request| spin.make_http_request(request))?; + + conformance_tests::assertions::assert_response(&invocation.response, &actual) + .with_context(|| { + format!( + "Failed assertion.\nstdout: {}\nstderr: {}", + spin.stdout().to_owned(), + spin.stderr() + ) + })?; + } + Ok(()) +} diff --git a/tests/conformance-tests/src/main.rs b/tests/conformance-tests/src/main.rs index 6c67433b9..38b97a6bd 100644 --- a/tests/conformance-tests/src/main.rs +++ b/tests/conformance-tests/src/main.rs @@ -1,63 +1,7 @@ -use anyhow::Context as _; -use testing_framework::runtimes::spin_cli::{SpinCli, SpinConfig}; - fn main() { let spin_binary: std::path::PathBuf = std::env::args() .nth(1) .expect("expected first argument to be path to spin binary") .into(); - conformance_tests::run_tests(move |test| run_test(test, &spin_binary)).unwrap(); -} - -fn run_test(test: conformance_tests::Test, spin_binary: &std::path::Path) -> anyhow::Result<()> { - let mut services = Vec::new(); - for precondition in test.config.preconditions { - match precondition { - conformance_tests::config::Precondition::HttpEcho => { - services.push("http-echo"); - } - conformance_tests::config::Precondition::TcpEcho => { - services.push("tcp-echo"); - } - conformance_tests::config::Precondition::Redis => services.push("redis"), - conformance_tests::config::Precondition::Mqtt => services.push("mqtt"), - conformance_tests::config::Precondition::KeyValueStore(_) => {} - conformance_tests::config::Precondition::Sqlite => {} - } - } - let env_config = SpinCli::config( - SpinConfig { - binary_path: spin_binary.to_owned(), - spin_up_args: Vec::new(), - app_type: testing_framework::runtimes::SpinAppType::Http, - }, - test_environment::services::ServicesConfig::new(services)?, - move |e| { - let mut manifest = - test_environment::manifest_template::EnvTemplate::from_file(&test.manifest)?; - manifest.substitute(e, |_| None)?; - e.write_file("spin.toml", manifest.contents())?; - e.copy_into(&test.component, test.component.file_name().unwrap())?; - Ok(()) - }, - ); - let mut env = test_environment::TestEnvironment::up(env_config, |_| Ok(()))?; - for invocation in test.config.invocations { - let conformance_tests::config::Invocation::Http(mut invocation) = invocation; - invocation.request.substitute_from_env(&mut env)?; - let spin = env.runtime_mut(); - let actual = invocation - .request - .send(|request| spin.make_http_request(request))?; - - conformance_tests::assertions::assert_response(&invocation.response, &actual) - .with_context(|| { - format!( - "Failed assertion.\nstdout: {}\nstderr: {}", - spin.stdout().to_owned(), - spin.stderr() - ) - })?; - } - Ok(()) + conformance_tests::run_tests(move |test| conformance::run_test(test, &spin_binary)).unwrap(); } diff --git a/tests/runtime-tests/tests/key-value-no-permission/error.txt b/tests/runtime-tests/tests/key-value-no-permission/error.txt deleted file mode 100644 index 11a87ef97..000000000 --- a/tests/runtime-tests/tests/key-value-no-permission/error.txt +++ /dev/null @@ -1 +0,0 @@ -Error::AccessDenied \ No newline at end of file diff --git a/tests/runtime-tests/tests/key-value-no-permission/spin.toml b/tests/runtime-tests/tests/key-value-no-permission/spin.toml deleted file mode 100644 index a9eee3a87..000000000 --- a/tests/runtime-tests/tests/key-value-no-permission/spin.toml +++ /dev/null @@ -1,13 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "key-value" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=key-value}" diff --git a/tests/runtime-tests/tests/key-value/spin.toml b/tests/runtime-tests/tests/key-value/spin.toml deleted file mode 100644 index ce7c2853c..000000000 --- a/tests/runtime-tests/tests/key-value/spin.toml +++ /dev/null @@ -1,14 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "key-value" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=key-value}" -key_value_stores = ["default"] diff --git a/tests/runtime-tests/tests/outbound-mqtt-variable-permission/services b/tests/runtime-tests/tests/outbound-mqtt-variable-permission/services deleted file mode 100644 index 1d00b34f3..000000000 --- a/tests/runtime-tests/tests/outbound-mqtt-variable-permission/services +++ /dev/null @@ -1 +0,0 @@ -mqtt \ No newline at end of file diff --git a/tests/runtime-tests/tests/outbound-mqtt-variable-permission/spin.toml b/tests/runtime-tests/tests/outbound-mqtt-variable-permission/spin.toml deleted file mode 100644 index ffff0180d..000000000 --- a/tests/runtime-tests/tests/outbound-mqtt-variable-permission/spin.toml +++ /dev/null @@ -1,19 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "outbound-mqtt" -authors = ["Suneet Nangia "] -version = "0.1.0" - -[variables] -mqtt_server = { default = "localhost" } - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=outbound-mqtt}" -allowed_outbound_hosts = ["mqtt://{{ mqtt_server }}:%{port=1883}"] -# To test anonymous MQTT authentication, remove the values from MQTT_USERNAME and MQTT_PASSWORD env variables. -environment = { MQTT_ADDRESS = "mqtt://localhost:%{port=1883}?client_id=spintest", MQTT_USERNAME = "user", MQTT_PASSWORD = "password", MQTT_KEEP_ALIVE_INTERVAL = "30" } diff --git a/tests/runtime-tests/tests/outbound-mqtt/services b/tests/runtime-tests/tests/outbound-mqtt/services deleted file mode 100644 index 1d00b34f3..000000000 --- a/tests/runtime-tests/tests/outbound-mqtt/services +++ /dev/null @@ -1 +0,0 @@ -mqtt \ No newline at end of file diff --git a/tests/runtime-tests/tests/outbound-mqtt/spin.toml b/tests/runtime-tests/tests/outbound-mqtt/spin.toml deleted file mode 100644 index a1b03ed47..000000000 --- a/tests/runtime-tests/tests/outbound-mqtt/spin.toml +++ /dev/null @@ -1,16 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "outbound-mqtt" -authors = ["Suneet Nangia "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=outbound-mqtt}" -allowed_outbound_hosts = ["mqtt://localhost:%{port=1883}"] -# To test anonymous MQTT authentication, remove the values from MQTT_USERNAME and MQTT_PASSWORD env variables. -environment = { MQTT_ADDRESS = "mqtt://localhost:%{port=1883}?client_id=spintest", MQTT_USERNAME = "user", MQTT_PASSWORD = "password", MQTT_KEEP_ALIVE_INTERVAL = "30" } diff --git a/tests/runtime-tests/tests/outbound-redis-no-permission/error.txt b/tests/runtime-tests/tests/outbound-redis-no-permission/error.txt deleted file mode 100644 index bdb4a74a8..000000000 --- a/tests/runtime-tests/tests/outbound-redis-no-permission/error.txt +++ /dev/null @@ -1 +0,0 @@ -Error::InvalidAddress \ No newline at end of file diff --git a/tests/runtime-tests/tests/outbound-redis-no-permission/spin.toml b/tests/runtime-tests/tests/outbound-redis-no-permission/spin.toml deleted file mode 100644 index 95e75b14b..000000000 --- a/tests/runtime-tests/tests/outbound-redis-no-permission/spin.toml +++ /dev/null @@ -1,14 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "outbound-redis" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=outbound-redis}" -environment = { REDIS_ADDRESS = "redis://localhost:6379" } diff --git a/tests/runtime-tests/tests/outbound-redis-variable-permission/services b/tests/runtime-tests/tests/outbound-redis-variable-permission/services deleted file mode 100644 index 74b362f93..000000000 --- a/tests/runtime-tests/tests/outbound-redis-variable-permission/services +++ /dev/null @@ -1 +0,0 @@ -redis \ No newline at end of file diff --git a/tests/runtime-tests/tests/outbound-redis-variable-permission/spin.toml b/tests/runtime-tests/tests/outbound-redis-variable-permission/spin.toml deleted file mode 100644 index 176e5b14a..000000000 --- a/tests/runtime-tests/tests/outbound-redis-variable-permission/spin.toml +++ /dev/null @@ -1,18 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "outbound-redis" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[variables] -redis_host = { default = "localhost" } - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=outbound-redis}" -environment = { REDIS_ADDRESS = "redis://localhost:%{port=6379}" } -allowed_outbound_hosts = ["redis://{{ redis_host }}:%{port=6379}"] diff --git a/tests/runtime-tests/tests/outbound-redis/services b/tests/runtime-tests/tests/outbound-redis/services deleted file mode 100644 index 74b362f93..000000000 --- a/tests/runtime-tests/tests/outbound-redis/services +++ /dev/null @@ -1 +0,0 @@ -redis \ No newline at end of file diff --git a/tests/runtime-tests/tests/outbound-redis/spin.toml b/tests/runtime-tests/tests/outbound-redis/spin.toml deleted file mode 100644 index 15b54a338..000000000 --- a/tests/runtime-tests/tests/outbound-redis/spin.toml +++ /dev/null @@ -1,15 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "outbound-redis" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=outbound-redis}" -environment = { REDIS_ADDRESS = "redis://localhost:%{port=6379}" } -allowed_outbound_hosts = ["redis://localhost:%{port=6379}"] diff --git a/tests/runtime-tests/tests/sqlite-no-permission/error.txt b/tests/runtime-tests/tests/sqlite-no-permission/error.txt deleted file mode 100644 index 11a87ef97..000000000 --- a/tests/runtime-tests/tests/sqlite-no-permission/error.txt +++ /dev/null @@ -1 +0,0 @@ -Error::AccessDenied \ No newline at end of file diff --git a/tests/runtime-tests/tests/sqlite-no-permission/spin.toml b/tests/runtime-tests/tests/sqlite-no-permission/spin.toml deleted file mode 100644 index b684a86ed..000000000 --- a/tests/runtime-tests/tests/sqlite-no-permission/spin.toml +++ /dev/null @@ -1,13 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "sqlite" -authors = ["Ryan Levick "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=sqlite}" diff --git a/tests/runtime-tests/tests/sqlite/spin.toml b/tests/runtime-tests/tests/sqlite/spin.toml deleted file mode 100644 index 1bc45fc4e..000000000 --- a/tests/runtime-tests/tests/sqlite/spin.toml +++ /dev/null @@ -1,14 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "sqlite" -authors = ["Ryan Levick "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=sqlite}" -sqlite_databases = ["default"] diff --git a/tests/runtime-tests/tests/tcp-sockets-ip-range-variable-permission/services b/tests/runtime-tests/tests/tcp-sockets-ip-range-variable-permission/services deleted file mode 100644 index 272b7c063..000000000 --- a/tests/runtime-tests/tests/tcp-sockets-ip-range-variable-permission/services +++ /dev/null @@ -1 +0,0 @@ -tcp-echo \ No newline at end of file diff --git a/tests/runtime-tests/tests/tcp-sockets-ip-range-variable-permission/spin.toml b/tests/runtime-tests/tests/tcp-sockets-ip-range-variable-permission/spin.toml deleted file mode 100644 index e50614a93..000000000 --- a/tests/runtime-tests/tests/tcp-sockets-ip-range-variable-permission/spin.toml +++ /dev/null @@ -1,19 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "tcp-sockets" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[variables] -addr_prefix = { default = "127.0.0.0" } -prefix_len = { default = "24" } - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=tcp-sockets}" -environment = { ADDRESS = "127.0.0.1:%{port=7}" } -allowed_outbound_hosts = ["*://{{ addr_prefix }}/{{ prefix_len }}:%{port=7}"] diff --git a/tests/runtime-tests/tests/tcp-sockets-ip-range/services b/tests/runtime-tests/tests/tcp-sockets-ip-range/services deleted file mode 100644 index 272b7c063..000000000 --- a/tests/runtime-tests/tests/tcp-sockets-ip-range/services +++ /dev/null @@ -1 +0,0 @@ -tcp-echo \ No newline at end of file diff --git a/tests/runtime-tests/tests/tcp-sockets-ip-range/spin.toml b/tests/runtime-tests/tests/tcp-sockets-ip-range/spin.toml deleted file mode 100644 index b4f36489f..000000000 --- a/tests/runtime-tests/tests/tcp-sockets-ip-range/spin.toml +++ /dev/null @@ -1,15 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "tcp-sockets" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=tcp-sockets}" -environment = { ADDRESS = "127.0.0.1:%{port=7}" } -allowed_outbound_hosts = ["*://127.0.0.0/24:%{port=7}"] diff --git a/tests/runtime-tests/tests/tcp-sockets-no-ip-permission/error.txt b/tests/runtime-tests/tests/tcp-sockets-no-ip-permission/error.txt deleted file mode 100644 index d62c3f596..000000000 --- a/tests/runtime-tests/tests/tcp-sockets-no-ip-permission/error.txt +++ /dev/null @@ -1 +0,0 @@ -access-denied \ No newline at end of file diff --git a/tests/runtime-tests/tests/tcp-sockets-no-ip-permission/spin.toml b/tests/runtime-tests/tests/tcp-sockets-no-ip-permission/spin.toml deleted file mode 100644 index f85b16be7..000000000 --- a/tests/runtime-tests/tests/tcp-sockets-no-ip-permission/spin.toml +++ /dev/null @@ -1,16 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "tcp-sockets" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=tcp-sockets}" -environment = { ADDRESS = "127.0.0.1:6001" } -# Component expects 127.0.0.1 but we only allow 127.0.0.2 -allowed_outbound_hosts = ["*://127.0.0.2:6001"] diff --git a/tests/runtime-tests/tests/tcp-sockets-no-port-permission/error.txt b/tests/runtime-tests/tests/tcp-sockets-no-port-permission/error.txt deleted file mode 100644 index d62c3f596..000000000 --- a/tests/runtime-tests/tests/tcp-sockets-no-port-permission/error.txt +++ /dev/null @@ -1 +0,0 @@ -access-denied \ No newline at end of file diff --git a/tests/runtime-tests/tests/tcp-sockets-no-port-permission/spin.toml b/tests/runtime-tests/tests/tcp-sockets-no-port-permission/spin.toml deleted file mode 100644 index 4c1b72ce2..000000000 --- a/tests/runtime-tests/tests/tcp-sockets-no-port-permission/spin.toml +++ /dev/null @@ -1,16 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "tcp-sockets" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=tcp-sockets}" -environment = { ADDRESS = "127.0.0.1:6001" } -# Component expects port 6001 but we allow 6002 -allowed_outbound_hosts = ["*://127.0.0.1:6002"] diff --git a/tests/runtime-tests/tests/tcp-sockets/services b/tests/runtime-tests/tests/tcp-sockets/services deleted file mode 100644 index 272b7c063..000000000 --- a/tests/runtime-tests/tests/tcp-sockets/services +++ /dev/null @@ -1 +0,0 @@ -tcp-echo \ No newline at end of file diff --git a/tests/runtime-tests/tests/tcp-sockets/spin.toml b/tests/runtime-tests/tests/tcp-sockets/spin.toml deleted file mode 100644 index 6bb3526f9..000000000 --- a/tests/runtime-tests/tests/tcp-sockets/spin.toml +++ /dev/null @@ -1,15 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "tcp-sockets" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=tcp-sockets}" -environment = { ADDRESS = "127.0.0.1:%{port=7}" } -allowed_outbound_hosts = ["*://127.0.0.1:%{port=7}"] diff --git a/tests/runtime-tests/tests/variables/spin.toml b/tests/runtime-tests/tests/variables/spin.toml deleted file mode 100644 index a961fbd89..000000000 --- a/tests/runtime-tests/tests/variables/spin.toml +++ /dev/null @@ -1,16 +0,0 @@ -spin_manifest_version = 2 - -[application] -name = "variables" -authors = ["Fermyon Engineering "] -version = "0.1.0" - -[[trigger.http]] -route = "/" -component = "test" - -[component.test] -source = "%{source=variables}" - -[component.test.variables] -variable = "value" diff --git a/tests/runtime.rs b/tests/runtime.rs index d541313e7..e2cb1ee79 100644 --- a/tests/runtime.rs +++ b/tests/runtime.rs @@ -25,4 +25,14 @@ mod runtime_tests { .expect("failed to bootstrap runtime tests tests") .run(); } + + #[test] + fn conformance_tests() { + conformance_tests::run_tests(move |test| conformance::run_test(test, &spin_binary())) + .unwrap(); + } + + fn spin_binary() -> PathBuf { + env!("CARGO_BIN_EXE_spin").into() + } } From f83eaa537be4155f3f180accfc737e8ea8a74fb6 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Mon, 1 Jul 2024 17:14:04 +0200 Subject: [PATCH 08/10] Allow sqlite migrations for non-default databases. The database will be selected by the name of the migration file. This makes the name of the migration file significant, whereas previously it was not. If the name of the file and a known database don't line up, `spin up` will fail with an error message. Signed-off-by: Ryan Levick --- crates/trigger/src/runtime_config/sqlite.rs | 22 +++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/crates/trigger/src/runtime_config/sqlite.rs b/crates/trigger/src/runtime_config/sqlite.rs index 6fc7c482e..8c48a296f 100644 --- a/crates/trigger/src/runtime_config/sqlite.rs +++ b/crates/trigger/src/runtime_config/sqlite.rs @@ -49,24 +49,30 @@ async fn execute_statements( if statements.is_empty() { return Ok(()); } - let Some(default) = databases.get("default") else { - debug_assert!( - false, - "the 'default' sqlite database should always be available but for some reason was not" - ); - return Ok(()); - }; for m in statements { if let Some(file) = m.strip_prefix('@') { + let database = file.strip_suffix(".sql").unwrap_or(file); + let database = databases.get(database).with_context(|| { + format!( + "based on the sql file '{file}' a registered database named '{database}' was expected but not found. The registered databases are '{:?}'", databases.keys() + ) + })?; let sql = std::fs::read_to_string(file).with_context(|| { format!("could not read file '{file}' containing sql statements") })?; - default + database .execute_batch(&sql) .await .with_context(|| format!("failed to execute sql from file '{file}'"))?; } else { + let Some(default) = databases.get("default") else { + debug_assert!( + false, + "the 'default' sqlite database should always be available but for some reason was not" + ); + return Ok(()); + }; default .query(m, Vec::new()) .await From d936d473562d65a79b3d997bfe2c5a45ffc9613d Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 3 Jul 2024 15:01:49 +0200 Subject: [PATCH 09/10] Don't use migration file name but a ':database' suffix Signed-off-by: Ryan Levick --- crates/trigger/src/runtime_config/sqlite.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/trigger/src/runtime_config/sqlite.rs b/crates/trigger/src/runtime_config/sqlite.rs index 8c48a296f..8d4e2da3a 100644 --- a/crates/trigger/src/runtime_config/sqlite.rs +++ b/crates/trigger/src/runtime_config/sqlite.rs @@ -51,11 +51,16 @@ async fn execute_statements( } for m in statements { - if let Some(file) = m.strip_prefix('@') { - let database = file.strip_suffix(".sql").unwrap_or(file); + if let Some(config) = m.strip_prefix('@') { + let config = config.trim(); + let (file, database) = match config.split_once(':') { + Some((file, database)) if database.trim().is_empty() => (file.trim(), "default"), + Some((file, database)) => (file.trim(), database.trim()), + None => (config, "default"), + }; let database = databases.get(database).with_context(|| { format!( - "based on the sql file '{file}' a registered database named '{database}' was expected but not found. The registered databases are '{:?}'", databases.keys() + "based on the '@{config}' a registered database named '{database}' was expected but not found. The registered databases are '{:?}'", databases.keys() ) })?; let sql = std::fs::read_to_string(file).with_context(|| { From 096904eb1ef6aea5705b6e50afd5dc88a8291e66 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Mon, 22 Jul 2024 13:22:52 +0200 Subject: [PATCH 10/10] PR Feedback Signed-off-by: Ryan Levick --- crates/trigger/src/runtime_config/sqlite.rs | 45 ++++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/crates/trigger/src/runtime_config/sqlite.rs b/crates/trigger/src/runtime_config/sqlite.rs index 8d4e2da3a..5163791e9 100644 --- a/crates/trigger/src/runtime_config/sqlite.rs +++ b/crates/trigger/src/runtime_config/sqlite.rs @@ -52,12 +52,7 @@ async fn execute_statements( for m in statements { if let Some(config) = m.strip_prefix('@') { - let config = config.trim(); - let (file, database) = match config.split_once(':') { - Some((file, database)) if database.trim().is_empty() => (file.trim(), "default"), - Some((file, database)) => (file.trim(), database.trim()), - None => (config, "default"), - }; + let (file, database) = parse_file_and_label(config)?; let database = databases.get(database).with_context(|| { format!( "based on the '@{config}' a registered database named '{database}' was expected but not found. The registered databases are '{:?}'", databases.keys() @@ -72,10 +67,7 @@ async fn execute_statements( .with_context(|| format!("failed to execute sql from file '{file}'"))?; } else { let Some(default) = databases.get("default") else { - debug_assert!( - false, - "the 'default' sqlite database should always be available but for some reason was not" - ); + debug_assert!(false, "the 'default' sqlite database should always be available but for some reason was not"); return Ok(()); }; default @@ -87,6 +79,19 @@ async fn execute_statements( Ok(()) } +/// Parses a @{file:label} sqlite statement +fn parse_file_and_label(config: &str) -> anyhow::Result<(&str, &str)> { + let config = config.trim(); + let (file, label) = match config.split_once(':') { + Some((_, label)) if label.trim().is_empty() => { + anyhow::bail!("database label is empty in the '@{config}' sqlite statement") + } + Some((file, label)) => (file.trim(), label.trim()), + None => (config, "default"), + }; + Ok((file, label)) +} + // Holds deserialized options from a `[sqlite_database.]` runtime config section. #[derive(Clone, Debug, serde::Deserialize)] #[serde(rename_all = "snake_case", tag = "type")] @@ -213,3 +218,23 @@ impl TriggerHooks for SqlitePersistenceMessageHook { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_parse_file_and_label() { + let config = "file:label"; + let result = parse_file_and_label(config).unwrap(); + assert_eq!(result, ("file", "label")); + + let config = "file:"; + let result = parse_file_and_label(config); + assert!(result.is_err()); + + let config = "file"; + let result = parse_file_and_label(config).unwrap(); + assert_eq!(result, ("file", "default")); + } +}