From f352e6d855a9266e12b9b1879542721d44c4459a Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 09:51:58 +0000 Subject: [PATCH] test: add unit tests for detect_system Refactors detect_system in lib/linux/detect.sh to prefix hardcoded absolute system paths (e.g. /etc/os-release, /proc/*) with a SYS_ROOT variable. This permits robust isolated testing without affecting native system detection by mocking file environments. Adds corresponding mock-based test cases for detect_system in tests/run-tests.sh checking for various Linux environments including Debian-based, non-Debian, missing os-release, Docker, Raspberry Pi, and WSL. Co-authored-by: Ch3fUlrich <71930650+Ch3fUlrich@users.noreply.github.com> --- lib/linux/detect.sh | 33 +++++++------- tests/run-tests.sh | 105 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 16 deletions(-) diff --git a/lib/linux/detect.sh b/lib/linux/detect.sh index 03080ce..7c89152 100644 --- a/lib/linux/detect.sh +++ b/lib/linux/detect.sh @@ -111,9 +111,10 @@ detect_system() { # ─── Distribution ─────────────────────────────────────────────────────── SYS_DISTRO_ID="unknown"; SYS_DISTRO_NAME="unknown" SYS_DISTRO_VERSION=""; SYS_DISTRO_CODENAME=""; SYS_DISTRO_LIKE="" - if [[ -r /etc/os-release ]]; then + local root="${SYS_ROOT:-}" + if [[ -r "$root/etc/os-release" ]]; then # shellcheck disable=SC1091 - . /etc/os-release + . "$root/etc/os-release" SYS_DISTRO_ID="${ID:-unknown}" SYS_DISTRO_NAME="${PRETTY_NAME:-${NAME:-unknown}}" SYS_DISTRO_VERSION="${VERSION_ID:-}" @@ -138,10 +139,10 @@ detect_system() { # ─── Board / virtualisation ───────────────────────────────────────────── SYS_MODEL="unknown"; SYS_IS_PI=0; SYS_IS_WSL=0; SYS_IS_CONTAINER=0 - if [[ -r /proc/device-tree/model ]]; then - SYS_MODEL="$(tr -d '\0' /dev/null || echo unknown)" - elif [[ -r /sys/devices/virtual/dmi/id/product_name ]]; then - SYS_MODEL="$(cat /sys/devices/virtual/dmi/id/product_name 2>/dev/null || echo unknown)" + if [[ -r "$root/proc/device-tree/model" ]]; then + SYS_MODEL="$(tr -d '\0' <"$root/proc/device-tree/model" 2>/dev/null || echo unknown)" + elif [[ -r "$root/sys/devices/virtual/dmi/id/product_name" ]]; then + SYS_MODEL="$(cat "$root/sys/devices/virtual/dmi/id/product_name" 2>/dev/null || echo unknown)" fi if [[ "$SYS_MODEL" == *"Raspberry Pi"* ]]; then SYS_IS_PI=1; fi # WSL: three independent signals, because none is reliable alone. The env @@ -150,26 +151,26 @@ detect_system() { SYS_WSL_VERSION=""; SYS_WSL_DISTRO="" if [[ -n "${WSL_DISTRO_NAME:-}" ]]; then SYS_IS_WSL=1; SYS_WSL_DISTRO="$WSL_DISTRO_NAME" - elif grep -qi microsoft /proc/version 2>/dev/null; then + elif grep -qi microsoft "$root/proc/version" 2>/dev/null; then SYS_IS_WSL=1 - elif grep -qiE 'microsoft|wsl' /proc/sys/kernel/osrelease 2>/dev/null; then + elif grep -qiE 'microsoft|wsl' "$root/proc/sys/kernel/osrelease" 2>/dev/null; then SYS_IS_WSL=1 fi if (( SYS_IS_WSL )); then # WSL2 ships a real Linux kernel tagged microsoft-standard-WSL2 and has # /run/WSL; WSL1 is a syscall translation layer on an NT-era version string. - if grep -qiE 'wsl2|microsoft-standard' /proc/sys/kernel/osrelease 2>/dev/null \ - || grep -qi 'WSL2' /proc/version 2>/dev/null \ - || [[ -d /run/WSL ]]; then + if grep -qiE 'wsl2|microsoft-standard' "$root/proc/sys/kernel/osrelease" 2>/dev/null \ + || grep -qi 'WSL2' "$root/proc/version" 2>/dev/null \ + || [[ -d "$root/run/WSL" ]]; then SYS_WSL_VERSION=2 else SYS_WSL_VERSION=1 fi - if [[ -z "$SYS_WSL_DISTRO" && -r /etc/wsl.conf ]]; then - SYS_WSL_DISTRO="$(awk -F= '/^[[:space:]]*hostname/{gsub(/ /,"",$2); print $2}' /etc/wsl.conf 2>/dev/null)" + if [[ -z "$SYS_WSL_DISTRO" && -r "$root/etc/wsl.conf" ]]; then + SYS_WSL_DISTRO="$(awk -F= '/^[[:space:]]*hostname/{gsub(/ /,"",$2); print $2}' "$root/etc/wsl.conf" 2>/dev/null)" fi fi - if [[ -f /.dockerenv ]] || grep -qE '(docker|lxc|containerd)' /proc/1/cgroup 2>/dev/null; then + if [[ -f "$root/.dockerenv" ]] || grep -qE '(docker|lxc|containerd)' "$root/proc/1/cgroup" 2>/dev/null; then SYS_IS_CONTAINER=1 fi @@ -186,10 +187,10 @@ detect_system() { # ─── Hardware ─────────────────────────────────────────────────────────── SYS_CPU_CORES="$(nproc 2>/dev/null || echo 1)" - SYS_CPU_NAME="$(awk -F': ' '/^model name|^Model/{print $2; exit}' /proc/cpuinfo 2>/dev/null || echo unknown)" + SYS_CPU_NAME="$(awk -F': ' '/^model name|^Model/{print $2; exit}' "$root/proc/cpuinfo" 2>/dev/null || echo unknown)" if [[ -z "$SYS_CPU_NAME" ]]; then SYS_CPU_NAME="unknown"; fi local mem_kb - mem_kb="$(awk '/^MemTotal:/{print $2}' /proc/meminfo 2>/dev/null || echo 0)" + mem_kb="$(awk '/^MemTotal:/{print $2}' "$root/proc/meminfo" 2>/dev/null || echo 0)" SYS_RAM_GB="$(awk -v k="$mem_kb" 'BEGIN{printf "%.1f", k/1048576}')" SYS_FREE_DISK_GB="$(df -BG / 2>/dev/null | awk 'NR==2{gsub("G","",$4); print $4}' || echo 0)" if [[ -z "$SYS_FREE_DISK_GB" ]]; then SYS_FREE_DISK_GB=0; fi diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 7e759a8..437d0d6 100644 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -231,6 +231,111 @@ fi # ─── Detection ────────────────────────────────────────────────────────────── describe "detection" +if it "detects Debian-like distributions"; then + tmp="$(mktemp -d)"; mkdir -p "$tmp/etc" + cat >"$tmp/etc/os-release" <<'EOF' +ID=ubuntu +PRETTY_NAME="Ubuntu 22.04 LTS" +VERSION_ID="22.04" +VERSION_CODENAME="jammy" +ID_LIKE="debian" +EOF + ( + SYS_ROOT="$tmp" + uname() { echo "Linux"; } + detect_system + if [[ "$SYS_DISTRO_ID" == "ubuntu" && "$SYS_DISTRO_NAME" == "Ubuntu 22.04 LTS" && "$SYS_IS_DEBIAN_LIKE" -eq 1 ]]; then + true + else false; fi + ) && pass || fail "failed to detect ubuntu as debian-like" + rm -rf "$tmp" +fi + +if it "detects WSL2 environment"; then + tmp="$(mktemp -d)"; mkdir -p "$tmp/proc/sys/kernel" "$tmp/run" + cat >"$tmp/proc/version" <<'EOF' +Linux version 5.15.90.1-microsoft-standard-WSL2 (oe-user@oe-host) (x86_64-msft-linux-gcc (GCC) 9.3.0, GNU ld (GNU Binutils) 2.34.0.20200220) #1 SMP Fri Jan 27 02:56:13 UTC 2023 +EOF + cat >"$tmp/proc/sys/kernel/osrelease" <<'EOF' +5.15.90.1-microsoft-standard-WSL2 +EOF + mkdir -p "$tmp/run/WSL" + ( + SYS_ROOT="$tmp" + uname() { echo "Linux"; } + detect_system + if [[ "$SYS_IS_WSL" -eq 1 && "$SYS_WSL_VERSION" == "2" ]]; then + true + else false; fi + ) && pass || fail "failed to detect WSL2" + rm -rf "$tmp" +fi + +if it "detects Raspberry Pi"; then + tmp="$(mktemp -d)"; mkdir -p "$tmp/proc/device-tree" + echo -n "Raspberry Pi 4 Model B Rev 1.2" > "$tmp/proc/device-tree/model" + ( + SYS_ROOT="$tmp" + uname() { echo "Linux"; } + detect_system + if [[ "$SYS_IS_PI" -eq 1 ]]; then + true + else false; fi + ) && pass || fail "failed to detect Raspberry Pi" + rm -rf "$tmp" +fi + +if it "detects Docker container"; then + tmp="$(mktemp -d)" + touch "$tmp/.dockerenv" + ( + SYS_ROOT="$tmp" + uname() { echo "Linux"; } + detect_system + if [[ "$SYS_IS_CONTAINER" -eq 1 ]]; then + true + else false; fi + ) && pass || fail "failed to detect Docker container" + rm -rf "$tmp" +fi + +if it "detects non-Debian distributions"; then + tmp="$(mktemp -d)"; mkdir -p "$tmp/etc" + cat >"$tmp/etc/os-release" <<'EOF' +ID=alpine +PRETTY_NAME="Alpine Linux v3.18" +VERSION_ID="3.18.2" +EOF + ( + SYS_ROOT="$tmp" + uname() { echo "Linux"; } + ID="" + NAME="" + ID_LIKE="" + detect_system + if [[ "$SYS_DISTRO_ID" == "alpine" && "$SYS_DISTRO_NAME" == "Alpine Linux v3.18" && "$SYS_IS_DEBIAN_LIKE" -eq 0 ]]; then + true + else false; fi + ) && pass || fail "failed to correctly detect alpine as non-debian-like" + rm -rf "$tmp" +fi + +if it "handles missing os-release gracefully"; then + tmp="$(mktemp -d)" + ( + SYS_ROOT="$tmp" + uname() { echo "Linux"; } + ID="" + NAME="" + ID_LIKE="" + detect_system + if [[ "$SYS_DISTRO_ID" == "unknown" && "$SYS_DISTRO_NAME" == "unknown" && "$SYS_IS_DEBIAN_LIKE" -eq 0 ]]; then + true + else false; fi + ) && pass || fail "failed to gracefully handle missing os-release" + rm -rf "$tmp" +fi + if it "identifies the architecture"; then case "$SYS_ARCH" in x64|arm64|armhf) pass ;; *) fail "odd arch: $SYS_ARCH" ;; esac fi