1+ #! /usr/bin/env bash
2+ set -euo pipefail
3+
4+ # -----------------------------------------------------------------------------
5+ # e2e-validate.sh — CI e2e Gateway smoke-test (chat + completion, 7 iterations)
6+ # By default we only test completion curls unless specifed to run chat.
7+ # -----------------------------------------------------------------------------
8+
9+ show_help () {
10+ cat << EOF
11+ Usage: $( basename " $0 " ) [OPTIONS]
12+
13+ Options:
14+ -n, --namespace NAMESPACE Kubernetes namespace (default: llm-d)
15+ -m, --model MODEL_ID Model to query.
16+ -c, --chatValidation Enable chat validation testing.
17+ -v, --verbose Echo kubectl/curl commands before running
18+ -h, --help Show this help and exit
19+ EOF
20+ exit 0
21+ }
22+
23+ # ── Defaults ────────────────────────────────────────────────────────────────
24+ NAMESPACE=" igw-e2e"
25+ CLI_MODEL_ID=" "
26+ VERBOSE=false
27+ TEST_CHAT=false
28+
29+ # ── Flag parsing ────────────────────────────────────────────────────────────
30+ while [[ $# -gt 0 ]]; do
31+ case $1 in
32+ -n|--namespace)
33+ if [[ -z " $2 " ]]; then echo " Error: $1 requires a value." >&2 ; exit 1; fi
34+ NAMESPACE=" $2 " ; shift 2 ;;
35+ -m|--model)
36+ if [[ -z " $2 " ]]; then echo " Error: $1 requires a value." >&2 ; exit 1; fi
37+ CLI_MODEL_ID=" $2 " ; shift 2 ;;
38+ -c|--chatValidation) TEST_CHAT=true; shift ;;
39+ -v|--verbose) VERBOSE=true; shift ;;
40+ -h|--help) show_help ;;
41+ * ) echo " Unknown option: $1 " ; show_help ;;
42+ esac
43+ done
44+
45+ if [[ " ${VERBOSE} " == " true" ]]; then
46+ set -x
47+ fi
48+
49+ # ── Create a unique pod suffix ────────────────────────────────────────────
50+ gen_id () { echo $(( RANDOM % 10000 + 1 )) ; }
51+
52+ # ── Discover Gateway address ────────────────────────────────────────────────
53+ HOST=" ${GATEWAY_HOST:- $(kubectl get gateway -n " $NAMESPACE " \
54+ -o jsonpath=' {.items[0].status.addresses[0].value}' 2>/ dev/ null || true)} "
55+ if [[ -z " $HOST " ]]; then
56+ echo " Error: could not discover a Gateway address in namespace '$NAMESPACE '." >&2
57+ exit 1
58+ fi
59+ PORT=80
60+ SVC_HOST=" ${HOST} :${PORT} "
61+
62+ # ── Determine MODEL_ID ──────────────────────────────────────────────────────
63+ if [[ -n " $CLI_MODEL_ID " ]]; then
64+ MODEL_ID=" $CLI_MODEL_ID "
65+ elif [[ -n " ${MODEL_ID-} " ]]; then
66+ MODEL_ID=" $MODEL_ID "
67+ else
68+ echo " Error: Failed to find model id. Please specify one using the -m flag or the MODEL_ID environment variable." >&2
69+ exit 1
70+ fi
71+
72+ echo " Namespace: $NAMESPACE "
73+ echo " Inference Gateway: ${SVC_HOST} "
74+ echo " Model ID: $MODEL_ID "
75+ echo
76+
77+ output=$( kubectl run --rm -i model-check \
78+ --namespace ${NAMESPACE} \
79+ --image=curlimages/curl \
80+ --restart=Never -- \
81+ sh -c ' curl -vS http://34.1.20.121:80/v1/models 2>&1; echo "Curl Exit code: $?"' )
82+
83+ echo " $output "
84+
85+ # ── Main test loop (10 iterations) ──────────────────────────────────────────
86+ for i in {1..7}; do
87+ echo " === Iteration $i of 10 ==="
88+ failed=false
89+
90+ if [[ -n " $TEST_CHAT " ]]; then
91+
92+ # POST /v1/chat/completions
93+ echo " 1) POST /v1/chat/completions at ${SVC_HOST} "
94+ chat_payload=' {
95+ "model":"' " $MODEL_ID " ' ",
96+ "messages":[{"role":"user","content":"Hello! Who are you?"}]
97+ }'
98+ ID=$( gen_id)
99+
100+ ret=0
101+ output=$( kubectl run --rm -i curl-" $ID " \
102+ --namespace " $NAMESPACE " \
103+ --image=curlimages/curl --restart=Never \
104+ --env " PAYLOAD=$chat_payload " -- \
105+ sh -c ' sleep 1; curl -sS -X POST "http://' ${SVC_HOST} ' /v1/chat/completions" \
106+ -H "accept: application/json" \
107+ -H "Content-Type: application/json" \
108+ -d "$PAYLOAD"' ) || ret=$?
109+ echo " $output "
110+ [[ $ret -ne 0 || " $output " != * ' {' * ]] && {
111+ echo " Error: POST /v1/chat/completions failed (exit $ret or no JSON)" >&2 ; failed=true; }
112+ echo
113+ fi
114+
115+ # POST /v1/completions
116+ echo " 2) POST /v1/completions at ${SVC_HOST} "
117+ payload=' {"model":"' " $MODEL_ID " ' ","prompt":"You are a helpful AI assistant."}'
118+ ID=$( gen_id)
119+
120+ ret=0
121+ output=$( kubectl run --rm -i curl-" $ID " \
122+ --namespace " $NAMESPACE " \
123+ --image=curlimages/curl --restart=Never \
124+ --env " PAYLOAD=$payload " -- \
125+ sh -c ' sleep 1; curl -sS -X POST "http://' ${SVC_HOST} ' /v1/completions" \
126+ -H "accept: application/json" \
127+ -H "Content-Type: application/json" \
128+ -d "$PAYLOAD"' ) || ret=$?
129+ echo " $output "
130+ [[ $ret -ne 0 || " $output " != * ' {' * ]] && {
131+ echo " Error: POST /v1/completions failed (exit $ret or no JSON)" >&2 ; failed=true; }
132+ echo
133+
134+ if $failed ; then
135+ echo " Iteration $i encountered errors; exiting." >&2
136+ exit 1
137+ fi
138+ done
139+
140+ echo " ✅ All 10 iterations succeeded."
0 commit comments