volli 0.1.10

CLI frontend for volli
#![allow(unused_crate_dependencies)]

use assert_cmd::prelude::*;
use predicates::prelude::*;
use serial_test::serial;
use std::process::Command;

// helper to issue a basic join secret for agent profile
fn make_secret() -> String {
    let mut csk = [0u8; 32];
    getrandom::getrandom(&mut csk).unwrap();
    let token = volli_core::token::issue_token(&csk, "t", "c", "aid", 60).unwrap();
    let secret = volli_core::BootstrapSecret {
        host: "h".into(),
        quic_port: 4243,
        tcp_port: 4242,
        token,
        cert: vec![],
    };
    secret.encode().unwrap()
}

#[test]
#[serial]
fn show_existing_coord_profile() {
    let base = tempfile::TempDir::new().unwrap();
    unsafe {
        std::env::set_var("VOLLI_CONFIG_DIR", base.path());
    }
    volli_server::save_profile_host("p1", "h").unwrap();
    volli_server::save_tcp_port("p1", 1111).unwrap();
    volli_server::save_quic_port("p1", 2222).unwrap();

    Command::cargo_bin("volli")
        .unwrap()
        .args(["profile", "show", "p1", "--coord"])
        .assert()
        .success()
        .stdout(predicate::str::contains("coordinator profile 'p1'"))
        .stdout(predicate::str::contains("tcp_port: 1111"))
        .stdout(predicate::str::contains("quic_port: 2222"));

    unsafe {
        std::env::remove_var("VOLLI_CONFIG_DIR");
    }
}

#[test]
#[serial]
fn show_existing_agent_profile() {
    let base = tempfile::TempDir::new().unwrap();
    unsafe {
        std::env::set_var("VOLLI_CONFIG_DIR", base.path());
    }
    let secret = make_secret();
    volli_agent::save_state("a1", &secret).unwrap();

    Command::cargo_bin("volli")
        .unwrap()
        .args(["profile", "show", "a1", "--agent"])
        .assert()
        .success()
        .stdout(predicate::str::contains("agent profile 'a1'"))
        .stdout(predicate::str::contains("host: h"))
        .stdout(predicate::str::contains("tcp_port: 4242"))
        .stdout(predicate::str::contains("quic_port: 4243"))
        .stdout(predicate::str::contains("tenant: t"))
        .stdout(predicate::str::contains("cluster: c"));

    unsafe {
        std::env::remove_var("VOLLI_CONFIG_DIR");
    }
}

#[test]
#[serial]
fn show_missing_profile() {
    let base = tempfile::TempDir::new().unwrap();
    unsafe {
        std::env::set_var("VOLLI_CONFIG_DIR", base.path());
    }

    Command::cargo_bin("volli")
        .unwrap()
        .args(["profile", "show", "missing"])
        .assert()
        .success()
        .stdout(predicate::str::contains("profile 'missing' not found"));

    unsafe {
        std::env::remove_var("VOLLI_CONFIG_DIR");
    }
}