sync from monorepo @ 2452e92e
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
#![cfg(feature = "test-utils")]
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use dirigent_archivist::backend::mock::MockBackend;
|
||||
use dirigent_archivist::backend::{ArchiveBackend, HealthStatus};
|
||||
use dirigent_archivist::coordinator::Archivist;
|
||||
use dirigent_archivist::registry::{ArchiveRegistration, FailureMode, WritePolicy};
|
||||
use uuid::Uuid;
|
||||
|
||||
fn reg(
|
||||
name: &str,
|
||||
backend: Arc<MockBackend>,
|
||||
priority: u32,
|
||||
failure: FailureMode,
|
||||
) -> Arc<ArchiveRegistration> {
|
||||
Arc::new(ArchiveRegistration::new(
|
||||
name.into(),
|
||||
"mock",
|
||||
backend as Arc<dyn ArchiveBackend>,
|
||||
true,
|
||||
failure,
|
||||
priority,
|
||||
true,
|
||||
WritePolicy::Inline,
|
||||
None,
|
||||
HealthStatus::Healthy,
|
||||
))
|
||||
}
|
||||
|
||||
fn sample_message(session: Uuid) -> dirigent_archivist::types::MessageRecord {
|
||||
dirigent_archivist::types::MessageRecord {
|
||||
version: 1,
|
||||
message_id: Uuid::now_v7(),
|
||||
session,
|
||||
parent_id: None,
|
||||
ts: chrono::Utc::now(),
|
||||
role: "user".into(),
|
||||
author: None,
|
||||
content_md: "hi".into(),
|
||||
content_parts: None,
|
||||
attachments: vec![],
|
||||
metadata: serde_json::Value::Null,
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_fans_out_to_both_backends() {
|
||||
let a = Arc::new(MockBackend::new());
|
||||
let b = Arc::new(MockBackend::new());
|
||||
let archivist = Archivist::from_registrations(vec![
|
||||
reg("a", a.clone(), 0, FailureMode::Required),
|
||||
reg("b", b.clone(), 10, FailureMode::BestEffort),
|
||||
]);
|
||||
|
||||
// Using a non-empty message vec for a robust positive-count check:
|
||||
let scroll = Uuid::new_v4();
|
||||
let m = sample_message(scroll);
|
||||
archivist
|
||||
.append_messages(scroll, vec![m], None)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(a.appended_count(scroll), 1);
|
||||
assert_eq!(b.appended_count(scroll), 1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn best_effort_failure_does_not_propagate() {
|
||||
let a = Arc::new(MockBackend::new());
|
||||
let b = Arc::new(MockBackend::new());
|
||||
b.inject_write_failures(1);
|
||||
|
||||
let archivist = Archivist::from_registrations(vec![
|
||||
reg("a", a.clone(), 0, FailureMode::Required),
|
||||
reg("b", b.clone(), 10, FailureMode::BestEffort),
|
||||
]);
|
||||
|
||||
archivist
|
||||
.append_messages(Uuid::new_v4(), vec![], None)
|
||||
.await
|
||||
.unwrap(); // Ok despite secondary failure
|
||||
|
||||
let snapshot = archivist.list_archives_with_health().await;
|
||||
let b_status = snapshot.iter().find(|s| s.name == "b").unwrap();
|
||||
assert!(matches!(b_status.health, HealthStatus::Degraded { .. }));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn required_secondary_failure_propagates() {
|
||||
let a = Arc::new(MockBackend::new());
|
||||
let b = Arc::new(MockBackend::new());
|
||||
b.inject_write_failures(1);
|
||||
|
||||
let archivist = Archivist::from_registrations(vec![
|
||||
reg("a", a.clone(), 0, FailureMode::Required),
|
||||
reg("b", b.clone(), 10, FailureMode::Required),
|
||||
]);
|
||||
|
||||
let err = archivist
|
||||
.append_messages(Uuid::new_v4(), vec![], None)
|
||||
.await;
|
||||
assert!(err.is_err(), "expected error when required secondary fails");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn explicit_archive_overrides_default_primary() {
|
||||
let a = Arc::new(MockBackend::new());
|
||||
let b = Arc::new(MockBackend::new());
|
||||
let archivist = Archivist::from_registrations(vec![
|
||||
reg("a", a.clone(), 0, FailureMode::Required),
|
||||
reg("b", b.clone(), 10, FailureMode::Required),
|
||||
]);
|
||||
|
||||
let scroll = Uuid::new_v4();
|
||||
let m = sample_message(scroll);
|
||||
archivist
|
||||
.append_messages(scroll, vec![m], Some("b".into()))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Both receive the write: b is explicit primary, a is secondary via fanout.
|
||||
assert_eq!(a.appended_count(scroll), 1);
|
||||
assert_eq!(b.appended_count(scroll), 1);
|
||||
}
|
||||
Reference in New Issue
Block a user