test(docker): add observability smoke

Add Docker aggregate observability coverage for QA-lab OTEL and Prometheus diagnostics.
This commit is contained in:
Vincent Koc
2026-04-26 16:43:56 -07:00
committed by GitHub
parent 560ddd2f9b
commit 5d7c6e6bda
7 changed files with 281 additions and 1 deletions

View File

@@ -0,0 +1,55 @@
# syntax=docker/dockerfile:1.7
FROM node:24-bookworm-slim@sha256:e8e2e91b1378f83c5b2dd15f0247f34110e2fe895f6ca7719dbb780f929368eb AS observability-runner
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates git \
&& rm -rf /var/lib/apt/lists/*
RUN corepack enable
RUN useradd --create-home --shell /bin/bash appuser \
&& mkdir -p /app \
&& chown appuser:appuser /app
ENV HOME="/home/appuser"
ENV NODE_OPTIONS="--disable-warning=ExperimentalWarning"
ENV OPENCLAW_DISABLE_BONJOUR="1"
USER appuser
WORKDIR /app
COPY --chown=appuser:appuser package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
COPY --chown=appuser:appuser ui/package.json ./ui/package.json
COPY --chown=appuser:appuser patches ./patches
COPY --chown=appuser:appuser scripts/postinstall-bundled-plugins.mjs scripts/preinstall-package-manager-warning.mjs scripts/npm-runner.mjs scripts/windows-cmd-helpers.mjs ./scripts/
RUN --mount=type=bind,source=extensions,target=/tmp/extensions,readonly \
find /tmp/extensions -mindepth 2 -maxdepth 2 -name package.json -print | \
while IFS= read -r manifest; do \
dest="${manifest#/tmp/}"; \
mkdir -p "$(dirname "$dest")"; \
cp "$manifest" "$dest"; \
done
RUN --mount=type=cache,id=openclaw-pnpm-store,target=/home/appuser/.local/share/pnpm/store,sharing=locked \
pnpm install --frozen-lockfile
COPY --chown=appuser:appuser .oxlintrc.json tsconfig.json tsconfig.plugin-sdk.dts.json tsconfig.oxlint*.json tsdown.config.ts vitest.config.ts openclaw.mjs ./
COPY --chown=appuser:appuser src ./src
COPY --chown=appuser:appuser test ./test
COPY --chown=appuser:appuser scripts ./scripts
COPY --chown=appuser:appuser docs ./docs
COPY --chown=appuser:appuser packages ./packages
COPY --chown=appuser:appuser qa ./qa
COPY --chown=appuser:appuser skills ./skills
COPY --chown=appuser:appuser ui ./ui
COPY --chown=appuser:appuser extensions ./extensions
COPY --chown=appuser:appuser vendor/a2ui/renderers/lit ./vendor/a2ui/renderers/lit
COPY --chown=appuser:appuser apps/shared/OpenClawKit/Sources/OpenClawKit/Resources ./apps/shared/OpenClawKit/Sources/OpenClawKit/Resources
COPY --chown=appuser:appuser apps/shared/OpenClawKit/Tools/CanvasA2UI ./apps/shared/OpenClawKit/Tools/CanvasA2UI
RUN pnpm build
RUN mkdir -p dist/control-ui \
&& printf '%s\n' '<!doctype html><title>OpenClaw Control UI</title>' > dist/control-ui/index.html
CMD ["bash"]

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
source "$ROOT_DIR/scripts/lib/docker-e2e-image.sh"
IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-docker-observability-e2e:local" OPENCLAW_DOCKER_OBSERVABILITY_E2E_IMAGE)"
SKIP_BUILD="${OPENCLAW_DOCKER_OBSERVABILITY_E2E_SKIP_BUILD:-0}"
LOOPS="${OPENCLAW_DOCKER_OBSERVABILITY_LOOPS:-1}"
OUTPUT_DIR="${OPENCLAW_DOCKER_OBSERVABILITY_OUTPUT_DIR:-$ROOT_DIR/.artifacts/docker-observability/$(date +%Y%m%d-%H%M%S)}"
if ! [[ "$LOOPS" =~ ^[1-9][0-9]*$ ]]; then
echo "OPENCLAW_DOCKER_OBSERVABILITY_LOOPS must be a positive integer, got: $LOOPS" >&2
exit 1
fi
mkdir -p "$OUTPUT_DIR"
docker_e2e_build_or_reuse "$IMAGE_NAME" docker-observability "$ROOT_DIR/scripts/e2e/Dockerfile.observability" "$ROOT_DIR" "" "$SKIP_BUILD"
echo "Running Docker observability smoke with $LOOPS loop(s)..."
run_logged docker-observability docker run --rm \
-e "OPENCLAW_DOCKER_OBSERVABILITY_LOOPS=$LOOPS" \
-v "$OUTPUT_DIR:/app/.artifacts/docker-observability-current" \
"$IMAGE_NAME" \
bash -lc '
set -euo pipefail
loops="${OPENCLAW_DOCKER_OBSERVABILITY_LOOPS:-1}"
artifact_root=".artifacts/docker-observability-current"
mkdir -p "$artifact_root"
for i in $(seq 1 "$loops"); do
iteration_dir="$artifact_root/loop-$i"
mkdir -p "$iteration_dir"
echo "== docker observability loop $i/$loops: otel =="
pnpm qa:otel:smoke \
--provider-mode mock-openai \
--output-dir "$iteration_dir/otel"
echo "== docker observability loop $i/$loops: prometheus =="
pnpm openclaw qa suite \
--provider-mode mock-openai \
--scenario docker-prometheus-smoke \
--concurrency 1 \
--fast \
--output-dir "$iteration_dir/prometheus"
done
'
echo "Docker observability smoke passed. Artifacts: $OUTPUT_DIR"

View File

@@ -25,7 +25,10 @@ function lane(name, command, options = {}) {
return {
cacheKey: options.cacheKey,
command,
e2eImageKind: options.e2eImageKind ?? (options.live ? undefined : "functional"),
e2eImageKind:
options.e2eImageKind === false
? undefined
: (options.e2eImageKind ?? (options.live ? undefined : "functional")),
estimateSeconds: options.estimateSeconds,
live: options.live === true,
name,
@@ -181,6 +184,10 @@ export const mainLanes = [
{ resources: ["service"], weight: 3 },
),
serviceLane("gateway-network", "OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:gateway-network"),
serviceLane("observability", "bash scripts/e2e/docker-observability-smoke.sh", {
e2eImageKind: false,
weight: 3,
}),
serviceLane(
"agents-delete-shared-workspace",
"OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:agents-delete-shared-workspace",