From 28007d9e5ac4c06f778c8eb1f0e2465d91611381 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 19 Oct 2026 22:11:07 +0000 Subject: [PATCH 1/4] fix(ci): distro jobs install their packages again Five distro jobs failed before any test ran: - debian:11 (distro matrix and the debian:11 integration test): the bullseye-security mirror now returns 404 for every package. Debian 11 is past end of life, so it leaves both matrices, the JSON matrix file and the local container runner. debian:12 stays. - rockylinux:9 and almalinux:9: dnf will not replace the image's curl-minimal with curl. `--allowerasing` lets it swap them, in the workflow and in the local runner's install line. - opensuse/leap:15.5 and opensuse/tumbleweed: actions/checkout unpacks the repository with tar, which neither image has. A step before checkout installs tar and gzip. These are the failures listed on #79. No container runtime was available here, so this PR's own CI is the test. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Y6FD63UrriRBHqmhhEca9t --- .github/workflows/distro-matrix.yml | 8 +++++--- .github/workflows/test.yml | 1 - tests/distro-matrix.json | 7 ------- tests/run-container-tests.sh | 3 +-- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/.github/workflows/distro-matrix.yml b/.github/workflows/distro-matrix.yml index 6c1b98d..2897419 100644 --- a/.github/workflows/distro-matrix.yml +++ b/.github/workflows/distro-matrix.yml @@ -37,8 +37,6 @@ jobs: image: ubuntu:22.04 - name: ubuntu-24.04 image: ubuntu:24.04 - - name: debian-11 - image: debian:11 - name: debian-12 image: debian:12 @@ -116,7 +114,7 @@ jobs: - name: Install dependencies run: | - dnf install -y \ + dnf install -y --allowerasing \ bash iproute iputils bind-utils curl sudo procps-ng ca-certificates - name: Setup scripts @@ -275,6 +273,10 @@ jobs: image: ${{ matrix.distro.image }} steps: + # actions/checkout unpacks the repository with tar, which these images lack. + - name: Install tar for checkout + run: zypper --non-interactive install tar gzip + - name: Checkout uses: actions/checkout@v7.0.1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 98402bb..bb267d2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -70,7 +70,6 @@ jobs: - ubuntu:20.04 - ubuntu:22.04 - ubuntu:24.04 - - debian:11 - debian:12 container: diff --git a/tests/distro-matrix.json b/tests/distro-matrix.json index e971aba..7bc40ca 100644 --- a/tests/distro-matrix.json +++ b/tests/distro-matrix.json @@ -23,13 +23,6 @@ "network_manager": "NetworkManager", "init": "systemd" }, - { - "name": "debian-11", - "image": "debian:11", - "package_manager": "apt", - "network_manager": "ifupdown", - "init": "systemd" - }, { "name": "debian-12", "image": "debian:12", diff --git a/tests/run-container-tests.sh b/tests/run-container-tests.sh index 6a56ad9..aca8578 100644 --- a/tests/run-container-tests.sh +++ b/tests/run-container-tests.sh @@ -40,7 +40,6 @@ declare -A DISTROS=( ["ubuntu-20.04"]="ubuntu:20.04" ["ubuntu-22.04"]="ubuntu:22.04" ["ubuntu-24.04"]="ubuntu:24.04" - ["debian-11"]="debian:11" ["debian-12"]="debian:12" # RHEL family ["fedora-39"]="fedora:39" @@ -73,7 +72,7 @@ get_install_cmd() { echo "apt-get update && apt-get install -y bash iproute2 iputils-ping dnsutils curl sudo procps" ;; fedora:*|rockylinux:*|almalinux:*) - echo "dnf install -y bash iproute iputils bind-utils curl sudo procps-ng" + echo "dnf install -y --allowerasing bash iproute iputils bind-utils curl sudo procps-ng" ;; archlinux:*) echo "pacman -Syu --noconfirm && pacman -S --noconfirm bash iproute2 iputils bind curl sudo procps-ng" From b435258940bd8193a1c6276451c6c7012284a17e Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 19 Oct 2026 22:46:18 +0000 Subject: [PATCH 2/4] fix(ci): install the tools the openSUSE Tumbleweed steps call With 28007d9 the openSUSE jobs check out and install their packages. Leap then reaches the help test, but Tumbleweed's minimal image has no find, so "Setup scripts" exits 127. The suse-family job, and the local container runner, now also install findutils, grep, sed, gawk, coreutils and hostname, the commands the later steps and the tests call. zypper leaves any that are already installed alone. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Y6FD63UrriRBHqmhhEca9t --- .github/workflows/distro-matrix.yml | 3 ++- tests/run-container-tests.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/distro-matrix.yml b/.github/workflows/distro-matrix.yml index 2897419..987d991 100644 --- a/.github/workflows/distro-matrix.yml +++ b/.github/workflows/distro-matrix.yml @@ -283,7 +283,8 @@ jobs: - name: Install dependencies run: | zypper --non-interactive install \ - bash iproute2 iputils bind-utils curl sudo procps ca-certificates + bash iproute2 iputils bind-utils curl sudo procps ca-certificates \ + findutils grep sed gawk coreutils hostname - name: Setup scripts run: | diff --git a/tests/run-container-tests.sh b/tests/run-container-tests.sh index aca8578..7fdc1d9 100644 --- a/tests/run-container-tests.sh +++ b/tests/run-container-tests.sh @@ -81,7 +81,7 @@ get_install_cmd() { echo "apk add --no-cache bash iproute2 iputils bind-tools curl sudo procps coreutils" ;; opensuse/*:*) - echo "zypper --non-interactive install bash iproute2 iputils bind-utils curl sudo procps" + echo "zypper --non-interactive install bash iproute2 iputils bind-utils curl sudo procps findutils grep sed gawk coreutils hostname" ;; *) echo "echo 'Unknown distro'" From 0d0f258d0d01fc089a4d817dc6174d1b216765b5 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Tue, 20 Oct 2026 00:45:04 +0000 Subject: [PATCH 3/4] fix(shell): prevent sourced modules from overwriting caller paths and stabilize tests --- src/diagnostics/connectivity.sh | 8 ++++---- src/diagnostics/dns.sh | 6 +++--- src/diagnostics/firewall.sh | 8 ++++---- src/diagnostics/interfaces.sh | 6 +++--- src/diagnostics/networkmanager.sh | 6 +++--- src/diagnostics/routing.sh | 6 +++--- src/repairs/dns.sh | 10 +++++----- src/repairs/interfaces.sh | 8 ++++---- src/repairs/networkmanager.sh | 8 ++++---- src/repairs/routing.sh | 12 ++++++------ src/utils/logging.sh | 4 ++-- src/utils/privileges.sh | 2 +- tests/run-tests.sh | 30 +++++++++++++++++++++++++++--- tests/test-utils.sh | 18 ++++++++++++++---- 14 files changed, 83 insertions(+), 49 deletions(-) diff --git a/src/diagnostics/connectivity.sh b/src/diagnostics/connectivity.sh index 6d2523b..5efae3d 100644 --- a/src/diagnostics/connectivity.sh +++ b/src/diagnostics/connectivity.sh @@ -2,9 +2,9 @@ # Connectivity diagnostics module # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" +DIAGNOSTICS_CONNECTIVITY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${DIAGNOSTICS_CONNECTIVITY_DIR}/../utils/logging.sh" +source "${DIAGNOSTICS_CONNECTIVITY_DIR}/../utils/system.sh" # Test basic connectivity test_basic_connectivity() { @@ -167,7 +167,7 @@ test_mtu() { # Subtract 28 bytes for IP + ICMP header local packet_size=$((size - 28)) - if ping -c 1 -W 2 -M do -s ${packet_size} 8.8.8.8 >/dev/null 2>&1; then + if ping -c 1 -W 2 -M 'do' -s ${packet_size} 8.8.8.8 >/dev/null 2>&1; then log_success " Packet size ${size} bytes: OK" break else diff --git a/src/diagnostics/dns.sh b/src/diagnostics/dns.sh index 51c5f09..1b4a1ef 100644 --- a/src/diagnostics/dns.sh +++ b/src/diagnostics/dns.sh @@ -2,9 +2,9 @@ # DNS diagnostics module # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" +DIAGNOSTICS_DNS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${DIAGNOSTICS_DNS_DIR}/../utils/logging.sh" +source "${DIAGNOSTICS_DNS_DIR}/../utils/system.sh" # Check DNS configuration check_dns_config() { diff --git a/src/diagnostics/firewall.sh b/src/diagnostics/firewall.sh index afbbf9a..f859020 100644 --- a/src/diagnostics/firewall.sh +++ b/src/diagnostics/firewall.sh @@ -2,10 +2,10 @@ # Firewall diagnostics module # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" -source "${SCRIPT_DIR}/../utils/privileges.sh" +DIAGNOSTICS_FIREWALL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${DIAGNOSTICS_FIREWALL_DIR}/../utils/logging.sh" +source "${DIAGNOSTICS_FIREWALL_DIR}/../utils/system.sh" +source "${DIAGNOSTICS_FIREWALL_DIR}/../utils/privileges.sh" # Check iptables rules check_iptables() { diff --git a/src/diagnostics/interfaces.sh b/src/diagnostics/interfaces.sh index dd429be..b2dd0fb 100644 --- a/src/diagnostics/interfaces.sh +++ b/src/diagnostics/interfaces.sh @@ -2,9 +2,9 @@ # Network interface diagnostics module # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" +DIAGNOSTICS_INTERFACES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${DIAGNOSTICS_INTERFACES_DIR}/../utils/logging.sh" +source "${DIAGNOSTICS_INTERFACES_DIR}/../utils/system.sh" # Check network interfaces check_interfaces() { diff --git a/src/diagnostics/networkmanager.sh b/src/diagnostics/networkmanager.sh index 89b9f7c..b0570b1 100644 --- a/src/diagnostics/networkmanager.sh +++ b/src/diagnostics/networkmanager.sh @@ -2,9 +2,9 @@ # NetworkManager diagnostics module # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" +DIAGNOSTICS_NETWORKMANAGER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${DIAGNOSTICS_NETWORKMANAGER_DIR}/../utils/logging.sh" +source "${DIAGNOSTICS_NETWORKMANAGER_DIR}/../utils/system.sh" # Check NetworkManager status check_nm_status() { diff --git a/src/diagnostics/routing.sh b/src/diagnostics/routing.sh index 59ce834..1a6f720 100644 --- a/src/diagnostics/routing.sh +++ b/src/diagnostics/routing.sh @@ -2,9 +2,9 @@ # Routing diagnostics module # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" +DIAGNOSTICS_ROUTING_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${DIAGNOSTICS_ROUTING_DIR}/../utils/logging.sh" +source "${DIAGNOSTICS_ROUTING_DIR}/../utils/system.sh" # Check routing table check_routing_table() { diff --git a/src/repairs/dns.sh b/src/repairs/dns.sh index 174686d..36be49e 100644 --- a/src/repairs/dns.sh +++ b/src/repairs/dns.sh @@ -2,11 +2,11 @@ # DNS repair procedures # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" -source "${SCRIPT_DIR}/../utils/privileges.sh" -source "${SCRIPT_DIR}/../utils/backup.sh" +REPAIRS_DNS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${REPAIRS_DNS_DIR}/../utils/logging.sh" +source "${REPAIRS_DNS_DIR}/../utils/system.sh" +source "${REPAIRS_DNS_DIR}/../utils/privileges.sh" +source "${REPAIRS_DNS_DIR}/../utils/backup.sh" # Repair DNS configuration repair_dns_config() { diff --git a/src/repairs/interfaces.sh b/src/repairs/interfaces.sh index 946e312..c504a3a 100644 --- a/src/repairs/interfaces.sh +++ b/src/repairs/interfaces.sh @@ -2,10 +2,10 @@ # Network interface repair procedures # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" -source "${SCRIPT_DIR}/../utils/privileges.sh" +REPAIRS_INTERFACES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${REPAIRS_INTERFACES_DIR}/../utils/logging.sh" +source "${REPAIRS_INTERFACES_DIR}/../utils/system.sh" +source "${REPAIRS_INTERFACES_DIR}/../utils/privileges.sh" # Bring up network interface interface_up() { diff --git a/src/repairs/networkmanager.sh b/src/repairs/networkmanager.sh index af850fe..c8550a2 100644 --- a/src/repairs/networkmanager.sh +++ b/src/repairs/networkmanager.sh @@ -2,10 +2,10 @@ # NetworkManager repair procedures # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" -source "${SCRIPT_DIR}/../utils/privileges.sh" +REPAIRS_NETWORKMANAGER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${REPAIRS_NETWORKMANAGER_DIR}/../utils/logging.sh" +source "${REPAIRS_NETWORKMANAGER_DIR}/../utils/system.sh" +source "${REPAIRS_NETWORKMANAGER_DIR}/../utils/privileges.sh" # Restart NetworkManager restart_networkmanager() { diff --git a/src/repairs/routing.sh b/src/repairs/routing.sh index deee95d..192d6a3 100644 --- a/src/repairs/routing.sh +++ b/src/repairs/routing.sh @@ -2,10 +2,10 @@ # Routing repair procedures # Source utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/../utils/logging.sh" -source "${SCRIPT_DIR}/../utils/system.sh" -source "${SCRIPT_DIR}/../utils/privileges.sh" +REPAIRS_ROUTING_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${REPAIRS_ROUTING_DIR}/../utils/logging.sh" +source "${REPAIRS_ROUTING_DIR}/../utils/system.sh" +source "${REPAIRS_ROUTING_DIR}/../utils/privileges.sh" # Add default route add_default_route() { @@ -134,7 +134,7 @@ repair_default_route() { log_step "Attempting to obtain gateway via DHCP" # Renew DHCP which should set up routes - source "${SCRIPT_DIR}/interfaces.sh" + source "${REPAIRS_ROUTING_DIR}/interfaces.sh" if renew_dhcp "${primary}"; then sleep 2 @@ -171,7 +171,7 @@ flush_routing_table() { log_step "Rebuilding routes via DHCP" # Renew DHCP to rebuild routes - source "${SCRIPT_DIR}/interfaces.sh" + source "${REPAIRS_ROUTING_DIR}/interfaces.sh" if renew_dhcp "${primary}"; then sleep 3 diff --git a/src/utils/logging.sh b/src/utils/logging.sh index 7f5b030..7eb1e3b 100644 --- a/src/utils/logging.sh +++ b/src/utils/logging.sh @@ -2,8 +2,8 @@ # Logging utilities for network repair tool # Source color utilities -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${SCRIPT_DIR}/colors.sh" +UTILS_LOGGING_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${UTILS_LOGGING_DIR}/colors.sh" # Log levels declare -gA LOG_LEVELS=( diff --git a/src/utils/privileges.sh b/src/utils/privileges.sh index 4ca6a64..3f28093 100644 --- a/src/utils/privileges.sh +++ b/src/utils/privileges.sh @@ -43,7 +43,7 @@ require_root() { SUDO_KEEPER_PID=$! # Kill sudo keeper on exit - trap "kill ${SUDO_KEEPER_PID} 2>/dev/null || true" EXIT + trap 'kill "${SUDO_KEEPER_PID}" 2>/dev/null || true' EXIT } # Run command with appropriate privileges diff --git a/tests/run-tests.sh b/tests/run-tests.sh index cb2ff0c..096ed76 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -172,6 +172,28 @@ test_utilities() { echo "" } +# Test nested imports without allowing modules to overwrite the caller's paths. +test_module_loading() { + echo -e "${BLUE}Testing Module Loading${NC}" + echo "" + + local module + for module in "${PROJECT_DIR}"/src/{utils,diagnostics,repairs}/*.sh; do + if bash -euo pipefail -c ' + cd / + readonly SCRIPT_DIR=/caller + source "$1" + [[ "${SCRIPT_DIR}" == /caller ]] + ' _ "${module}"; then + print_result "PASS" "${module#"${PROJECT_DIR}/"} loads independently" + else + print_result "FAIL" "${module#"${PROJECT_DIR}/"} loads independently" + fi + done + + echo "" +} + # Test main script test_main() { echo -e "${BLUE}Testing Main Script${NC}" @@ -252,9 +274,10 @@ test_safe_mode() { print_result "FAIL" "Repairs should be blocked in safe mode" fi - # Test that diagnose works without flags - if "${PROJECT_DIR}/network-repair" diagnose >/dev/null 2>&1 || \ - "${PROJECT_DIR}/network-repair" diagnose 2>&1 | grep -q "Diagnostic"; then + # This checks that safe mode allows diagnostics to start. Diagnostics may + # return a nonzero issue count; capture once to avoid pipefail/SIGPIPE. + output=$("${PROJECT_DIR}/network-repair" diagnose 2>&1) || true + if grep -q "Complete Network Diagnostics" <<< "${output}"; then print_result "PASS" "Diagnose works in safe mode" else print_result "FAIL" "Diagnose should work in safe mode" @@ -281,6 +304,7 @@ main() { test_utilities test_diagnostics test_repairs + test_module_loading test_main test_installation test_permissions diff --git a/tests/test-utils.sh b/tests/test-utils.sh index 98cd1fe..885247a 100755 --- a/tests/test-utils.sh +++ b/tests/test-utils.sh @@ -15,10 +15,20 @@ source "${PROJECT_DIR}/src/utils/system.sh" test_colors() { echo "Testing color utilities..." - # Test that color variables are defined - [[ -n "${COLOR_RED}" ]] || { echo "COLOR_RED not defined"; exit 1; } - [[ -n "${COLOR_GREEN}" ]] || { echo "COLOR_GREEN not defined"; exit 1; } - [[ -n "${COLOR_RESET}" ]] || { echo "COLOR_RESET not defined"; exit 1; } + # Colors are defined but may be empty when output is not a terminal. + [[ -v COLOR_RED ]] || { echo "COLOR_RED not defined"; exit 1; } + [[ -v COLOR_GREEN ]] || { echo "COLOR_GREEN not defined"; exit 1; } + [[ -v COLOR_RESET ]] || { echo "COLOR_RESET not defined"; exit 1; } + + # Explicitly disabling colors must produce plain output. + ( + USE_COLORS=never + source "${PROJECT_DIR}/src/utils/colors.sh" + [[ -z "${COLOR_RED}${COLOR_GREEN}${COLOR_RESET}" ]] || { + echo "Colors should be empty when disabled" + exit 1 + } + ) echo "✓ Color utilities work" } From c73c2a3e6dc5383315b95e25e5f40cb88a8a2047 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 20 Oct 2026 03:47:39 +0000 Subject: [PATCH 4/4] Revert CodeRabbit's SCRIPT_DIR port (0d0f258) CodeRabbit's CI-fix agent ported its own version of the SCRIPT_DIR fix into this PR. #79 is that fix, and the owner's order lands #79 first and keeps each PR to its own change rather than cross-porting. The port uses different variable names and tests from #79, so it would conflict with #79 in fourteen files once #79 merges. Its tests cover #79's change, not this one. This PR stays the distro install fix. Its jobs go green once #79 is in main. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Y6FD63UrriRBHqmhhEca9t --- src/diagnostics/connectivity.sh | 8 ++++---- src/diagnostics/dns.sh | 6 +++--- src/diagnostics/firewall.sh | 8 ++++---- src/diagnostics/interfaces.sh | 6 +++--- src/diagnostics/networkmanager.sh | 6 +++--- src/diagnostics/routing.sh | 6 +++--- src/repairs/dns.sh | 10 +++++----- src/repairs/interfaces.sh | 8 ++++---- src/repairs/networkmanager.sh | 8 ++++---- src/repairs/routing.sh | 12 ++++++------ src/utils/logging.sh | 4 ++-- src/utils/privileges.sh | 2 +- tests/run-tests.sh | 30 +++--------------------------- tests/test-utils.sh | 18 ++++-------------- 14 files changed, 49 insertions(+), 83 deletions(-) diff --git a/src/diagnostics/connectivity.sh b/src/diagnostics/connectivity.sh index 5efae3d..6d2523b 100644 --- a/src/diagnostics/connectivity.sh +++ b/src/diagnostics/connectivity.sh @@ -2,9 +2,9 @@ # Connectivity diagnostics module # Source utilities -DIAGNOSTICS_CONNECTIVITY_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${DIAGNOSTICS_CONNECTIVITY_DIR}/../utils/logging.sh" -source "${DIAGNOSTICS_CONNECTIVITY_DIR}/../utils/system.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" # Test basic connectivity test_basic_connectivity() { @@ -167,7 +167,7 @@ test_mtu() { # Subtract 28 bytes for IP + ICMP header local packet_size=$((size - 28)) - if ping -c 1 -W 2 -M 'do' -s ${packet_size} 8.8.8.8 >/dev/null 2>&1; then + if ping -c 1 -W 2 -M do -s ${packet_size} 8.8.8.8 >/dev/null 2>&1; then log_success " Packet size ${size} bytes: OK" break else diff --git a/src/diagnostics/dns.sh b/src/diagnostics/dns.sh index 1b4a1ef..51c5f09 100644 --- a/src/diagnostics/dns.sh +++ b/src/diagnostics/dns.sh @@ -2,9 +2,9 @@ # DNS diagnostics module # Source utilities -DIAGNOSTICS_DNS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${DIAGNOSTICS_DNS_DIR}/../utils/logging.sh" -source "${DIAGNOSTICS_DNS_DIR}/../utils/system.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" # Check DNS configuration check_dns_config() { diff --git a/src/diagnostics/firewall.sh b/src/diagnostics/firewall.sh index f859020..afbbf9a 100644 --- a/src/diagnostics/firewall.sh +++ b/src/diagnostics/firewall.sh @@ -2,10 +2,10 @@ # Firewall diagnostics module # Source utilities -DIAGNOSTICS_FIREWALL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${DIAGNOSTICS_FIREWALL_DIR}/../utils/logging.sh" -source "${DIAGNOSTICS_FIREWALL_DIR}/../utils/system.sh" -source "${DIAGNOSTICS_FIREWALL_DIR}/../utils/privileges.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" +source "${SCRIPT_DIR}/../utils/privileges.sh" # Check iptables rules check_iptables() { diff --git a/src/diagnostics/interfaces.sh b/src/diagnostics/interfaces.sh index b2dd0fb..dd429be 100644 --- a/src/diagnostics/interfaces.sh +++ b/src/diagnostics/interfaces.sh @@ -2,9 +2,9 @@ # Network interface diagnostics module # Source utilities -DIAGNOSTICS_INTERFACES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${DIAGNOSTICS_INTERFACES_DIR}/../utils/logging.sh" -source "${DIAGNOSTICS_INTERFACES_DIR}/../utils/system.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" # Check network interfaces check_interfaces() { diff --git a/src/diagnostics/networkmanager.sh b/src/diagnostics/networkmanager.sh index b0570b1..89b9f7c 100644 --- a/src/diagnostics/networkmanager.sh +++ b/src/diagnostics/networkmanager.sh @@ -2,9 +2,9 @@ # NetworkManager diagnostics module # Source utilities -DIAGNOSTICS_NETWORKMANAGER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${DIAGNOSTICS_NETWORKMANAGER_DIR}/../utils/logging.sh" -source "${DIAGNOSTICS_NETWORKMANAGER_DIR}/../utils/system.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" # Check NetworkManager status check_nm_status() { diff --git a/src/diagnostics/routing.sh b/src/diagnostics/routing.sh index 1a6f720..59ce834 100644 --- a/src/diagnostics/routing.sh +++ b/src/diagnostics/routing.sh @@ -2,9 +2,9 @@ # Routing diagnostics module # Source utilities -DIAGNOSTICS_ROUTING_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${DIAGNOSTICS_ROUTING_DIR}/../utils/logging.sh" -source "${DIAGNOSTICS_ROUTING_DIR}/../utils/system.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" # Check routing table check_routing_table() { diff --git a/src/repairs/dns.sh b/src/repairs/dns.sh index 36be49e..174686d 100644 --- a/src/repairs/dns.sh +++ b/src/repairs/dns.sh @@ -2,11 +2,11 @@ # DNS repair procedures # Source utilities -REPAIRS_DNS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${REPAIRS_DNS_DIR}/../utils/logging.sh" -source "${REPAIRS_DNS_DIR}/../utils/system.sh" -source "${REPAIRS_DNS_DIR}/../utils/privileges.sh" -source "${REPAIRS_DNS_DIR}/../utils/backup.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" +source "${SCRIPT_DIR}/../utils/privileges.sh" +source "${SCRIPT_DIR}/../utils/backup.sh" # Repair DNS configuration repair_dns_config() { diff --git a/src/repairs/interfaces.sh b/src/repairs/interfaces.sh index c504a3a..946e312 100644 --- a/src/repairs/interfaces.sh +++ b/src/repairs/interfaces.sh @@ -2,10 +2,10 @@ # Network interface repair procedures # Source utilities -REPAIRS_INTERFACES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${REPAIRS_INTERFACES_DIR}/../utils/logging.sh" -source "${REPAIRS_INTERFACES_DIR}/../utils/system.sh" -source "${REPAIRS_INTERFACES_DIR}/../utils/privileges.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" +source "${SCRIPT_DIR}/../utils/privileges.sh" # Bring up network interface interface_up() { diff --git a/src/repairs/networkmanager.sh b/src/repairs/networkmanager.sh index c8550a2..af850fe 100644 --- a/src/repairs/networkmanager.sh +++ b/src/repairs/networkmanager.sh @@ -2,10 +2,10 @@ # NetworkManager repair procedures # Source utilities -REPAIRS_NETWORKMANAGER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${REPAIRS_NETWORKMANAGER_DIR}/../utils/logging.sh" -source "${REPAIRS_NETWORKMANAGER_DIR}/../utils/system.sh" -source "${REPAIRS_NETWORKMANAGER_DIR}/../utils/privileges.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" +source "${SCRIPT_DIR}/../utils/privileges.sh" # Restart NetworkManager restart_networkmanager() { diff --git a/src/repairs/routing.sh b/src/repairs/routing.sh index 192d6a3..deee95d 100644 --- a/src/repairs/routing.sh +++ b/src/repairs/routing.sh @@ -2,10 +2,10 @@ # Routing repair procedures # Source utilities -REPAIRS_ROUTING_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${REPAIRS_ROUTING_DIR}/../utils/logging.sh" -source "${REPAIRS_ROUTING_DIR}/../utils/system.sh" -source "${REPAIRS_ROUTING_DIR}/../utils/privileges.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/../utils/logging.sh" +source "${SCRIPT_DIR}/../utils/system.sh" +source "${SCRIPT_DIR}/../utils/privileges.sh" # Add default route add_default_route() { @@ -134,7 +134,7 @@ repair_default_route() { log_step "Attempting to obtain gateway via DHCP" # Renew DHCP which should set up routes - source "${REPAIRS_ROUTING_DIR}/interfaces.sh" + source "${SCRIPT_DIR}/interfaces.sh" if renew_dhcp "${primary}"; then sleep 2 @@ -171,7 +171,7 @@ flush_routing_table() { log_step "Rebuilding routes via DHCP" # Renew DHCP to rebuild routes - source "${REPAIRS_ROUTING_DIR}/interfaces.sh" + source "${SCRIPT_DIR}/interfaces.sh" if renew_dhcp "${primary}"; then sleep 3 diff --git a/src/utils/logging.sh b/src/utils/logging.sh index 7eb1e3b..7f5b030 100644 --- a/src/utils/logging.sh +++ b/src/utils/logging.sh @@ -2,8 +2,8 @@ # Logging utilities for network repair tool # Source color utilities -UTILS_LOGGING_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -source "${UTILS_LOGGING_DIR}/colors.sh" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +source "${SCRIPT_DIR}/colors.sh" # Log levels declare -gA LOG_LEVELS=( diff --git a/src/utils/privileges.sh b/src/utils/privileges.sh index 3f28093..4ca6a64 100644 --- a/src/utils/privileges.sh +++ b/src/utils/privileges.sh @@ -43,7 +43,7 @@ require_root() { SUDO_KEEPER_PID=$! # Kill sudo keeper on exit - trap 'kill "${SUDO_KEEPER_PID}" 2>/dev/null || true' EXIT + trap "kill ${SUDO_KEEPER_PID} 2>/dev/null || true" EXIT } # Run command with appropriate privileges diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 096ed76..cb2ff0c 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -172,28 +172,6 @@ test_utilities() { echo "" } -# Test nested imports without allowing modules to overwrite the caller's paths. -test_module_loading() { - echo -e "${BLUE}Testing Module Loading${NC}" - echo "" - - local module - for module in "${PROJECT_DIR}"/src/{utils,diagnostics,repairs}/*.sh; do - if bash -euo pipefail -c ' - cd / - readonly SCRIPT_DIR=/caller - source "$1" - [[ "${SCRIPT_DIR}" == /caller ]] - ' _ "${module}"; then - print_result "PASS" "${module#"${PROJECT_DIR}/"} loads independently" - else - print_result "FAIL" "${module#"${PROJECT_DIR}/"} loads independently" - fi - done - - echo "" -} - # Test main script test_main() { echo -e "${BLUE}Testing Main Script${NC}" @@ -274,10 +252,9 @@ test_safe_mode() { print_result "FAIL" "Repairs should be blocked in safe mode" fi - # This checks that safe mode allows diagnostics to start. Diagnostics may - # return a nonzero issue count; capture once to avoid pipefail/SIGPIPE. - output=$("${PROJECT_DIR}/network-repair" diagnose 2>&1) || true - if grep -q "Complete Network Diagnostics" <<< "${output}"; then + # Test that diagnose works without flags + if "${PROJECT_DIR}/network-repair" diagnose >/dev/null 2>&1 || \ + "${PROJECT_DIR}/network-repair" diagnose 2>&1 | grep -q "Diagnostic"; then print_result "PASS" "Diagnose works in safe mode" else print_result "FAIL" "Diagnose should work in safe mode" @@ -304,7 +281,6 @@ main() { test_utilities test_diagnostics test_repairs - test_module_loading test_main test_installation test_permissions diff --git a/tests/test-utils.sh b/tests/test-utils.sh index 885247a..98cd1fe 100755 --- a/tests/test-utils.sh +++ b/tests/test-utils.sh @@ -15,20 +15,10 @@ source "${PROJECT_DIR}/src/utils/system.sh" test_colors() { echo "Testing color utilities..." - # Colors are defined but may be empty when output is not a terminal. - [[ -v COLOR_RED ]] || { echo "COLOR_RED not defined"; exit 1; } - [[ -v COLOR_GREEN ]] || { echo "COLOR_GREEN not defined"; exit 1; } - [[ -v COLOR_RESET ]] || { echo "COLOR_RESET not defined"; exit 1; } - - # Explicitly disabling colors must produce plain output. - ( - USE_COLORS=never - source "${PROJECT_DIR}/src/utils/colors.sh" - [[ -z "${COLOR_RED}${COLOR_GREEN}${COLOR_RESET}" ]] || { - echo "Colors should be empty when disabled" - exit 1 - } - ) + # Test that color variables are defined + [[ -n "${COLOR_RED}" ]] || { echo "COLOR_RED not defined"; exit 1; } + [[ -n "${COLOR_GREEN}" ]] || { echo "COLOR_GREEN not defined"; exit 1; } + [[ -n "${COLOR_RESET}" ]] || { echo "COLOR_RESET not defined"; exit 1; } echo "✓ Color utilities work" }