diff --git a/Cargo.lock b/Cargo.lock index e8304ce37..3c20ea01e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -584,18 +584,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -2094,12 +2082,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "futures" version = "0.3.29" @@ -3173,6 +3155,15 @@ dependencies = [ "sha2", ] +[[package]] +name = "keyed_priority_queue" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee7893dab2e44ae5f9d0173f26ff4aa327c10b01b06a72b52dd9405b628640d" +dependencies = [ + "indexmap 2.1.0", +] + [[package]] name = "kqueue" version = "1.0.8" @@ -3235,79 +3226,6 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" -[[package]] -name = "lexical" -version = "6.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7aefb36fd43fef7003334742cbf77b243fcd36418a1d1bdd480d613a67968f6" -dependencies = [ - "lexical-core", -] - -[[package]] -name = "lexical-core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" -dependencies = [ - "lexical-parse-float", - "lexical-parse-integer", - "lexical-util", - "lexical-write-float", - "lexical-write-integer", -] - -[[package]] -name = "lexical-parse-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" -dependencies = [ - "lexical-parse-integer", - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-parse-integer" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9" -dependencies = [ - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-util" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc" -dependencies = [ - "static_assertions", -] - -[[package]] -name = "lexical-write-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862" -dependencies = [ - "lexical-util", - "lexical-write-integer", - "static_assertions", -] - -[[package]] -name = "lexical-write-integer" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446" -dependencies = [ - "lexical-util", - "static_assertions", -] - [[package]] name = "libc" version = "0.2.150" @@ -3603,11 +3521,11 @@ dependencies = [ [[package]] name = "lru" -version = "0.10.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" dependencies = [ - "hashbrown 0.13.2", + "hashbrown 0.14.3", ] [[package]] @@ -3809,9 +3727,9 @@ dependencies = [ [[package]] name = "mysql_async" -version = "0.32.2" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5272f59b5b1f93d65f7f826c1f025d6e410e89fb50a67e05aa20b35a55a8c0a" +checksum = "6750b17ce50f8f112ef1a8394121090d47c596b56a6a17569ca680a9626e2ef2" dependencies = [ "bytes", "crossbeam", @@ -3819,8 +3737,9 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", + "keyed_priority_queue", "lazy_static", - "lru 0.10.1", + "lru 0.12.1", "mio", "mysql_common", "native-tls", @@ -3828,7 +3747,7 @@ dependencies = [ "pem", "percent-encoding", "pin-project", - "priority-queue", + "rand 0.8.5", "serde", "serde_json", "socket2 0.5.5", @@ -3842,14 +3761,14 @@ dependencies = [ [[package]] name = "mysql_common" -version = "0.30.6" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57349d5a326b437989b6ee4dc8f2f34b0cc131202748414712a8e7d98952fc8c" +checksum = "06f19e4cfa0ab5a76b627cec2d81331c49b034988eaf302c3bafeada684eadef" dependencies = [ "base64 0.21.5", "bindgen", "bitflags 2.4.1", - "bitvec", + "btoi", "byteorder", "bytes", "cc", @@ -3857,7 +3776,6 @@ dependencies = [ "crc32fast", "flate2", "lazy_static", - "lexical", "num-bigint", "num-traits", "rand 0.8.5", @@ -3871,6 +3789,7 @@ dependencies = [ "subprocess", "thiserror", "uuid", + "zstd 0.12.4", ] [[package]] @@ -4388,9 +4307,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pem" -version = "2.0.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" +checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" dependencies = [ "base64 0.21.5", "serde", @@ -4653,16 +4572,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "priority-queue" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff39edfcaec0d64e8d0da38564fad195d2d51b680940295fcc307366e101e61" -dependencies = [ - "autocfg", - "indexmap 1.9.3", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -4754,12 +4663,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand" version = "0.7.3" @@ -5122,6 +5025,7 @@ dependencies = [ "fslock", "log", "nix 0.26.4", + "regex", "reqwest", "temp-dir", "test-components", @@ -6595,12 +6499,6 @@ dependencies = [ name = "table" version = "2.2.0-pre0" -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "tar" version = "0.4.40" @@ -7685,7 +7583,7 @@ dependencies = [ "sha2", "toml 0.5.11", "windows-sys 0.48.0", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -8625,15 +8523,6 @@ dependencies = [ "wast 35.0.2", ] -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "xattr" version = "0.2.3" @@ -8695,7 +8584,7 @@ dependencies = [ "pbkdf2", "sha1 0.10.6", "time", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -8704,7 +8593,16 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe", + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe 6.0.6", ] [[package]] @@ -8717,6 +8615,16 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.0.9+zstd.1.5.5" diff --git a/Makefile b/Makefile index 24bf2aa2a..31eec5c44 100644 --- a/Makefile +++ b/Makefile @@ -95,6 +95,7 @@ test-crate: .PHONY: test-integration test-integration: + cargo test -F e2e-tests -- runtime_tests --nocapture; \ $(LOG_LEVEL_VAR) cargo test --test integration --no-fail-fast -- --skip spinup_tests --skip cloud_tests --nocapture .PHONY: test-spin-up diff --git a/crates/outbound-mysql/Cargo.toml b/crates/outbound-mysql/Cargo.toml index d26a81b6a..607a6528b 100644 --- a/crates/outbound-mysql/Cargo.toml +++ b/crates/outbound-mysql/Cargo.toml @@ -11,11 +11,11 @@ doctest = false anyhow = "1.0" flate2 = "1.0.17" # Removing default features for mysql_async to remove flate2/zlib feature -mysql_async = { version = "0.32.2", default-features = false, features = [ +mysql_async = { version = "0.33.0", default-features = false, features = [ "native-tls-tls", ] } # Removing default features for mysql_common to remove flate2/zlib feature -mysql_common = { version = "0.30.6", default-features = false } +mysql_common = { version = "0.31.0", default-features = false } spin-app = { path = "../app" } spin-core = { path = "../core" } spin-outbound-networking = { path = "../outbound-networking" } diff --git a/crates/outbound-pg/src/lib.rs b/crates/outbound-pg/src/lib.rs index c54738cef..e7a82bb91 100644 --- a/crates/outbound-pg/src/lib.rs +++ b/crates/outbound-pg/src/lib.rs @@ -42,14 +42,20 @@ impl OutboundPg { let Ok(config) = address.parse::() else { return false; }; - for host in config.get_hosts() { + for (i, host) in config.get_hosts().iter().enumerate() { match host { tokio_postgres::config::Host::Tcp(address) => { - if !spin_outbound_networking::check_url( - address, - "postgres", - &self.allowed_hosts, - ) { + let ports = config.get_ports(); + // The port we use is either: + // * The port at the same index as the host + // * The first port if there is only one port + let port = + ports + .get(i) + .or_else(|| if ports.len() == 1 { ports.get(1) } else { None }); + let port_str = port.map(|p| format!(":{}", p)).unwrap_or_default(); + let url = format!("{address}{port_str}"); + if !spin_outbound_networking::check_url(&url, "postgres", &self.allowed_hosts) { return false; } } diff --git a/e2e-tests.Dockerfile b/e2e-tests.Dockerfile index 533489877..3825d45d8 100644 --- a/e2e-tests.Dockerfile +++ b/e2e-tests.Dockerfile @@ -76,8 +76,6 @@ RUN printf '#!/bin/bash cargo build --release \n \ fi \n\n \ cargo test spinup_tests --features e2e-tests --no-fail-fast -- --nocapture \n \ - # Run the runtime tests which will supersede many e2e tests in the future \n \ - cargo test -F e2e-tests -- runtime_tests --nocapture \n \ ' > /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh diff --git a/examples/spin-timer/Cargo.lock b/examples/spin-timer/Cargo.lock index ad638b5b9..622f77b2c 100644 --- a/examples/spin-timer/Cargo.lock +++ b/examples/spin-timer/Cargo.lock @@ -83,6 +83,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "ambient-authority" version = "0.0.2" @@ -274,24 +280,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] -name = "bitvec" -version = "1.0.1" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "funty", - "radium", - "tap", - "wyz", + "generic-array", ] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "btoi" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" dependencies = [ - "generic-array", + "num-traits", ] [[package]] @@ -865,6 +868,16 @@ dependencies = [ "uuid", ] +[[package]] +name = "deranged" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "derive_builder" version = "0.11.2" @@ -1195,12 +1208,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - [[package]] name = "futures" version = "0.3.28" @@ -1392,7 +1399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" dependencies = [ "fallible-iterator 0.3.0", - "indexmap 2.0.2", + "indexmap 2.1.0", "stable_deref_trait", ] @@ -1404,9 +1411,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.19" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -1414,7 +1421,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util 0.7.9", @@ -1456,6 +1463,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" dependencies = [ "ahash 0.8.3", + "allocator-api2", ] [[package]] @@ -1576,9 +1584,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -1628,7 +1636,7 @@ checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ "futures-util", "http", - "hyper 0.14.26", + "hyper 0.14.27", "log", "rustls", "rustls-native-certs", @@ -1644,7 +1652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.26", + "hyper 0.14.27", "native-tls", "tokio", "tokio-native-tls", @@ -1685,9 +1693,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown 0.14.1", @@ -1843,6 +1851,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keyed_priority_queue" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee7893dab2e44ae5f9d0173f26ff4aa327c10b01b06a72b52dd9405b628640d" +dependencies = [ + "indexmap 2.1.0", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1861,79 +1878,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" -[[package]] -name = "lexical" -version = "6.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7aefb36fd43fef7003334742cbf77b243fcd36418a1d1bdd480d613a67968f6" -dependencies = [ - "lexical-core", -] - -[[package]] -name = "lexical-core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" -dependencies = [ - "lexical-parse-float", - "lexical-parse-integer", - "lexical-util", - "lexical-write-float", - "lexical-write-integer", -] - -[[package]] -name = "lexical-parse-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" -dependencies = [ - "lexical-parse-integer", - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-parse-integer" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9" -dependencies = [ - "lexical-util", - "static_assertions", -] - -[[package]] -name = "lexical-util" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc" -dependencies = [ - "static_assertions", -] - -[[package]] -name = "lexical-write-float" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862" -dependencies = [ - "lexical-util", - "lexical-write-integer", - "static_assertions", -] - -[[package]] -name = "lexical-write-integer" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446" -dependencies = [ - "lexical-util", - "static_assertions", -] - [[package]] name = "libc" version = "0.2.150" @@ -1961,7 +1905,7 @@ dependencies = [ "fallible-iterator 0.3.0", "futures", "http", - "hyper 0.14.26", + "hyper 0.14.27", "hyper-rustls", "serde", "serde_json", @@ -1991,9 +1935,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "llm" @@ -2120,11 +2064,11 @@ dependencies = [ [[package]] name = "lru" -version = "0.10.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" dependencies = [ - "hashbrown 0.13.2", + "hashbrown 0.14.1", ] [[package]] @@ -2175,11 +2119,11 @@ checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memfd" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc89ccdc6e10d6907450f753537ebc5c5d3460d2e4e62ea74bd571db62c0f9e" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.37.20", + "rustix 0.38.25", ] [[package]] @@ -2233,9 +2177,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", @@ -2266,9 +2210,9 @@ dependencies = [ [[package]] name = "mysql_async" -version = "0.32.2" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5272f59b5b1f93d65f7f826c1f025d6e410e89fb50a67e05aa20b35a55a8c0a" +checksum = "6750b17ce50f8f112ef1a8394121090d47c596b56a6a17569ca680a9626e2ef2" dependencies = [ "bytes", "crossbeam", @@ -2276,8 +2220,9 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", + "keyed_priority_queue", "lazy_static", - "lru 0.10.1", + "lru 0.12.1", "mio", "mysql_common", "native-tls", @@ -2285,7 +2230,7 @@ dependencies = [ "pem", "percent-encoding", "pin-project", - "priority-queue", + "rand 0.8.5", "serde", "serde_json", "socket2 0.5.5", @@ -2299,14 +2244,14 @@ dependencies = [ [[package]] name = "mysql_common" -version = "0.30.6" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57349d5a326b437989b6ee4dc8f2f34b0cc131202748414712a8e7d98952fc8c" +checksum = "06f19e4cfa0ab5a76b627cec2d81331c49b034988eaf302c3bafeada684eadef" dependencies = [ "base64 0.21.4", "bindgen", "bitflags 2.4.1", - "bitvec", + "btoi", "byteorder", "bytes", "cc", @@ -2314,7 +2259,6 @@ dependencies = [ "crc32fast", "flate2", "lazy_static", - "lexical", "num-bigint", "num-traits", "rand 0.8.5", @@ -2328,6 +2272,7 @@ dependencies = [ "subprocess", "thiserror", "uuid", + "zstd 0.12.4", ] [[package]] @@ -2442,7 +2387,7 @@ checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "crc32fast", "hashbrown 0.14.1", - "indexmap 2.0.2", + "indexmap 2.1.0", "memchr", ] @@ -2526,9 +2471,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "os_str_bytes" -version = "6.5.0" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "ouroboros" @@ -2712,9 +2657,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pem" -version = "2.0.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" +checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" dependencies = [ "base64 0.21.4", "serde", @@ -2767,18 +2712,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", @@ -2818,9 +2763,9 @@ dependencies = [ [[package]] name = "postgres-protocol" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d" +checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" dependencies = [ "base64 0.21.4", "byteorder", @@ -2836,9 +2781,9 @@ dependencies = [ [[package]] name = "postgres-types" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f028f05971fe20f512bcc679e2c10227e57809a3af86a7606304435bc8896cd6" +checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" dependencies = [ "bytes", "fallible-iterator 0.2.0", @@ -2846,20 +2791,16 @@ dependencies = [ ] [[package]] -name = "ppv-lite86" -version = "0.2.17" +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] -name = "priority-queue" -version = "1.3.2" +name = "ppv-lite86" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff39edfcaec0d64e8d0da38564fad195d2d51b680940295fcc307366e101e61" -dependencies = [ - "autocfg", - "indexmap 1.9.3", -] +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-error" @@ -2912,12 +2853,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - [[package]] name = "rand" version = "0.7.3" @@ -3130,7 +3065,7 @@ dependencies = [ "h2", "http", "http-body 0.4.5", - "hyper 0.14.26", + "hyper 0.14.27", "hyper-rustls", "hyper-tls", "ipnet", @@ -3268,7 +3203,7 @@ dependencies = [ "errno", "itoa", "libc", - "linux-raw-sys 0.4.11", + "linux-raw-sys 0.4.12", "once_cell", "windows-sys 0.48.0", ] @@ -3359,11 +3294,11 @@ checksum = "ece8e78b2f38ec51c51f5d475df0a7187ba5111b2a28bdc761ee05b075d40a71" [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -3978,7 +3913,7 @@ dependencies = [ "bitflags 2.4.1", "cc", "fallible-iterator 0.3.0", - "indexmap 2.0.2", + "indexmap 2.1.0", "log", "memchr", "phf", @@ -4095,12 +4030,6 @@ dependencies = [ name = "table" version = "2.2.0-pre0" -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "tar" version = "0.4.38" @@ -4177,13 +4106,15 @@ dependencies = [ [[package]] name = "time" -version = "0.3.21" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ + "deranged", "itoa", "libc", "num_threads", + "powerfmt", "serde", "time-core", "time-macros", @@ -4191,15 +4122,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -4255,9 +4186,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.32.0" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" dependencies = [ "backtrace", "bytes", @@ -4274,9 +4205,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", @@ -4295,9 +4226,9 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e89f6234aa8fd43779746012fcf53603cdb91fdd8399aa0de868c2d56b6dde1" +checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" dependencies = [ "async-trait", "byteorder", @@ -4312,9 +4243,11 @@ dependencies = [ "pin-project-lite", "postgres-protocol", "postgres-types", + "rand 0.8.5", "socket2 0.5.5", "tokio", "tokio-util 0.7.9", + "whoami", ] [[package]] @@ -4391,7 +4324,7 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "serde", "serde_spanned", "toml_datetime", @@ -4413,7 +4346,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "serde", "serde_spanned", "toml_datetime", @@ -4853,7 +4786,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14abc161bfda5b519aa229758b68f2a52b45a12b993808665c857d1a9a00223c" dependencies = [ "anyhow", - "indexmap 2.0.2", + "indexmap 2.1.0", "serde", "serde_derive", "serde_json", @@ -4881,7 +4814,7 @@ version = "0.115.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e06c0641a4add879ba71ccb3a1e4278fd546f76f1eafb21d8f7b07733b547cd5" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "semver", ] @@ -4891,7 +4824,7 @@ version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "semver", ] @@ -4901,7 +4834,7 @@ version = "0.118.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95ee9723b928e735d53000dec9eae7b07a60e490c85ab54abb66659fc61bfcd9" dependencies = [ - "indexmap 2.0.2", + "indexmap 2.1.0", "semver", ] @@ -4928,7 +4861,7 @@ dependencies = [ "cfg-if", "encoding_rs", "fxprof-processed-profile", - "indexmap 2.0.2", + "indexmap 2.1.0", "libc", "log", "object 0.32.1", @@ -4981,7 +4914,7 @@ dependencies = [ "sha2", "toml 0.5.11", "windows-sys 0.48.0", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -5055,7 +4988,7 @@ dependencies = [ "anyhow", "cranelift-entity", "gimli 0.28.0", - "indexmap 2.0.2", + "indexmap 2.1.0", "log", "object 0.32.1", "serde", @@ -5144,7 +5077,7 @@ dependencies = [ "cc", "cfg-if", "encoding_rs", - "indexmap 2.0.2", + "indexmap 2.1.0", "libc", "log", "mach", @@ -5272,7 +5205,7 @@ checksum = "41786c7bbbf250c0e685b291323b50c6bb65f0505a2c0b4f0b598c740f13f185" dependencies = [ "anyhow", "heck", - "indexmap 2.0.2", + "indexmap 2.1.0", "wit-parser 0.13.0", ] @@ -5337,6 +5270,16 @@ version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wiggle" version = "15.0.0" @@ -5594,9 +5537,9 @@ dependencies = [ [[package]] name = "winx" -version = "0.36.2" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357bb8e2932df531f83b052264b050b81ba0df90ee5a59b2d1d3949f344f81e5" +checksum = "4857cedf8371f690bb6782a3e2b065c54d1b6661be068aaf3eac8b45e813fdf8" dependencies = [ "bitflags 2.4.1", "windows-sys 0.48.0", @@ -5610,7 +5553,7 @@ checksum = "e87488b57a08e2cbbd076b325acbe7f8666965af174d69d5929cd373bd54547f" dependencies = [ "anyhow", "bitflags 2.4.1", - "indexmap 2.0.2", + "indexmap 2.1.0", "log", "serde", "serde_derive", @@ -5629,7 +5572,7 @@ checksum = "f6ace9943d89bbf3dbbc71b966da0e7302057b311f36a4ac3d65ddfef17b52cf" dependencies = [ "anyhow", "id-arena", - "indexmap 2.0.2", + "indexmap 2.1.0", "log", "semver", "serde", @@ -5646,7 +5589,7 @@ checksum = "15df6b7b28ce94b8be39d8df5cb21a08a4f3b9f33b631aedb4aa5776f785ead3" dependencies = [ "anyhow", "id-arena", - "indexmap 2.0.2", + "indexmap 2.1.0", "log", "semver", "serde", @@ -5667,15 +5610,6 @@ dependencies = [ "wast 35.0.2", ] -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - [[package]] name = "xattr" version = "0.2.3" @@ -5702,7 +5636,7 @@ dependencies = [ "pbkdf2", "sha1 0.10.5", "time", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -5711,7 +5645,16 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe", + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe 6.0.6", ] [[package]] @@ -5724,13 +5667,22 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + [[package]] name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" +version = "2.0.9+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" dependencies = [ "cc", - "libc", "pkg-config", ] diff --git a/tests/runtime-tests/Cargo.toml b/tests/runtime-tests/Cargo.toml index b2d78436c..5576ad262 100644 --- a/tests/runtime-tests/Cargo.toml +++ b/tests/runtime-tests/Cargo.toml @@ -9,6 +9,7 @@ env_logger = "0.10.0" fslock = "0.2.1" log = "0.4" nix = "0.26.1" +regex = "1.10.2" reqwest = { workspace = true } temp-dir = "0.1.11" test-components = { path = "../test-components" } diff --git a/tests/runtime-tests/README.md b/tests/runtime-tests/README.md index 69343de39..03836287f 100644 --- a/tests/runtime-tests/README.md +++ b/tests/runtime-tests/README.md @@ -22,9 +22,12 @@ The runtime tests can either be run as a library function (e.g., this is how the ## How do I add a new test? -To add a new test you must add a new folder to the `tests` directory with at least a `spin.toml` manifest. +To add a new test you must add a new folder to the `tests` directory with at least a `spin.toml` manifest. -The manifest can reference pre-built Spin compliant WebAssembly modules that can be found in the `test-components` folder in the Spin repo. It does so by using the `{{$NAME}}` where `$NAME` is substituted for the name of the test component to be used. For example `{{sqlite}}` will use the test-component named "sqlite" found in the `test-components` directory. +The manifest is actually a template that allows for a few values to be interpolated by the test runner. The interpolation happens through `%{key=value}` annotations where `key` is one of a limited number of keys the test runner supports. The supported keys are: + +* `source`: The manifest can reference pre-built Spin compliant WebAssembly modules that can be found in the `test-components` folder in the Spin repo. The value is substituted for the name of the test component to be used. For example `%{source=sqlite}` will use the test-component named "sqlite" found in the `test-components` directory. +* `port`: The manifest can reference a port that has been exposed by a service (see the section on services below). For example, if the test runner sees `%{port=1234}` it will look for a service that exposes the guest port 1234 on some randomly assigned host port and substitute `%{port=1234}` for that randomly assigned port. The test directory may additionally contain: * an `error.txt` if the Spin application is expected to fail @@ -39,13 +42,16 @@ The test runner will make a GET request against the `/` path. The component shou Services allow for tests to be run against external sources. The service definitions can be found in the 'services' directory. Each test directory contains a 'services' file that configures the tests services. Each line of the services file should contain the name of a services file that needs to run. For example, the following 'services' file will run the `tcp-echo.py` service: ```txt -tcp-echo.py +tcp-echo ``` Each service is run under a file lock meaning that all other tests that require that service must wait until the current test using that service has finished. The following service types are supported: * Python services (a python script ending in the .py file extension) +* Docker services (a docker file ending in the .Dockerfile extension) + +When looking to add a new service, always prefer the Python based service as it's generally much quicker and lighter weight to run a Python script than a Docker container. Only use Docker when the service you require is not possible to achieve in cross platform way as a Python script. ## When do tests pass? diff --git a/tests/runtime-tests/services/mysql.Dockerfile b/tests/runtime-tests/services/mysql.Dockerfile new file mode 100644 index 000000000..84f78750f --- /dev/null +++ b/tests/runtime-tests/services/mysql.Dockerfile @@ -0,0 +1,10 @@ +FROM mysql + +ENV MYSQL_ROOT_PASSWORD=spin +ENV MYSQL_DATABASE=spin_dev +ENV MYSQL_USER=spin +ENV MYSQL_PASSWORD=spin + +HEALTHCHECK --start-period=4s --interval=1s CMD /usr/bin/mysqladmin ping --silent + +EXPOSE 3306 \ No newline at end of file diff --git a/tests/runtime-tests/services/postgres.Dockerfile b/tests/runtime-tests/services/postgres.Dockerfile new file mode 100644 index 000000000..6be0ea25b --- /dev/null +++ b/tests/runtime-tests/services/postgres.Dockerfile @@ -0,0 +1,5 @@ +FROM postgres + +ENV POSTGRES_USER=postgres +ENV POSTGRES_PASSWORD=postgres +ENV POSTGRES_DB=spin_dev diff --git a/tests/runtime-tests/services/redis.Dockerfile b/tests/runtime-tests/services/redis.Dockerfile new file mode 100644 index 000000000..fff849070 --- /dev/null +++ b/tests/runtime-tests/services/redis.Dockerfile @@ -0,0 +1 @@ +FROM redis \ No newline at end of file diff --git a/tests/runtime-tests/src/lib.rs b/tests/runtime-tests/src/lib.rs index ae5372cb7..feaf3311e 100644 --- a/tests/runtime-tests/src/lib.rs +++ b/tests/runtime-tests/src/lib.rs @@ -1,10 +1,14 @@ +mod services; + use std::{ io::Read, path::{Path, PathBuf}, process::{Command, Stdio}, + sync::OnceLock, }; -use anyhow::{bail, Context}; +use anyhow::Context; +use services::Services; /// Configuration for the test suite pub struct Config { @@ -54,93 +58,14 @@ pub fn bootstrap_and_run(test_path: &Path, config: &Config) -> Result<(), anyhow let temp = temp_dir::TempDir::new() .context("failed to produce a temporary directory to run the test in")?; log::trace!("Temporary directory: {}", temp.path().display()); - copy_manifest(test_path, &temp)?; - let mut services = start_services(test_path)?; + let mut services = services::start_services(test_path)?; + copy_manifest(test_path, &temp, &services)?; let spin = Spin::start(&config.spin_binary_path, temp.path(), &mut services)?; log::debug!("Spin started on port {}.", spin.port()); run_test(test_path, spin, config.on_error); Ok(()) } -fn start_services(test_path: &Path) -> anyhow::Result { - let services_config_path = test_path.join("services"); - let children = if services_config_path.exists() { - let services = std::fs::read_to_string(&services_config_path) - .context("could not read services file")?; - let service_files = services.lines().filter_map(|s| { - let s = s.trim(); - (!s.is_empty()).then_some(Path::new(s)) - }); - // TODO: make this more robust so that it is not just assumed where the services definitions are - let services_path = test_path - .parent() - .unwrap() - .parent() - .unwrap() - .join("services"); - let mut services = Vec::new(); - for service_file in service_files { - let service_name = service_file.file_stem().unwrap().to_str().unwrap(); - let child = match service_file.extension().and_then(|e| e.to_str()) { - Some("py") => { - let mut lock = - fslock::LockFile::open(&services_path.join(format!("{service_name}.lock"))) - .context("failed to open service file lock")?; - lock.lock().context("failed to obtain service file lock")?; - let child = python() - .arg(services_path.join(service_file).display().to_string()) - // Ignore stdout - .stdout(Stdio::null()) - .spawn() - .context("service failed to spawn")?; - (child, Some(lock)) - } - _ => bail!("unsupported service type found: {service_name}",), - }; - services.push(child); - } - services - } else { - Vec::new() - }; - - Ok(Services { children }) -} - -fn python() -> Command { - Command::new("python3") -} - -struct Services { - children: Vec<(std::process::Child, Option)>, -} - -impl Services { - fn error(&mut self) -> std::io::Result<()> { - for (child, _) in &mut self.children { - let exit = child.try_wait()?; - if exit.is_some() { - return Err(std::io::Error::new( - std::io::ErrorKind::Interrupted, - "process exited early", - )); - } - } - Ok(()) - } -} - -impl Drop for Services { - fn drop(&mut self) { - for (child, lock) in &mut self.children { - let _ = child.kill(); - if let Some(lock) = lock { - let _ = lock.unlock(); - } - } - } -} - /// Run an individual test fn run_test(test_path: &Path, mut spin: Spin, on_error: OnTestError) { // macro which will look at `on_error` and do the right thing @@ -194,9 +119,11 @@ fn run_test(test_path: &Path, mut spin: Spin, on_error: OnTestError) { } else { error!( on_error, - "Test errored but not in the expected way.\n\texpected: {}\n\tgot: {}", + "Test errored but not in the expected way.\n\texpected: {}\n\tgot: {}\n\nSpin stderr:\n{}", expected, - e + e, + spin.stderr.output_as_str().unwrap_or("") + ) } } @@ -209,7 +136,12 @@ fn run_test(test_path: &Path, mut spin: Spin, on_error: OnTestError) { error!(on_error, "Test '{}' errored: {e}", test_path.display()); } ResponseKind::Err(e) => { - error!(on_error, "Test '{}' errored: {e}", test_path.display()); + error!( + on_error, + "Test '{}' errored: {e}\nSpin stderr: {}", + test_path.display(), + spin.stderr.output_as_str().unwrap_or("") + ); } } if let OnTestError::Log = on_error { @@ -217,55 +149,61 @@ fn run_test(test_path: &Path, mut spin: Spin, on_error: OnTestError) { } } +static TEMPLATE: OnceLock = OnceLock::new(); /// Copies the test dir's manifest file into the temporary directory /// /// Replaces template variables in the manifest file with components from the components path. -fn copy_manifest(test_dir: &Path, temp: &temp_dir::TempDir) -> anyhow::Result<()> { +fn copy_manifest( + test_dir: &Path, + temp: &temp_dir::TempDir, + services: &Services, +) -> anyhow::Result<()> { let manifest_path = test_dir.join("spin.toml"); - let manifest = std::fs::read_to_string(&manifest_path).with_context(|| { + let mut manifest = std::fs::read_to_string(manifest_path).with_context(|| { format!( "no spin.toml manifest found in test directory {}", test_dir.display() ) })?; - let mut table = manifest - .parse::() - .context("could not parse the manifest as toml")?; - for (_, component) in table["component"].as_table_mut().with_context(|| { - format!( - "malformed manifest '{}' does not contain 'component' array", - manifest_path.display(), - ) - })? { - let source = component.get_mut("source").with_context(|| { - format!( - "malformed manifest '{}' does not contain 'source' string key in component", - manifest_path.display() - ) - })?; - let source_str = source.as_str().with_context(|| { - format!( - "malformed manifest '{}' contains 'source' key that isn't a string in component", - manifest_path.display() - ) + let regex = TEMPLATE.get_or_init(|| regex::Regex::new(r"%\{(.*?)\}").unwrap()); + while let Some(captures) = regex.captures(&manifest) { + let (Some(full), Some(capture)) = (captures.get(0), captures.get(1)) else { + continue; + }; + let template = capture.as_str(); + let (template_key, template_value) = template.split_once('=').with_context(|| { + format!("invalid template '{template}'(template should be in the form $KEY=$VALUE)") })?; - // TODO: make this more robust - if source_str.starts_with("{{") { - let name = &source_str[2..source_str.len() - 2]; - let path = - std::path::PathBuf::from(test_components::path(name).context("no such component")?); - let wasm_name = path.file_name().unwrap().to_str().unwrap(); - std::fs::copy(&path, temp.path().join(wasm_name)).with_context(|| { - format!( - "failed to copy wasm file '{}' to temporary directory", - path.display() - ) - })?; - *source = toml::Value::String(wasm_name.into()); - } + let replacement = match template_key.trim() { + "source" => { + let path = std::path::PathBuf::from( + test_components::path(template_value) + .with_context(|| format!("no such component '{template_value}'"))?, + ); + let wasm_name = path.file_name().unwrap().to_str().unwrap(); + std::fs::copy(&path, temp.path().join(wasm_name)).with_context(|| { + format!( + "failed to copy wasm file '{}' to temporary directory", + path.display() + ) + })?; + wasm_name.to_owned() + } + "port" => { + let guest_port = template_value + .parse() + .with_context(|| format!("failed to parse '{template_value}' as port"))?; + let port = services + .get_port(guest_port)? + .with_context(|| format!("no port {guest_port} exposed by any service"))?; + port.to_string() + } + _ => { + anyhow::bail!("unknown template key: {template_key}"); + } + }; + manifest.replace_range(full.range(), &replacement); } - let manifest = - toml::to_string(&table).context("failed to re-serialize manifest as a string")?; std::fs::write(temp.path().join("spin.toml"), manifest) .context("failed to copy spin.toml manifest to temporary directory")?; Ok(()) @@ -315,7 +253,7 @@ impl Spin { fn start( spin_binary_path: &Path, current_dir: &Path, - services: &mut Services, + services: &mut services::Services, ) -> Result { let port = get_random_port()?; let mut child = Command::new(spin_binary_path) diff --git a/tests/runtime-tests/src/services.rs b/tests/runtime-tests/src/services.rs new file mode 100644 index 000000000..bc5256b61 --- /dev/null +++ b/tests/runtime-tests/src/services.rs @@ -0,0 +1,132 @@ +use std::{collections::HashMap, path::Path}; + +mod docker; +mod python; + +use anyhow::{bail, Context}; + +use docker::DockerService; +use python::PythonService; + +pub fn start_services(test_path: &Path) -> anyhow::Result { + let services_config_path = test_path.join("services"); + if !services_config_path.exists() { + return Ok(Services { + services: Vec::new(), + }); + } + + let services_config_file = + std::fs::read_to_string(&services_config_path).context("could not read services file")?; + let required_services = services_config_file.lines().filter_map(|s| { + let s = s.trim(); + (!s.is_empty()).then_some(s) + }); + + // TODO: make this more robust so that it is not just assumed that the services definitions are + // located at ../../services relative to the test path + let service_definitions_path = test_path + .parent() + .unwrap() + .parent() + .unwrap() + .join("services"); + let service_definitions = service_definitions(&service_definitions_path)?; + let mut services = Vec::new(); + for required_service in required_services { + let service_definition_extension = service_definitions + .get(required_service) + .map(|e| e.as_str()); + let service: Box = match service_definition_extension { + Some("py") => Box::new(PythonService::start( + required_service, + &service_definitions_path, + )?), + Some("Dockerfile") => Box::new(DockerService::start( + required_service, + &service_definitions_path, + )?), + Some(extension) => { + bail!("service definitions with the '{extension}' extension are not supported") + } + None => bail!("no service definition found for '{required_service}'"), + }; + service.await_ready()?; + services.push(service); + } + + Ok(Services { services }) +} + +/// Get all of the service definitions returning a HashMap of the service name to the extension. +fn service_definitions(service_definitions_path: &Path) -> anyhow::Result> { + std::fs::read_dir(service_definitions_path)? + .map(|d| { + let d = d?; + if !d.file_type()?.is_file() { + bail!("directories are not allowed in the service definitions directory") + } + let file_name = d.file_name(); + let file_name = file_name.to_str().unwrap(); + let (file_name, file_extension) = file_name + .find('.') + .map(|i| (&file_name[..i], &file_name[i + 1..])) + .context("service definition did not have an extension")?; + Ok((file_name.to_owned(), file_extension.to_owned())) + }) + .filter(|r| !matches!( r , Ok((_, extension)) if extension == "lock")) + .collect() +} + +/// All the services that are running for a test. +pub struct Services { + services: Vec>, +} + +impl Services { + pub fn error(&mut self) -> anyhow::Result<()> { + for service in &mut self.services { + service.error()?; + } + Ok(()) + } + + /// Get the host port that a service exposes a guest port on. + pub(crate) fn get_port(&self, guest_port: u16) -> anyhow::Result> { + let mut result = None; + for service in &self.services { + let host_port = service.ports().unwrap().get(&guest_port); + match result { + None => result = host_port.copied(), + Some(_) => { + anyhow::bail!("more than one service exposes port {guest_port} to the host"); + } + } + } + Ok(result) + } +} + +impl<'a> IntoIterator for &'a Services { + type Item = &'a Box; + type IntoIter = std::slice::Iter<'a, Box>; + + fn into_iter(self) -> Self::IntoIter { + self.services.iter() + } +} + +/// An external service a test may depend on. +pub trait Service { + /// The name of the service + fn name(&self) -> &str; + + /// Block until the service is ready. + fn await_ready(&self) -> anyhow::Result<()>; + + /// Check if the service is in an error state. + fn error(&mut self) -> anyhow::Result<()>; + + /// Get a mapping of ports that the service exposes. + fn ports(&self) -> anyhow::Result<&HashMap>; +} diff --git a/tests/runtime-tests/src/services/docker.rs b/tests/runtime-tests/src/services/docker.rs new file mode 100644 index 000000000..67c11bff7 --- /dev/null +++ b/tests/runtime-tests/src/services/docker.rs @@ -0,0 +1,185 @@ +use super::Service; +use anyhow::{bail, Context as _}; +use std::{ + cell::OnceCell, + collections::HashMap, + path::Path, + process::{Command, Stdio}, +}; + +/// A docker container as a service +pub struct DockerService { + image_name: String, + container: Container, + // We declare lock after container so that the lock is dropped after the container is + _lock: fslock::LockFile, + ports: OnceCell>, +} + +impl DockerService { + /// Start a docker container as a service + pub fn start(name: &str, service_definitions_path: &Path) -> anyhow::Result { + let docker_file_path = service_definitions_path.join(format!("{name}.Dockerfile")); + let image_name = format!("spin/runtime-tests/services/{name}"); + let mut lock = + fslock::LockFile::open(&service_definitions_path.join(format!("{name}.lock"))) + .context("failed to open service file lock")?; + lock.lock().context("failed to obtain service file lock")?; + + stop_containers(&get_running_containers(&image_name)?)?; + build_image(&docker_file_path, &image_name)?; + let container = run_container(&image_name)?; + + Ok(Self { + image_name, + container, + _lock: lock, + ports: OnceCell::new(), + }) + } +} + +struct Container { + id: String, +} + +impl Container { + fn get_ports(&self) -> anyhow::Result> { + let output = Command::new("docker") + .arg("port") + .arg(&self.id) + .output() + .context("docker failed to fetch ports")?; + if !output.status.success() { + bail!("failed to run fetch ports for docker container"); + } + let output = String::from_utf8(output.stdout)?; + output + .lines() + .map(|s| { + // 3306/tcp -> 0.0.0.0:32770 + let s = s.trim(); + let (guest, host) = s + .split_once(" -> ") + .context("failed to parse port mapping")?; + let (guest_port, _) = guest.split_once('/').context("TODO")?; + let host_port = host.rsplit(':').next().context("TODO")?; + Ok((guest_port.parse()?, host_port.parse()?)) + }) + .collect() + } +} + +impl Drop for Container { + fn drop(&mut self) { + let _ = stop_containers(&[std::mem::take(&mut self.id)]); + } +} + +impl Service for DockerService { + fn name(&self) -> &str { + "docker" + } + + fn await_ready(&self) -> anyhow::Result<()> { + // docker container inspect -f '{{.State.Health.Status}}' + loop { + let output = Command::new("docker") + .arg("container") + .arg("inspect") + .arg("-f") + // Ensure that .State.Health exists and otherwise just print that it's healthy + .arg("{{with .State.Health}}{{.Status}}{{else}}healthy{{end}}") + .arg(&self.container.id) + .output() + .context("failed to determine container health")?; + if !output.status.success() { + let stderr = std::str::from_utf8(&output.stderr).unwrap_or(""); + bail!("docker health status check failed: {stderr}"); + } + let output = String::from_utf8(output.stdout)?; + match output.trim() { + "healthy" => return Ok(()), + "unhealthy" => bail!("docker container is unhealthy"), + _ => std::thread::sleep(std::time::Duration::from_millis(100)), + } + } + } + + fn error(&mut self) -> anyhow::Result<()> { + anyhow::ensure!(!get_running_containers(&self.image_name)?.is_empty()); + Ok(()) + } + + fn ports(&self) -> anyhow::Result<&HashMap> { + match self.ports.get() { + Some(p) => Ok(p), + None => { + let ports = self.container.get_ports()?; + Ok(self.ports.get_or_init(|| ports)) + } + } + } +} + +fn build_image(docker_file_path: &Path, image_name: &String) -> anyhow::Result<()> { + let temp_dir = temp_dir::TempDir::new() + .context("failed to produce a temporary directory to run docker in")?; + let status = Command::new("docker") + .arg("build") + .arg("-f") + .arg(docker_file_path) + .arg("-t") + .arg(image_name) + .arg(temp_dir.path()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status() + .context("service failed to spawn")?; + + if !status.success() { + bail!("failed to build docker image"); + } + Ok(()) +} + +fn get_running_containers(image_name: &str) -> anyhow::Result> { + let output = Command::new("docker") + .arg("ps") + .arg("-q") + .arg("--filter") + .arg(format!("ancestor={image_name}")) + .output() + .context("failed to get running containers")?; + let output = String::from_utf8(output.stdout)?; + Ok(output.lines().map(|s| s.to_owned()).collect()) +} + +fn run_container(image_name: &str) -> anyhow::Result { + let output = Command::new("docker") + .arg("run") + .arg("-d") + .arg("-P") + .arg("--health-start-period=1s") + .arg(image_name) + .output() + .context("service failed to spawn")?; + if !output.status.success() { + bail!("failed to run docker image"); + } + let output = String::from_utf8(output.stdout)?; + let id = output.trim().to_owned(); + Ok(Container { id }) +} + +fn stop_containers(ids: &[String]) -> anyhow::Result<()> { + for id in ids { + Command::new("docker") + .arg("stop") + .arg(id) + .output() + .context("failed to stop container")?; + let _ = Command::new("docker").arg("rm").arg(id).output(); + } + Ok(()) +} diff --git a/tests/runtime-tests/src/services/python.rs b/tests/runtime-tests/src/services/python.rs new file mode 100644 index 000000000..082fd6e57 --- /dev/null +++ b/tests/runtime-tests/src/services/python.rs @@ -0,0 +1,69 @@ +use super::Service; +use anyhow::Context as _; +use std::{ + collections::HashMap, + path::Path, + process::{Command, Stdio}, +}; + +pub struct PythonService { + child: std::process::Child, + _lock: fslock::LockFile, +} + +impl PythonService { + pub fn start(name: &str, service_definitions_path: &Path) -> anyhow::Result { + let mut lock = + fslock::LockFile::open(&service_definitions_path.join(format!("{name}.lock"))) + .context("failed to open service file lock")?; + lock.lock().context("failed to obtain service file lock")?; + let child = python() + .arg( + service_definitions_path + .join(format!("{name}.py")) + .display() + .to_string(), + ) + // Ignore stdout + .stdout(Stdio::null()) + .spawn() + .context("service failed to spawn")?; + Ok(Self { child, _lock: lock }) + } +} + +impl Service for PythonService { + fn name(&self) -> &str { + "python" + } + + fn await_ready(&self) -> anyhow::Result<()> { + Ok(()) + } + + fn error(&mut self) -> anyhow::Result<()> { + let exit = self.child.try_wait()?; + if exit.is_some() { + return Err(std::io::Error::new( + std::io::ErrorKind::Interrupted, + "process exited early", + ) + .into()); + } + Ok(()) + } + + fn ports(&self) -> anyhow::Result<&HashMap> { + todo!() + } +} + +impl Drop for PythonService { + fn drop(&mut self) { + let _ = self.child.kill(); + } +} + +fn python() -> Command { + Command::new("python3") +} diff --git a/tests/runtime-tests/tests/key-value-no-permission/spin.toml b/tests/runtime-tests/tests/key-value-no-permission/spin.toml index 9410446a4..a9eee3a87 100644 --- a/tests/runtime-tests/tests/key-value-no-permission/spin.toml +++ b/tests/runtime-tests/tests/key-value-no-permission/spin.toml @@ -10,4 +10,4 @@ route = "/" component = "test" [component.test] -source = "{{key-value}}" +source = "%{source=key-value}" diff --git a/tests/runtime-tests/tests/key-value/spin.toml b/tests/runtime-tests/tests/key-value/spin.toml index 5161be2d5..ce7c2853c 100644 --- a/tests/runtime-tests/tests/key-value/spin.toml +++ b/tests/runtime-tests/tests/key-value/spin.toml @@ -10,5 +10,5 @@ route = "/" component = "test" [component.test] -source = "{{key-value}}" +source = "%{source=key-value}" key_value_stores = ["default"] diff --git a/tests/runtime-tests/tests/outbound-mysql-no-permission/error.txt b/tests/runtime-tests/tests/outbound-mysql-no-permission/error.txt index 61bdfe422..fdca07431 100644 --- a/tests/runtime-tests/tests/outbound-mysql-no-permission/error.txt +++ b/tests/runtime-tests/tests/outbound-mysql-no-permission/error.txt @@ -1 +1 @@ -Error::ConnectionFailed("address mysql://spin:spin@mysql:3306/spin_dev is not permitted") \ No newline at end of file +Error::ConnectionFailed("address mysql://spin:spin@localhost:3306/spin_dev is not permitted") \ No newline at end of file diff --git a/tests/runtime-tests/tests/outbound-mysql-no-permission/spin.toml b/tests/runtime-tests/tests/outbound-mysql-no-permission/spin.toml index 573b884a7..8ef8bba45 100644 --- a/tests/runtime-tests/tests/outbound-mysql-no-permission/spin.toml +++ b/tests/runtime-tests/tests/outbound-mysql-no-permission/spin.toml @@ -10,5 +10,5 @@ route = "/" component = "test" [component.test] -source = "{{outbound-mysql}}" -environment = { DB_URL = "mysql://spin:spin@mysql:3306/spin_dev" } +source = "%{source=outbound-mysql}" +environment = { DB_URL = "mysql://spin:spin@localhost:3306/spin_dev" } diff --git a/tests/runtime-tests/tests/outbound-mysql/services b/tests/runtime-tests/tests/outbound-mysql/services new file mode 100644 index 000000000..0d46ca321 --- /dev/null +++ b/tests/runtime-tests/tests/outbound-mysql/services @@ -0,0 +1 @@ +mysql \ No newline at end of file diff --git a/tests/runtime-tests/tests/outbound-mysql/spin.toml b/tests/runtime-tests/tests/outbound-mysql/spin.toml index efe39c735..3f1a4eb6f 100644 --- a/tests/runtime-tests/tests/outbound-mysql/spin.toml +++ b/tests/runtime-tests/tests/outbound-mysql/spin.toml @@ -10,6 +10,6 @@ route = "/" component = "test" [component.test] -source = "{{outbound-mysql}}" -allowed_outbound_hosts = ["mysql://mysql:3306"] -environment = { DB_URL = "mysql://spin:spin@mysql:3306/spin_dev" } +source = "%{source=outbound-mysql}" +allowed_outbound_hosts = ["mysql://localhost:%{port=3306}"] +environment = { DB_URL = "mysql://spin:spin@localhost:%{port=3306}/spin_dev" } diff --git a/tests/runtime-tests/tests/outbound-postgres-no-permission/error.txt b/tests/runtime-tests/tests/outbound-postgres-no-permission/error.txt index ce02e5aa9..ed1984c5c 100644 --- a/tests/runtime-tests/tests/outbound-postgres-no-permission/error.txt +++ b/tests/runtime-tests/tests/outbound-postgres-no-permission/error.txt @@ -1 +1 @@ -Error::ConnectionFailed("address postgres://spin:spin@postgres:5432/spin_dev is not permitted") \ No newline at end of file +Error::ConnectionFailed("address postgres://spin:spin@localhost:5432/spin_dev is not permitted") \ No newline at end of file diff --git a/tests/runtime-tests/tests/outbound-postgres-no-permission/spin.toml b/tests/runtime-tests/tests/outbound-postgres-no-permission/spin.toml index b117c4aff..83ab63552 100644 --- a/tests/runtime-tests/tests/outbound-postgres-no-permission/spin.toml +++ b/tests/runtime-tests/tests/outbound-postgres-no-permission/spin.toml @@ -10,5 +10,5 @@ route = "/" component = "test" [component.test] -source = "{{outbound-postgres}}" -environment = { DB_URL = "postgres://spin:spin@postgres:5432/spin_dev" } +source = "%{source=outbound-postgres}" +environment = { DB_URL = "postgres://spin:spin@localhost:5432/spin_dev" } diff --git a/tests/runtime-tests/tests/outbound-postgres/services b/tests/runtime-tests/tests/outbound-postgres/services new file mode 100644 index 000000000..7d72bd782 --- /dev/null +++ b/tests/runtime-tests/tests/outbound-postgres/services @@ -0,0 +1 @@ +postgres \ No newline at end of file diff --git a/tests/runtime-tests/tests/outbound-postgres/spin.toml b/tests/runtime-tests/tests/outbound-postgres/spin.toml index e1976e87e..bea814010 100644 --- a/tests/runtime-tests/tests/outbound-postgres/spin.toml +++ b/tests/runtime-tests/tests/outbound-postgres/spin.toml @@ -10,6 +10,6 @@ route = "/" component = "test" [component.test] -source = "{{outbound-postgres}}" -allowed_outbound_hosts = ["postgres://postgres:5432"] -environment = { DB_URL = "postgres://postgres:postgres@postgres:5432/spin_dev" } +source = "%{source=outbound-postgres}" +allowed_outbound_hosts = ["postgres://localhost:%{port=5432}"] +environment = { DB_URL = "postgres://postgres:postgres@localhost:%{port=5432}/spin_dev" } diff --git a/tests/runtime-tests/tests/outbound-redis-no-permission/spin.toml b/tests/runtime-tests/tests/outbound-redis-no-permission/spin.toml index a8798c1bc..95e75b14b 100644 --- a/tests/runtime-tests/tests/outbound-redis-no-permission/spin.toml +++ b/tests/runtime-tests/tests/outbound-redis-no-permission/spin.toml @@ -10,5 +10,5 @@ route = "/" component = "test" [component.test] -source = "{{outbound-redis}}" -environment = { REDIS_ADDRESS = "redis://redis:6379" } +source = "%{source=outbound-redis}" +environment = { REDIS_ADDRESS = "redis://localhost:6379" } diff --git a/tests/runtime-tests/tests/outbound-redis/services b/tests/runtime-tests/tests/outbound-redis/services new file mode 100644 index 000000000..74b362f93 --- /dev/null +++ b/tests/runtime-tests/tests/outbound-redis/services @@ -0,0 +1 @@ +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 index 6fe542ba6..15b54a338 100644 --- a/tests/runtime-tests/tests/outbound-redis/spin.toml +++ b/tests/runtime-tests/tests/outbound-redis/spin.toml @@ -10,6 +10,6 @@ route = "/" component = "test" [component.test] -source = "{{outbound-redis}}" -environment = { REDIS_ADDRESS = "redis://redis:6379" } -allowed_outbound_hosts = ["redis://redis:6379"] +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/spin.toml b/tests/runtime-tests/tests/sqlite-no-permission/spin.toml index 46cc46c5e..b684a86ed 100644 --- a/tests/runtime-tests/tests/sqlite-no-permission/spin.toml +++ b/tests/runtime-tests/tests/sqlite-no-permission/spin.toml @@ -10,4 +10,4 @@ route = "/" component = "test" [component.test] -source = "{{sqlite}}" +source = "%{source=sqlite}" diff --git a/tests/runtime-tests/tests/sqlite/spin.toml b/tests/runtime-tests/tests/sqlite/spin.toml index beff28bb4..1bc45fc4e 100644 --- a/tests/runtime-tests/tests/sqlite/spin.toml +++ b/tests/runtime-tests/tests/sqlite/spin.toml @@ -10,5 +10,5 @@ route = "/" component = "test" [component.test] -source = "{{sqlite}}" +source = "%{source=sqlite}" sqlite_databases = ["default"] diff --git a/tests/runtime-tests/tests/tcp-sockets-ip-range/services b/tests/runtime-tests/tests/tcp-sockets-ip-range/services index 4e17dc0fe..272b7c063 100644 --- a/tests/runtime-tests/tests/tcp-sockets-ip-range/services +++ b/tests/runtime-tests/tests/tcp-sockets-ip-range/services @@ -1 +1 @@ -tcp-echo.py \ No newline at end of file +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 index f0c56b781..5c710bc84 100644 --- a/tests/runtime-tests/tests/tcp-sockets-ip-range/spin.toml +++ b/tests/runtime-tests/tests/tcp-sockets-ip-range/spin.toml @@ -10,5 +10,5 @@ route = "/" component = "test" [component.test] -source = "{{tcp-sockets}}" +source = "%{source=tcp-sockets}" allowed_outbound_hosts = ["*://127.0.0.0/24:6001"] 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 index 82c28db11..f71400733 100644 --- a/tests/runtime-tests/tests/tcp-sockets-no-ip-permission/spin.toml +++ b/tests/runtime-tests/tests/tcp-sockets-no-ip-permission/spin.toml @@ -10,6 +10,6 @@ route = "/" component = "test" [component.test] -source = "{{tcp-sockets}}" +source = "%{source=tcp-sockets}" # 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/spin.toml b/tests/runtime-tests/tests/tcp-sockets-no-port-permission/spin.toml index e7e94219c..dfa0ef57d 100644 --- a/tests/runtime-tests/tests/tcp-sockets-no-port-permission/spin.toml +++ b/tests/runtime-tests/tests/tcp-sockets-no-port-permission/spin.toml @@ -10,6 +10,6 @@ route = "/" component = "test" [component.test] -source = "{{tcp-sockets}}" +source = "%{source=tcp-sockets}" # Component expects port 5001 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 index 4e17dc0fe..272b7c063 100644 --- a/tests/runtime-tests/tests/tcp-sockets/services +++ b/tests/runtime-tests/tests/tcp-sockets/services @@ -1 +1 @@ -tcp-echo.py \ No newline at end of file +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 index dad9e3012..49ddfbbe6 100644 --- a/tests/runtime-tests/tests/tcp-sockets/spin.toml +++ b/tests/runtime-tests/tests/tcp-sockets/spin.toml @@ -10,5 +10,5 @@ route = "/" component = "test" [component.test] -source = "{{tcp-sockets}}" +source = "%{source=tcp-sockets}" allowed_outbound_hosts = ["*://127.0.0.1:6001"] diff --git a/tests/runtime-tests/tests/variables/spin.toml b/tests/runtime-tests/tests/variables/spin.toml index 7a9cc739d..a961fbd89 100644 --- a/tests/runtime-tests/tests/variables/spin.toml +++ b/tests/runtime-tests/tests/variables/spin.toml @@ -10,7 +10,7 @@ route = "/" component = "test" [component.test] -source = "{{variables}}" +source = "%{source=variables}" [component.test.variables] variable = "value"