diff --git a/.github/workflows/test-and-build.yml b/.github/workflows/test-and-build.yml index 31ceb26ca..de9709e83 100644 --- a/.github/workflows/test-and-build.yml +++ b/.github/workflows/test-and-build.yml @@ -12,133 +12,151 @@ env: ghcr: ghcr.io/${{ github.repository_owner }}/pihole jobs: - build-and-test: + test: runs-on: ubuntu-latest strategy: fail-fast: false matrix: - registry: [dockerhub, ghcr] - platform: [linux/amd64, linux/386, linux/arm/v6, linux/arm/v7, linux/arm64/v8] - container: [3.18] - include: - - registry: dockerhub - platform: linux/riscv64 - container: edge - - registry: ghcr - platform: linux/riscv64 - container: edge + platform: [linux/amd64, linux/386, linux/arm/v6, linux/arm/v7, linux/arm64/v8, linux/riscv64] steps: - - name: Checkout Repo - uses: actions/checkout@v3 - with: - ref: development-v6 + - name: Checkout Repo + uses: actions/checkout@v3 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: ${{ matrix.platform}} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Run Tests + run: | + echo "Building image to test" + PLATFORM=${{ matrix.platform}} ./build-and-test.sh + # build: + # if: github.event_name != 'pull_request' + # runs-on: ubuntu-latest + # strategy: + # fail-fast: false + # matrix: + # registry: [dockerhub, ghcr] + # platform: [linux/amd64, linux/386, linux/arm/v6, linux/arm/v7, linux/arm64/v8] + # container: [3.18] + # include: + # - registry: dockerhub + # platform: linux/riscv64 + # container: edge + # - registry: ghcr + # platform: linux/riscv64 + # container: edge + # steps: + # - name: Checkout Repo + # uses: actions/checkout@v3 - - name: Docker meta (Docker Hub and GitHub Container Registry) - id: meta - uses: docker/metadata-action@v4 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - images: | - ${{ env[matrix.registry] }} - flavor: | - latest=false - tags: | - development-v6 + # - name: Docker meta (Docker Hub and GitHub Container Registry) + # id: meta + # uses: docker/metadata-action@v4 + # with: + # github-token: ${{ secrets.GITHUB_TOKEN }} + # images: | + # ${{ env[matrix.registry] }} + # flavor: | + # latest=false + # tags: | + # development-v6 - - name: Login to DockerHub and GitHub Container Registry - if: github.event_name != 'pull_request' - uses: ./.github/actions/login-repo - with: - docker_username: ${{ secrets.DOCKERHUB_USER }} - docker_password: ${{ secrets.DOCKERHUB_PASS }} - ghcr_username: ${{ github.repository_owner }} - ghcr_password: ${{ secrets.GITHUB_TOKEN }} + # - name: Login to DockerHub and GitHub Container Registry + # if: github.event_name != 'pull_request' + # uses: ./.github/actions/login-repo + # with: + # docker_username: ${{ secrets.DOCKERHUB_USER }} + # docker_password: ${{ secrets.DOCKERHUB_PASS }} + # ghcr_username: ${{ github.repository_owner }} + # ghcr_password: ${{ secrets.GITHUB_TOKEN }} - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - with: - platforms: all - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + # - name: Set up QEMU + # uses: docker/setup-qemu-action@v2 + # with: + # platforms: ${{ matrix.platform}} + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v2 - - name: Build container and push by digest (${{ matrix.registry }}) - id: build - uses: docker/build-push-action@v4 - with: - context: ./src/ - platforms: ${{ matrix.platform }} - build-args: | - PIHOLE_DOCKER_TAG=${{ steps.meta.outputs.version }} - CONTAINER=${{ matrix.container }} - labels: ${{ steps.meta.outputs.labels }} - outputs: | - type=image,name=${{ env[matrix.registry] }},push-by-digest=${{ github.event_name != 'pull_request' }},name-canonical=true,push=${{ github.event_name != 'pull_request' }} + # - name: Build container and push by digest (${{ matrix.registry }}) + # id: build + # uses: docker/build-push-action@v4 + # with: + # context: ./src/ + # platforms: ${{ matrix.platform }} + # build-args: | + # PIHOLE_DOCKER_TAG=${{ steps.meta.outputs.version }} + # CONTAINER=${{ matrix.container }} + # labels: ${{ steps.meta.outputs.labels }} + # outputs: | + # type=image,name=${{ env[matrix.registry] }},push-by-digest=${{ github.event_name != 'pull_request' }},name-canonical=true,push=${{ github.event_name != 'pull_request' }} - - name: Export digests - run: | - mkdir -p /tmp/digests/${{ matrix.registry }} - digest_docker="${{ steps.build.outputs.digest }}" - touch "/tmp/digests/${{ matrix.registry }}/${digest_docker#sha256:}" + # - name: Export digests + # run: | + # mkdir -p /tmp/digests/${{ matrix.registry }} + # digest_docker="${{ steps.build.outputs.digest }}" + # touch "/tmp/digests/${{ matrix.registry }}/${digest_docker#sha256:}" - - name: Upload digest - uses: actions/upload-artifact@v3 - with: - name: digests - path: /tmp/digests/* - if-no-files-found: error - retention-days: 1 + # - name: Upload digest + # uses: actions/upload-artifact@v3 + # with: + # name: digests + # path: /tmp/digests/* + # if-no-files-found: error + # retention-days: 1 - # Merge all the digests into a single file - # If we would push immediately above, the individual runners would overwrite each other's images - # https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners - merge-and-deploy: - if: github.event_name != 'pull_request' - strategy: - fail-fast: false - matrix: - registry: [dockerhub, ghcr] - runs-on: ubuntu-latest - needs: - - build-and-test - steps: - - name: Checkout Repo - uses: actions/checkout@v3 + # # Merge all the digests into a single file + # # If we would push immediately above, the individual runners would overwrite each other's images + # # https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners + # merge-and-deploy: + # if: github.event_name != 'pull_request' + # strategy: + # fail-fast: false + # matrix: + # registry: [dockerhub, ghcr] + # runs-on: ubuntu-latest + # needs: + # - build + # steps: + # - name: Checkout Repo + # uses: actions/checkout@v3 - - name: Download digests - uses: actions/download-artifact@v3 - with: - name: digests - path: /tmp/digests + # - name: Download digests + # uses: actions/download-artifact@v3 + # with: + # name: digests + # path: /tmp/digests - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v2 - - name: Login to DockerHub and GitHub Container Registry - uses: ./.github/actions/login-repo - with: - docker_username: ${{ secrets.DOCKERHUB_USER }} - docker_password: ${{ secrets.DOCKERHUB_PASS }} - ghcr_username: ${{ github.repository_owner }} - ghcr_password: ${{ secrets.GITHUB_TOKEN }} + # - name: Login to DockerHub and GitHub Container Registry + # uses: ./.github/actions/login-repo + # with: + # docker_username: ${{ secrets.DOCKERHUB_USER }} + # docker_password: ${{ secrets.DOCKERHUB_PASS }} + # ghcr_username: ${{ github.repository_owner }} + # ghcr_password: ${{ secrets.GITHUB_TOKEN }} - - name: Docker meta (Docker Hub and GitHub Container Registry) - id: meta - uses: docker/metadata-action@v4 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - images: | - ${{ env[matrix.registry] }} - flavor: | - latest=false - tags: | - development-v6 + # - name: Docker meta (Docker Hub and GitHub Container Registry) + # id: meta + # uses: docker/metadata-action@v4 + # with: + # github-token: ${{ secrets.GITHUB_TOKEN }} + # images: | + # ${{ env[matrix.registry] }} + # flavor: | + # latest=false + # tags: | + # development-v6 - - name: Create manifest list and push (${{ matrix.registry }}) - working-directory: /tmp/digests/${{ matrix.registry }} - run: | - docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ - $(printf '${{ env[matrix.registry] }}@sha256:%s ' *) + # - name: Create manifest list and push (${{ matrix.registry }}) + # working-directory: /tmp/digests/${{ matrix.registry }} + # run: | + # docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + # $(printf '${{ env[matrix.registry] }}@sha256:%s ' *) - - name: Inspect image - run: | - docker buildx imagetools inspect ${{ env[matrix.registry] }}:${{ steps.meta.outputs.version }} + # - name: Inspect image + # run: | + # docker buildx imagetools inspect ${{ env[matrix.registry] }}:${{ steps.meta.outputs.version }} diff --git a/build-and-test.sh b/build-and-test.sh index b73ed1566..353535ea1 100755 --- a/build-and-test.sh +++ b/build-and-test.sh @@ -8,9 +8,10 @@ fi GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD | sed "s/\//-/g") GIT_TAG=$(git describe --tags --exact-match 2> /dev/null || true) GIT_TAG="${GIT_TAG:-$GIT_BRANCH}" +PLATFORM="${PLATFORM:-linux/amd64}" # generate and build dockerfile -docker build --tag image_pipenv --file test/Dockerfile test/ +docker buildx build --load --platform=${PLATFORM} --tag image_pipenv --file test/Dockerfile test/ docker run --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume "$(pwd):/$(pwd)" \ diff --git a/test/Dockerfile b/test/Dockerfile index 511833ae4..4aaaeb360 100644 --- a/test/Dockerfile +++ b/test/Dockerfile @@ -1,18 +1,12 @@ -FROM python:3.10-slim-bullseye +FROM python:3.10-alpine3.18 # Only works for docker CLIENT (bind mounted socket) COPY --from=docker:20.10.17 /usr/local/bin/docker /usr/local/bin/ -ARG packages -RUN apt-get update && \ - apt-get install -y python3-dev curl gcc make \ - libffi-dev libssl-dev ${packages} \ - && rm -rf /var/lib/apt/lists/* \ +RUN apk add --no-cache \ + curl \ && pip3 install --no-cache-dir -U pip pipenv -RUN curl -L https://github.com/docker/compose/releases/download/2.10.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && \ - chmod +x /usr/local/bin/docker-compose - COPY ./cmd.sh /usr/local/bin/ COPY Pipfile* /root/ WORKDIR /root diff --git a/test/cmd.sh b/test/cmd.sh index 958a8d8ec..e5ee55f40 100755 --- a/test/cmd.sh +++ b/test/cmd.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh set -eux docker build ./src --tag pihole:${GIT_TAG} --no-cache @@ -9,4 +9,4 @@ python -m black ./test/tests/ # TODO: Add junitxml output and have something consume it # 2 parallel max b/c race condition with docker fixture (I think?) -py.test -vv -n 2 ./test/tests/ +py.test -vv -n auto ./test/tests/ diff --git a/test/tests/conftest.py b/test/tests/conftest.py index 99e080542..1399160f1 100644 --- a/test/tests/conftest.py +++ b/test/tests/conftest.py @@ -42,7 +42,7 @@ def args_volumes(): @pytest.fixture() def args_env(): - return '-e FTLCONF_LOCAL_IPV4="127.0.0.1"' + return '-e TZ="Europe/London"' @pytest.fixture() @@ -87,33 +87,6 @@ def docker(request, test_args, args, image, cmd, entrypoint): return docker_generic(request, test_args, args, image, cmd, entrypoint) -@pytest.fixture(scope="module") -def docker_persist( - request, - persist_test_args, - persist_args, - persist_image, - persist_cmd, - persist_entrypoint, - dig, -): - """ - Persistent Docker container for multiple tests, instead of stopping container after one test - Uses DUP'd module scoped fixtures because smaller scoped fixtures won't mix with module scope - """ - persistent_container = docker_generic( - request, - persist_test_args, - persist_args, - persist_image, - persist_cmd, - persist_entrypoint, - ) - """ attach a dig container for lookups """ - persistent_container.dig = dig(persistent_container.id) - return persistent_container - - @pytest.fixture def entrypoint(): return "" @@ -129,12 +102,6 @@ def tag(version): return "{}".format(version) -@pytest.fixture -def webserver(tag): - """TODO: this is obvious without alpine+nginx as the alternative, remove fixture, hard code lighttpd in tests?""" - return "lighttpd" - - @pytest.fixture() def image(tag): image = "pihole" @@ -146,64 +113,6 @@ def cmd(): return TAIL_DEV_NULL -@pytest.fixture(scope="module") -def persist_version(): - return version - - -@pytest.fixture(scope="module") -def persist_args_dns(): - return "--dns 127.0.0.1 --dns 1.1.1.1" - - -@pytest.fixture(scope="module") -def persist_args_volumes(): - return "-v /dev/null:/etc/pihole/adlists.list" - - -@pytest.fixture(scope="module") -def persist_args_env(): - return '-e ServerIP="127.0.0.1"' - - -@pytest.fixture(scope="module") -def persist_args(persist_args_volumes, persist_args_env): - return "{} {}".format(persist_args_volumes, persist_args_env) - - -@pytest.fixture(scope="module") -def persist_test_args(): - """test override fixture to provide arguments separate from our core args""" - return "" - - -@pytest.fixture(scope="module") -def persist_tag(persist_version): - return "{}".format(persist_version) - - -@pytest.fixture(scope="module") -def persist_webserver(persist_tag): - """TODO: this is obvious without alpine+nginx as the alternative, remove fixture, hard code lighttpd in tests?""" - return "lighttpd" - - -@pytest.fixture(scope="module") -def persist_image(persist_tag): - image = "pihole" - return "{}:{}".format(image, persist_tag) - - -@pytest.fixture(scope="module") -def persist_cmd(): - return TAIL_DEV_NULL - - -@pytest.fixture(scope="module") -def persist_entrypoint(): - return "" - - @pytest.fixture def slow(): """ @@ -225,26 +134,3 @@ def _slow(check, timeout=20): return return _slow - - -@pytest.fixture(scope="module") -def dig(): - """separate container to link to pi-hole and perform lookups""" - """ a docker pull is faster than running an install of dnsutils """ - - def _dig(docker_id): - args = "--link {}:test_pihole".format(docker_id) - image = "azukiapp/dig" - cmd = TAIL_DEV_NULL - dig_container = docker_generic(request, "", args, image, cmd, "") - return dig_container - - return _dig - - -@pytest.fixture -def running_pihole(docker_persist, slow, persist_webserver): - """Persist a fully started docker-pi-hole to help speed up subsequent tests""" - slow(lambda: docker_persist.run("pgrep pihole-FTL").rc == 0) - slow(lambda: docker_persist.run("pgrep lighttpd").rc == 0) - return docker_persist diff --git a/test/tests/test_bash_functions.py b/test/tests/test_bash_functions.py index 64540b9f4..c80543bae 100644 --- a/test/tests/test_bash_functions.py +++ b/test/tests/test_bash_functions.py @@ -2,289 +2,77 @@ import pytest import re -SETUPVARS_LOC = "/etc/pihole/setupVars.conf" -DNSMASQ_CONFIG_LOC = "/etc/dnsmasq.d/01-pihole.conf" -CMD_SETUP_FTL_CACHESIZE = ". bash_functions.sh ; setup_FTL_CacheSize" -CMD_SETUP_FTL_INTERFACE = ". bash_functions.sh ; setup_FTL_Interface" -CMD_SETUP_WEB_PASSWORD = ". bash_functions.sh ; setup_web_password" +# CMD_SETUP_WEB_PASSWORD = ". bash_functions.sh ; setup_web_password" +CMD_APPLY_FTL_CONFIG_FROM_ENV = ". bash_functions.sh ; apply_FTL_Configs_From_Env" -def _cat(file): - return "cat {}".format(file) - - -def _grep(string, file): - return "grep -q '{}' {}".format(string, file) +@pytest.mark.parametrize("test_args", ['-e "FTLCONF_webserver_port=999"']) +def test_FTLCONF_webserver_port(docker, test_args): + function = docker.run(CMD_APPLY_FTL_CONFIG_FROM_ENV) + assert "Applied pihole-FTL setting webserver.port=999" in function.stdout @pytest.mark.parametrize( - "test_args,expected_ipv6,expected_stdout", - [ - ("", True, "IPv4 and IPv6"), - ('-e "IPv6=True"', True, "IPv4 and IPv6"), - ('-e "IPv6=False"', False, "IPv4"), - ('-e "IPv6=foobar"', False, "IPv4"), - ], + "test_args", ['-e "FTLCONF_dns_upstreams=1.1.1.1;8.8.8.8#1234"'] ) -def test_ipv6_not_true_removes_ipv6( - docker, slow, test_args, expected_ipv6, expected_stdout -): - """When a user overrides IPv6=True they only get IPv4 listening webservers""" - IPV6_LINE = "use-ipv6.pl" - WEB_CONFIG = "/etc/lighttpd/lighttpd.conf" - - function = docker.run(". /usr/local/bin/bash_functions.sh ; setup_ipv4_ipv6") - assert "Using {}".format(expected_stdout) in function.stdout - if expected_stdout == "IPv4": - assert "IPv6" not in function.stdout - # On overlay2(?) docker sometimes writes to disk are slow enough to break some tests... - expected_ipv6_check = ( - lambda: ( - IPV6_LINE in docker.run("grep 'use-ipv6.pl' {}".format(WEB_CONFIG)).stdout - ) - == expected_ipv6 - ) - slow(expected_ipv6_check) - - -@pytest.mark.parametrize("test_args", ['-e "WEB_PORT=999"']) -def test_overrides_default_web_port(docker, slow, test_args): - """When a --net=host user sets WEB_PORT to avoid synology's 80 default IPv4 and or IPv6 ports are updated""" - CONFIG_LINE = r"server.port\s*=\s*999" - WEB_CONFIG = "/etc/lighttpd/lighttpd.conf" - - function = docker.run( - ". /usr/local/bin/bash_functions.sh ; eval `grep setup_web_port /usr/local/bin/_startup.sh`" - ) - assert " [i] Custom WEB_PORT set to 999" in function.stdout +def test_FTLCONF_dns_upstreams(docker, test_args): + function = docker.run(CMD_APPLY_FTL_CONFIG_FROM_ENV) assert ( - " [i] Without proper router DNAT forwarding to 127.0.0.1:999, you may not get any blocked websites on ads" + 'Applied pihole-FTL setting dns.upstreams=["1.1.1.1","8.8.8.8#1234"]' in function.stdout ) - slow( - lambda: re.search(CONFIG_LINE, docker.run(_cat(WEB_CONFIG)).stdout) is not None - ) - - -@pytest.mark.parametrize( - "test_args,expected_error", - [ - ( - '-e WEB_PORT="LXXX"', - "WARNING: Custom WEB_PORT not used - LXXX is not an integer", - ), - ( - '-e WEB_PORT="1,000"', - "WARNING: Custom WEB_PORT not used - 1,000 is not an integer", - ), - ( - '-e WEB_PORT="99999"', - "WARNING: Custom WEB_PORT not used - 99999 is not within valid port range of 1-65535", - ), - ], -) -def test_bad_input_to_web_port(docker, test_args, expected_error): - function = docker.run( - ". /usr/local/bin/bash_functions.sh ; eval `grep setup_web_port /usr/local/bin/_startup.sh`" - ) - assert expected_error in function.stdout - - -@pytest.mark.parametrize( - "test_args,cache_size", - [('-e CUSTOM_CACHE_SIZE="0"', "0"), ('-e CUSTOM_CACHE_SIZE="20000"', "20000")], -) -def test_overrides_default_custom_cache_size(docker, slow, test_args, cache_size): - """Changes the cache_size setting to increase or decrease the cache size for dnsmasq""" - CONFIG_LINE = r"cache-size\s*=\s*{}".format(cache_size) - - function = docker.run( - "echo ${CUSTOM_CACHE_SIZE};. ./usr/local/bin/bash_functions.sh; echo ${CUSTOM_CACHE_SIZE}; eval `grep setup_FTL_CacheSize /usr/local/bin/_startup.sh`" - ) - assert "Custom CUSTOM_CACHE_SIZE set to {}".format(cache_size) in function.stdout - slow( - lambda: re.search(CONFIG_LINE, docker.run(_cat(DNSMASQ_CONFIG_LOC)).stdout) - is not None - ) - - -@pytest.mark.parametrize( - "test_args", - [ - '-e CUSTOM_CACHE_SIZE="-1"', - '-e CUSTOM_CACHE_SIZE="1,000"', - ], -) -def test_bad_input_to_custom_cache_size(docker, slow, test_args): - CONFIG_LINE = r"cache-size\s*=\s*10000" - - docker.run(CMD_SETUP_FTL_CACHESIZE) - slow( - lambda: re.search(CONFIG_LINE, docker.run(_cat(DNSMASQ_CONFIG_LOC)).stdout) - is not None - ) - - -@pytest.mark.parametrize( - "test_args", - [ - '-e DNSSEC="true" -e CUSTOM_CACHE_SIZE="0"', - ], -) -def test_dnssec_enabled_with_custom_cache_size(docker, slow, test_args): - CONFIG_LINE = r"cache-size\s*=\s*10000" - - docker.run(CMD_SETUP_FTL_CACHESIZE) - slow( - lambda: re.search(CONFIG_LINE, docker.run(_cat(DNSMASQ_CONFIG_LOC)).stdout) - is not None - ) - - -@pytest.mark.parametrize( - "args_env, expected_stdout, expected_config_line", - [ - ("", "binding to default interface: eth0", "PIHOLE_INTERFACE=eth0"), - ( - '-e INTERFACE="br0"', - "binding to custom interface: br0", - "PIHOLE_INTERFACE=br0", - ), - ], -) -def test_dns_interface_override_defaults( - docker, slow, args_env, expected_stdout, expected_config_line -): - """When INTERFACE environment var is passed in, overwrite dnsmasq interface""" - function = docker.run(CMD_SETUP_FTL_INTERFACE) - assert expected_stdout in function.stdout - slow( - lambda: expected_config_line + "\n" - == docker.run('grep "^PIHOLE_INTERFACE" {}'.format(SETUPVARS_LOC)).stdout - ) - - -expected_debian_lines = [ - '"VIRTUAL_HOST" => "127.0.0.1"', - '"PHP_ERROR_LOG" => "/var/log/lighttpd/error-pihole.log"', -] - - -@pytest.mark.parametrize( - "expected_lines,repeat_function", - [(expected_debian_lines, 1), (expected_debian_lines, 2)], -) -def test_debian_setup_php_env(docker, expected_lines, repeat_function): - """confirm all expected output is there and nothing else""" - for _ in range(repeat_function): - docker.run( - ". /usr/local/bin/bash_functions.sh ; eval `grep setup_php_env /usr/local/bin/_startup.sh`" - ) - for expected_line in expected_lines: - search_config_cmd = ( - "grep -c '{}' /etc/lighttpd/conf-enabled/15-pihole-admin.conf".format( - expected_line - ) - ) - search_config_count = docker.run(search_config_cmd) - found_lines = int(search_config_count.stdout.rstrip("\n")) - if found_lines > 1: - assert ( - False - ), f"Found line {expected_line} times (more than once): {found_lines}" - - -def test_webpassword_random_generation(docker): - """When a user sets webPassword env the admin password gets set to that""" - function = docker.run(CMD_SETUP_WEB_PASSWORD) - assert "assigning random password" in function.stdout.lower() - - -@pytest.mark.parametrize("entrypoint,cmd", [("--entrypoint=tail", "-f /dev/null")]) -@pytest.mark.parametrize( - "args_env,secure,setupvars_hash", - [ - ( - "-e WEBPASSWORD=login", - True, - "WEBPASSWORD=6060d59351e8c2f48140f01b2c3f3b61652f396c53a5300ae239ebfbe7d5ff08", - ), - ('-e WEBPASSWORD=""', False, ""), - ], -) -def test_webpassword_env_assigns_password_to_file_or_removes_if_empty( - docker, args_env, secure, setupvars_hash -): - """When a user sets webPassword env the admin password gets set or removed if empty""" - function = docker.run(CMD_SETUP_WEB_PASSWORD) - - if secure: - assert "new password set" in function.stdout.lower() - assert docker.run(_grep(setupvars_hash, SETUPVARS_LOC)).rc == 0 - else: - assert "password removed" in function.stdout.lower() - assert docker.run(_grep("^WEBPASSWORD=$", SETUPVARS_LOC)).rc == 0 - - -@pytest.mark.parametrize("entrypoint,cmd", [("--entrypoint=tail", "-f /dev/null")]) -@pytest.mark.parametrize("test_args", ["-e WEBPASSWORD=login", '-e WEBPASSWORD=""']) -def test_env_always_updates_password(docker, args_env, test_args): - """When a user sets the WEBPASSWORD environment variable, ensure it always sets the password""" - function = docker.run(CMD_SETUP_WEB_PASSWORD) - - assert " [i] Assigning password defined by Environment Variable" in function.stdout - - -@pytest.mark.parametrize("entrypoint,cmd", [("--entrypoint=tail", "-f /dev/null")]) -def test_setupvars_trumps_random_password_if_set(docker, args_env, test_args): - """If a password is already set in setupvars, and no password is set in the environment variable, do not generate a random password""" - docker.run( - ". /opt/pihole/utils.sh ; addOrEditKeyValPair {} WEBPASSWORD volumepass".format( - SETUPVARS_LOC - ) - ) - function = docker.run(CMD_SETUP_WEB_PASSWORD) - - assert "Pre existing WEBPASSWORD found" in function.stdout - assert docker.run(_grep("WEBPASSWORD=volumepass", SETUPVARS_LOC)).rc == 0 - - -@pytest.mark.parametrize( - "args_env,test_args,expected_bind,expect_warning", - [ - ("-e FTLCONF_LOCAL_IPV4=192.0.2.10", "--net=host", "192.0.2.10", True), - ("-e FTLCONF_LOCAL_IPV4=192.0.2.10", "", "0.0.0.0", False), - ( - "-e WEB_BIND_ADDR=192.0.2.20 -e FTLCONF_LOCAL_IPV4=192.0.2.10", - "--net=host", - "192.0.2.20", - False, - ), - ( - "-e WEB_BIND_ADDR=192.0.2.20 -e FTLCONF_LOCAL_IPV4=192.0.2.10", - "", - "192.0.2.20", - False, - ), - ], -) -def test_setup_lighttpd_bind( - docker, args_env, test_args, expected_bind, expect_warning -): - """Lighttpd's bind address is correctly set""" - WEB_CONFIG = "/etc/lighttpd/lighttpd.conf" - WARNING_EXTRACT = "[i] WARNING: running in host network mode forces" - - function = docker.run(". /usr/local/bin/bash_functions.sh ; setup_lighttpd_bind") - - if expect_warning: - assert WARNING_EXTRACT in function.stdout - else: - assert WARNING_EXTRACT not in function.stdout - config = docker.run(f"cat {WEB_CONFIG} | grep 'server.bind'") - if expected_bind == "0.0.0.0": - assert "server.bind" not in config.stdout - else: - assert f'server.bind = "{expected_bind}"' in config.stdout +# def test_webpassword_random_generation(docker): +# """When a user sets webPassword env the admin password gets set to that""" +# function = docker.run(CMD_SETUP_WEB_PASSWORD) +# assert "assigning random password" in function.stdout.lower() + + +# @pytest.mark.parametrize("entrypoint,cmd", [("--entrypoint=tail", "-f /dev/null")]) +# @pytest.mark.parametrize( +# "args_env,secure,setupvars_hash", +# [ +# ( +# "-e WEBPASSWORD=login", +# True, +# "WEBPASSWORD=6060d59351e8c2f48140f01b2c3f3b61652f396c53a5300ae239ebfbe7d5ff08", +# ), +# ('-e WEBPASSWORD=""', False, ""), +# ], +# ) +# def test_webpassword_env_assigns_password_to_file_or_removes_if_empty( +# docker, args_env, secure, setupvars_hash +# ): +# """When a user sets webPassword env the admin password gets set or removed if empty""" +# function = docker.run(CMD_SETUP_WEB_PASSWORD) + +# if secure: +# assert "new password set" in function.stdout.lower() +# assert docker.run(_grep(setupvars_hash, SETUPVARS_LOC)).rc == 0 +# else: +# assert "password removed" in function.stdout.lower() +# assert docker.run(_grep("^WEBPASSWORD=$", SETUPVARS_LOC)).rc == 0 + + +# @pytest.mark.parametrize("entrypoint,cmd", [("--entrypoint=tail", "-f /dev/null")]) +# @pytest.mark.parametrize("test_args", ["-e WEBPASSWORD=login", '-e WEBPASSWORD=""']) +# def test_env_always_updates_password(docker, args_env, test_args): +# """When a user sets the WEBPASSWORD environment variable, ensure it always sets the password""" +# function = docker.run(CMD_SETUP_WEB_PASSWORD) + +# assert " [i] Assigning password defined by Environment Variable" in function.stdout + + +# @pytest.mark.parametrize("entrypoint,cmd", [("--entrypoint=tail", "-f /dev/null")]) +# def test_setupvars_trumps_random_password_if_set(docker, args_env, test_args): +# """If a password is already set in setupvars, and no password is set in the environment variable, do not generate a random password""" +# docker.run( +# ". /opt/pihole/utils.sh ; addOrEditKeyValPair {} WEBPASSWORD volumepass".format( +# SETUPVARS_LOC +# ) +# ) +# function = docker.run(CMD_SETUP_WEB_PASSWORD) + +# assert "Pre existing WEBPASSWORD found" in function.stdout +# assert docker.run(_grep("WEBPASSWORD=volumepass", SETUPVARS_LOC)).rc == 0 diff --git a/test/tests/test_start.py b/test/tests/test_start.py deleted file mode 100644 index 967403b8d..000000000 --- a/test/tests/test_start.py +++ /dev/null @@ -1,37 +0,0 @@ -import pytest -import time - -""" conftest.py provides the defaults through fixtures """ -""" Note, testinfra builtins don't seem fully compatible with - docker containers (esp. musl based OSs) stripped down nature """ - - -# If the test runs /usr/local/bin/_startup.sh, do not let s6 run it too! Kill entrypoint to avoid race condition/duplicated execution -@pytest.mark.parametrize("entrypoint,cmd", [("--entrypoint=tail", "-f /dev/null")]) -@pytest.mark.parametrize( - "args,error_msg,expect_rc", - [ - ( - '-e FTLCONF_LOCAL_IPV4="1.2.3.z"', - "FTLCONF_LOCAL_IPV4 Environment variable (1.2.3.z) doesn't appear to be a valid IPv4 address", - 1, - ), - ( - '-e FTLCONF_LOCAL_IPV4="1.2.3.4" -e FTLCONF_LOCAL_IPV6="1234:1234:1234:ZZZZ"', - "Environment variable (1234:1234:1234:ZZZZ) doesn't appear to be a valid IPv6 address", - 1, - ), - ( - '-e FTLCONF_LOCAL_IPV4="1.2.3.4" -e FTLCONF_LOCAL_IPV6="kernel"', - "ERROR: You passed in IPv6 with a value of 'kernel'", - 1, - ), - ], -) -def test_ftlconf_local_addr_invalid_ips_triggers_exit_error( - docker, error_msg, expect_rc -): - start = docker.run("/usr/local/bin/_startup.sh") - assert start.rc == expect_rc - assert "ERROR" in start.stdout - assert error_msg in start.stdout