voa-core 0.4.2

File Hierarchy for the Verification of OS Artifacts (VOA)
Documentation
//! User mode tests
//!
//! Also see <https://uapi-group.org/specifications/specs/file_hierarchy_for_the_verification_of_os_artifacts/#user-mode>
//!
//! Load path list in these containerized user mode tests:
//!
//! ```
//! LoadPathList([
//!     LoadPath {
//!         path: "/home/user/.config/voa",
//!         ephemeral: false,
//!         writable: true,
//!     },
//!     LoadPath {
//!         path: "/etc/xdg/voa",
//!         ephemeral: false,
//!         writable: false,
//!     },
//!     LoadPath {
//!         path: "/home/user/.local/share/voa",
//!         ephemeral: false,
//!         writable: false,
//!     },
//!     LoadPath {
//!         path: "/usr/local/share/voa",
//!         ephemeral: false,
//!         writable: false,
//!     },
//!     LoadPath {
//!         path: "/usr/share/voa",
//!         ephemeral: false,
//!         writable: false,
//!     },
//! ])
//! ```

use std::collections::HashMap;

use change_user_run::{
    COVERAGE_ENV_LIST,
    collect_coverage_data,
    create_users,
    run_command_as_user,
};
use serde::Deserialize;
use testresult::TestResult;
use voa_core::Error;

use crate::{TestObject, init_logger, setup};

#[derive(Debug, Deserialize, PartialEq)]
struct VerifierOutput {
    load_path: String,
    verifier: String,
}

/// Binary built from `examples/voa-list.rs`
const LIST_VOA_CMD: &str = "/usr/local/bin/examples/voa-list";
const USER: &str = "user";

#[test]
fn user_mode_test() -> TestResult {
    init_logger();

    const SETUP: &[TestObject] = &[
        TestObject::Path("/usr/local/share/voa/arch/packages/default/openpgp/"),
        TestObject::File("/usr/local/share/voa/arch/packages/default/openpgp/foo.pgp"),
        TestObject::Path("/home/user/.local/share/voa/arch/packages/default/openpgp/"),
        TestObject::File("/home/user/.local/share/voa/arch/packages/default/openpgp/bar.pgp"),
    ];

    setup(SETUP)?;

    // Create all system users and their homes
    create_users(&[USER], None, None)?;

    let cmdout = run_command_as_user(
        LIST_VOA_CMD,
        &["--os-id", "arch", "--role", "packages"],
        None,
        COVERAGE_ENV_LIST,
        Some(HashMap::from_iter([(
            "LLVM_PROFILE_FILE".to_string(),
            "/tmp/voa-%p-%16m.profraw".to_string(),
        )])),
        USER,
    )
    .map_err(|source| Error::InternalError {
        context: format!("{source}"),
    })?;

    let res: Vec<VerifierOutput> = serde_json::from_str(&cmdout.stdout).unwrap();

    assert_eq!(res.len(), 2);

    assert_eq!(
        res[0],
        VerifierOutput {
            load_path: "/home/user/.local/share/voa".into(),
            verifier: "/home/user/.local/share/voa/arch/packages/default/openpgp/bar.pgp".into()
        }
    );

    assert_eq!(
        res[1],
        VerifierOutput {
            load_path: "/usr/local/share/voa".into(),
            verifier: "/usr/local/share/voa/arch/packages/default/openpgp/foo.pgp".into()
        }
    );

    collect_coverage_data("/tmp")?;

    Ok(())
}