diff --git a/test/run.sh b/test/run.sh index dac34c7e..40ccd56f 100755 --- a/test/run.sh +++ b/test/run.sh @@ -75,10 +75,17 @@ BATS="${BATS:-libs/bats/bin/bats}" export IMAGE_TAG DISTRO DISTRO_FAMILY -TEST_FILES=(test_automated_install.bats test_utils.bats) +TEST_FILES=( + test_automated_install.bats + test_ftl.bats + test_network.bats + test_utils.bats +) [[ "$DISTRO_FAMILY" == "rhel" ]] && TEST_FILES+=(test_selinux.bats) -# Use pretty output only when stdout is a real terminal; fall back to TAP in CI +# Use pretty output only when stdout is a real terminal; fall back to TAP in CI. +# Parallelise across files with --jobs when GNU parallel is available. BATS_FLAGS=() [[ -t 1 ]] && BATS_FLAGS+=("-p") +command -v parallel > /dev/null 2>&1 && BATS_FLAGS+=("--jobs" "$(nproc)") "$BATS" "${BATS_FLAGS[@]}" "${TEST_FILES[@]}" diff --git a/test/test_automated_install.bats b/test/test_automated_install.bats index 5fb2cd3c..8d19d23e 100755 --- a/test/test_automated_install.bats +++ b/test/test_automated_install.bats @@ -1,5 +1,5 @@ #!/usr/bin/env bats -# Tests for basic-install.sh — translated from test_any_automated_install.py +# Core installer tests — package manager, cache, fresh install, dependencies load 'libs/bats-support/load' load 'libs/bats-assert/load' @@ -156,189 +156,6 @@ teardown() { assert_output --partial "Error: Unable to update package cache." } -# --------------------------------------------------------------------------- -# FTL architecture detection — one @test per arch (replaces parametrize) -# --------------------------------------------------------------------------- - -_test_ftl_arch() { - local arch="$1" detected_string="$2" supported="$3" - - mock_command "$CID" uname "-m" "$arch" "0" - mock_command_2 "$CID" readelf \ - "-A /bin/sh" "Tag_CPU_arch: ${arch}" "0" \ - "-A /usr/bin/sh" "Tag_CPU_arch: ${arch}" "0" \ - "-A /usr/sbin/sh" "Tag_CPU_arch: ${arch}" "0" - docker exec "$CID" bash -c "echo '${FTL_BRANCH}' > /etc/pihole/ftlbranch" - - run docker exec "$CID" bash -c " - source /opt/pihole/basic-install.sh - create_pihole_user - funcOutput=\$(get_binary_name) - binary=\"pihole-FTL\${funcOutput##*pihole-FTL}\" - theRest=\"\${funcOutput%pihole-FTL*}\" - FTLdetect \"\${binary}\" \"\${theRest}\" - " - - if [[ "$supported" == "true" ]]; then - assert_output --partial "${INFO} FTL Checks..." - assert_output --partial "${TICK} Detected ${detected_string} architecture" - assert_output --partial "${TICK} Downloading and Installing FTL" - else - assert_output --partial "Not able to detect architecture (unknown: ${detected_string})" - fi -} - -@test "FTL detects aarch64 architecture" { - _test_ftl_arch "aarch64" "AArch64 (64 Bit ARM)" "true" -} - -@test "FTL detects ARMv6 architecture" { - _test_ftl_arch "armv6" "ARMv6" "true" -} - -@test "FTL detects ARMv7l architecture" { - _test_ftl_arch "armv7l" "ARMv7 (or newer)" "true" -} - -@test "FTL detects ARMv7 architecture" { - _test_ftl_arch "armv7" "ARMv7 (or newer)" "true" -} - -@test "FTL detects ARMv8a architecture" { - _test_ftl_arch "armv8a" "ARMv7 (or newer)" "true" -} - -@test "FTL detects x86_64 architecture" { - _test_ftl_arch "x86_64" "x86_64" "true" -} - -@test "FTL detects riscv64 architecture" { - _test_ftl_arch "riscv64" "riscv64" "true" -} - -@test "FTL reports unsupported architecture" { - _test_ftl_arch "mips" "mips" "false" -} - -@test "FTL development binary is installed and responsive" { - docker exec "$CID" bash -c "echo '${FTL_BRANCH}' > /etc/pihole/ftlbranch" - docker exec "$CID" bash -c " - source /opt/pihole/basic-install.sh - create_pihole_user - funcOutput=\$(get_binary_name) - binary=\"pihole-FTL\${funcOutput##*pihole-FTL}\" - theRest=\"\${funcOutput%pihole-FTL*}\" - FTLdetect \"\${binary}\" \"\${theRest}\" - " - run docker exec "$CID" bash -c ' - VERSION=$(pihole-FTL version) - echo "${VERSION:0:1}" - ' - assert_output --partial "v" -} - -# --------------------------------------------------------------------------- -# IPv6 detection -# --------------------------------------------------------------------------- - -@test "IPv6 link-local only: blocking disabled" { - mock_command_2 "$CID" ip \ - "-6 address" "inet6 fe80::d210:52fa:fe00:7ad7/64 scope link" "0" - run docker exec "$CID" bash -c " - source /opt/pihole/basic-install.sh - find_IPv6_information - " - assert_output --partial "Unable to find IPv6 ULA/GUA address" -} - -@test "IPv6 ULA only: blocking enabled" { - mock_command_2 "$CID" ip \ - "-6 address" "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global" "0" - run docker exec "$CID" bash -c " - source /opt/pihole/basic-install.sh - find_IPv6_information - " - assert_output --partial "Found IPv6 ULA address" -} - -@test "IPv6 GUA only: blocking enabled" { - mock_command_2 "$CID" ip \ - "-6 address" "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global" "0" - run docker exec "$CID" bash -c " - source /opt/pihole/basic-install.sh - find_IPv6_information - " - assert_output --partial "Found IPv6 GUA address" -} - -@test "IPv6 GUA + ULA: ULA takes precedence" { - mock_command_2 "$CID" ip \ - "-6 address" "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global -inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global" "0" - run docker exec "$CID" bash -c " - source /opt/pihole/basic-install.sh - find_IPv6_information - " - assert_output --partial "Found IPv6 ULA address" -} - -@test "IPv6 ULA + GUA: ULA takes precedence" { - mock_command_2 "$CID" ip \ - "-6 address" "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global -inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global" "0" - run docker exec "$CID" bash -c " - source /opt/pihole/basic-install.sh - find_IPv6_information - " - assert_output --partial "Found IPv6 ULA address" -} - -# --------------------------------------------------------------------------- -# IP address validation -# --------------------------------------------------------------------------- - -@test "valid_ip accepts and rejects addresses correctly" { - _valid() { - run docker exec "$CID" bash -c "source /opt/pihole/basic-install.sh; valid_ip '${1}'" - assert_success - } - _invalid() { - run docker exec "$CID" bash -c "source /opt/pihole/basic-install.sh; valid_ip '${1}'" - assert_failure - } - - _valid "192.168.1.1" - _valid "127.0.0.1" - _valid "255.255.255.255" - _invalid "255.255.255.256" - _invalid "255.255.256.255" - _invalid "255.256.255.255" - _invalid "256.255.255.255" - _invalid "1092.168.1.1" - _invalid "not an IP" - _invalid "8.8.8.8#" - _valid "8.8.8.8#0" - _valid "8.8.8.8#1" - _valid "8.8.8.8#42" - _valid "8.8.8.8#888" - _valid "8.8.8.8#1337" - _valid "8.8.8.8#65535" - _invalid "8.8.8.8#65536" - _invalid "8.8.8.8#-1" - _invalid "00.0.0.0" - _invalid "010.0.0.0" - _invalid "001.0.0.0" - _invalid "0.0.0.0#00" - _invalid "0.0.0.0#01" - _invalid "0.0.0.0#001" - _invalid "0.0.0.0#0001" - _invalid "0.0.0.0#00001" -} - -# --------------------------------------------------------------------------- -# Package dependency installation -# --------------------------------------------------------------------------- - @test "OS can install required Pi-hole dependency packages" { mock_command "$CID" dialog "*" "" "0" run docker exec "$CID" bash -c " diff --git a/test/test_ftl.bats b/test/test_ftl.bats new file mode 100755 index 00000000..55f5d5da --- /dev/null +++ b/test/test_ftl.bats @@ -0,0 +1,104 @@ +#!/usr/bin/env bats +# FTL architecture detection and binary installation tests + +load 'libs/bats-support/load' +load 'libs/bats-assert/load' +load 'helpers/mocks' + +TICK="[✓]" +INFO="[i]" + +FTL_BRANCH="development" + +CID="" + +setup() { + CID=$(docker run -d -t --cap-add=ALL "$IMAGE_TAG") +} + +teardown() { + if [[ -n "$CID" ]]; then + docker rm -f "$CID" > /dev/null 2>&1 || true + fi +} + +# --------------------------------------------------------------------------- +# FTL architecture detection — one @test per arch (replaces parametrize) +# --------------------------------------------------------------------------- + +_test_ftl_arch() { + local arch="$1" detected_string="$2" supported="$3" + + mock_command "$CID" uname "-m" "$arch" "0" + mock_command_2 "$CID" readelf \ + "-A /bin/sh" "Tag_CPU_arch: ${arch}" "0" \ + "-A /usr/bin/sh" "Tag_CPU_arch: ${arch}" "0" \ + "-A /usr/sbin/sh" "Tag_CPU_arch: ${arch}" "0" + docker exec "$CID" bash -c "echo '${FTL_BRANCH}' > /etc/pihole/ftlbranch" + + run docker exec "$CID" bash -c " + source /opt/pihole/basic-install.sh + create_pihole_user + funcOutput=\$(get_binary_name) + binary=\"pihole-FTL\${funcOutput##*pihole-FTL}\" + theRest=\"\${funcOutput%pihole-FTL*}\" + FTLdetect \"\${binary}\" \"\${theRest}\" + " + + if [[ "$supported" == "true" ]]; then + assert_output --partial "${INFO} FTL Checks..." + assert_output --partial "${TICK} Detected ${detected_string} architecture" + assert_output --partial "${TICK} Downloading and Installing FTL" + else + assert_output --partial "Not able to detect architecture (unknown: ${detected_string})" + fi +} + +@test "FTL detects aarch64 architecture" { + _test_ftl_arch "aarch64" "AArch64 (64 Bit ARM)" "true" +} + +@test "FTL detects ARMv6 architecture" { + _test_ftl_arch "armv6" "ARMv6" "true" +} + +@test "FTL detects ARMv7l architecture" { + _test_ftl_arch "armv7l" "ARMv7 (or newer)" "true" +} + +@test "FTL detects ARMv7 architecture" { + _test_ftl_arch "armv7" "ARMv7 (or newer)" "true" +} + +@test "FTL detects ARMv8a architecture" { + _test_ftl_arch "armv8a" "ARMv7 (or newer)" "true" +} + +@test "FTL detects x86_64 architecture" { + _test_ftl_arch "x86_64" "x86_64" "true" +} + +@test "FTL detects riscv64 architecture" { + _test_ftl_arch "riscv64" "riscv64" "true" +} + +@test "FTL reports unsupported architecture" { + _test_ftl_arch "mips" "mips" "false" +} + +@test "FTL development binary is installed and responsive" { + docker exec "$CID" bash -c "echo '${FTL_BRANCH}' > /etc/pihole/ftlbranch" + docker exec "$CID" bash -c " + source /opt/pihole/basic-install.sh + create_pihole_user + funcOutput=\$(get_binary_name) + binary=\"pihole-FTL\${funcOutput##*pihole-FTL}\" + theRest=\"\${funcOutput%pihole-FTL*}\" + FTLdetect \"\${binary}\" \"\${theRest}\" + " + run docker exec "$CID" bash -c ' + VERSION=$(pihole-FTL version) + echo "${VERSION:0:1}" + ' + assert_output --partial "v" +} diff --git a/test/test_network.bats b/test/test_network.bats new file mode 100755 index 00000000..5e9bcfab --- /dev/null +++ b/test/test_network.bats @@ -0,0 +1,116 @@ +#!/usr/bin/env bats +# Network detection tests — IPv6 address detection and IP validation + +load 'libs/bats-support/load' +load 'libs/bats-assert/load' +load 'helpers/mocks' + +CID="" + +setup() { + CID=$(docker run -d -t --cap-add=ALL "$IMAGE_TAG") +} + +teardown() { + if [[ -n "$CID" ]]; then + docker rm -f "$CID" > /dev/null 2>&1 || true + fi +} + +# --------------------------------------------------------------------------- +# IPv6 detection +# --------------------------------------------------------------------------- + +@test "IPv6 link-local only: blocking disabled" { + mock_command_2 "$CID" ip \ + "-6 address" "inet6 fe80::d210:52fa:fe00:7ad7/64 scope link" "0" + run docker exec "$CID" bash -c " + source /opt/pihole/basic-install.sh + find_IPv6_information + " + assert_output --partial "Unable to find IPv6 ULA/GUA address" +} + +@test "IPv6 ULA only: blocking enabled" { + mock_command_2 "$CID" ip \ + "-6 address" "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global" "0" + run docker exec "$CID" bash -c " + source /opt/pihole/basic-install.sh + find_IPv6_information + " + assert_output --partial "Found IPv6 ULA address" +} + +@test "IPv6 GUA only: blocking enabled" { + mock_command_2 "$CID" ip \ + "-6 address" "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global" "0" + run docker exec "$CID" bash -c " + source /opt/pihole/basic-install.sh + find_IPv6_information + " + assert_output --partial "Found IPv6 GUA address" +} + +@test "IPv6 GUA + ULA: ULA takes precedence" { + mock_command_2 "$CID" ip \ + "-6 address" "inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global +inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global" "0" + run docker exec "$CID" bash -c " + source /opt/pihole/basic-install.sh + find_IPv6_information + " + assert_output --partial "Found IPv6 ULA address" +} + +@test "IPv6 ULA + GUA: ULA takes precedence" { + mock_command_2 "$CID" ip \ + "-6 address" "inet6 fda2:2001:5555:0:d210:52fa:fe00:7ad7/64 scope global +inet6 2003:12:1e43:301:d210:52fa:fe00:7ad7/64 scope global" "0" + run docker exec "$CID" bash -c " + source /opt/pihole/basic-install.sh + find_IPv6_information + " + assert_output --partial "Found IPv6 ULA address" +} + +# --------------------------------------------------------------------------- +# IP address validation +# --------------------------------------------------------------------------- + +@test "valid_ip accepts and rejects addresses correctly" { + _valid() { + run docker exec "$CID" bash -c "source /opt/pihole/basic-install.sh; valid_ip '${1}'" + assert_success + } + _invalid() { + run docker exec "$CID" bash -c "source /opt/pihole/basic-install.sh; valid_ip '${1}'" + assert_failure + } + + _valid "192.168.1.1" + _valid "127.0.0.1" + _valid "255.255.255.255" + _invalid "255.255.255.256" + _invalid "255.255.256.255" + _invalid "255.256.255.255" + _invalid "256.255.255.255" + _invalid "1092.168.1.1" + _invalid "not an IP" + _invalid "8.8.8.8#" + _valid "8.8.8.8#0" + _valid "8.8.8.8#1" + _valid "8.8.8.8#42" + _valid "8.8.8.8#888" + _valid "8.8.8.8#1337" + _valid "8.8.8.8#65535" + _invalid "8.8.8.8#65536" + _invalid "8.8.8.8#-1" + _invalid "00.0.0.0" + _invalid "010.0.0.0" + _invalid "001.0.0.0" + _invalid "0.0.0.0#00" + _invalid "0.0.0.0#01" + _invalid "0.0.0.0#001" + _invalid "0.0.0.0#0001" + _invalid "0.0.0.0#00001" +}