wslc 0.1.0

Safe Rust wrapper for Microsoft WSL Containers
Documentation
use std::path::PathBuf;
use std::time::Duration;

use wslc::{
    DeleteContainerOptions, Error, ImagePullOptions, ProcessOptions, Service, Session, Signal,
    WslcErrorKind,
};

#[test]
fn session_builder_rejects_empty_session_name_before_loading_sdk() {
    let err = Session::builder("", PathBuf::from(r"C:\WslcData\test"))
        .start()
        .unwrap_err();

    assert!(matches!(err, Error::InvalidInput(message) if message.contains("session name")));
}

#[test]
fn session_builder_rejects_zero_cpu_count() {
    let err = Session::builder("test", PathBuf::from(r"C:\WslcData\test"))
        .cpu_count(0)
        .start()
        .unwrap_err();

    assert!(matches!(err, Error::InvalidInput(message) if message.contains("cpu_count")));
}

#[test]
fn process_options_reject_empty_command_when_used_as_init_process() {
    let err = ProcessOptions::new(Vec::<String>::new())
        .validate()
        .unwrap_err();

    assert!(matches!(err, Error::InvalidInput(message) if message.contains("command")));
}

#[test]
fn image_pull_options_reject_empty_uri_before_loading_sdk() {
    let err = ImagePullOptions::new("").validate().unwrap_err();

    assert!(matches!(err, Error::InvalidInput(message) if message.contains("image uri")));
}

#[test]
fn delete_container_options_default_is_not_forceful() {
    assert!(!DeleteContainerOptions::default().force);
}

#[test]
fn timeout_validation_rejects_values_that_do_not_fit_u32_milliseconds() {
    let err = Session::builder("test", PathBuf::from(r"C:\WslcData\test"))
        .timeout(Duration::from_millis(u64::from(u32::MAX) + 1))
        .start()
        .unwrap_err();

    assert!(matches!(err, Error::InvalidInput(message) if message.contains("timeout")));
}

#[test]
fn hresult_errors_expose_original_code_and_wslc_kind() {
    let err = Error::from_hresult(0x8004_0603_u32 as i32, "missing container");

    assert_eq!(err.hresult(), Some(0x8004_0603_u32 as i32));
    assert_eq!(err.wslc_kind(), Some(WslcErrorKind::ContainerNotFound));
    assert!(err.to_string().contains("missing container"));
}

#[test]
fn service_reports_missing_sdk_as_sdk_not_found_or_components() {
    let result = Service::version();

    if let Err(error) = result {
        assert!(
            matches!(error, Error::SdkNotFound(_) | Error::MissingComponents(_)),
            "unexpected error: {error:?}"
        );
    }
}

#[test]
fn signal_values_match_linux_signal_numbers() {
    assert_eq!(Signal::Sigterm.as_raw(), 15);
    assert_eq!(Signal::Sigkill.as_raw(), 9);
}