#![cfg(test)]
use std::sync::Arc;
use crate::backend::BackendKind;
use crate::backend::plugins::postgres::PostgresPlugin;
use crate::broker::RequestContext;
use crate::runtime::executors::handle::DispatchExecutor;
fn fake_context() -> RequestContext {
RequestContext {
tenant_id: "acme-billing".into(),
project_id: "billing".into(),
purpose: "verify_rls".into(),
correlation_id: "rls-test-1".into(),
target_backend: "postgres".into(),
target_instance: "primary".into(),
..Default::default()
}
}
#[test]
fn postgres_plugin_is_the_rls_factory() {
use crate::backend::plugin::Backend;
let plugin = PostgresPlugin;
assert_eq!(plugin.kind(), BackendKind::Postgres);
}
#[tokio::test]
async fn pg_executor_with_context_carries_request_context() {
let pool = sqlx::postgres::PgPoolOptions::new()
.max_connections(1)
.connect_lazy("postgres://localhost/udb_rls_test_unused")
.expect("lazy pool builds without connecting");
let ctx = Arc::new(fake_context());
let with_ctx =
crate::runtime::executors::postgres::PostgresExecutor::with_context(pool.clone(), ctx);
let without_ctx = crate::runtime::executors::postgres::PostgresExecutor::with_pool(pool);
assert!(
with_ctx.context.is_some(),
"PostgresExecutor::with_context MUST carry a context so query/mutate \
wrap in tx + set_request_local_settings"
);
assert!(
without_ctx.context.is_none(),
"PostgresExecutor::with_pool MUST NOT carry a context so probe paths \
skip the transaction overhead"
);
let ctx = with_ctx.context.as_ref().expect("context");
assert_eq!(ctx.tenant_id, "acme-billing");
assert_eq!(ctx.project_id, "billing");
assert_eq!(ctx.purpose, "verify_rls");
assert_eq!(ctx.correlation_id, "rls-test-1");
}
#[tokio::test]
async fn dispatch_factory_uses_with_context_when_caller_passes_context() {
let pool = sqlx::postgres::PgPoolOptions::new()
.max_connections(1)
.connect_lazy("postgres://localhost/udb_rls_test_unused")
.expect("lazy pool builds without connecting");
let ctx = fake_context();
let with_ctx = crate::runtime::executors::postgres::PostgresExecutor::with_context(
pool.clone(),
Arc::new(ctx.clone()),
);
let without_ctx = crate::runtime::executors::postgres::PostgresExecutor::with_pool(pool);
let dispatch_with = DispatchExecutor::Postgres(with_ctx);
let dispatch_without = DispatchExecutor::Postgres(without_ctx);
if let DispatchExecutor::Postgres(exec) = &dispatch_with {
assert!(
exec.context.is_some(),
"Some(&ctx) path must produce a context-bound executor"
);
} else {
panic!("expected DispatchExecutor::Postgres variant");
}
if let DispatchExecutor::Postgres(exec) = &dispatch_without {
assert!(
exec.context.is_none(),
"None path must produce a bare executor (probe / health)"
);
} else {
panic!("expected DispatchExecutor::Postgres variant");
}
let _ = PostgresPlugin;
}
#[test]
fn set_request_local_settings_is_publicly_reachable() {
fn assert_reachable<T>(_function: T) {}
assert_reachable(crate::runtime::core::set_request_local_settings);
}