Skip to content

chore(deps): bump docker/setup-qemu-action from 4.0.0 to 4.1.0 #101

chore(deps): bump docker/setup-qemu-action from 4.0.0 to 4.1.0

chore(deps): bump docker/setup-qemu-action from 4.0.0 to 4.1.0 #101

name: Integration Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
integration:
name: integration-tests
runs-on: ubuntu-24.04
services:
nats:
image: nats:latest
ports:
- 4222:4222
# nats:latest is a scratch image — no shell, so no healthcheck.
# Tests use wait_until() to retry connections instead.
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ninja-build python3 python3-pip
pip3 install --user conan
- name: Configure Conan
run: conan profile detect --force
- name: Install Conan dependencies (gcc/release)
run: |
conan install . \
--output-folder=build/ci \
--build=missing \
--lockfile=conan.lock \
-s build_type=Release \
-s compiler=gcc \
-s compiler.version=14 \
-s compiler.libcxx=libstdc++11 \
-s compiler.cppstd=20
- name: Configure
run: cmake --preset ci
- name: Build
run: cmake --build --preset ci
- name: Start mock Agamemnon
# Bind to an ephemeral port (port 0) so parallel jobs on the same
# runner cannot collide on a fixed port (issue #91). The script
# prints the actual bound port to stdout; we tee it to a log file
# and extract the port in the next step.
run: |
set -euo pipefail
mkdir -p "$RUNNER_TEMP/mock-agamemnon"
( python3 scripts/mock-agamemnon.py \
> "$RUNNER_TEMP/mock-agamemnon/stdout.log" 2>&1 ) &
echo $! > "$RUNNER_TEMP/mock-agamemnon/pid"
env:
PYTHONUNBUFFERED: "1"
- name: Wait for mock Agamemnon to be ready
run: |
set -euo pipefail
log="$RUNNER_TEMP/mock-agamemnon/stdout.log"
# Wait for the "listening on :<port>" line to appear (up to ~10s).
port=""
for i in $(seq 1 40); do
if [ -s "$log" ]; then
port=$(grep -oE 'listening on :[0-9]+' "$log" \
| head -n1 \
| sed 's/^listening on ://') || port=""
if [ -n "$port" ]; then
break
fi
fi
sleep 0.25
done
if [ -z "$port" ]; then
echo "mock-agamemnon never printed bound port"
if [ -f "$log" ]; then cat "$log"; fi
exit 1
fi
echo "MOCK_AGAMEMNON_PORT=$port" >> "$GITHUB_ENV"
echo "AGAMEMNON_URL=http://localhost:$port" >> "$GITHUB_ENV"
for i in $(seq 1 20); do
if curl -sf "http://localhost:$port/v1/health" | grep -q '"ok"'; then
echo "mock-agamemnon ready on :$port"; exit 0
fi
sleep 0.5
done
echo "mock-agamemnon did not become ready in time"
if [ -f "$log" ]; then cat "$log"; fi
exit 1
- name: Verify NATS connectivity
# Fail fast if NATS is unreachable, so REQUIRES_NATS tests can't
# silently skip the NATS code paths (#92). A real NATS server greets
# every new TCP connection with an INFO line; require it before tests.
shell: bash
run: |
set -euo pipefail
probe_nats() {
# Open a TCP connection to NATS and read the first line. Returns
# 0 only when the server emits a valid INFO greeting; nonzero on
# connection failure, timeout, or unexpected payload.
local line
set +e
line=$(timeout 2 bash -c \
'exec 3<>/dev/tcp/localhost/4222 && head -n 1 <&3' \
2>/dev/null)
local rc=$?
set -e
if [ "$rc" -ne 0 ]; then return 1; fi
printf '%s' "$line" | grep -q '^INFO '
}
for i in $(seq 1 30); do
if probe_nats; then
echo "NATS reachable after ${i}s"
exit 0
fi
sleep 1
done
echo "ERROR: NATS server at nats://localhost:4222 did not greet within 30s"
exit 1
- name: Run integration tests
env:
NATS_URL: nats://localhost:4222
# AGAMEMNON_URL is exported by the previous step via $GITHUB_ENV
run: ctest --preset integration --output-junit integration-results.xml
- name: Assert REQUIRES_NATS tests actually executed
# Guard against the integration preset matching zero tests (e.g. if the
# REQUIRES_NATS label is renamed/removed). ctest exits 0 when no tests
# match the filter, which would silently bypass the NATS suite (#92).
run: |
set -euo pipefail
xml=build/ci/integration-results.xml
if [ ! -f "$xml" ]; then
echo "ERROR: $xml not produced — ctest did not run"
exit 1
fi
count=$(python3 -c "import xml.etree.ElementTree as ET, sys; \
root = ET.parse('$xml').getroot(); \
print(sum(1 for _ in root.iter('testcase')))")
echo "integration testcases executed: $count"
if [ "$count" -lt 1 ]; then
echo "ERROR: zero REQUIRES_NATS tests ran — NATS integration silently skipped (#92)"
exit 1
fi
- name: Upload ctest logs on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: ctest-logs
path: |
build/ci/Testing/Temporary/LastTest.log
build/ci/Testing/Temporary/LastTestsFailed.log
build/ci/Testing/Temporary/CTestCostData.txt
if-no-files-found: ignore
retention-days: 7