From 2f895218df8115d90ba03253024f6974a1c4f21b Mon Sep 17 00:00:00 2001 From: mo khan Date: Fri, 27 Jun 2025 14:50:34 -0600 Subject: test: add tests for grpc server --- Cargo.lock | 1 + Cargo.toml | 1 + tests/authorization/check_service_test.rs | 47 +++++++++++++++++++++--- tests/authorization/mod.rs | 1 + tests/authorization/server_test.rs | 7 ++++ tests/common/factory_bot.rs | 2 +- tests/common/mod.rs | 2 - tests/grpc_server_test.rs | 61 +++++++++++++++++++++++++++++++ tests/integration_test.rs | 2 + tests/main_test.rs | 8 ---- 10 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 tests/authorization/server_test.rs create mode 100644 tests/grpc_server_test.rs create mode 100644 tests/integration_test.rs delete mode 100644 tests/main_test.rs diff --git a/Cargo.lock b/Cargo.lock index a1c069e6..4c657df8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,6 +110,7 @@ dependencies = [ "log", "please", "tokio", + "tokio-stream", "tokio-test", "tonic", "tonic-build", diff --git a/Cargo.toml b/Cargo.toml index 2ac42209..ebacce3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,5 +24,6 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["json"] } [dev-dependencies] +tokio-stream = "0.1" tokio-test = "0.4.0" tonic-build = "0.10.0" diff --git a/tests/authorization/check_service_test.rs b/tests/authorization/check_service_test.rs index 4a8f1426..3bdf30c2 100644 --- a/tests/authorization/check_service_test.rs +++ b/tests/authorization/check_service_test.rs @@ -7,12 +7,8 @@ mod tests { use std::collections::HashMap; use std::sync::Arc; - fn authorizer() -> Arc { - Arc::new(build_cedar_authorizer()) - } - fn subject() -> CheckService { - CheckService::new(authorizer()) + CheckService::new(Arc::new(build_cedar_authorizer())) } #[tokio::test] @@ -50,6 +46,47 @@ mod tests { assert_eq!(status.code, tonic::Code::Unauthenticated as i32); } + #[tokio::test] + async fn test_static_assets() { + let static_paths = vec![ + "app.js", + "favicon.ico", + "image.jpg", + "index.html", + "logo.png", + "style.css", + ]; + + for path in static_paths { + let request = tonic::Request::new(build_request(|http| { + http.headers = build_headers(vec![(":path".to_string(), path.to_string())]); + })); + + let response = subject().check(request).await; + assert!(response.is_ok()); + + let check_response = response.unwrap().into_inner(); + assert!(check_response.status.is_some()); + + let status = check_response.status.unwrap(); + assert_eq!(status.code, tonic::Code::Ok as i32); + } + } + + #[tokio::test] + async fn test_no_headers() { + let request = tonic::Request::new(build_request(|_http| {})); + + let response = subject().check(request).await; + assert!(response.is_ok()); + + let check_response = response.unwrap().into_inner(); + assert!(check_response.status.is_some()); + + let status = check_response.status.unwrap(); + assert_eq!(status.code, tonic::Code::Unauthenticated as i32); + } + #[tokio::test] async fn test_table() { let test_cases = vec![ diff --git a/tests/authorization/mod.rs b/tests/authorization/mod.rs index a4ece924..675247d4 100644 --- a/tests/authorization/mod.rs +++ b/tests/authorization/mod.rs @@ -1,2 +1,3 @@ mod cedar_authorizer_test; mod check_service_test; +mod server_test; diff --git a/tests/authorization/server_test.rs b/tests/authorization/server_test.rs new file mode 100644 index 00000000..6001e978 --- /dev/null +++ b/tests/authorization/server_test.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { + #[test] + fn test_create_server() { + assert!(authzd::create_server().is_ok()); + } +} diff --git a/tests/common/factory_bot.rs b/tests/common/factory_bot.rs index ea3a7da1..c64b53a2 100644 --- a/tests/common/factory_bot.rs +++ b/tests/common/factory_bot.rs @@ -17,7 +17,7 @@ where } pub fn build_request(f: impl std::ops::FnOnce(&mut HttpRequest)) -> CheckRequest { - crate::common::build_with(|item: &mut CheckRequest| { + build_with(|item: &mut CheckRequest| { item.attributes = Some(please::build_with(|item: &mut AttributeContext| { item.request = Some(please::build_with(|item: &mut Request| { item.http = Some(please::build_with(|item: &mut HttpRequest| f(item))); diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 4db87a2c..5e2a6d78 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,3 +1 @@ pub mod factory_bot; - -use factory_bot::*; diff --git a/tests/grpc_server_test.rs b/tests/grpc_server_test.rs new file mode 100644 index 00000000..ec471799 --- /dev/null +++ b/tests/grpc_server_test.rs @@ -0,0 +1,61 @@ +#[cfg(test)] +mod tests { + use authzd::create_server; + use std::net::SocketAddr; + use tokio::net::TcpListener; + use tonic::transport::Channel; + + async fn available_port() -> SocketAddr { + let listener = TcpListener::bind("127.0.0.1:0") + .await + .expect("Failed to bind to random port"); + let addr = listener.local_addr().expect("Failed to get local address"); + drop(listener); + addr + } + + async fn start_server() -> (SocketAddr, tokio::task::JoinHandle<()>) { + let addr = available_port().await; + let server = create_server().expect("Failed to create server"); + + let handle = tokio::spawn(async move { + server.serve(addr).await.expect("Failed to start server"); + }); + + tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; + + (addr, handle) + } + + async fn build_channel(addr: SocketAddr) -> Channel { + Channel::from_shared(format!("http://{}", addr)) + .expect("Failed to create channel") + .connect() + .await + .expect("Failed to connect to server") + } + + async fn build_client( + addr: SocketAddr, + ) -> tonic_health::pb::health_client::HealthClient { + tonic_health::pb::health_client::HealthClient::new(build_channel(addr).await) + } + + #[tokio::test] + async fn test_health_check_service() { + let (addr, server) = start_server().await; + let mut client = build_client(addr).await; + let request = tonic::Request::new(tonic_health::pb::HealthCheckRequest { + service: String::new(), + }); + + let response = client.check(request).await; + assert!(response.is_ok()); + assert_eq!( + response.unwrap().into_inner().status(), + tonic_health::pb::health_check_response::ServingStatus::Serving + ); + + server.abort(); + } +} diff --git a/tests/integration_test.rs b/tests/integration_test.rs new file mode 100644 index 00000000..c1edf36e --- /dev/null +++ b/tests/integration_test.rs @@ -0,0 +1,2 @@ +mod authorization; +mod common; diff --git a/tests/main_test.rs b/tests/main_test.rs deleted file mode 100644 index 69c6eda1..00000000 --- a/tests/main_test.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[cfg(test)] -mod tests { - #[test] - fn test_create_server() { - let result = authzd::create_server(); - assert!(result.is_ok()); - } -} -- cgit v1.2.3