Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions .github/scripts/e2e/e2e-validate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#!/usr/bin/env bash
set -euo pipefail

# -----------------------------------------------------------------------------
# e2e-validate.sh — CI e2e Gateway smoke-test (chat + completion, 7 iterations)
# By default we only test completion curls unless specifed to run chat.
# -----------------------------------------------------------------------------

show_help() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS]

Options:
-n, --namespace NAMESPACE Kubernetes namespace (default: llm-d)
-m, --model MODEL_ID Model to query.
-c, --chatValidation Enable chat validation testing.
-v, --verbose Echo kubectl/curl commands before running
-h, --help Show this help and exit
EOF
exit 0
}

# ── Defaults ────────────────────────────────────────────────────────────────
NAMESPACE="igw-e2e"
CLI_MODEL_ID=""
VERBOSE=false
TEST_CHAT=false

# ── Flag parsing ────────────────────────────────────────────────────────────
while [[ $# -gt 0 ]]; do
case $1 in
-n|--namespace)
if [[ -z "$2" ]]; then echo "Error: $1 requires a value." >&2; exit 1; fi
NAMESPACE="$2"; shift 2 ;;
-m|--model)
if [[ -z "$2" ]]; then echo "Error: $1 requires a value." >&2; exit 1; fi
CLI_MODEL_ID="$2"; shift 2 ;;
-c|--chatValidation) TEST_CHAT=true; shift ;;
-v|--verbose) VERBOSE=true; shift ;;
-h|--help) show_help ;;
*) echo "Unknown option: $1"; show_help ;;
esac
done

if [[ "${VERBOSE}" == "true" ]]; then
set -x
fi

# ── Create a unique pod suffix ────────────────────────────────────────────
gen_id() { echo $(( RANDOM % 10000 + 1 )); }

# ── Discover Gateway address ────────────────────────────────────────────────
HOST="${GATEWAY_HOST:-$(kubectl get gateway -n "$NAMESPACE" \
-o jsonpath='{.items[0].status.addresses[0].value}' 2>/dev/null || true)}"
if [[ -z "$HOST" ]]; then
echo "Error: could not discover a Gateway address in namespace '$NAMESPACE'." >&2
exit 1
fi
PORT=80
SVC_HOST="${HOST}:${PORT}"

# ── Determine MODEL_ID ──────────────────────────────────────────────────────
if [[ -n "$CLI_MODEL_ID" ]]; then
MODEL_ID="$CLI_MODEL_ID"
elif [[ -n "${MODEL_ID-}" ]]; then
MODEL_ID="$MODEL_ID"
else
echo "Error: Failed to find model id. Please specify one using the -m flag or the MODEL_ID environment variable." >&2
exit 1
fi

echo "Namespace: $NAMESPACE"
echo "Inference Gateway: ${SVC_HOST}"
echo "Model ID: $MODEL_ID"
echo

# ── Main test loop (10 iterations) ──────────────────────────────────────────
for i in {1..7}; do
echo "=== Iteration $i of 10 ==="
failed=false

if [[ -n "$TEST_CHAT" ]]; then

# POST /v1/chat/completions
echo "1) POST /v1/chat/completions at ${SVC_HOST}"
chat_payload='{
"model":"'"$MODEL_ID"'",
"messages":[{"role":"user","content":"Hello! Who are you?"}]
}'
ID=$(gen_id)

ret=0
output=$(kubectl run --rm -i curl-"$ID" \
--namespace "$NAMESPACE" \
--image=curlimages/curl --restart=Never \
--env "PAYLOAD=$chat_payload" -- \
sh -c 'sleep 1; curl -sS -X POST "http://'${SVC_HOST}'/v1/chat/completions" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"') || ret=$?
echo "$output"
[[ $ret -ne 0 || "$output" != *'{'* ]] && {
echo "Error: POST /v1/chat/completions failed (exit $ret or no JSON)" >&2; failed=true; }
echo
fi

# POST /v1/completions
echo "2) POST /v1/completions at ${SVC_HOST}"
payload='{"model":"'"$MODEL_ID"'","prompt":"You are a helpful AI assistant."}'
ID=$(gen_id)

ret=0
output=$(kubectl run --rm -i curl-"$ID" \
--namespace "$NAMESPACE" \
--image=curlimages/curl --restart=Never \
--env "PAYLOAD=$payload" -- \
sh -c 'sleep 1; curl -sS -X POST "http://'${SVC_HOST}'/v1/completions" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"') || ret=$?
echo "$output"
[[ $ret -ne 0 || "$output" != *'{'* ]] && {
echo "Error: POST /v1/completions failed (exit $ret or no JSON)" >&2; failed=true; }
echo

if $failed; then
echo "Iteration $i encountered errors; exiting." >&2
exit 1
fi
done

echo "✅ All 10 iterations succeeded."
Loading