Files
firezone/.github/workflows/_integration_tests.yml
Jamil a05067d410 chore(ci): Add 50ms simulated API latency (#10132)
In the real world, it's entirely possible that the latency between
clients, gateways, and relays is much lower than the latency to the API
nodes. This added latency will test that we can handle such cases
reliably.

---------

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2025-08-05 09:23:43 -07:00

191 lines
6.4 KiB
YAML

name: Integration Tests
run-name: Triggered from ${{ github.event_name }} by ${{ github.actor }}
on:
workflow_call:
inputs:
domain_image:
required: false
type: string
default: "ghcr.io/firezone/domain"
domain_tag:
required: false
type: string
default: ${{ github.sha }}
api_image:
required: false
type: string
default: "ghcr.io/firezone/api"
api_tag:
required: false
type: string
default: ${{ github.sha }}
web_image:
required: false
type: string
default: "ghcr.io/firezone/web"
web_tag:
required: false
type: string
default: ${{ github.sha }}
elixir_image:
required: false
type: string
default: "ghcr.io/firezone/elixir"
elixir_tag:
required: false
type: string
default: ${{ github.sha }}
relay_image:
required: false
type: string
default: "ghcr.io/firezone/debug/relay"
relay_tag:
required: false
type: string
default: ${{ github.sha }}
gateway_image:
required: false
type: string
default: "ghcr.io/firezone/debug/gateway"
gateway_tag:
required: false
type: string
default: ${{ github.sha }}
client_image:
required: false
type: string
default: "ghcr.io/firezone/debug/client"
client_tag:
required: false
type: string
default: ${{ github.sha }}
http_test_server_image:
required: false
type: string
default: "ghcr.io/firezone/debug/http-test-server"
http_test_server_tag:
required: false
type: string
default: ${{ github.sha }}
env:
COMPOSE_PARALLEL_LIMIT: 1 # Temporary fix for https://github.com/docker/compose/pull/12752 until compose v2.36.0 lands on GitHub actions runners.
jobs:
integration-tests:
name: ${{ matrix.test.name }}
runs-on: ubuntu-22.04-xlarge
permissions:
contents: read
id-token: write
pull-requests: write
env:
DOMAIN_IMAGE: ${{ inputs.domain_image }}
DOMAIN_TAG: ${{ inputs.domain_tag }}
API_IMAGE: ${{ inputs.api_image }}
API_TAG: ${{ inputs.api_tag }}
WEB_IMAGE: ${{ inputs.web_image }}
WEB_TAG: ${{ inputs.web_tag }}
RELAY_IMAGE: ${{ inputs.relay_image }}
RELAY_TAG: ${{ inputs.relay_tag }}
GATEWAY_IMAGE: ${{ inputs.gateway_image }}
GATEWAY_TAG: ${{ inputs.gateway_tag }}
CLIENT_IMAGE: ${{ inputs.client_image }}
CLIENT_TAG: ${{ inputs.client_tag }}
ELIXIR_IMAGE: ${{ inputs.elixir_image }}
ELIXIR_TAG: ${{ inputs.elixir_tag }}
HTTP_TEST_SERVER_IMAGE: ${{ inputs.http_test_server_image }}
HTTP_TEST_SERVER_TAG: ${{ inputs.http_test_server_tag }}
strategy:
fail-fast: false
matrix:
test:
- name: direct-curl-api-down
- name: direct-curl-api-restart
- name: direct-curl-ecn
- name: direct-download-packet-loss
- name: direct-dns-api-down
- name: direct-dns-two-resources
- name: direct-dns
- name: direct-download-roaming-network
# Too noisy can cause flaky tests due to the amount of data
rust_log: debug
- name: dns-nm
- name: tcp-dns
- name: relay-graceful-shutdown
- name: systemd/dns-systemd-resolved
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: ./.github/actions/ghcr-docker-login
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Seed database
run: docker compose run elixir /bin/sh -c 'cd apps/domain && mix ecto.migrate --migrations-path priv/repo/migrations --migrations-path priv/repo/manual_migrations && mix ecto.seed'
- name: Start docker compose in the background
run: |
set -xe
if [[ -n "${{ matrix.test.rust_log }}" ]]; then
export RUST_LOG="${{ matrix.test.rust_log }}"
fi
# Start one-by-one to avoid variability in service startup order
docker compose up -d dns.httpbin.search.test --no-build
docker compose up -d httpbin --no-build
docker compose up -d download.httpbin --no-build
docker compose up -d api web domain --no-build
docker compose up -d otel --no-build
docker compose up -d relay-1 --no-build
docker compose up -d relay-2 --no-build
docker compose up -d gateway --no-build
docker compose up -d client --no-build
# Wait a few seconds for the services to fully start. GH runners are
# slow, so this gives the Client enough time to initialize its tun interface,
# for example.
# Intended to mitigate <https://github.com/firezone/firezone/issues/5830>
sleep 3
- name: Add 50ms simulated API latency
run: |
docker compose exec -T -u root api sh -c 'apk add --no-cache iproute2-tc'
docker compose exec -T -u root api sh -c 'tc qdisc add dev eth0 root netem delay 50ms'
- name: Add 10ms simulated gateway latency
run: |
# compatibility test images won't have the `tc` command
docker compose exec -T gateway sh -c 'apk add --no-cache iproute2-tc'
docker compose exec -T gateway sh -c 'tc qdisc add dev eth0 root netem delay 10ms'
- run: ./scripts/tests/${{ matrix.test.name }}.sh
- name: Ensure Client emitted no warnings
if: "!cancelled()"
# Remove the error filter once headless-client 1.5.2 is released.
run: |
docker compose logs client | \
grep "Operation not permitted (os error 1)" --invert | \
grep "WARN" && exit 1 || exit 0
- name: Show Client logs
if: "!cancelled()"
run: docker compose logs client
- name: Show Relay-1 logs
if: "!cancelled()"
run: docker compose logs relay-1
- name: Show Relay-2 logs
if: "!cancelled()"
run: docker compose logs relay-2
- name: Ensure Gateway emitted no warnings
if: "!cancelled()"
run: docker compose logs gateway | grep "WARN" && exit 1 || exit 0
- name: Show Gateway logs
if: "!cancelled()"
run: docker compose logs gateway
- name: Show API logs
if: "!cancelled()"
run: docker compose logs api