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
29 changes: 28 additions & 1 deletion proxy-stress-test/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ services:
echo 'ConnectPort 443' >> /tmp/tp.conf &&
tinyproxy -d -c /tmp/tp.conf"

# Local stand-in for httpbin.org. This lane used to drive 20 concurrent HTTPS
# calls at the public internet during RECORD, so the recorded response
# depended on whether httpbin was healthy: a slow or 5xx httpbin got baked
# into the expected body ("succeeded": 6, "failed": 14, "status": 503) and
# never reproduced on replay, failing the test set for reasons unrelated to
# keploy. It also burned minutes per run in 30s timeouts, and truncated one
# record window enough that only 3 of 5 test cases were captured.
#
# Still real HTTPS on 443, so the CONNECT-tunnel and TLS-cert-caching paths
# this sample exists to stress are untouched — only the far end moves
# in-cluster, where it is deterministic.
httpstub:
image: caddy:2-alpine
volumes:
- ./httpstub.Caddyfile:/etc/caddy/Caddyfile:ro
healthcheck:
test: ["CMD-SHELL", "wget -q --no-check-certificate -O /dev/null https://127.0.0.1/get || exit 1"]
interval: 2s
timeout: 5s
retries: 15
# Caddy mints its internal CA on first boot; give it room before the
# first probe counts against the retry budget.
start_period: 5s

app:
build: .
container_name: proxyStressApp
Expand All @@ -36,7 +60,8 @@ services:
environment:
LISTEN_ADDR: ":8080"
DATABASE_URL: "postgres://repro:repro@db:5432/reprodb?sslmode=disable"
HTTPS_TARGET: "https://httpbin.org/get"
HTTPS_TARGET: "https://httpstub/get"
HTTPS_POST_TARGET: "https://httpstub/post"
HTTP_PROXY_URL: "http://proxy:3128"
# 20 concurrent HTTPS connections through CONNECT tunnel.
# Exercises TLS cert caching (same code path as production 42).
Expand All @@ -55,6 +80,8 @@ services:
depends_on:
db:
condition: service_healthy
httpstub:
condition: service_healthy
# Resource limits for GitHub Actions ubuntu-latest (4 vCPU / 16GB).
deploy:
resources:
Expand Down
33 changes: 33 additions & 0 deletions proxy-stress-test/httpstub.Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Local stand-in for httpbin.org, served over real HTTPS on 443 so the
# CONNECT-tunnel + TLS-cert-caching path this sample stresses is unchanged.
#
# `tls internal` mints a self-signed cert from Caddy's local CA. Nothing
# validates it and nothing needs to: the app sets InsecureSkipVerify to accept
# keploy's MITM cert (main.go), and keploy never validates upstream certs
# either (proxy_v2.go, locked in by TestNewProxyTLSUpgradeFn_DestSide_
# AlwaysInsecureSkipVerify). So no CA has to be distributed to any container.
{
auto_https disable_redirects
admin off
}

https://httpstub:443, https://127.0.0.1:443 {
tls internal

handle /get {
header Content-Type application/json
# Padded to roughly httpbin /get's response size so the volume of data
# crossing the CONNECT tunnel stays comparable to what this lane used to
# exercise; the tunnel and the TLS handshake are the point, not the body.
respond `{"url":"https://httpstub/get","ok":true,"headers":{"Accept-Encoding":"gzip","Host":"httpstub","User-Agent":"Go-http-client/1.1"},"origin":"127.0.0.1","args":{},"padding":"0123456789012345678901234567890123456789012345678901234567890123456789"}` 200
}

handle /post {
header Content-Type application/json
respond `{"url":"https://httpstub/post","ok":true}` 200
}

handle {
respond 404
}
}
11 changes: 11 additions & 0 deletions proxy-stress-test/keploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Checked in so `keploy test` ignores the one field in these responses that
# cannot be reproduced: each stress endpoint reports its own wall-clock
# elapsed time (main.go's `time.Since(start).String()` on /api/transfer,
# /api/batch-transfer and /api/post-transfer). Without this, those three test
# cases mismatch on every replay, forever.
#
# `keploy config --generate` is a no-op when this file exists, so CI keeps
# working unchanged and `./test.sh` gets the same behaviour as CI.
test:
globalNoise:
global: {"body": {"duration": []}}
Loading