litellm/tests/e2e/docker-compose.yml
yucheng-berri d6f498ff5c
test(e2e): failed request error span carries the full untruncated message and status (LIT-4179) (#33304)
* test(e2e): failed request error span carries the full untruncated message and status

Covers logging.otel.failure.exports_metric on chat_completions: a request that
fails at the provider (invalid upstream key deployment) must export one
complete trace whose gen-AI span carries the LIT-4179 error contract, declared
as one reviewable payload (EXPECTED_ERROR_SPAN_ATTRIBUTES) plus an untruncated
error.message proven by parsing the embedded provider error JSON back out of
the attribute. The root SERVER span must record the 401 the client received.
Adds STORE_MODEL_IN_DB to the compose stack so /model/new works locally, which
the suite's model-registering tests already assume

* test(e2e): clean failure diagnostics on the error-span contract per review

A truncated error.message with missing braces now fails with a readable
assertion instead of an unhandled ValueError, an unparseable embedded JSON
fails via pytest.fail with the truncation context, and the retry loop now
asserts the upstream provider failure was actually observed so a fresh-key
propagation deadline cannot masquerade as a trace-export failure

* test(e2e): pin the full error attribute set including the litellm.provider.error keys

The LIT-4179 fix restored error.message/code/stack_trace/llm_provider; a later
refactor (#32591) moved the litellm-specific keys under litellm.provider.error.*,
which the initial contract missed. The payload now pins error, error.type,
otel.status_code, litellm.provider.error.code=401, and
litellm.provider.error.llm_provider=anthropic exactly, plus non-empty
litellm.provider.error.stack_trace and the untruncated error.message

* test(e2e): author the error-span test docstring
2026-07-14 22:13:13 -07:00

140 lines
4.4 KiB
YAML

# local setup to run e2e tests
configs:
litellm_config:
content: |
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
database_url: os.environ/DATABASE_URL
store_prompts_in_spend_logs: true
proxy_budget_rescheduler_min_time: 5
proxy_budget_rescheduler_max_time: 10
litellm_settings:
drop_params: true
num_retries: 3
request_timeout: 600
cache: true
cache_params:
type: redis
host: redis
port: 6379
# OTEL v2 trace destination for the logging suite's trace-completeness
# tests: the arize_phoenix preset is OTLP with a configurable endpoint
# (PHOENIX_COLLECTOR_HTTP_ENDPOINT below points it at the jaeger service),
# so gen-AI spans export through a preset-owned provider - the code path
# where trace splits actually happen - with no cloud credentials needed.
callbacks: ["arize_phoenix"]
router_settings:
routing_strategy: simple-shuffle
num_retries: 3
allowed_fails: 5
cooldown_time: 30
fallbacks:
- gemini-2.5-flash: ["gpt-5.5", "claude-haiku-4-5"]
finetune_settings:
- custom_llm_provider: openai
api_key: os.environ/OPENAI_API_KEY
files_settings:
- custom_llm_provider: openai
api_key: os.environ/OPENAI_API_KEY
- custom_llm_provider: azure
api_base: os.environ/AZURE_API_BASE
api_key: os.environ/AZURE_API_KEY
api_version: "2024-05-01-preview"
model_list:
- model_name: gpt-5.5
litellm_params:
model: openai/gpt-5.5
api_key: os.environ/OPENAI_API_KEY
- model_name: claude-haiku-4-5
litellm_params:
model: anthropic/claude-haiku-4-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: gemini-2.5-flash
litellm_params:
model: gemini/gemini-2.5-flash
api_key: os.environ/GEMINI_API_KEY
- model_name: openai-text-embedding-3-small
litellm_params:
model: openai/text-embedding-3-small
api_key: os.environ/OPENAI_API_KEY
services:
litellm:
image: ghcr.io/berriai/litellm:main-latest
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
jaeger:
condition: service_healthy
env_file: .env
environment:
LITELLM_MASTER_KEY: sk-1234
STORE_MODEL_IN_DB: "True"
LITELLM_OTEL_V2: "true"
PHOENIX_COLLECTOR_HTTP_ENDPOINT: http://jaeger:4318/v1/traces
PHOENIX_API_KEY: local-jaeger-noauth
DATABASE_URL: postgresql://litellm:litellm@db:5432/litellm
UI_USERNAME: admin
UI_PASSWORD: sk-1234
AWS_S3_BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-${AWS_BATCH_S3_BUCKET:-}}
AWS_BATCH_S3_BUCKET: ${AWS_BATCH_S3_BUCKET:-${AWS_S3_BUCKET_NAME:-}}
AWS_BATCH_ROLE_ARN: ${AWS_BATCH_ROLE_ARN:-}
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-}
AWS_REGION: ${AWS_REGION:-us-east-1}
GCS_BUCKET_NAME: ${GCS_BUCKET_NAME:-}
VERTEXAI_PROJECT: ${VERTEXAI_PROJECT:-}
VERTEXAI_CREDENTIALS: ${VERTEXAI_CREDENTIALS:-}
GOOGLE_APPLICATION_CREDENTIALS: ${GOOGLE_APPLICATION_CREDENTIALS:-}
MISTRAL_API_KEY: ${MISTRAL_API_KEY:-}
AZURE_API_BASE: ${AZURE_API_BASE:-}
AZURE_API_KEY: ${AZURE_API_KEY:-}
ports:
- "4000:4000"
configs:
- source: litellm_config
target: /app/config.yaml
command: ["--config", "/app/config.yaml", "--port", "4000"]
# throwaway db
db:
image: postgres:16
environment:
POSTGRES_USER: litellm
POSTGRES_PASSWORD: litellm
POSTGRES_DB: litellm
healthcheck:
test: ["CMD-SHELL", "pg_isready -U litellm"]
interval: 3s
timeout: 3s
retries: 20
redis:
image: redis:7
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 3s
timeout: 3s
retries: 20
# throwaway OTEL trace destination (OTLP ingest on 4318 inside the network,
# query API on host 16686 for test read-back; see E2E_OTEL_QUERY_URL)
jaeger:
image: jaegertracing/all-in-one:1.62.0
ports:
- "16686:16686"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:14269/"]
interval: 3s
timeout: 3s
retries: 20