use hydracache::{
anti_entropy_repair, select_backup_promotion, AdaptiveWindow, ClusterEpoch,
InMemoryReplicatedValueStore, LiveReplicationPeer, PartitionId, PromotionFreezeWindow,
PromotionPhase, Replicas, ReplicatedValueRecord, ReplicatedValueStore,
};
#[test]
fn replication_under_load_live_slow_backup_does_not_stall_primary() {
let mut slow = LiveReplicationPeer::new("member-b", AdaptiveWindow::new(1, 1, 4));
let mut healthy = LiveReplicationPeer::new("member-c", AdaptiveWindow::new(1, 4, 8));
let mut slow_store = InMemoryReplicatedValueStore::default();
let mut healthy_store = InMemoryReplicatedValueStore::default();
let record =
ReplicatedValueRecord::value(PartitionId::new(1), 1, ClusterEpoch::new(1), b"value");
let slow_send = slow
.send_record(&mut slow_store, "user:1", record.clone(), false)
.unwrap();
let healthy_send = healthy
.send_record(&mut healthy_store, "user:1", record, true)
.unwrap();
assert!(slow_send.admitted);
assert!(healthy_send.admitted);
assert!(healthy_send.max_in_flight > slow_send.max_in_flight);
assert!(healthy_store.get("user:1").unwrap().is_some());
}
#[test]
fn replication_under_load_live_promotion_freeze_window_bounded_under_load() {
let partition = PartitionId::new(9);
let replicas = Replicas::new("member-a", vec!["member-b".into(), "member-c".into()]);
let promotion = select_backup_promotion(partition, &replicas).expect("backup promotion");
let freeze = PromotionFreezeWindow {
observed_ms: 42,
bound_ms: 100,
};
assert_eq!(promotion.phase, PromotionPhase::Before);
assert_eq!(promotion.new_primary.as_str(), "member-b");
assert!(freeze.is_bounded());
}
#[test]
fn replication_under_load_live_anti_entropy_converges_after_partition_heal() {
let mut backup = InMemoryReplicatedValueStore::default();
let records = vec![(
"user:1".to_owned(),
ReplicatedValueRecord::value(PartitionId::new(1), 9, ClusterEpoch::new(2), b"fresh"),
)];
let repaired = anti_entropy_repair(&mut backup, records).unwrap();
assert_eq!(repaired, 1);
assert_eq!(backup.get("user:1").unwrap().unwrap().version, 9);
}
#[test]
#[ignore = "chaos gate: run with -- --ignored when exercising slow backup partitions"]
fn replication_under_load_live_anti_entropy_converges_after_partition_heal_chaos() {
let mut backup = InMemoryReplicatedValueStore::default();
assert_eq!(anti_entropy_repair(&mut backup, Vec::new()).unwrap(), 0);
}