wsb-daemon 0.248.6265

wsb's daemon: the workbench, the GitHub mirror's schedule and peer continuity, for every workspace on the machine
//! What two machines agree they both have — and what they must not assume.

use super::*;

fn summary(id: &str, name: &str, root_commit: &str) -> WorkspaceSummary {
    WorkspaceSummary {
        workspace: WorkspaceId::parse(id).expect("a workspace id"),
        display_name: name.to_string(),
        root_commit: root_commit.to_string(),
    }
}

fn find<'a>(shared: &'a [SharedWorkspace], id: &str) -> &'a SharedWorkspace {
    shared
        .iter()
        .find(|entry| entry.id.to_string() == id)
        .unwrap_or_else(|| panic!("{id} is missing from {shared:?}"))
}

/// TEST9991: a workspace both machines have is shared; one machine's is not.
///
/// The whole comparison in one case, and the reason it is by identity: the
/// two machines keep these in different directories under different names,
/// and nothing here compares either.
#[test]
fn test9991_presence_is_decided_by_identity() {
    let mine = vec![
        summary("aaaaaaaaaaaaaaaa@main", "machinefabric", "c0ffee"),
        summary("bbbbbbbbbbbbbbbb@main", "only-here", "beef"),
    ];
    let theirs = vec![
        // The peer calls it something else and keeps it somewhere else. Same
        // workspace: same root commit, same derived id.
        summary("aaaaaaaaaaaaaaaa@main", "mf", "c0ffee"),
        summary("cccccccccccccccc@main", "only-there", "cafe"),
    ];

    let shared = compare(&mine, &theirs);
    assert_eq!(shared.len(), 3, "every workspace of both machines appears: {shared:?}");
    assert_eq!(find(&shared, "aaaaaaaaaaaaaaaa@main").presence, WorkspacePresence::Shared);
    assert_eq!(find(&shared, "bbbbbbbbbbbbbbbb@main").presence, WorkspacePresence::LocalOnly);
    assert_eq!(find(&shared, "cccccccccccccccc@main").presence, WorkspacePresence::PeerOnly);

    // A shared workspace is named as THIS machine names it: the person reading
    // is here, and the peer's name for it is the peer's business.
    assert_eq!(find(&shared, "aaaaaaaaaaaaaaaa@main").display_name, "machinefabric");
}

/// TEST9992: the same id over a different history is reported incompatible.
///
/// The id derives from the root commit, so this cannot happen by accident —
/// it takes a restored backup or an edited database. It is checked anyway,
/// because the failure it prevents is two unrelated trees converging onto each
/// other, and that destroys work rather than reporting a state.
#[test]
fn test9992_the_same_id_over_a_different_history_is_incompatible() {
    let mine = vec![summary("aaaaaaaaaaaaaaaa@main", "mine", "c0ffee")];
    let theirs = vec![summary("aaaaaaaaaaaaaaaa@main", "theirs", "deadbeef")];

    let shared = compare(&mine, &theirs);
    let entry = find(&shared, "aaaaaaaaaaaaaaaa@main");
    assert_eq!(entry.presence, WorkspacePresence::Shared);
    assert!(
        !entry.compatible,
        "two different histories under one id must not read as the same workspace"
    );
}

/// TEST9993: nothing in common is a state, not a failure.
#[test]
fn test9993_two_machines_with_nothing_in_common() {
    let mine = vec![summary("aaaaaaaaaaaaaaaa@main", "mine", "c0ffee")];
    let theirs = vec![summary("bbbbbbbbbbbbbbbb@main", "theirs", "beef")];

    let shared = compare(&mine, &theirs);
    assert_eq!(shared.len(), 2);
    assert!(shared.iter().all(|entry| entry.presence != WorkspacePresence::Shared));
    assert!(
        shared.iter().all(|entry| entry.compatible),
        "a workspace only one machine has has nothing to be incompatible with"
    );

    // And a machine that has none at all still answers.
    assert_eq!(compare(&[], &[]), Vec::new());
}

/// TEST9994: the list is ordered, so two reads of the same pair agree.
///
/// A page that re-renders a differently-ordered list on every poll makes
/// clicking the right row a matter of timing.
#[test]
fn test9994_the_comparison_is_ordered() {
    let mine = vec![
        summary("cccccccccccccccc@main", "zeta", "1"),
        summary("aaaaaaaaaaaaaaaa@main", "alpha", "2"),
    ];
    let theirs = vec![summary("bbbbbbbbbbbbbbbb@main", "middle", "3")];

    let names: Vec<String> = compare(&mine, &theirs)
        .into_iter()
        .map(|entry| entry.display_name)
        .collect();
    assert_eq!(names, vec!["alpha", "middle", "zeta"]);
    assert_eq!(
        compare(&mine, &theirs),
        compare(&mine, &theirs),
        "the same inventories must compare the same way twice"
    );
}