diff --git a/.github/workflows/build-test-lint.yml b/.github/workflows/build-test-lint.yml index 596e905..d749ddf 100644 --- a/.github/workflows/build-test-lint.yml +++ b/.github/workflows/build-test-lint.yml @@ -40,3 +40,9 @@ jobs: echo "Working tree dirty at end of job" exit 1 fi + + - name: Build e2e tests image + run: docker build -f tests/Dockerfile -t geoblock-tests . + + - name: Run e2e tests + run: docker run geoblock-tests diff --git a/tests/Dockerfile b/tests/Dockerfile new file mode 100644 index 0000000..c644935 --- /dev/null +++ b/tests/Dockerfile @@ -0,0 +1,10 @@ +# ----------------------------------------------------------------------------- +# E2E Tests +# ----------------------------------------------------------------------------- + +FROM golang:1.23.4 AS builder + +WORKDIR /app +COPY . . + +ENTRYPOINT [ "/app/tests/run.sh" ] diff --git a/tests/expected.log b/tests/expected.log new file mode 100644 index 0000000..060b3b0 --- /dev/null +++ b/tests/expected.log @@ -0,0 +1,9 @@ +time="2024-12-08T08:54:07Z" level=info msg="Loading configuration file" +time="2024-12-08T08:54:07Z" level=info msg="Initializing database resolver" +time="2024-12-08T08:54:09Z" level=info msg="Starting server at :8080" +time="2024-12-08T08:54:09Z" level=error msg="Missing required headers" request_domain= request_method=GET source_ip=127.0.0.1 +time="2024-12-08T08:54:10Z" level=error msg="Invalid source IP" error="ParseAddr(\"invalid-ip\"): unable to parse IP" request_domain=example.org request_method=GET source_ip=invalid-ip +time="2024-12-08T08:54:10Z" level=error msg="Missing required headers" request_domain=example.com request_method=GET source_ip= +time="2024-12-08T08:54:10Z" level=error msg="Missing required headers" request_domain=example.com request_method= source_ip=8.8.8.8 +time="2024-12-08T08:54:10Z" level=warning msg="Request denied" request_domain=example.org request_method=GET source_asn=15169 source_country=US source_ip=8.8.8.8 source_org=GOOGLE +time="2024-12-08T08:54:10Z" level=info msg="Request authorized" request_domain=example.com request_method=GET source_asn=15169 source_country=US source_ip=8.8.8.8 source_org=GOOGLE diff --git a/tests/run.sh b/tests/run.sh new file mode 100755 index 0000000..795e813 --- /dev/null +++ b/tests/run.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -euo pipefail + +CGO_ENABLED=0 make build + +export GEOBLOCK_CONFIG=/app/examples/config.yaml +export GEOBLOCK_PORT=8080 +export GEOBLOCK_LOG_LEVEL=debug + +./dist/geoblock &> geoblock.log & + +while ! curl -fs http://localhost:8080/v1/health; do + sleep 1 +done + +function test() { + local test_name=$1 + shift + + local expected_status=$1 + shift + + local status + status=$(curl -s -o /dev/null -w "%{http_code}" "$@") + + if [ "$status" -ne "$expected_status" ]; then + echo ":: Test \"$test_name\" failed. Expected status $expected_status, got $status" + exit 1 + fi +} + +test 'missing "X-Forwarded-Host" header' 400 \ + http://localhost:8080/v1/forward-auth \ + -H "X-Forwarded-For: 127.0.0.1" \ + -H "X-Forwarded-Method: GET" + +test 'invalid source IP address' 400 \ + http://localhost:8080/v1/forward-auth \ + -H "X-Forwarded-For: invalid-ip" \ + -H "X-Forwarded-Host: example.org" \ + -H "X-Forwarded-Method: GET" + +test 'missing "X-Forwarded-For" header' 400 \ + http://localhost:8080/v1/forward-auth \ + -H "X-Forwarded-Host: example.com" \ + -H "X-Forwarded-Method: GET" + +test 'missing "X-Forwarded-Method" header' 400 \ + http://localhost:8080/v1/forward-auth \ + -H "X-Forwarded-For: 8.8.8.8" \ + -H "X-Forwarded-Host: example.com" + +test 'blocked by domain+country' 403 \ + http://localhost:8080/v1/forward-auth \ + -H "X-Forwarded-For: 8.8.8.8" \ + -H "X-Forwarded-Host: example.org" \ + -H "X-Forwarded-Method: GET" + +test 'allowed by domain+country' 204 \ + http://localhost:8080/v1/forward-auth \ + -H "X-Forwarded-For: 8.8.8.8" \ + -H "X-Forwarded-Host: example.com" \ + -H "X-Forwarded-Method: GET" + +diff <(sed 's/^time="[^"]*"//' tests/expected.log) \ + <(sed 's/^time="[^"]*"//' geoblock.log) + +echo ":: ALL E2E TESTS PASSED"