dope-tls 0.32.0

TCP TLS streams for dope runtime, rustls-backed
Documentation
use dope::core::driver::route::KeyTag;
use dope::net::wire::{
    domain::{Bootstrap as _, Limits},
    open::{self, Runtime as _},
    send::Store as _,
};
use dope_test::alloc::Tracker;
use dope_tls::{
    config::raw::Identity,
    tls::{endpoint, protocol::Bootstrap, roles},
};
use std::sync::Arc;

#[global_allocator]
static ALLOCATOR: Tracker = Tracker::new();

#[test]
fn full_admission_no_alloc() {
    let slots = endpoint::Sessions::<roles::Client>::try_new(1).expect("one session slot");
    let config = endpoint::Config::client(
        Arc::new(Identity::client([7; 32]).expect("client configuration")),
        "example.com".try_into().expect("server name"),
    );
    let mut run = Bootstrap::<roles::Client>::try_runtime::<KeyTag<0>>(
        Limits::fixed::<1, 0, 0, { 64 * 1024 }>(),
        config.bind(&slots),
    )
    .expect("endpoint runtime");
    let first = match run.open((), |(), wire, send| open::Disposition::Commit((wire, send))) {
        open::Outcome::Opened(parts) => Some(parts),
        open::Outcome::Failed { .. } | open::Outcome::Unavailable(()) => None,
    }
    .expect("first client open");
    let hello = first.1.as_slice().to_vec();
    assert!(!hello.is_empty());

    let (full, activity) = Tracker::counts(|| run.open(7, |_, _, _| open::Disposition::Commit(())));
    assert!(matches!(full, open::Outcome::Unavailable(7)));
    assert_eq!(activity, [0, 0]);
    assert_eq!(first.1.as_slice(), hello);
    drop(first);
    assert!(matches!(
        run.open((), |(), wire, send| open::Disposition::Commit((wire, send))),
        open::Outcome::Opened(_)
    ));
}

#[test]
fn rejects_rebinding() {
    let pool = endpoint::Sessions::<roles::Server>::try_new(1).expect("one session slot");
    let config = Arc::new(
        Identity::from_seed(&[11; 32])
            .expect("server identity")
            .server()
            .expect("server configuration"),
    );
    let runtime = Bootstrap::<roles::Server>::try_runtime::<KeyTag<0>>(
        Limits::fixed::<1, 0, 0, { 64 * 1024 }>(),
        endpoint::Config::from(config.clone()).bind(&pool),
    )
    .expect("bind storage");
    drop(runtime);

    let result = Bootstrap::<roles::Server>::try_runtime::<KeyTag<0>>(
        Limits::fixed::<1, 0, 0, { 64 * 1024 }>(),
        endpoint::Config::from(config).bind(&pool),
    );
    assert!(matches!(
        result,
        Err(dope::net::Resource::Binding(
            dope::net::BindingError::AlreadyBound
        ))
    ));
}

#[test]
fn failed_binding_retries() {
    let pool = endpoint::Sessions::<roles::Server>::try_new(1).expect("one session slot");
    let config = Arc::new(
        Identity::from_seed(&[11; 32])
            .expect("server identity")
            .server()
            .expect("server configuration"),
    );
    let (result, activity) = Tracker::activity(|| {
        Tracker::fail_after(3, || {
            Bootstrap::<roles::Server>::try_runtime::<KeyTag<0>>(
                Limits::fixed::<1, 0, 0, { 64 * 1024 }>(),
                endpoint::Config::from(config.clone()).bind(&pool),
            )
        })
    });
    assert!(matches!(
        result,
        Err(dope::net::Resource::Queue(o3::alloc::Error::Exhausted))
    ));
    assert_eq!(activity.allocations, 3);
    assert_eq!(activity.deallocations, 3);
    assert_eq!(activity.allocated_bytes, activity.deallocated_bytes);

    let mut runtime = Bootstrap::<roles::Server>::try_runtime::<KeyTag<0>>(
        Limits::fixed::<1, 0, 0, { 64 * 1024 }>(),
        endpoint::Config::from(config).bind(&pool),
    )
    .expect("retry unbound storage");
    assert!(matches!(
        runtime.open((), |(), wire, send| open::Disposition::Commit((wire, send))),
        open::Outcome::Opened(_)
    ));
}