Merge pull request #517 from garasubo/feat/add-gnu-tests

feat: run GNU testsuite
This commit is contained in:
Takumi Shimada
2026-05-13 22:59:28 +09:00
committed by GitHub
parent 588e410d35
commit a2e41f9142
5 changed files with 252 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
name: Run GNU Test
on:
pull_request:
push:
branches:
- 'main'
jobs:
native:
name: Run GNU tests (native)
runs-on: ubuntu-24.04
steps:
- name: Checkout code (uutils/util-linux)
uses: actions/checkout@v6
with:
path: uutils-util-linux
- name: Checkout code (util-linux/util-linux)
uses: actions/checkout@v6
with:
repository: util-linux/util-linux
path: gnu-util-linux
ref: v2.41.4
- uses: Swatinem/rust-cache@v2
with:
workspaces: "./uutils-util-linux -> target"
- name: Install dependencies
run: |
sudo apt-get update --quiet
sudo apt-get install -y \
build-essential autoconf automake autopoint pkg-config \
libtool gettext bison \
bc socat ntp iproute2 squashfs-tools \
libcap-ng-dev libpam-dev libudev-dev python3-dev libmount-dev libclang-dev libsmartcols-dev curl
- name: Build GNU tests
run: |
cd gnu-util-linux
./autogen.sh
./configure
make -j$(nproc) check-programs
- name: Download test baseline if exists
id: download-test-baseline
continue-on-error: true
uses: actions/download-artifact@v8
with:
name: gnu-test-failures
path: uutils-util-linux/.reference/
- name: Run GNU tests
env:
GNU_PROJECT_DIR: ${{ github.workspace }}/gnu-util-linux
run: |
cd uutils-util-linux
./scripts/run-tests.sh
- name: Update test baseline
if: github.ref == 'refs/heads/main'
run: |
cd uutils-util-linux
./scripts/check-new-gnu-failures.sh --update-baseline
- name: Upload test baseline artifact
if: github.ref == 'refs/heads/main' || steps.download-test-baseline.outcome == 'failure'
uses: actions/upload-artifact@v7
with:
name: gnu-test-failures
path: uutils-util-linux/.reference/gnu-test-failures.txt
+3
View File
@@ -1,3 +1,6 @@
syntax: glob
/target/
.test-helpers
.reference
+96
View File
@@ -0,0 +1,96 @@
#!/bin/bash
set -euo pipefail
cd "$(dirname "$0")/../"
PROJECT_DIR="$(pwd)"
DIFF_DIR="$PROJECT_DIR/.test-helpers/tests/diff"
BASELINE="$PROJECT_DIR/.reference/gnu-test-failures.txt"
UPDATE_BASELINE=false
EMPTY_BASELINE=false
for arg in "$@"; do
case "$arg" in
--update-baseline) UPDATE_BASELINE=true ;;
*) echo "Unknown argument: $arg" >&2; exit 2 ;;
esac
done
# Collect current failures (exclude .err companion files)
current_tmp=$(mktemp)
trap 'rm -f "$current_tmp"' EXIT
if [[ -d "$DIFF_DIR" ]]; then
find "$DIFF_DIR" -mindepth 2 -maxdepth 2 -type f ! -name "*.err" -print0 \
| sort -z \
| while IFS= read -r -d '' path; do
echo "${path#"$DIFF_DIR/"}"
done > "$current_tmp"
fi
# --update-baseline mode
if [[ "$UPDATE_BASELINE" == true ]]; then
{
echo "# Known GNU test failures - format: util/testname"
echo "# Update with: ./scripts/check-new-gnu-failures.sh --update-baseline"
cat "$current_tmp"
} > "$BASELINE"
count=$(wc -l < "$current_tmp")
echo "Baseline updated: $BASELINE ($count failures recorded)"
exit 0
fi
# Load baseline (strip comments and blank lines)
baseline_tmp=$(mktemp)
trap 'rm -f "$current_tmp" "$baseline_tmp"' EXIT
if [[ -f "$BASELINE" ]]; then
grep -v '^\s*#' "$BASELINE" | grep -v '^\s*$' | sort > "$baseline_tmp"
else
echo "WARNING: Baseline not found: $BASELINE" >&2
echo " Run with --update-baseline to create it." >&2
touch "$baseline_tmp"
EMPTY_BASELINE=true
fi
# comm: -13 = lines only in current (new failures), -23 = lines only in baseline (fixed)
new_failures=$(comm -13 "$baseline_tmp" "$current_tmp")
fixed_tests=$(comm -23 "$baseline_tmp" "$current_tmp")
# Report
echo "--- GNU test failure summary ---"
echo "Baseline failures: $(wc -l < "$baseline_tmp")"
echo "Current failures: $(wc -l < "$current_tmp")"
echo ""
if [[ "$EMPTY_BASELINE" == true ]]; then
mkdir -p "$(dirname "$BASELINE")"
{
echo "# Known GNU test failures - format: util/testname"
echo "# Update with: ./scripts/check-new-gnu-failures.sh --update-baseline"
cat "$current_tmp"
} > "$BASELINE"
count=$(wc -l < "$current_tmp")
echo "Initial baseline created: $BASELINE ($count failures recorded)"
exit 0
fi
if [[ -n "$fixed_tests" ]]; then
echo "Tests newly FIXED:"
awk '{print " [FIXED] " $0}' <<< "$fixed_tests"
echo ""
fi
if [[ -n "$new_failures" ]]; then
echo "Tests newly FAILING:"
awk '{print " [NEW FAILURE] " $0}' <<< "$new_failures"
echo ""
count=$(wc -l <<< "$new_failures")
echo "ERROR: $count new test failure(s) detected." >&2
echo " Fix the regression, or if intentional, update the baseline:" >&2
echo " ./scripts/check-new-gnu-failures.sh --update-baseline" >&2
exit 1
fi
echo "No new failures. All current failures are known."
if [[ -n "$fixed_tests" ]]; then
echo "Consider updating the baseline to remove fixed tests:"
echo " ./scripts/check-new-gnu-failures.sh --update-baseline"
fi
+52
View File
@@ -0,0 +1,52 @@
#!/bin/bash
set -euxo pipefail
cd "$(dirname "$0")/../"
PROJECT_DIR="$(pwd)"
BINARY="$PROJECT_DIR/target/release/util-linux"
if [[ -z "${GNU_PROJECT_DIR:-}" ]]; then
echo "ERROR: GNU_PROJECT_DIR is not set." >&2
echo " Set it to the path of a gnu-util-linux checkout." >&2
exit 2
fi
GNU_TS_DIR="$GNU_PROJECT_DIR/tests/ts"
if [[ ! -d "$GNU_TS_DIR" ]]; then
echo "ERROR: GNU test directory not found: $GNU_TS_DIR" >&2
exit 2
fi
mkdir -p .test-helpers
ours_tmp=$(mktemp)
gnu_tmp=$(mktemp)
trap 'rm -f "$ours_tmp" "$gnu_tmp"' EXIT
for d in "$PROJECT_DIR/src/uu/"*/; do
basename "$d"
done | sort > "$ours_tmp"
for d in "$GNU_TS_DIR/"*/; do
basename "$d"
done | sort > "$gnu_tmp"
comm -12 "$ours_tmp" "$gnu_tmp" > "$PROJECT_DIR/.test-helpers/utils.list"
mapfile -t UTILS < "$PROJECT_DIR/.test-helpers/utils.list"
if [[ ${#UTILS[@]} -eq 0 ]]; then
echo "ERROR: No utilities matched between src/uu/ and $GNU_TS_DIR/" >&2
exit 1
fi
for util in "${UTILS[@]}"; do
cat > ".test-helpers/$util" <<EOF
#!/bin/bash
exec "$BINARY" $util "\$@"
EOF
chmod +x ".test-helpers/$util"
done
echo "Generated wrappers for ${#UTILS[@]} utilities: ${UTILS[*]}"
+33
View File
@@ -0,0 +1,33 @@
#!/bin/bash
set -euxo pipefail
cd "$(dirname "$0")/../"
PROJECT_DIR="$(pwd)"
cargo build --release
./scripts/gen-test-helper.sh
mapfile -t UTILS < "$PROJECT_DIR/.test-helpers/utils.list"
if [[ ${#UTILS[@]} -eq 0 ]]; then
echo "ERROR: .test-helpers/utils.list is empty; nothing to test." >&2
exit 1
fi
# Clear stale diff files from any previous run
rm -rf "$PROJECT_DIR/.test-helpers/tests/diff"
# Run GNU tests; allow non-zero exit (known failures exist)
set +e
"$GNU_PROJECT_DIR/tests/run.sh" \
--builddir="$PROJECT_DIR/.test-helpers" \
"$@" \
"${UTILS[@]}"
GNU_TEST_EXIT=$?
set -e
[[ $GNU_TEST_EXIT -ne 0 ]] && echo "GNU test runner exited with code $GNU_TEST_EXIT"
./scripts/check-new-gnu-failures.sh