fix(session): add test-only constructor so tests do not read real sessions

SessionStore::new() reads /var/lib/archipelago/sessions.json, which on
any node with an active dashboard contains live sessions that pollute
test state and cause intermittent failures. Introduce a cfg(test) only
new_for_tests(PathBuf) constructor and switch the test suite to it so
tests always start from a clean tempdir.
This commit is contained in:
archipelago 2026-04-23 13:02:22 -04:00
parent 2843cc1e84
commit 7af048cc1a

View File

@ -70,6 +70,17 @@ impl SessionStore {
}
}
/// Construct an empty SessionStore that persists to a caller-supplied
/// path. Used by tests so they don't pick up sessions from the dev
/// machine's real /var/lib/archipelago/sessions.json.
#[cfg(test)]
pub fn new_for_tests(persist_path: PathBuf) -> Self {
Self {
sessions: Arc::new(RwLock::new(HashMap::new())),
persist_path,
}
}
/// Load persisted sessions from disk (only Full sessions).
async fn load_from_disk(path: &Path) -> HashMap<[u8; 32], Session> {
let mut map = HashMap::new();
@ -462,7 +473,7 @@ mod tests {
#[tokio::test]
async fn test_session_create_and_validate() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let token = store.create().await;
assert!(store.validate(&token).await);
@ -470,13 +481,13 @@ mod tests {
#[tokio::test]
async fn test_session_invalid_token() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
assert!(!store.validate("nonexistent_token").await);
}
#[tokio::test]
async fn test_session_remove() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let token = store.create().await;
assert!(store.validate(&token).await);
@ -486,7 +497,7 @@ mod tests {
#[tokio::test]
async fn test_pending_session_upgrade() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let secret = vec![1, 2, 3, 4];
let token = store.create_pending(secret.clone()).await;
@ -510,7 +521,7 @@ mod tests {
#[tokio::test]
async fn test_pending_session_max_attempts() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let secret = vec![1, 2, 3];
let token = store.create_pending(secret).await;
@ -538,7 +549,7 @@ mod tests {
#[tokio::test]
async fn test_session_activity_updates_on_validate() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let token = store.create().await;
// First validation should succeed and touch last_activity
@ -550,7 +561,7 @@ mod tests {
#[tokio::test]
async fn test_invalidate_all_except() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let token1 = store.create().await;
let token2 = store.create().await;
let token3 = store.create().await;
@ -565,7 +576,7 @@ mod tests {
#[tokio::test]
async fn test_session_rotate() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let old_token = store.create().await;
assert!(store.validate(&old_token).await);
@ -580,7 +591,7 @@ mod tests {
#[tokio::test]
async fn test_max_concurrent_sessions() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let mut tokens = Vec::new();
// Create MAX_CONCURRENT_SESSIONS sessions
@ -608,7 +619,7 @@ mod tests {
#[tokio::test]
async fn test_active_session_count() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
assert_eq!(store.active_session_count().await, 0);
let token1 = store.create().await;
@ -623,7 +634,7 @@ mod tests {
#[tokio::test]
async fn test_cleanup_expired_removes_stale() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let token = store.create().await;
assert!(store.validate(&token).await);
@ -636,7 +647,7 @@ mod tests {
#[tokio::test]
async fn test_rotate_preserves_session_count() {
let store = SessionStore::new().await;
let store = SessionStore::new_for_tests(std::env::temp_dir().join(format!("archipelago-sessions-test-{}.json", rand::random::<u64>())));
let token = store.create().await;
assert_eq!(store.active_session_count().await, 1);