tests: factor out utility function is_external_tool_installed

A pattern has emerged where a integration tests check for the
availability of an external tool (`git`, `taplo`, `gpg`, ...) and skip
the test (by simply passing it) when it is not available. To check this,
the program is run with the `--version` flag.

Some tests require that the program be available at least when running
in CI, by calling `ensure_running_outside_ci` conditionally on the
outcome. The decision is up to each test, though, the utility merely
returns a `bool`.
This commit is contained in:
Jonas Greitemann 2025-04-16 17:26:03 +02:00 committed by Jonas Greitemann
parent bf2c01e74b
commit 7bb8e17e88
4 changed files with 18 additions and 17 deletions

View File

@ -4,14 +4,10 @@ use std::process::Output;
use std::process::Stdio; use std::process::Stdio;
use testutils::ensure_running_outside_ci; use testutils::ensure_running_outside_ci;
use testutils::is_external_tool_installed;
fn taplo_check_config(file: &Path) -> datatest_stable::Result<Option<Output>> { fn taplo_check_config(file: &Path) -> datatest_stable::Result<Option<Output>> {
if Command::new("taplo") if !is_external_tool_installed("taplo") {
.arg("--version")
.stdout(Stdio::null())
.status()
.is_err()
{
ensure_running_outside_ci("`taplo` must be in the PATH"); ensure_running_outside_ci("`taplo` must be in the PATH");
eprintln!("Skipping test because taplo is not installed on the system"); eprintln!("Skipping test because taplo is not installed on the system");
return Ok(None); return Ok(None);

View File

@ -15,7 +15,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use std::path::Path; use std::path::Path;
use std::process::Command;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use std::time::SystemTime; use std::time::SystemTime;
@ -39,6 +38,7 @@ use testutils::commit_with_tree;
use testutils::create_random_commit; use testutils::create_random_commit;
use testutils::create_single_tree; use testutils::create_single_tree;
use testutils::create_tree; use testutils::create_tree;
use testutils::is_external_tool_installed;
use testutils::repo_path; use testutils::repo_path;
use testutils::repo_path_buf; use testutils::repo_path_buf;
use testutils::CommitGraphBuilder; use testutils::CommitGraphBuilder;
@ -96,7 +96,7 @@ fn make_commit(
#[test] #[test]
fn test_gc() { fn test_gc() {
// TODO: Better way to disable the test if git command couldn't be executed // TODO: Better way to disable the test if git command couldn't be executed
if Command::new("git").arg("--version").status().is_err() { if !is_external_tool_installed("git") {
eprintln!("Skipping because git command might fail to run"); eprintln!("Skipping because git command might fail to run");
return; return;
} }

View File

@ -3,7 +3,6 @@ use std::fs::Permissions;
use std::io::Write as _; use std::io::Write as _;
#[cfg(unix)] #[cfg(unix)]
use std::os::unix::prelude::PermissionsExt as _; use std::os::unix::prelude::PermissionsExt as _;
use std::process::Command;
use std::process::Stdio; use std::process::Stdio;
use assert_matches::assert_matches; use assert_matches::assert_matches;
@ -14,6 +13,7 @@ use jj_lib::signing::SigStatus;
use jj_lib::signing::SignError; use jj_lib::signing::SignError;
use jj_lib::signing::SigningBackend as _; use jj_lib::signing::SigningBackend as _;
use testutils::ensure_running_outside_ci; use testutils::ensure_running_outside_ci;
use testutils::is_external_tool_installed;
static GPG_PRIVATE_KEY: &str = r#"-----BEGIN PGP PRIVATE KEY BLOCK----- static GPG_PRIVATE_KEY: &str = r#"-----BEGIN PGP PRIVATE KEY BLOCK-----
@ -165,7 +165,7 @@ impl GpgsmEnvironment {
macro_rules! gpg_guard { macro_rules! gpg_guard {
() => { () => {
if Command::new("gpg").arg("--version").status().is_err() { if !is_external_tool_installed("gpg") {
ensure_running_outside_ci("`gpg` must be in the PATH"); ensure_running_outside_ci("`gpg` must be in the PATH");
eprintln!("Skipping test because gpg is not installed on the system"); eprintln!("Skipping test because gpg is not installed on the system");
return; return;
@ -175,7 +175,7 @@ macro_rules! gpg_guard {
macro_rules! gpgsm_guard { macro_rules! gpgsm_guard {
() => { () => {
if Command::new("gpgsm").arg("--version").status().is_err() { if !is_external_tool_installed("gpgsm") {
ensure_running_outside_ci("`gpgsm` must be in the PATH"); ensure_running_outside_ci("`gpgsm` must be in the PATH");
eprintln!("Skipping test because gpgsm is not installed on the system"); eprintln!("Skipping test because gpgsm is not installed on the system");
return; return;

View File

@ -15,6 +15,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use std::env; use std::env;
use std::ffi::OsStr;
use std::fs; use std::fs;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::Read as _; use std::io::Read as _;
@ -142,6 +143,15 @@ pub fn ensure_running_outside_ci(reason: &str) {
assert!(!running_in_ci, "Running in CI, {reason}."); assert!(!running_in_ci, "Running in CI, {reason}.");
} }
/// Tests if an external tool is installed and in the PATH
pub fn is_external_tool_installed(program_name: impl AsRef<OsStr>) -> bool {
Command::new(program_name)
.arg("--version")
.stdout(Stdio::null())
.status()
.is_ok()
}
#[derive(Debug)] #[derive(Debug)]
pub struct TestEnvironment { pub struct TestEnvironment {
temp_dir: TempDir, temp_dir: TempDir,
@ -627,12 +637,7 @@ pub fn assert_abandoned_with_parent(
pub fn assert_no_forgotten_test_files(test_dir: &Path) { pub fn assert_no_forgotten_test_files(test_dir: &Path) {
// We require `taplo` for this check; if it's not installed, that's ok unless // We require `taplo` for this check; if it's not installed, that's ok unless
// we're running in CI. // we're running in CI.
if Command::new("taplo") if !is_external_tool_installed("taplo") {
.arg("--version")
.stdout(Stdio::null())
.status()
.is_err()
{
ensure_running_outside_ci("`taplo` must be in the PATH"); ensure_running_outside_ci("`taplo` must be in the PATH");
eprintln!( eprintln!(
"Skipping check for forgotten test files because taplo is not installed on the system" "Skipping check for forgotten test files because taplo is not installed on the system"