FIX: TLS options
This commit is contained in:
@@ -126,3 +126,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
109
furumi-server/src/tests.rs
Normal file
109
furumi-server/src/tests.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
use crate::metrics;
|
||||
use crate::security::AuthInterceptor;
|
||||
use tonic::service::Interceptor;
|
||||
use tonic::Request;
|
||||
// Since counters are lazy statics, we can get their values directly for testing
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
#[test]
|
||||
fn test_metrics_request_timer_ok() {
|
||||
let method = "test_method_ok";
|
||||
let timer = metrics::RequestTimer::new(method);
|
||||
|
||||
// Simulate some work
|
||||
sleep(Duration::from_millis(10));
|
||||
timer.finish_ok();
|
||||
|
||||
// Check counters
|
||||
let started = metrics::GRPC_REQUESTS_TOTAL
|
||||
.with_label_values(&[method, "started"])
|
||||
.get();
|
||||
let ok = metrics::GRPC_REQUESTS_TOTAL
|
||||
.with_label_values(&[method, "ok"])
|
||||
.get();
|
||||
|
||||
assert_eq!(started, 1.0);
|
||||
assert_eq!(ok, 1.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_metrics_request_timer_err() {
|
||||
let method = "test_method_err";
|
||||
let timer = metrics::RequestTimer::new(method);
|
||||
|
||||
// Simulate some work
|
||||
sleep(Duration::from_millis(5));
|
||||
timer.finish_err();
|
||||
|
||||
// Check counters
|
||||
let started = metrics::GRPC_REQUESTS_TOTAL
|
||||
.with_label_values(&[method, "started"])
|
||||
.get();
|
||||
let err = metrics::GRPC_REQUESTS_TOTAL
|
||||
.with_label_values(&[method, "error"])
|
||||
.get();
|
||||
|
||||
assert_eq!(started, 1.0);
|
||||
assert_eq!(err, 1.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_metrics_render() {
|
||||
// Just trigger a metric to ensure the registry isn't empty
|
||||
metrics::BYTES_READ_TOTAL.inc_by(4096.0);
|
||||
|
||||
let rendered = metrics::render_metrics();
|
||||
assert!(rendered.contains("furumi_bytes_read_total"));
|
||||
assert!(rendered.contains("4096"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_auth_interceptor_valid() {
|
||||
let mut interceptor = AuthInterceptor::new("supersecret".to_string());
|
||||
let mut req = Request::new(());
|
||||
req.metadata_mut()
|
||||
.insert("authorization", "Bearer supersecret".parse().unwrap());
|
||||
|
||||
let res = interceptor.call(req);
|
||||
assert!(res.is_ok(), "Valid token should be accepted");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_auth_interceptor_invalid() {
|
||||
let mut interceptor = AuthInterceptor::new("supersecret".to_string());
|
||||
let mut req = Request::new(());
|
||||
req.metadata_mut()
|
||||
.insert("authorization", "Bearer wrongtoken".parse().unwrap());
|
||||
|
||||
let res = interceptor.call(req);
|
||||
assert!(res.is_err(), "Invalid token should be rejected");
|
||||
assert_eq!(res.unwrap_err().code(), tonic::Code::Unauthenticated);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_auth_interceptor_missing() {
|
||||
let mut interceptor = AuthInterceptor::new("supersecret".to_string());
|
||||
let req = Request::new(());
|
||||
// Missing metadata entirely
|
||||
|
||||
let res = interceptor.call(req);
|
||||
assert!(
|
||||
res.is_err(),
|
||||
"Missing token should be rejected when auth is enabled"
|
||||
);
|
||||
assert_eq!(res.unwrap_err().code(), tonic::Code::Unauthenticated);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_auth_interceptor_disabled() {
|
||||
// Empty string means auth is disabled
|
||||
let mut interceptor = AuthInterceptor::new("".to_string());
|
||||
let req = Request::new(());
|
||||
|
||||
let res = interceptor.call(req);
|
||||
assert!(
|
||||
res.is_ok(),
|
||||
"Request should pass if auth is disabled on server"
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user