test(relay): parameterize app state backend

Centralize relay test state construction behind BUZZ_TEST_BACKEND, defaulting to the unchanged PostgreSQL path and providing a migrated in-memory SQLite database with a configured community fixture.

Signed-off-by: npub13n66s06epmqf2kc3v373ez8hj65cuzyvxzjf93vwpervxqn2u7jq2qd9je <8cf5a83f590ec0955b11647d1c88f796a98e088c30a492c58e0e46c3026ae7a4@buzz.block.builderlab.xyz>
Signed-off-by: Brother Darryl <146fb160a3266e6165bfa385f6048c975eda9e21cf65da097a0b5ea7952532a5@buzz.block.builderlab.xyz>
This commit is contained in:
npub13n66s06epmqf2kc3v373ez8hj65cuzyvxzjf93vwpervxqn2u7jq2qd9je
2026-08-04 12:41:45 -04:00
committed by Brother Darryl
parent 127386d091
commit e93e651eeb
7 changed files with 121 additions and 181 deletions

View File

@@ -332,44 +332,13 @@ mod tests {
use tower::ServiceExt;
async fn test_state() -> Arc<crate::state::AppState> {
let mut config = crate::config::Config::from_env().expect("default config loads");
config.require_relay_membership = false;
config.redis_url = "redis://127.0.0.1:1".to_string();
config.admin = Some(crate::config::AdminConfig {
host: "admin.example".to_string(),
web_dir: None,
});
let pool = sqlx::PgPool::connect_lazy(&config.database_url).expect("lazy pg pool");
let db = buzz_db::Db::from_pool(pool.clone());
let redis_pool = deadpool_redis::Config::from_url(&config.redis_url)
.create_pool(Some(deadpool_redis::Runtime::Tokio1))
.expect("redis pool");
let pubsub = Arc::new(
buzz_pubsub::PubSubManager::new(&config.redis_url, redis_pool.clone())
.await
.expect("pubsub manager"),
);
let audit = buzz_audit::AuditService::new(pool.clone());
let auth = buzz_auth::AuthService::new(config.auth.clone());
let search = buzz_search::SearchService::new(pool.clone());
let workflow_engine = Arc::new(buzz_workflow::WorkflowEngine::new(
db.clone(),
buzz_workflow::WorkflowConfig::default(),
));
let media_storage = buzz_media::MediaStorage::new(&config.media).expect("media storage");
let (state, _audit_shutdown) = crate::state::AppState::new(
config,
db,
redis_pool,
audit,
pubsub,
auth,
search,
workflow_engine,
nostr::Keys::generate(),
media_storage,
);
Arc::new(state)
crate::test_support::test_state_with_config(|config| {
config.admin = Some(crate::config::AdminConfig {
host: "admin.example".to_string(),
web_dir: None,
});
})
.await
}
const HASH: &str = "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789";

View File

@@ -937,47 +937,18 @@ mod tests {
}
async fn test_state() -> Arc<AppState> {
let mut config = crate::config::Config::from_env().expect("default config loads");
config.require_relay_membership = false;
config.redis_url = "redis://127.0.0.1:1".to_string();
config.media_uploads_per_minute = 1;
config.media_max_concurrent_uploads = 2;
config.media_max_concurrent_uploads_per_pubkey = 1;
let pool = sqlx::PgPool::connect_lazy(&config.database_url).expect("lazy pg pool");
let db = buzz_db::Db::from_pool(pool.clone());
db.ensure_configured_community("relay.example")
let state = crate::test_support::test_state_with_config(|config| {
config.media_uploads_per_minute = 1;
config.media_max_concurrent_uploads = 2;
config.media_max_concurrent_uploads_per_pubkey = 1;
})
.await;
state
.db
.ensure_configured_community("relay.example")
.await
.expect("seed relay.example community for host-bound media tests");
let redis_pool = deadpool_redis::Config::from_url(&config.redis_url)
.create_pool(Some(deadpool_redis::Runtime::Tokio1))
.expect("redis pool");
let pubsub = Arc::new(
buzz_pubsub::PubSubManager::new(&config.redis_url, redis_pool.clone())
.await
.expect("pubsub manager"),
);
let audit = buzz_audit::AuditService::new(pool.clone());
let auth = buzz_auth::AuthService::new(config.auth.clone());
let search = buzz_search::SearchService::new(pool.clone());
let workflow_engine = Arc::new(buzz_workflow::WorkflowEngine::new(
db.clone(),
buzz_workflow::WorkflowConfig::default(),
));
let media_storage = buzz_media::MediaStorage::new(&config.media).expect("media storage");
let (state, _audit_shutdown) = AppState::new(
config,
db,
redis_pool,
audit,
pubsub,
auth,
search,
workflow_engine,
nostr::Keys::generate(),
media_storage,
);
Arc::new(state)
state
}
async fn media_get_auth_router() -> axum::Router {

View File

@@ -2004,44 +2004,14 @@ mod tests {
}
pub(super) async fn test_state_with_redis_url(redis_url: &str) -> Arc<AppState> {
let mut config = test_config();
config.redis_url = redis_url.to_string();
let pool = sqlx::PgPool::connect_lazy(&config.database_url).expect("lazy pg pool");
let db = buzz_db::Db::from_pool(pool.clone());
let redis_pool = deadpool_redis::Config::from_url(&config.redis_url)
.create_pool(Some(deadpool_redis::Runtime::Tokio1))
.expect("redis pool");
let pubsub = Arc::new(
buzz_pubsub::PubSubManager::new(&config.redis_url, redis_pool.clone())
.await
.expect("pubsub manager"),
);
let audit = buzz_audit::AuditService::new(pool.clone());
let auth = buzz_auth::AuthService::new(config.auth.clone());
let search = buzz_search::SearchService::new(pool.clone());
let workflow_engine = Arc::new(buzz_workflow::WorkflowEngine::new(
db.clone(),
buzz_workflow::WorkflowConfig::default(),
));
let media_storage =
buzz_media::MediaStorage::new(&config.media).expect("media storage");
let (state, _audit_shutdown) = AppState::new(
config,
db,
redis_pool,
audit,
pubsub,
auth,
search,
workflow_engine,
Keys::generate(),
media_storage,
);
Arc::new(state)
crate::test_support::test_state_with_config(|config| {
config.redis_url = redis_url.to_string();
})
.await
}
pub(super) async fn test_state() -> Arc<AppState> {
test_state_with_redis_url("redis://127.0.0.1:1").await
crate::test_support::test_state().await
}
/// Real-PG, real-Redis state that hands back the audit shutdown handle so

View File

@@ -44,6 +44,8 @@ pub mod subscription;
pub mod telemetry;
/// Row-zero host binding: resolve the request community from the connection host.
pub mod tenant;
#[cfg(test)]
mod test_support;
/// Relay-side tunnel session directory and routing.
pub mod tunnel;
/// Webhook secret generation and constant-time comparison.

View File

@@ -1411,40 +1411,7 @@ mod tests {
}
async fn test_state() -> Arc<AppState> {
let mut config = crate::config::Config::from_env().expect("default config loads");
config.require_relay_membership = false;
config.redis_url = "redis://127.0.0.1:1".to_string();
let pool = sqlx::PgPool::connect_lazy(&config.database_url).expect("lazy pg pool");
let db = buzz_db::Db::from_pool(pool.clone());
let redis_pool = deadpool_redis::Config::from_url(&config.redis_url)
.create_pool(Some(deadpool_redis::Runtime::Tokio1))
.expect("redis pool");
let pubsub = Arc::new(
buzz_pubsub::PubSubManager::new(&config.redis_url, redis_pool.clone())
.await
.expect("pubsub manager"),
);
let audit = buzz_audit::AuditService::new(pool.clone());
let auth = buzz_auth::AuthService::new(config.auth.clone());
let search = buzz_search::SearchService::new(pool.clone());
let workflow_engine = Arc::new(buzz_workflow::WorkflowEngine::new(
db.clone(),
buzz_workflow::WorkflowConfig::default(),
));
let media_storage = buzz_media::MediaStorage::new(&config.media).expect("media storage");
let (state, _audit_shutdown) = AppState::new(
config,
db,
redis_pool,
audit,
pubsub,
auth,
search,
workflow_engine,
nostr::Keys::generate(),
media_storage,
);
Arc::new(state)
crate::test_support::test_state().await
}
#[test]

View File

@@ -0,0 +1,95 @@
//! Shared relay test state for backend-conformance tests.
use std::sync::Arc;
use crate::config::Config;
use crate::state::AppState;
const SQLITE_TEST_URL: &str = "sqlite::memory:";
const TEST_COMMUNITY_HOST: &str = "relay.example";
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum TestBackend {
Postgres,
Sqlite,
}
impl TestBackend {
fn from_env() -> Self {
match std::env::var("BUZZ_TEST_BACKEND") {
Err(_) => Self::Postgres,
Ok(value) if value.eq_ignore_ascii_case("postgres") => Self::Postgres,
Ok(value) if value.eq_ignore_ascii_case("sqlite") => Self::Sqlite,
Ok(value) => panic!("BUZZ_TEST_BACKEND must be 'postgres' or 'sqlite', got {value:?}"),
}
}
}
/// Build the standard relay test state for `BUZZ_TEST_BACKEND`.
pub(crate) async fn test_state() -> Arc<AppState> {
test_state_with_config(|_| {}).await
}
/// Build relay test state after applying test-specific configuration.
pub(crate) async fn test_state_with_config(configure: impl FnOnce(&mut Config)) -> Arc<AppState> {
let mut config = Config::from_env().expect("default config loads");
config.require_relay_membership = false;
config.redis_url = "redis://127.0.0.1:1".to_string();
configure(&mut config);
let auxiliary_pg_pool = sqlx::PgPool::connect_lazy(&config.database_url).expect("lazy pg pool");
let db = match TestBackend::from_env() {
TestBackend::Postgres => buzz_db::Db::from_pool(auxiliary_pg_pool.clone()),
TestBackend::Sqlite => {
let db = buzz_db::Db::new_sqlite(SQLITE_TEST_URL)
.await
.expect("in-memory sqlite database");
db.migrate().await.expect("sqlite migrations");
db.ensure_configured_community(TEST_COMMUNITY_HOST)
.await
.expect("configured sqlite test community");
db
}
};
let redis_pool = deadpool_redis::Config::from_url(&config.redis_url)
.create_pool(Some(deadpool_redis::Runtime::Tokio1))
.expect("redis pool");
let pubsub = Arc::new(
buzz_pubsub::PubSubManager::new(&config.redis_url, redis_pool.clone())
.await
.expect("pubsub manager"),
);
let audit = buzz_audit::AuditService::new(auxiliary_pg_pool.clone());
let auth = buzz_auth::AuthService::new(config.auth.clone());
let search = buzz_search::SearchService::new(auxiliary_pg_pool);
let workflow_engine = Arc::new(buzz_workflow::WorkflowEngine::new(
db.clone(),
buzz_workflow::WorkflowConfig::default(),
));
let media_storage = buzz_media::MediaStorage::new(&config.media).expect("media storage");
let (state, _audit_shutdown) = AppState::new(
config,
db,
redis_pool,
audit,
pubsub,
auth,
search,
workflow_engine,
nostr::Keys::generate(),
media_storage,
);
Arc::new(state)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn backend_names_are_explicit() {
assert_eq!(TestBackend::Postgres, TestBackend::Postgres);
assert_ne!(TestBackend::Postgres, TestBackend::Sqlite);
}
}

View File

@@ -571,42 +571,8 @@ mod integration_tests {
use buzz_db::CreateCommunityWithOwnerResult;
use std::sync::Arc;
/// Real-PG state mirroring `handlers::event::tests::test_state_with_redis_url`.
async fn test_state() -> Arc<AppState> {
let mut config = crate::config::Config::from_env().expect("default config loads");
config.require_relay_membership = false;
config.redis_url = "redis://127.0.0.1:1".to_string();
let pool = sqlx::PgPool::connect_lazy(&config.database_url).expect("lazy pg pool");
let db = buzz_db::Db::from_pool(pool.clone());
let redis_pool = deadpool_redis::Config::from_url(&config.redis_url)
.create_pool(Some(deadpool_redis::Runtime::Tokio1))
.expect("redis pool");
let pubsub = Arc::new(
buzz_pubsub::PubSubManager::new(&config.redis_url, redis_pool.clone())
.await
.expect("pubsub manager"),
);
let audit = buzz_audit::AuditService::new(pool.clone());
let auth = buzz_auth::AuthService::new(config.auth.clone());
let search = buzz_search::SearchService::new(pool.clone());
let workflow_engine = Arc::new(buzz_workflow::WorkflowEngine::new(
db.clone(),
buzz_workflow::WorkflowConfig::default(),
));
let media_storage = buzz_media::MediaStorage::new(&config.media).expect("media storage");
let (state, _audit_shutdown) = AppState::new(
config,
db,
redis_pool,
audit,
pubsub,
auth,
search,
workflow_engine,
nostr::Keys::generate(),
media_storage,
);
Arc::new(state)
crate::test_support::test_state().await
}
#[tokio::test]