1- name : wstest
1+ name : WebSocket Conformance Testing
22
33on :
4- push :
5- branches : [master]
6- pull_request :
7- branches : [master]
84 workflow_dispatch :
95 inputs :
106 test_mode :
11- description : " Test mode to run "
7+ description : ' Test mode (quick or full) '
128 required : false
13- default : " quick"
9+ default : ' quick'
1410 type : choice
1511 options :
1612 - quick
1713 - full
14+ schedule :
15+ # Run daily at 02:00 UTC
16+ - cron : ' 0 2 * * *'
1817
1918env :
20- UV_CACHE_DIR : ${{ github.workspace }}/.uv-cache
21- # Test mode: 'quick' for fast CI, 'full' for comprehensive testing
19+ UV_CACHE_DIR : /tmp/.uv-cache
2220 TEST_MODE : ${{ github.event.inputs.test_mode || 'quick' }}
2321
2422jobs :
25- # Client testing: Test autobahn-python clients against testsuite server
23+ # Client testing: Test autobahn-python clients against testsuite server
2624 client-conformance :
27- name : WebSocket Client Testing (${{ matrix.backend }})
25+ name : WebSocket Client Testing (${{ matrix.backend }}-${{ matrix.python }} )
2826 runs-on : ubuntu-24.04
29-
27+
3028 strategy :
31- fail-fast : false
3229 matrix :
3330 backend : [twisted, asyncio]
34-
31+ python : [cpy311, cpy314, pypy311]
32+
3533 steps :
3634 - name : Checkout code
3735 uses : actions/checkout@v4
3836
39- - name : Install Just
37+ - name : Install toolchain
4038 run : |
4139 curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ~/bin
42- echo "$HOME/bin" >> $GITHUB_PATH
43-
44- - name : Install uv
45- run : |
4640 curl -LsSf https://astral.sh/uv/install.sh | sh
47- source $HOME/.cargo/env
41+ echo " $HOME/bin" >> $GITHUB_PATH
4842 echo "$HOME/.cargo/bin" >> $GITHUB_PATH
4943
50- - name : Verify toolchain installation
51- run : |
52- just --version
53- uv --version
54- docker --version
55-
5644 - name : Setup uv cache
5745 uses : actions/cache@v4
5846 with :
5947 path : ${{ env.UV_CACHE_DIR }}
60- key : uv-cache-ubuntu-wstest-${{ hashFiles('pyproject.toml') }}
61- restore-keys : |
62- uv-cache-ubuntu-wstest-
48+ key : uv-cache-${{ matrix.python }}-${{ hashFiles('pyproject.toml') }}
6349
6450 - name : Setup Python environment
65- run : |
66- just create cpy314
67- just install cpy314
51+ run : just create ${{ matrix.python }}
6852
69- - name : Install Autobahn|Testsuite Docker image
70- run : just install-wstest
71-
72- - name : Start Autobahn|Testsuite server (background)
53+ - name : Start fuzzingserver
7354 run : |
74- echo "==> Starting Autobahn|Testsuite server in background..."
75- nohup just wstest-fuzzingserver > fuzzingserver.log 2>&1 &
76- echo $! > fuzzingserver.pid
77-
78- # Wait for server to be ready
79- echo "==> Waiting for fuzzingserver to be ready..."
80- sleep 15
81-
82- # Verify server is running
83- if ! docker ps | grep -q fuzzingserver; then
84- echo "❌ Fuzzingserver failed to start"
85- cat fuzzingserver.log
86- exit 1
87- fi
88- echo "✅ Fuzzingserver is running"
89-
90- - name : Test ${{ matrix.backend }} client
91- run : |
92- echo "==> Testing ${{ matrix.backend }} WebSocket client..."
93- if [ "${{ matrix.backend }}" = "twisted" ]; then
94- just wstest-testeeclient-twisted cpy314
95- else
96- just wstest-testeeclient-asyncio cpy314
97- fi
55+ nohup just wstest-fuzzingserver "" "" ${{ env.TEST_MODE }} > fuzzingserver.log 2>&1 &
56+ sleep 10
57+ curl -f http://127.0.0.1:9001 || (echo "❌ Fuzzingserver failed"; cat fuzzingserver.log; exit 1)
9858
99- - name : Stop fuzzingserver and collect results
100- if : always()
101- run : |
102- echo "==> Stopping fuzzingserver..."
103- if [ -f fuzzingserver.pid ]; then
104- kill $(cat fuzzingserver.pid) || true
105- fi
106- docker stop fuzzingserver || true
107-
108- echo "==> Client test results for ${{ matrix.backend }}:"
109- ls -la .wstest/clients/ || echo "No client reports found"
59+ - name : Run client tests
60+ run : just wstest-testeeclient-${{ matrix.backend }} ${{ matrix.python }}
11061
111- - name : Upload client test reports
62+ - name : Upload client reports
11263 uses : actions/upload-artifact@v4
11364 if : always()
11465 with :
115- name : client-reports- ${{ matrix.backend }}-${{ env.TEST_MODE }}
66+ name : client-${{ matrix.backend }}-${{ matrix.python }}-${{ env.TEST_MODE }}
11667 path : .wstest/clients/
11768 retention-days : 30
11869
119- # Server testing: Test both autobahn-python servers against testsuite client
70+ # Server testing: Test all server combinations against testsuite client
12071 server-conformance :
121- name : WebSocket Server Testing
72+ name : WebSocket Server Testing (All Combinations)
12273 runs-on : ubuntu-24.04
12374
12475 steps :
12576 - name : Checkout code
12677 uses : actions/checkout@v4
12778
128- - name : Install Just
79+ - name : Install toolchain
12980 run : |
13081 curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to ~/bin
131- echo "$HOME/bin" >> $GITHUB_PATH
132-
133- - name : Install uv
134- run : |
13582 curl -LsSf https://astral.sh/uv/install.sh | sh
136- source $HOME/.cargo/env
83+ echo " $HOME/bin" >> $GITHUB_PATH
13784 echo "$HOME/.cargo/bin" >> $GITHUB_PATH
13885
139- - name : Verify toolchain installation
140- run : |
141- just --version
142- uv --version
143- docker --version
144-
14586 - name : Setup uv cache
14687 uses : actions/cache@v4
14788 with :
14889 path : ${{ env.UV_CACHE_DIR }}
149- key : uv-cache-ubuntu-wstest-${{ hashFiles('pyproject.toml') }}
150- restore-keys : |
151- uv-cache-ubuntu-wstest-
90+ key : uv-cache-servers-${{ hashFiles('pyproject.toml') }}
15291
153- - name : Setup Python environment
92+ - name : Setup Python environments
15493 run : |
155- just create cpy314
156- just install cpy314
94+ just create cpy311
95+ just create cpy314
96+ just create pypy311
15797
158- - name : Install Autobahn|Testsuite Docker image
159- run : just install-wstest
160-
161- - name : Start Autobahn|Python servers (background)
98+ - name : Start all WebSocket servers
16299 run : |
163- echo "==> Starting Twisted server on port 9011..."
164- nohup .venvs/cpy314/bin/python ./wstest/testee_server_tx.py --url ws://127.0.0.1:9011 > twisted-server.log 2>&1 &
165- echo $! > twisted-server.pid
166-
167- echo "==> Starting asyncio server on port 9012..."
168- nohup .venvs/cpy314/bin/python ./wstest/testee_server_aio.py --url ws://127.0.0.1:9012 > asyncio-server.log 2>&1 &
169- echo $! > asyncio-server.pid
170-
171- # Wait for servers to be ready
172- echo "==> Waiting for servers to be ready..."
173- sleep 15
100+ echo "==> Starting 6 WebSocket server combinations..."
101+ nohup just wstest-testeeserver-twisted cpy311 "ws://127.0.0.1:9011" > twisted-cpy311.log 2>&1 &
102+ nohup just wstest-testeeserver-asyncio cpy311 "ws://127.0.0.1:9012" > asyncio-cpy311.log 2>&1 &
103+ nohup just wstest-testeeserver-twisted cpy314 "ws://127.0.0.1:9013" > twisted-cpy314.log 2>&1 &
104+ nohup just wstest-testeeserver-asyncio cpy314 "ws://127.0.0.1:9014" > asyncio-cpy314.log 2>&1 &
105+ nohup just wstest-testeeserver-twisted pypy311 "ws://127.0.0.1:9015" > twisted-pypy311.log 2>&1 &
106+ nohup just wstest-testeeserver-asyncio pypy311 "ws://127.0.0.1:9016" > asyncio-pypy311.log 2>&1 &
174107
175- # Verify both servers are listening
176- if ! netstat -tlnp | grep -q ":9011"; then
177- echo "❌ Twisted server failed to start on port 9011"
178- cat twisted-server.log
179- exit 1
180- fi
108+ sleep 10
181109
182- if ! netstat -tlnp | grep -q ":9012"; then
183- echo "❌ asyncio server failed to start on port 9012"
184- cat asyncio-server.log
185- exit 1
186- fi
187-
188- echo "✅ Both servers are running"
189- netstat -tlnp | grep -E ":(9011|9012) "
110+ echo "==> Verifying all servers are running..."
111+ for port in 9011 9012 9013 9014 9015 9016; do
112+ if ! netstat -tuln | grep :${port}; then
113+ echo "❌ Server failed to start on port ${port}"
114+ exit 1
115+ fi
116+ done
117+ echo "✅ All 6 servers are running "
190118
191- - name : Test servers with fuzzingclient
192- run : |
193- echo "==> Testing both Autobahn|Python servers..."
194- just wstest-fuzzingclient
119+ - name : Run server tests
120+ run : just wstest-fuzzingclient "" "" ${{ env.TEST_MODE }}
195121
196- - name : Stop servers and collect results
197- if : always()
198- run : |
199- echo "==> Stopping servers..."
200- if [ -f twisted-server.pid ]; then
201- kill $(cat twisted-server.pid) || true
202- fi
203- if [ -f asyncio-server.pid ]; then
204- kill $(cat asyncio-server.pid) || true
205- fi
206-
207- echo "==> Server test results:"
208- ls -la .wstest/servers/ || echo "No server reports found"
209-
210- - name : Upload server test reports
122+ - name : Upload server reports
211123 uses : actions/upload-artifact@v4
212124 if : always()
213125 with :
214- name : server-reports -${{ env.TEST_MODE }}
126+ name : servers-all -${{ env.TEST_MODE }}
215127 path : .wstest/servers/
216128 retention-days : 30
217129
218- # Consolidate all reports
130+ # Consolidate all reports using the proven justfile recipe
219131 consolidate-reports :
220132 name : Consolidate WebSocket Reports
221133 needs : [client-conformance, server-conformance]
@@ -226,56 +138,37 @@ jobs:
226138 - name : Checkout code
227139 uses : actions/checkout@v4
228140
229- - name : Download all WebSocket reports
141+ - name : Download all artifacts
230142 uses : actions/download-artifact@v4
231143 with :
232- pattern : " *-reports-*"
233- merge-multiple : false
234- path : all-reports/
144+ path : artifacts/
235145
236- - name : Consolidate test reports for documentation
146+ - name : Reconstruct test directory structure
237147 run : |
238- mkdir -p docs/_static/websocket/conformance
148+ echo "==> Reconstructing .wstest directory structure..."
149+ mkdir -p .wstest/clients .wstest/servers
239150
240- echo "==> Consolidating WebSocket conformance test reports..."
241-
242- # Copy client reports to docs/_static
243- for backend in twisted asyncio; do
244- client_dir="client-reports-${backend}-${{ env.TEST_MODE }}"
245- if [ -d "all-reports/${client_dir}" ]; then
246- echo "Copying ${backend} client reports..."
247- cp -r "all-reports/${client_dir}"/* "docs/_static/websocket/conformance/" || true
248- else
249- echo "⚠️ Client report directory not found: ${client_dir}"
250- fi
151+ # Combine all client reports
152+ find artifacts -name "client-*" -type d | while read dir; do
153+ echo "Processing: $dir"
154+ cp -r "$dir"/* .wstest/clients/ || true
251155 done
252156
253- # Copy server reports to docs/_static
254- server_dir="server-reports-${{ env.TEST_MODE }}"
255- if [ -d "all-reports/${server_dir}" ]; then
256- echo "Copying server reports..."
257- cp -r "all-reports/${server_dir}"/* "docs/_static/websocket/conformance/" || true
258- else
259- echo "⚠️ Server report directory not found: ${server_dir}"
260- fi
261-
262- # Create ZIP archive of all JSON test reports
263- echo "==> Creating JSON reports archive..."
264- find docs/_static/websocket/conformance -name "*.json" -type f > json_files.txt
265- if [ -s json_files.txt ]; then
266- json_count=$(wc -l < json_files.txt)
267- echo "Found ${json_count} JSON test report files"
268- zip -r "docs/_static/websocket/conformance/conformance-reports-${{ env.TEST_MODE }}.zip" -@ < json_files.txt
269- echo "✅ Created conformance-reports-${{ env.TEST_MODE }}.zip with ${json_count} JSON files"
270- else
271- echo "⚠️ No JSON test report files found"
272- fi
157+ # Copy server reports
158+ find artifacts -name "servers-*" -type d | while read dir; do
159+ echo "Processing: $dir"
160+ cp -r "$dir"/* .wstest/servers/ || true
161+ done
273162
274- echo "✅ Test reports consolidated for documentation"
275- echo "HTML reports: docs/_static/websocket/conformance/"
276- ls -la docs/_static/websocket/conformance/ | head -10
163+ echo "Client reports:" && ls -la .wstest/clients/ || echo "None"
164+ echo "Server reports:" && ls -la .wstest/servers/ || echo "None"
277165
278- - name : Upload consolidated WebSocket reports
166+ - name : Consolidate reports for documentation
167+ run : |
168+ echo "==> Using proven justfile recipe..."
169+ just wstest-consolidate-reports
170+
171+ - name : Upload consolidated reports
279172 uses : actions/upload-artifact@v4
280173 with :
281174 name : websocket-conformance-docs-${{ env.TEST_MODE }}
@@ -284,13 +177,11 @@ jobs:
284177
285178 - name : Report summary
286179 run : |
287- echo "==> WebSocket Conformance Testing Complete"
180+ echo "==> WebSocket Conformance Testing Complete ✅ "
288181 echo "Test Mode: ${{ env.TEST_MODE }}"
289- echo "Reports integrated into documentation:"
290- find docs/_static/websocket/conformance -name "index.html" | sort
182+ echo "Matrix tested: (client|server) × (twisted|asyncio) × (cpy311|cpy314|pypy311)"
291183 echo ""
292- if [ -f docs/_static/websocket/conformance/conformance-reports-${{ env.TEST_MODE }}.zip ]; then
293- echo "📦 JSON reports archive: conformance-reports-${{ env.TEST_MODE }}.zip"
294- fi
295- echo "📄 HTML reports available in docs/_static/websocket/conformance/"
296- echo "🔗 All reports available in job artifacts"
184+ find docs/_static/websocket/conformance -name "*.zip" | while read zip; do
185+ echo "📦 $(basename "$zip")"
186+ done
187+ echo "📄 Documentation: docs/_static/websocket/conformance/"
0 commit comments