Replace PIHOLE_DNS_1/PIHOLE_DNS_2 numbered variables with a bash array
PIHOLE_DNS=() throughout basic-install.sh. This naturally supports one
or more upstream DNS entries without duplicating a single entry into
both slots when no comma is present in the input.
- User input is split on commas into the array; empty entries skipped
- Invalid entries are filtered out; valid ones retained
- Confirmation dialog joins array elements so it reflects exactly what
was entered
- Preset DNS selection populates the array from the semicolon-delimited
preset string, adding a second element only when one is present
Closes#4783.
Signed-off-by: Austin Gilmour <gilmoursa@gmail.com>
Split the BATS suite into two containers: one for mock/function tests
and one for the fresh install, so installer tests can mutate the
filesystem freely without teardown.
Replace mocks.bash with bats-mock and bats-file, baked into the test
images at build time via Docker ARG-versioned git clones.
Improve the invalid-distro error to list available distros rather than
printing an opaque Dockerfile path.
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
Add ARG declarations and a build-time RUN step to all Dockerfiles so
bats-core, bats-support, bats-assert, bats-mock, and bats-file are cloned
at image build time rather than at container runtime. Library versions are
defined once in run.sh and passed down via --build-arg
Add .dockerignore to exclude any locally-cached test/libs/ directory from
the build context, preventing 'destination already exists' failures when
the directory exists from a previous local test run.
Remove the legacy commented-out sed stub command from all Dockerfiles
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
The test refactor intentionally prioritizes deterministic CI behavior and clearer semantics over historical transition scaffolding.
Reasoning behind the changes:
- Keep output consistent across distros by enabling pretty BATS output in all images; Alpine now installs ncurses so tput is available.
- Remove no-longer-needed migration plumbing in test/run.sh (CSV env handoff and extra local filename array), while preserving isolated /tmp tests execution to avoid installer side effects on /etc/.pihole.
- Rename ambiguous terminology from earlier direct-vs-legacy comparison and keep runner naming minimal (TEST_FILES, /tmp/tests).
- Clarify scope of the former FTL suite by renaming it to test_installer_ftl.bats and updating test titles to reflect that these validate installer architecture-detection/install paths.
- Reduce duplicated setup/teardown cleanup code in BATS files via shared reset helpers without changing behavior.
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
Replace the Python/tox-based test stack with BATS and run tests directly inside each built DISTRO container. Remove docker:cli orchestration and unify local mock helpers in test/helpers/mocks.bash for direct execution.
Signed-off-by: Adam Warner <me@adamwarner.co.uk>
gravity_build_tree is called twice in gravity.sh without exit status
checks. If either call fails (disk full, I/O error, DB corruption),
execution continues and gravity_swap_databases installs a database with
no search indexes. FTL then performs full table scans on every DNS
query against a potentially million-entry blocklist, causing DNS
timeouts with no logged error.
database_recovery() pipes sqlite3 .recover output into a second sqlite3
command without pipefail. A failure in the .recover command is invisible:
the RHS sqlite3 receives empty input, exits 0, and the if-branch signals
success. The empty recovered database is then swapped into production,
silently breaking DNS blocking. This affects the error-recovery path
specifically -- it triggers when the database is already corrupt and
makes it worse.
Add if ! guards to both gravity_build_tree calls. gravity_build_tree
already prints its own error on failure; the guards just stop execution
from continuing past a failed index build, matching the pattern used for
migrate_to_database and gravity_swap_databases in the same flow.
Stage the .recover output to a temp file in database_recovery() so each
command's exit status is checked independently. Use a RETURN trap for
temp-file cleanup so all exit paths are covered without repeating rm -f.
Error branches use return 1 and the call site handles script termination
with || exit 1.
Signed-off-by: John Luzzi <john.luzzi@gmail.com>