fundaia 0.52.2

Command line for the Fundaia deployment platform: projects, services, variables, deployments, logs and metrics
use std::process::{Command, Output};
use std::time::{Duration, Instant};

fn budget() -> Duration {
    let millis = std::env::var("FUNDAIA_PERF_BUDGET_MS")
        .ok()
        .and_then(|value| value.parse().ok())
        .unwrap_or(500);
    Duration::from_millis(millis)
}

fn fundaia(arguments: &[&str]) -> Command {
    let mut command = Command::new(env!("CARGO_BIN_EXE_fundaia"));
    command
        .args(arguments)
        .env("FUNDAIA_CONFIG", "/nonexistent/fundaia-perf/config.toml")
        .env("FUNDAIA_NO_UPDATE_CHECK", "1")
        .env_remove("FUNDAIA_URL")
        .env_remove("FUNDAIA_TOKEN")
        .env_remove("FUNDAIA_PROFILE")
        .env_remove("FUNDAIA_JSON");
    command
}

fn run(arguments: &[&str]) -> Output {
    fundaia(arguments)
        .output()
        .expect("the binary this test suite was built alongside runs")
}

fn median_run_millis(arguments: &[&str]) -> u128 {
    run(arguments);

    let mut samples: Vec<u128> = (0..9)
        .map(|_| {
            let started = Instant::now();
            run(arguments);
            started.elapsed().as_millis()
        })
        .collect();
    samples.sort_unstable();

    samples[samples.len() / 2]
}

#[test]
fn it_should_print_the_version_within_the_startup_budget() {
    assert!(median_run_millis(&["--version"]) < budget().as_millis());
}

#[test]
fn it_should_print_the_help_within_the_startup_budget() {
    assert!(median_run_millis(&["--help"]) < budget().as_millis());
}

#[test]
fn it_should_refuse_an_unconfigured_command_within_the_startup_budget() {
    assert!(median_run_millis(&["projects"]) < budget().as_millis());
}

#[test]
fn it_should_exit_nonzero_when_nothing_is_configured() {
    assert!(!run(&["projects"]).status.success());
}

#[test]
fn it_should_ask_for_a_login_when_nothing_is_configured() {
    let stderr = String::from_utf8_lossy(&run(&["projects"]).stderr).to_string();
    assert!(stderr.contains("login"));
}

#[test]
fn it_should_answer_an_error_as_json_in_json_mode() {
    let output = run(&["--json", "projects"]);
    let stderr = String::from_utf8_lossy(&output.stderr);

    let parsed: serde_json::Value =
        serde_json::from_str(stderr.trim()).expect("stderr is exactly one JSON object");

    assert_eq!(parsed["error"]["code"], "unauthorized");
}

#[test]
fn it_should_exit_five_when_nothing_is_configured() {
    assert_eq!(run(&["projects"]).status.code(), Some(5));
}

#[test]
fn it_should_carry_the_exit_code_it_is_about_to_leave_in_the_json() {
    let output = run(&["--json", "projects"]);
    let parsed: serde_json::Value =
        serde_json::from_str(String::from_utf8_lossy(&output.stderr).trim())
            .expect("stderr is exactly one JSON object");

    assert_eq!(
        parsed["error"]["exit"].as_i64(),
        output.status.code().map(i64::from)
    );
}

#[test]
fn it_should_not_invite_a_retry_when_nothing_is_configured() {
    let output = run(&["--json", "projects"]);
    let parsed: serde_json::Value =
        serde_json::from_str(String::from_utf8_lossy(&output.stderr).trim())
            .expect("stderr is exactly one JSON object");

    assert_eq!(parsed["error"]["retryable"], false);
}

#[test]
fn it_should_describe_itself_with_nothing_configured() {
    let stdout = String::from_utf8_lossy(&run(&["schema", "--json"]).stdout).to_string();
    let parsed: serde_json::Value =
        serde_json::from_str(stdout.trim()).expect("stdout is exactly one JSON object");

    assert_eq!(parsed["tool"], "fundaia");
}

#[test]
fn it_should_describe_itself_within_the_startup_budget() {
    assert!(median_run_millis(&["schema", "--json"]) < budget().as_millis());
}

#[test]
fn it_should_hand_over_the_guide_with_nothing_configured() {
    assert!(run(&["guide"]).status.success());
}

#[test]
fn it_should_keep_stdout_empty_when_a_json_command_fails() {
    assert!(run(&["--json", "projects"]).stdout.is_empty());
}

#[test]
fn it_should_write_a_completion_script_on_stdout() {
    let stdout = String::from_utf8_lossy(&run(&["completions", "bash"]).stdout).to_string();
    assert!(stdout.contains("fundaia"));
}