Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/monetize

crates/monetize-server/src/estate_order/tests/paired_terminate.rs

//! **F10 (2026-10-21): a paired estate that never reached delivered can be terminated.**
//! test3-holger-rs was adopted by F5's re-check into `paired` and never reached delivered; its
//! terminate was refused "still being set up; it can be terminated once it runs".
//!
//! * **Paired is terminable** (adopted on a re-check or paired by its installer's PASS): every
//!   box is PAIRED and its install no longer runs, so its boxes are safe to give back, the way
//!   a FAILED setup's are. The Sites listing's `terminable` says the same.
//! * **An installing estate is still refused**, and nothing of it is touched.
//! * **The money follows the existing rules**: a terminate captures nothing, refunds nothing
//!   and releases no money already taken (as for FAILED and owed).

use super::recheck::{answers, install_failed_on, site_of};
use super::*;

/// The site's cloud name.
const SITE: &str = "gunnarrs";

/// ★ **A paired, adopted estate is terminated, and its machines are given back** in the mock
/// cloud; the Sites listing offered it.
#[test]
fn a_paired_adopted_estate_is_terminated_and_its_machines_given_back() {
    let (state, cloud, kit, _mails, _clock) = install_failed_on("f10-adopted", true, cfg());
    answers(&kit, true);
    assert_eq!(
        settle(&state, "gunnar-rs", RECHECK).expect("adopted").phase,
        phase::PAIRED
    );
    let run = state.estates.get(SITE).unwrap();
    assert_eq!(
        run.phase,
        phase::PAIRED,
        "adopted, never delivered: {:#?}",
        run.history
    );
    assert!(run
        .history
        .iter()
        .any(|t| t.note.starts_with(ADOPTED_ON_RECHECK)));
    assert!(cloud.live_under("estate/gunnarrs") > 0, "its boxes stand");
    let s = site_of(&state);
    assert!(
        s.terminable,
        "the Sites listing offers Terminate on a paired site: {s:?}"
    );
    let t = terminate::terminate(&state, None, "gunnar-rs", "gunnar-rs")
        .expect("a paired estate is terminated");
    assert!(!t.done && t.words.contains("being ended now"), "{t:?}");
    crate::estate_order::drive(&state, SITE);
    assert_eq!(
        cloud.live_under("estate/gunnarrs"),
        0,
        "every machine and disk is given back"
    );
    assert_eq!(state.estates.get(SITE).unwrap().phase, phase::TERMINATED);
}

/// ★ **A paired estate its installer passed (not adopted) is terminated too**, and the money
/// follows the existing rules: the payment taken at the order is neither refunded nor taken
/// again, and nothing is captured by the terminate.
#[test]
fn a_paired_estate_its_installer_passed_is_terminated_and_no_money_moves() {
    let r = rig_with("f10-paired", cfg(), "PASS");
    r.kit.silent.store(true, Ordering::SeqCst);
    start_for(
        &r.state,
        "acme",
        "buyer@example.org",
        "",
        "alice",
        &EstateSizes::default(),
    )
    .unwrap();
    r.pay.authorize(&handle_of(&r, "acme"));
    crate::estate_order::drive(&r.state, "acme");
    assert_eq!(
        r.state.estates.get("acme").unwrap().phase,
        phase::PAIRED,
        "no box reported yet"
    );
    assert!(r.cloud.live_under("estate/acme") > 0, "its boxes stand");
    let (captures, refunds) = (r.pay.captures(), r.pay.refunds());
    let t = terminate::terminate(&r.state, None, "acme", "acme")
        .expect("a paired estate is terminated");
    assert!(!t.done && t.words.contains("being ended now"), "{t:?}");
    crate::estate_order::drive(&r.state, "acme");
    assert_eq!(
        r.cloud.live_under("estate/acme"),
        0,
        "every machine and disk is given back"
    );
    assert_eq!(
        r.state.estates.get("acme").unwrap().phase,
        phase::TERMINATED
    );
    assert_eq!(
        (r.pay.captures(), r.pay.refunds()),
        (captures, refunds),
        "no money moved"
    );
}

/// ★ **An installing estate is still refused** a terminate, nothing of it is touched, the Sites
/// listing does not offer it, and its install goes on.
#[test]
fn an_installing_estate_is_still_refused_a_terminate() {
    let (state, pay, cloud, kit, _dir, _clock, _mails) = site_rig_with("f10-installing", true);
    let run = site::start_site(
        &state,
        "gunnar-rs",
        "ops@example.org",
        &EstateSizes::default(),
    )
    .unwrap();
    pay.authorize(&run.handle.clone().unwrap().id);
    kit.install_gate.arm();
    let s = state.clone();
    let driver = std::thread::spawn(move || super::drive(&s, SITE));
    kit.install_gate.reached();
    assert_eq!(state.estates.get(SITE).unwrap().phase, phase::INSTALLING);
    assert!(
        !site_of(&state).terminable,
        "an installing site is not offered Terminate"
    );
    let destroys = cloud.destroys().len();
    match terminate::terminate(&state, None, "gunnar-rs", "gunnar-rs") {
        Err(StartRefusal::NotNow(w)) => assert!(w.contains("still being set up"), "{w}"),
        other => panic!("{other:?}"),
    }
    assert_eq!(cloud.destroys().len(), destroys, "nothing was given back");
    kit.install_gate.open();
    driver.join().unwrap();
    assert_eq!(
        state.estates.get(SITE).unwrap().phase,
        phase::CAPTURED,
        "its install went on"
    );
}

/// ★ **Protected from terminate stays a guard** for a paired site.
#[test]
fn a_protected_paired_site_is_refused_a_terminate() {
    let (state, pay, cloud, kit, _dir, _clock, _mails) = site_rig_with("f10-protected", false);
    kit.silent.store(true, Ordering::SeqCst);
    let run = site::start_site(
        &state,
        "gunnar-rs",
        "ops@example.org",
        &EstateSizes::default(),
    )
    .unwrap();
    pay.authorize(&run.handle.clone().unwrap().id);
    super::drive(&state, SITE);
    assert_eq!(state.estates.get(SITE).unwrap().phase, phase::PAIRED);
    assert!(!site_of(&state).terminable);
    assert!(
        matches!(terminate::terminate(&state, None, "gunnar-rs", "gunnar-rs"), Err(StartRefusal::NotNow(w)) if w.contains("protected"))
    );
    assert!(cloud.live_under("estate/gunnarrs") > 0, "nothing was ended");
}