Skip to content

Commit db21e9e

Browse files
authored
feat: Adds e2e test script (#294)
* feat: Adds e2e test script Signed-off-by: Daneyon Hansen <[email protected]> * Docs the e2e test script Signed-off-by: Daneyon Hansen <[email protected]> --------- Signed-off-by: Daneyon Hansen <[email protected]>
1 parent 0662f1f commit db21e9e

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

Diff for: hack/test-e2e.sh

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/bin/bash
2+
#
3+
# This script verifies end-to-end connectivity for an example inference extension test environment based on
4+
# resources from the quickstart guide or e2e test framework. It can optionally launch a "curl" client pod to
5+
# run these tests within the cluster.
6+
#
7+
# USAGE: ./hack/e2e-test.sh
8+
#
9+
# OPTIONAL ENVIRONMENT VARIABLES:
10+
# - TIME: The duration (in seconds) for which the test will run. Defaults to 1 second.
11+
# - CURL_POD: If set to "true", the script will use a Kubernetes pod named "curl" for making requests.
12+
# - IP: Override the detected IP address. If not provided, the script attempts to use a Gateway based on
13+
# the quickstart guide or an Envoy service IP based on the e2e test framework.
14+
# - PORT: Override the detected port. If not provided, the script attempts to use a Gateway based on the
15+
# quickstart guide or an Envoy service IP based on the e2e test framework.
16+
#
17+
# WHAT THE SCRIPT DOES:
18+
# 1. Determines if there is a Gateway named "inference-gateway" in the "default" namespace. If found, it extracts the IP
19+
# address and port from the Gateway's "llm-gw" listener. Otherwise, it falls back to the Envoy service in the "default" namespace.
20+
# 2. Optionally checks for (or creates) a "curl" pod, ensuring it is ready to execute requests.
21+
# 3. Loops for $TIME seconds, sending requests every 5 seconds to the /v1/completions endpoint to confirm successful connectivity.
22+
23+
set -euo pipefail
24+
25+
# Determine the directory of this script and build an absolute path to client.yaml.
26+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
27+
CLIENT_YAML="$SCRIPT_DIR/../test/testdata/client.yaml"
28+
29+
# TIME is the amount of time, in seconds, to run the test.
30+
TIME=${TIME:-1}
31+
# Optionally use a client curl pod for executing the curl command.
32+
CURL_POD=${CURL_POD:-false}
33+
34+
check_resource_exists() {
35+
local type=$1
36+
local name=$2
37+
local namespace=$3
38+
39+
if kubectl get "$type" "$name" -n "$namespace" &>/dev/null; then
40+
return 0
41+
else
42+
return 1
43+
fi
44+
}
45+
46+
check_pod_ready() {
47+
local pod_name=$1
48+
local namespace=$2
49+
# Check the Ready condition using jsonpath. Default to False if not found.
50+
local ready_status
51+
ready_status=$(kubectl get pod "$pod_name" -n "$namespace" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null || echo "False")
52+
if [[ "$ready_status" == "True" ]]; then
53+
return 0
54+
else
55+
return 1
56+
fi
57+
}
58+
59+
# Try to get the Gateway's IP and the port from the listener named "llm-gw" if it exists.
60+
if check_resource_exists "gateway" "inference-gateway" "default"; then
61+
GATEWAY_IP=$(kubectl get gateway inference-gateway -n default -o jsonpath='{.status.addresses[0].value}')
62+
# Use JSONPath to select the port from the listener with name "llm-gw"
63+
GATEWAY_PORT=$(kubectl get gateway inference-gateway -n default -o jsonpath='{.spec.listeners[?(@.name=="llm-gw")].port}')
64+
else
65+
GATEWAY_IP=""
66+
GATEWAY_PORT=""
67+
fi
68+
69+
if [[ -n "$GATEWAY_IP" && -n "$GATEWAY_PORT" ]]; then
70+
echo "Using Gateway inference-gateway IP and port from listener 'llm-gw'."
71+
IP=${IP:-$GATEWAY_IP}
72+
PORT=${PORT:-$GATEWAY_PORT}
73+
else
74+
echo "Gateway inference-gateway not found or missing IP/port. Falling back to Envoy service."
75+
# Ensure the Envoy service exists.
76+
if ! check_resource_exists "svc" "envoy" "default"; then
77+
echo "Error: Envoy service not found in namespace 'default'."
78+
exit 1
79+
fi
80+
IP=${IP:-$(kubectl get svc envoy -n default -o jsonpath='{.spec.clusterIP}')}
81+
PORT=${PORT:-$(kubectl get svc envoy -n default -o jsonpath='{.spec.ports[0].port}')}
82+
fi
83+
84+
# Optionally verify that the curl pod exists and is ready.
85+
if [[ "$CURL_POD" == "true" ]]; then
86+
if ! check_resource_exists "pod" "curl" "default"; then
87+
echo "Pod 'curl' not found in namespace 'default'. Applying client.yaml from $CLIENT_YAML..."
88+
kubectl apply -f "$CLIENT_YAML"
89+
fi
90+
echo "Waiting for pod 'curl' to be ready..."
91+
# Retry every 5 seconds for up to 30 seconds (6 attempts)
92+
for i in {1..6}; do
93+
if check_pod_ready "curl" "default"; then
94+
echo "Pod 'curl' is now ready."
95+
break
96+
fi
97+
echo "Retry attempt $i: Pod 'curl' not ready; waiting 5 seconds..."
98+
sleep 5
99+
done
100+
101+
if ! check_pod_ready "curl" "default"; then
102+
echo "Error: Pod 'curl' is still not ready in namespace 'default' after 30 seconds."
103+
exit 1
104+
fi
105+
fi
106+
107+
# Validate that we have a non-empty IP and PORT.
108+
if [[ -z "$IP" ]]; then
109+
echo "Error: Unable to determine a valid IP from either Gateway or Envoy service."
110+
exit 1
111+
fi
112+
113+
if [[ -z "$PORT" ]]; then
114+
echo "Error: Unable to determine a valid port from either Gateway or Envoy service."
115+
exit 1
116+
fi
117+
118+
echo "Using IP: $IP"
119+
echo "Using PORT: $PORT"
120+
121+
# Run the test for the specified duration.
122+
end=$((SECONDS + TIME))
123+
if [[ "$CURL_POD" == "true" ]]; then
124+
while [ $SECONDS -lt $end ]; do
125+
kubectl exec po/curl -- curl -i "$IP:$PORT/v1/completions" \
126+
-H 'Content-Type: application/json' \
127+
-d '{"model": "tweet-summary","prompt": "Write as if you were a critic: San Francisco","max_tokens": 100,"temperature": 0}'
128+
sleep 5
129+
done
130+
else
131+
while [ $SECONDS -lt $end ]; do
132+
curl -i "$IP:$PORT/v1/completions" \
133+
-H 'Content-Type: application/json' \
134+
-d '{"model": "tweet-summary","prompt": "Write as if you were a critic: San Francisco","max_tokens": 100,"temperature": 0}'
135+
sleep 5
136+
done
137+
fi

0 commit comments

Comments
 (0)