66jobs :
77 test-tutorials :
88 timeout-minutes : 15
9- name : test-tutorial-${{ matrix.tutorial }}
9+ name : test-tutorials
1010 runs-on : ubuntu-latest
1111
1212 steps :
@@ -86,32 +86,32 @@ jobs:
8686 echo "UV version: $(uv --version)"
8787 echo "UV path: $(which uv)"
8888
89- # Start background job to continuously poll AgentEx container logs
90- echo "🔍 Starting AgentEx container log polling in background..."
89+ # Start background job to poll AgentEx container logs and write to file
9190 (
92- echo "Log polling started at $(date)"
91+ echo "AgentEx container log polling started at $(date)" > /tmp/agentex_container_logs.txt
9392
9493 # Function to get container logs
9594 get_logs() {
96- echo "=== AgentEx Container Logs $(date) ==="
97- docker logs agentex --tail=20 2>/dev/null || {
98- echo "⚠️ Failed to get logs from 'agentex' container"
99- echo "Available containers:"
100- docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
101- }
102- echo "=== End Logs ==="
103- echo ""
95+ echo "=== AgentEx Container Logs $(date) ===" >> /tmp/agentex_container_logs.txt
96+ docker logs agentex --tail=20 2>/dev/null >> /tmp/agentex_container_logs.txt || {
97+ echo "⚠️ Failed to get logs from 'agentex' container" >> /tmp/agentex_container_logs.txt
98+ echo "Available containers:" >> /tmp/agentex_container_logs.txt
99+ docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" >> /tmp/agentex_container_logs.txt
100+ } 2>/dev/null
101+ echo "=== End Logs ===" >> /tmp/agentex_container_logs.txt
102+ echo "" >> /tmp/agentex_container_logs.txt
104103 }
105104
106- # Poll logs every 2 seconds (very frequent for debugging)
105+ # Poll logs every 10 seconds during test execution
107106 while true; do
108107 get_logs
109- sleep 2
108+ sleep 10
110109 done
111110 ) &
112111
113112 LOG_POLLER_PID=$!
114- echo "📋 Log poller started with PID: $LOG_POLLER_PID"
113+ echo "📋 AgentEx log polling started in background (PID: $LOG_POLLER_PID)"
114+
115115
116116 # Find all tutorial directories
117117 tutorial_paths=()
@@ -148,23 +148,30 @@ jobs:
148148
149149 # Keep host_address as host.docker.internal for CI (allows Docker container to reach GitHub runner host)
150150 # Note: The AgentEx server runs in Docker and needs host.docker.internal to reach the tutorial agent on the host
151-
152- echo "Updated $manifest_path to use port $port (keeping host_address: host.docker.internal)"
153151 fi
154152
155153
156- # Run test in background with unique port
154+ # Run test in background with unique port and show pytest output in real-time
157155 (
156+ test_output_file="/tmp/test_output_$i.log"
157+ echo "Running test: $tutorial" | tee "$test_output_file"
158+ echo "Port: $port" | tee -a "$test_output_file"
159+ echo "========================================" | tee -a "$test_output_file"
160+
158161 AGENTEX_API_BASE_URL="http://localhost:5003" \
159- ./run_agent_test.sh --build-cli "$tutorial"
162+ ./run_agent_test.sh --build-cli --quiet "$tutorial" 2>&1 | tee -a "$test_output_file "
160163
161- if [ $? -eq 0 ]; then
164+ exit_code=${PIPESTATUS[0]}
165+ if [ $exit_code -eq 0 ]; then
162166 echo "✅ PASSED: $tutorial (port $port)"
163167 echo "$tutorial" > "/tmp/passed_$i.txt"
168+ echo "$test_output_file" > "/tmp/passed_output_$i.txt"
164169 else
165170 echo "❌ FAILED: $tutorial (port $port)"
166171 echo "$tutorial" > "/tmp/failed_$i.txt"
172+ echo "$test_output_file" > "/tmp/failed_output_$i.txt"
167173 fi
174+ exit $exit_code
168175 ) &
169176
170177 pids+=($!)
@@ -177,32 +184,6 @@ jobs:
177184 wait "$pid"
178185 done
179186
180- # Always show AgentEx server container logs immediately after tests complete
181- echo ""
182- echo "========================================="
183- echo "AGENTEX SERVER CONTAINER LOGS"
184- echo "========================================="
185-
186- # Show AgentEx server container logs
187- echo "📋 AgentEx server container logs:"
188- echo "----------------------------------------"
189-
190- echo "Available containers:"
191- docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
192-
193- echo ""
194- echo "AgentEx container logs (last 100 lines):"
195- docker logs agentex --tail=100 2>/dev/null || {
196- echo "❌ Failed to get logs from 'agentex' container"
197- echo "Available containers:"
198- docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
199- }
200- echo "----------------------------------------"
201-
202- # Stop the log poller
203- echo "🛑 Stopping log poller (PID: $LOG_POLLER_PID)"
204- kill $LOG_POLLER_PID 2>/dev/null || echo "Log poller already stopped"
205-
206187 # Restore all original manifests
207188 echo ""
208189 echo "Restoring original manifest files..."
@@ -223,6 +204,10 @@ jobs:
223204 done
224205
225206
207+ # Stop the background log poller
208+ echo "🛑 Stopping AgentEx log poller (PID: $LOG_POLLER_PID)"
209+ kill $LOG_POLLER_PID 2>/dev/null || echo "Log poller already stopped"
210+
226211 # Print summary
227212 echo ""
228213 echo "========================================="
@@ -238,14 +223,101 @@ jobs:
238223 for test in "${failed_tests[@]}"; do
239224 echo " ❌ $test"
240225 done
241-
242-
243- exit 1
244226 else
245227 echo ""
246228 echo "🎉 All tests passed!"
247229 fi
248230
231+ # Show comprehensive pytest summary
232+ echo ""
233+ echo "========================================="
234+ echo "PYTEST RESULTS SUMMARY"
235+ echo "========================================="
236+
237+ # Collect all pytest results
238+ total_passed_tests=0
239+ total_failed_tests=0
240+ total_pytest_tests=0
241+
242+ echo ""
243+ echo "📊 PYTEST EXECUTION SUMMARY:"
244+ echo "----------------------------------------"
245+
246+ for i in "${!tutorial_paths[@]}"; do
247+ tutorial="${tutorial_paths[$i]}"
248+ output_file="/tmp/test_output_$i.log"
249+
250+ if [ -f "$output_file" ]; then
251+ # Extract pytest summary from each test
252+ if grep -q "PYTEST OUTPUT" "$output_file"; then
253+ pytest_section=$(sed -n '/========== PYTEST OUTPUT ==========/,/========== END PYTEST OUTPUT ==========/p' "$output_file")
254+
255+ # Count individual test results in this tutorial
256+ test_passed=$(echo "$pytest_section" | grep -c "PASSED" || echo "0")
257+ test_failed=$(echo "$pytest_section" | grep -c "FAILED" || echo "0")
258+ test_errors=$(echo "$pytest_section" | grep -c "ERROR" || echo "0")
259+
260+ if [ "$test_passed" -gt 0 ] || [ "$test_failed" -gt 0 ] || [ "$test_errors" -gt 0 ]; then
261+ tutorial_total=$((test_passed + test_failed + test_errors))
262+ total_pytest_tests=$((total_pytest_tests + tutorial_total))
263+ total_passed_tests=$((total_passed_tests + test_passed))
264+ total_failed_tests=$((total_failed_tests + test_failed + test_errors))
265+
266+ if [ "$test_failed" -gt 0 ] || [ "$test_errors" -gt 0 ]; then
267+ echo "❌ $tutorial: $tutorial_total tests ($test_passed passed, $test_failed failed, $test_errors errors)"
268+ else
269+ echo "✅ $tutorial: $tutorial_total tests ($test_passed passed)"
270+ fi
271+ else
272+ echo "⚠️ $tutorial: No pytest results found"
273+ fi
274+ else
275+ echo "⚠️ $tutorial: No pytest output detected"
276+ fi
277+ else
278+ echo "⚠️ $tutorial: No output file found"
279+ fi
280+ done
281+
282+ echo "----------------------------------------"
283+ echo "🏁 OVERALL PYTEST SUMMARY:"
284+ echo " Total pytest tests run: $total_pytest_tests"
285+ echo " Total pytest tests passed: $total_passed_tests"
286+ echo " Total pytest tests failed: $total_failed_tests"
287+ echo ""
288+
289+ # Show detailed results for failed tests only
290+ if [ ${#failed_tests[@]} -gt 0 ]; then
291+ echo "❌ DETAILED FAILURE ANALYSIS:"
292+ echo "----------------------------------------"
293+ for i in "${!tutorial_paths[@]}"; do
294+ if [ -f "/tmp/failed_$i.txt" ]; then
295+ test_name=$(cat "/tmp/failed_$i.txt")
296+ output_file=$(cat "/tmp/failed_output_$i.txt")
297+ echo ""
298+ echo "📋 FAILED: $test_name"
299+ echo "----------------------------------------"
300+ if [ -f "$output_file" ]; then
301+ # Show just the pytest failure details
302+ if grep -q "PYTEST OUTPUT" "$output_file"; then
303+ echo "Pytest failure details:"
304+ sed -n '/========== PYTEST OUTPUT ==========/,/========== END PYTEST OUTPUT ==========/p' "$output_file"
305+ else
306+ echo "No pytest output found. Showing last 40 lines:"
307+ tail -40 "$output_file"
308+ fi
309+ else
310+ echo "No output file found"
311+ fi
312+ echo "----------------------------------------"
313+ fi
314+ done
315+ fi
316+
317+ if [ ${#failed_tests[@]} -gt 0 ]; then
318+ exit 1
319+ fi
320+
249321 - name : Debug Logs for Failed Tests
250322 if : always()
251323 run : |
@@ -256,19 +328,27 @@ jobs:
256328 echo "🐛 DEBUG LOGS (for troubleshooting)"
257329 echo "================================================================================"
258330
259- # Show AgentEx server container logs
331+ # Show collected AgentEx server container logs
260332 echo ""
261333 echo "========================================="
262- echo "AGENTEX SERVER LOGS"
334+ echo "AGENTEX SERVER LOGS (COLLECTED DURING TESTS) "
263335 echo "========================================="
264- echo "📋 AgentEx server container logs (last 200 lines):"
265- echo "----------------------------------------"
266- docker logs agentex --tail=200 2>/dev/null || {
267- echo "❌ Failed to get logs from 'agentex' container"
268- echo "Available containers:"
269- docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
270- }
271- echo "----------------------------------------"
336+ if [ -f "/tmp/agentex_container_logs.txt" ]; then
337+ echo "📋 AgentEx server logs collected during test execution:"
338+ echo "----------------------------------------"
339+ cat /tmp/agentex_container_logs.txt
340+ echo "----------------------------------------"
341+ else
342+ echo "⚠️ No AgentEx container logs file found"
343+ echo "📋 Attempting to get current container logs:"
344+ echo "----------------------------------------"
345+ docker logs agentex --tail=50 2>/dev/null || {
346+ echo "❌ Failed to get logs from 'agentex' container"
347+ echo "Available containers:"
348+ docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
349+ }
350+ echo "----------------------------------------"
351+ fi
272352
273353 # Show tutorial agent logs for failed tests
274354 cd ../../examples/tutorials
0 commit comments