From cb6ac6622320ed8c88135473125a88a140ac686b Mon Sep 17 00:00:00 2001 From: Steven Presti Date: Thu, 21 Mar 2024 10:39:31 -0400 Subject: [PATCH] ci: add lint tests Add lint tests to CI which runs linting against test image, and then cp's kernel to create a negative test. Co-authored-by: Joseph Marrero Co-authored-by: Huijing Hei Co-authored-by: Yasmin de Souza Signed-off-by: Steven Presti --- .github/workflows/ci.yml | 25 +++++++++++++++++++++++++ lib/src/cli.rs | 26 ++++++++++++++++++++++++-- lib/src/privtests.rs | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f25aa332a..0c10c0640 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,6 +127,31 @@ jobs: run: sudo tar -C / -xvf bootc.tar.zst - name: Integration tests run: bootc internal-tests run-container-integration + - name: lint tests + run: | + set -xeuo pipefail + bootc build-lint + if ["$1" -eq 0]; then + echo "No errors found" + else + echo "Linting failed" + exit 1 + fi + cd /usr/lib/modules + kernel=$(ls | tail -n 1) + sudo cp -r $kernel "$kernel-to-delete" + bootc build-lint + if ["$1" -eq 0]; then + echo "No errors found" + exit 1 + else + echo "Linting found both kernels" + fi + + #clean-up + sudo rm -rf "$kernel-to-delete" + + privtest-alongside: if: ${{ !contains(github.event.pull_request.labels.*.name, 'control/skip-ci') }} name: "Test install-alongside" diff --git a/lib/src/cli.rs b/lib/src/cli.rs index 8fcc90c6a..d1a181fcb 100644 --- a/lib/src/cli.rs +++ b/lib/src/cli.rs @@ -2,7 +2,6 @@ //! //! Command line tool to manage bootable ostree-based containers. -use anyhow::Ok; use anyhow::{Context, Result}; use camino::Utf8PathBuf; use cap_std_ext::cap_std; @@ -176,6 +175,10 @@ pub(crate) enum TestingOpts { image: String, blockdev: Utf8PathBuf, }, + // Test set of lints on ostree container + TestBuildLint { + image: String, + }, #[clap(name = "verify-selinux")] VerifySELinux { root: String, @@ -624,7 +627,8 @@ fn lint() -> Result<()> { } let root = cap_std::fs::Dir::open_ambient_dir("/", cap_std::ambient_authority())?; - ostree_ext::bootabletree::find_kernel_dir_fs(&root)?; + let result = ostree_ext::bootabletree::find_kernel_dir_fs(&root)?; + tracing::debug!("Found kernel: {:?}", result); return Ok(()); } @@ -749,3 +753,21 @@ fn test_parse_generator() { Opt::Internals(InternalsOpts::SystemdGenerator { .. }) )); } + +#[test] +fn test_linting() { + // linting should only occur in side of a container. + match ostree_ext::container_utils::is_ostree_container() { + Ok(result) => { + if !result { + let expected_error_message = "Not in a ostree container, this command only verifies ostree containers."; + + let result = lint(); + assert_eq!(result.err().unwrap().to_string(), expected_error_message, "Error message mismatch"); + } + + }, + Err(_) =>{ + } + } +} \ No newline at end of file diff --git a/lib/src/privtests.rs b/lib/src/privtests.rs index ea56c077d..05fb26a9c 100644 --- a/lib/src/privtests.rs +++ b/lib/src/privtests.rs @@ -9,7 +9,6 @@ use cap_std_ext::cap_std::fs::Dir; use fn_error_context::context; use rustix::fd::AsFd; use xshell::{cmd, Shell}; - use crate::blockdev::LoopbackDevice; use crate::install::config::InstallConfiguration; @@ -196,6 +195,37 @@ fn verify_selinux_recurse(root: &Dir, path: &mut PathBuf, warn: bool) -> Result< Ok(()) } +#[context("Container tests")] +fn test_build_lint(image: &str) -> Result<()> { + + let sh = Shell::new()?; + + // Smoke test of build_lint + let _test_1_result = cmd!(sh, "podman run --rm --privileged --pid=host --env=RUST_LOG -v /usr/bin/bootc:/usr/bin/bootc {image} bootc build-lint").run(); + + // Setup for multiple kernels lint test + cmd!(sh, "podman run -dt --name test --privileged --pid=host --env=RUST_LOG -v /usr/bin/bootc:/usr/bin/bootc {image} bash").run()?; + let kernel_name = cmd!(sh, "podman exec test bash -c 'ls /usr/lib/modules | tail -n -1'" ).read()?; + Command::new("podman") + .arg("exec") + .arg("test") + .arg("bash") + .arg("-c") + .arg(format!("sudo cp -r /usr/lib/modules/{} /usr/lib/modules/delete-me", kernel_name)) + .output()?; + let more_then_one_kernel_result = cmd!(sh, "podman exec test bash -c 'bootc build-lint'").read_stderr(); + // Container Cleanup + cmd!(sh, "podman rm -f test").run()?; + + _test_1_result?; + if let Err(e) = more_then_one_kernel_result { + assert!(e.to_string().contains("bootc build-lint")); + } else { + assert!(false, "Expected error, got none"); + } + Ok(()) +} + pub(crate) async fn run(opts: TestingOpts) -> Result<()> { match opts { TestingOpts::RunPrivilegedIntegration {} => { @@ -221,5 +251,9 @@ pub(crate) async fn run(opts: TestingOpts) -> Result<()> { tokio::task::spawn_blocking(move || verify_selinux_recurse(&rootfs, &mut path, warn)) .await? } + TestingOpts::TestBuildLint { image } => { + tokio::task::spawn_blocking(move || test_build_lint(&image)).await? + } + } }