liminal-server 0.25.4

Standalone server for the liminal messaging bus
Documentation
//! SRV-041 R4: the first pass issue a boot leaves for after its bind.
use super::super::fixture::{Fixture, NOW, Result};
use super::StartIssue;
use crate::link::LinkAction;
use std::sync::atomic::Ordering;

fn issued(issue: std::thread::JoinHandle<()>) -> Result {
    issue.join().map_err(|_| "the pass issue panicked")?;
    Ok(())
}

#[test]
fn the_start_issue_holds_the_pass_and_the_first_open_asks_nothing() -> Result {
    let fixture = Fixture::unissued(false)?;
    issued(StartIssue::new(fixture.authority.clone(), NOW).begin()?)?;
    assert_eq!(fixture.calls.load(Ordering::Relaxed), 1);
    let opened = fixture
        .session()?
        .open_link(&Fixture::link(), LinkAction::Export, NOW);
    assert!(opened.is_ok(), "the open after the issue was refused");
    assert_eq!(
        fixture.calls.load(Ordering::Relaxed),
        1,
        "the open asked for a pass already held"
    );
    fixture.finish()
}

#[test]
fn an_open_during_the_start_issue_waits_for_it_and_is_served_by_it() -> Result {
    let (fixture, hold) = Fixture::unissued_held()?;
    let issue = StartIssue::new(fixture.authority.clone(), NOW).begin()?;
    // The issue is inside Lys and holds the authority's lock.
    hold.entered.recv()?;
    let session = fixture.session()?;
    let open = std::thread::spawn(move || {
        session
            .open_link(&Fixture::link(), LinkAction::Export, NOW)
            .is_ok()
    });
    hold.release.send(())?;
    issued(issue)?;
    assert!(
        open.join().map_err(|_| "the open panicked")?,
        "the open that came during the issue was refused"
    );
    assert_eq!(
        fixture.calls.load(Ordering::Relaxed),
        1,
        "the waiting open asked again"
    );
    fixture.finish()
}

#[test]
fn a_refused_start_issue_holds_nothing_and_the_next_open_asks_again() -> Result {
    let fixture = Fixture::unissued(true)?;
    issued(StartIssue::new(fixture.authority.clone(), NOW).begin()?)?;
    assert!(
        fixture.authority.pass.current()?.is_empty(),
        "a refused issue left a pass held"
    );
    let opened = fixture
        .authority
        .open(&Fixture::link(), LinkAction::Export, NOW);
    assert!(opened.is_err(), "an open with no pass was admitted");
    assert_eq!(fixture.calls.load(Ordering::Relaxed), 2);
    fixture.finish()
}