1
use super::*;
2

            
3
2
fn report_with(migrated: usize, quarantined: Vec<(Uuid, String)>) -> FleetReport {
4
2
    FleetReport {
5
2
        migrated,
6
2
        quarantined,
7
2
        ..FleetReport::default()
8
2
    }
9
2
}
10

            
11
#[test]
12
1
fn a_run_that_verified_everything_is_healthy() {
13
1
    assert!(report_with(3, Vec::new()).is_healthy());
14
1
    assert!(FleetReport::default().is_healthy());
15
1
}
16

            
17
#[test]
18
1
fn a_single_quarantine_makes_the_run_degraded() {
19
1
    let report = report_with(9, vec![(Uuid::nil(), "unreachable".to_owned())]);
20

            
21
1
    assert!(
22
1
        !report.is_healthy(),
23
        "one tenant left behind must be visible in the exit code, not averaged away"
24
    );
25
1
}
26

            
27
#[test]
28
1
fn the_summary_reports_every_category() {
29
1
    let report = FleetReport {
30
1
        migrated: 2,
31
1
        quarantined: vec![(Uuid::nil(), "boom".to_owned())],
32
1
        unresolved: vec![Uuid::nil()],
33
1
        unpublished: vec![(Uuid::nil(), "write failed".to_owned())],
34
1
    };
35

            
36
1
    assert_eq!(
37
1
        report.summary(),
38
        "migrated 2, quarantined 1, unresolved 1, unpublished 1"
39
    );
40
1
}
41

            
42
#[test]
43
1
fn a_tenant_this_run_never_verified_is_not_a_success() {
44
    // Another worker held the claim to the end. It may since have died, and
45
    // nothing would say so — exiting 0 here would gate a rollout on a database
46
    // no one has looked at.
47
1
    let report = FleetReport {
48
1
        unresolved: vec![Uuid::nil()],
49
1
        ..FleetReport::default()
50
1
    };
51

            
52
1
    assert!(!report.is_healthy());
53
1
}
54

            
55
#[test]
56
1
fn a_verdict_that_could_not_be_written_fails_the_run() {
57
    // The dangerous case: the tenant failed, but its quarantine did not stick,
58
    // so it is still being served on the wrong schema.
59
1
    let report = FleetReport {
60
1
        migrated: 5,
61
1
        unpublished: vec![(Uuid::nil(), "directory unreachable".to_owned())],
62
1
        ..FleetReport::default()
63
1
    };
64

            
65
1
    assert!(!report.is_healthy());
66
1
}
67

            
68
#[test]
69
1
fn outcomes_carry_their_reason() {
70
1
    assert_eq!(Outcome::Migrated, Outcome::Migrated);
71
1
    assert_ne!(Outcome::Migrated, Outcome::Unresolved);
72
1
    assert_eq!(
73
1
        Outcome::Quarantined("no such database".to_owned()),
74
1
        Outcome::Quarantined("no such database".to_owned())
75
    );
76
1
}
77

            
78
#[test]
79
1
fn a_directory_at_the_current_schema_is_aligned() {
80
1
    let drift = schema_drift(&[1, 2, 3, 5, 6], &[1, 2, 3, 5, 6]);
81

            
82
1
    assert!(drift.is_aligned());
83
1
}
84

            
85
#[test]
86
1
fn a_directory_behind_this_binary_is_reported_as_missing() {
87
    // The Job reconciled before its own release migrated the global database.
88
1
    let drift = schema_drift(&[1, 2, 3, 5, 6], &[1, 2, 3]);
89

            
90
1
    assert_eq!(drift.missing, vec![5, 6]);
91
1
    assert!(drift.unknown.is_empty());
92
1
    assert!(!drift.is_aligned());
93
1
}
94

            
95
#[test]
96
1
fn a_directory_ahead_of_this_binary_is_reported_as_unknown() {
97
    // A rolled-back image, or one whose migration files were edited in place
98
    // after being applied. Passing this would fail EVERY tenant on a
99
    // disagreement that is not the tenant's, and those quarantines would outrank
100
    // the correct run's because they are written later.
101
1
    let drift = schema_drift(&[1, 2, 3], &[1, 2, 3, 5, 6]);
102

            
103
1
    assert_eq!(drift.unknown, vec![5, 6]);
104
1
    assert!(drift.missing.is_empty());
105
1
    assert!(!drift.is_aligned());
106
1
}
107

            
108
#[test]
109
1
fn drift_is_judged_by_version_not_by_count() {
110
    // Five applied, but the wrong five. Counting would call this aligned.
111
1
    let drift = schema_drift(&[1, 2, 3, 5, 6], &[1, 2, 3, 4, 7]);
112

            
113
1
    assert_eq!(drift.missing, vec![5, 6]);
114
1
    assert_eq!(drift.unknown, vec![4, 7]);
115
1
}