nordisk/monetize
crates/monetize-server/src/estate_order/tests.rs
//! The lay-estate job, driven against doubles: a vendor that HOLDS until the
//! buyer authorises ([`HoldPay`]), `MockCloud`'s lay (labelled, journaled,
//! faultable), a fake installer that writes the kit's verdict file, and the
//! recording DNS. Every test drives the job synchronously with [`drive`].
use std::collections::BTreeMap;
use std::path::PathBuf;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::{Arc, Mutex};
use monetize::testing::{LayFault, MockCloud};
use monetize_pay::{
CallbackEvent, ChargeHandle, ChargeRequest, ChargeStatus, Market, Money, PayError, RawCallback,
};
use super::*;
use crate::registry::Registry;
use crate::testing::lifecycles::GUNNAR_KEEP_MEDIUM as KEEP_MEDIUM;
// ── the doubles ─────────────────────────────────────────────────────────────
/// **A vendor that holds only once the buyer has authorised** — the shape of a
/// Stripe checkout with `capture_method=manual`: `reserve` mints a page
/// (`AwaitingCustomer`), [`HoldPay::authorize`] is the buyer at the card step
/// (`Reserved`), `capture` draws, `release` lets go.
#[derive(Clone, Default)]
struct HoldPay(Arc<HoldInner>);
#[derive(Default)]
struct HoldInner {
next: AtomicU64,
state: Mutex<BTreeMap<String, ChargeStatus>>,
captures: AtomicU64,
releases: AtomicU64,
refunds: AtomicU64,
requests: Mutex<Vec<ChargeRequest>>,
/// Armed: the next `reserve` stops here until the test opens it.
reserve_gate: Gate,
/// The double's key is a TEST key (the test button): `livemode` answers
/// `Some(false)`, and its test payer pays a hold at once.
test_key: std::sync::atomic::AtomicBool,
/// The double's key is a LIVE key (`site test-order` is refused on it): `livemode`
/// answers `Some(true)` and there is no test payer.
live_key: std::sync::atomic::AtomicBool,
/// Every `reserve_back_to`: (reference, where the payer is sent back).
back_tos: Mutex<Vec<(String, String)>>,
/// Every `reserve_returning` with a cancel page: (reference, where a payer who cancels goes).
cancels: Mutex<Vec<(String, String)>>,
/// Armed: the buyer pays the page in the second it is closed — the next `release` of an
/// unpaid page finds it authorised and is refused, as Stripe refuses to expire a completed
/// session (F-S-02).
pay_on_release: std::sync::atomic::AtomicBool,
/// Set: every `release` fails (the vendor does not answer).
release_down: std::sync::atomic::AtomicBool,
/// Armed: the next `reserve` is refused by the vendor (Stripe's 400), after it was asked.
refuse_next: std::sync::atomic::AtomicBool,
/// Set: the double keeps Stripe's key rule (24 h): a reference (the `Idempotency-Key`) keeps
/// its FIRST answer, a refusal too, and the same key with other parameters answers
/// `idempotency_error` (R34-3, rehearsal 2026-10-25).
stripe_keys: std::sync::atomic::AtomicBool,
/// Under [`HoldInner::stripe_keys`]: key → (the parameters it was first asked with, its first answer).
keyed: Mutex<BTreeMap<String, Keyed>>,
}
/// A Stripe key's first parameters and its first answer.
type Keyed = (String, Result<ChargeHandle, String>);
/// **A gate in a double** (2026-10-06): armed, the next call that reaches it
/// says so and waits there until the test opens it — a step held between its
/// read of the run and its write, for exactly as long as the test needs.
/// No sleep, no guess.
#[derive(Default)]
struct Gate {
armed: std::sync::atomic::AtomicBool,
/// (a call is at the gate, the gate is open)
at: Mutex<(bool, bool)>,
moved: std::sync::Condvar,
}
impl Gate {
fn arm(&self) {
self.armed.store(true, Ordering::SeqCst);
}
/// In the double: the one armed call stops here until [`Gate::open`].
fn pass(&self) {
if !self.armed.swap(false, Ordering::SeqCst) {
return;
}
let mut at = self.at.lock().unwrap();
at.0 = true;
self.moved.notify_all();
while !at.1 {
at = self.moved.wait(at).unwrap();
}
}
/// The test: until the armed call is at the gate.
fn reached(&self) {
let mut at = self.at.lock().unwrap();
while !at.0 {
at = self.moved.wait(at).unwrap();
}
}
fn open(&self) {
self.at.lock().unwrap().1 = true;
self.moved.notify_all();
}
}
/// **Until `now()` holds** — a condition the test names exactly, looked at
/// again with the CPU given away between looks. The deadline only turns a
/// hang into a failure; nothing waits on a guess.
fn until(what: &str, now: impl Fn() -> bool) {
let give_up = std::time::Instant::now() + std::time::Duration::from_secs(300);
while !now() {
assert!(std::time::Instant::now() < give_up, "never: {what}");
std::thread::yield_now();
}
}
impl HoldPay {
fn authorize(&self, id: &str) {
self.0
.state
.lock()
.unwrap()
.insert(id.into(), ChargeStatus::Reserved);
}
/// The vendor let the authorisation lapse (its 7 days passed, or the buyer cancelled).
fn lapse(&self, id: &str) {
self.0
.state
.lock()
.unwrap()
.insert(id.into(), ChargeStatus::Released);
}
fn state_of(&self, id: &str) -> ChargeStatus {
self.0.state.lock().unwrap().get(id).cloned().unwrap()
}
fn captures(&self) -> u64 {
self.0.captures.load(Ordering::SeqCst)
}
fn refunds(&self) -> u64 {
self.0.refunds.load(Ordering::SeqCst)
}
}
/// The double's test payment method.
const HOLD_TEST_PAYER: &str = "pm_card_visa";
impl HoldPay {
pub fn vendor(&self) -> &'static str {
"holdpay"
}
pub fn live(&self) -> Option<bool> {
if self.0.live_key.load(Ordering::SeqCst) {
return Some(true);
}
self.0.test_key.load(Ordering::SeqCst).then_some(false)
}
pub fn test_payer(&self) -> Option<String> {
(self.0.test_key.load(Ordering::SeqCst) && !self.0.live_key.load(Ordering::SeqCst))
.then(|| HOLD_TEST_PAYER.to_owned())
}
pub fn markets(&self) -> &[Market] {
&[Market::Se, Market::Fi, Market::Dk]
}
pub fn reserve(&self, req: &ChargeRequest) -> Result<ChargeHandle, PayError> {
self.0.reserve_gate.pass();
self.0.requests.lock().unwrap().push(req.clone());
if self.0.stripe_keys.load(Ordering::SeqCst) {
let params = format!(
"{} {:?} {:?} {}",
req.amount.minor,
req.payer,
req.description,
self.0.refuse_next.load(Ordering::SeqCst)
);
if let Some((first, answer)) = self.0.keyed.lock().unwrap().get(&req.reference).cloned()
{
if first != params {
return Err(PayError::Declined("holdpay: create intent -> 400: idempotency_error: Keys for idempotent requests can only be used with the same parameters they were first used with".into()));
}
return answer.map_err(PayError::Declined);
}
self.0.stripe_keys.store(false, Ordering::SeqCst);
let answer = self.reserve(req).map_err(|e| e.to_string());
self.0.requests.lock().unwrap().pop();
self.0.stripe_keys.store(true, Ordering::SeqCst);
self.0
.keyed
.lock()
.unwrap()
.insert(req.reference.clone(), (params, answer.clone()));
return answer.map_err(PayError::Declined);
}
if self.0.refuse_next.swap(false, Ordering::SeqCst) {
return Err(PayError::Declined(
"holdpay: create intent -> 400: you must provide a return_url".into(),
));
}
let id = format!("cs_test_{}", self.0.next.fetch_add(1, Ordering::SeqCst));
// The test payer pays the hold at once, with nobody at a page — on a test key only.
let paid =
req.payer.as_deref() == Some(HOLD_TEST_PAYER) && self.0.test_key.load(Ordering::SeqCst);
self.0.state.lock().unwrap().insert(
id.clone(),
if paid {
ChargeStatus::Reserved
} else {
ChargeStatus::AwaitingCustomer
},
);
Ok(ChargeHandle {
vendor: "holdpay".into(),
id,
})
}
pub fn reserve_back_to(
&self,
req: &ChargeRequest,
back_to: &str,
) -> Result<ChargeHandle, PayError> {
self.0
.back_tos
.lock()
.unwrap()
.push((req.reference.clone(), back_to.to_owned()));
self.reserve(req)
}
pub fn reserve_returning(
&self,
req: &ChargeRequest,
back_to: &str,
cancel_to: &str,
) -> Result<ChargeHandle, PayError> {
if !cancel_to.trim().is_empty() {
self.0
.cancels
.lock()
.unwrap()
.push((req.reference.clone(), cancel_to.to_owned()));
}
if back_to.trim().is_empty() {
self.reserve(req)
} else {
self.reserve_back_to(req, back_to)
}
}
pub fn draw(&self, h: &ChargeHandle) -> Result<ChargeStatus, PayError> {
let mut st = self.0.state.lock().unwrap();
let now = st
.get(&h.id)
.cloned()
.ok_or_else(|| PayError::UnknownHandle(h.clone()))?;
let next = match now {
ChargeStatus::Reserved => {
self.0.captures.fetch_add(1, Ordering::SeqCst);
ChargeStatus::Captured {
at_unix_ms: 1,
vendor_ref: format!("pi_{}", h.id),
}
}
c @ ChargeStatus::Captured { .. } => c,
other => return Err(PayError::Declined(format!("{other:?} cannot be captured"))),
};
st.insert(h.id.clone(), next.clone());
Ok(next)
}
pub fn unlock(&self, h: &ChargeHandle) -> Result<ChargeStatus, PayError> {
if self.0.release_down.load(Ordering::SeqCst) {
return Err(PayError::Unavailable(
"holdpay: the vendor does not answer".into(),
));
}
let mut st = self.0.state.lock().unwrap();
let now = st
.get(&h.id)
.cloned()
.ok_or_else(|| PayError::UnknownHandle(h.clone()))?;
if now == ChargeStatus::AwaitingCustomer
&& self.0.pay_on_release.swap(false, Ordering::SeqCst)
{
st.insert(h.id.clone(), ChargeStatus::Reserved);
return Err(PayError::Unavailable(
"holdpay: the session is complete and cannot be expired".into(),
));
}
let next = match now {
ChargeStatus::Captured { .. } => {
return Err(PayError::Declined(
"captured: a refund, not a release".into(),
))
}
_ => ChargeStatus::Released,
};
self.0.releases.fetch_add(1, Ordering::SeqCst);
st.insert(h.id.clone(), next.clone());
Ok(next)
}
pub fn charge_status(&self, h: &ChargeHandle) -> Result<ChargeStatus, PayError> {
self.0
.state
.lock()
.unwrap()
.get(&h.id)
.cloned()
.ok_or_else(|| PayError::UnknownHandle(h.clone()))
}
/// Only the vendor's word that money went back or is contested
/// ([`crate::testing::CallbackPay::reversal_body`]'s shape, as Stripe's `charge.refunded` /
/// `charge.dispute.*` are read): the estate's reversals (F-S-01). Nothing else is a callback.
pub fn parse_callback(&self, raw: RawCallback<'_>) -> Result<CallbackEvent, PayError> {
let v: serde_json::Value = serde_json::from_slice(raw.body)
.map_err(|e| PayError::Unverified(format!("holdpay: {e}")))?;
let kind = match v.get("event").and_then(|e| e.as_str()) {
Some("refunded") => monetize_pay::ReversalKind::Refunded,
Some("dispute_opened") => monetize_pay::ReversalKind::DisputeOpened,
Some("dispute_won") => monetize_pay::ReversalKind::DisputeWon,
Some("dispute_lost") => monetize_pay::ReversalKind::DisputeLost,
// A32-26: the buyer paid on the vendor's page — the money is authorised (held).
Some("paid") => {
let field = |k: &str| {
v.get(k)
.and_then(|x| x.as_str())
.unwrap_or_default()
.to_owned()
};
return Ok(CallbackEvent {
reference: field("reference"),
handle: ChargeHandle {
vendor: "holdpay".into(),
id: field("handle"),
},
status: ChargeStatus::Reserved,
});
}
_ => return Err(PayError::Unverified("holdpay has no callbacks".into())),
};
let field = |k: &str| {
v.get(k)
.and_then(|x| x.as_str())
.unwrap_or_default()
.to_owned()
};
let handle = ChargeHandle {
vendor: "holdpay".into(),
id: field("handle"),
};
let amount = v.get("amount").and_then(|a| a.as_u64()).unwrap_or(0);
let id = if kind == monetize_pay::ReversalKind::Refunded {
format!("re-{}-{amount}", handle.id)
} else {
format!("dp-{}", handle.id)
};
Err(PayError::Reversal(Box::new(monetize_pay::Reversal {
vendor: "holdpay".into(),
handle,
reference: field("reference"),
kind,
id,
amount: Money {
minor: amount,
currency: monetize_pay::Currency::Eur,
},
reason: "holdpay".into(),
})))
}
pub fn give_back(&self, h: &ChargeHandle, _amount: Money) -> Result<ChargeStatus, PayError> {
let mut st = self.0.state.lock().unwrap();
match st.get(&h.id).cloned() {
Some(ChargeStatus::Captured { .. }) => {
self.0.refunds.fetch_add(1, Ordering::SeqCst);
st.insert(h.id.clone(), ChargeStatus::Released);
Ok(ChargeStatus::Released)
}
Some(other) => Err(PayError::Declined(format!(
"{other:?}: nothing captured to refund"
))),
None => Err(PayError::UnknownHandle(h.clone())),
}
}
pub fn settled(&self, _h: &ChargeHandle) -> Option<monetize_pay::Settlement> {
None
}
pub fn redirect(&self, h: &ChargeHandle) -> Option<String> {
Some(format!("https://pay.example/{}", h.id))
}
pub fn start_signup(
&self,
_order: &monetize_pay::signup::SignupOrder,
) -> Result<Option<monetize_pay::signup::SignupCheckout>, PayError> {
Ok(None)
}
}
impl monetize_pay::payment::Payment for HoldPay {
fn manifest(&self) -> monetize_pay::payment::PayManifest {
monetize_pay::payment::PayManifest {
vendor: self.vendor().to_string(),
markets: self.markets().to_vec(),
settings: Vec::new(),
holds: true,
test_payer: self.test_payer(),
}
}
fn page(
&self,
charge: &monetize_pay::payment::Charge<'_>,
back: &monetize_pay::payment::Return,
) -> Result<monetize_pay::payment::Page, monetize_pay::PayError> {
Ok(match charge {
monetize_pay::payment::Charge::Order(req) => monetize_pay::payment::Page::Order {
handle: self.reserve_returning(req, &back.paid, &back.cancel)?,
url: None,
},
monetize_pay::payment::Charge::Signup(o) => {
monetize_pay::payment::Page::Signup(self.start_signup(o)?)
}
monetize_pay::payment::Charge::CardCheck(_o) => {
monetize_pay::payment::Page::CardCheck(None)
}
monetize_pay::payment::Charge::TestSignup(_o) => {
monetize_pay::payment::Page::TestSignup(None)
}
})
}
fn status(
&self,
of: &monetize_pay::payment::Of<'_>,
) -> Result<monetize_pay::payment::Standing, monetize_pay::PayError> {
Ok(match of {
monetize_pay::payment::Of::Charge(h) => {
monetize_pay::payment::Standing::Charge(self.charge_status(h)?)
}
monetize_pay::payment::Of::Page(h) => {
monetize_pay::payment::Standing::Page(self.redirect(h))
}
monetize_pay::payment::Of::Signup { session: _ } => {
monetize_pay::payment::Standing::Signup(None)
}
monetize_pay::payment::Of::CardCheck { session: _ } => {
monetize_pay::payment::Standing::CardCheck(None)
}
})
}
fn capture(
&self,
h: &monetize_pay::ChargeHandle,
) -> Result<monetize_pay::ChargeStatus, monetize_pay::PayError> {
self.draw(h)
}
fn release(
&self,
h: &monetize_pay::ChargeHandle,
) -> Result<monetize_pay::ChargeStatus, monetize_pay::PayError> {
self.unlock(h)
}
fn refund(
&self,
h: &monetize_pay::ChargeHandle,
amount: monetize_pay::Money,
) -> Result<monetize_pay::ChargeStatus, monetize_pay::PayError> {
self.give_back(h, amount)
}
fn callback(
&self,
raw: monetize_pay::RawCallback<'_>,
) -> Result<monetize_pay::CallbackEvent, monetize_pay::PayError> {
self.parse_callback(raw)
}
fn settlement(&self, h: &monetize_pay::ChargeHandle) -> Option<monetize_pay::Settlement> {
self.settled(h)
}
fn paid_since(
&self,
_since_unix_ms: i64,
) -> Result<Vec<monetize_pay::reconcile::PaidAtVendor>, monetize_pay::PayError> {
Err(monetize_pay::reconcile::cannot_be_asked())
}
fn livemode(&self) -> Option<bool> {
self.live()
}
}
/// **The kit, faked**: reads `laid.json` and the hand-off as the kit does,
/// hands a pairing file BACK, and writes the verdict file. Its boxes call home
/// from their first boot unless `silent`.
struct FakeKit {
verdict: Mutex<String>,
seen: Mutex<Vec<(LaidEstate, Vec<String>, usize)>>,
/// The names each install was told to serve.
names: Mutex<Vec<Vec<String>>>,
/// Whose estate each install was told it is (`InstallRequest.account`).
accounts: Mutex<Vec<String>>,
/// The SHA-256 of the first-login invite each install was handed — what
/// the kit feeds gunnar as the operator's first invite — and its lifetime.
first_logins: Mutex<Vec<(String, u64)>>,
/// The hand-off's files as the kit got them (the last install's): what the
/// ESTATE holds from then on — the shop forgets them after the hand-off.
handed: Mutex<BTreeMap<String, Vec<u8>>>,
/// The shop's own pairing: mint seeds before the lay (`Installer::mint`).
mints: std::sync::atomic::AtomicBool,
/// The role each install was asked to lay (`InstallRequest.role`; empty: the whole estate).
roles: Mutex<Vec<String>>,
/// The boxes' fleet keys the kit names in its verdict (empty: they pin on first call).
appliance_keys: Mutex<BTreeMap<String, String>>,
/// The server's guardian and clock, set by [`build_with`] (again on a restart): the
/// installed boxes call home on it from their first boot, inside the install.
fleet: Mutex<Option<(Arc<monetize_guardian::Guardian>, Arc<AtomicU64>)>>,
/// Boxes that never call home (the estate is installed and silent).
silent: std::sync::atomic::AtomicBool,
/// F4: the install hands back the installer material its estate keeps.
bundles: std::sync::atomic::AtomicBool,
/// A22 #7: the install hands back a file the custody cannot read (not text), so its
/// take-back fails.
unsealable: std::sync::atomic::AtomicBool,
/// S4: what the sold instance's PUBLIC front serves, as the sale check finds it.
front: Mutex<FakeFront>,
/// S4: each sale check asked — where it looked and with which secrets.
sale_checks: Mutex<Vec<SaleChecked>>,
/// The ticket key the primary offers, as the installer's verdict names it (empty: none).
ticket_key: Mutex<String>,
/// What each install of an operator site was handed ([`InstallRequest::site`]).
sites: Mutex<Vec<SiteFeed>>,
/// OX-RELAY2: the mail relay each install was handed, by the run's company
/// ([`InstallRequest::relay`]).
relays: Mutex<Vec<(String, BTreeMap<String, String>)>>,
/// Armed: the next install stops at its start until the test opens it (an installer
/// that is still running).
install_gate: Gate,
/// F5: what each box answers a re-check of its pair status (empty: the installer cannot ask).
pairs: Mutex<Vec<(String, Result<String, String>)>>,
/// F5: how many re-checks were asked.
pair_asks: std::sync::atomic::AtomicUsize,
/// HRS-DIAG: how often the fleet seam was asked to be fed again, and whether the boxes
/// call home once it was.
seam_asks: std::sync::atomic::AtomicUsize,
seam_heals: std::sync::atomic::AtomicBool,
/// F9: each box's live door as the ONE box reaches it over the installer link (none: it
/// reaches no live door).
lives: Mutex<BTreeMap<String, update::LiveRunning>>,
/// F9: each stage the ONE box sent, by role, with its pin.
staged: Mutex<Vec<(String, String)>>,
/// Lane B5: every stage the ONE box handed a box, whole.
pub stages: Mutex<Vec<update::LiveStage>>,
/// Lane B5: the box's refusal of its next stage (taken once).
pub refuse_stage: Mutex<Option<String>>,
/// The site's first-admin door, as its front answers (none: it cannot be asked).
first_door: Mutex<Option<FirstDoor>>,
/// How often the first-admin door was asked.
first_door_asks: std::sync::atomic::AtomicUsize,
}
/// **The sold instance's public front, faked** (S4): whether `https://<host>/login` answers,
/// whether the first-login door answers, and the repositories it lists (`<account>` = the
/// order's account). The default serves.
#[derive(Clone)]
struct FakeFront {
login: bool,
door: bool,
repos: Vec<String>,
}
impl Default for FakeFront {
fn default() -> Self {
FakeFront {
login: true,
door: true,
repos: vec!["<account>/welcome".into()],
}
}
}
/// One sale check, as the kit was asked it: the host, the account, the front's public
/// address, and the SHA-256 of the invite and of the bearer it proved with.
#[derive(Clone, Debug)]
struct SaleChecked {
host: String,
account: String,
front_ipv4: String,
invite_sha: String,
token_sha: String,
}
impl FakeKit {
fn new(verdict: &str) -> Arc<Self> {
Arc::new(FakeKit {
verdict: Mutex::new(verdict.into()),
seen: Mutex::default(),
names: Mutex::default(),
accounts: Mutex::default(),
first_logins: Mutex::default(),
handed: Mutex::default(),
mints: Default::default(),
roles: Mutex::default(),
appliance_keys: Mutex::default(),
fleet: Mutex::default(),
silent: Default::default(),
bundles: Default::default(),
unsealable: Default::default(),
front: Mutex::default(),
sale_checks: Mutex::default(),
ticket_key: Mutex::default(),
sites: Mutex::default(),
relays: Mutex::default(),
install_gate: Gate::default(),
pairs: Mutex::default(),
pair_asks: Default::default(),
seam_asks: Default::default(),
seam_heals: Default::default(),
lives: Mutex::default(),
staged: Mutex::default(),
stages: Mutex::default(),
refuse_stage: Mutex::default(),
first_door: Mutex::default(),
first_door_asks: Default::default(),
})
}
}
impl Installer for FakeKit {
fn first_door(&self, at: &SaleCheckAt<'_>) -> Result<FirstDoor, String> {
self.first_door_asks.fetch_add(1, Ordering::SeqCst);
assert!(
!at.first_login.is_empty() && !at.host.is_empty(),
"asked with the custody's invite at the site's host"
);
self.first_door
.lock()
.unwrap()
.clone()
.ok_or_else(|| "the front cannot be asked".into())
}
/// The public front judged as the shop's pairing judges it: the login page, the door, and
/// exactly one `<account>/welcome`.
fn sale_check(&self, at: &SaleCheckAt<'_>) -> Result<String, String> {
self.sale_checks.lock().unwrap().push(SaleChecked {
host: at.host.into(),
account: at.account.into(),
front_ipv4: at.front.map(|m| m.public_ipv4.clone()).unwrap_or_default(),
invite_sha: sha256_hex(at.first_login),
token_sha: sha256_hex(at.console_token),
});
let f = self.front.lock().unwrap().clone();
if !f.login {
return Err(format!("GET https://{}/login did not answer", at.host));
}
if !f.door {
return Err(format!(
"the first-login door at https://{} did not answer",
at.host
));
}
let repos: Vec<String> = f
.repos
.iter()
.map(|p| p.replace("<account>", at.account))
.collect();
let welcome: Vec<&String> = repos.iter().filter(|p| p.ends_with("/welcome")).collect();
let want = format!("{}/welcome", at.account);
if welcome.len() != 1 || *welcome[0] != want {
return Err(format!(
"{} welcome repositories ({welcome:?}), not exactly {want}",
welcome.len()
));
}
Ok(format!(
"https://{} serves its login page, its first-login door and {want}",
at.host
))
}
fn mint(&self, company: &str, host: &str) -> Result<Vec<(String, String)>, String> {
if !self.mints.load(Ordering::SeqCst) {
return Ok(Vec::new());
}
Ok(vec![
(
"ca.cert.pem".into(),
"-----BEGIN CERTIFICATE-----minted".into(),
),
(
"seed.front.toml".into(),
format!("estate = \"{host}\"\nkind = \"front\"\n# {company}\n"),
),
(
"seed.gunnar.toml".into(),
format!("estate = \"{host}\"\nkind = \"gunnar\"\n"),
),
])
}
/// F9: the box's live door, reached only with the installer material the custody handed over.
fn live_running(
&self,
req: &InstallRequest,
role: &str,
) -> Result<update::LiveRunning, String> {
let m = req.handoff.join(crate::custody::handoff::MATERIAL_DIR);
if !m.is_dir() {
return Err(format!(
"no installer material was handed over ({})",
m.display()
));
}
self.lives
.lock()
.unwrap()
.get(role)
.cloned()
.ok_or_else(|| {
format!("its live door did not answer: the fake {role} runs no live door")
})
}
/// F9: the stage taken and confirmed at once.
fn live_stage(
&self,
req: &InstallRequest,
role: &str,
stage: &update::LiveStage,
) -> Result<String, String> {
self.live_running(req, role)?;
self.stages.lock().unwrap().push(stage.clone());
if let Some(e) = self.refuse_stage.lock().unwrap().take() {
return Err(e);
}
self.staged
.lock()
.unwrap()
.push((role.to_string(), stage.pin_hex.clone()));
let mut l = self.lives.lock().unwrap();
let r = l.get_mut(role).unwrap();
r.app = stage.pin_hex.clone();
r.slot = "b".into();
Ok("staged".into())
}
/// F5: each box's pair status as the test set it, asked over the order's own hand-off.
/// HRS-DIAG: the seam fed again over the installer's link, with the custody's material; the
/// boxes that lacked it then call home.
fn refeed_seam(&self, req: &InstallRequest, instance: &str) -> Result<Option<String>, String> {
assert!(
instance == req.company || !instance.trim().is_empty(),
"asked with the estate the guardian knows"
);
if req.company == "acme" {
assert_eq!(instance, "acme", "a sold estate pulls as its company");
}
self.seam_asks.fetch_add(1, Ordering::SeqCst);
let order: LaidOrder =
serde_json::from_slice(&std::fs::read(&req.laid).map_err(|e| e.to_string())?)
.map_err(|e| e.to_string())?;
if !self.seam_heals.load(Ordering::SeqCst) {
return Ok(None);
}
if !req
.handoff
.join(crate::custody::handoff::ROOT_SEED)
.is_file()
{
return Err("no custody material was handed over".into());
}
if let Some((g, clock)) = self.fleet.lock().unwrap().as_ref() {
for m in &order.estate.machines {
g.store
.record_report(
&req.company,
&m.role,
clock.load(Ordering::SeqCst),
&running(&m.role),
)
.unwrap();
}
}
Ok(Some(format!(
"fleet_at fed to {} box(es) over the installer's link",
order.estate.machines.len()
)))
}
fn pair_status(&self, req: &InstallRequest) -> Result<PairCheck, String> {
self.pair_asks.fetch_add(1, Ordering::SeqCst);
std::fs::read(&req.laid).map_err(|e| format!("{}: {e}", req.laid.display()))?;
let boxes = self.pairs.lock().unwrap().clone();
if boxes.is_empty() {
return Err("the fake kit cannot ask the boxes".into());
}
Ok(PairCheck {
boxes,
ticket_key: self.ticket_key.lock().unwrap().clone(),
})
}
fn install(&self, req: &InstallRequest) -> Result<InstallVerdict, String> {
self.install_gate.pass();
let order: LaidOrder =
serde_json::from_slice(&std::fs::read(&req.laid).map_err(|e| e.to_string())?)
.map_err(|e| e.to_string())?;
let laid = order.estate.clone();
self.names.lock().unwrap().push(order.names.clone());
self.accounts.lock().unwrap().push(req.account.clone());
self.relays
.lock()
.unwrap()
.push((req.company.clone(), req.relay.clone()));
req.narrate
.say("installer", "the kit pairs the laid estate");
if let Ok(invite) =
std::fs::read_to_string(req.handoff.join(crate::custody::handoff::FIRST_LOGIN))
{
self.first_logins
.lock()
.unwrap()
.push((sha256_hex(&invite), order.first_login_ttl_secs));
}
let mut files: Vec<String> = std::fs::read_dir(&req.handoff)
.unwrap()
.flatten()
.map(|e| e.file_name().to_string_lossy().into_owned())
.collect();
files.sort();
*self.handed.lock().unwrap() = files
.iter()
.filter_map(|f| {
std::fs::read(req.handoff.join(f))
.ok()
.map(|b| (f.clone(), b))
})
.collect();
let seed = std::fs::read(req.handoff.join(crate::custody::handoff::ROOT_SEED))
.map(|b| b.len())
.unwrap_or(0);
self.seen.lock().unwrap().push((laid, files, seed));
// The kit hands the pairing material it minted back to the custodian.
std::fs::write(
req.handoff
.join(crate::custody::handoff::RETURN_DIR)
.join("installer-ca.key.pem"),
"-----BEGIN PRIVATE KEY-----kitminted",
)
.unwrap();
std::fs::write(
req.handoff
.join(crate::custody::handoff::RETURN_DIR)
.join("ca.cert.pem"),
"-----BEGIN CERTIFICATE-----ca",
)
.unwrap();
// F4: the shop's own pairing hands back the bundle its estate keeps.
if self.bundles.load(Ordering::SeqCst) {
std::fs::write(
req.handoff
.join(crate::custody::handoff::RETURN_DIR)
.join(crate::custody::handoff::INSTALLER_MATERIAL),
"{\"v\":\"installer-material/1\"}",
)
.unwrap();
}
if self.unsealable.load(Ordering::SeqCst) {
std::fs::write(
req.handoff
.join(crate::custody::handoff::RETURN_DIR)
.join("unreadable.bin"),
[0xffu8, 0xfe, 0x00],
)
.unwrap();
}
let word = self.verdict.lock().unwrap().clone();
let v = InstallVerdict {
verdict: word.clone(),
detail: "fake kit".into(),
receipt: serde_json::json!({"verb": "estate-install-monetize", "verdict": word}),
peers: ["front", "main", "twin"]
.iter()
.enumerate()
.map(|(i, n)| WgPeer {
name: n.to_string(),
overlay: format!("10.44.0.{}", i + 1),
public_key: format!("PUB{n}="),
..WgPeer::default()
})
.collect(),
appliance_keys: self.appliance_keys.lock().unwrap().clone(),
ticket_key: self.ticket_key.lock().unwrap().clone(),
};
if let Some(site) = &req.site {
self.sites.lock().unwrap().push(site.clone());
}
self.roles.lock().unwrap().push(req.role.clone());
std::fs::write(req.run.join(VERDICT_FILE), serde_json::to_vec(&v).unwrap()).unwrap();
std::fs::write(
req.run.join("install.log"),
"fake kit: installed onto the laid servers\n",
)
.unwrap();
// The installed boxes boot and call home on the pull channel.
if !self.silent.load(Ordering::SeqCst) {
if let Some((g, clock)) = self.fleet.lock().unwrap().as_ref() {
for m in &order.estate.machines {
g.store
.record_report(
req.site
.as_ref()
.map(|x| x.label.as_str())
.unwrap_or(&req.company),
&m.role,
clock.load(Ordering::SeqCst),
&running(&m.role),
)
.unwrap();
}
}
}
Ok(v)
}
}
/// The lowercase hex SHA-256 of a secret's trimmed text — what the kit feeds
/// gunnar as an invite's hash (`installer::invite_hash`).
fn sha256_hex(secret: &str) -> String {
ring::digest::digest(&ring::digest::SHA256, secret.trim().as_bytes())
.as_ref()
.iter()
.map(|b| format!("{b:02x}"))
.collect()
}
fn tmp(name: &str) -> PathBuf {
let d = std::env::temp_dir().join(format!(
"monetize-estate-order-{}-{name}",
std::process::id()
));
let _ = std::fs::remove_dir_all(&d);
std::fs::create_dir_all(&d).unwrap();
d
}
struct Rig {
state: Arc<AppState>,
pay: HoldPay,
cloud: Arc<MockCloud>,
kit: Arc<FakeKit>,
dir: PathBuf,
clock: Arc<AtomicU64>,
mails: Arc<Mails>,
/// The twin's samples, as the estate's control link would read them.
health: Arc<twin::MockTwinHealth>,
}
/// The one mail path, recording (the reminders, the warnings, the renewal);
/// armed, its gate holds the next mail.
/// ★ Armed (`.3`), it MAKES the accounts it is asked for (pay once, 2026-10-22) and names
/// them in `.4`; a name there is taken.
#[derive(Default)]
struct Mails(
Mutex<Vec<monetize_pay::CustomerNotice>>,
Gate,
std::sync::atomic::AtomicBool,
std::sync::atomic::AtomicBool,
Mutex<Vec<String>>,
);
impl Mails {
fn gate(&self) -> &Gate {
&self.1
}
fn kinds(&self) -> Vec<String> {
self.0
.lock()
.unwrap()
.iter()
.map(|n| n.kind.clone())
.collect()
}
fn count(&self, kind: &str) -> usize {
self.0
.lock()
.unwrap()
.iter()
.filter(|n| n.kind == kind)
.count()
}
fn last(&self) -> monetize_pay::CustomerNotice {
self.0
.lock()
.unwrap()
.last()
.cloned()
.expect("a mail was sent")
}
}
impl monetize_pay::SignupSink for Mails {
fn paid(
&self,
s: &monetize_pay::signup::PaidSignup,
) -> Result<monetize_pay::signup::SignupOutcome, monetize_pay::SignupError> {
if !self.3.load(Ordering::SeqCst) {
return Err(monetize_pay::SignupError::Refused(
"not a signup test".into(),
));
}
let mut made = self.4.lock().unwrap();
if made.contains(&s.username) {
return Err(monetize_pay::SignupError::NameTaken(format!(
"username {:?} is taken",
s.username
)));
}
made.push(s.username.clone());
Ok(monetize_pay::signup::SignupOutcome::Created {
namespace: s.username.clone(),
username: s.username.clone(),
})
}
fn creates_accounts(&self) -> bool {
self.3.load(Ordering::SeqCst)
}
fn name_verdict(
&self,
name: &str,
) -> Result<monetize_pay::signup::NameVerdict, monetize_pay::SignupError> {
if self.4.lock().unwrap().iter().any(|n| n == name) {
return Ok(monetize_pay::signup::NameVerdict::Taken(format!(
"username {name:?} is taken; choose another"
)));
}
Ok(monetize_pay::signup::NameVerdict::Free)
}
fn notify(
&self,
n: &monetize_pay::CustomerNotice,
) -> Result<String, monetize_pay::SignupError> {
self.1.pass();
// Down: the relay takes nothing (A47's test).
if self.2.load(Ordering::SeqCst) {
return Err(monetize_pay::SignupError::Unavailable(
"the relay is down".into(),
));
}
self.0.lock().unwrap().push(n.clone());
Ok(format!("sent to {}", n.to))
}
}
/// The mock prices every resource at 10.00 EUR a month; sold in EUR, so no rate is needed.
/// A paid plan change resizes at once here (`resize_notice_secs: 0`); the
/// notice a sold estate is given first has its own test.
/// Gunnar's words, as the run views were asked before the Gunnar-defaulting wrappers went (v2.0 step 1).
fn gw() -> lifecycle::ProductWords {
crate::testing::lifecycles::gunnar_words()
}
fn cfg() -> EstateOrderConfig {
EstateOrderConfig {
product: "gunnar".into(),
vendor: "holdpay".into(),
apex: "gunnar.rs".into(),
cloud: "mockcloud".into(),
currency: "EUR".into(),
resize_notice_secs: 0,
shop_door: DOOR.into(),
shape: crate::testing::lifecycles::gunnar_shape(),
..EstateOrderConfig::default()
}
}
/// The Gunnar rules' plan for `cfg` (the native `plan_for` went in v2.0 P2 12.4).
fn plan_for(
cfg: &EstateOrderConfig,
company: &str,
sizes: &EstateSizes,
twin_plan: &str,
) -> monetize_cloud::lay::EstatePlan {
plan_for_as(
cfg,
company,
sizes,
twin_plan,
&crate::testing::lifecycles::gunnar(),
)
}
/// Each machine's release medium by the Gunnar rules' kinds.
fn give_release_media(
plan: &mut monetize_cloud::lay::EstatePlan,
media: &BTreeMap<String, String>,
objects: &BTreeMap<String, monetize_cloud::lay::MediaObject>,
) {
give_release_media_as(plan, media, objects, &crate::testing::lifecycles::gunnar())
}
/// Each machine's template by the Gunnar rules' kinds.
fn give_templates(
plan: &mut monetize_cloud::lay::EstatePlan,
c: &EstateOrderConfig,
) -> Vec<String> {
give_templates_as(plan, c, &crate::testing::lifecycles::gunnar())
}
/// The one monetize's door for gunnar's sales (ops config's placeholder, the owner 2026-10-10).
const DOOR: &str = "https://monetize.ignalina.dk";
fn rig_with(name: &str, cfg: EstateOrderConfig, verdict: &str) -> Rig {
let dir = tmp(name);
let pay = HoldPay::default();
let cloud = Arc::new(MockCloud::new());
let kit = FakeKit::new(verdict);
let rig = build(&dir, cfg, pay.clone(), cloud.clone(), kit.clone());
Rig {
state: rig.0,
pay,
cloud,
kit,
dir,
clock: rig.1,
mails: rig.2,
health: rig.3,
}
}
/// One server over `dir` — called again on the same `dir` to model a restart.
fn build(
dir: &std::path::Path,
cfg: EstateOrderConfig,
pay: HoldPay,
cloud: Arc<MockCloud>,
kit: Arc<FakeKit>,
) -> (
Arc<AppState>,
Arc<AtomicU64>,
Arc<Mails>,
Arc<twin::MockTwinHealth>,
) {
build_with(dir, cfg, pay, cloud, kit, None, None)
}
/// [`build`], with the DNS writer and the twin's source the config would
/// make (`dns_writer`, the installer's twin reader) instead of the recording ones.
fn build_with(
dir: &std::path::Path,
cfg: EstateOrderConfig,
pay: HoldPay,
cloud: Arc<MockCloud>,
kit: Arc<FakeKit>,
dns: Option<Arc<dyn EstateDns>>,
source: Option<Arc<dyn twin::TwinHealth>>,
) -> (
Arc<AppState>,
Arc<AtomicU64>,
Arc<Mails>,
Arc<twin::MockTwinHealth>,
) {
build_in(
Registry::new()
.sells("gunnar", pay)
.cloud(cloud)
.shared_product(shop_product())
.ticket_key("gunnar", &shop_key_hex()),
dir,
cfg,
kit,
dns,
source,
)
}
/// [`build_with`] over a registry the test made (its vendors, its sites).
fn build_in(
reg: Registry,
dir: &std::path::Path,
cfg: EstateOrderConfig,
kit: Arc<FakeKit>,
dns: Option<Arc<dyn EstateDns>>,
source: Option<Arc<dyn twin::TwinHealth>>,
) -> (
Arc<AppState>,
Arc<AtomicU64>,
Arc<Mails>,
Arc<twin::MockTwinHealth>,
) {
// The suite sells on the Gunnar- and Holger-shaped TEST lifecycles, never the natives (A28 H6).
crate::testing::lifecycles::install();
let mut state = AppState::in_memory(reg);
let mails = Arc::new(Mails::default());
state.signup_sink = mails.clone();
let clock = Arc::new(AtomicU64::new(1_900_000_000_000));
let c = clock.clone();
state.clock = Box::new(move || c.load(Ordering::SeqCst));
let custody = crate::custody::Custody::open(dir.join("custody")).unwrap();
let health = Arc::new(twin::MockTwinHealth::default());
let dns = dns.unwrap_or_else(|| Arc::new(FileDns(dir.join("dns.json"))));
let source: Arc<dyn twin::TwinHealth> = source.unwrap_or_else(|| health.clone());
*kit.fleet.lock().unwrap() = Some((
state
.fleet
.guardian()
.expect("the in-memory guardian")
.clone(),
clock.clone(),
));
state.estates = EstateOrders::with(cfg, dir.join("estate-orders"), kit, dns, custody)
.resolving(Arc::new(FileResolver(dir.join("world-dns.json"))))
.watching(source);
(Arc::new(state), clock, mails, health)
}
/// **An order for the job's own tests**: owned by `buyer` (G5: every order
/// names the account it is a row on; the wire's proof is tested on its own).
fn start(
state: &AppState,
company: &str,
email: &str,
own_domain: &str,
sizes: &EstateSizes,
) -> Result<EstateRun, StartRefusal> {
start_for(state, company, email, own_domain, "buyer", sizes)
}
/// **The boxes of `company`'s laid estate call home** (a Fleet `Report` each, at the
/// clock) — what a running estate does every minute.
fn calls_home(state: &AppState, company: &str) {
let Some(run) = state.estates.get(company) else {
return;
};
let Some(laid) = run.laid.clone() else { return };
let company = run.fleet_name();
let g = state.fleet.guardian().expect("the in-memory guardian");
if g.store.product_of(company).is_none() {
return;
}
for m in &laid.machines {
g.store
.record_report(company, &m.role, state.now(), &running(&m.role))
.unwrap();
}
}
/// **One tick of the job, its estate's boxes calling home first** (the running estate's
/// minute; an installed one only — the guardian knows it). [`super::drive`] is the tick
/// alone: a silent estate.
fn drive(state: &AppState, company: &str) {
calls_home(state, company);
super::drive(state, company);
}
fn rig(name: &str) -> Rig {
rig_with(name, cfg(), "PASS")
}
fn phases(run: &EstateRun) -> Vec<String> {
run.history
.iter()
.map(|t| t.phase.clone())
.filter(|p| !p.is_empty())
.fold(Vec::new(), |mut v, p| {
if v.last() != Some(&p) {
v.push(p);
}
v
})
}
fn handle_of(r: &Rig, company: &str) -> String {
r.state.estates.get(company).unwrap().handle.unwrap().id
}
/// ★ **The suite sells on the TEST lifecycles** (v2.0 P2 12.0, A28 H6): every rig's `gunnar`
/// and `holger` are the Gunnar- and Holger-shaped test ones, never the native fall-back.
#[test]
fn the_rig_sells_on_the_test_lifecycles_never_the_natives() {
let r = rig("test-lifecycles");
assert!(
Arc::ptr_eq(
&lifecycle::of(r.state.estates.cfg.as_ref().unwrap()).unwrap(),
&crate::testing::lifecycles::gunnar()
),
"the rig's gunnar is the test one"
);
assert!(
Arc::ptr_eq(
&lifecycle::find("holger").unwrap(),
&crate::testing::lifecycles::holger()
),
"and its holger"
);
}
// ── the vertical slice, rung 0 ──────────────────────────────────────────────
/// **The happy path**: the order is a hold, the hold is a job, the job lays
/// the three servers and their disks, the kit installs on what was laid, the
/// estate answers, and only then is the money captured.
#[test]
fn an_order_is_held_then_laid_installed_and_captured_only_when_the_estate_answers() {
let r = rig("happy");
let run = start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.expect("ordered");
assert_eq!(run.phase, phase::ORDERED);
assert_eq!(run.reference, "estate/acme");
assert!(
run.checkout_url.starts_with("https://pay.example/"),
"the buyer is sent to the vendor's page"
);
// 3 servers + 8 disks at 10.00 EUR = 110.00 a month; + 20 % = 132.00; six months prepaid.
assert_eq!(
run.quote.cost_in_sale,
Money {
minor: 11_000,
currency: monetize_pay::Currency::Eur
}
);
assert_eq!(
run.quote.monthly,
Money {
minor: 13_200,
currency: monetize_pay::Currency::Eur
}
);
assert_eq!(
run.amount,
Money {
minor: 79_200,
currency: monetize_pay::Currency::Eur
},
"six months, prepaid, is what is held"
);
assert_eq!(run.quote.term_months, 6);
let asked = r.pay.0.requests.lock().unwrap()[0].clone();
assert_eq!(asked.reference, "estate/acme");
assert_eq!(asked.amount, run.amount, "the vendor holds the six months");
assert_eq!(
run.customer_view_as("gunnar.rs", &gw()).0,
"waiting_for_payment"
);
// Nothing is laid before the money is held.
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::ORDERED);
assert!(
r.cloud.lays().is_empty(),
"nothing is laid while the buyer has not paid"
);
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(
phases(&run),
vec![
"ordered",
"held",
"laying",
"installing",
"paired",
"captured"
],
"{:#?}",
run.history
);
assert_eq!(r.pay.captures(), 1, "captured once");
assert_eq!(
run.paid_until_ms,
price::add_months(run.captured_at_ms, 6),
"paid for six months from the capture"
);
assert!(matches!(
r.pay.state_of(&handle_of(&r, "acme")),
ChargeStatus::Captured { .. }
));
let (state, words, url) = run.customer_view_as("gunnar.rs", &gw());
assert_eq!(
(state.as_str(), url.as_str()),
("ready", "https://www.acme.gunnar.rs"),
"the site's canonical www name (WWW-CANON): {words}"
);
// The cloud laid the three servers and their disks, labelled.
assert_eq!(r.cloud.lays(), vec!["estate/acme".to_string()]);
let laid = run.laid.clone().unwrap();
assert_eq!(
laid.machines
.iter()
.map(|m| m.role.as_str())
.collect::<Vec<_>>(),
vec!["front", "main", "twin"]
);
assert_eq!(
laid.machine("main").unwrap().disks.len(),
5,
"main: a system disk and four data disks"
);
assert_eq!(laid.machine("front").unwrap().hostname, "gunnar-front-acme");
assert_eq!(
r.cloud.live_under("estate/acme"),
3 + 1 + 5 + 2,
"3 servers and 8 disks, every one labelled estate/acme"
);
// The kit was handed what was laid and the custody's files, and handed back.
let seen = r.kit.seen.lock().unwrap().clone();
assert_eq!(seen.len(), 1);
assert_eq!(seen[0].0, laid);
assert_eq!(seen[0].2, 32, "the media signing seed is 32 bytes");
for f in ["console-admin-token", "pairing.seed", "return", "root.seed"] {
assert!(
seen[0].1.contains(&f.to_string()),
"the hand-off carries {f}: {:?}",
seen[0].1
);
}
assert!(
!seen[0].1.contains(&"monetize-backup-kek".to_string()),
"G16: no monetize of its own, no backup key for one: {:?}",
seen[0].1
);
let custody = r.state.estates.custody.as_ref().unwrap();
assert!(
run.history.iter().any(|t| t
.note
.contains("2 pairing file(s) sealed back into custody")),
"the pairing material the kit minted was sealed into custody: {:#?}",
run.history
);
assert!(
!custody.holds("acme"),
"and forgotten with every other secret of the estate once it was handed off (2026-10-08)"
);
assert!(
!r.dir.join("estate-orders/acme/handoff").exists(),
"the plain hand-off is gone after the step"
);
// The estate's WireGuard peer map: every box, its PUBLIC key, kept by monetize.
assert_eq!(
run.peers
.iter()
.map(|p| (p.name.as_str(), p.public_key.as_str()))
.collect::<Vec<_>>(),
vec![
("front", "PUBfront="),
("main", "PUBmain="),
("twin", "PUBtwin=")
]
);
// The names.
let dns = FileDns(r.dir.join("dns.json")).listed().unwrap();
let names: Vec<&str> = dns.iter().map(|d| d.name.as_str()).collect();
assert_eq!(
names,
vec!["acme.gunnar.rs", "www.acme.gunnar.rs", "git.acme.gunnar.rs"],
"G16: no monetize.<host> — a sold estate runs no monetize"
);
assert!(dns
.iter()
.all(|d| !d.proxied && d.value == laid.machine("front").unwrap().public_ipv4));
// The journal has every create, intent before confirmation.
let journal = std::fs::read_to_string(r.dir.join("estate-orders/acme/journal")).unwrap();
assert_eq!(
journal.matches("\"lay-server\"").count(),
6,
"3 servers × intent + confirmed"
);
assert_eq!(
journal.matches("\"lay-disk\"").count(),
16,
"8 disks × intent + confirmed"
);
}
/// **The failure path**: the cloud refuses part-way through the lay. Every
/// resource already bought under the reference is given back, the read-back
/// proves nothing is billed, and only then is the hold released. Nothing is
/// charged, and the estate's secrets are forgotten.
#[test]
fn a_mid_lay_failure_gives_everything_back_proves_it_and_the_paid_order_is_owed() {
let r = rig("midlay");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault {
after: Some(4),
outage: false,
});
drive(&r.state, "acme");
// Paid at the order (A23): given back, laid again once, then owed.
let run = r.state.estates.get("acme").unwrap();
assert_eq!(
phases(&run),
vec!["ordered", "held", "laying", "failed", "held", "laying", "failed", "owed"],
"{:#?}",
run.history
);
assert!(
run.history.iter().any(|t| t.note.contains("refused")),
"the refusal is named: {:#?}",
run.history
);
assert_eq!(
r.cloud.live_under("estate/acme"),
0,
"no billed resource is left under the reference"
);
assert_eq!(
r.cloud.released_for(),
vec![
vec!["estate/acme".to_string()],
vec!["estate/acme".to_string()]
]
);
assert_eq!(
(r.pay.captures(), r.pay.refunds()),
(1, 0),
"paid once, never refunded by itself"
);
assert!(
!r.state.estates.custody.as_ref().unwrap().holds("acme"),
"an estate that does not exist keeps no secrets"
);
assert!(
r.kit.seen.lock().unwrap().is_empty(),
"nothing was installed"
);
assert_eq!(
run.customer_view_as("gunnar.rs", &gw()).0,
"queued",
"the buyer reads that it is paid and takes longer"
);
}
/// The release WAITS for the proof: a resource the cloud will not let go of
/// keeps the job in `failed`, the hold still held, until it is gone.
#[test]
fn a_paid_order_is_not_laid_again_while_anything_is_still_billed() {
let r = rig("stuck");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault {
after: Some(2),
outage: false,
});
*r.cloud.fail_destroy.lock().unwrap() = true;
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::FAILED);
assert!(
matches!(
r.pay.state_of(&handle_of(&r, "acme")),
ChargeStatus::Captured { .. }
),
"paid at the order"
);
assert!(
run.why.contains("give-back") || run.why.contains("billed"),
"{}",
run.why
);
// Given back at last; laid again, and this time it lays.
*r.cloud.fail_destroy.lock().unwrap() = false;
r.cloud.lay_fails(LayFault::default());
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
assert_eq!(r.cloud.live_under("estate/acme"), 11);
assert_eq!(r.pay.captures(), 1);
}
/// An outage mid-lay is not a failure: the job stays in `laying`, and the
/// next tick lays again — ADOPTING what the first attempt bought.
#[test]
fn an_outage_mid_lay_parks_and_the_retry_adopts_what_was_laid() {
let r = rig("outage");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault {
after: Some(3),
outage: true,
});
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::LAYING);
assert!(run.why.contains("unavailable"), "{}", run.why);
assert_eq!(r.cloud.live_under("estate/acme"), 3);
r.cloud.lay_fails(LayFault::default());
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::CAPTURED);
assert_eq!(
r.cloud.live_under("estate/acme"),
11,
"the three from the first attempt were adopted, not bought again"
);
}
/// ★ **What was laid is written down BEFORE the DNS step** (code-smell review 2026-10-10,
/// stinky #13): a DNS write that fails parks the run with its estate kept in `run.laid`,
/// so the next tick writes the records again and never lays again. RED before: the park
/// came before `run.laid` was set, and every tick laid the estate again (adopted only
/// because the provider's labels matched).
#[test]
fn a_dns_write_that_fails_after_the_lay_keeps_what_was_laid_and_never_lays_again() {
let r = rig("dns-fails");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
// A directory where the records file goes: every DNS write fails.
let dns = r.dir.join("dns.json");
std::fs::create_dir_all(&dns).unwrap();
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::LAYING);
assert!(
run.why.contains("DNS records were not written"),
"{}",
run.why
);
assert!(
run.laid.is_some(),
"what was bought is in the run before the DNS step"
);
drive(&r.state, "acme");
assert_eq!(r.cloud.lays().len(), 1, "a DNS retry lays nothing again");
std::fs::remove_dir_all(&dns).unwrap();
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::CAPTURED);
assert_eq!(r.cloud.lays().len(), 1);
assert_eq!(r.cloud.live_under("estate/acme"), 11);
}
/// ★ **A cloud that is not linked never lets the give-back say "released"** (code-smell
/// review 2026-10-10, finding 3): an estate laid on a cloud this server no longer links (a
/// build without it, a guest whose digest no longer matches) cannot be given back here, so
/// the give-back WAITS, by name — the servers are still billed — and nothing is said gone.
#[test]
fn a_give_back_without_its_cloud_waits_by_name_and_never_says_released() {
let r = rig("no-cloud");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault {
after: Some(3),
outage: true,
});
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::LAYING);
assert_eq!(r.cloud.live_under("estate/acme"), 3);
// Restarted with the order's cloud no longer linked.
let (state, ..) = build(
&r.dir,
EstateOrderConfig {
cloud: "gone".into(),
..cfg()
},
r.pay.clone(),
r.cloud.clone(),
r.kit.clone(),
);
drive(&state, "acme");
let run = state.estates.get("acme").unwrap();
assert!(
!phases(&run)
.iter()
.any(|p| p == phase::RELEASED || p == phase::OWED),
"nothing was given back, so nothing is released: {:#?}",
run.history
);
assert_eq!(run.phase, phase::FAILED, "{:#?}", run.history);
assert!(
run.why.contains("\"gone\"") && run.why.contains("not linked"),
"the wait names the missing cloud: {}",
run.why
);
assert_eq!(
r.cloud.live_under("estate/acme"),
3,
"the servers still stand"
);
assert!(
r.cloud.released_for().is_empty(),
"no release was asked of any cloud"
);
assert!(
state.estates.custody.as_ref().unwrap().holds("acme"),
"the estate's secrets are kept while it still stands"
);
}
/// ★ **A give-back that cannot write down what it asked to go stops there** (code-smell
/// review 2026-10-10, stinky #14): each server the give-back destroys is remembered in
/// `given_back` so it is never asked twice; a run file that cannot be written parks the
/// give-back, by name, at that server. RED before: `let _ = save` went on through every
/// server and the release with nothing written, and the next tick asked them all again.
#[test]
fn a_give_back_that_cannot_write_down_a_server_it_asked_to_go_stops_there() {
let r = rig("save-fails");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault {
after: Some(10),
outage: true,
});
drive(&r.state, "acme");
assert_eq!(r.cloud.live_under("estate/acme"), 10);
// Failed with its cloud missing: written down FAILED, nothing given back yet.
let (gone, ..) = build(
&r.dir,
EstateOrderConfig {
cloud: "gone".into(),
..cfg()
},
r.pay.clone(),
r.cloud.clone(),
r.kit.clone(),
);
drive(&gone, "acme");
assert_eq!(gone.estates.get("acme").unwrap().phase, phase::FAILED);
// The cloud is back, but the run file cannot be written.
r.cloud.lay_fails(LayFault::default());
let (state, ..) = build(&r.dir, cfg(), r.pay.clone(), r.cloud.clone(), r.kit.clone());
let blocked = r.dir.join("estate-orders").join("acme").join("run.tmp");
std::fs::create_dir_all(&blocked).unwrap();
drive(&state, "acme");
assert_eq!(
r.cloud.destroys().len(),
1,
"one server asked to go, then the give-back parks: {:?}",
r.cloud.destroys()
);
assert!(
r.cloud.released_for().is_empty(),
"nothing released over an unwritten give-back"
);
std::fs::remove_dir_all(&blocked).unwrap();
drive(&state, "acme");
// Written again: the give-back finishes (once), and the paid order is laid again.
let run = state.estates.get("acme").unwrap();
assert_eq!(r.cloud.released_for().len(), 1, "given back once");
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
assert_eq!(
r.cloud.live_under("estate/acme"),
11,
"only the new lay stands"
);
}
/// A server that stops mid-lay comes back to the same phase from its files,
/// and finishes.
#[test]
fn a_restart_mid_lay_resumes_from_the_run_file() {
let r = rig("restart");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault {
after: Some(5),
outage: true,
});
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::LAYING);
// A new server over the same files: the run is read back.
r.cloud.lay_fails(LayFault::default());
let (again, _, _, _) = build(&r.dir, cfg(), r.pay.clone(), r.cloud.clone(), r.kit.clone());
assert_eq!(
again.estates.get("acme").unwrap().phase,
phase::LAYING,
"the phase is the file's"
);
drive(&again, "acme");
assert_eq!(again.estates.get("acme").unwrap().phase, phase::CAPTURED);
assert_eq!(r.cloud.live_under("estate/acme"), 11);
assert_eq!(r.pay.captures(), 1);
}
/// The installer says FAIL: everything is given back, nothing is charged.
#[test]
fn an_install_that_fails_gives_back_and_the_paid_order_is_owed() {
let r = rig_with("installfail", cfg(), "FAIL");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(
phases(&run),
vec![
"ordered",
"held",
"laying",
"installing",
"failed",
"held",
"laying",
"installing",
"failed",
"owed"
]
);
assert_eq!(r.cloud.live_under("estate/acme"), 0);
assert!(
FileDns(r.dir.join("dns.json")).listed().unwrap().is_empty(),
"the names are removed"
);
assert_eq!((r.pay.captures(), r.pay.refunds()), (1, 0));
}
/// The vendor lets the hold lapse while the estate is being set up: the job
/// fails, gives back, and never captures — never a second charge.
#[test]
fn a_paid_order_never_looks_for_a_hold_again() {
let r = rig_with("lapse", cfg(), "PASS");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault {
after: Some(2),
outage: true,
});
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::LAYING);
// A vendor that says the authorisation is gone changes nothing: the money
// was captured at the order (A23).
r.pay.lapse(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault::default());
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
assert_eq!(r.pay.captures(), 1);
assert_eq!(r.cloud.live_under("estate/acme"), 11);
}
/// ★ **G1 #14: the estate answers by calling home.** Monetize never dials an estate: an
/// installed estate whose boxes have sent no Fleet report since the install waits at
/// `paired`, its paid term not started, saying so; its first report starts the term.
#[test]
fn an_installed_estate_is_captured_only_once_its_boxes_have_called_home() {
let r = rig("calls-home");
r.kit.silent.store(true, Ordering::SeqCst);
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
super::drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::PAIRED, "{:#?}", run.history);
assert_eq!(
run.paid_until_ms, 0,
"the paid term does not start before the estate called home"
);
assert!(
run.why.contains("called home"),
"the wait is said: {}",
run.why
);
r.clock.fetch_add(60_000, Ordering::SeqCst);
calls_home(&r.state, "acme");
super::drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
assert_eq!(
run.paid_until_ms,
price::add_months(r.clock.load(Ordering::SeqCst), 6),
"the term runs from the call home"
);
assert!(
run.history
.iter()
.any(|t| t.phase == phase::CAPTURED
&& t.note.contains("called home (front, main, twin)")),
"{:#?}",
run.history
);
}
/// What a running box reports: a main says it serves its data (the S4 sale check).
fn running(role: &str) -> monetize_embed::fleet::Report {
// `node` is the primary of the parametric test product of `more_machines` (P3-FACTS).
if role == "main" || role == "node" {
report_saying(&[("serving", "yes"), ("data", "ok")])
} else {
Default::default()
}
}
/// A Fleet report whose health says `words`.
fn report_saying(words: &[(&str, &str)]) -> monetize_embed::fleet::Report {
monetize_embed::fleet::Report {
health: words
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect(),
..Default::default()
}
}
/// ★ **S4: the sale check is the estate's own word that it serves** (F4, the ONE model). A call
/// home alone is not a sale: a main that reports it does not serve, or that has no data yet (no
/// identity and no welcome repository: `data` = `fresh`), keeps the order at `paired`, its term
/// not started and the word that is missing said. The main's `serving` = `yes` and `data` = `ok`
/// in a report since the install began are the first half; the public front's proof is the
/// second ([`a_sale_whose_public_front_holds_no_welcome_repo_is_not_captured`]).
#[test]
fn a_sale_is_captured_only_once_the_estates_main_reports_it_serves_its_data() {
let r = rig("sale-check");
r.kit.silent.store(true, Ordering::SeqCst);
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
super::drive(&r.state, "acme");
let g = r
.state
.fleet
.guardian()
.expect("the in-memory guardian")
.clone();
let say = |main: &[(&str, &str)]| {
r.clock.fetch_add(60_000, Ordering::SeqCst);
let now = r.state.now();
g.store
.record_report("acme", "front", now, &report_saying(&[]))
.unwrap();
g.store
.record_report(
"acme",
"twin",
now,
&report_saying(&[("twin_state", "following")]),
)
.unwrap();
g.store
.record_report("acme", "main", now, &report_saying(main))
.unwrap();
super::drive(&r.state, "acme");
r.state.estates.get("acme").unwrap()
};
let run = say(&[("serving", "no"), ("data", "fresh")]);
assert_eq!(run.phase, phase::PAIRED, "{:#?}", run.history);
assert_eq!(
run.paid_until_ms, 0,
"the paid term does not start before the main serves"
);
assert!(
run.why.contains("serving") && run.why.contains("no"),
"the missing word is said: {}",
run.why
);
let run = say(&[("serving", "yes"), ("data", "fresh")]);
assert_eq!(
run.phase,
phase::PAIRED,
"a main with no data (no welcome repository) is no sale: {:#?}",
run.history
);
assert!(
run.why.contains("data") && run.why.contains("fresh"),
"{}",
run.why
);
let run = say(&[
("serving", "yes"),
("data", "ok"),
("serves_at", "10.44.0.2:50051"),
]);
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
assert_eq!(r.pay.captures(), 1, "the money is taken once");
assert_eq!(
run.paid_until_ms,
price::add_months(r.clock.load(Ordering::SeqCst), 6),
"the term runs from the main's word"
);
assert!(
run.history
.iter()
.any(|t| t.phase == phase::CAPTURED && t.note.contains("main serves")),
"{:#?}",
run.history
);
}
/// The sold instance's public front says `front`; the order is started, paid and driven to the
/// sale check, its boxes calling home and the main saying it serves its data (the shallow
/// check passes).
fn sale_checked(name: &str, front: FakeFront) -> Rig {
let r = rig(name);
*r.kit.front.lock().unwrap() = front;
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
r
}
/// ★ **S4: the sale check proves the PUBLIC front serves before anything is captured** (stinky
/// S4, 2026-10-11). RED before: the check was the main's own word (`serving`, `data`) and a call
/// home — an instance serving its login page while holding NO welcome repository was captured,
/// its term started and the buyer mailed a link to an estate that is not what was sold. Now the
/// installer looks at `https://<host>` — the login page, the first-login door, exactly ONE
/// `<account>/welcome` — and a front that does not prove all three keeps the order at
/// `paired`: no term, no ready mail, the miss said by name.
#[test]
fn a_sale_whose_public_front_holds_no_welcome_repo_is_not_captured() {
let r = sale_checked(
"s4-no-welcome",
FakeFront {
repos: vec![],
..FakeFront::default()
},
);
let run = r.state.estates.get("acme").unwrap();
assert_eq!(
run.phase,
phase::PAIRED,
"a front with no welcome repository is no sale: {:#?}",
run.history
);
assert_eq!(run.paid_until_ms, 0, "the term does not start");
assert!(
r.mails.count("estate.ready") == 0,
"the buyer is not sent to it: {:?}",
r.mails.kinds()
);
assert!(
run.why.contains("sale check") && run.why.contains("welcome"),
"the miss is said: {}",
run.why
);
// The front holds its welcome repository: the next look (not before SALE_CHECK_EVERY_MS)
// captures it.
*r.kit.front.lock().unwrap() = FakeFront::default();
drive(&r.state, "acme");
assert_eq!(
r.state.estates.get("acme").unwrap().phase,
phase::PAIRED,
"the front is not asked again at once"
);
r.clock.fetch_add(SALE_CHECK_EVERY_MS, Ordering::SeqCst);
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
assert_eq!(r.mails.count("estate.ready"), 1);
assert!(
run.history
.iter()
.any(|t| t.phase == phase::CAPTURED && t.note.contains("buyer/welcome")),
"what was proven is written: {:#?}",
run.history
);
}
/// ★ **F12: the operator's status names the capture step that holds a paired order**
/// (test3-holger-rs 2026-10-21: it stood `installing (paired)` and `site status` said no why).
/// Silent: step 1, the call home. Heard, its main not serving: step 2. Its main serving and its
/// public front not proving the sale: step 3, the sale check's own words. Captured: no hold.
#[test]
fn a_paired_orders_status_names_the_capture_step_that_holds_it() {
let words = |r: &Rig| {
r.state
.estates
.get("acme")
.unwrap()
.operator_view_as("gunnar.rs", &gw())
.1
};
let r = rig("f12-hold");
r.kit.silent.store(true, Ordering::SeqCst);
*r.kit.front.lock().unwrap() = FakeFront {
door: false,
..FakeFront::default()
};
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
super::drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::PAIRED);
let w = words(&r);
assert!(
w.contains("Why: held at step 1 of 3 (the call home)") && w.contains("called home"),
"{w}"
);
let g = r
.state
.fleet
.guardian()
.expect("the in-memory guardian")
.clone();
r.clock.fetch_add(60_000, Ordering::SeqCst);
let now = r.state.now();
for role in ["front", "twin"] {
g.store
.record_report("acme", role, now, &report_saying(&[]))
.unwrap();
}
g.store
.record_report(
"acme",
"main",
now,
&report_saying(&[("serving", "no"), ("data", "ok")]),
)
.unwrap();
super::drive(&r.state, "acme");
let w = words(&r);
assert!(
w.contains("Why: held at step 2 of 3 (the main's word that it serves)")
&& w.contains("serving = no"),
"{w}"
);
r.clock.fetch_add(60_000, Ordering::SeqCst);
g.store
.record_report(
"acme",
"main",
r.state.now(),
&report_saying(&[("serving", "yes"), ("data", "ok")]),
)
.unwrap();
super::drive(&r.state, "acme");
let w = words(&r);
assert!(
w.contains("Why: held at step 3 of 3 (the sale check)") && w.contains("first-login door"),
"{w}"
);
*r.kit.front.lock().unwrap() = FakeFront::default();
r.clock.fetch_add(SALE_CHECK_EVERY_MS, Ordering::SeqCst);
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
assert!(
!words(&r).contains("Why:"),
"a captured order is held by no step: {}",
words(&r)
);
assert_eq!(capture_hold(phase::INSTALLING, "anything"), None);
}
/// ★ **S4: each of the three is required** — a login page that does not answer, a first-login
/// door that does not answer, two welcome repositories, or the one at another account's
/// name: never captured.
#[test]
fn a_sale_is_not_captured_unless_the_login_page_the_door_and_exactly_one_welcome_repo_answer() {
for (name, front, said) in [
(
"s4-login",
FakeFront {
login: false,
..FakeFront::default()
},
"/login",
),
(
"s4-door",
FakeFront {
door: false,
..FakeFront::default()
},
"first-login door",
),
(
"s4-two",
FakeFront {
repos: vec!["buyer/welcome".into(), "operator/welcome".into()],
..FakeFront::default()
},
"2 welcome",
),
(
"s4-other",
FakeFront {
repos: vec!["operator/welcome".into()],
..FakeFront::default()
},
"buyer/welcome",
),
] {
let r = sale_checked(name, front);
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::PAIRED, "{name}: {:#?}", run.history);
assert_eq!(
(run.paid_until_ms, r.mails.count("estate.ready")),
(0, 0),
"{name}: no term, no ready mail"
);
assert!(run.why.contains(said), "{name}: {}", run.why);
}
}
/// ★ **S4: the check looks where the buyer will** — the public name `https://<company>.<apex>`,
/// the laid front's PUBLIC address (never the utility net), the order's account, and the very
/// invite and break-glass bearer the estate was fed; none of them is ever written down.
#[test]
fn the_sale_check_looks_at_the_public_front_with_the_invite_the_mail_will_carry() {
let r = rig("s4-where");
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
*r.kit.front.lock().unwrap() = FakeFront {
repos: vec!["alice/welcome".into()],
..FakeFront::default()
};
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
let checks = r.kit.sale_checks.lock().unwrap().clone();
assert_eq!(checks.len(), 1, "{checks:?}");
let front = run.laid.as_ref().unwrap().machine("front").unwrap().clone();
assert_eq!(
(
checks[0].host.as_str(),
checks[0].account.as_str(),
checks[0].front_ipv4.as_str()
),
("acme.gunnar.rs", "alice", front.public_ipv4.as_str())
);
assert_ne!(checks[0].front_ipv4, front.utility_ipv4);
assert_eq!(
checks[0].invite_sha,
r.kit.first_logins.lock().unwrap()[0].0,
"the invite the kit fed gunnar, the one the mail carries"
);
let handed = String::from_utf8(
r.kit.handed.lock().unwrap()[crate::custody::handoff::CONSOLE_TOKEN].clone(),
)
.unwrap();
assert_eq!(
checks[0].token_sha,
sha256_hex(&handed),
"the break-glass bearer the front was fed"
);
let file = std::fs::read_to_string(r.dir.join("estate-orders/acme/run.json")).unwrap();
assert!(
!file.contains(handed.trim()),
"the bearer is never in the run"
);
}
/// ★ **S4: no default yes** — an installer that proves no sale check captures nothing.
#[test]
fn an_installer_that_proves_no_sale_check_captures_nothing() {
struct Proves;
impl Installer for Proves {
fn install(&self, _: &InstallRequest) -> Result<InstallVerdict, String> {
Err("unused".into())
}
}
let dir = tmp("s4-default");
let run_dir = dir.join("run");
let facts = crate::facts::Facts::default();
let at = SaleCheckAt {
facts: &facts,
company: "acme",
host: "acme.gunnar.rs",
account: "buyer",
front: None,
run_dir: &run_dir,
console_token: "t0ken",
first_login: "inv1te",
};
let said = Proves.sale_check(&at).unwrap_err();
assert!(said.contains("no sale check"), "{said}");
let debug = format!("{at:?}");
assert!(
!debug.contains("t0ken") && !debug.contains("inv1te"),
"{debug}"
);
}
/// ★ **G1 #14, a resize**: the change is captured only once the resized estate's boxes call
/// home again — a report from before the resize is not an answer.
#[test]
fn a_resized_estate_is_captured_only_once_it_calls_home_again() {
let r = delivered("calls-home-again", cfg());
r.cloud
.plan_prices
.lock()
.unwrap()
.insert("STARTER-16xCPU-64GB".into(), 5_000);
let now = r.state.estates.get("acme").unwrap().paid_until_ms - 90 * DAY;
r.clock.store(now, Ordering::SeqCst);
let c = change::change(&r.state, "acme", &bigger_main()).unwrap();
r.pay.authorize(&c.handle.as_ref().unwrap().id);
r.clock.store(now + 60_000, Ordering::SeqCst);
super::drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert!(!r.cloud.plan_changes().is_empty(), "resized");
assert_eq!(
r.pay.captures(),
1,
"the change is not captured before the estate called home again"
);
assert!(
run.change.as_ref().unwrap().why.contains("call home"),
"{:#?}",
run.change
);
r.clock.store(now + 120_000, Ordering::SeqCst);
let run = at(&r, now + 120_000);
assert_eq!(
r.pay.captures(),
2,
"captured once the estate called home again"
);
assert!(run.change.is_none(), "{:#?}", run.change);
}
/// Past `capture_within_secs` of the hold, the job fails and releases.
#[test]
fn a_job_past_its_deadline_is_given_back_laid_again_then_owed() {
let r = rig("deadline");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault {
after: Some(1),
outage: true,
});
drive(&r.state, "acme");
r.clock.fetch_add((86_400 + 1) * 1_000, Ordering::SeqCst);
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(
run.phase,
phase::LAYING,
"given back and laid again: {:#?}",
run.history
);
assert!(
run.history
.iter()
.any(|t| t.note.contains("did not answer within")),
"{:#?}",
run.history
);
r.clock.fetch_add((86_400 + 1) * 1_000, Ordering::SeqCst);
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::OWED);
assert_eq!(r.cloud.live_under("estate/acme"), 0);
}
/// An unpaid page is given up after `order_ttl_secs`: nothing was held,
/// nothing is laid, and the name is free again.
#[test]
fn an_unpaid_page_expires_lays_nothing_and_frees_the_name() {
let r = rig("unpaid");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.clock.fetch_add(3_601 * 1_000, Ordering::SeqCst);
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::RELEASED);
assert!(r.cloud.lays().is_empty());
assert!(
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default()
)
.is_ok(),
"a released name can be ordered again"
);
}
/// Slots: with `max_open = 1`, a second held order waits ("queued") until the
/// first is no longer laying or installing.
#[test]
fn a_second_order_is_queued_while_the_slots_are_full() {
let r = rig_with(
"slots",
EstateOrderConfig {
max_open: 1,
..cfg()
},
"PASS",
);
start(
&r.state,
"acme",
"a@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
start(
&r.state,
"bolt",
"b@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.pay.authorize(&handle_of(&r, "bolt"));
r.cloud.lay_fails(LayFault {
after: Some(1),
outage: true,
});
drive(&r.state, "acme");
drive(&r.state, "bolt");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::LAYING);
let bolt = r.state.estates.get("bolt").unwrap();
assert_eq!(bolt.phase, phase::HELD);
assert!(bolt.why.starts_with("queued"), "{}", bolt.why);
assert_eq!(bolt.customer_view_as("gunnar.rs", &gw()).0, "queued");
r.cloud.lay_fails(LayFault::default());
drive(&r.state, "acme");
drive(&r.state, "bolt");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::CAPTURED);
assert_eq!(r.state.estates.get("bolt").unwrap().phase, phase::CAPTURED);
}
/// `Start` refuses by name, before any money moves.
#[test]
fn start_refuses_by_name_before_any_money_moves() {
let r = rig_with(
"refusals",
EstateOrderConfig {
max_estates: 2,
..cfg()
},
"PASS",
);
for bad in [
"Acme",
"acme-corp",
"www",
"git",
"test2",
"abcdefghijklmnopq",
] {
assert!(
matches!(
start(&r.state, bad, "x@example.com", "", &EstateSizes::default()),
Err(StartRefusal::BadName(_))
),
"{bad}"
);
}
assert!(matches!(
start(&r.state, "acme", "no-address", "", &EstateSizes::default()),
Err(StartRefusal::BadName(_))
));
start(
&r.state,
"acme",
"x@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
assert!(matches!(
start_for(
&r.state,
"acme",
"y@example.com",
"",
"somebody",
&EstateSizes::default()
),
Err(StartRefusal::Taken(_))
));
// F-B-01: the same buyer asking again is answered its own order, never a second hold.
assert!(start(
&r.state,
"acme",
"x@example.com",
"",
&EstateSizes::default()
)
.is_ok());
assert_eq!(
r.pay.0.requests.lock().unwrap().len(),
1,
"a refused order asked the vendor for nothing"
);
// A57: no resolver here, no own domain — refused before any money moves.
let mut blind = AppState::in_memory(Registry::new().sells("gunnar", r.pay.clone()));
blind.estates = EstateOrders::with(
cfg(),
r.dir.join("blind-orders"),
Arc::new(NoInstaller),
Arc::new(NoDns),
crate::custody::Custody::open(r.dir.join("blind-custody")).unwrap(),
);
let asked = r.pay.0.requests.lock().unwrap().len();
assert!(
matches!(start(&blind, "dora", "x@example.com", "gunnar.company9.se", &EstateSizes::default()), Err(StartRefusal::BadName(w)) if w.contains("cannot be used here"))
);
assert_eq!(
r.pay.0.requests.lock().unwrap().len(),
asked,
"nothing was asked of the vendor"
);
let off = rig_with("notsold", cfg(), "PASS");
let mut state = AppState::in_memory(Registry::new().sells("gunnar", off.pay.clone()));
state.estates = EstateOrders::default();
assert!(matches!(
start(&state, "acme", "x@example.com", "", &EstateSizes::default()),
Err(StartRefusal::NotSold(_))
));
}
/// ★ **S2 (trace-private 2026-10-09): a shop with no DNS writer sells nothing** — the sold
/// host would never resolve, the front's certificate never come, and the order would still be
/// captured and mailed "ready". `Sells` is false and `Start` is refused by name before any
/// money moves; a shop with a writer sells.
#[test]
fn a_shop_with_no_dns_writer_sells_nothing_and_takes_no_order() {
let r = rig_with("no-dns", cfg(), "PASS");
assert!(
super::ladder::sells_refresh(&r.state),
"the rig's shop writes its records: it sells"
);
let dir = tmp("no-dns-shop");
let kit = FakeKit::new("PASS");
let (none, _, _, _) = build_with(
&dir,
cfg(),
r.pay.clone(),
r.cloud.clone(),
kit,
Some(Arc::new(NoDns)),
None,
);
assert!(
!super::ladder::sells_refresh(&none),
"no DNS writer: Sells false"
);
let asked = r.pay.0.requests.lock().unwrap().len();
match start(&none, "acme", "x@example.com", "", &EstateSizes::default()) {
Err(StartRefusal::NotSold(w)) => assert_eq!(w, NO_DNS_WRITER),
other => panic!("{other:?}"),
}
assert_eq!(
r.pay.0.requests.lock().unwrap().len(),
asked,
"nothing was asked of the vendor"
);
// The writer's credential the kit FEEDS is sealed into the custody, the fed file removed;
// a fed file that is no credential is refused by name.
let custody = crate::custody::Custody::open(dir.join("seal-custody")).unwrap();
let secrets = dir.join("secrets");
std::fs::create_dir_all(&secrets).unwrap();
assert!(
!seal_fed_dns(&custody, &secrets, "cloudflare").unwrap(),
"nothing fed"
);
std::fs::write(
secrets.join("secret.dns_cloudflare"),
r#"{"zone_id":"z1","api_token":"t1"}"#,
)
.unwrap();
assert!(seal_fed_dns(&custody, &secrets, "cloudflare").unwrap());
assert_eq!(
custody.unseal_credential("dns.cloudflare").unwrap(),
br#"{"zone_id":"z1","api_token":"t1"}"#.to_vec()
);
assert!(
!secrets.join("secret.dns_cloudflare").exists(),
"the fed file is gone once sealed"
);
std::fs::write(secrets.join("secret.dns_cloudflare"), "not json").unwrap();
let e = seal_fed_dns(&custody, &secrets, "cloudflare").unwrap_err();
assert!(
e.contains("secret.dns_cloudflare") && !e.contains("not json"),
"{e}"
);
assert!(
!seal_fed_dns(&custody, &secrets, "").unwrap()
&& !seal_fed_dns(&custody, &secrets, "manual").unwrap()
);
}
/// ★ **S10 (owner 2026-10-11 05:53Z): a delivered estate's resend is a SIGNED ORDER its main
/// pulls** — the one link of the ready mail was lost or ran out. The shop queues a
/// `sign_in_again` order for the estate's main, signed by monetize's key: whose account, which
/// address, which host, how long the link lives — and NO secret. The estate verifies it, mints
/// the fresh invite itself and mails the link itself; the shop never holds the login secret of
/// a resend, mails nothing and asks no installer. Once per ten minutes (a newer order
/// supersedes an unacked older one); never before delivery. The FIRST link stays the shop's
/// (OM-21 decision A).
#[test]
fn a_delivered_estates_resend_is_a_signed_order_its_main_pulls_and_mints() {
let r = rig_with("sign-in-again", cfg(), "PASS");
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
assert!(
matches!(
send_sign_in_again(&r.state, "acme"),
Err(StartRefusal::NotNow(_))
),
"not delivered: nothing to sign in to"
);
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::CAPTURED);
let g = r.state.fleet.guardian().unwrap().clone();
let asked = |role: &str| {
g.store
.orders_for("acme", role, 0)
.into_iter()
.filter(|o| o.kind == monetize_embed::fleet::kind::SIGN_IN_AGAIN)
.collect::<Vec<_>>()
};
let mails = r.mails.kinds().len();
let words = send_sign_in_again(&r.state, "acme").expect("queued");
let host = cfg().host_of("acme");
assert!(
words.contains(&host) && words.contains("mints"),
"the buyer is told the estate mints and mails it: {words}"
);
let orders = asked("main");
assert_eq!(
orders.len(),
1,
"one signed order for acme's main: {orders:?}"
);
assert!(
asked("twin").is_empty() && asked("front").is_empty(),
"only the main mints"
);
let o = &orders[0];
let pk = ed25519_dalek::VerifyingKey::from_bytes(
&r.state
.signer_for(r.state.sold_product().unwrap())
.public_key(),
)
.unwrap();
monetize_embed::fleet::verify_order(
o,
&pk,
(r.state.sold_product().unwrap(), "acme", "main"),
r.clock.load(Ordering::SeqCst),
0,
)
.expect("signed by monetize's key, for acme's main");
let body: monetize_embed::fleet::SignInAgain = serde_json::from_str(&o.body).unwrap();
assert_eq!(
body,
monetize_embed::fleet::SignInAgain {
account: "alice".into(),
to: "buyer@example.com".into(),
host: host.clone(),
ttl_secs: cfg().first_login_ttl()
}
);
assert!(
!o.body.contains("invite") && !o.body.contains("secret"),
"the order carries no login secret: {}",
o.body
);
assert!(
o.not_after_unix_ms > r.clock.load(Ordering::SeqCst),
"the order is good for a while"
);
assert_eq!(
r.mails.kinds().len(),
mails,
"the shop mails nothing: the estate does: {:?}",
r.mails.kinds()
);
assert_eq!(r.mails.count("estate.sign_in_again"), 0);
let run = r.state.estates.get("acme").unwrap();
assert!(
run.history
.iter()
.any(|t| t.note.contains("sign_in_again") && t.note.contains("main")),
"{:#?}",
run.history
);
assert!(run.sign_in_again_at_ms > 0);
assert!(
matches!(
send_sign_in_again(&r.state, "acme"),
Err(StartRefusal::NotNow(_))
),
"once per ten minutes"
);
r.clock
.fetch_add(SIGN_IN_AGAIN_EVERY_MS + 1, Ordering::SeqCst);
send_sign_in_again(&r.state, "acme").expect("again after the wait");
let again = asked("main");
assert_eq!(
again.len(),
1,
"the newer order supersedes the unacked older one: {again:?}"
);
assert!(again[0].seq > o.seq);
assert!(matches!(
send_sign_in_again(&r.state, "nobody"),
Err(StartRefusal::NotFound(_))
));
}
/// S10: an estate the fleet does not hold as sold has no main that pulls — the resend is
/// refused in words, nothing queued, nothing mailed.
#[test]
fn a_resend_for_an_estate_the_fleet_does_not_hold_is_refused() {
let r = rig_with("sign-in-again-unheld", cfg(), "PASS");
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let g = r.state.fleet.guardian().unwrap().clone();
g.store.declare("acme", "someone-else").unwrap();
let mails = r.mails.kinds().len();
let e = send_sign_in_again(&r.state, "acme").unwrap_err();
assert!(
matches!(&e, StartRefusal::NotNow(w) if w.contains("pull")),
"{e:?}"
);
assert!(g
.store
.orders_for("acme", "main", 0)
.iter()
.all(|o| o.kind != "sign_in_again"));
assert_eq!(r.mails.kinds().len(), mails);
}
/// ★ **test2's one-DAY term** (the owner, 2026-10-08: a real purchase cheap to repeat): the
/// hold is the monthly price pro rata (`monthly × 1 / 30`, rounded up), the paid period one
/// day from the capture, the grace one HOUR; a reminder never comes (half a day is none) and
/// a renewal opens half the term before its end. Months stay months for gunnar.rs.
#[test]
fn a_one_day_term_holds_a_thirtieth_and_runs_a_day_with_an_hours_grace() {
let day = EstateOrderConfig {
term_days: 1,
term: TermPolicy {
grace_hours: 1,
..TermPolicy::default()
},
..cfg()
};
let r = rig_with("one-day", day.clone(), "PASS");
let q = quote(&r.state, "acme", &EstateSizes::default()).unwrap();
assert_eq!(
q.total.minor,
q.monthly.minor.div_ceil(30),
"a thirtieth of the month, rounded up: {}",
q.price_words()
);
assert!(
q.price_words().contains("1 day prepaid"),
"{}",
q.price_words()
);
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
assert_eq!(
run.paid_until_ms,
r.clock.load(Ordering::SeqCst) + DAY,
"paid for one day from the capture"
);
assert_eq!(day.term.grace_ms(), 3_600_000, "one hour's grace");
assert_eq!(day.term.grace_words(), "1 hour");
assert!(
day.term.remind_days_for(0, 1).is_empty(),
"a day's term has no reminder"
);
assert!(
day.term.check().is_ok(),
"deleted 60 days on: never inside the hour's grace"
);
assert_eq!(price::term_words(6, 0), "6 months");
assert_eq!(price::add_term(0, 6, 1), DAY, "a day is a day");
assert_eq!(
price::term_charge(3_000, 6, 0),
18_000,
"six months, as before"
);
}
/// ★ **No worker pulls a sale's install any more** (no-dwarf step 8, the owner 2026-10-08:
/// "DWARFS MUST NOT BE INVOLVED!"): a config that still names one is refused at start, by
/// name — never silently ignored.
#[test]
fn a_config_that_names_an_install_worker_is_refused_at_start() {
let dir = tmp("workers-removed");
let text = format!("data_dir = {:?}\n[estate_orders]\ncurrency = \"EUR\"\n[estate_orders.install_workers]\ndwarf = \"{}\"\n", dir.display().to_string(), "ab".repeat(32));
let cfg = crate::config::Config::from_toml(&text).unwrap();
let e = EstateOrders::from_config_with(&cfg, &crate::registry::Linked::default())
.err()
.expect("refused")
.to_string();
assert_eq!(e, WORKERS_REMOVED);
}
/// ★ **G14: the shop door is config, never made up** (one monetize, the owner 2026-10-10):
/// a sold estate calls the ONE monetize through the configured `shop_door`
/// (`<product>.monetize.ignalina.dk` in ops config) — no `monetize.<apex>` (the
/// shop's own web address) is made up when it is absent, and only an https URL
/// with a host is taken.
#[test]
fn the_shop_door_comes_from_config_and_nothing_else() {
let with = |door: &str| EstateOrderConfig {
apex: "gunnar.rs".into(),
shop_door: door.into(),
..EstateOrderConfig::default()
};
assert_eq!(with(DOOR).shop_door().unwrap(), DOOR);
assert_eq!(
with(&format!(" {DOOR}/ ")).shop_door().unwrap(),
DOOR,
"trimmed, no trailing slash"
);
for bad in [
"",
" ",
"http://monetize.ignalina.dk",
"https://",
"https:// x",
"monetize.ignalina.dk",
] {
let e = with(bad).shop_door().expect_err(bad);
assert!(
e.contains("[estate_orders] shop_door"),
"{bad:?} refused by name: {e}"
);
assert!(
!e.contains("monetize.gunnar.rs"),
"no door made up from the apex: {e}"
);
}
}
/// ★ **G14: a shop that sells with no door is refused at start**, by name —
/// never a sold estate laid with a made-up door.
#[test]
fn a_shop_without_a_door_is_refused_at_start() {
let dir = tmp("no-shop-door");
let text = format!("data_dir = {:?}\n[estate_orders]\ncurrency = \"EUR\"\napex = \"gunnar.rs\"\nproduct = \"gunnar\"\n", dir.display().to_string());
let cfg = crate::config::Config::from_toml(&text).unwrap();
let e = EstateOrders::from_config_with(&cfg, &crate::registry::Linked::default())
.err()
.expect("refused")
.to_string();
assert!(e.contains("[estate_orders] shop_door"), "{e}");
let text = format!("{text}shop_door = \"{DOOR}\"\n");
let cfg = crate::config::Config::from_toml(&text).unwrap();
EstateOrders::from_config_with(&cfg, &crate::registry::Linked::default())
.expect("a configured door starts");
}
/// ★ **OM-4: the product a sold estate is comes from config, never a
/// hard-coded "gunnar"** (ONE monetize, the owner 2026-10-10): test2's sold
/// estates would book their growth, fleet lane and accounts under PROD
/// gunnar's product. `[estate_orders] product` names it; unset, the one
/// `[pricing.<product>]` on the box is it; unset on a box that prices
/// several (or none), the start is refused by name — never "gunnar" made up.
#[test]
fn the_sold_product_is_named_or_the_one_priced_and_never_made_up() {
let dir = tmp("sold-product");
let base = format!("data_dir = {:?}\n", dir.display().to_string());
let orders = |body: &str| {
let cfg = crate::config::Config::from_toml(&format!("{base}{body}")).unwrap();
EstateOrders::from_config_with(&cfg, &crate::registry::Linked::default())
};
let eo = format!("[estate_orders]\ncurrency = \"EUR\"\nshop_door = \"{DOOR}\"\n");
let o = orders(&format!("{eo}product = \"test2gunnar\"\n")).expect("a named product starts");
assert_eq!(
o.cfg.as_ref().unwrap().sold_product().unwrap(),
"test2gunnar",
"named: taken as it is"
);
let o = orders(&format!("[pricing.test2gunnar]\n{eo}")).expect("one priced product starts");
assert_eq!(
o.cfg.as_ref().unwrap().sold_product().unwrap(),
"test2gunnar",
"unset: the one priced product is it"
);
let e = orders(&format!("[pricing.gunnar]\n[pricing.other]\n{eo}"))
.err()
.expect("several priced, none named: refused")
.to_string();
assert!(
e.contains("[estate_orders] product") && e.contains("gunnar") && e.contains("other"),
"refused by name, the choices listed: {e}"
);
let e = orders(&eo)
.err()
.expect("none priced, none named: refused")
.to_string();
assert!(e.contains("[estate_orders] product"), "{e}");
assert!(!e.contains("\"gunnar\""), "no product made up: {e}");
}
/// ★ **G12: the twin is never read by running a command** (2026-10-10): a config that still
/// names `[estate_orders] twin_health` (the kit's argv, `cargo xtask … estate twin-health`) is
/// refused at start, by name — never run, never silently ignored.
#[test]
fn a_config_that_names_a_twin_health_command_is_refused_at_start() {
let dir = tmp("twin-command-removed");
let text = format!("data_dir = {:?}\n[estate_orders]\ncurrency = \"EUR\"\ntwin_health = [\"cargo\", \"xtask\", \"estate\", \"twin-health\"]\n", dir.display().to_string());
let cfg = crate::config::Config::from_toml(&text).unwrap();
let e = EstateOrders::from_config_with(&cfg, &crate::registry::Linked::default())
.err()
.expect("refused")
.to_string();
assert!(
e.starts_with("[estate_orders] twin_health is REMOVED"),
"{e}"
);
}
/// ★ **G12: a shop reads its twins from the estates' own reports** — the source a loaded shop
/// watches through is the pull channel's store (no door dialled, no command run).
#[test]
fn a_loaded_shop_reads_its_twins_from_the_estates_reports() {
let dir = tmp("twin-reported");
let cfg = crate::config::Config::from_toml(&format!("data_dir = {:?}\n[estate_orders]\ncurrency = \"EUR\"\nproduct = \"gunnar\"\nshop_door = \"{DOOR}\"\n", dir.display().to_string())).unwrap();
let orders =
EstateOrders::from_config_with(&cfg, &crate::registry::Linked::default()).expect("loads");
let store = monetize_guardian::Store::in_memory().unwrap();
let review =
serde_json::json!({"state": "following", "primary_head_seq": 1_042, "applied_seq": 1_000})
.to_string();
store
.record_report(
"acme",
"main",
5,
&monetize_embed::fleet::Report {
twin_review: Some(review),
..Default::default()
},
)
.unwrap();
let run = dir.join("estate-orders/acme");
std::fs::create_dir_all(&run).unwrap();
let gunnars = crate::facts::TwinFacts {
role: "twin".into(),
mirrors: "main".into(),
};
let at = twin::SampleAt {
company: "acme",
apex: "gunnar.rs",
now_ms: 9,
run_dir: &run,
reports: Some(&store),
every_ms: 600_000,
twin: &gunnars,
};
assert_eq!(
orders.twin_health.samples(&at),
Ok(vec![twin::TwinSample {
at_ms: 9,
lag_entries: 42,
cpu_millicores_busy: 0,
cpu_millicores: 0
}]),
"the estate's report is the source"
);
}
/// ★ **The Sells rule: no install path, no sale** (2026-10-08): a shop whose `[estate_orders]`
/// names no pairing, installer or worker answers Sells false however its steps price, and a
/// Start is refused before any money moves; with an install path the same shop sells.
#[test]
fn a_shop_with_no_install_path_sells_nothing_and_takes_no_order() {
let r = rig_with("sells-rule", cfg(), "PASS");
assert!(
super::ladder::sells_refresh(&r.state),
"the rig's shop installs: it sells"
);
let mut none = AppState::in_memory(
Registry::new()
.sells("gunnar", r.pay.clone())
.cloud(r.cloud.clone())
.shared_product(shop_product())
.ticket_key("gunnar", &shop_key_hex()),
);
none.estates = EstateOrders::with(
cfg(),
r.dir.join("no-path-orders"),
Arc::new(NoInstaller),
Arc::new(NoDns),
crate::custody::Custody::open(r.dir.join("no-path-custody")).unwrap(),
);
assert!(
!super::ladder::sells_refresh(&none),
"no install path: Sells false"
);
let asked = r.pay.0.requests.lock().unwrap().len();
match start(&none, "acme", "x@example.com", "", &EstateSizes::default()) {
Err(StartRefusal::NotSold(w)) => assert_eq!(
w,
no_install_path(&crate::testing::lifecycles::gunnar_words())
),
other => panic!("{other:?}"),
}
assert_eq!(
r.pay.0.requests.lock().unwrap().len(),
asked,
"nothing was asked of the vendor"
);
}
/// ★ **A09: `max_estates` never refuses a buyer** (the owner, 2026-10-08:
/// "accepted, paid and queued, the operator told"). test2 sells ONE estate at
/// a time: a second buyer's order is taken and held; it waits in `held` — the
/// buyer reads "being prepared", never a count or a limit — while the first
/// stands, and the operator reads "orders wait: raise max_estates".
#[test]
fn an_order_past_max_estates_is_taken_and_waits_never_refused() {
let r = rig_with(
"max-estates",
EstateOrderConfig {
max_estates: 1,
max_open: 1,
..cfg()
},
"PASS",
);
start_for(
&r.state,
"acme",
"a@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
start_for(
&r.state,
"bolt",
"b@example.com",
"",
"bob",
&EstateSizes::default(),
)
.expect("a second order is taken, not refused");
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::CAPTURED);
r.pay.authorize(&handle_of(&r, "bolt"));
drive(&r.state, "bolt");
let bolt = r.state.estates.get("bolt").unwrap();
assert_eq!(bolt.phase, phase::HELD, "{:#?}", bolt.history);
assert!(
bolt.why.starts_with(ORDERS_WAIT_ESTATES) && bolt.why.contains("1 of 1"),
"the operator's words: {}",
bolt.why
);
let (state, words, _) = bolt.customer_view_as(&cfg().apex, &gw());
assert_eq!(state, "queued");
assert!(
words.contains("being prepared")
&& !words.contains("1 of 1")
&& !words.to_lowercase().contains("max"),
"the buyer reads no limit: {words}"
);
assert_eq!(r.cloud.lays().len(), 1, "only acme was laid");
// The operator raises max_estates (a restart over the same runs): bolt is laid.
let (state, clock, _, _) = build(
&r.dir,
EstateOrderConfig {
max_estates: 2,
max_open: 1,
..cfg()
},
r.pay.clone(),
r.cloud.clone(),
r.kit.clone(),
);
clock.store(
r.clock.load(Ordering::SeqCst) + QUEUE_LOOK_EVERY_MS + 1,
Ordering::SeqCst,
);
drive(&state, "bolt");
let bolt = state.estates.get("bolt").unwrap();
assert_eq!(bolt.phase, phase::CAPTURED, "{:#?}", bolt.history);
assert!(
bolt.history
.iter()
.any(|t| t.note.contains("the queue admits it")),
"{:#?}",
bolt.history
);
}
/// **First ordered, first laid** (the UpCloud mockup's test2 row, 2026-10-08):
/// two paid orders for test2's ONE estate — whichever the driver looks at
/// first, the one ordered first is laid, and the other waits for max_estates.
#[test]
fn the_order_placed_first_is_laid_first() {
let r = rig_with(
"fifo",
EstateOrderConfig {
max_estates: 1,
max_open: 1,
..cfg()
},
"PASS",
);
start_for(
&r.state,
"cora",
"c@example.com",
"",
"carol",
&EstateSizes::default(),
)
.unwrap();
r.clock.fetch_add(1_000, Ordering::SeqCst);
start_for(
&r.state,
"eva",
"e@example.com",
"",
"eve",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "cora"));
r.pay.authorize(&handle_of(&r, "eva"));
// Both paid; the driver happens to look at eva first, and cora is held.
{
let _pen = r.state.estates.pen("cora");
let mut cora = r.state.estates.get("cora").unwrap();
cora.phase = phase::HELD.into();
cora.captured_at_ms = r.clock.load(Ordering::SeqCst);
cora.held_at_ms = cora.captured_at_ms;
save(&r.state, &cora).unwrap();
}
drive(&r.state, "eva");
let eva = r.state.estates.get("eva").unwrap();
assert_eq!(
eva.phase,
phase::HELD,
"eva waits behind cora: {:#?}",
eva.history
);
assert!(
eva.why.contains("queued behind cora.gunnar.rs"),
"{}",
eva.why
);
drive(&r.state, "cora");
assert_eq!(r.state.estates.get("cora").unwrap().phase, phase::CAPTURED);
let now = r.clock.load(Ordering::SeqCst);
let eva = at_of(&r, "eva", now + QUEUE_LOOK_EVERY_MS + 1);
assert_eq!(eva.phase, phase::HELD);
assert!(
eva.why.starts_with(ORDERS_WAIT_ESTATES),
"now it waits for max_estates: {}",
eva.why
);
assert_eq!(r.cloud.lays(), vec!["estate/cora".to_string()]);
}
/// ★ **The shop's own pairing: seeds minted at the payment, handed to each machine as its
/// user_data at the lay, forgotten at the hand-off** (no operator machine in a sale,
/// 2026-10-08): the front gets the front's seed, main and the twin gunnar's; the seeds live in
/// the custody only (never the run, the plan kept, a log); after the hand-off they are gone.
#[test]
fn the_shops_own_seeds_reach_each_machine_as_user_data_and_go_at_the_hand_off() {
let r = rig("seeds");
r.kit.mints.store(true, Ordering::SeqCst);
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let custody = r.state.estates.custody.as_ref().unwrap();
let given = r.cloud.last_user_data();
assert_eq!(given.len(), 3, "{given:?}");
for (role, len, seedlike) in &given {
assert!(
*len > 0 && *seedlike,
"{role} was handed no seed: {given:?}"
);
}
let run = r.state.estates.get("acme").unwrap();
assert!(
!serde_json::to_string(&run)
.unwrap()
.contains("kind = \"front\""),
"no seed in the run"
);
assert_eq!(run.phase, phase::CAPTURED);
let now = r.clock.load(Ordering::SeqCst);
let _ = at(&r, now + 60_000);
assert!(
!custody.holds("acme"),
"after the hand-off the seeds are gone with every other secret"
);
// A kit installer mints nothing: no user_data.
let k = rig("seeds-kit");
start_for(
&k.state,
"bolt",
"b@example.com",
"",
"bob",
&EstateSizes::default(),
)
.unwrap();
k.pay.authorize(&handle_of(&k, "bolt"));
drive(&k.state, "bolt");
assert!(
k.cloud.last_user_data().iter().all(|(_, len, _)| *len == 0),
"{:?}",
k.cloud.last_user_data()
);
}
/// ★ **A paired estate is laid from the release's seedless media** (no-dwarf steps 3/4,
/// 2026-10-08): each machine is cloned from its KIND's medium — the front's, gunnar's for main
/// and the twin — and a shop that pairs the estate itself with no medium for a kind refuses to
/// start, by name.
#[test]
fn a_paired_estate_is_laid_from_the_releases_media_and_none_missing_is_refused() {
let media: BTreeMap<String, String> = [
("front".to_string(), "01-front-release".to_string()),
("gunnar".to_string(), "01-gunnar-release".to_string()),
]
.into();
let r = rig_with(
"media",
EstateOrderConfig {
media: media.clone(),
..cfg()
},
"PASS",
);
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let laid: BTreeMap<String, String> = r.cloud.last_media().into_iter().collect();
assert_eq!(
laid.get("front").map(String::as_str),
Some("01-front-release"),
"{laid:?}"
);
assert_eq!(
laid.get("main").map(String::as_str),
Some("01-gunnar-release"),
"{laid:?}"
);
assert_eq!(
laid.get("twin").map(String::as_str),
Some("01-gunnar-release"),
"{laid:?}"
);
let run = r.state.estates.get("acme").unwrap();
assert_eq!(run.phase, phase::CAPTURED, "{:#?}", run.history);
let clones: std::collections::BTreeSet<String> = run
.laid
.as_ref()
.unwrap()
.machines
.iter()
.map(|m| m.medium_clone.clone())
.collect();
assert!(
clones.len() == 3 && !clones.contains(""),
"one clone per machine: {clones:?}"
);
assert!(run.told, "handed over: the ready mail went");
assert!(
r.cloud.standing_clones().is_empty(),
"after the hand-off the release clones are given back: {:?}",
r.cloud.standing_clones()
);
assert!(
run.media_forgotten_at_ms > 0
&& run
.history
.iter()
.any(|t| t.note.contains("release clones are given back")),
"{:#?}",
run.history
);
// ★ The seeds rode the user_data: after the hand-off no laid machine serves it any more.
let servers: std::collections::BTreeSet<String> = run
.laid
.as_ref()
.unwrap()
.machines
.iter()
.map(|m| m.server.clone())
.collect();
let off: std::collections::BTreeSet<String> = r.cloud.metadata_off().into_iter().collect();
assert_eq!(
off, servers,
"every laid machine's metadata is off after the hand-off"
);
assert!(
run.history
.iter()
.any(|t| t.note.contains("metadata is off")),
"{:#?}",
run.history
);
let mut c = cfg();
c.pairing = "shop-pairing".into();
let why = media_missing(&c).expect("no media: refused");
assert!(
why.contains("front and gunnar") && why.contains("release-image"),
"{why}"
);
c.media = [("front".to_string(), "01-front-release".to_string())].into();
assert!(
media_missing(&c).unwrap().contains("for gunnar:"),
"{}",
media_missing(&c).unwrap()
);
c.media = media;
assert!(media_missing(&c).is_none());
}
/// ★ **A failed install gives its release clones back too** (no-dwarf step 4): they carry
/// no label of the estate, so the label walk would miss them; the lay journal names them.
#[test]
fn a_failed_install_gives_its_release_clones_back() {
let media: BTreeMap<String, String> = [
("front".to_string(), "01-front-release".to_string()),
("gunnar".to_string(), "01-gunnar-release".to_string()),
]
.into();
let r = rig_with("media-fail", EstateOrderConfig { media, ..cfg() }, "FAIL");
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert!(
r.cloud.standing_clones().is_empty(),
"the give-back took the clones: {:?} {:#?}",
r.cloud.standing_clones(),
run.history
);
assert!(
run.history
.iter()
.any(|t| t.note.contains("release clones are given back")),
"{:#?}",
run.history
);
}
/// ★ **A failed LAY gives its release clones back too** (code-smell review 2026-10-10,
/// finding 2): a lay refused after it cloned leaves no laid estate, and its journal is set
/// aside before the next lay — so the give-back asks the cloud for the journal's clones
/// (and the clones it only intended) with the estate as it stands, before that.
#[test]
fn a_failed_lay_gives_its_release_clones_back() {
let media: BTreeMap<String, String> = [
("front".to_string(), "01-front-release".to_string()),
("gunnar".to_string(), "01-gunnar-release".to_string()),
]
.into();
let r = rig_with(
"media-lay-fail",
EstateOrderConfig { media, ..cfg() },
"PASS",
);
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
r.cloud.lay_fails(LayFault {
after: Some(4),
outage: false,
});
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(
phases(&run),
vec!["ordered", "held", "laying", "failed", "held", "laying", "failed", "owed"],
"{:#?}",
run.history
);
assert!(run.laid.is_none(), "nothing was laid");
assert_eq!(
r.cloud.live_under("estate/acme"),
0,
"no billed resource is left under the reference"
);
assert!(
r.cloud.standing_clones().is_empty(),
"the failed lays' release clones were given back: {:?} {:#?}",
r.cloud.standing_clones(),
run.history
);
}
/// ★ **The shop's own pairing is a LINKED installer** (no operator machine in a sale,
/// 2026-10-08): `pairing = "<name>"` builds what the build links under that name and hands it
/// the order like any installer; a build that links none of that name refuses by name, and
/// naming both a pairing and a kit installer is refused.
#[test]
fn the_shops_own_pairing_is_a_linked_installer_refused_by_name_where_none_is_linked() {
let mut c = cfg();
c.pairing = "shop-pairing".into();
let open = crate::registry::Linked::default();
let e = linked_installer(&c, &open, std::path::Path::new("/tmp"))
.err()
.expect("refused");
assert!(
e.contains("pairing = \"shop-pairing\"") && e.contains("links none"),
"{e}"
);
let mut linked = crate::registry::Linked::default();
fn build(_: &crate::registry::InstallerBuild<'_>) -> Result<Arc<dyn Installer>, String> {
Ok(Arc::new(NoInstaller))
}
linked.installer(crate::registry::InstallerFactory {
name: "shop-pairing",
build,
});
assert_eq!(linked.installer_names(), vec!["shop-pairing"]);
assert!(
linked_installer(&c, &linked, std::path::Path::new("/tmp")).is_ok(),
"the linked one is built"
);
c.pairing = "other".into();
assert!(linked_installer(&c, &linked, std::path::Path::new("/tmp"))
.err()
.unwrap()
.contains("it links shop-pairing"));
}
/// ★ **Two paid orders driven at once: one is laid, the other waits for `max_estates`**
/// (the UpCloud mockup run 4, 2026-10-08: eva and cora were both laid past test2's
/// one estate — each read the other as not yet laying). The admission is one at a time,
/// and the admitted order reads LAYING to every other before the lock goes.
#[test]
fn two_orders_driven_at_once_never_pass_max_estates() {
for round in 0..8 {
let r = rig_with(
&format!("admit-{round}"),
EstateOrderConfig {
max_estates: 1,
max_open: 2,
..cfg()
},
"PASS",
);
start_for(
&r.state,
"cora",
"c@example.com",
"",
"carol",
&EstateSizes::default(),
)
.unwrap();
start_for(
&r.state,
"eva",
"e@example.com",
"",
"eve",
&EstateSizes::default(),
)
.unwrap();
for co in ["cora", "eva"] {
r.pay.authorize(&handle_of(&r, co));
let _pen = r.state.estates.pen(co);
let mut run = r.state.estates.get(co).unwrap();
run.phase = phase::HELD.into();
run.captured_at_ms = r.clock.load(Ordering::SeqCst);
run.held_at_ms = run.captured_at_ms;
save(&r.state, &run).unwrap();
}
let go = Arc::new(std::sync::Barrier::new(2));
let threads: Vec<_> = ["cora", "eva"]
.into_iter()
.map(|co| {
let (state, go) = (r.state.clone(), go.clone());
std::thread::spawn(move || {
go.wait();
drive(&state, co);
})
})
.collect();
for t in threads {
t.join().unwrap();
}
assert_eq!(
r.cloud.lays().len(),
1,
"round {round}: one estate at a time: {:?}",
r.cloud.lays()
);
let waiting: Vec<String> = ["cora", "eva"]
.iter()
.map(|c| r.state.estates.get(c).unwrap())
.filter(|run| run.phase == phase::HELD)
.map(|run| run.company)
.collect();
assert_eq!(waiting.len(), 1, "round {round}: the other waits");
}
}
fn at_of(r: &Rig, company: &str, ms: u64) -> EstateRun {
r.clock.store(ms, Ordering::SeqCst);
drive(&r.state, company);
r.state.estates.get(company).unwrap()
}
/// **No secret leaves the custody**: not into the run file, the journal, the
/// installer's log, the DNS file or the customer's view.
#[test]
fn no_estate_secret_reaches_the_run_file_the_journal_or_a_log() {
let r = rig("nosecret");
start_for(
&r.state,
"acme",
"buyer@example.com",
"",
"alice",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
// The secrets as the ESTATE got them (the shop forgets its own copies
// after the hand-off): the seed, the pairing seed, the break-glass bearer,
// the client seed and — it leaves only in the "ready" mail — the buyer's
// first-login invite. G16 (ONE monetize): no backup key of a monetize of
// its own — it runs none.
let hex = |b: &[u8]| b.iter().map(|x| format!("{x:02x}")).collect::<String>();
let handed = r.kit.handed.lock().unwrap().clone();
let text = |f: &str| {
String::from_utf8(
handed
.get(f)
.cloned()
.unwrap_or_else(|| panic!("{f} was handed")),
)
.unwrap()
.trim()
.to_string()
};
use crate::custody::handoff as h;
assert!(
!handed.contains_key("monetize-backup-kek"),
"no monetize of its own, so no backup key for one: {:?}",
handed.keys()
);
let secrets = [
hex(handed.get(h::ROOT_SEED).expect("the seed")),
text(h::PAIRING_SEED),
text(h::CONSOLE_TOKEN),
text(h::FIRST_LOGIN),
text(h::ESTATE_CLIENT),
"kitminted".to_string(),
"readerkey".to_string(),
];
let run = r.state.estates.get("acme").unwrap();
let view = format!("{:?}", run.customer_view_as("gunnar.rs", &gw()));
let mut haystacks = vec![view, serde_json::to_string(&run).unwrap()];
for f in [
"estate-orders/acme/run.json",
"estate-orders/acme/journal",
"estate-orders/acme/install.log",
"estate-orders/acme/laid.json",
"dns.json",
"custody/acme.sealed",
"custody/acme.reader.sealed",
] {
haystacks.push(std::fs::read_to_string(r.dir.join(f)).unwrap_or_default());
}
for secret in &secrets {
for h in &haystacks {
assert!(
!h.contains(secret.as_str()),
"a secret reached a file or a view"
);
}
}
}
#[test]
fn the_plan_is_the_kits_declaration_for_an_instance() {
let p = plan_for(&cfg(), "acme", &EstateSizes::default(), "STARTER-1xCPU-4GB");
p.check().unwrap();
let main = p.machines.iter().find(|m| m.role == "main").unwrap();
assert_eq!(main.hostname, "gunnar-appliance-acme");
assert_eq!(main.title, "gunnar appliance — the forge, no shell-acme");
assert_eq!(main.disks[1].title, "gunnar-appliance-acme data 1");
assert_eq!(
main.disks[1].labels.get("volume").map(String::as_str),
Some("data1")
);
assert_eq!(
main.labels.get("role").map(String::as_str),
Some("appliance")
);
let twin = p.machines.iter().find(|m| m.role == "twin").unwrap();
assert_eq!(twin.disks[1].title, "gunnar-twin-acme data");
assert_eq!(twin.disks[1].tier, "hdd");
assert_eq!(
twin.disks[1].gib, 40,
"the twin's data disk holds main's whole data set (4 × 10)"
);
}
#[test]
fn the_dns_records_never_name_the_serving_estate() {
let ok = records_for("acme", "gunnar.rs", "203.0.113.5").unwrap();
assert_eq!(
ok.len(),
3,
"G16: acme., www.acme., git.acme. — no monetize of its own: {ok:?}"
);
assert!(ok.iter().all(|r| r.kind == "A" && !r.proxied));
// A company called `git` is refused by the name rule; the record guard is the belt.
assert!(
records_for("git", "gunnar.rs", "203.0.113.5").is_err(),
"git.gunnar.rs is the serving estate's forge"
);
}
// ── the owner's 18:00 rules: price, term, domains, many estates ─────────────
/// **20 % buys; 9.9 % is refused before any machine exists.** The provider's
/// price is read again at the buy: when it rose so far that the quoted price
/// would leave under 10 %, nothing is bought, the hold is released, and the
/// buyer is told why in one sentence.
#[test]
fn twenty_percent_buys_and_nine_point_nine_percent_is_refused_before_any_machine_exists() {
// 20 %: the price did not move.
let r = rig("margin20");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::CAPTURED);
// Under the floor: every resource went from 10.00 to 10.92 EUR between the
// quote and the buy — 132.00 over 120.12 is 9.89 % before the payment fee
// and 8.2 % after it (the six months are one charge: 0.25 + 1.5 %).
let r = rig("margin99");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
*r.cloud.price_minor.lock().unwrap() = Some(1_092);
drive(&r.state, "acme");
let run = r.state.estates.get("acme").unwrap();
assert_eq!(
phases(&run),
vec!["ordered", "held", "laying", "failed", "held", "laying", "failed", "owed"],
"{:#?}",
run.history
);
assert!(r.cloud.lays().is_empty(), "no machine was asked for");
assert_eq!(r.cloud.live_under("estate/acme"), 0, "no machine exists");
assert_eq!(
(r.pay.captures(), r.pay.refunds()),
(1, 0),
"paid at the order; the operator decides (refund or retry)"
);
let said = run
.history
.iter()
.find(|t| t.phase == phase::FAILED)
.unwrap()
.note
.clone();
assert!(
said.contains("rose to 120.12 EUR")
&& said.contains("after the payment fee would be 8.2 %")
&& said.contains("nothing was bought"),
"{said}"
);
// Just over 10 % AFTER the fee: 10.74 a resource (118.14 a month) leaves
// 10.02 % of the 792.00 charge less its 12.13 fee — bought. (10.90 left
// 10.09 % before the fee and 8.4 % after it: not since 2026-10-05.)
let r = rig("margin10");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
*r.cloud.price_minor.lock().unwrap() = Some(1_074);
drive(&r.state, "acme");
assert_eq!(r.state.estates.get("acme").unwrap().phase, phase::CAPTURED);
let r = rig("margin10-after-fee");
start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
r.pay.authorize(&handle_of(&r, "acme"));
*r.cloud.price_minor.lock().unwrap() = Some(1_075);
drive(&r.state, "acme");
assert_eq!(
r.state.estates.get("acme").unwrap().phase,
phase::OWED,
"10.75 a resource: under 10 % after the fee — nothing bought"
);
}
/// A margin configured under the floor sells nothing: `Start` refuses before
/// the vendor is asked for anything.
#[test]
fn a_margin_configured_under_the_floor_sells_nothing() {
let r = rig_with(
"thin",
EstateOrderConfig {
margin_bp: 990,
..cfg()
},
"PASS",
);
let e = start(
&r.state,
"acme",
"buyer@example.com",
"",
&EstateSizes::default(),
)
.unwrap_err();
assert!(
matches!(&e, StartRefusal::Price(w) if w.contains("under the floor")),
"{e:?}"
);
assert!(r.pay.0.requests.lock().unwrap().is_empty());
}
/// **Priced in EUR, the provider's currency, with no exchange rate in our
/// code** (owner, 2026-10-04 19:45): an offer in another currency than the
/// provider's is refused, never converted; Stripe shows the buyer SEK/DKK.
#[test]
fn a_private_gunnar_is_priced_in_the_providers_currency_and_nothing_is_converted() {
assert_eq!(
EstateOrderConfig::default().currency,
"EUR",
"the offer is in EUR by default"
);
let r = rig_with(
"dkk",
EstateOrderConfig {
currency: "DKK".into(),
..cfg()
},
"PASS",
);
assert!(
matches!(start(&r.state, "acme", "b@example.com", "", &EstateSizes::default()), Err(StartRefusal::Price(w)) if w.contains("no conversion"))
);
assert!(
r.pay.0.requests.lock().unwrap().is_empty(),
"nothing was asked of the vendor"
);
let r = rig("eur");
let run = start(
&r.state,
"acme",
"b@example.com",
"",
&EstateSizes::default(),
)
.unwrap();
assert_eq!(
run.quote.cost_in_sale,
Money {
minor: 11_000,
currency: monetize_pay::Currency::Eur
},
"the provider's EUR, as it is"
);
assert_eq!(
r.pay.0.requests.lock().unwrap()[0].market,
Market::Fi,
"EUR is the hold's currency"
);
}
/// **The buyer sizes main and front; the twin follows.** A main of 64 cores
/// gets a twin of 8 (an eighth, never under one core and 4 GiB), whose data
/// disk holds main's whole data set.
#[test]
fn the_buyer_sizes_main_and_front_and_the_twin_follows_main() {
let r = rig("sizes");
let sizes = EstateSizes {
front_plan: "STARTER-2xCPU-4GB".into(),
main_plan: "HIMEM-64xCPU-256GB".into(),
main_data_gib: 100,
..Default::default()
};
let q = quote(&r.state, "acme", &sizes).unwrap();
assert_eq!(q.twin_plan, "STARTER-8xCPU-32GB");
let twin = q.machines.iter().find(|m| m.role == "twin").unwrap();
assert_eq!(
(twin.cores, twin.disks_gib[1]),
(8, 400),
"8 cores; 4 × 100 GB of main's data"
);
let main = q.machines.iter().find(|m| m.role == "main").unwrap();
assert_eq!(
(main.cores, main.memory_mib, main.disks_gib.clone()),
(64, 256 * 1024, vec![50, 100, 100, 100, 100])
);
// Bigger disks cost more: 3 servers + 8 disks priced, + 20 %.
assert_eq!(
q.monthly.minor, 13_200,
"the mock prices every resource alike; the shape is what changed"
);
assert!(
matches!(quote(&r.state, "acme", &EstateSizes { main_plan: "NO-SUCH-PLAN".into(), ..EstateSizes::default() }), Err(StartRefusal::Price(w)) if w.contains("does not sell"))
);
// The choices the page offers are the provider's plans, smallest first.
let names: Vec<&str> = q.offered.iter().map(|p| p.name.as_str()).collect();
The file goes on; the console shows all of it.