Skip to content

Commit 6ef31e8

Browse files
committed
Merge branch 'loadgen-5hs-tests' into multi-server-tests
2 parents 3f76714 + e16c151 commit 6ef31e8

6 files changed

Lines changed: 209 additions & 44 deletions

File tree

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
name: Multi-Server CI Tests
2+
3+
on:
4+
push:
5+
branches: [ "loadgen-5hs-tests" ]
6+
7+
pull_request:
8+
branches: [ "loadgen-5hs-tests" ]
9+
paths:
10+
- '.github/workflows/ci-multi-server-tests.yml'
11+
- 'src/tests/multi-server/**'
12+
workflow_dispatch:
13+
14+
jobs:
15+
pre-test:
16+
runs-on: ubuntu-latest
17+
outputs:
18+
selfhosted: 0
19+
#selfhosted: ${{ github.repository_owner == 'FreeRADIUS' && '1' || '0' }}
20+
steps:
21+
- run: echo "Pre-test job; checking if using self-hosted runners"
22+
23+
test-5hs-autoaccept:
24+
needs: pre-test
25+
runs-on: ${{ needs.pre-test.outputs.selfhosted == '1' && 'self-hosted' || 'ubuntu-24.04' }}
26+
27+
env:
28+
MULTI_SERVER_ENV_DOCKER_BUILD_OS: ubuntu24
29+
MULTI_SERVER_TEST_LOG: build/tests/multi-server/freeradius-multi-server/multi_server_test.log
30+
31+
steps:
32+
# Checkout, but defer pulling LFS objects until we've restored the cache
33+
- uses: actions/checkout@v4
34+
with:
35+
lfs: false
36+
37+
- name: Package manager performance improvements
38+
run: |
39+
sudo sh -c 'echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/02speedup'
40+
echo 'man-db man-db/auto-update boolean false' | sudo debconf-set-selections
41+
sudo dpkg-reconfigure man-db
42+
sudo sed -i 's/^update_initramfs=.*/update_initramfs=no/' /etc/initramfs-tools/update-initramfs.conf
43+
44+
- name: NetworkRADIUS signing key
45+
shell: bash
46+
run: |
47+
sudo install -d -o root -g root -m 0755 /etc/apt/keyrings
48+
curl -s 'https://packages.inkbridgenetworks.com/pgp/packages.networkradius.com.asc' | sudo tee /etc/apt/keyrings/packages.networkradius.com.asc > /dev/null
49+
50+
- name: Set up NetworkRADIUS extras repository
51+
shell: bash
52+
run: |
53+
DIST=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
54+
RELEASE=$(lsb_release -cs)
55+
sudo /bin/sh -c "echo \"deb [arch=amd64 signed-by=/etc/apt/keyrings/packages.networkradius.com.asc] http://packages.networkradius.com/extras/${DIST}/${RELEASE} ${RELEASE} main\" \
56+
> /etc/apt/sources.list.d/networkradius-extras.list"
57+
sudo apt-get update
58+
59+
# Remove pre-installed package which conflicts with dependency installation
60+
- name: Remove package conflicts
61+
run: |
62+
sudo apt-get remove -y libhashkit2
63+
64+
# Installing build dependencies requires a ubuntu-24.04 runner
65+
- name: Install build dependencies
66+
run: |
67+
sudo apt-get install -y --no-install-recommends build-essential devscripts equivs quilt
68+
debian/rules debian/control
69+
sudo mk-build-deps -irt"apt-get -y --no-install-recommends" debian/control
70+
sudo mk-build-deps -irt"apt-get -y --no-install-recommends" scripts/ci/extra-packages.debian.control
71+
72+
- name: Build Docker image for multi-server test environment
73+
if: ${{ needs.pre-test.outputs.selfhosted != '1' }}
74+
run: |
75+
./configure
76+
make docker.${MULTI_SERVER_ENV_DOCKER_BUILD_OS}.build
77+
78+
# List all images
79+
docker images --all
80+
81+
# Tag freeradius build image using using a non-OS specific name to be used with the multi-server docker compose environment.
82+
docker tag freeradius4/${MULTI_SERVER_ENV_DOCKER_BUILD_OS}:latest freeradius-build:latest
83+
84+
- name: Get pre-built Docker image for self-hosted runner test
85+
if: ${{ needs.pre-test.outputs.selfhosted == '1' }}
86+
run: |
87+
docker pull docker.internal.networkradius.com/self-hosted-${MULTI_SERVER_ENV_DOCKER_BUILD_OS}:latest
88+
89+
# Tag freeradius build image using using a non-OS specific name to be used with the multi-server docker compose environment.
90+
docker tag docker.internal.networkradius.com/self-hosted-${MULTI_SERVER_ENV_DOCKER_BUILD_OS}:latest freeradius-build:latest
91+
92+
- name: Run test-5hs-autoaccept test
93+
if: ${{ needs.pre-test.outputs.selfhosted != '1' }}
94+
run: |
95+
if ! docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "^freeradius-build:latest$"; then
96+
echo "Error: freeradius-build:latest Docker image not found and required for multi-server test environment."
97+
exit 1
98+
fi
99+
make -f src/tests/multi-server/all.mk test-5hs-autoaccept
100+
101+
- name: Verify test results
102+
shell: bash
103+
run: |
104+
set -euo pipefail
105+
106+
echo "============ ${MULTI_SERVER_TEST_LOG} ============"
107+
cat "${MULTI_SERVER_TEST_LOG}"
108+
109+
if grep -q '\[Failed\]' "${MULTI_SERVER_TEST_LOG}"; then
110+
echo "TEST FAILED: Found [Failed] in log"
111+
grep '\[Failed\]' "${MULTI_SERVER_TEST_LOG}"
112+
exit 1
113+
fi
114+
115+
if grep -Eq '\(Failures:[[:space:]]*[1-9][0-9]*[[:space:]]*\)' "${MULTI_SERVER_TEST_LOG}"; then
116+
echo "TEST FAILED: Found Failures > 0 in log"
117+
grep -E '\(Failures:[[:space:]]*[1-9][0-9]*[[:space:]]*\)' "${MULTI_SERVER_TEST_LOG}"
118+
exit 1
119+
fi
120+
121+
log="${MULTI_SERVER_TEST_LOG}"
122+
if awk '
123+
BEGIN { found=0; n1=0; n2=0; line="" }
124+
index($0,"Matched:") {
125+
orig=$0
126+
s=$0
127+
gsub(/[[:space:]]/, "", s)
128+
sub(/^.*Matched:/, "", s)
129+
sub(/\(.*/, "", s)
130+
n = split(s, parts, "/")
131+
if (n == 2) {
132+
a = parts[1] + 0
133+
b = parts[2] + 0
134+
if (a > 0 && a == b) { found=1; n1=a; n2=b; line=orig }
135+
}
136+
}
137+
END {
138+
if (found) { printf "MATCH: %d / %d\nMatched line: %s\n", n1, n2, line; exit 0 }
139+
exit 1
140+
}
141+
' "$log"
142+
then
143+
: # PASS
144+
else
145+
echo "TEST FAILED: No Matched line found with equal non-zero counts"
146+
exit 1
147+
fi

src/tests/multi-server/all.mk

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,20 @@
2626
# of the test-framework.
2727
#
2828

29-
# Find ENV compose file by stripping trailing "-suffix" chunks until a match exists.
30-
# Returns: environments/docker-compose/env-<base-without-test->.yml
31-
define FIND_ENV_COMPOSE
29+
# Find ENV compose template by stripping trailing "-suffix" chunks until a match exists.
30+
# Returns: environments/docker-compose/env-<base-without-test->.yml.j2
31+
define FIND_ENV_COMPOSE_J2
3232
$(strip $(shell \
3333
name='$(1)'; base="$$name"; \
3434
while :; do \
3535
env="environments/docker-compose/env-$${base#test-}.yml"; \
3636
envj2="$$env.j2"; \
3737
if [ -f "$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$envj2" ]; then \
38-
printf '%s' "$$env"; exit 0; \
39-
elif [ -f "$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$env" ]; then \
40-
printf '%s' "$$env"; exit 0; \
38+
printf '%s' "$$envj2"; exit 0; \
4139
fi; \
4240
newbase="$${base%-*}"; \
4341
if [ "$$newbase" = "$$base" ]; then \
44-
echo "ERROR: No matching env compose file for $(1) (tried $$env(.j2) and shorter prefixes)" 1>&2; \
42+
echo "ERROR: No matching env compose template for $(1) (expected $$env.j2 and shorter prefixes)" 1>&2; \
4543
exit 1; \
4644
fi; \
4745
base="$$newbase"; \
@@ -54,49 +52,66 @@ define MAKE_TEST_TARGET
5452
$(1): TEST_NAME := $(1)
5553
$(1): TEST_FILENAME := $$(TEST_NAME).yml
5654

57-
# Compute compose path by finding the longest matching base env file
58-
$(1): ENV_COMPOSE_PATH := $$(call FIND_ENV_COMPOSE,$$(TEST_NAME))
55+
# Compose template (must exist)
56+
$(1): ENV_COMPOSE_TEMPLATE_PATH := $$(call FIND_ENV_COMPOSE_J2,$$(TEST_NAME))
57+
58+
# Output compose file (strip .j2)
59+
$(1): ENV_COMPOSE_PATH := $$(patsubst %.j2,%,$$(ENV_COMPOSE_TEMPLATE_PATH))
60+
61+
# Stem: environments/docker-compose/env-5hs-autoaccept.yml -> 5hs-autoaccept
62+
$(1): ENV_STEM := $$(patsubst environments/docker-compose/env-%.yml,%,$$(ENV_COMPOSE_PATH))
63+
64+
# Vars aligned to stem
65+
$(1): VARS_FILE_REL ?= environments/jinja-vars/env-$$(ENV_STEM).vars.yml
5966

6067
$(1): clone
6168
@echo "MULTI_SERVER_BUILD_DIR_REL_PATH=$(MULTI_SERVER_BUILD_DIR_REL_PATH)"
6269
@echo "MULTI_SERVER_BUILD_DIR_ABS_PATH=$(MULTI_SERVER_BUILD_DIR_ABS_PATH)"
6370
@mkdir -p "$(MULTI_SERVER_BUILD_DIR_REL_PATH)/freeradius-listener-logs/$$(TEST_NAME)"
64-
@cd "$(FRAMEWORK_REPO_DIR)" && \
65-
git pull && \
66-
\
67-
$(MAKE) configure && \
68-
. ".venv/bin/activate" && \
71+
@bash -lc 'set -euo pipefail; \
72+
echo "INFO: entering framework repo: $(FRAMEWORK_REPO_DIR)"; \
73+
cd "$(FRAMEWORK_REPO_DIR)"; \
74+
git pull; \
75+
$(MAKE) configure; \
76+
. ".venv/bin/activate"; \
6977
\
7078
DATA_PATH="$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)environments/configs"; \
7179
LISTENER_DIR="$(MULTI_SERVER_BUILD_DIR_ABS_PATH)/freeradius-listener-logs/$$(TEST_NAME)"; \
80+
INCLUDE_PATH_ABS="$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)"; \
81+
VARS_FILE_ABS="$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$(VARS_FILE_REL)"; \
82+
ENV_COMPOSE_TEMPLATE_ABS="$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$(ENV_COMPOSE_TEMPLATE_PATH)"; \
83+
ENV_COMPOSE_ABS="$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$(ENV_COMPOSE_PATH)"; \
84+
TEST_ABS="$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$(TEST_FILENAME)"; \
7285
\
73-
echo "INFO: TEST_FILENAME=$$(TEST_FILENAME)"; \
7486
echo "INFO: TEST_NAME=$$(TEST_NAME)"; \
87+
echo "INFO: TEST_FILENAME=$$(TEST_FILENAME)"; \
88+
echo "INFO: TEST_ABS=$$TEST_ABS"; \
89+
echo "INFO: ENV_COMPOSE_TEMPLATE_PATH=$$(ENV_COMPOSE_TEMPLATE_PATH)"; \
7590
echo "INFO: ENV_COMPOSE_PATH=$$(ENV_COMPOSE_PATH)"; \
76-
echo "INFO: MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH=$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)"; \
77-
echo "INFO: DATA_PATH=$$$$DATA_PATH"; \
78-
echo "INFO: MULTI_SERVER_BUILD_DIR_REL_PATH=$(MULTI_SERVER_BUILD_DIR_REL_PATH)"; \
91+
echo "INFO: ENV_STEM=$$(ENV_STEM)"; \
92+
echo "INFO: VARS_FILE_REL=$$(VARS_FILE_REL)"; \
93+
echo "INFO: VARS_FILE_ABS=$$$$VARS_FILE_ABS"; \
94+
echo "INFO: ENV_COMPOSE_TEMPLATE_ABS=$$$$ENV_COMPOSE_TEMPLATE_ABS"; \
95+
echo "INFO: ENV_COMPOSE_ABS=$$$$ENV_COMPOSE_ABS"; \
7996
echo "INFO: LISTENER_DIR=$$$$LISTENER_DIR"; \
8097
\
81-
CMD="python3 src/config_builder.py --listener_type file --aux $(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)environments/configs/freeradius/homeserver/radiusd.conf.j2 --includepath $(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)"; \
82-
echo "INFO: CMD = $$$$CMD"; \
83-
bash -c "$$$$CMD"; \
98+
test -f "$$$$VARS_FILE_ABS" || { echo "ERROR: Missing vars file: $$$$VARS_FILE_ABS" >&2; exit 1; }; \
99+
test -f "$$$$ENV_COMPOSE_TEMPLATE_ABS" || { echo "ERROR: Missing compose template: $$$$ENV_COMPOSE_TEMPLATE_ABS" >&2; exit 1; }; \
100+
test -f "$$$$TEST_ABS" || { echo "ERROR: Missing test file: $$$$TEST_ABS" >&2; exit 1; }; \
84101
\
85-
CMD="python3 src/config_builder.py --listener_type file --aux $(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)environments/configs/freeradius/load-generator/radiusd.conf.j2 --includepath $(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)"; \
86-
echo "INFO: CMD = $$$$CMD"; \
87-
bash -c "$$$$CMD"; \
102+
echo "INFO: Rendering homeserver radiusd.conf.j2"; \
103+
python3 src/config_builder.py --vars-file "$$$$VARS_FILE_ABS" --aux-file "$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)environments/configs/freeradius/homeserver/radiusd.conf.j2" --include-path "$$$$INCLUDE_PATH_ABS"; \
88104
\
89-
CMD="python3 src/config_builder.py --listener_type file --aux $(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)environments/docker-compose/env-5hs-autoaccept.yml.j2 --includepath $(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)"; \
90-
echo "INFO: CMD = $$$$CMD"; \
91-
bash -c "$$$$CMD"; \
105+
echo "INFO: Rendering load-generator radiusd.conf.j2"; \
106+
python3 src/config_builder.py --vars-file "$$$$VARS_FILE_ABS" --aux-file "$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)environments/configs/freeradius/load-generator/radiusd.conf.j2" --include-path "$$$$INCLUDE_PATH_ABS"; \
92107
\
93-
test -f "$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$(ENV_COMPOSE_PATH)" || { \
94-
echo "ERROR: Missing compose file: $(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$(ENV_COMPOSE_PATH)"; \
95-
exit 1; \
96-
} && \
97-
CMD="DATA_PATH=$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)environments/configs make test-framework -- -x -v --compose $(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$(ENV_COMPOSE_PATH) --test $(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)$$(TEST_FILENAME) --use-files --listener-dir $$$$LISTENER_DIR"; \
98-
echo "INFO: CMD = $$$$CMD"; \
99-
bash -c "$$$$CMD"
108+
echo "INFO: Rendering docker-compose env from template"; \
109+
python3 src/config_builder.py --vars-file "$$$$VARS_FILE_ABS" --aux-file "$$$$ENV_COMPOSE_TEMPLATE_ABS" --include-path "$$$$INCLUDE_PATH_ABS"; \
110+
\
111+
test -f "$$$$ENV_COMPOSE_ABS" || { echo "ERROR: Compose file was not generated: $$$$ENV_COMPOSE_ABS" >&2; exit 1; }; \
112+
\
113+
echo "INFO: Running test-framework"; \
114+
DATA_PATH="$(MULTI_SERVER_TESTS_BASE_DIR_ABS_PATH)environments/configs" make test-framework -- -x -v --compose "$$$$ENV_COMPOSE_ABS" --test "$$$$TEST_ABS" --use-files --listener-dir "$$$$LISTENER_DIR"'
100115
endef
101116

102117
# Set directory name where all.mk is located. Help with relative paths

src/tests/multi-server/environments/configs/freeradius/homeserver/radiusd.conf.j2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ modules {
3838
{% include "environments/configs/freeradius/common/mods-available/linelog" %}
3939

4040
# Test-framework specific linelog module configuration based on OS environment
41-
{% if test.listener_type == "unix" %}
41+
{% if listener_type == "unix" %}
4242
{% include "environments/configs/freeradius/common/mods-available/linelog_socket" %}
43-
{% elif test.listener_type == "file" %}
43+
{% elif listener_type == "file" %}
4444
{% include "environments/configs/freeradius/common/mods-available/linelog_file" %}
4545
{% endif %}
4646

src/tests/multi-server/environments/configs/freeradius/load-generator/radiusd.conf.j2

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,17 @@ modules {
3030
{% include "environments/configs/freeradius/common/mods-available/linelog" %}
3131

3232
# Test-framework specific linelog module configuration based on OS environment
33-
{% if test.listener_type == "unix" %}
33+
{% if listener_type == "unix" %}
3434
{% include "environments/configs/freeradius/common/mods-available/linelog_socket" %}
35-
{% elif test.listener_type == "file" %}
35+
{% elif listener_type == "file" %}
3636
{% include "environments/configs/freeradius/common/mods-available/linelog_file" %}
3737
{% endif %}
3838

3939
# Common stats module configuration
4040
{% include "environments/configs/freeradius/common/mods-available/stats" %}
4141

4242
# radius module instance configuration
43-
{% for i in range(1, 6) %}
43+
{% for i in range(1, (num_of_dst_servers + 1)) %}
4444
radius radius-module-dst-server{{ i }} {
4545
$template radius-module-dst-server-tmpl
4646
udp {
@@ -183,7 +183,7 @@ server load-generator {
183183
authenticate load-generator-proxy {
184184
# Use redundant-load-balance to distribute requests to multiple home servers
185185
redundant-load-balance {
186-
{% for i in range(1, 6) %}
186+
{% for i in range(1, (num_of_dst_servers + 1)) %}
187187
radius-module-dst-server{{ i }}
188188
{% endfor %}
189189
}

src/tests/multi-server/environments/docker-compose/env-5hs-autoaccept.yml.j2

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ x-common-config: &id001
1717
- NET_ADMIN
1818
- SYS_PTRACE
1919
services:
20-
{% for i in range(1,6) %}
20+
{% for i in range(1, (num_of_dst_servers + 1)) %}
2121
homeserver{{ i }}:
22-
image: fr-build-ubuntu22:latest
22+
image: freeradius-build:latest
2323
volumes:
2424
- ${DATA_PATH}/freeradius/homeserver/radiusd.conf:/etc/raddb/radiusd.conf
2525
- ${DATA_PATH}/freeradius/env-setup.sh:/tmp/env-setup.sh
@@ -41,14 +41,14 @@ services:
4141
<<: *id001
4242
{% endfor %}
4343
load-generator:
44-
image: fr-build-ubuntu22:latest
44+
image: freeradius-build:latest
4545
ports:
4646
# Expose RADIUS ports for load generator to allow us to access the server from outside docker
4747
- "1812:1812/udp"
4848
- "1813:1813/udp"
4949
- "1820:1820/udp"
5050
depends_on:
51-
{% for i in range(1,6) %}
51+
{% for i in range(1, (num_of_dst_servers + 1)) %}
5252
- homeserver{{ i }}
5353
{% endfor %}
5454
volumes:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
num_of_dst_servers: 5
2+
dst_server_name: homeserver
3+
listener_type: file

0 commit comments

Comments
 (0)