Skip to content

Commit 431bb6b

Browse files
authored
Merge pull request rh-ai-quickstart#125 from skattoju/fix/port-forwarding-timeout
fix: Enhance reliability of UI E2E tests
2 parents a6dae68 + 0ff01e9 commit 431bb6b

5 files changed

Lines changed: 97 additions & 28 deletions

File tree

.github/workflows/e2e-tests.yaml

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -629,17 +629,23 @@ jobs:
629629
deployment/llamastack -n rag-e2e-ui
630630
kubectl wait --for=condition=available --timeout=300s \
631631
deployment/rag -n rag-e2e-ui
632+
633+
echo "Waiting for pods to be ready..."
634+
kubectl wait --for=condition=ready --timeout=600s \
635+
pod -l app.kubernetes.io/name=llamastack -n rag-e2e-ui
636+
kubectl wait --for=condition=ready --timeout=300s \
637+
pod -l app.kubernetes.io/name=rag -n rag-e2e-ui
638+
639+
echo "✅ All pods are ready"
640+
kubectl get pods -n rag-e2e-ui
632641
633642
- name: Expose services via NodePort
634643
run: |
635644
kubectl patch service rag -n rag-e2e-ui -p '{"spec":{"type":"NodePort","ports":[{"port":8501,"nodePort":30080}]}}'
636645
kubectl patch service llamastack -n rag-e2e-ui -p '{"spec":{"type":"NodePort","ports":[{"port":8321,"nodePort":30081}]}}'
637-
638-
- name: Port forward services
639-
run: |
640-
kubectl port-forward -n rag-e2e-ui svc/rag 8501:8501 &
641-
kubectl port-forward -n rag-e2e-ui svc/llamastack 8321:8321 &
642-
sleep 10
646+
647+
# Verify services
648+
kubectl get services -n rag-e2e-ui
643649
644650
- name: Run UI E2E tests with Playwright
645651
env:
@@ -649,10 +655,74 @@ jobs:
649655
MAAS_MODEL_ID: ${{ env.MAAS_MODEL_ID }}
650656
SKIP_MODEL_TESTS: "false" # Enable MaaS inference tests in UI
651657
run: |
658+
echo "Starting port forwarding and running tests..."
659+
660+
# Start port forwarding in background and keep them running
661+
echo "Starting port forwarding for RAG UI..."
662+
kubectl port-forward -n rag-e2e-ui svc/rag 8501:8501 > /tmp/rag-portforward.log 2>&1 &
663+
RAG_PF_PID=$!
664+
echo "RAG port-forward PID: $RAG_PF_PID"
665+
666+
echo "Starting port forwarding for LlamaStack..."
667+
kubectl port-forward -n rag-e2e-ui svc/llamastack 8321:8321 > /tmp/llamastack-portforward.log 2>&1 &
668+
LLAMASTACK_PF_PID=$!
669+
echo "LlamaStack port-forward PID: $LLAMASTACK_PF_PID"
670+
671+
# Function to check if port forwarding is working
672+
check_port_forwarding() {
673+
(timeout 2 bash -c 'cat < /dev/null > /dev/tcp/localhost/8501' 2>/dev/null) && \
674+
(timeout 2 bash -c 'cat < /dev/null > /dev/tcp/localhost/8321' 2>/dev/null)
675+
}
676+
677+
# Function to verify processes are alive
678+
check_processes() {
679+
kill -0 $RAG_PF_PID 2>/dev/null && kill -0 $LLAMASTACK_PF_PID 2>/dev/null
680+
}
681+
682+
# Wait for port forwarding to establish
683+
echo "Waiting for port forwarding to be ready..."
684+
for i in {1..30}; do
685+
if check_port_forwarding && check_processes; then
686+
echo "✅ Port forwarding is working! (attempt $i)"
687+
break
688+
fi
689+
if [ $i -eq 30 ]; then
690+
echo "❌ Port forwarding failed to establish after 30 attempts"
691+
echo "RAG port-forward log:"
692+
cat /tmp/rag-portforward.log || true
693+
echo "LlamaStack port-forward log:"
694+
cat /tmp/llamastack-portforward.log || true
695+
echo "Checking port-forward processes:"
696+
ps aux | grep "kubectl port-forward" || true
697+
echo "Checking if ports are listening:"
698+
ss -tlnp | grep -E ':(8501|8321)' || netstat -tlnp 2>/dev/null | grep -E ':(8501|8321)' || true
699+
exit 1
700+
fi
701+
echo "Waiting for port forwarding... (attempt $i/30)"
702+
sleep 2
703+
done
704+
705+
# Set up cleanup trap to kill port forwarding on exit
706+
trap "echo 'Cleaning up port forwarding...'; kill $RAG_PF_PID $LLAMASTACK_PF_PID 2>/dev/null || true" EXIT
707+
652708
echo "Running UI E2E tests with MaaS integration..."
653709
echo "MaaS Endpoint: ${MAAS_ENDPOINT}"
654710
echo "MaaS Model ID: ${MAAS_MODEL_ID}"
655-
pytest tests/e2e_ui/ -v --tb=short --browser chromium
711+
712+
# Run tests
713+
pytest tests/e2e_ui/ -v --tb=short --browser chromium || TEST_EXIT_CODE=$?
714+
715+
# Verify port forwarding was still working after tests
716+
if ! check_port_forwarding; then
717+
echo "⚠️ Warning: Port forwarding stopped working during tests"
718+
echo "RAG port-forward log:"
719+
cat /tmp/rag-portforward.log || true
720+
echo "LlamaStack port-forward log:"
721+
cat /tmp/llamastack-portforward.log || true
722+
fi
723+
724+
# Exit with test result
725+
exit ${TEST_EXIT_CODE:-0}
656726
657727
- name: Upload Playwright test results
658728
if: always()

deploy/helm/rag/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ apiVersion: v2
22
name: rag
33
description: A Helm chart for Kubernetes
44
type: application
5-
version: 0.2.28
6-
appVersion: "0.2.28"
5+
version: 0.2.30
6+
appVersion: "0.2.30"
77

88
dependencies:
99
- name: pgvector

deploy/helm/rag/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ replicaCount: 1
33
image:
44
repository: quay.io/rh-ai-quickstart/llamastack-dist-ui
55
pullPolicy: Always
6-
tag: latest-dev
6+
tag: 0.2.30
77

88
service:
99
type: ClusterIP

pytest.ini

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[pytest]
22
# Pytest configuration
3-
asyncio_default_fixture_loop_scope = function
43

54
# Test discovery patterns
65
python_files = test_*.py

tests/e2e_ui/test_chat_ui.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,23 @@ def browser_context_args(browser_context_args):
2929
@pytest.fixture(autouse=True)
3030
def wait_for_app(page: Page):
3131
"""Wait for the Streamlit app to be ready before each test"""
32-
page.goto(RAG_UI_ENDPOINT)
33-
# Wait for Streamlit to finish loading
34-
page.wait_for_load_state("networkidle")
35-
# Give Streamlit additional time to initialize
36-
time.sleep(2)
32+
# Retry navigation in case of transient connection issues
33+
max_retries = 3
34+
for attempt in range(max_retries):
35+
try:
36+
page.goto(RAG_UI_ENDPOINT, timeout=60000, wait_until="domcontentloaded")
37+
# Wait for Streamlit to finish loading
38+
page.wait_for_load_state("networkidle", timeout=60000)
39+
# Give Streamlit additional time to initialize
40+
time.sleep(2)
41+
# Verify page actually loaded
42+
if page.url.startswith(RAG_UI_ENDPOINT):
43+
return
44+
except Exception as e:
45+
if attempt == max_retries - 1:
46+
raise
47+
print(f"Navigation attempt {attempt + 1} failed: {e}, retrying...")
48+
time.sleep(2)
3749

3850

3951
class TestChatUIBasics:
@@ -108,18 +120,6 @@ def test_agent_mode_shows_toolgroups(self, page: Page):
108120

109121
toolgroups = page.get_by_text("Available ToolGroups", exact=False)
110122
expect(toolgroups).to_be_visible(timeout=TEST_TIMEOUT)
111-
112-
def test_agent_type_selector(self, page: Page):
113-
"""Test agent type selector (Regular vs ReAct)"""
114-
agent_radio = page.get_by_text("Agent-based", exact=False).first
115-
if agent_radio.is_visible():
116-
agent_radio.click()
117-
time.sleep(1)
118-
119-
# Look for agent type options with more specific selectors
120-
# Check if either Regular or ReAct options exist
121-
page_content = page.content()
122-
assert "Regular" in page_content or "ReAct" in page_content
123123

124124

125125
class TestConfigurationOptions:

0 commit comments

Comments
 (0)