From 9dec8076a0e1327e38778bfa79f718e68f997d67 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 25 Sep 2026 12:45:09 -0400 Subject: [PATCH] tests-integration: Serialize the install-config writer against readers libtest runs the container tests concurrently as threads of one process, and "printconfig --all" writes and then removes a fragment in /run/bootc/install that "install config" can pick up while scanning the same directory. That made "install config" flake with a bare "No such file or directory" when the fragment vanished between the scan and the read, and it could also see the fragment half-written or get the wrong config. This is a race between the tests, so fix it there: the test that writes config takes a write lock and the ones that read it take a read lock. Generated-by: AI Signed-off-by: Colin Walters --- crates/tests-integration/src/container.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/tests-integration/src/container.rs b/crates/tests-integration/src/container.rs index 08716f475a..d43e00d53f 100644 --- a/crates/tests-integration/src/container.rs +++ b/crates/tests-integration/src/container.rs @@ -4,6 +4,7 @@ use indoc::indoc; use scopeguard::defer; use serde::Deserialize; use std::process::{Command, Stdio}; +use std::sync::RwLock; use std::{fs, path::Path}; use anyhow::{Context, Result}; @@ -114,7 +115,16 @@ pub(crate) fn test_bootc_upgrade() -> Result<()> { Ok(()) } +/// libtest runs the tests as threads of this one process, concurrently. Tests +/// that change the install config (under /run/bootc/install) take this for +/// writing and those that read it take it for reading, so no reader can see +/// a fragment being written or removed. +static INSTALL_CONFIG_LOCK: RwLock<()> = RwLock::new(()); + pub(crate) fn test_bootc_install_config() -> Result<()> { + let _guard = INSTALL_CONFIG_LOCK + .read() + .unwrap_or_else(|e| e.into_inner()); let sh = &xshell::Shell::new()?; let config = cmd!(sh, "bootc install print-configuration").read()?; let config: serde_json::Value = @@ -137,6 +147,9 @@ pub(crate) fn test_bootc_install_config_all() -> Result<()> { ostree: Option, } + let _guard = INSTALL_CONFIG_LOCK + .write() + .unwrap_or_else(|e| e.into_inner()); let config_d = std::path::Path::new("/run/bootc/install/"); let test_toml_path = config_d.join("10-test.toml"); std::fs::create_dir_all(&config_d)?;