Skip to content

Commit 41a77b0

Browse files
committed
fix(gateway): harden smoke validation
1 parent 3b24c07 commit 41a77b0

4 files changed

Lines changed: 110 additions & 40 deletions

File tree

Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ conformance:
1818
kind create cluster --name $(CLUSTER_NAME) --wait 5m
1919
kubectl wait --for=condition=ready node --all --timeout=2m
2020
@echo "=== Installing Gateway API CRDs ==="
21-
kubectl apply -f $(GATEWAY_API_CRDS_STANDARD)
22-
-kubectl apply -f $(GATEWAY_API_CRDS_EXPERIMENTAL)
21+
GATEWAY_API_CHANNEL=experimental scripts/ci/install-gateway-api-crds.sh
2322
@echo "=== Deploying nantian-gw ==="
2423
kustomize build deploy/kubernetes/overlays/kind-conformance --load-restrictor LoadRestrictionsNone | kubectl apply -f -
2524
kubectl wait --for=condition=ready pod --all -n nantian-gw --timeout=180s

scripts/ci/ci_assets_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func TestSmokeScriptForwardsToProgrammedGatewayListener(t *testing.T) {
163163
for _, want := range []string{
164164
`LOCAL_HTTP_PORT="${LOCAL_HTTP_PORT:-10080}"`,
165165
`GATEWAY_HTTP_PORT="${GATEWAY_HTTP_PORT:-80}"`,
166-
`service/$DATA_PLANE_SVC`,
166+
`deployment/$DATA_PLANE_DEPLOYMENT`,
167167
`"${LOCAL_HTTP_PORT}:${GATEWAY_HTTP_PORT}"`,
168168
`request_deadline=`,
169169
} {
@@ -176,10 +176,11 @@ func TestSmokeScriptForwardsToProgrammedGatewayListener(t *testing.T) {
176176
`pod/$dataplane_pod`,
177177
`dataplane_pod=$(kubectl get pod`,
178178
`port-forward to $dataplane_pod exited before request succeeded`,
179-
`10080:10080`,
179+
`service/$DATA_PLANE_SVC`,
180+
`DATA_PLANE_HTTP_PORT=`,
180181
} {
181182
if strings.Contains(contents, unwanted) {
182-
t.Fatalf("smoke script still contains stale pod-forward pattern %q", unwanted)
183+
t.Fatalf("smoke script still contains stale port-forward pattern %q", unwanted)
183184
}
184185
}
185186
}
@@ -206,7 +207,7 @@ func TestCIEntrypointsUseCurrentDeployResourceNames(t *testing.T) {
206207
}
207208

208209
for _, oldName := range []string{
209-
"nantian-controlplane",
210+
`CONTROL_PLANE_DEPLOYMENT="nantian-controlplane"`,
210211
"gatewayClassName: nantian",
211212
"app=nantian-dataplane",
212213
} {

scripts/ci/install-gateway-api-crds.sh

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ set -euo pipefail
44
GATEWAY_API_VERSION="${GATEWAY_API_VERSION:-v1.5.1}"
55
GATEWAY_API_CHANNEL="${GATEWAY_API_CHANNEL:-experimental}"
66
BASE_URL="https://github.com/kubernetes-sigs/gateway-api/releases/download/${GATEWAY_API_VERSION}"
7+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8+
GATEWAY_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
9+
HELM_CHARTS_ROOT="${HELM_CHARTS_ROOT:-$GATEWAY_ROOT/../helm-charts}"
10+
BUNDLED_STANDARD_CRDS="$HELM_CHARTS_ROOT/charts/nantian-gw/charts/gateway-api-crds-standard/crds"
711

812
case "$GATEWAY_API_CHANNEL" in
913
standard | experimental)
@@ -20,11 +24,6 @@ cleanup() {
2024
}
2125
trap cleanup EXIT
2226

23-
manifest_file="$tmpdir/${GATEWAY_API_CHANNEL}-install.yaml"
24-
curl -fsSL --connect-timeout 15 --max-time 120 --retry 3 --retry-delay 5 --retry-all-errors \
25-
"${BASE_URL}/${GATEWAY_API_CHANNEL}-install.yaml" \
26-
-o "$manifest_file"
27-
2827
apply_with_retries() {
2928
local manifest="$1"
3029

@@ -41,14 +40,32 @@ apply_with_retries() {
4140
return 1
4241
}
4342

43+
wait_for_standard_crds() {
44+
kubectl wait --for=condition=established crd/gatewayclasses.gateway.networking.k8s.io --timeout=60s
45+
kubectl wait --for=condition=established crd/gateways.gateway.networking.k8s.io --timeout=60s
46+
kubectl wait --for=condition=established crd/httproutes.gateway.networking.k8s.io --timeout=60s
47+
kubectl wait --for=condition=established crd/referencegrants.gateway.networking.k8s.io --timeout=60s
48+
}
49+
50+
if [[ -d "$BUNDLED_STANDARD_CRDS" ]]; then
51+
echo "Installing bundled Gateway API CRDs from $BUNDLED_STANDARD_CRDS"
52+
apply_with_retries "$BUNDLED_STANDARD_CRDS"
53+
wait_for_standard_crds
54+
exit 0
55+
fi
56+
57+
manifest_file="$tmpdir/${GATEWAY_API_CHANNEL}-install.yaml"
58+
curl -fsSL --connect-timeout 15 --max-time 120 --retry 3 --retry-delay 5 --retry-all-errors \
59+
"${BASE_URL}/${GATEWAY_API_CHANNEL}-install.yaml" \
60+
-o "$manifest_file"
61+
4462
apply_with_retries "$manifest_file"
45-
kubectl wait --for=condition=established crd/gatewayclasses.gateway.networking.k8s.io --timeout=60s
46-
kubectl wait --for=condition=established crd/gateways.gateway.networking.k8s.io --timeout=60s
47-
kubectl wait --for=condition=established crd/httproutes.gateway.networking.k8s.io --timeout=60s
48-
kubectl wait --for=condition=established crd/referencegrants.gateway.networking.k8s.io --timeout=60s
49-
50-
if [[ "$GATEWAY_API_CHANNEL" == "experimental" ]]; then
51-
kubectl wait --for=condition=established crd/tcproutes.gateway.networking.k8s.io --timeout=60s
52-
kubectl wait --for=condition=established crd/udproutes.gateway.networking.k8s.io --timeout=60s
53-
kubectl wait --for=condition=established crd/tlsroutes.gateway.networking.k8s.io --timeout=60s
63+
wait_for_standard_crds
64+
65+
if [[ "$GATEWAY_API_CHANNEL" != "experimental" ]]; then
66+
exit 0
5467
fi
68+
69+
kubectl wait --for=condition=established crd/tcproutes.gateway.networking.k8s.io --timeout=60s
70+
kubectl wait --for=condition=established crd/udproutes.gateway.networking.k8s.io --timeout=60s
71+
kubectl wait --for=condition=established crd/tlsroutes.gateway.networking.k8s.io --timeout=60s

test/e2e/smoke/run.sh

Lines changed: 73 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ CLUSTER_NAME="${CLUSTER_NAME:-nantian-e2e}"
1010
CONTROL_PLANE_NS="nantian-gw"
1111
TEST_NS="nantian-e2e"
1212
CONTROL_PLANE_DEPLOYMENT="nantian-gw-controlplane"
13-
DATA_PLANE_SVC="nantian-gw-dataplane"
13+
DATA_PLANE_DEPLOYMENT="nantian-gw-dataplane"
14+
CONTROL_PLANE_IMAGE="${CONTROL_PLANE_IMAGE:-ghcr.io/nantian-gw/nantian-controlplane:latest}"
15+
DATA_PLANE_IMAGE="${DATA_PLANE_IMAGE:-ghcr.io/nantian-gw/dataplane:latest}"
16+
DASHBOARD_IMAGE="${DASHBOARD_IMAGE:-ghcr.io/nantian-gw/dashboard:latest}"
1417
DATA_PLANE_SELECTOR="app=nantian-gw-dataplane"
1518
GATEWAY_CLASS_NAME="${GATEWAY_CLASS_NAME:-nantian-gw}"
19+
ECHO_IMAGE="${ECHO_IMAGE:-registry.k8s.io/e2e-test-images/echoserver:2.5}"
1620
ECHO_PORT=8080
1721
LOCAL_HTTP_PORT="${LOCAL_HTTP_PORT:-10080}"
1822
GATEWAY_HTTP_PORT="${GATEWAY_HTTP_PORT:-80}"
19-
TIMEOUT="${TIMEOUT:-180}"
23+
TIMEOUT="${TIMEOUT:-300}"
2024
CLEANUP="${1:-}"
2125
FAILED=false
2226

@@ -38,6 +42,21 @@ cleanup_cluster() {
3842
kind delete cluster --name "$CLUSTER_NAME" 2>/dev/null || true
3943
}
4044

45+
finish() {
46+
local exit_code=$?
47+
if (( exit_code != 0 )); then
48+
FAILED=true
49+
fi
50+
51+
cleanup_cluster
52+
if $FAILED; then
53+
red "✗ Smoke test FAILED"
54+
else
55+
green "✓ Smoke test PASSED"
56+
fi
57+
exit "$exit_code"
58+
}
59+
4160
stop_port_forward() {
4261
local pid="$1"
4362
kill "$pid" 2>/dev/null || true
@@ -62,29 +81,64 @@ install_gateway_api_crds() {
6281
return
6382
fi
6483
echo "=== Installing Gateway API CRDs ==="
65-
BASE="https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1"
66-
kubectl apply -f "$BASE/standard-install.yaml"
67-
kubectl apply -f "$BASE/experimental-install.yaml" || true
68-
kubectl wait --for=condition=established crd/gatewayclasses.gateway.networking.k8s.io --timeout=60s
84+
GATEWAY_API_CHANNEL=experimental "$GATEWAY_ROOT/scripts/ci/install-gateway-api-crds.sh"
85+
}
86+
87+
# ── Step 3: preload runtime images ──
88+
preload_image() {
89+
local image="$1"
90+
local image_archive
91+
92+
for attempt in 1 2 3; do
93+
if docker image inspect "$image" >/dev/null 2>&1 || docker pull "$image"; then
94+
image_archive="$(mktemp "${TMPDIR:-/tmp}/nantian-kind-image.XXXXXX.tar")"
95+
if docker save --platform linux/amd64 -o "$image_archive" "$image" \
96+
&& kind load image-archive --name "$CLUSTER_NAME" "$image_archive"; then
97+
rm -f "$image_archive"
98+
return
99+
fi
100+
rm -f "$image_archive"
101+
fi
102+
103+
echo "Failed to preload $image on attempt $attempt; retrying in 10s..." >&2
104+
sleep 10
105+
done
106+
107+
echo "Failed to preload $image after 3 attempts." >&2
108+
return 1
69109
}
70110

71-
# ── Step 3: deploy nantian-gw ──
111+
preload_gateway_images() {
112+
echo "=== Preloading nantian-gw images ==="
113+
preload_image "$CONTROL_PLANE_IMAGE"
114+
preload_image "$DATA_PLANE_IMAGE"
115+
preload_image "$DASHBOARD_IMAGE"
116+
}
117+
118+
# ── Step 4: deploy nantian-gw ──
72119
deploy_gateway() {
73120
if kubectl get deployment -n "$CONTROL_PLANE_NS" "$CONTROL_PLANE_DEPLOYMENT" &>/dev/null; then
74121
yellow "nantian-gw already deployed, skipping"
75122
return
76123
fi
77124
echo "=== Deploying nantian-gw ==="
78125
kustomize build "$GATEWAY_ROOT/deploy/kubernetes/overlays/kind-conformance" --load-restrictor LoadRestrictionsNone | kubectl apply -f -
79-
kubectl wait --for=condition=ready pod --all -n "$CONTROL_PLANE_NS" --timeout="${TIMEOUT}s"
126+
kubectl wait --for=condition=available deployment/"$CONTROL_PLANE_DEPLOYMENT" -n "$CONTROL_PLANE_NS" --timeout="${TIMEOUT}s"
127+
kubectl wait --for=condition=available deployment/"$DATA_PLANE_DEPLOYMENT" -n "$CONTROL_PLANE_NS" --timeout="${TIMEOUT}s"
128+
}
129+
130+
# ── Step 5: preload echo backend image ──
131+
preload_echo_image() {
132+
echo "=== Preloading echo backend image ==="
133+
preload_image "$ECHO_IMAGE"
80134
}
81135

82-
# ── Step 4: deploy echo backend ──
136+
# ── Step 6: deploy echo backend ──
83137
deploy_backend() {
84138
echo "=== Deploying echo backend ==="
85139
kubectl create namespace "$TEST_NS" --dry-run=client -o yaml | kubectl apply -f -
86140

87-
kubectl apply -n "$TEST_NS" -f - <<'YAML'
141+
kubectl apply -n "$TEST_NS" -f - <<YAML
88142
apiVersion: apps/v1
89143
kind: Deployment
90144
metadata:
@@ -101,12 +155,9 @@ spec:
101155
spec:
102156
containers:
103157
- name: echo
104-
image: docker.io/ealen/echo-server:latest
158+
image: $ECHO_IMAGE
105159
ports:
106-
- containerPort: 80
107-
env:
108-
- name: PORT
109-
value: "80"
160+
- containerPort: 8080
110161
---
111162
apiVersion: v1
112163
kind: Service
@@ -117,14 +168,14 @@ spec:
117168
app: echo
118169
ports:
119170
- port: 80
120-
targetPort: 80
171+
targetPort: 8080
121172
YAML
122173

123174
kubectl wait --for=condition=ready pod -l app=echo -n "$TEST_NS" --timeout="${TIMEOUT}s"
124175
green " echo backend ready"
125176
}
126177

127-
# ── Step 5: create Gateway, ReferenceGrant, and HTTPRoute ──
178+
# ── Step 7: create Gateway, ReferenceGrant, and HTTPRoute ──
128179
create_gateway() {
129180
echo "=== Creating Gateway ==="
130181
kubectl apply -n "$CONTROL_PLANE_NS" -f - <<YAML
@@ -195,9 +246,9 @@ YAML
195246
green " HTTPRoute created"
196247
}
197248

198-
# ── Step 6: port-forward and send request ──
249+
# ── Step 8: port-forward and send request ──
199250
send_request() {
200-
local dataplane_target="service/$DATA_PLANE_SVC"
251+
local dataplane_target="deployment/$DATA_PLANE_DEPLOYMENT"
201252

202253
echo "=== Sending test request (port-forward $dataplane_target ${LOCAL_HTTP_PORT}:${GATEWAY_HTTP_PORT}) ==="
203254

@@ -231,11 +282,13 @@ send_request() {
231282

232283
# ── Main ──
233284
main() {
234-
trap 'cleanup_cluster; if $FAILED; then red "✗ Smoke test FAILED"; else green "✓ Smoke test PASSED"; fi' EXIT
285+
trap finish EXIT
235286

236287
ensure_cluster
237288
install_gateway_api_crds
289+
preload_gateway_images
238290
deploy_gateway
291+
preload_echo_image
239292
deploy_backend
240293
create_gateway
241294
create_reference_grant

0 commit comments

Comments
 (0)