Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/holger

server/lib/tests/readyz_is_real.rs

//! **What `/readyz` asks** (lane B4, A31 §7.3): [`Readiness::check`] — every
//! repository's storage place is there, the data root takes a write, and the
//! scan sandbox answers when the server scans. Each failure is named, all of
//! them at once, so one probe line tells the operator what to fix.

use std::os::unix::fs::PermissionsExt as _;
use std::sync::Arc;

use holger_server_lib::ready::{Place, Readiness};

#[test]
fn a_server_whose_storage_and_sandbox_answer_is_ready() {
    let d = tempfile::tempdir().unwrap();
    std::fs::create_dir_all(d.path().join("raw")).unwrap();
    let r = Readiness {
        places: vec![
            ("raw".into(), Place::Files(d.path().join("raw"))),
            ("fresh".into(), Place::Files(d.path().join("fresh"))),
        ],
        data_root: d.path().to_path_buf(),
        sandbox: Some(Arc::new(|| Ok(()))),
    };
    r.check().expect("ready");
    let left: Vec<_> = std::fs::read_dir(d.path())
        .unwrap()
        .filter_map(|e| e.ok())
        .map(|e| e.file_name())
        .collect();
    assert_eq!(
        left,
        vec![std::ffi::OsString::from("raw")],
        "the write probe leaves nothing behind, and a fresh repository is not made by a probe"
    );
}

#[test]
fn a_missing_storage_place_and_a_sandbox_that_does_not_answer_are_both_named() {
    let d = tempfile::tempdir().unwrap();
    let r = Readiness {
        places: vec![(
            "charts".into(),
            Place::Archive(d.path().join("charts.znippy")),
        )],
        data_root: d.path().to_path_buf(),
        sandbox: Some(Arc::new(|| {
            Err("[holger-sandbox-1] the scan sidecar is not there".into())
        })),
    };
    let e = r.check().unwrap_err();
    assert!(
        e.contains("storage `charts`") && e.contains("charts.znippy"),
        "{e}"
    );
    assert!(
        e.contains("sandbox") && e.contains("holger-sandbox-1"),
        "{e}"
    );
}

#[test]
fn a_data_root_that_takes_no_write_is_not_ready() {
    if rustix_is_root() {
        return; // root writes through a 0555 directory; the check is for the pod's uid
    }
    let d = tempfile::tempdir().unwrap();
    let ro = d.path().join("ro");
    std::fs::create_dir(&ro).unwrap();
    std::fs::set_permissions(&ro, std::fs::Permissions::from_mode(0o555)).unwrap();
    let r = Readiness {
        places: vec![("raw".into(), Place::Files(ro.join("raw")))],
        data_root: ro.clone(),
        sandbox: None,
    };
    let e = r.check().unwrap_err();
    std::fs::set_permissions(&ro, std::fs::Permissions::from_mode(0o755)).unwrap();
    assert!(e.contains("data root"), "{e}");
    assert!(
        e.contains("storage `raw`") && e.contains("cannot be made"),
        "a fresh repository under a read-only parent is named too: {e}"
    );
}

#[test]
fn a_server_that_does_not_scan_needs_no_sandbox_to_be_ready() {
    let d = tempfile::tempdir().unwrap();
    Readiness {
        places: vec![],
        data_root: d.path().to_path_buf(),
        sandbox: None,
    }
    .check()
    .expect("ready");
}

fn rustix_is_root() -> bool {
    std::fs::read_to_string("/proc/self/status")
        .ok()
        .and_then(|s| {
            s.lines()
                .find(|l| l.starts_with("Uid:"))
                .map(|l| l.split_whitespace().nth(1) == Some("0"))
        })
        .unwrap_or(false)
}