feat(e2e): add distributed E2E test framework with parametric traffic generation
Add run-e2e-test.sh with CLI parameters (--hits, --http-ratio, --dns, --tls, --src-ips, --keep-analysis, --up) for configurable traffic generation. Traffic runs from VM endpoints with multiple source IPs (alias IPs on eth0) to produce distinct sessions for the ML pipeline. Fix curl TLS flags (--tlsv1.2 instead of --tls-v1-2), skip redundant local verification in distributed mode, and fix dashboard is_available() cache that never retried after ClickHouse recovery. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -68,6 +68,17 @@ get_eth0_ip() {
|
||||
|
||||
# ── ClickHouse ────────────────────────────────────────────────────────────────
|
||||
start_clickhouse() {
|
||||
# Si un ClickHouse externe est configuré, ne pas démarrer le conteneur local
|
||||
if [ -n "${CH_HOST:-}" ] && [ "$CH_HOST" != "127.0.0.1" ] && [ "$CH_HOST" != "localhost" ]; then
|
||||
log "ClickHouse externe ($CH_HOST) — démarrage local ignoré"
|
||||
# Vérifier que le ClickHouse distant est accessible
|
||||
for i in $(seq 1 30); do
|
||||
curl -sf "http://${CH_HOST}:8123/ping" >/dev/null 2>&1 && { pass "ClickHouse distant prêt"; return 0; }
|
||||
sleep 2
|
||||
done
|
||||
fail "ClickHouse distant ($CH_HOST) inaccessible"; return 1
|
||||
fi
|
||||
|
||||
log "Démarrage ClickHouse..."
|
||||
docker rm -f ja4-clickhouse 2>/dev/null || true
|
||||
|
||||
@ -104,11 +115,12 @@ start_ja4ebpf() {
|
||||
done
|
||||
[ -z "$ssl_lib" ] && ssl_lib="/usr/lib64/libssl.so.3"
|
||||
|
||||
local ch_addr="${CH_HOST:-127.0.0.1}"
|
||||
cat > /tmp/ja4ebpf.yml << EOF
|
||||
interface: eth0
|
||||
ssl_lib_path: "${ssl_lib}"
|
||||
clickhouse:
|
||||
dsn: "clickhouse://default:@127.0.0.1:9000/ja4_logs"
|
||||
dsn: "clickhouse://default:@${ch_addr}:9000/ja4_logs"
|
||||
batch_size: 100
|
||||
flush_secs: 1
|
||||
correlation:
|
||||
@ -287,21 +299,47 @@ verify_db() {
|
||||
log "Vérification des données dans ClickHouse..."
|
||||
|
||||
ch_val() {
|
||||
curl -sf "http://localhost:8123/?database=ja4_logs" \
|
||||
local ch_http_host="${CH_HOST:-localhost}"
|
||||
curl -sf "http://${ch_http_host}:8123/?database=ja4_logs" \
|
||||
--data-urlencode "query=$1" 2>/dev/null | tr -d ' \n' || echo "0"
|
||||
}
|
||||
|
||||
# http_logs_raw (données brutes avant MV)
|
||||
local raw_count
|
||||
raw_count=$(ch_val "SELECT count() FROM http_logs_raw")
|
||||
if [ "${raw_count:-0}" -gt 0 ] 2>/dev/null; then
|
||||
pass "http_logs_raw : $raw_count lignes"
|
||||
else
|
||||
# Attendre que http_logs_raw contienne des données (max 30s)
|
||||
local raw_ok=false
|
||||
log " Attente données brutes dans ClickHouse..."
|
||||
for i in $(seq 1 15); do
|
||||
local raw_count
|
||||
raw_count=$(ch_val "SELECT count() FROM http_logs_raw")
|
||||
if [ "${raw_count:-0}" -gt 0 ] 2>/dev/null; then
|
||||
pass "http_logs_raw : $raw_count lignes (${i}*2s)"
|
||||
raw_ok=true
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
if [ "$raw_ok" = "false" ]; then
|
||||
fail "http_logs_raw vide — ja4ebpf n'a rien capturé"
|
||||
log " Logs ja4ebpf :"
|
||||
tail -10 /tmp/ja4ebpf.log 2>/dev/null | sed 's/^/ /'
|
||||
fi
|
||||
|
||||
# Attendre que la MV http_logs se remplisse (max 30s)
|
||||
local logs_ok=false
|
||||
log " Attente MV http_logs..."
|
||||
for i in $(seq 1 15); do
|
||||
local logs_count
|
||||
logs_count=$(ch_val "SELECT count() FROM http_logs")
|
||||
if [ "${logs_count:-0}" -gt 0 ] 2>/dev/null; then
|
||||
logs_ok=true
|
||||
break
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ "$logs_ok" = "false" ]; then
|
||||
warn "MV http_logs vide après 30s — vérification partielle uniquement"
|
||||
fi
|
||||
|
||||
# L3/L4
|
||||
ttl=$(ch_val "SELECT count() FROM http_logs WHERE ip_meta_ttl > 0")
|
||||
[ "${ttl:-0}" -gt 0 ] 2>/dev/null && pass "L3/L4 TTL ($ttl)" || fail "L3/L4 TTL absent"
|
||||
@ -343,7 +381,10 @@ stop_stack() {
|
||||
apache) stop_apache ;;
|
||||
hitch-varnish) stop_hitch_varnish ;;
|
||||
esac
|
||||
docker rm -f ja4-clickhouse 2>/dev/null || true
|
||||
# Ne pas supprimer le ClickHouse s'il est externe (VM analysis)
|
||||
if [ -z "${CH_HOST:-}" ] || [ "$CH_HOST" = "127.0.0.1" ] || [ "$CH_HOST" = "localhost" ]; then
|
||||
docker rm -f ja4-clickhouse 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
@ -371,7 +412,10 @@ do_start() {
|
||||
GOWORK=off go generate ./internal/loader/ 2>&1 | tail -3
|
||||
GOWORK=off CGO_ENABLED=0 go build -o /tmp/ja4ebpf_new ./cmd/ja4ebpf/ && mv /tmp/ja4ebpf_new /usr/local/bin/ja4ebpf
|
||||
}
|
||||
command -v docker >/dev/null 2>&1 || { fail "Docker non installé"; exit 1; }
|
||||
# Docker n'est nécessaire que pour un ClickHouse local
|
||||
if [ -z "${CH_HOST:-}" ] || [ "$CH_HOST" = "127.0.0.1" ] || [ "$CH_HOST" = "localhost" ]; then
|
||||
command -v docker >/dev/null 2>&1 || { fail "Docker non installé"; exit 1; }
|
||||
fi
|
||||
|
||||
start_clickhouse
|
||||
|
||||
@ -434,7 +478,21 @@ case "$MODE" in
|
||||
[ -f /tmp/ja4ebpf-traffic-done ] && break
|
||||
sleep 1
|
||||
done
|
||||
do_verify
|
||||
# En mode ClickHouse externe (E2E distribué), la vérification est faite
|
||||
# par le script orchestrateur (run-e2e-test.sh Phase 5). On saute la
|
||||
# vérification locale car les MV peuvent ne pas encore être peuplées.
|
||||
if [ -n "${CH_HOST:-}" ] && [ "$CH_HOST" != "127.0.0.1" ] && [ "$CH_HOST" != "localhost" ]; then
|
||||
log "ClickHouse externe — vérification locale ignorée (gérée par l'orchestrateur)"
|
||||
log "Logs ja4ebpf :"
|
||||
tail -5 /tmp/ja4ebpf.log 2>/dev/null | sed 's/^/ /'
|
||||
pass "ja4ebpf actif (ClickHouse externe)"
|
||||
else
|
||||
# Laisser le temps au pipeline ClickHouse de traiter les données brutes
|
||||
# (http_logs_raw → MV http_logs) avant de vérifier
|
||||
log "Attente pipeline ClickHouse (20s)..."
|
||||
sleep 20
|
||||
do_verify
|
||||
fi
|
||||
;;
|
||||
verify)
|
||||
do_verify
|
||||
|
||||
Reference in New Issue
Block a user