From cbea533457b332fb6af5251a8c510e70ca353297 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Fri, 12 Jan 2024 15:37:10 +0100 Subject: [PATCH] Put e2e tests back into module Signed-off-by: Ryan Levick --- .github/workflows/build.yml | 2 +- tests/spinup_tests.rs | 852 +++++++++--------- .../test-components/components/llm/src/lib.rs | 2 +- tests/testcases/mod.rs | 29 +- 4 files changed, 453 insertions(+), 432 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd9b7337b6..d3c719f80b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,7 +42,7 @@ jobs: run: BUILD_SPIN_EXAMPLES=0 make lint - name: Run lints on examples - run: BUILD_SPIN_EXAMPLES=0 make lint-rust-examples-and-testcases + run: BUILD_SPIN_EXAMPLES=0 make lint-rust-examples - name: Cancel everything if linting fails if: failure() diff --git a/tests/spinup_tests.rs b/tests/spinup_tests.rs index e809174523..d5c218d8d3 100644 --- a/tests/spinup_tests.rs +++ b/tests/spinup_tests.rs @@ -1,474 +1,484 @@ -use anyhow::Context; -use testcases::{ - assert_spin_request, bootstap_env, bootstrap_smoke_test, http_smoke_test_template, - http_smoke_test_template_with_route, redis_smoke_test_template, run_test, -}; - mod testcases; -#[test] -/// Test that the --key-value flag works as expected -fn key_value_cli_flag() -> anyhow::Result<()> { - let test_key = uuid::Uuid::new_v4().to_string(); - let test_value = uuid::Uuid::new_v4().to_string(); - run_test( - "key-value", - testing_framework::SpinMode::Http, - ["--key-value".into(), format!("{test_key}={test_value}")], - testing_framework::ServicesConfig::none(), - move |env| { - let spin = env.runtime_mut(); - assert_spin_request( - spin, - testing_framework::Request::new( - reqwest::Method::GET, - &format!("/test?key={test_key}"), - ), - 200, - &[], - &test_value, - ) - }, - )?; - Ok(()) -} - -#[test] -/// Test that basic http trigger support works -fn http_smoke_test() -> anyhow::Result<()> { - run_test( - "http-smoke-test", - testing_framework::SpinMode::Http, - [], - testing_framework::ServicesConfig::none(), - move |env| { - let spin = env.runtime_mut(); - assert_spin_request( - spin, - testing_framework::Request::new(reqwest::Method::GET, "/test/hello"), - 200, - &[], - "I'm a teapot", - )?; - assert_spin_request( - spin, - testing_framework::Request::new( - reqwest::Method::GET, - "/test/hello/wildcards/should/be/handled", - ), - 200, - &[], - "I'm a teapot", - )?; - assert_spin_request( - spin, - testing_framework::Request::new(reqwest::Method::GET, "/thishsouldfail"), - 404, - &[], - "", - )?; - assert_spin_request( - spin, - testing_framework::Request::new(reqwest::Method::GET, "/test/hello/test-placement"), - 200, - &[], - "text for test", - ) - }, - )?; - - Ok(()) -} - -#[test] -// TODO: it seems that running this test on macOS CI is not possible because the docker services doesn't run. -// Investigate if there is a possible fix for this. -#[cfg(feature = "e2e-tests")] -/// Test that basic redis trigger support works -fn redis_smoke_test() -> anyhow::Result<()> { - /// Helper macro to assert that a condition is true eventually - macro_rules! assert_eventually { - ($e:expr) => { - let mut i = 0; - loop { - if $e { - break; - } else if i > 20 { - assert!($e); - break; - } - std::thread::sleep(std::time::Duration::from_millis(100)); - i += 1; - } - }; - } - +mod spinup_tests { + use super::testcases::{ + assert_spin_request, bootstap_env, bootstrap_smoke_test, http_smoke_test_template, + http_smoke_test_template_with_route, redis_smoke_test_template, run_test, spin_binary, + }; use anyhow::Context; - use redis::Commands; - run_test( - "redis-smoke-test", - testing_framework::SpinMode::Redis, - [], - testing_framework::ServicesConfig::new(vec!["redis".into()])?, - move |env| { - let redis_port = env - .services_mut() - .get_port(6379)? - .context("no redis port was exposed by test services")?; - - let mut redis = redis::Client::open(format!("redis://localhost:{redis_port}")) - .context("could not connect to redis in test")?; - redis - .publish("my-channel", "msg-from-test") - .context("could not publish test message to redis")?; - assert_eventually!({ - match env.read_file(".spin/logs/hello_stdout.txt") { - Ok(logs) => { - let logs = String::from_utf8_lossy(&logs); - logs.contains("Got message: 'msg-from-test'") - } - Err(e) if e.kind() == std::io::ErrorKind::NotFound => false, - Err(e) => return Err(anyhow::anyhow!("could not read stdout file: {e}").into()), - } - }); - Ok(()) - }, - )?; - - Ok(()) -} -#[test] -/// Test dynamic environment variables -fn dynamic_env_test() -> anyhow::Result<()> { - run_test( - "dynamic-env-test", - testing_framework::SpinMode::Http, - vec!["--env".to_owned(), "foo=bar".to_owned()], - testing_framework::ServicesConfig::none(), - move |env| { - let spin = env.runtime_mut(); - assert_spin_request( - spin, - testing_framework::Request::new(reqwest::Method::GET, "/env"), - 200, - &[("env_some_key", "some_value"), ("ENV_foo", "bar")], - "I'm a teapot", - )?; - Ok(()) - }, - )?; - - Ok(()) -} - -#[test] -/// Test that mounting works properly -fn assets_routing_test() -> anyhow::Result<()> { - run_test( - "assets-test", - testing_framework::SpinMode::Http, - [], - testing_framework::ServicesConfig::none(), - move |env| { - let spin = env.runtime_mut(); - let mut assert_file = |name: &str, content: &str| { + #[test] + /// Test that the --key-value flag works as expected + fn key_value_cli_flag() -> anyhow::Result<()> { + let test_key = uuid::Uuid::new_v4().to_string(); + let test_value = uuid::Uuid::new_v4().to_string(); + run_test( + "key-value", + testing_framework::SpinMode::Http, + ["--key-value".into(), format!("{test_key}={test_value}")], + testing_framework::ServicesConfig::none(), + move |env| { + let spin = env.runtime_mut(); assert_spin_request( spin, testing_framework::Request::new( reqwest::Method::GET, - &format!("/static/thisshouldbemounted/{name}"), + &format!("/test?key={test_key}"), ), 200, &[], - content, + &test_value, ) - }; - let mut assert_file_content_eq_name = - |name: &str| assert_file(name, &format!("{name}\n")); - - assert_file_content_eq_name("1")?; - assert_file_content_eq_name("2")?; - assert_file_content_eq_name("3")?; - assert_file("empty", "")?; - assert_file("one-byte", "{")?; + }, + )?; + Ok(()) + } - let mut assert_not_found = |path: &str| { + #[test] + /// Test that basic http trigger support works + fn http_smoke_test() -> anyhow::Result<()> { + run_test( + "http-smoke-test", + testing_framework::SpinMode::Http, + [], + testing_framework::ServicesConfig::none(), + move |env| { + let spin = env.runtime_mut(); + assert_spin_request( + spin, + testing_framework::Request::new(reqwest::Method::GET, "/test/hello"), + 200, + &[], + "I'm a teapot", + )?; assert_spin_request( spin, testing_framework::Request::new( reqwest::Method::GET, - &format!("/static/{path}"), + "/test/hello/wildcards/should/be/handled", ), + 200, + &[], + "I'm a teapot", + )?; + assert_spin_request( + spin, + testing_framework::Request::new(reqwest::Method::GET, "/thishsouldfail"), 404, &[], - "Not Found", + "", + )?; + assert_spin_request( + spin, + testing_framework::Request::new( + reqwest::Method::GET, + "/test/hello/test-placement", + ), + 200, + &[], + "text for test", ) - }; + }, + )?; - assert_not_found("donotmount/a")?; - assert_not_found("thisshouldbemounted/thisshouldbeexcluded/4")?; - Ok(()) - }, - )?; + Ok(()) + } - Ok(()) -} + #[test] + // TODO: it seems that running this test on macOS CI is not possible because the docker services doesn't run. + // Investigate if there is a possible fix for this. + #[cfg(any(not(target_os = "macos"), feature = "e2e-tests"))] + /// Test that basic redis trigger support works + fn redis_smoke_test() -> anyhow::Result<()> { + /// Helper macro to assert that a condition is true eventually + macro_rules! assert_eventually { + ($e:expr) => { + let mut i = 0; + loop { + if $e { + break; + } else if i > 20 { + assert!($e); + break; + } + std::thread::sleep(std::time::Duration::from_millis(100)); + i += 1; + } + }; + } + + use anyhow::Context; + use redis::Commands; + run_test( + "redis-smoke-test", + testing_framework::SpinMode::Redis, + [], + testing_framework::ServicesConfig::new(vec!["redis".into()])?, + move |env| { + let redis_port = env + .services_mut() + .get_port(6379)? + .context("no redis port was exposed by test services")?; + + let mut redis = redis::Client::open(format!("redis://localhost:{redis_port}")) + .context("could not connect to redis in test")?; + redis + .publish("my-channel", "msg-from-test") + .context("could not publish test message to redis")?; + assert_eventually!({ + match env.read_file(".spin/logs/hello_stdout.txt") { + Ok(logs) => { + let logs = String::from_utf8_lossy(&logs); + logs.contains("Got message: 'msg-from-test'") + } + Err(e) if e.kind() == std::io::ErrorKind::NotFound => false, + Err(e) => { + return Err(anyhow::anyhow!("could not read stdout file: {e}").into()) + } + } + }); + Ok(()) + }, + )?; + + Ok(()) + } -#[test] -/// Test that mounting works properly -fn legacy_apps() -> anyhow::Result<()> { - run_test( - "legacy-apps-test", - testing_framework::SpinMode::Http, - [], - testing_framework::ServicesConfig::none(), - move |env| { - let spin = env.runtime_mut(); - let mut test = |lang: &str, body: &str| { + #[test] + /// Test dynamic environment variables + fn dynamic_env_test() -> anyhow::Result<()> { + run_test( + "dynamic-env-test", + testing_framework::SpinMode::Http, + vec!["--env".to_owned(), "foo=bar".to_owned()], + testing_framework::ServicesConfig::none(), + move |env| { + let spin = env.runtime_mut(); assert_spin_request( spin, - testing_framework::Request::new(reqwest::Method::GET, &format!("/{lang}")), + testing_framework::Request::new(reqwest::Method::GET, "/env"), 200, - &[], - body, - ) - }; + &[("env_some_key", "some_value"), ("ENV_foo", "bar")], + "I'm a teapot", + )?; + Ok(()) + }, + )?; - test("golang", "Hello Fermyon!\n")?; - test("rust", "Hello, Fermyon")?; - test("javascript", "Hello from JS-SDK")?; - test("typescript", "Hello from TS-SDK")?; - Ok(()) - }, - )?; + Ok(()) + } - Ok(()) -} + #[test] + /// Test that mounting works properly + fn assets_routing_test() -> anyhow::Result<()> { + run_test( + "assets-test", + testing_framework::SpinMode::Http, + [], + testing_framework::ServicesConfig::none(), + move |env| { + let spin = env.runtime_mut(); + let mut assert_file = |name: &str, content: &str| { + assert_spin_request( + spin, + testing_framework::Request::new( + reqwest::Method::GET, + &format!("/static/thisshouldbemounted/{name}"), + ), + 200, + &[], + content, + ) + }; + let mut assert_file_content_eq_name = + |name: &str| assert_file(name, &format!("{name}\n")); + + assert_file_content_eq_name("1")?; + assert_file_content_eq_name("2")?; + assert_file_content_eq_name("3")?; + assert_file("empty", "")?; + assert_file("one-byte", "{")?; + + let mut assert_not_found = |path: &str| { + assert_spin_request( + spin, + testing_framework::Request::new( + reqwest::Method::GET, + &format!("/static/{path}"), + ), + 404, + &[], + "Not Found", + ) + }; + + assert_not_found("donotmount/a")?; + assert_not_found("thisshouldbemounted/thisshouldbeexcluded/4")?; + Ok(()) + }, + )?; + + Ok(()) + } + + #[test] + /// Test that mounting works properly + fn legacy_apps() -> anyhow::Result<()> { + run_test( + "legacy-apps-test", + testing_framework::SpinMode::Http, + [], + testing_framework::ServicesConfig::none(), + move |env| { + let spin = env.runtime_mut(); + let mut test = |lang: &str, body: &str| { + assert_spin_request( + spin, + testing_framework::Request::new(reqwest::Method::GET, &format!("/{lang}")), + 200, + &[], + body, + ) + }; + + test("golang", "Hello Fermyon!\n")?; + test("rust", "Hello, Fermyon")?; + test("javascript", "Hello from JS-SDK")?; + test("typescript", "Hello from TS-SDK")?; + Ok(()) + }, + )?; -#[test] -fn bad_build_test() -> anyhow::Result<()> { - let mut env = bootstap_env( - "error", - [], - testing_framework::ServicesConfig::none(), - testing_framework::SpinMode::None, - )?; - let expected = r#"Error: Couldn't find trigger executor for local app "spin.toml" + Ok(()) + } + + #[test] + fn bad_build_test() -> anyhow::Result<()> { + let mut env = bootstap_env( + "error", + [], + testing_framework::ServicesConfig::none(), + testing_framework::SpinMode::None, + )?; + let expected = r#"Error: Couldn't find trigger executor for local app "spin.toml" Caused by: no triggers in app "#; - assert_eq!(env.runtime_mut().stderr(), expected); + assert_eq!(env.runtime_mut().stderr(), expected); - Ok(()) -} + Ok(()) + } -#[test] -fn outbound_http_works() -> anyhow::Result<()> { - run_test( - "outbound-http-to-same-app", - testing_framework::SpinMode::Http, - [], - testing_framework::ServicesConfig::none(), - move |env| { - let spin = env.runtime_mut(); - assert_spin_request( - spin, - testing_framework::Request::new(reqwest::Method::GET, "/test/outbound-allowed"), - 200, - &[], - "Hello, Fermyon!\n", - )?; - - assert_spin_request( - spin, - testing_framework::Request::new(reqwest::Method::GET, "/test/outbound-not-allowed"), - 500, - &[], - "", - )?; + #[test] + fn outbound_http_works() -> anyhow::Result<()> { + run_test( + "outbound-http-to-same-app", + testing_framework::SpinMode::Http, + [], + testing_framework::ServicesConfig::none(), + move |env| { + let spin = env.runtime_mut(); + assert_spin_request( + spin, + testing_framework::Request::new(reqwest::Method::GET, "/test/outbound-allowed"), + 200, + &[], + "Hello, Fermyon!\n", + )?; - Ok(()) - }, - )?; + assert_spin_request( + spin, + testing_framework::Request::new( + reqwest::Method::GET, + "/test/outbound-not-allowed", + ), + 500, + &[], + "", + )?; - Ok(()) -} + Ok(()) + }, + )?; -#[test] -fn http_rust_template_smoke_test() -> anyhow::Result<()> { - http_smoke_test_template("http-rust", None, &[], |_| Ok(()), "Hello, Fermyon") -} + Ok(()) + } -#[test] -#[cfg(feature = "e2e-tests")] -fn http_python_template_smoke_test() -> anyhow::Result<()> { - http_smoke_test_template( - "http-py", - Some("https://github.com/fermyon/spin-python-sdk"), - &["py2wasm"], - |_| Ok(()), - "Hello from the Python SDK", - ) -} + #[test] + fn http_rust_template_smoke_test() -> anyhow::Result<()> { + http_smoke_test_template("http-rust", None, &[], |_| Ok(()), "Hello, Fermyon") + } -#[test] -#[cfg(feature = "e2e-tests")] -fn http_c_template_smoke_test() -> anyhow::Result<()> { - http_smoke_test_template("http-c", None, &[], |_| Ok(()), "Hello from WAGI/1\n") -} + #[test] + #[cfg(feature = "e2e-tests")] + fn http_python_template_smoke_test() -> anyhow::Result<()> { + http_smoke_test_template( + "http-py", + Some("https://github.com/fermyon/spin-python-sdk"), + &["py2wasm"], + |_| Ok(()), + "Hello from the Python SDK", + ) + } -#[test] -#[cfg(feature = "e2e-tests")] -fn http_go_template_smoke_test() -> anyhow::Result<()> { - let prebuild = |env: &mut testing_framework::TestEnvironment<_>| { - let mut tidy = std::process::Command::new("go"); - tidy.args(["mod", "tidy"]); - env.run_in(&mut tidy)?; - Ok(()) - }; - http_smoke_test_template("http-go", None, &[], prebuild, "Hello Fermyon!\n") -} + #[test] + #[cfg(feature = "e2e-tests")] + fn http_c_template_smoke_test() -> anyhow::Result<()> { + http_smoke_test_template("http-c", None, &[], |_| Ok(()), "Hello from WAGI/1\n") + } -#[test] -#[cfg(feature = "e2e-tests")] -fn http_js_template_smoke_test() -> anyhow::Result<()> { - let prebuild = |env: &mut testing_framework::TestEnvironment<_>| { - let mut tidy = std::process::Command::new("npm"); - tidy.args(["install"]); - env.run_in(&mut tidy)?; - Ok(()) - }; - http_smoke_test_template( - "http-js", - Some("https://github.com/fermyon/spin-js-sdk"), - &["js2wasm"], - prebuild, - "Hello from JS-SDK", - ) -} + #[test] + #[cfg(feature = "e2e-tests")] + fn http_go_template_smoke_test() -> anyhow::Result<()> { + let prebuild = |env: &mut testing_framework::TestEnvironment<_>| { + let mut tidy = std::process::Command::new("go"); + tidy.args(["mod", "tidy"]); + env.run_in(&mut tidy)?; + Ok(()) + }; + http_smoke_test_template("http-go", None, &[], prebuild, "Hello Fermyon!\n") + } -#[test] -#[cfg(feature = "e2e-tests")] -fn http_ts_template_smoke_test() -> anyhow::Result<()> { - let prebuild = |env: &mut testing_framework::TestEnvironment<_>| { - let mut tidy = std::process::Command::new("npm"); - tidy.args(["install"]); - env.run_in(&mut tidy)?; - Ok(()) - }; - http_smoke_test_template( - "http-ts", - Some("https://github.com/fermyon/spin-js-sdk"), - &["js2wasm"], - prebuild, - "Hello from TS-SDK", - ) -} + #[test] + #[cfg(feature = "e2e-tests")] + fn http_js_template_smoke_test() -> anyhow::Result<()> { + let prebuild = |env: &mut testing_framework::TestEnvironment<_>| { + let mut tidy = std::process::Command::new("npm"); + tidy.args(["install"]); + env.run_in(&mut tidy)?; + Ok(()) + }; + http_smoke_test_template( + "http-js", + Some("https://github.com/fermyon/spin-js-sdk"), + &["js2wasm"], + prebuild, + "Hello from JS-SDK", + ) + } -#[test] -#[cfg(target_arch = "x86_64")] -#[cfg(feature = "e2e-tests")] -fn http_grain_template_smoke_test() -> anyhow::Result<()> { - http_smoke_test_template("http-grain", None, &[], |_| Ok(()), "Hello, World\n") -} + #[test] + #[cfg(feature = "e2e-tests")] + fn http_ts_template_smoke_test() -> anyhow::Result<()> { + let prebuild = |env: &mut testing_framework::TestEnvironment<_>| { + let mut tidy = std::process::Command::new("npm"); + tidy.args(["install"]); + env.run_in(&mut tidy)?; + Ok(()) + }; + http_smoke_test_template( + "http-ts", + Some("https://github.com/fermyon/spin-js-sdk"), + &["js2wasm"], + prebuild, + "Hello from TS-SDK", + ) + } -#[test] -#[cfg(feature = "e2e-tests")] -fn http_zig_template_smoke_test() -> anyhow::Result<()> { - http_smoke_test_template("http-zig", None, &[], |_| Ok(()), "Hello World!\n") -} + #[test] + #[cfg(target_arch = "x86_64")] + #[cfg(feature = "e2e-tests")] + fn http_grain_template_smoke_test() -> anyhow::Result<()> { + http_smoke_test_template("http-grain", None, &[], |_| Ok(()), "Hello, World\n") + } -#[test] -#[cfg(feature = "e2e-tests")] -fn http_swift_template_smoke_test() -> anyhow::Result<()> { - http_smoke_test_template("http-swift", None, &[], |_| Ok(()), "Hello from WAGI/1!\n") -} + #[test] + #[cfg(feature = "e2e-tests")] + fn http_zig_template_smoke_test() -> anyhow::Result<()> { + http_smoke_test_template("http-zig", None, &[], |_| Ok(()), "Hello World!\n") + } -#[test] -fn http_php_template_smoke_test() -> anyhow::Result<()> { - http_smoke_test_template_with_route( - "http-php", - None, - &[], - |_| Ok(()), - "/index.php", - "Hello Fermyon Spin", - ) -} + #[test] + #[cfg(feature = "e2e-tests")] + fn http_swift_template_smoke_test() -> anyhow::Result<()> { + http_smoke_test_template("http-swift", None, &[], |_| Ok(()), "Hello from WAGI/1!\n") + } -#[test] -fn redis_go_template_smoke_test() -> anyhow::Result<()> { - redis_smoke_test_template( - "redis-go", - None, - &[], - |port| { - vec![ - "--value".into(), - "redis-channel=redis-channel".into(), - "--value".into(), - format!("redis-address=redis://localhost:{port}"), - ] - }, - |_| Ok(()), - ) -} + #[test] + fn http_php_template_smoke_test() -> anyhow::Result<()> { + http_smoke_test_template_with_route( + "http-php", + None, + &[], + |_| Ok(()), + "/index.php", + "Hello Fermyon Spin", + ) + } -#[test] -fn redis_rust_template_smoke_test() -> anyhow::Result<()> { - redis_smoke_test_template( - "redis-rust", - None, - &[], - |port| { - vec![ - "--value".into(), - "redis-channel=redis-channel".into(), - "--value".into(), - format!("redis-address=redis://localhost:{port}"), - ] - }, - |_| Ok(()), - ) -} + #[test] + fn redis_go_template_smoke_test() -> anyhow::Result<()> { + redis_smoke_test_template( + "redis-go", + None, + &[], + |port| { + vec![ + "--value".into(), + "redis-channel=redis-channel".into(), + "--value".into(), + format!("redis-address=redis://localhost:{port}"), + ] + }, + |_| Ok(()), + ) + } -#[test] -fn registry_works() -> anyhow::Result<()> { - let services = testing_framework::ServicesConfig::new(vec!["registry".into()])?; - let spin_up_args = |env: &mut testing_framework::TestEnvironment<()>| { - let registry_url = format!( - "localhost:{}/spin-e2e-tests/registry-works/v1", - env.get_port(5000)? - .context("no registry port was exposed by test services")? - ); - let mut registry_push = std::process::Command::new(testcases::spin_binary()); - registry_push.args(&["registry", "push", ®istry_url, "--insecure"]); - env.run_in(&mut registry_push)?; - Ok(vec![ - "--from-registry".into(), - registry_url, - "--insecure".into(), - ]) - }; - let mut env = bootstrap_smoke_test( - &services, - None, - &[], - "http-rust", - |_| Ok(Vec::new()), - |_| Ok(()), - spin_up_args, - testing_framework::SpinMode::Http, - )?; - assert_spin_request( - env.runtime_mut(), - testing_framework::Request::new(reqwest::Method::GET, "/"), - 200, - &[], - "Hello, Fermyon", - )?; - Ok(()) + #[test] + fn redis_rust_template_smoke_test() -> anyhow::Result<()> { + redis_smoke_test_template( + "redis-rust", + None, + &[], + |port| { + vec![ + "--value".into(), + "redis-channel=redis-channel".into(), + "--value".into(), + format!("redis-address=redis://localhost:{port}"), + ] + }, + |_| Ok(()), + ) + } + + #[test] + fn registry_works() -> anyhow::Result<()> { + let services = testing_framework::ServicesConfig::new(vec!["registry".into()])?; + let spin_up_args = |env: &mut testing_framework::TestEnvironment<()>| { + let registry_url = format!( + "localhost:{}/spin-e2e-tests/registry-works/v1", + env.get_port(5000)? + .context("no registry port was exposed by test services")? + ); + let mut registry_push = std::process::Command::new(spin_binary()); + registry_push.args(["registry", "push", ®istry_url, "--insecure"]); + env.run_in(&mut registry_push)?; + Ok(vec![ + "--from-registry".into(), + registry_url, + "--insecure".into(), + ]) + }; + let mut env = bootstrap_smoke_test( + &services, + None, + &[], + "http-rust", + |_| Ok(Vec::new()), + |_| Ok(()), + spin_up_args, + testing_framework::SpinMode::Http, + )?; + assert_spin_request( + env.runtime_mut(), + testing_framework::Request::new(reqwest::Method::GET, "/"), + 200, + &[], + "Hello, Fermyon", + )?; + Ok(()) + } } diff --git a/tests/test-components/components/llm/src/lib.rs b/tests/test-components/components/llm/src/lib.rs index 5f497d6317..6cc1287949 100644 --- a/tests/test-components/components/llm/src/lib.rs +++ b/tests/test-components/components/llm/src/lib.rs @@ -20,7 +20,7 @@ impl Component { Some(param) )); - ensure!(inference.text.len() > 0); + ensure!(!inference.text.is_empty()); ensure_eq!(inference.usage.generated_token_count, 1); Ok(()) diff --git a/tests/testcases/mod.rs b/tests/testcases/mod.rs index 3b9a7e89c8..a568c0db40 100644 --- a/tests/testcases/mod.rs +++ b/tests/testcases/mod.rs @@ -66,9 +66,9 @@ pub fn assert_spin_request( ))); } if body != expected_body { - return Err(testing_framework::TestError::Failure( - anyhow::anyhow!("expected body '{expected_body}', got '{body}'").into(), - )); + return Err(testing_framework::TestError::Failure(anyhow::anyhow!( + "expected body '{expected_body}', got '{body}'" + ))); } Ok(()) } @@ -183,6 +183,8 @@ pub fn redis_smoke_test_template( } /// Bootstrap a test environment for a smoke test +// TODO: refactor this function to not take so many arguments +#[allow(clippy::too_many_arguments)] pub fn bootstrap_smoke_test( services: &testing_framework::ServicesConfig, template_url: Option<&str>, @@ -199,15 +201,24 @@ pub fn bootstrap_smoke_test( ) -> anyhow::Result> { let mut env: testing_framework::TestEnvironment<()> = testing_framework::TestEnvironment::boot(services)?; - if let Some(template_url) = template_url { - let mut template_install = std::process::Command::new(spin_binary()); - template_install.args(["templates", "install", "--git", template_url, "--update"]); - env.run_in(&mut template_install)?; - } + + let template_url = template_url.unwrap_or("https://github.com/fermyon/spin"); + let mut template_install = std::process::Command::new(spin_binary()); + template_install.args(["templates", "install", "--git", template_url, "--update"]); + env.run_in(&mut template_install)?; + if !plugins.is_empty() { let mut plugin_update = std::process::Command::new(spin_binary()); plugin_update.args(["plugin", "update"]); - env.run_in(&mut plugin_update)?; + if let Err(e) = env.run_in(&mut plugin_update) { + // We treat plugin updates as best efforts since it only needs to be run once + if !e + .to_string() + .contains("update operation is already in progress") + { + return Err(e); + } + } } for plugin in plugins { let mut plugin_install = std::process::Command::new(spin_binary());