diff --git a/lading/src/blackhole/otlp/http.rs b/lading/src/blackhole/otlp/http.rs index c85b86a8f..c95e19c5e 100644 --- a/lading/src/blackhole/otlp/http.rs +++ b/lading/src/blackhole/otlp/http.rs @@ -84,6 +84,10 @@ struct OtlpHttpHandler { } impl OtlpHttpHandler { + #[expect( + clippy::expect_used, + reason = "serde_json on default-constructed OTLP response protos is infallible" + )] fn new(response_delay: Duration, labels: &[(String, String)]) -> Self { // Pre-compute empty responses for both formats let empty_metrics = ExportMetricsServiceResponse::default(); @@ -105,10 +109,10 @@ impl OtlpHttpHandler { let content_type_proto = "application/x-protobuf" .parse() - .expect("application/x-protobuf is a valid MIME type"); + .unwrap_or_else(|_| unreachable!("\"application/x-protobuf\" is a valid HeaderValue")); let content_type_json = "application/json" .parse() - .expect("application/json is a valid MIME type"); + .unwrap_or_else(|_| unreachable!("\"application/json\" is a valid HeaderValue")); Self { labels: labels.to_vec(), @@ -135,13 +139,15 @@ impl OtlpHttpHandler { } let mut response = Response::builder().status(StatusCode::OK); - let headers = response - .headers_mut() - .expect("Response builder should always provide headers_mut"); + let headers = response.headers_mut().unwrap_or_else(|| { + unreachable!("Response::builder produces a builder with headers_mut available") + }); headers.insert(hyper::header::CONTENT_TYPE, content_type.clone()); Ok(response .body(crate::full(response_bytes)) - .expect("Creating HTTP response should not fail")) + .unwrap_or_else(|_| { + unreachable!("Response::builder().body() on an OK builder cannot fail") + })) } #[expect(clippy::too_many_lines)] @@ -156,7 +162,9 @@ impl OtlpHttpHandler { return Ok(Response::builder() .status(StatusCode::NOT_FOUND) .body(crate::full(Bytes::from_static(NOT_FOUND))) - .expect("Creating HTTP response should not fail")); + .unwrap_or_else(|_| { + unreachable!("Response::builder().body() on an OK builder cannot fail") + })); } counter!("requests_received", &self.labels).increment(1); diff --git a/lading/src/blackhole/tcp_rr.rs b/lading/src/blackhole/tcp_rr.rs index cf32a2cd9..10cc23167 100644 --- a/lading/src/blackhole/tcp_rr.rs +++ b/lading/src/blackhole/tcp_rr.rs @@ -151,6 +151,10 @@ impl TcpRr { /// /// Panics if the ready-barrier tokio task is cancelled. #[allow(clippy::too_many_lines)] + #[expect( + clippy::expect_used, + reason = "set_nonblocking on a freshly bound TcpListener panics only on system resource exhaustion; documented contract for blackhole startup" + )] pub async fn run(self) -> Result<(), Error> { let shutdown_flag = thread::new_shutdown_flag(); let num_threads = self.config.threads.get(); @@ -298,6 +302,10 @@ impl TcpRr { /// Create a listener socket. When `num_threads` > 1, sets `SO_REUSEPORT` /// and (for thread 0) attaches the reuseport eBPF program. +#[expect( + clippy::expect_used, + reason = "socket-setup syscalls (set_nonblocking/cloexec/reuse_addr/reuse_port/listen) panic on system resource exhaustion; documented contract for blackhole startup" +)] fn create_listener( thread_index: u16, num_threads: u16, @@ -349,6 +357,10 @@ fn create_listener( } #[allow(clippy::too_many_arguments)] +#[expect( + clippy::expect_used, + reason = "mio Poll/registry setup panics on system resource exhaustion; documented contract for the server thread" +)] fn server_thread_main( thread_index: u16, num_threads: u16, diff --git a/lading/src/generator/container.rs b/lading/src/generator/container.rs index d82dfdadf..ce47420aa 100644 --- a/lading/src/generator/container.rs +++ b/lading/src/generator/container.rs @@ -226,6 +226,10 @@ impl Container { /// /// Panics if container index cannot be converted to u32. #[expect(clippy::too_many_lines)] + #[expect( + clippy::expect_used, + reason = "u32::try_from on `idx` from enumerate(..self.concurrent_containers) which is u32 by config" + )] pub async fn spin(mut self) -> Result<(), Error> { info!( "Container generator running: {repository}:{tag}", diff --git a/lading/src/generator/file_tree.rs b/lading/src/generator/file_tree.rs index ca1da942a..c098d6807 100644 --- a/lading/src/generator/file_tree.rs +++ b/lading/src/generator/file_tree.rs @@ -207,6 +207,10 @@ impl FileTree { /// # Panics /// /// Function will panic if one node is not path is not populated properly + #[expect( + clippy::expect_used, + reason = "self.nodes is non-empty at construction and iter().cycle() never terminates" + )] pub async fn spin(mut self) -> Result<(), Error> { let mut iter = self.nodes.iter().cycle(); let mut folders = Vec::with_capacity(self.total_folder);