tests: pin the survivors that mattered (score arithmetic, pulse bounds, foreign pulse, heartbeat.cc store and its fail-closed refusal)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
16f54117ab
commit
686f6d4888
4 changed files with 93 additions and 0 deletions
|
|
@ -1699,6 +1699,25 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// A pulse votes a tempo in bounds, declares an urgency in bounds, or does both; a pulse that does neither is refused.
|
||||
#[test]
|
||||
fn a_pulse_is_in_bounds_and_says_something() {
|
||||
let validated = |beat: Option<u32>, urgency: Option<u16>| {
|
||||
PipelineDocument::Pulse(PipelinePulse { instance: slug(INSTANCE), label: l("2026-10-31t041200-t0"), tempo_vote_beat_s: beat, urgency_permille: urgency, note: "".into() }).validate()
|
||||
};
|
||||
for (beat, urgency) in [(Some(60), None), (Some(86_400), None), (None, Some(0)), (None, Some(1000)), (Some(600), Some(250))] {
|
||||
assert_eq!(validated(beat, urgency), Ok(()), "{beat:?} {urgency:?}");
|
||||
}
|
||||
for (beat, urgency, field) in [
|
||||
(Some(59), None, "pulse.tempo_vote_beat_s"),
|
||||
(Some(86_401), None, "pulse.tempo_vote_beat_s"),
|
||||
(None, Some(1001), "pulse.urgency_permille"),
|
||||
(None, None, "pulse.tempo_vote_beat_s"),
|
||||
] {
|
||||
assert!(matches!(validated(beat, urgency), Err(PipelineRefusal::InvalidFormat { field: f, .. }) if f == field), "{beat:?} {urgency:?}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Bounds: a run's campaigns and claims stop at their maximums.
|
||||
#[test]
|
||||
fn a_runs_lists_are_bounded() {
|
||||
|
|
|
|||
|
|
@ -2448,6 +2448,20 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
/// A pulse is her own: one of another mind is a ForeignInstance, her own is admitted.
|
||||
#[test]
|
||||
fn a_pulse_of_another_mind_is_a_foreign_instance_and_her_own_is_admitted() {
|
||||
let mut mind = with_specs();
|
||||
let pulse = |instance: &str| {
|
||||
D::Pulse(eureka_pipeline::PipelinePulse { instance: slug(instance), label: l("p1"), tempo_vote_beat_s: Some(600), urgency_permille: None, note: "".into() })
|
||||
};
|
||||
assert_eq!(
|
||||
refusal(admit(&mut mind, vec![pulse(OTHER_INSTANCE)])),
|
||||
MindRefusal::ForeignInstance { declared: OTHER_INSTANCE.into(), mind: INSTANCE.into() }
|
||||
);
|
||||
committed(admit(&mut mind, vec![pulse(INSTANCE)]));
|
||||
}
|
||||
|
||||
/// A run ends: Recorded or Withdrawn, and no other outcome.
|
||||
#[test]
|
||||
fn a_run_resolves_recorded_or_withdrawn_and_nothing_else() {
|
||||
|
|
|
|||
|
|
@ -457,3 +457,51 @@ fn the_heartbeat_holds_no_usage_port_so_usage_cannot_change_a_launch() {
|
|||
again.turn(BOB, 1000);
|
||||
assert_eq!(first, again.poll());
|
||||
}
|
||||
|
||||
/// A document of the dollar-initiative days, standing in for what an old `heartbeat.cc` holds.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DatabaseEntry)]
|
||||
#[cultcache(type = "eureka.heartbeat.initiative.v1", schema = "OldInitiative")]
|
||||
struct OldInitiative {
|
||||
#[cultcache(key = 0)]
|
||||
initiative: String,
|
||||
}
|
||||
|
||||
fn trace_at(seconds: i64, tempo_s: u32) -> PollTrace {
|
||||
PollTrace { at: crate::testkit::at(seconds), tempo_s, instances: vec![], launches: vec!["ann".into()] }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_file_store_keeps_the_state_and_the_traces_and_the_tempo_view_reads_the_newest_trace() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
let path = dir.path().join("heartbeat.cc");
|
||||
let store = FileStore::new(&path);
|
||||
store.check().unwrap();
|
||||
assert_eq!((store.load().unwrap(), store.latest().unwrap()), (None, None), "no file is no state");
|
||||
let state = HeartbeatState { last_beat_at: crate::testkit::at(5), handled_mentions: vec!["ann:e1".into()] };
|
||||
store.save(&state).unwrap();
|
||||
assert_eq!(store.load().unwrap(), Some(state));
|
||||
store.record(&trace_at(20, 600)).unwrap();
|
||||
store.record(&trace_at(10, 900)).unwrap();
|
||||
assert_eq!(store.latest().unwrap().map(|trace| trace.tempo_s), Some(600), "the newest by time, not by write order");
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
assert_eq!(std::fs::metadata(&path).unwrap().permissions().mode() & 0o777, 0o644, "Persona units read it");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_old_heartbeat_store_fails_closed_naming_the_file_and_is_never_migrated() {
|
||||
let dir = TempDir::new().unwrap();
|
||||
let path = dir.path().join("heartbeat.cc");
|
||||
let mut cache = CultCache::new();
|
||||
cache.register_entry_type::<OldInitiative>().unwrap();
|
||||
cache.add_generic_backing_store(SingleFileMessagePackBackingStore::new(&path)).unwrap();
|
||||
cache.pull_all_backing_stores().unwrap();
|
||||
cache.put("eureka", &OldInitiative { initiative: "3.5".into() }).unwrap();
|
||||
let store = FileStore::new(&path);
|
||||
for result in [store.check().map(|()| ()), store.load().map(|_| ()), store.latest().map(|_| ()), store.save(&HeartbeatState { last_beat_at: crate::testkit::at(1), handled_mentions: vec![] }), store.record(&trace_at(1, 900))] {
|
||||
let error = format!("{:#}", result.unwrap_err());
|
||||
assert!(error.contains(&path.display().to_string()) && error.contains("archive it, nothing migrates it"), "{error}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,18 @@ fn mind(slug: &str, waited_s: Option<u64>) -> Standing {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_score_is_the_wait_in_beats_times_ten_to_the_urgency_in_orders() {
|
||||
let mut standing = mind("a", Some(1800));
|
||||
assert_eq!(score(&standing, 900), 2.0, "two beats waited, no urgency");
|
||||
assert_eq!(score(&standing, 600), 3.0);
|
||||
standing.self_permille = 1000;
|
||||
assert_eq!(score(&standing, 900), 20.0, "full urgency is worth one order of magnitude");
|
||||
standing.self_permille = 500;
|
||||
assert!((score(&standing, 900) - 2.0 * 10f64.sqrt()).abs() < 1e-9);
|
||||
assert_eq!(score(&mind("never", None), 900), f64::INFINITY);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_votes_is_the_default_beat() {
|
||||
assert_eq!(tally(&[]), DEFAULT_BEAT_S);
|
||||
|
|
|
|||
Loading…
Reference in a new issue