|
1 | 1 | import os |
| 2 | +import time |
2 | 3 | from pathlib import Path |
3 | 4 |
|
4 | 5 | import pytest |
@@ -37,6 +38,44 @@ def get(self, endpoint, params=None): |
37 | 38 | return requests.get(url, params=params, verify=False) |
38 | 39 |
|
39 | 40 |
|
| 41 | +def _wait_for_http_ready(route_url: str, timeout: int = 180, interval: int = 5) -> None: |
| 42 | + """ |
| 43 | + Poll the HTTP endpoint until it returns a non-502 response. |
| 44 | +
|
| 45 | + After Pod/CR readiness is confirmed, the backend behind the ingress may |
| 46 | + still be initializing. This helper avoids the race condition where tests |
| 47 | + start before the Feast server is ready, causing all requests to return 502. |
| 48 | + """ |
| 49 | + health_url = f"{route_url}/api/v1/projects" |
| 50 | + deadline = time.time() + timeout |
| 51 | + last_status = None |
| 52 | + |
| 53 | + print( |
| 54 | + f"\n Waiting for HTTP endpoint to become ready (timeout={timeout}s): {health_url}" |
| 55 | + ) |
| 56 | + |
| 57 | + while time.time() < deadline: |
| 58 | + try: |
| 59 | + resp = requests.get(health_url, timeout=10, verify=False) |
| 60 | + last_status = resp.status_code |
| 61 | + if resp.status_code != 502: |
| 62 | + print(f" HTTP endpoint is ready (status={resp.status_code})") |
| 63 | + return |
| 64 | + print( |
| 65 | + f" HTTP endpoint returned {resp.status_code}, retrying in {interval}s..." |
| 66 | + ) |
| 67 | + except requests.exceptions.RequestException as exc: |
| 68 | + last_status = str(exc) |
| 69 | + print(f" HTTP request failed ({exc}), retrying in {interval}s...") |
| 70 | + |
| 71 | + time.sleep(interval) |
| 72 | + |
| 73 | + raise RuntimeError( |
| 74 | + f"HTTP endpoint {health_url} did not become ready within {timeout}s " |
| 75 | + f"(last status: {last_status})" |
| 76 | + ) |
| 77 | + |
| 78 | + |
40 | 79 | @pytest.fixture(scope="session") |
41 | 80 | def feast_rest_client(): |
42 | 81 | # Load kubeconfig and initialize Kubernetes client |
@@ -142,6 +181,11 @@ def feast_rest_client(): |
142 | 181 | if not route_url: |
143 | 182 | raise RuntimeError("Route URL could not be fetched.") |
144 | 183 |
|
| 184 | + # Wait for the HTTP endpoint to become ready before running tests. |
| 185 | + # Pod/CR readiness does not guarantee the backend is serving traffic; |
| 186 | + # the ingress may return 502 while the Feast server is still starting. |
| 187 | + _wait_for_http_ready(route_url) |
| 188 | + |
145 | 189 | print(f"\n Connected to Feast REST at: {route_url}") |
146 | 190 | yield FeastRestClient(route_url) |
147 | 191 |
|
|
0 commit comments