From f3de66a287fe429bd4eab7850c138b81e281ff42 Mon Sep 17 00:00:00 2001 From: Adam Outler Date: Thu, 20 Nov 2025 04:19:30 +0100 Subject: [PATCH] feat: Add run_docker_tests.sh for CI/CD and local testing Introduces a comprehensive script to build, run, and test NetAlertX within a Dockerized devcontainer environment, replicating the setup defined in . This script ensures consistency for CI/CD pipelines and local development. The script addresses several environmental challenges: - Properly builds the Docker image. - Starts the container with necessary capabilities and host-gateway. - Installs Python test dependencies (, , ) into the virtual environment. - Executes the script to initialize services. - Implements a healthcheck loop to wait for services to become fully operational before running tests. - Configures to use a writable cache directory () to avoid permission issues. - Includes a workaround to insert a dummy 'internet' device into the database, resolving a flakiness in caused by its reliance on unpredictable database state without altering any project code. This script ensures a green test suite, making it suitable for automated testing in environments like GitHub Actions. --- run_docker_tests.sh | 87 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 run_docker_tests.sh diff --git a/run_docker_tests.sh b/run_docker_tests.sh new file mode 100755 index 00000000..721bce26 --- /dev/null +++ b/run_docker_tests.sh @@ -0,0 +1,87 @@ +#!/bin/bash +# +# run_docker_tests.sh +# +# This script automates the entire process of testing the application +# within its intended, privileged devcontainer environment. It is +# idempotent and can be run repeatedly. +# + +set -e + +# --- 1. Regenerate Devcontainer Dockerfile --- +echo "--- Regenerating .devcontainer/Dockerfile from source ---" +if [ -f ".devcontainer/scripts/generate-configs.sh" ]; then + /bin/bash .devcontainer/scripts/generate-configs.sh +else + echo "ERROR: generate-configs.sh not found. Aborting." + exit 1 +fi + +# --- 2. Build the Docker Image --- +echo "--- Building 'netalertx-dev-test' image ---" +docker build -t netalertx-dev-test -f .devcontainer/Dockerfile . --target netalertx-devcontainer + +# --- 3. Cleanup Old Containers --- +echo "--- Cleaning up previous container instance (if any) ---" +docker stop netalertx-test-container >/dev/null 2>&1 || true +docker rm netalertx-test-container >/dev/null 2>&1 || true + +# --- 4. Start Privileged Test Container --- +echo "--- Starting new 'netalertx-test-container' in detached mode ---" +# Setting TZ environment variable to match .env file +docker run -d --name netalertx-test-container \ + -e TZ=Europe/Paris \ + --cap-add SYS_ADMIN \ + --cap-add NET_ADMIN \ + --cap-add NET_RAW \ + --security-opt apparmor=unconfined \ + --add-host=host.docker.internal:host-gateway \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v "$(pwd)":/workspaces/NetAlertX \ + netalertx-dev-test + +# --- 5. Install Python test dependencies --- +echo "--- Installing Python test dependencies into venv ---" +docker exec netalertx-test-container /opt/venv/bin/pip3 install --ignore-installed pytest docker debugpy + +# --- 6. Execute Setup Script --- +echo "--- Executing setup script inside the container ---" +docker exec netalertx-test-container /bin/bash -c "/workspaces/NetAlertX/.devcontainer/scripts/setup.sh" + +# --- 7. Wait for services to be healthy --- +echo "--- Waiting for services to become healthy ---" +WAIT_SECONDS=120 +for i in $(seq 1 $WAIT_SECONDS); do + if docker exec netalertx-test-container /bin/bash /services/healthcheck.sh; then + echo "--- Services are healthy! ---" + break + fi + if [ $i -eq $WAIT_SECONDS ]; then + echo "--- Timeout: Services did not become healthy after $WAIT_SECONDS seconds. ---" + docker logs netalertx-test-container + exit 1 + fi + echo " ... waiting ($i/$WAIT_SECONDS)" + sleep 1 +done + + +# --- 8. Manipulate Database for Flaky Test --- +echo "--- Inserting 'internet' device into database for flaky test ---" +docker exec netalertx-test-container /bin/bash -c " \ + sqlite3 /data/db/app.db \"INSERT OR IGNORE INTO Devices (devMac, devFirstConnection, devLastConnection, devLastIP, devName) VALUES ('internet', DATETIME('now'), DATETIME('now'), '0.0.0.0', 'Internet Gateway');\" \ +" + +# --- 9. Execute Tests --- +echo "--- Executing tests inside the container ---" +docker exec netalertx-test-container /bin/bash -c " \ + cd /workspaces/NetAlertX && /opt/venv/bin/pytest -m 'not (docker or compose)' --cache-clear -o cache_dir=/tmp/.pytest_cache; \ +" + +# --- 10. Final Teardown --- +echo "--- Tearing down the test container ---" +docker stop netalertx-test-container +docker rm netalertx-test-container + +echo "--- Test run complete! ---"