From d6907fc55a29674b403afee95bdad0a6a58da772 Mon Sep 17 00:00:00 2001 From: Adam Leventhal Date: Fri, 13 Sep 2024 20:39:49 -0700 Subject: [PATCH] Replace a custom hyper test server with httpmock (#6576) --- Cargo.lock | 457 +++++++++++++++++++++++++++++++- Cargo.toml | 1 + oximeter/collector/Cargo.toml | 2 +- oximeter/collector/src/agent.rs | 104 +++----- workspace-hack/Cargo.toml | 36 +-- 5 files changed, 509 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d72059cd27..ee4572ad0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -238,6 +238,16 @@ dependencies = [ "term", ] +[[package]] +name = "assert-json-diff" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "assert_cmd" version = "2.0.16" @@ -260,6 +270,16 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "async-bb8-diesel" version = "0.2.1" @@ -274,6 +294,116 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-object-pool" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "333c456b97c3f2d50604e8b2624253b7f787208cb72eb75e64b0ad11b221652c" +dependencies = [ + "async-std", +] + +[[package]] +name = "async-process" +version = "2.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a07789659a4d385b79b18b9127fc27e1a59e1e89117c78c5ea3b806f016374" +dependencies = [ + "async-channel 2.3.1", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener 5.3.1", + "futures-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "async-recursion" version = "1.1.1" @@ -285,6 +415,52 @@ dependencies = [ "syn 2.0.74", ] +[[package]] +name = "async-signal" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-std" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +dependencies = [ + "async-attributes", + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + [[package]] name = "async-stream" version = "0.3.5" @@ -307,6 +483,12 @@ dependencies = [ "syn 2.0.74", ] +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + [[package]] name = "async-trait" version = "0.1.82" @@ -662,6 +844,19 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + [[package]] name = "blowfish" version = "0.9.1" @@ -1258,6 +1453,15 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "console" version = "0.15.8" @@ -2605,6 +2809,33 @@ dependencies = [ "rustversion", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + [[package]] name = "expectorate" version = "1.1.0" @@ -2894,6 +3125,19 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.30" @@ -3176,6 +3420,18 @@ dependencies = [ "regex-syntax 0.8.4", ] +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "goblin" version = "0.8.2" @@ -3250,6 +3506,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.4.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.4.1" @@ -3320,13 +3595,28 @@ checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ "base64 0.21.7", "bytes", - "headers-core", + "headers-core 0.2.0", "http 0.2.12", "httpdate", "mime", "sha1", ] +[[package]] +name = "headers" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core 0.3.0", + "http 1.1.0", + "httpdate", + "mime", + "sha1", +] + [[package]] name = "headers-core" version = "0.2.0" @@ -3336,6 +3626,15 @@ dependencies = [ "http 0.2.12", ] +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http 1.1.0", +] + [[package]] name = "heapless" version = "0.7.17" @@ -3395,6 +3694,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -3592,6 +3897,19 @@ dependencies = [ "http 1.1.0", ] +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "pin-project-lite", +] + [[package]] name = "http-range" version = "0.1.5" @@ -3610,6 +3928,42 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "httpmock" +version = "0.8.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d649264818ad8f19c01f72b4ddf2f0cfcd1183691b956de733673e81d8a51f" +dependencies = [ + "assert-json-diff", + "async-object-pool", + "async-std", + "async-trait", + "base64 0.22.1", + "bytes", + "crossbeam-utils", + "form_urlencoded", + "futures-timer", + "futures-util", + "headers 0.4.0", + "http 1.1.0", + "http-body-util", + "hyper 1.4.1", + "hyper-util", + "lazy_static", + "log", + "path-tree", + "regex", + "serde", + "serde_json", + "serde_regex", + "similar", + "stringmetrics", + "tabwriter", + "thiserror", + "tokio", + "url", +] + [[package]] name = "httptest" version = "0.15.5" @@ -3689,7 +4043,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -3705,16 +4059,18 @@ dependencies = [ [[package]] name = "hyper" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", "futures-util", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.0", "httparse", + "httpdate", "itoa", "pin-project-lite", "smallvec 1.13.2", @@ -3744,7 +4100,7 @@ checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.3.1", + "hyper 1.4.1", "hyper-util", "log", "rustls 0.22.4", @@ -3798,7 +4154,7 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.0", - "hyper 1.3.1", + "hyper 1.4.1", "pin-project-lite", "socket2 0.5.7", "tokio", @@ -4347,6 +4703,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lalrpop" version = "0.19.12" @@ -4654,6 +5019,9 @@ name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +dependencies = [ + "value-bag", +] [[package]] name = "lpc55_areas" @@ -5027,7 +5395,7 @@ dependencies = [ "cookie 0.18.1", "dropshot 0.10.2-dev", "futures", - "headers", + "headers 0.3.9", "http 0.2.12", "hyper 0.14.30", "newtype_derive", @@ -5533,7 +5901,7 @@ dependencies = [ "futures", "gateway-messages", "gateway-test-utils", - "headers", + "headers 0.3.9", "hickory-resolver", "http 0.2.12", "hyper 0.14.30", @@ -6210,7 +6578,7 @@ dependencies = [ "gateway-client", "gateway-messages", "gateway-test-utils", - "headers", + "headers 0.3.9", "hex", "hickory-resolver", "http 0.2.12", @@ -6584,7 +6952,7 @@ dependencies = [ "expectorate", "filetime", "gethostname", - "headers", + "headers 0.3.9", "hex", "http 0.2.12", "libc", @@ -6670,6 +7038,8 @@ dependencies = [ "hickory-proto", "hmac", "hyper 0.14.30", + "hyper 1.4.1", + "hyper-util", "indexmap 2.4.0", "inout", "itertools 0.10.5", @@ -7068,7 +7438,7 @@ dependencies = [ "dropshot 0.10.2-dev", "expectorate", "futures", - "hyper 0.14.30", + "httpmock", "internal-dns", "nexus-client", "nexus-types", @@ -7387,6 +7757,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.11.2" @@ -7512,6 +7888,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498a099351efa4becc6a19c72aa9270598e8fd274ca47052e37455241c88b696" +[[package]] +name = "path-tree" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c7fabb0b56aba5d2eb3fa9b1547c187f21f8c051295a7b97a50be6a9332f4cb" +dependencies = [ + "smallvec 1.13.2", +] + [[package]] name = "pathdiff" version = "0.2.1" @@ -7711,6 +8096,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + [[package]] name = "pkcs1" version = "0.7.5" @@ -7805,6 +8201,21 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "poly1305" version = "0.8.0" @@ -8649,7 +9060,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.30", @@ -9477,6 +9888,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_regex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" +dependencies = [ + "regex", + "serde", +] + [[package]] name = "serde_repr" version = "0.1.19" @@ -10268,6 +10689,12 @@ dependencies = [ "serde", ] +[[package]] +name = "stringmetrics" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b3c8667cd96245cbb600b8dec5680a7319edd719c5aa2b5d23c6bff94f39765" + [[package]] name = "stringprep" version = "0.1.4" @@ -11688,6 +12115,12 @@ dependencies = [ "log", ] +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index 0a42f86120..b7b34390e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -383,6 +383,7 @@ hickory-server = "0.24.1" highway = "1.2.0" hkdf = "0.12.4" http = "0.2.12" +httpmock = "0.8.0-alpha.1" httptest = "0.15.5" hubtools = { git = "https://github.com/oxidecomputer/hubtools.git", branch = "main" } humantime = "2.1.0" diff --git a/oximeter/collector/Cargo.toml b/oximeter/collector/Cargo.toml index cd1e012e5c..f8f8e147ec 100644 --- a/oximeter/collector/Cargo.toml +++ b/oximeter/collector/Cargo.toml @@ -40,7 +40,7 @@ nexus-client.workspace = true [dev-dependencies] expectorate.workspace = true -hyper.workspace = true +httpmock.workspace = true omicron-test-utils.workspace = true openapi-lint.workspace = true openapiv3.workspace = true diff --git a/oximeter/collector/src/agent.rs b/oximeter/collector/src/agent.rs index b13fbd3938..60d5a7766b 100644 --- a/oximeter/collector/src/agent.rs +++ b/oximeter/collector/src/agent.rs @@ -196,6 +196,16 @@ async fn collection_task( } #[cfg(test)] Some(CollectionMessage::Statistics { reply_tx }) => { + // Time should be paused when using this retrieval + // mechanism. We advance time to cause a panic if this + // message were to be sent with time *not* paused. + tokio::time::advance(Duration::from_nanos(1)).await; + // The collection timer *may* be ready to go in which + // case we would do a collection right after + // processesing this message, thus changing the actual + // data. Instead we reset the timer to prevent + // additional collections (i.e. since time is paused). + collection_timer.reset(); debug!( log, "received request for current task statistics" @@ -849,21 +859,11 @@ mod tests { use super::OximeterAgent; use super::ProducerEndpoint; use crate::self_stats::FailureReason; - use hyper::service::make_service_fn; - use hyper::service::service_fn; - use hyper::Body; - use hyper::Request; - use hyper::Response; - use hyper::Server; - use hyper::StatusCode; use omicron_common::api::internal::nexus::ProducerKind; use omicron_test_utils::dev::test_setup_log; - use std::convert::Infallible; use std::net::Ipv6Addr; use std::net::SocketAddr; use std::net::SocketAddrV6; - use std::sync::atomic::AtomicU64; - use std::sync::atomic::Ordering; use std::time::Duration; use tokio::sync::oneshot; use tokio::time::Instant; @@ -888,12 +888,6 @@ mod tests { + COLLECTION_INTERVAL.as_millis() as u64 / 2, ); - // The number of actual successful test collections. - static N_SUCCESSFUL_COLLECTIONS: AtomicU64 = AtomicU64::new(0); - - // The number of actual failed test collections. - static N_FAILED_COLLECTIONS: AtomicU64 = AtomicU64::new(0); - // Test that we count successful collections from a target correctly. #[tokio::test] async fn test_self_stat_collection_count() { @@ -911,25 +905,18 @@ mod tests { .await .unwrap(); - // And a dummy server that will always report empty statistics. There - // will be no actual data here, but the sample counter will increment. - let addr = - SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::LOCALHOST, 0, 0, 0)); - let make_svc = make_service_fn(|_conn| async { - Ok::<_, Infallible>(service_fn(|_: Request| async { - N_SUCCESSFUL_COLLECTIONS.fetch_add(1, Ordering::SeqCst); - Ok::<_, Infallible>(Response::new(Body::from("[]"))) - })) + // Spawn the mock server that always reports empty statistics. + let server = httpmock::MockServer::start(); + let mock_ok = server.mock(|when, then| { + when.any_request(); + then.status(reqwest::StatusCode::OK).body("[]"); }); - let server = Server::bind(&addr).serve(make_svc); - let address = server.local_addr(); - let _task = tokio::task::spawn(server); // Register the dummy producer. let endpoint = ProducerEndpoint { id: Uuid::new_v4(), kind: ProducerKind::Service, - address, + address: *server.address(), interval: COLLECTION_INTERVAL, }; collector @@ -963,10 +950,11 @@ mod tests { .await .expect("failed to request statistics from task"); let stats = rx.await.expect("failed to receive statistics from task"); - assert_eq!( - stats.collections.datum.value(), - N_SUCCESSFUL_COLLECTIONS.load(Ordering::SeqCst) - ); + + let count = stats.collections.datum.value() as usize; + + assert!(count != 0); + mock_ok.assert_calls(count); assert!(stats.failed_collections.is_empty()); logctx.cleanup_successful(); } @@ -1057,26 +1045,18 @@ mod tests { .await .unwrap(); - // And a dummy server that will always fail with a 500. - let addr = - SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::LOCALHOST, 0, 0, 0)); - let make_svc = make_service_fn(|_conn| async { - Ok::<_, Infallible>(service_fn(|_: Request| async { - N_FAILED_COLLECTIONS.fetch_add(1, Ordering::SeqCst); - let mut res = Response::new(Body::from("im ded")); - *res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - Ok::<_, Infallible>(res) - })) + // Spawn the mock server that always responds with a server error + let server = httpmock::MockServer::start(); + let mock_fail = server.mock(|when, then| { + when.any_request(); + then.status(500).body("im ded"); }); - let server = Server::bind(&addr).serve(make_svc); - let address = server.local_addr(); - let _task = tokio::task::spawn(server); // Register the rather flaky producer. let endpoint = ProducerEndpoint { id: Uuid::new_v4(), kind: ProducerKind::Service, - address, + address: *server.address(), interval: COLLECTION_INTERVAL, }; collector @@ -1084,13 +1064,11 @@ mod tests { .await .expect("failed to register flaky producer"); - // Step time until there has been exactly `N_COLLECTIONS` collections. + // Step time for a few collections. // - // NOTE: This is technically still a bit racy, in that the server task - // may have made a different number of attempts than we expect. In - // practice, we've not seen this one fail, so basing the number of - // counts on time seems reasonable, especially since we don't have other - // low-cost options for verifying the behavior. + // Due to scheduling variations, we don't verify the number of + // collections we expect based on time, but we instead check that every + // collection that _has_ occurred bumps the counter. tokio::time::pause(); let now = Instant::now(); while now.elapsed() < TEST_WAIT_PERIOD { @@ -1112,16 +1090,18 @@ mod tests { .await .expect("failed to request statistics from task"); let stats = rx.await.expect("failed to receive statistics from task"); + let count = stats + .failed_collections + .get(&FailureReason::Other( + reqwest::StatusCode::INTERNAL_SERVER_ERROR, + )) + .unwrap() + .datum + .value() as usize; + assert_eq!(stats.collections.datum.value(), 0); - assert_eq!( - stats - .failed_collections - .get(&FailureReason::Other(StatusCode::INTERNAL_SERVER_ERROR)) - .unwrap() - .datum - .value(), - N_FAILED_COLLECTIONS.load(Ordering::SeqCst), - ); + assert!(count != 0); + mock_fail.assert_calls(count); assert_eq!(stats.failed_collections.len(), 1); logctx.cleanup_successful(); } diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index 4b1a4f28d0..4580173e48 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -49,7 +49,7 @@ fs-err = { version = "2.11.0", default-features = false, features = ["tokio"] } futures = { version = "0.3.30" } futures-channel = { version = "0.3.30", features = ["sink"] } futures-core = { version = "0.3.30" } -futures-io = { version = "0.3.30", default-features = false, features = ["std"] } +futures-io = { version = "0.3.30" } futures-sink = { version = "0.3.30" } futures-task = { version = "0.3.30", default-features = false, features = ["std"] } futures-util = { version = "0.3.30", features = ["channel", "io", "sink"] } @@ -61,7 +61,9 @@ hashbrown = { version = "0.14.5", features = ["raw"] } hex = { version = "0.4.3", features = ["serde"] } hickory-proto = { version = "0.24.1", features = ["text-parsing"] } hmac = { version = "0.12.1", default-features = false, features = ["reset"] } -hyper = { version = "0.14.30", features = ["full"] } +hyper-582f2526e08bb6a0 = { package = "hyper", version = "0.14.30", features = ["full"] } +hyper-dff4ba8e3ae991db = { package = "hyper", version = "1.4.1", features = ["client", "http1", "http2", "server"] } +hyper-util = { version = "0.1.3", features = ["client-legacy", "server-auto", "tokio"] } indexmap = { version = "2.4.0", features = ["serde"] } inout = { version = "0.1.3", default-features = false, features = ["std"] } itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } @@ -69,7 +71,7 @@ itertools-93f6ce9d446188ac = { package = "itertools", version = "0.10.5" } lalrpop-util = { version = "0.19.12" } lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] } libc = { version = "0.2.158", features = ["extra_traits"] } -log = { version = "0.4.21", default-features = false, features = ["std"] } +log = { version = "0.4.21", default-features = false, features = ["kv_unstable", "std"] } managed = { version = "0.8.0", default-features = false, features = ["alloc", "map"] } memchr = { version = "2.7.2" } nom = { version = "7.1.3" } @@ -157,7 +159,7 @@ fs-err = { version = "2.11.0", default-features = false, features = ["tokio"] } futures = { version = "0.3.30" } futures-channel = { version = "0.3.30", features = ["sink"] } futures-core = { version = "0.3.30" } -futures-io = { version = "0.3.30", default-features = false, features = ["std"] } +futures-io = { version = "0.3.30" } futures-sink = { version = "0.3.30" } futures-task = { version = "0.3.30", default-features = false, features = ["std"] } futures-util = { version = "0.3.30", features = ["channel", "io", "sink"] } @@ -169,7 +171,9 @@ hashbrown = { version = "0.14.5", features = ["raw"] } hex = { version = "0.4.3", features = ["serde"] } hickory-proto = { version = "0.24.1", features = ["text-parsing"] } hmac = { version = "0.12.1", default-features = false, features = ["reset"] } -hyper = { version = "0.14.30", features = ["full"] } +hyper-582f2526e08bb6a0 = { package = "hyper", version = "0.14.30", features = ["full"] } +hyper-dff4ba8e3ae991db = { package = "hyper", version = "1.4.1", features = ["client", "http1", "http2", "server"] } +hyper-util = { version = "0.1.3", features = ["client-legacy", "server-auto", "tokio"] } indexmap = { version = "2.4.0", features = ["serde"] } inout = { version = "0.1.3", default-features = false, features = ["std"] } itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12.1" } @@ -177,7 +181,7 @@ itertools-93f6ce9d446188ac = { package = "itertools", version = "0.10.5" } lalrpop-util = { version = "0.19.12" } lazy_static = { version = "1.5.0", default-features = false, features = ["spin_no_std"] } libc = { version = "0.2.158", features = ["extra_traits"] } -log = { version = "0.4.21", default-features = false, features = ["std"] } +log = { version = "0.4.21", default-features = false, features = ["kv_unstable", "std"] } managed = { version = "0.8.0", default-features = false, features = ["alloc", "map"] } memchr = { version = "2.7.2" } nom = { version = "7.1.3" } @@ -236,49 +240,49 @@ zeroize = { version = "1.7.0", features = ["std", "zeroize_derive"] } [target.x86_64-unknown-linux-gnu.dependencies] dof = { version = "0.3.0", default-features = false, features = ["des"] } -linux-raw-sys = { version = "0.4.13", default-features = false, features = ["elf", "errno", "general", "ioctl", "no_std", "std", "system"] } +linux-raw-sys = { version = "0.4.13", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "std", "system", "xdp"] } mio = { version = "1.0.2", features = ["net", "os-ext"] } once_cell = { version = "1.19.0" } -rustix = { version = "0.38.34", features = ["fs", "stdio", "system", "termios"] } +rustix = { version = "0.38.34", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] } signal-hook-mio = { version = "0.2.4", default-features = false, features = ["support-v0_8", "support-v1_0"] } [target.x86_64-unknown-linux-gnu.build-dependencies] dof = { version = "0.3.0", default-features = false, features = ["des"] } -linux-raw-sys = { version = "0.4.13", default-features = false, features = ["elf", "errno", "general", "ioctl", "no_std", "std", "system"] } +linux-raw-sys = { version = "0.4.13", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "std", "system", "xdp"] } mio = { version = "1.0.2", features = ["net", "os-ext"] } once_cell = { version = "1.19.0" } -rustix = { version = "0.38.34", features = ["fs", "stdio", "system", "termios"] } +rustix = { version = "0.38.34", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] } signal-hook-mio = { version = "0.2.4", default-features = false, features = ["support-v0_8", "support-v1_0"] } [target.x86_64-apple-darwin.dependencies] mio = { version = "1.0.2", features = ["net", "os-ext"] } once_cell = { version = "1.19.0" } -rustix = { version = "0.38.34", features = ["fs", "stdio", "system", "termios"] } +rustix = { version = "0.38.34", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] } signal-hook-mio = { version = "0.2.4", default-features = false, features = ["support-v0_8", "support-v1_0"] } [target.x86_64-apple-darwin.build-dependencies] mio = { version = "1.0.2", features = ["net", "os-ext"] } once_cell = { version = "1.19.0" } -rustix = { version = "0.38.34", features = ["fs", "stdio", "system", "termios"] } +rustix = { version = "0.38.34", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] } signal-hook-mio = { version = "0.2.4", default-features = false, features = ["support-v0_8", "support-v1_0"] } [target.aarch64-apple-darwin.dependencies] mio = { version = "1.0.2", features = ["net", "os-ext"] } once_cell = { version = "1.19.0" } -rustix = { version = "0.38.34", features = ["fs", "stdio", "system", "termios"] } +rustix = { version = "0.38.34", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] } signal-hook-mio = { version = "0.2.4", default-features = false, features = ["support-v0_8", "support-v1_0"] } [target.aarch64-apple-darwin.build-dependencies] mio = { version = "1.0.2", features = ["net", "os-ext"] } once_cell = { version = "1.19.0" } -rustix = { version = "0.38.34", features = ["fs", "stdio", "system", "termios"] } +rustix = { version = "0.38.34", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] } signal-hook-mio = { version = "0.2.4", default-features = false, features = ["support-v0_8", "support-v1_0"] } [target.x86_64-unknown-illumos.dependencies] dof = { version = "0.3.0", default-features = false, features = ["des"] } mio = { version = "1.0.2", features = ["net", "os-ext"] } once_cell = { version = "1.19.0" } -rustix = { version = "0.38.34", features = ["fs", "stdio", "system", "termios"] } +rustix = { version = "0.38.34", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] } signal-hook-mio = { version = "0.2.4", default-features = false, features = ["support-v0_8", "support-v1_0"] } toml_edit-cdcf2f9584511fe6 = { package = "toml_edit", version = "0.19.15", features = ["serde"] } @@ -286,7 +290,7 @@ toml_edit-cdcf2f9584511fe6 = { package = "toml_edit", version = "0.19.15", featu dof = { version = "0.3.0", default-features = false, features = ["des"] } mio = { version = "1.0.2", features = ["net", "os-ext"] } once_cell = { version = "1.19.0" } -rustix = { version = "0.38.34", features = ["fs", "stdio", "system", "termios"] } +rustix = { version = "0.38.34", features = ["event", "fs", "net", "pipe", "process", "stdio", "system", "termios", "time"] } signal-hook-mio = { version = "0.2.4", default-features = false, features = ["support-v0_8", "support-v1_0"] } toml_edit-cdcf2f9584511fe6 = { package = "toml_edit", version = "0.19.15", features = ["serde"] }