sync from monorepo @ 2452e92e

This commit is contained in:
2026-05-08 01:59:04 +02:00
commit b03dc15371
459 changed files with 129586 additions and 0 deletions
@@ -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);
}