Skip to main content
Version: dev

llm-d Deployment Smoke Test

A lightweight smoke-test script that verifies an llm-d cluster is healthy after deployment.

Location:

  • docs/operations/validation/smoke-test/healthcheck.sh

What It Checks​

CheckEndpointPurpose
(Optional) LivenessGET /healthIf exposed by your gateway; can be required via --require-health
ReadinessGET /v1/modelsConfirms OpenAI-compatible API is reachable; can auto-discover model when jq is available
InferencePOST /v1/completions and/or POST /v1/chat/completionsEnd-to-end inference works; measures latency (auto-fallback supported)

jq dependency​

  • curl is required.
  • jq is optional:
    • With jq: enables model auto-discovery, response structure validation, and -o json output.
    • Without jq: still performs HTTP-level smoke tests, but you must provide --model (or MODEL_ID=...).

Usage​

# Basic — port-forwarded gateway on localhost:8000
./healthcheck.sh

# Explicit endpoint and model
./healthcheck.sh -e http://inference.example.com -m meta-llama/Llama-3-8B

# Force chat-completions
./healthcheck.sh -e http://gateway:80 --api chat -m meta-llama/Llama-3-8B

# Fail if inference latency exceeds 5 seconds
./healthcheck.sh -l 5000

# JSON output for CI pipelines (requires jq)
./healthcheck.sh -o json

Options​

FlagEnv VarDefaultDescription
-e, --endpointENDPOINThttp://localhost:8000Base URL of the inference endpoint
-m, --modelMODEL_ID(auto-discovered with jq)Model ID to query
-t, --timeoutTIMEOUT30HTTP request timeout in seconds
-l, --max-latencyMAX_LATENCY0 (disabled)Fail if inference latency exceeds this (ms)
-o, --output—textOutput format: text or json (json requires jq)
--api—autoauto, completions, or chat
--require-health—disabledTreat /health non-200 as a failure (default: warn)

Kubernetes Usage​

One-off (ephemeral) pod​

This uses alpine and installs dependencies at runtime (simple and reproducible):

kubectl run llm-d-healthcheck --rm -i --restart=Never \
--namespace llm-d \
--image=alpine:3.20 \
-- sh -lc '
apk add --no-cache bash curl jq >/dev/null &&
bash -lc "$(cat docs/operations/validation/smoke-test/healthcheck.sh)" -- -e http://llm-d-gateway:80 -o json
'

If you prefer no jq, drop it and provide -m explicitly:

kubectl run llm-d-healthcheck --rm -i --restart=Never \
--namespace llm-d \
--image=alpine:3.20 \
-- sh -lc '
apk add --no-cache bash curl >/dev/null &&
bash -lc "$(cat docs/operations/validation/smoke-test/healthcheck.sh)" -- -e http://llm-d-gateway:80 -m meta-llama/Llama-3-8B
'
kubectl create configmap llm-d-healthcheck-script \
--from-file=healthcheck.sh=docs/operations/validation/smoke-test/healthcheck.sh \
--namespace llm-d
apiVersion: batch/v1
kind: Job
metadata:
name: llm-d-healthcheck
namespace: llm-d
spec:
backoffLimit: 3
template:
spec:
restartPolicy: Never
containers:
- name: healthcheck
image: alpine:3.20
command: ["sh", "-lc"]
args:
- |
apk add --no-cache bash curl jq >/dev/null &&
/scripts/healthcheck.sh -e http://llm-d-gateway:80 -o json
volumeMounts:
- name: script
mountPath: /scripts
volumes:
- name: script
configMap:
name: llm-d-healthcheck-script
defaultMode: 0755

Example Output​

Text (default)​

╔══════════════════════════════════════════╗
║ llm-d Health Check Report ║
╠══════════════════════════════════════════╣
║ Status: HEALTHY ║
║ Endpoint: http://localhost:8000 ║
║ Model: meta-llama/Llama-3-8B ║
║ API: auto ║
║ jq: true ║
╠══════════════════════════════════════════╣
║ /health HTTP 404 ║
║ /v1/models HTTP 200 count=1 ║
║ /v1/completions HTTP 200 1842 ms ║
╠══════════════════════════════════════════╣
║ Checks: 2 passed, 0 failed, 1 warned ║
╚══════════════════════════════════════════╝

JSON (-o json, requires jq)​

{
"status": "healthy",
"timestamp": "2026-02-13T00:00:00Z",
"endpoint": "http://localhost:8000",
"model": "meta-llama/Llama-3-8B",
"api_mode": "auto",
"jq_present": true,
"checks": { "passed": 3, "failed": 0, "warned": 0 },
"results": {
"health": { "http_status": "200" },
"models": { "http_status": "200", "model_count": "1" },
"inference": { "path": "/v1/completions", "http_status": "200", "latency_ms": "1842" }
}
}