From f3ad53833753a8d02e19da75b91e0030a4a2fba6 Mon Sep 17 00:00:00 2001 From: Tess Neau Date: Mon, 5 Oct 2026 17:47:29 +0200 Subject: [PATCH 01/10] Add manual OTel Demo trace E2E validation Reuse the existing vdev Compose harness and PR review trigger. Compare captured span semantics and multiplicities, require realistic trace coverage, and retain evidence for migration PRs. Generated with GPT-6 (Codex). --- .config/nextest.toml | 6 + .github/workflows/ci-integration-review.yml | 65 ++ Cargo.toml | 3 +- tests/e2e/opentelemetry-demo/README.md | 91 ++ .../opentelemetry-demo/config/compose.yaml | 808 ++++++++++++++++++ tests/e2e/opentelemetry-demo/config/test.yaml | 17 + .../data/collector-sink.yaml | 21 + .../data/collector-source.yaml | 47 + .../opentelemetry-demo/data/demo.flagd.json | 201 +++++ tests/e2e/opentelemetry-demo/data/init.sql | 94 ++ .../opentelemetry-demo/data/otel-config.yml | 37 + tests/e2e/opentelemetry-demo/data/scenario.py | 38 + tests/e2e/opentelemetry-demo/data/vector.yaml | 20 + tests/e2e/opentelemetry/demo/mod.rs | 447 ++++++++++ tests/e2e/opentelemetry/mod.rs | 155 +++- tests/e2e/opentelemetry/traces/mod.rs | 81 +- 16 files changed, 2048 insertions(+), 83 deletions(-) create mode 100644 tests/e2e/opentelemetry-demo/README.md create mode 100644 tests/e2e/opentelemetry-demo/config/compose.yaml create mode 100644 tests/e2e/opentelemetry-demo/config/test.yaml create mode 100644 tests/e2e/opentelemetry-demo/data/collector-sink.yaml create mode 100644 tests/e2e/opentelemetry-demo/data/collector-source.yaml create mode 100644 tests/e2e/opentelemetry-demo/data/demo.flagd.json create mode 100644 tests/e2e/opentelemetry-demo/data/init.sql create mode 100644 tests/e2e/opentelemetry-demo/data/otel-config.yml create mode 100644 tests/e2e/opentelemetry-demo/data/scenario.py create mode 100644 tests/e2e/opentelemetry-demo/data/vector.yaml create mode 100644 tests/e2e/opentelemetry/demo/mod.rs diff --git a/.config/nextest.toml b/.config/nextest.toml index b21c53f67f28d..70d7f40da6705 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -20,3 +20,9 @@ slow-timeout = { period = "30s", terminate-after = 4 } # output test results at target/nextest/default/junit.xml path = "junit.xml" store-failure-output = true + +[[profile.default.overrides]] +filter = 'test(opentelemetry::demo::demo_trace_round_trip)' +# This test stops its producers and collectors, so a retry needs a fresh Compose run. +retries = 0 +slow-timeout = { period = "30s", terminate-after = 10 } diff --git a/.github/workflows/ci-integration-review.yml b/.github/workflows/ci-integration-review.yml index ae4e960e1162f..eae4ff7088e63 100644 --- a/.github/workflows/ci-integration-review.yml +++ b/.github/workflows/ci-integration-review.yml @@ -251,6 +251,70 @@ jobs: max_attempts: 3 command: vdev e2e run ${{ matrix.service }} ${{ runner.debug == '1' && '--always-show-logs' || '' }} + otel-demo: + name: OTel Demo trace validation + if: startsWith(github.event.review.body, '/ci-run-e2e-opentelemetry-demo') + needs: + - prep-pr + - build-test-runner + runs-on: ubuntu-24.04-8core + timeout-minutes: 60 + permissions: + contents: read + packages: read # Required to pull test runner image from GHCR + id-token: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + submodules: "recursive" + ref: ${{ github.event.review.commit_id }} + + - uses: ./.github/actions/dd-token + + - uses: ./.github/actions/setup + with: + vdev: true + datadog-ci: true + + - name: Pull test runner image + uses: ./.github/actions/pull-test-runner + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + commit_sha: ${{ github.event.review.commit_id }} + + - name: OTel Demo trace validation + run: | + mkdir -p target/otel-demo-evidence + set -o pipefail + vdev e2e run opentelemetry-demo --retries 0 --always-show-logs 2>&1 | tee target/otel-demo-evidence/runner.log + + - name: Collect OTel Demo evidence + if: always() + run: | + mkdir -p target/otel-demo-evidence + git rev-parse HEAD > target/otel-demo-evidence/revision.txt + cp -R tests/e2e/opentelemetry-demo/config tests/e2e/opentelemetry-demo/data target/otel-demo-evidence/ + if docker volume inspect opentelemetry_demo_evidence >/dev/null 2>&1; then + docker run --rm \ + -v opentelemetry_demo_evidence:/output/opentelemetry-demo:ro \ + -v "$PWD/target/otel-demo-evidence:/evidence" \ + alpine:3.20 sh -c 'if [ -d /output/opentelemetry-demo ]; then cp -R /output/opentelemetry-demo/. /evidence/; fi' + fi + summaries=(target/otel-demo-evidence/*/summary.md) + if [ -f "${summaries[0]}" ]; then + cat "${summaries[@]}" >> "$GITHUB_STEP_SUMMARY" + else + echo 'OTel Demo did not produce a validation summary. See runner.log and the failed job steps.' >> "$GITHUB_STEP_SUMMARY" + fi + + - name: Upload OTel Demo evidence + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: otel-demo-${{ github.event.review.commit_id }} + path: target/otel-demo-evidence/ + retention-days: 14 + update-pr-status: name: Signal result to PR runs-on: ubuntu-24.04 @@ -258,6 +322,7 @@ jobs: needs: - integration-tests - e2e-tests + - otel-demo if: always() && (startsWith(github.event.review.body, '/ci-run-integration') || contains(github.event.review.body, '/ci-run-all') || contains(github.event.review.body, '/ci-run-e2e')) permissions: statuses: write # Required to set final commit status diff --git a/Cargo.toml b/Cargo.toml index c27081250a296..5b81842ed9052 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1156,7 +1156,8 @@ e2e-tests-opentelemetry = [ "sinks-console", "sinks-file", "codecs-opentelemetry", - "dep:prost-reflect" + "dep:prost-reflect", + "dep:bollard" ] vector-api-tests = [ diff --git a/tests/e2e/opentelemetry-demo/README.md b/tests/e2e/opentelemetry-demo/README.md new file mode 100644 index 0000000000000..d8796a5d19bd2 --- /dev/null +++ b/tests/e2e/opentelemetry-demo/README.md @@ -0,0 +1,91 @@ +# OpenTelemetry Demo trace validation + +This manual E2E test runs the multilingual +[OpenTelemetry Demo 3.1.0](https://github.com/open-telemetry/opentelemetry-demo/tree/3.1.0) +through Vector using the existing `vdev` Compose harness and Collector 0.159.0. + +## Input and destination + +```text +Demo applications → ingress Collector → Vector → destination Collector + input.jsonl output.jsonl +``` + +[scenario.py](data/scenario.py) runs one instrumented Locust user through three +sets of ad, recommendation, cart, and multi-item checkout requests, followed by a +missing-product request to generate errors. Checkout also exercises the Kafka +accounting and fraud-detection consumers. Browser traffic is disabled. + +The ingress Collector accepts the applications' OTLP/gRPC and OTLP/HTTP telemetry. +Its [configuration](data/collector-source.yaml) captures traces in `input.jsonl`. +The [test matrix](config/test.yaml) runs two separate environments: `otlphttp` +forwards over HTTP to `http://vector:4318/v1/traces`, and `otlp` forwards over +gRPC to `vector:4317`. Each run forwards the input once and applies the same +validations; captures are kept separately. +Application logs and metrics are accepted by the Collector but not sent to Vector. + +Vector runs [data/vector.yaml](data/vector.yaml), mounted as +`/etc/vector/vector.yaml`. Its `opentelemetry` source uses +`use_otlp_decoding: true`; its `opentelemetry` sink reads `otel.traces`, encodes +OTLP, and sends HTTP requests to `http://otel-collector-sink:4318/v1/traces`, +with a one-second batch timeout. There are no transforms. + +The destination is a second local OpenTelemetry Collector, configured by +[collector-sink.yaml](data/collector-sink.yaml) to write `output.jsonl`. +No external telemetry backend is involved. + +## Validations + +The [Rust test](../opentelemetry/demo/mod.rs) verifies: + +- Workload completion and drain: requires the completion marker, lets Kafka + consumers finish, stops producers and the ingress Collector, and waits up to + 120 seconds for Vector's output before closing the destination capture. +- Service coverage: requires spans from ad, cart, checkout, currency, email, + frontend, payment, product-catalog, quote, recommendation, shipping, + load-generator, accounting, and fraud-detection. +- Trace coverage: requires roots, multi-span traces, children with captured + parents, cross-service parent relationships, and error spans. +- Round-trip preservation: compares every span with its resource, scope, and + schema URLs, including identities, parents, attributes, timestamps, status, + events, links, flags, and dropped counts. Missing, extra, or changed spans, + including changes to duplicate counts, fail. Only batching, span traversal + order, and attribute-map order may differ. +- Capture support: rejects malformed IDs and unknown protobuf fields rather than + silently discarding them before comparison. + +Events, links, and scope groups containing multiple trace IDs are reported as +observed; they are not required coverage gates. This currently validates the +existing OTLP relay, not the proposed typed trace conversion. The flattened +`use_otlp_decoding: false` layout needs separate converter assertions because it +already loses scope information and cannot feed the current OTLP sink directly. + +Once OTLP-to-Datadog conversion is implemented, the same input can also feed a +`datadog_traces` sink targeting a local intake receiver. That branch should check +the [RFC's cross-format mapping](../../../rfcs/2026-04-29-25329-trace-data-model/datadog-mapping.md#cross-format-conformance-otlp---vector---datadog_traces), +while the OTLP branch continues checking round-trip preservation. + +## Running and results + +Locally, with Docker available, run both ingress transports: + +```shell +cargo vdev e2e run opentelemetry-demo --retries 0 --always-show-logs +``` + +To run one transport, add `-e 0.159.0-otlphttp` (HTTP) or `-e 0.159.0-otlp` (gRPC). + +In CI, a Vector-team member submits a PR review starting with +`/ci-run-e2e-opentelemetry-demo`. The dedicated job tests the reviewed commit. +Ordinary comments, both “run all” commands, automatic PR CI, and schedules do not +run the demo. The candidate branch must include this test. + +Captures, `coverage.json`, `differences.txt`, and `summary.md` are stored in the +`opentelemetry_demo_evidence` Docker volume, mounted under +`/output/opentelemetry-demo/`, in separate `otlphttp/` and `otlp/` directories. +The dedicated volume retains both runs across the harness's per-environment +cleanup. Each selected run replaces its own captures; unselected or unstarted +transports may retain older local results. CI publishes +these with the configuration, commit SHA, and runner logs in an +`otel-demo-` artifact and adds the summary to the job. Startup or drain +failures may leave partial evidence. diff --git a/tests/e2e/opentelemetry-demo/config/compose.yaml b/tests/e2e/opentelemetry-demo/config/compose.yaml new file mode 100644 index 0000000000000..248f4a07f3b50 --- /dev/null +++ b/tests/e2e/opentelemetry-demo/config/compose.yaml @@ -0,0 +1,808 @@ +# Adapted from OpenTelemetry Demo 3.1.0 compose.yaml and compose.full.yaml. +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +services: + ad: + image: ghcr.io/open-telemetry/demo:3.1.0-ad + healthcheck: + test: + - CMD-SHELL + - bash -c 'echo > /dev/tcp/localhost/9555' + timeout: 5s + interval: 5s + retries: 20 + start_period: 20s + depends_on: + flagd: + condition: service_started + required: true + otel-collector: + condition: service_healthy + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "314572800" + environment: + - AD_PORT=9555 + - AD_PROMETHEUS_PORT=9465 + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_LOGS_EXPORTER=otlp + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=medium + - OTEL_SERVICE_NAME=ad + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + cart: + image: ghcr.io/open-telemetry/demo:3.1.0-cart + depends_on: + flagd: + condition: service_started + required: true + otel-collector: + condition: service_healthy + required: true + valkey-cart: + condition: service_healthy + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "167772160" + environment: + - ASPNETCORE_URLS=http://*:7070 + - CART_PORT=7070 + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=high + - OTEL_SERVICE_NAME=cart + - VALKEY_ADDR=valkey-cart:6379 + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + checkout: + image: ghcr.io/open-telemetry/demo:3.1.0-checkout + healthcheck: + test: + - CMD + - "/bin/grpc_health_probe" + - "-addr=:5050" + timeout: 5s + interval: 5s + retries: 20 + start_period: 10s + depends_on: + cart: + condition: service_started + required: true + currency: + condition: service_healthy + required: true + email: + condition: service_healthy + required: true + flagd: + condition: service_started + required: true + kafka: + condition: service_healthy + required: true + otel-collector: + condition: service_healthy + required: true + payment: + condition: service_healthy + required: true + product-catalog: + condition: service_started + required: true + shipping: + condition: service_started + required: true + read_only: true + tmpfs: + - "/tmp" + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: 128M + environment: + - CART_ADDR=cart:7070 + - CHECKOUT_PORT=5050 + - CURRENCY_ADDR=currency:7001 + - EMAIL_ADDR=http://email:6060 + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - GOMEMLIMIT=100MiB + - KAFKA_ADDR=kafka:9092 + - KAFKA_TOPIC=orders + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf + - OTEL_GO_X_OBSERVABILITY=true + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=critical + - OTEL_SERVICE_NAME=checkout + - PAYMENT_ADDR=payment:50051 + - PRODUCT_CATALOG_ADDR=product-catalog:3550 + - SHIPPING_ADDR=http://shipping:50050 + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + currency: + image: ghcr.io/open-telemetry/demo:3.1.0-currency + healthcheck: + test: + - CMD-SHELL + - nc -z localhost 7001 + timeout: 5s + interval: 5s + retries: 20 + start_period: 10s + depends_on: + otel-collector: + condition: service_healthy + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: 128M + environment: + - CURRENCY_PORT=7001 + - IPV6_ENABLED=false + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=high + - OTEL_SERVICE_NAME=currency + - VERSION=3.0.0 + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + email: + image: ghcr.io/open-telemetry/demo:3.1.0-email + healthcheck: + test: + - CMD + - ruby + - "-e" + - require 'socket'; TCPSocket.new('localhost', 6060).close + timeout: 5s + interval: 5s + retries: 20 + start_period: 10s + depends_on: + otel-collector: + condition: service_healthy + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "104857600" + environment: + - APP_ENV=production + - EMAIL_PORT=6060 + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=medium + - OTEL_SERVICE_NAME=email + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + frontend: + image: ghcr.io/open-telemetry/demo:3.1.0-frontend + healthcheck: + test: + - CMD + - "/nodejs/bin/node" + - "-e" + - require('net').connect(8080,require('os').hostname(),function(){process.exit(0)}).on('error',function(){process.exit(1)}) + timeout: 10s + interval: 10s + retries: 5 + start_period: 1m0s + depends_on: + ad: + condition: service_healthy + required: true + cart: + condition: service_started + required: true + checkout: + condition: service_started + required: true + currency: + condition: service_healthy + required: true + flagd: + condition: service_started + required: true + otel-collector: + condition: service_healthy + required: true + product-catalog: + condition: service_started + required: true + quote: + condition: service_healthy + required: true + recommendation: + condition: service_healthy + required: true + shipping: + condition: service_started + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "262144000" + environment: + - AD_ADDR=ad:9555 + - CART_ADDR=cart:7070 + - CHECKOUT_ADDR=checkout:5050 + - CURRENCY_ADDR=currency:7001 + - ENV_PLATFORM=local + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - FRONTEND_ADDR=frontend:8080 + - OTEL_COLLECTOR_HOST=otel-collector + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=critical + - OTEL_SERVICE_NAME=frontend + - PORT=8080 + - PRODUCT_CATALOG_ADDR=product-catalog:3550 + - PUBLIC_OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:8080/otlp-http/v1/traces + - RECOMMENDATION_ADDR=recommendation:9001 + - SHIPPING_ADDR=http://shipping:50050 + - WEB_OTEL_SERVICE_NAME=frontend-web + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + payment: + image: ghcr.io/open-telemetry/demo:3.1.0-payment + healthcheck: + test: + - CMD + - "/nodejs/bin/node" + - "-e" + - const net=require('net');const c=new net.Socket(); c.setTimeout(2000); c.connect(50051,'127.0.0.1',()=>{c.destroy();process.exit(0)}); + c.on('error',()=>process.exit(1)); c.on('timeout',()=>process.exit(1)) + timeout: 5s + interval: 5s + retries: 20 + start_period: 10s + depends_on: + flagd: + condition: service_started + required: true + otel-collector: + condition: service_healthy + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "146800640" + environment: + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - IPV6_ENABLED=false + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_EXPORTER_OTLP_PROTOCOL=grpc + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=critical + - OTEL_SERVICE_NAME=payment + - PAYMENT_PORT=50051 + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + product-catalog: + image: ghcr.io/open-telemetry/demo:3.1.0-product-catalog + healthcheck: + test: + - CMD + - "/bin/grpc_health_probe" + - "-addr=:3550" + timeout: 5s + interval: 5s + retries: 20 + start_period: 10s + depends_on: + astronomy-db: + condition: service_healthy + required: true + flagd: + condition: service_started + required: true + otel-collector: + condition: service_healthy + required: true + read_only: true + tmpfs: + - "/tmp" + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: 128M + environment: + - DB_CONNECTION_STRING=postgres://astronomy_user:astronomy_password@astronomy-db/astronomy_db?sslmode=disable + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - GOMEMLIMIT=100MiB + - OTEL_CONFIG_FILE=/otel-config.yml + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_GO_X_OBSERVABILITY=true + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=high + - OTEL_SEMCONV_STABILITY_OPT_IN=database + - OTEL_SERVICE_NAME=product-catalog + - PRODUCT_CATALOG_PORT=3550 + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + volumes: + - "../data/otel-config.yml:/otel-config.yml:ro" + quote: + image: ghcr.io/open-telemetry/demo:3.1.0-quote + healthcheck: + test: + - CMD + - php + - "-r" + - fsockopen('localhost', 8090) or die('fail'); + timeout: 5s + interval: 5s + retries: 20 + start_period: 10s + depends_on: + otel-collector: + condition: service_healthy + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "41943040" + environment: + - IPV6_ENABLED=false + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_PHP_AUTOLOAD_ENABLED=true + - OTEL_PHP_INTERNAL_METRICS_ENABLED=true + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=low + - OTEL_SERVICE_NAME=quote + - QUOTE_PORT=8090 + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + recommendation: + image: ghcr.io/open-telemetry/demo:3.1.0-recommendation + healthcheck: + test: + - CMD-SHELL + - nc -z localhost 9001 + timeout: 5s + interval: 5s + retries: 20 + start_period: 10s + depends_on: + flagd: + condition: service_started + required: true + otel-collector: + condition: service_healthy + required: true + product-catalog: + condition: service_started + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "524288000" + environment: + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_PYTHON_LOG_CORRELATION=true + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=medium + - OTEL_SERVICE_NAME=recommendation + - PRODUCT_CATALOG_ADDR=product-catalog:3550 + - PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python + - RECOMMENDATION_PORT=9001 + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + shipping: + image: ghcr.io/open-telemetry/demo:3.1.0-shipping + healthcheck: + test: + - CMD + - "/app/healthcheck" + timeout: 5s + interval: 5s + retries: 20 + start_period: 10s + depends_on: + flagd: + condition: service_started + required: true + otel-collector: + condition: service_healthy + required: true + read_only: true + tmpfs: + - "/tmp" + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: 128M + environment: + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - IPV6_ENABLED=false + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=high + - OTEL_SERVICE_NAME=shipping + - QUOTE_ADDR=http://quote:8090 + - SHIPPING_PORT=50050 + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + accounting: + image: ghcr.io/open-telemetry/demo:3.1.0-accounting + depends_on: + kafka: + condition: service_healthy + required: true + otel-collector: + condition: service_healthy + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "167772160" + environment: + - DB_CONNECTION_STRING=Host=astronomy-db;Username=astronomy_user;Password=astronomy_password;Database=astronomy_db + - KAFKA_ADDR=kafka:9092 + - KAFKA_TOPIC=orders + - OTEL_DOTNET_AUTO_TRACES_ENTITYFRAMEWORKCORE_INSTRUMENTATION_ENABLED=false + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=low + - OTEL_SERVICE_NAME=accounting + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + fraud-detection: + image: ghcr.io/open-telemetry/demo:3.1.0-fraud-detection + depends_on: + kafka: + condition: service_healthy + required: true + otel-collector: + condition: service_healthy + required: true + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "314572800" + environment: + - FLAGD_HOST=flagd + - FLAGD_PORT=8013 + - KAFKA_ADDR=kafka:9092 + - KAFKA_TOPIC=orders + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_INSTRUMENTATION_KAFKA_EXPERIMENTAL_SPAN_ATTRIBUTES=true + - OTEL_INSTRUMENTATION_MESSAGING_EXPERIMENTAL_RECEIVE_TELEMETRY_ENABLED=true + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=low + - OTEL_SERVICE_NAME=fraud-detection + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + kafka: + image: ghcr.io/open-telemetry/demo:3.1.0-kafka + healthcheck: + test: + - CMD-SHELL + - nc -z kafka 9092 + timeout: 10s + interval: 5s + retries: 10 + start_period: 10s + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "650117120" + environment: + - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092 + - KAFKA_CONTROLLER_QUORUM_VOTERS=1@kafka:9093 + - KAFKA_HEAP_OPTS=-Xmx400m -Xms400m + - KAFKA_LISTENERS=PLAINTEXT://kafka:9092,CONTROLLER://kafka:9093 + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=low + - OTEL_SERVICE_NAME=kafka + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + flagd: + image: ghcr.io/open-feature/flagd:v0.16.0 + command: + - start + - "--uri" + - file:./etc/flagd/demo.flagd.json + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "78643200" + environment: + - GOMEMLIMIT=100MiB + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 + - OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=low + - OTEL_SERVICE_NAME=flagd + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + volumes: + - "../data/demo.flagd.json:/etc/flagd/demo.flagd.json:ro" + astronomy-db: + image: postgres:18.4 + command: + - postgres + - "-c" + - shared_preload_libraries=pg_stat_statements + healthcheck: + test: + - CMD-SHELL + - pg_isready + timeout: 5s + interval: 5s + retries: 10 + start_period: 10s + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "83886080" + environment: + - POSTGRES_PASSWORD=changeit + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + volumes: + - "../data/init.sql:/docker-entrypoint-initdb.d/init.sql:ro" + valkey-cart: + image: ghcr.io/valkey-io/valkey:9.0.4-alpine3.23 + healthcheck: + test: + - CMD-SHELL + - valkey-cli ping + timeout: 3s + interval: 5s + retries: 10 + start_period: 5s + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "20971520" + environment: + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + load-generator: + image: ghcr.io/open-telemetry/demo:3.1.0-load-generator + depends_on: + flagd: + condition: service_started + required: true + frontend: + condition: service_healthy + required: true + accounting: + condition: service_started + fraud-detection: + condition: service_started + logging: + driver: json-file + options: + max-file: "2" + max-size: 5m + mem_limit: "1572864000" + environment: + - CONFIG_INGRESS_EXPORTER=${CONFIG_INGRESS_EXPORTER} + - FLAGD_HOST=flagd + - FLAGD_OFREP_PORT=8016 + - FLAGD_PORT=8013 + - LOCUST_AUTOSTART=false + - LOCUST_BROWSER_TRAFFIC_ENABLED=false + - LOCUST_BROWSER_USER_WEIGHT=1 + - LOCUST_HEADLESS=true + - LOCUST_HOST=http://frontend:8080 + - LOCUST_HTTP_USER_WEIGHT=9 + - LOCUST_USERS=5 + - LOCUST_WEB_HOST=0.0.0.0 + - LOCUST_WEB_PORT=8089 + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 + - OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION=explicit_bucket_histogram + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative + - OTEL_RESOURCE_ATTRIBUTES=service.namespace=opentelemetry-demo,service.version=3.1.0,service.criticality=low + - OTEL_SERVICE_NAME=load-generator + - PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python + - OTEL_BSP_SCHEDULE_DELAY=1000 + - OTEL_TRACES_SAMPLER=always_on + labels: + vector.otel-demo.producer: "true" + command: + - "-f" + - "/usr/src/app/scenario.py" + - "--headless" + - "--users=1" + - "--spawn-rate=1" + - "--run-time=90s" + - "--stop-timeout=15" + - DemoUser + volumes: + - "../data/scenario.py:/usr/src/app/scenario.py:ro" + - opentelemetry_demo_evidence:/output/opentelemetry-demo + prepare-output: + image: alpine:3.20 + command: + - sh + - "-c" + - rm -rf /output/opentelemetry-demo/${CONFIG_INGRESS_EXPORTER} && mkdir -p /output/opentelemetry-demo/${CONFIG_INGRESS_EXPORTER} + volumes: + - opentelemetry_demo_evidence:/output/opentelemetry-demo + otel-collector: + build: + context: "../../../.." + dockerfile: tests/e2e/opentelemetry-common/collector.Dockerfile + args: + CONFIG_COLLECTOR_VERSION: "${CONFIG_COLLECTOR_VERSION}" + environment: + - CONFIG_INGRESS_EXPORTER=${CONFIG_INGRESS_EXPORTER} + command: + - "--config=/etc/otelcol-contrib/config.yaml" + depends_on: + prepare-output: + condition: service_completed_successfully + vector: + condition: service_started + volumes: + - "../data/collector-source.yaml:/etc/otelcol-contrib/config.yaml:ro" + - opentelemetry_demo_evidence:/output/opentelemetry-demo + healthcheck: + test: + - CMD-SHELL + - wget -q -O /dev/null http://localhost:13133/ + interval: 1s + timeout: 1s + retries: 120 + otel-collector-sink: + build: + context: "../../../.." + dockerfile: tests/e2e/opentelemetry-common/collector.Dockerfile + args: + CONFIG_COLLECTOR_VERSION: "${CONFIG_COLLECTOR_VERSION}" + environment: + - CONFIG_INGRESS_EXPORTER=${CONFIG_INGRESS_EXPORTER} + command: + - "--config=/etc/otelcol-contrib/config.yaml" + depends_on: + prepare-output: + condition: service_completed_successfully + volumes: + - "../data/collector-sink.yaml:/etc/otelcol-contrib/config.yaml:ro" + - opentelemetry_demo_evidence:/output/opentelemetry-demo + healthcheck: + test: + - CMD-SHELL + - wget -q -O /dev/null http://localhost:13133/ + interval: 1s + timeout: 1s + retries: 120 + vector: + image: "${CONFIG_VECTOR_IMAGE}" + command: + - vector + - "--config" + - "/etc/vector/vector.yaml" + environment: + - VECTOR_LOG=${VECTOR_LOG:-info} + depends_on: + prepare-output: + condition: service_completed_successfully + otel-collector-sink: + condition: service_healthy + volumes: + - "../data/vector.yaml:/etc/vector/vector.yaml:ro" + demo-ready: + image: alpine:3.20 + command: + - sh + - "-c" + - test -f /output/opentelemetry-demo/${CONFIG_INGRESS_EXPORTER}/workload-complete + depends_on: + load-generator: + condition: service_completed_successfully + volumes: + - opentelemetry_demo_evidence:/output/opentelemetry-demo +volumes: + opentelemetry_demo_evidence: + external: true +networks: + default: + name: "${VECTOR_NETWORK}" + external: true diff --git a/tests/e2e/opentelemetry-demo/config/test.yaml b/tests/e2e/opentelemetry-demo/config/test.yaml new file mode 100644 index 0000000000000..88c4fe40825e6 --- /dev/null +++ b/tests/e2e/opentelemetry-demo/config/test.yaml @@ -0,0 +1,17 @@ +features: + - e2e-tests-opentelemetry + +test: e2e +test_filter: "opentelemetry::demo::" + +runner: + needs_docker_socket: true + volumes: + opentelemetry_demo_evidence: /output/opentelemetry-demo + +matrix: + collector_version: ["0.159.0"] + ingress_exporter: ["otlphttp", "otlp"] # HTTP and gRPC into Vector, respectively. + + +# Intentionally absent from the automatic CI matrices and changed-file filters. diff --git a/tests/e2e/opentelemetry-demo/data/collector-sink.yaml b/tests/e2e/opentelemetry-demo/data/collector-sink.yaml new file mode 100644 index 0000000000000..14d467ccce164 --- /dev/null +++ b/tests/e2e/opentelemetry-demo/data/collector-sink.yaml @@ -0,0 +1,21 @@ +extensions: + health_check: + endpoint: 0.0.0.0:13133 + +receivers: + otlp: + protocols: + http: + endpoint: 0.0.0.0:4318 + +exporters: + file: + path: /output/opentelemetry-demo/${env:CONFIG_INGRESS_EXPORTER}/output.jsonl + flush_interval: 100ms + +service: + extensions: [health_check] + pipelines: + traces: + receivers: [otlp] + exporters: [file] diff --git a/tests/e2e/opentelemetry-demo/data/collector-source.yaml b/tests/e2e/opentelemetry-demo/data/collector-source.yaml new file mode 100644 index 0000000000000..ce584f6260821 --- /dev/null +++ b/tests/e2e/opentelemetry-demo/data/collector-source.yaml @@ -0,0 +1,47 @@ +extensions: + health_check: + endpoint: 0.0.0.0:13133 + +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + +exporters: + file: + path: /output/opentelemetry-demo/${env:CONFIG_INGRESS_EXPORTER}/input.jsonl + flush_interval: 100ms + otlphttp: + endpoint: http://vector:4318 + sending_queue: + enabled: false + retry_on_failure: + enabled: true + max_elapsed_time: 30s + otlp: + endpoint: vector:4317 + tls: + insecure: true + sending_queue: + enabled: false + retry_on_failure: + enabled: true + max_elapsed_time: 30s + debug: + verbosity: basic + +service: + extensions: [health_check] + pipelines: + traces: + receivers: [otlp] + exporters: [file, "${env:CONFIG_INGRESS_EXPORTER}"] + metrics: + receivers: [otlp] + exporters: [debug] + logs: + receivers: [otlp] + exporters: [debug] diff --git a/tests/e2e/opentelemetry-demo/data/demo.flagd.json b/tests/e2e/opentelemetry-demo/data/demo.flagd.json new file mode 100644 index 0000000000000..1b8ab340b2d27 --- /dev/null +++ b/tests/e2e/opentelemetry-demo/data/demo.flagd.json @@ -0,0 +1,201 @@ +{ + "$schema": "https://flagd.dev/schema/v0/flags.json", + "flags": { + "adFailure": { + "defaultVariant": "off", + "description": "Fail ad service", + "state": "ENABLED", + "variants": { + "off": false, + "on": true + } + }, + "adHighCpu": { + "defaultVariant": "off", + "description": "Triggers high cpu load in the ad service", + "state": "ENABLED", + "variants": { + "off": false, + "on": true + } + }, + "adManualGc": { + "defaultVariant": "off", + "description": "Triggers full manual garbage collections in the ad service", + "state": "ENABLED", + "variants": { + "off": false, + "on": true + } + }, + "aiRunawayAgent": { + "defaultVariant": "off", + "description": "forces the agent to keep looping tool calls until it hits its recursion limit", + "state": "ENABLED", + "variants": { + "off": 0, + "on": 20 + } + }, + "aiSlowResponse": { + "defaultVariant": "off", + "description": "slow LLM responses in the agent service", + "state": "ENABLED", + "variants": { + "10sec": 10000, + "5sec": 5000, + "off": 0 + } + }, + "cartFailure": { + "defaultVariant": "off", + "description": "Fail cart service n% of the time", + "state": "ENABLED", + "variants": { + "10%": 0.1, + "100%": 1, + "25%": 0.25, + "50%": 0.5, + "75%": 0.75, + "90%": 0.9, + "off": 0 + } + }, + "emailMemoryLeak": { + "defaultVariant": "off", + "description": "Memory leak in the email service.", + "state": "ENABLED", + "variants": { + "10000x": 10000, + "1000x": 1000, + "100x": 100, + "10x": 10, + "1x": 1, + "off": 0 + } + }, + "emitRawPii": { + "defaultVariant": "off", + "description": "Emit raw PII attributes (user.email, demo.payment.card_number, demo.payment.card_cvv) from checkout and payment for the collector redaction example. Not a failure scenario -- controls PII emission, independent of collector-side redaction which always runs.", + "metadata": { + "schedulable": false + }, + "state": "ENABLED", + "variants": { + "off": false, + "on": true + } + }, + "failedReadinessProbe": { + "defaultVariant": "off", + "description": "readiness probe failure for cart service", + "state": "ENABLED", + "variants": { + "off": false, + "on": true + } + }, + "imageSlowLoad": { + "defaultVariant": "off", + "description": "slow loading images in the frontend", + "state": "ENABLED", + "variants": { + "10sec": 10000, + "5sec": 5000, + "off": 0 + } + }, + "intlShippingSlowdown": { + "defaultVariant": "off", + "description": "Delays international shipping responses to simulate overseas shipping delay", + "state": "ENABLED", + "variants": { + "10sec": 10, + "5sec": 5, + "off": 0 + } + }, + "kafkaQueueProblems": { + "defaultVariant": "off", + "description": "Overloads Kafka queue while simultaneously introducing a consumer side delay leading to a lag spike", + "state": "ENABLED", + "variants": { + "off": 0, + "on": 100 + } + }, + "loadGeneratorFloodHomepage": { + "defaultVariant": "off", + "description": "Flood the frontend with a large amount of requests.", + "state": "ENABLED", + "variants": { + "off": 0, + "on": 100 + } + }, + "paymentFailure": { + "defaultVariant": "off", + "description": "Fail payment service charge requests n%", + "state": "ENABLED", + "variants": { + "10%": 0.1, + "100%": 1, + "25%": 0.25, + "50%": 0.5, + "75%": 0.75, + "90%": 0.95, + "off": 0 + } + }, + "paymentUnreachable": { + "defaultVariant": "off", + "description": "Payment service is unavailable", + "state": "ENABLED", + "variants": { + "off": false, + "on": true + } + }, + "productCatalogFailure": { + "defaultVariant": "off", + "description": "Fail product catalog service on a specific product", + "state": "ENABLED", + "targeting": { + "if": [ + { + "==": [ + { + "var": "product_id" + }, + "OLJCESPC7Z" + ] + }, + "off", + "off" + ] + }, + "variants": { + "off": false, + "on": true + } + }, + "productCatalogLockContention": { + "defaultVariant": "off", + "description": "Trigger lock contention on the product catalog database", + "state": "ENABLED", + "variants": { + "off": false, + "on": true + } + }, + "recommendationCacheFailure": { + "defaultVariant": "off", + "description": "Fail recommendation service cache", + "state": "ENABLED", + "variants": { + "off": false, + "on": true + } + } + } +} diff --git a/tests/e2e/opentelemetry-demo/data/init.sql b/tests/e2e/opentelemetry-demo/data/init.sql new file mode 100644 index 0000000000000..8e1387f624dce --- /dev/null +++ b/tests/e2e/opentelemetry-demo/data/init.sql @@ -0,0 +1,94 @@ +-- Copyright The OpenTelemetry Authors +-- SPDX-License-Identifier: Apache-2.0 + +-- Enable pg_stat_statements in the default postgres database +CREATE EXTENSION IF NOT EXISTS pg_stat_statements; + +-- Create application user +CREATE USER astronomy_user WITH PASSWORD 'astronomy_password'; + +-- Create application database +CREATE DATABASE astronomy_db OWNER astronomy_user; + +-- Create monitoring user with pg_monitor role (visibility on all databases and schemas) +CREATE USER monitoring_user WITH PASSWORD 'monitoring_password'; +GRANT pg_monitor TO monitoring_user; + +-- Switch to the application database +\connect astronomy_db + +-- Enable pg_stat_statements in the application database +CREATE EXTENSION IF NOT EXISTS pg_stat_statements; + +-- Accounting Service: create a schema +CREATE SCHEMA accounting; +GRANT USAGE ON SCHEMA accounting TO astronomy_user; + +-- Accounting Service: create tables +CREATE TABLE accounting."order" ( + order_id TEXT PRIMARY KEY +); + +CREATE TABLE accounting.shipping ( + shipping_tracking_id TEXT PRIMARY KEY, + shipping_cost_currency_code TEXT NOT NULL, + shipping_cost_units BIGINT NOT NULL, + shipping_cost_nanos INT NOT NULL, + street_address TEXT, + city TEXT, + state TEXT, + country TEXT, + zip_code TEXT, + order_id TEXT NOT NULL, + FOREIGN KEY (order_id) REFERENCES accounting."order"(order_id) ON DELETE CASCADE +); + +CREATE TABLE accounting.orderitem ( + item_cost_currency_code TEXT NOT NULL, + item_cost_units BIGINT NOT NULL, + item_cost_nanos INT NOT NULL, + product_id TEXT NOT NULL, + quantity INT NOT NULL, + order_id TEXT NOT NULL, + PRIMARY KEY (order_id, product_id), + FOREIGN KEY (order_id) REFERENCES accounting."order"(order_id) ON DELETE CASCADE +); + +-- Accounting Service: grant permission to schema +GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA accounting TO astronomy_user; + +-- Product Catalog Service: create a schema +CREATE SCHEMA catalog; +GRANT USAGE ON SCHEMA catalog TO astronomy_user; + +-- Product Catalog Service: create tables +CREATE TABLE catalog.products ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + description TEXT, + picture TEXT, + price_currency_code TEXT NOT NULL, + price_units BIGINT NOT NULL, + price_nanos INT NOT NULL, + categories TEXT +); + +-- Product Catalog Service: grant permission to schema +-- UPDATE is required to acquire the ACCESS EXCLUSIVE lock used by the +-- productCatalogLockContention fault-injection flag; the service otherwise +-- only reads from this schema. +GRANT SELECT, UPDATE ON ALL TABLES IN SCHEMA catalog TO astronomy_user; + +-- Product Catalog Service: add product data +INSERT INTO catalog.products (id, name, description, picture, price_currency_code, price_units, price_nanos, categories) +VALUES + ('OLJCESPC7Z', 'National Park Foundation Explorascope', 'The National Park Foundation''s (NPF) Explorascope 60AZ is a manual alt-azimuth, refractor telescope perfect for celestial viewing on the go. The NPF Explorascope 60 can view the planets, moon, star clusters and brighter deep sky objects like the Orion Nebula and Andromeda Galaxy.', 'NationalParkFoundationExplorascope.jpg', 'USD', 101, 960000000, 'telescopes'), + ('66VCHSJNUP', 'Starsense Explorer Refractor Telescope', 'The first telescope that uses your smartphone to analyze the night sky and calculate its position in real time. StarSense Explorer is ideal for beginners thanks to the app''s user-friendly interface and detailed tutorials. It''s like having your own personal tour guide of the night sky', 'StarsenseExplorer.jpg', 'USD', 349, 950000000, 'telescopes'), + ('1YMWWN1N4O', 'Eclipsmart Travel Refractor Telescope', 'Dedicated white-light solar scope for the observer on the go. The 50mm refracting solar scope uses Solar Safe, ISO compliant, full-aperture glass filter material to ensure the safest view of solar events. The kit comes complete with everything you need, including the dedicated travel solar scope, a Solar Safe finderscope, tripod, a high quality 20mm (18x) Kellner eyepiece and a nylon backpack to carry everything in. This Travel Solar Scope makes it easy to share the Sun as well as partial and total solar eclipses with the whole family and offers much higher magnifications than you would otherwise get using handheld solar viewers or binoculars.', 'EclipsmartTravelRefractorTelescope.jpg', 'USD', 129, 950000000, 'telescopes,travel'), + ('L9ECAV7KIM', 'Lens Cleaning Kit', 'Wipe away dust, dirt, fingerprints and other particles on your lenses to see clearly with the Lens Cleaning Kit. This cleaning kit works on all glass and optical surfaces, including telescopes, binoculars, spotting scopes, monoculars, microscopes, and even your camera lenses, computer screens, and mobile devices. The kit comes complete with a retractable lens brush to remove dust particles and dirt and two options to clean smudges and fingerprints off of your optics, pre-moistened lens wipes and a bottled lens cleaning fluid with soft cloth.', 'LensCleaningKit.jpg', 'USD', 21, 950000000, 'accessories'), + ('2ZYFJ3GM2N', 'Roof Binoculars', 'This versatile, all-around binocular is a great choice for the trail, the stadium, the arena, or just about anywhere you want a close-up view of the action without sacrificing brightness or detail. It''s an especially great companion for nature observation and bird watching, with ED glass that helps you spot the subtlest field markings and a close focus of just 6.5 feet.', 'RoofBinoculars.jpg', 'USD', 209, 950000000, 'binoculars'), + ('0PUK6V6EV0', 'Solar System Color Imager', 'You have your new telescope and have observed Saturn and Jupiter. Now you''re ready to take the next step and start imaging them. But where do you begin? The NexImage 10 Solar System Imager is the perfect solution.', 'SolarSystemColorImager.jpg', 'USD', 175, 0, 'accessories,telescopes'), + ('LS4PSXUNUM', 'Red Flashlight', 'This 3-in-1 device features a 3-mode red flashlight, a hand warmer, and a portable power bank for recharging your personal electronics on the go. Whether you use it to light the way at an astronomy star party, a night walk, or wildlife research, ThermoTorch 3 Astro Red''s rugged, IPX4-rated design will withstand your everyday activities.', 'RedFlashlight.jpg', 'USD', 57, 80000000, 'accessories,flashlights'), + ('9SIQT8TOJO', 'Optical Tube Assembly', 'Capturing impressive deep-sky astroimages is easier than ever with Rowe-Ackermann Schmidt Astrograph (RASA) V2, the perfect companion to today''s top DSLR or astronomical CCD cameras. This fast, wide-field f/2.2 system allows for shorter exposure times compared to traditional f/10 astroimaging, without sacrificing resolution. Because shorter sub-exposure times are possible, your equatorial mount won''t need to accurately track over extended periods. The short focal length also lessens equatorial tracking demands. In many cases, autoguiding will not be required.', 'OpticalTubeAssembly.jpg', 'USD', 3599, 0, 'accessories,telescopes,assembly'), + ('6E92ZMYYFZ', 'Solar Filter', 'Enhance your viewing experience with EclipSmart Solar Filter for 8" telescopes. With two Velcro straps and four self-adhesive Velcro pads for added safety, you can be assured that the solar filter cannot be accidentally knocked off and will provide Solar Safe, ISO compliant viewing.', 'SolarFilter.jpg', 'USD', 69, 950000000, 'accessories,telescopes'), + ('HQTGWGPNH4', 'The Comet Book', 'A 16th-century treatise on comets, created anonymously in Flanders (now northern France) and now held at the Universitätsbibliothek Kassel. Commonly known as The Comet Book (or Kometenbuch in German), its full title translates as "Comets and their General and Particular Meanings, According to Ptolomeé, Albumasar, Haly, Aliquind and other Astrologers". The image is from https://publicdomainreview.org/collection/the-comet-book, made available by the Universitätsbibliothek Kassel under a CC-BY SA 4.0 license (https://creativecommons.org/licenses/by-sa/4.0/)', 'TheCometBook.jpg', 'USD', 0, 990000000, 'books'); diff --git a/tests/e2e/opentelemetry-demo/data/otel-config.yml b/tests/e2e/opentelemetry-demo/data/otel-config.yml new file mode 100644 index 0000000000000..2526521510693 --- /dev/null +++ b/tests/e2e/opentelemetry-demo/data/otel-config.yml @@ -0,0 +1,37 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 + +file_format: "1.0" +disabled: false +log_level: info +logger_provider: + processors: + - batch: + exporter: + otlp_grpc: + endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT} +meter_provider: + readers: + - periodic: + exporter: + otlp_grpc: + endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT} + temporality_preference: ${OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE:-cumulative} +tracer_provider: + processors: + - batch: + exporter: + otlp_grpc: + endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT} +propagator: + composite: + - tracecontext: + - baggage: +resource: + attributes_list: ${OTEL_RESOURCE_ATTRIBUTES} + detection/development: + detectors: + - container: + - host: + - process: + - service: diff --git a/tests/e2e/opentelemetry-demo/data/scenario.py b/tests/e2e/opentelemetry-demo/data/scenario.py new file mode 100644 index 0000000000000..ce0fa88735a2c --- /dev/null +++ b/tests/e2e/opentelemetry-demo/data/scenario.py @@ -0,0 +1,38 @@ +"""Bounded transactions using the pinned demo's instrumented Locust user.""" + +import os +from pathlib import Path + +from locust import task +from locustfile import WebsiteUser +from opentelemetry import trace + + +class DemoUser(WebsiteUser): + @task + def transactions(self): + for _ in range(3): + self.get_ads() + self.get_recommendations() + self.view_cart() + self.checkout_multi() + + # The catalog's not-found RPC exercises real error spans without a fault flag. + with self.tracer.start_as_current_span("user_missing_product"): + with self.client.get( + "/api/products/vector-e2e-missing", catch_response=True + ) as response: + if response.status_code < 400: + response.failure("missing product unexpectedly succeeded") + self.environment.process_exit_code = 1 + else: + response.success() + + trace.get_tracer_provider().shutdown() + directory = Path("/output/opentelemetry-demo") / os.environ["CONFIG_INGRESS_EXPORTER"] + (directory / "workload-complete").touch() + self.environment.runner.quit() + + +# Locust adds inherited tasks during class creation, even when tasks = []. +DemoUser.tasks = [DemoUser.transactions] diff --git a/tests/e2e/opentelemetry-demo/data/vector.yaml b/tests/e2e/opentelemetry-demo/data/vector.yaml new file mode 100644 index 0000000000000..b18c905fd27ba --- /dev/null +++ b/tests/e2e/opentelemetry-demo/data/vector.yaml @@ -0,0 +1,20 @@ +sources: + otel: + type: opentelemetry + grpc: + address: 0.0.0.0:4317 + http: + address: 0.0.0.0:4318 + use_otlp_decoding: true + +sinks: + output: + inputs: [otel.traces] + type: opentelemetry + protocol: + type: http + uri: http://otel-collector-sink:4318/v1/traces + encoding: + codec: otlp + batch: + timeout_secs: 1 diff --git a/tests/e2e/opentelemetry/demo/mod.rs b/tests/e2e/opentelemetry/demo/mod.rs new file mode 100644 index 0000000000000..8b3ee7996b278 --- /dev/null +++ b/tests/e2e/opentelemetry/demo/mod.rs @@ -0,0 +1,447 @@ +use std::{ + collections::{BTreeMap, BTreeSet, HashMap}, + fs, + path::Path, + thread, + time::{Duration, Instant}, +}; + +use bollard::{ + Docker, + query_parameters::{ListContainersOptionsBuilder, StopContainerOptionsBuilder}, +}; +use prost::Message; +use vector_lib::opentelemetry::proto::{ + collector::trace::v1::ExportTraceServiceRequest, + common::v1::{AnyValue, KeyValue, any_value::Value}, + trace::v1::{ResourceSpans, ScopeSpans}, +}; + +use crate::opentelemetry::parse_export_traces_request; + +const OUTPUT: &str = "/output/opentelemetry-demo"; +const NETWORK: &str = "vector-integration-tests-opentelemetry-demo"; +const REQUIRED_SERVICES: &[&str] = &[ + "ad", + "cart", + "checkout", + "currency", + "email", + "frontend", + "payment", + "product-catalog", + "quote", + "recommendation", + "shipping", + "load-generator", + "accounting", + "fraud-detection", +]; + +// Attribute lists are maps; arrays, events and links keep their meaningful order. +fn sort_attributes(attributes: &mut [KeyValue]) { + fn sort_value(value: &mut AnyValue) { + match value.value.as_mut() { + Some(Value::KvlistValue(list)) => sort_attributes(&mut list.values), + Some(Value::ArrayValue(array)) => array.values.iter_mut().for_each(sort_value), + _ => {} + } + } + for attribute in attributes.iter_mut() { + if let Some(value) = &mut attribute.value { + sort_value(value); + } + } + attributes.sort_by(|a, b| a.key.cmp(&b.key)); +} + +type SpanKey = (Vec, Vec); + +fn records(request: &ExportTraceServiceRequest) -> BTreeMap>> { + let mut records: BTreeMap>> = BTreeMap::new(); + for rs in &request.resource_spans { + for ss in &rs.scope_spans { + for span in &ss.spans { + let mut record = ResourceSpans { + resource: rs.resource.clone(), + schema_url: rs.schema_url.clone(), + scope_spans: vec![ScopeSpans { + scope: ss.scope.clone(), + schema_url: ss.schema_url.clone(), + spans: vec![span.clone()], + }], + }; + if let Some(resource) = &mut record.resource { + sort_attributes(&mut resource.attributes); + } + let scope = &mut record.scope_spans[0]; + if let Some(scope) = &mut scope.scope { + sort_attributes(&mut scope.attributes); + } + let span = &mut scope.spans[0]; + sort_attributes(&mut span.attributes); + for event in &mut span.events { + sort_attributes(&mut event.attributes); + } + for link in &mut span.links { + sort_attributes(&mut link.attributes); + } + records + .entry((span.trace_id.clone(), span.span_id.clone())) + .or_default() + .push(record.encode_to_vec()); + } + } + } + for occurrences in records.values_mut() { + occurrences.sort(); + } + records +} + +fn compare(source: &ExportTraceServiceRequest, sink: &ExportTraceServiceRequest) -> Vec { + let source = records(source); + let sink = records(sink); + let keys: BTreeSet<_> = source.keys().chain(sink.keys()).collect(); + keys.into_iter() + .filter_map(|key| { + let expected = source.get(key).cloned().unwrap_or_default(); + let actual = sink.get(key).cloned().unwrap_or_default(); + if expected == actual { + return None; + } + let decode = |values: Vec>| { + values + .into_iter() + .map(|value| ResourceSpans::decode(value.as_slice()).unwrap()) + .collect::>() + }; + Some(format!( + "trace={} span={}\nexpected: {:#?}\nactual: {:#?}", + hex::encode(&key.0), + hex::encode(&key.1), + decode(expected), + decode(actual), + )) + }) + .collect() +} + +fn service(rs: &ResourceSpans) -> &str { + rs.resource + .as_ref() + .and_then(|resource| { + resource + .attributes + .iter() + .find(|attribute| attribute.key == "service.name") + }) + .and_then(|attribute| attribute.value.as_ref()) + .and_then(|value| value.value.as_ref()) + .and_then(|value| match value { + Value::StringValue(value) => Some(value.as_str()), + _ => None, + }) + .unwrap_or("") +} + +fn coverage(request: &ExportTraceServiceRequest) -> serde_json::Value { + let mut services = BTreeMap::<&str, usize>::new(); + let mut scopes = BTreeMap::<&str, usize>::new(); + let mut traces = BTreeMap::<&[u8], usize>::new(); + let mut parents = BTreeMap::new(); + let mut roots = 0; + let mut errors = 0; + let mut events = 0; + let mut links = 0; + let mut mixed_scopes = 0; + for rs in &request.resource_spans { + for ss in &rs.scope_spans { + let ids: BTreeSet<_> = ss.spans.iter().map(|span| &span.trace_id).collect(); + mixed_scopes += usize::from(ids.len() > 1); + for span in &ss.spans { + *services.entry(service(rs)).or_default() += 1; + *scopes + .entry( + ss.scope + .as_ref() + .map_or("", |scope| scope.name.as_str()), + ) + .or_default() += 1; + *traces.entry(&span.trace_id).or_default() += 1; + parents.insert( + (span.trace_id.as_slice(), span.span_id.as_slice()), + service(rs), + ); + roots += usize::from( + span.parent_span_id.is_empty() + || span.parent_span_id.iter().all(|byte| *byte == 0), + ); + errors += usize::from(span.status.as_ref().is_some_and(|status| status.code == 2)); + events += span.events.len(); + links += span.links.len(); + } + } + } + let mut children = 0; + let mut cross_service = 0; + for rs in &request.resource_spans { + for ss in &rs.scope_spans { + for span in &ss.spans { + if let Some(parent_service) = + parents.get(&(span.trace_id.as_slice(), span.parent_span_id.as_slice())) + { + children += 1; + cross_service += usize::from(*parent_service != service(rs)); + } + } + } + } + serde_json::json!({ + "services": services, "scopes": scopes, + "spans": services.values().sum::(), "traces": traces.len(), + "multi_span_traces": traces.values().filter(|count| **count > 1).count(), + "root_spans": roots, "children_with_captured_parent": children, + "cross_service_parent_relationships": cross_service, + "error_spans": errors, "events": events, "links": links, + "scope_groups_with_multiple_trace_ids": mixed_scopes, + }) +} + +async fn stop_containers(docker: &Docker, filter: &str) -> Result<(), String> { + let filters = HashMap::from([ + ("network".to_owned(), vec![NETWORK.to_owned()]), + ("label".to_owned(), vec![filter.to_owned()]), + ]); + let containers = docker + .list_containers(Some( + ListContainersOptionsBuilder::new() + .filters(&filters) + .build(), + )) + .await + .map_err(|error| error.to_string())?; + if containers.is_empty() { + return Err(format!("No running demo containers matching {filter}")); + } + // Stop producers together so consumers remain alive during SDK shutdown. + futures::future::try_join_all(containers.iter().map(|container| async { + docker + .stop_container( + container.id.as_deref().ok_or("Container ID missing")?, + Some(StopContainerOptionsBuilder::new().t(30).build()), + ) + .await + .map_err(|error| error.to_string()) + })) + .await?; + Ok(()) +} + +fn read_capture(directory: &Path, name: &str) -> Result { + let path = directory.join(name); + parse_export_traces_request( + &fs::read_to_string(&path).map_err(|error| format!("{}: {error}", path.display()))?, + ) +} + +async fn validate_demo() -> Result<(), String> { + let exporter = std::env::var("CONFIG_INGRESS_EXPORTER").map_err(|error| error.to_string())?; + let transport = match exporter.as_str() { + "otlphttp" => "HTTP", + "otlp" => "gRPC", + _ => return Err(format!("Unsupported ingress exporter: {exporter}")), + }; + let directory = Path::new(OUTPUT).join(&exporter); + if !directory.join("workload-complete").exists() { + return Err( + "Demo workload did not complete; run cargo vdev e2e run opentelemetry-demo".into(), + ); + } + let docker = Docker::connect_with_socket_defaults().map_err(|error| error.to_string())?; + // Give asynchronous Kafka consumers time to process the final checkout. + thread::sleep(Duration::from_secs(5)); + stop_containers(&docker, "vector.otel-demo.producer=true").await?; + stop_containers(&docker, "com.docker.compose.service=otel-collector").await?; + let input = read_capture(&directory, "input.jsonl")?; + let input_coverage = coverage(&input); + fs::write( + directory.join("coverage.json"), + serde_json::to_string_pretty(&input_coverage).unwrap(), + ) + .map_err(|error| error.to_string())?; + + let deadline = Instant::now() + Duration::from_secs(120); + let mut failures = Vec::new(); + loop { + if let Ok(output) = read_capture(&directory, "output.jsonl") + && coverage(&output)["spans"].as_u64() >= input_coverage["spans"].as_u64() + { + break; + } + if Instant::now() >= deadline { + failures.push("Timed out draining Vector; inspect input.jsonl and output.jsonl".into()); + break; + } + thread::sleep(Duration::from_millis(500)); + } + stop_containers(&docker, "com.docker.compose.service=otel-collector-sink").await?; + let output = read_capture(&directory, "output.jsonl")?; + let differences = compare(&input, &output); + fs::write(directory.join("differences.txt"), differences.join("\n\n")) + .map_err(|error| error.to_string())?; + for name in REQUIRED_SERVICES { + if input_coverage["services"][*name].as_u64().unwrap_or(0) == 0 { + failures.push(format!("Missing service: {name}")); + } + } + for field in [ + "root_spans", + "multi_span_traces", + "children_with_captured_parent", + "cross_service_parent_relationships", + "error_spans", + ] { + if input_coverage[field].as_u64().unwrap_or(0) == 0 { + failures.push(format!("Missing trace shape: {field}")); + } + } + if !differences.is_empty() { + failures.push(format!( + "{} differing span identities; see differences.txt", + differences.len() + )); + } + let summary = format!( + "# OTel Demo trace validation\n\nDemo: 3.1.0; Vector ingress: {transport}\n\n```json\n{}\n```\n\n{}\n", + serde_json::to_string_pretty(&input_coverage).unwrap(), + if failures.is_empty() { + "PASS: captured trace semantics and multiplicities match.".into() + } else { + failures.join("\n") + } + ); + fs::write(directory.join("summary.md"), summary).map_err(|error| error.to_string())?; + if failures.is_empty() { + Ok(()) + } else { + Err(failures.join("\n")) + } +} + +#[tokio::test] +async fn demo_trace_round_trip() { + validate_demo() + .await + .unwrap_or_else(|error| panic!("{error}")); +} + +#[cfg(test)] +mod tests { + use super::*; + use vector_lib::opentelemetry::proto::trace::v1::{ResourceSpans, ScopeSpans, Span}; + + fn request() -> ExportTraceServiceRequest { + ExportTraceServiceRequest { + resource_spans: vec![ResourceSpans { + scope_spans: vec![ScopeSpans { + spans: vec![Span { + trace_id: vec![1; 16], + span_id: vec![2; 8], + parent_span_id: vec![3; 8], + name: "checkout".into(), + ..Default::default() + }], + ..Default::default() + }], + ..Default::default() + }], + } + } + + #[test] + fn comparison_preserves_multiplicity_and_context() { + let source = request(); + let mut repeated = source.clone(); + repeated + .resource_spans + .push(source.resource_spans[0].clone()); + let mut rebatched = source.clone(); + rebatched.resource_spans[0].scope_spans[0] + .spans + .push(source.resource_spans[0].scope_spans[0].spans[0].clone()); + assert!(compare(&repeated, &rebatched).is_empty()); + assert!(!compare(&source, &rebatched).is_empty()); + assert!(!compare(&source, &ExportTraceServiceRequest::default()).is_empty()); + for field in ["parent", "span", "resource", "scope", "schema"] { + let mut changed = source.clone(); + let rs = &mut changed.resource_spans[0]; + match field { + "parent" => rs.scope_spans[0].spans[0].parent_span_id = vec![4; 8], + "span" => rs.scope_spans[0].spans[0].name = "changed".into(), + "resource" => rs.resource = Some(Default::default()), + "scope" => rs.scope_spans[0].scope = Some(Default::default()), + "schema" => rs.schema_url = "changed".into(), + _ => unreachable!(), + } + assert!(!compare(&source, &changed).is_empty(), "missed {field}"); + } + } + + #[test] + fn comparison_ignores_attribute_order_but_preserves_values_and_events() { + use vector_lib::opentelemetry::proto::{ + common::v1::KeyValueList, + trace::v1::span::{Event, Link}, + }; + let attribute = |key: &str, value: &str| KeyValue { + key: key.into(), + value: Some(AnyValue { + value: Some(Value::StringValue(value.into())), + }), + }; + let mut source = request(); + let span = &mut source.resource_spans[0].scope_spans[0].spans[0]; + span.attributes = vec![ + attribute("z", "last"), + KeyValue { + key: "nested".into(), + value: Some(AnyValue { + value: Some(Value::KvlistValue(KeyValueList { + values: vec![attribute("b", "2"), attribute("a", "1")], + })), + }), + }, + ]; + span.events = vec![Event { + name: "exception".into(), + ..Default::default() + }]; + span.links = vec![Link { + trace_id: vec![4; 16], + span_id: vec![5; 8], + ..Default::default() + }]; + let mut reordered = source.clone(); + let attributes = &mut reordered.resource_spans[0].scope_spans[0].spans[0].attributes; + attributes.reverse(); + if let Some(Value::KvlistValue(list)) = attributes[0].value.as_mut().unwrap().value.as_mut() + { + list.values.reverse(); + } + assert!(compare(&source, &reordered).is_empty()); + for field in ["attribute", "event", "link", "flags", "dropped"] { + let mut changed = source.clone(); + let span = &mut changed.resource_spans[0].scope_spans[0].spans[0]; + match field { + "attribute" => span.attributes[0] = attribute("z", "changed"), + "event" => span.events[0].name = "changed".into(), + "link" => span.links[0].span_id = vec![6; 8], + "flags" => span.flags = 1, + "dropped" => span.dropped_attributes_count = 1, + _ => unreachable!(), + } + assert!(!compare(&source, &changed).is_empty(), "missed {field}"); + } + } +} diff --git a/tests/e2e/opentelemetry/mod.rs b/tests/e2e/opentelemetry/mod.rs index c87368a27b7df..92f33c0d241bc 100644 --- a/tests/e2e/opentelemetry/mod.rs +++ b/tests/e2e/opentelemetry/mod.rs @@ -1,3 +1,4 @@ +pub mod demo; pub mod logs; pub mod metrics; pub mod metrics_native; @@ -5,10 +6,14 @@ pub mod traces; use std::{io, path::Path, process::Command}; +use base64::prelude::{BASE64_STANDARD, Engine as _}; use prost::Message as ProstMessage; -use prost_reflect::{DescriptorPool, prost::Message as ProstReflectMessage}; +use prost_reflect::{ + DescriptorPool, Kind, MessageDescriptor, prost::Message as ProstReflectMessage, +}; use vector_lib::opentelemetry::proto::{ - DESCRIPTOR_BYTES, common::v1::any_value::Value as AnyValueEnum, resource::v1::Resource, + DESCRIPTOR_BYTES, TRACES_REQUEST_MESSAGE_TYPE, collector::trace::v1::ExportTraceServiceRequest, + common::v1::any_value::Value as AnyValueEnum, resource::v1::Resource, }; use vrl::value::Value as VrlValue; @@ -175,3 +180,149 @@ pub fn assert_component_received_events_total(data_type: &str, expected_count: u not batch requests. Found: {total_events}" ); } + +pub(super) fn parse_export_traces_request( + content: &str, +) -> Result { + // The file may contain multiple lines, each with a JSON object containing an array of resourceSpans + let mut merged_request = ExportTraceServiceRequest { + resource_spans: Vec::new(), + }; + + for (line_num, line) in content.lines().enumerate() { + let line = line.trim(); + if line.is_empty() { + continue; + } + + merged_request.resource_spans.extend( + parse_collector_trace_line(line) + .map_err(|e| format!("Line {}: {}", line_num + 1, e))? + .resource_spans, + ); + } + + if merged_request.resource_spans.is_empty() { + return Err("No resource spans found in file".to_string()); + } + + Ok(merged_request) +} + +fn parse_collector_trace_line(line: &str) -> Result { + let mut value: VrlValue = serde_json::from_str::(line) + .map_err(|e| format!("Failed to parse JSON: {e}"))? + .into(); + + let pool = DescriptorPool::decode(DESCRIPTOR_BYTES).map_err(|error| error.to_string())?; + let descriptor = pool + .get_message_by_name(TRACES_REQUEST_MESSAGE_TYPE) + .ok_or("Trace request descriptor missing")?; + reject_unknown_fields(&value, &descriptor)?; + decode_collector_ids(&mut value)?; + parse_value_to_export_type_request(TRACES_REQUEST_MESSAGE_TYPE, value) +} + +// VRL's protobuf encoder otherwise discards unknown JSON fields from both captures. +fn reject_unknown_fields(value: &VrlValue, descriptor: &MessageDescriptor) -> Result<(), String> { + let fields = value + .as_object() + .ok_or_else(|| format!("{} should be an object", descriptor.full_name()))?; + for (name, value) in fields { + let field = descriptor.get_field_by_json_name(name).ok_or_else(|| { + format!( + "Unsupported captured field {}.{name}", + descriptor.full_name() + ) + })?; + if let Kind::Message(child) = field.kind() { + if field.is_list() { + for value in value + .as_array() + .ok_or_else(|| format!("{name} should be an array"))? + { + reject_unknown_fields(value, &child)?; + } + } else if !matches!(value, VrlValue::Null) { + reject_unknown_fields(value, &child)?; + } + } + } + Ok(()) +} + +fn decode_collector_ids(value: &mut VrlValue) -> Result<(), String> { + match value { + VrlValue::Object(fields) => { + for (name, value) in fields { + if name.as_str() == "bytesValue" { + let encoded = value + .as_bytes() + .ok_or("bytesValue should be a base64 string")?; + *value = VrlValue::Bytes( + BASE64_STANDARD + .decode(encoded) + .map_err(|error| format!("Failed to decode bytesValue: {error}"))? + .into(), + ); + continue; + } + let valid_hex_lengths: &[usize] = match name.as_str() { + "traceId" => &[32], + "spanId" => &[16], + "parentSpanId" => &[0, 16], + _ => { + decode_collector_ids(value)?; + continue; + } + }; + + let encoded = value + .as_bytes() + .ok_or_else(|| format!("{name} should be a hexadecimal string"))?; + if !valid_hex_lengths.contains(&encoded.len()) { + return Err(format!( + "{name} has invalid hexadecimal length {}", + encoded.len() + )); + } + + *value = VrlValue::Bytes( + hex::decode(encoded.as_ref()) + .map_err(|e| format!("Failed to decode {name}: {e}"))? + .into(), + ); + } + } + VrlValue::Array(values) => { + for value in values { + decode_collector_ids(value)?; + } + } + _ => {} + } + + Ok(()) +} + +#[test] +fn collector_trace_parser_rejects_unknown_fields() { + let capture = r#"{"resourceSpans":[{"resource":{"entityRefs":[]},"scopeSpans":[]}]}"#; + assert!( + parse_export_traces_request(capture) + .unwrap_err() + .contains("entityRefs") + ); +} + +#[test] +fn collector_trace_parser_decodes_byte_attributes() { + let capture = r#"{"resourceSpans":[{"scopeSpans":[{"spans":[{"attributes":[{"key":"payload","value":{"bytesValue":"AAEC/w=="}}]}]}]}]}"#; + let request = parse_export_traces_request(capture).unwrap(); + assert_eq!( + request.resource_spans[0].scope_spans[0].spans[0].attributes[0].value, + Some(vector_lib::opentelemetry::proto::common::v1::AnyValue { + value: Some(AnyValueEnum::BytesValue(vec![0, 1, 2, 255])) + }) + ); +} diff --git a/tests/e2e/opentelemetry/traces/mod.rs b/tests/e2e/opentelemetry/traces/mod.rs index 874fc5cd78e83..5f512b5797085 100644 --- a/tests/e2e/opentelemetry/traces/mod.rs +++ b/tests/e2e/opentelemetry/traces/mod.rs @@ -1,10 +1,8 @@ -use vector_lib::opentelemetry::proto::TRACES_REQUEST_MESSAGE_TYPE; use vector_lib::opentelemetry::proto::collector::trace::v1::ExportTraceServiceRequest; use crate::opentelemetry::{ - assert_service_name_with, parse_value_to_export_type_request, read_file_helper, + assert_service_name_with, parse_export_traces_request, read_file_helper, }; -use vrl::value::Value as VrlValue; // The source collector records telemetrygen's input once, then forwards it to Vector over both // OTLP protocols. @@ -12,83 +10,6 @@ const EXPECTED_TRACE_COUNT: usize = 100; const SOURCE_SPAN_COUNT: usize = 200; // 100 traces * 2 spans (parent + child). const FORWARDED_SPAN_COUNT: usize = 400; // 200 spans * 2 Vector exports (gRPC + HTTP). -fn parse_export_traces_request(content: &str) -> Result { - // The file may contain multiple lines, each with a JSON object containing an array of resourceSpans - let mut merged_request = ExportTraceServiceRequest { - resource_spans: Vec::new(), - }; - - for (line_num, line) in content.lines().enumerate() { - let line = line.trim(); - if line.is_empty() { - continue; - } - - merged_request.resource_spans.extend( - parse_collector_trace_line(line) - .map_err(|e| format!("Line {}: {}", line_num + 1, e))? - .resource_spans, - ); - } - - if merged_request.resource_spans.is_empty() { - return Err("No resource spans found in file".to_string()); - } - - Ok(merged_request) -} - -fn parse_collector_trace_line(line: &str) -> Result { - let mut value: VrlValue = serde_json::from_str::(line) - .map_err(|e| format!("Failed to parse JSON: {e}"))? - .into(); - - decode_collector_ids(&mut value)?; - parse_value_to_export_type_request(TRACES_REQUEST_MESSAGE_TYPE, value) -} - -fn decode_collector_ids(value: &mut VrlValue) -> Result<(), String> { - match value { - VrlValue::Object(fields) => { - for (name, value) in fields { - let valid_hex_lengths: &[usize] = match name.as_str() { - "traceId" => &[32], - "spanId" => &[16], - "parentSpanId" => &[0, 16], - _ => { - decode_collector_ids(value)?; - continue; - } - }; - - let encoded = value - .as_bytes() - .ok_or_else(|| format!("{name} should be a hexadecimal string"))?; - if !valid_hex_lengths.contains(&encoded.len()) { - return Err(format!( - "{name} has invalid hexadecimal length {}", - encoded.len() - )); - } - - *value = VrlValue::Bytes( - hex::decode(encoded.as_ref()) - .map_err(|e| format!("Failed to decode {name}: {e}"))? - .into(), - ); - } - } - VrlValue::Array(values) => { - for value in values { - decode_collector_ids(value)?; - } - } - _ => {} - } - - Ok(()) -} - /// Asserts that all spans have expected static fields set: /// - `name`: Should be non-empty /// - `kind`: Should be set From f002f26f410ca1e25c74641735287c4436313d8e Mon Sep 17 00:00:00 2001 From: Tess Neau Date: Wed, 7 Oct 2026 15:09:38 +0200 Subject: [PATCH 02/10] Clarify OTel trace test documentation and add architecture diagram --- tests/e2e/opentelemetry-demo/README.md | 121 ++++++++---------- tests/e2e/opentelemetry-demo/architecture.png | Bin 0 -> 313211 bytes 2 files changed, 56 insertions(+), 65 deletions(-) create mode 100644 tests/e2e/opentelemetry-demo/architecture.png diff --git a/tests/e2e/opentelemetry-demo/README.md b/tests/e2e/opentelemetry-demo/README.md index d8796a5d19bd2..20cf4b28c4b13 100644 --- a/tests/e2e/opentelemetry-demo/README.md +++ b/tests/e2e/opentelemetry-demo/README.md @@ -1,73 +1,70 @@ -# OpenTelemetry Demo trace validation +# Multiservice OpenTelemetry trace validation -This manual E2E test runs the multilingual +This manual E2E test checks that Vector preserves multilingual, multiservice +traces from the [OpenTelemetry Demo 3.1.0](https://github.com/open-telemetry/opentelemetry-demo/tree/3.1.0) -through Vector using the existing `vdev` Compose harness and Collector 0.159.0. +using the existing `vdev` Compose harness and +[OTel Collector](https://opentelemetry.io/docs/collector/) 0.159.0. + +It provides realistic trace-preservation evidence for changes such as the +[trace model RFC](../../../rfcs/2026-04-29-25329-trace-data-model.md). +It runs manually because the full application setup is heavier than the +fixture-based trace tests. ## Input and destination -```text -Demo applications → ingress Collector → Vector → destination Collector - input.jsonl output.jsonl -``` +![Trace test architecture: application traces pass through Vector between two Collectors; input and output captures are compared after each run.](architecture.png) + +Trace and span counts in the diagram are examples from local runs, not assertions. + +[scenario.py](data/scenario.py) runs one simulated shopper through three rounds of ad, +recommendation, cart, and multi-item checkout requests, then a missing-product +request to generate errors. Checkout also exercises the Kafka accounting and +fraud-detection consumers. -[scenario.py](data/scenario.py) runs one instrumented Locust user through three -sets of ad, recommendation, cart, and multi-item checkout requests, followed by a -missing-product request to generate errors. Checkout also exercises the Kafka -accounting and fraud-detection consumers. Browser traffic is disabled. +The [ingress Collector](data/collector-source.yaml) writes `input.jsonl` and +forwards traces to Vector. The [matrix](config/test.yaml) runs each transport +separately with the same checks: -The ingress Collector accepts the applications' OTLP/gRPC and OTLP/HTTP telemetry. -Its [configuration](data/collector-source.yaml) captures traces in `input.jsonl`. -The [test matrix](config/test.yaml) runs two separate environments: `otlphttp` -forwards over HTTP to `http://vector:4318/v1/traces`, and `otlp` forwards over -gRPC to `vector:4317`. Each run forwards the input once and applies the same -validations; captures are kept separately. -Application logs and metrics are accepted by the Collector but not sent to Vector. +- HTTP (`otlphttp`): `http://vector:4318/v1/traces`. +- gRPC (`otlp`): `vector:4317`. + +Application logs and metrics are not forwarded to Vector. Vector runs [data/vector.yaml](data/vector.yaml), mounted as -`/etc/vector/vector.yaml`. Its `opentelemetry` source uses -`use_otlp_decoding: true`; its `opentelemetry` sink reads `otel.traces`, encodes -OTLP, and sends HTTP requests to `http://otel-collector-sink:4318/v1/traces`, -with a one-second batch timeout. There are no transforms. +`/etc/vector/vector.yaml`: an `opentelemetry` source with +`use_otlp_decoding: true` feeds `otel.traces` directly to an `opentelemetry` +sink, which sends OTLP/HTTP to `http://otel-collector-sink:4318/v1/traces`. -The destination is a second local OpenTelemetry Collector, configured by -[collector-sink.yaml](data/collector-sink.yaml) to write `output.jsonl`. -No external telemetry backend is involved. +The destination is a [second local Collector](data/collector-sink.yaml) that +writes `output.jsonl`. ## Validations The [Rust test](../opentelemetry/demo/mod.rs) verifies: -- Workload completion and drain: requires the completion marker, lets Kafka - consumers finish, stops producers and the ingress Collector, and waits up to - 120 seconds for Vector's output before closing the destination capture. -- Service coverage: requires spans from ad, cart, checkout, currency, email, - frontend, payment, product-catalog, quote, recommendation, shipping, - load-generator, accounting, and fraud-detection. -- Trace coverage: requires roots, multi-span traces, children with captured +- Completion: requires the workload marker, allows Kafka consumers to finish, + stops the input, and waits up to 120 seconds for Vector to drain. +- Service coverage: requires spans from 14 services exercised by the workload. +- Trace shapes: requires roots, multi-span traces, children with captured parents, cross-service parent relationships, and error spans. -- Round-trip preservation: compares every span with its resource, scope, and - schema URLs, including identities, parents, attributes, timestamps, status, - events, links, flags, and dropped counts. Missing, extra, or changed spans, - including changes to duplicate counts, fail. Only batching, span traversal - order, and attribute-map order may differ. -- Capture support: rejects malformed IDs and unknown protobuf fields rather than - silently discarding them before comparison. - -Events, links, and scope groups containing multiple trace IDs are reported as -observed; they are not required coverage gates. This currently validates the -existing OTLP relay, not the proposed typed trace conversion. The flattened -`use_otlp_decoding: false` layout needs separate converter assertions because it -already loses scope information and cannot feed the current OTLP sink directly. - -Once OTLP-to-Datadog conversion is implemented, the same input can also feed a -`datadog_traces` sink targeting a local intake receiver. That branch should check -the [RFC's cross-format mapping](../../../rfcs/2026-04-29-25329-trace-data-model/datadog-mapping.md#cross-format-conformance-otlp---vector---datadog_traces), -while the OTLP branch continues checking round-trip preservation. +- Preservation: compares every span and its resource, scope, and schema URLs. + Missing, extra, or changed spans and duplicate counts fail. Only batching, + span order, and attribute-map order may differ. +- Capture format: fails on malformed IDs or unknown capture fields. + +## Coverage and limitations + +- Decoding: only `use_otlp_decoding: true` is tested. +- Optional coverage: events, links, and scope groups with multiple trace IDs + are reported in `coverage.json` and compared when present. They are not required, + so a run without them can pass. +- Edge cases: the workload does not guarantee all field values, such as byte + attributes, missing scopes, or nonzero dropped counts. ## Running and results -Locally, with Docker available, run both ingress transports: +With Docker available, run both transports: ```shell cargo vdev e2e run opentelemetry-demo --retries 0 --always-show-logs @@ -75,17 +72,11 @@ cargo vdev e2e run opentelemetry-demo --retries 0 --always-show-logs To run one transport, add `-e 0.159.0-otlphttp` (HTTP) or `-e 0.159.0-otlp` (gRPC). -In CI, a Vector-team member submits a PR review starting with -`/ci-run-e2e-opentelemetry-demo`. The dedicated job tests the reviewed commit. -Ordinary comments, both “run all” commands, automatic PR CI, and schedules do not -run the demo. The candidate branch must include this test. - -Captures, `coverage.json`, `differences.txt`, and `summary.md` are stored in the -`opentelemetry_demo_evidence` Docker volume, mounted under -`/output/opentelemetry-demo/`, in separate `otlphttp/` and `otlp/` directories. -The dedicated volume retains both runs across the harness's per-environment -cleanup. Each selected run replaces its own captures; unselected or unstarted -transports may retain older local results. CI publishes -these with the configuration, commit SHA, and runner logs in an -`otel-demo-` artifact and adds the summary to the job. Startup or drain -failures may leave partial evidence. +In CI, a Vector-team member can submit a PR review starting with +`/ci-run-e2e-opentelemetry-demo` to test the reviewed commit. +Comments, “run all” commands, automatic PR CI, and schedules do not trigger it. + +Read the results on the CI job's summary page. Download the +`otel-demo-` artifact for input/output captures, `coverage.json`, +`differences.txt`, configs, and runner logs. Results are separated by transport; +failed runs may leave partial results. diff --git a/tests/e2e/opentelemetry-demo/architecture.png b/tests/e2e/opentelemetry-demo/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..18b6d7084c3ebe1cadf94fda7ec1ab778e7a22af GIT binary patch literal 313211 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

~K^|WPjOSjrAQ|x# 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 Date: Wed, 7 Oct 2026 15:15:22 +0200 Subject: [PATCH 03/10] Rename OTel trace E2E suite to multiservice traces --- .config/nextest.toml | 2 +- .github/workflows/ci-integration-review.yml | 42 +++++++------- .../README.md | 8 +-- .../architecture.png | Bin .../config/compose.yaml | 52 +++++++++--------- .../config/test.yaml | 4 +- .../data/collector-sink.yaml | 2 +- .../data/collector-source.yaml | 2 +- .../data/demo.flagd.json | 0 .../data/init.sql | 0 .../data/otel-config.yml | 0 .../data/scenario.py | 2 +- .../data/vector.yaml | 0 tests/e2e/opentelemetry/mod.rs | 2 +- .../{demo => multiservice_traces}/mod.rs | 16 +++--- 15 files changed, 67 insertions(+), 65 deletions(-) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/README.md (91%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/architecture.png (100%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/config/compose.yaml (93%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/config/test.yaml (68%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/data/collector-sink.yaml (75%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/data/collector-source.yaml (89%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/data/demo.flagd.json (100%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/data/init.sql (100%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/data/otel-config.yml (100%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/data/scenario.py (91%) rename tests/e2e/{opentelemetry-demo => opentelemetry-traces-multiservice}/data/vector.yaml (100%) rename tests/e2e/opentelemetry/{demo => multiservice_traces}/mod.rs (96%) diff --git a/.config/nextest.toml b/.config/nextest.toml index 70d7f40da6705..cdde6b58ed242 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -22,7 +22,7 @@ path = "junit.xml" store-failure-output = true [[profile.default.overrides]] -filter = 'test(opentelemetry::demo::demo_trace_round_trip)' +filter = 'test(opentelemetry::multiservice_traces::trace_round_trip)' # This test stops its producers and collectors, so a retry needs a fresh Compose run. retries = 0 slow-timeout = { period = "30s", terminate-after = 10 } diff --git a/.github/workflows/ci-integration-review.yml b/.github/workflows/ci-integration-review.yml index eae4ff7088e63..8381bbefe3242 100644 --- a/.github/workflows/ci-integration-review.yml +++ b/.github/workflows/ci-integration-review.yml @@ -187,6 +187,8 @@ jobs: command: vdev integration run ${{ matrix.service }} ${{ runner.debug == '1' && '--always-show-logs' || '' }} e2e-tests: + # The dedicated command also starts with the ordinary opentelemetry-traces command. + if: ${{ !startsWith(github.event.review.body, '/ci-run-e2e-opentelemetry-traces-multiservice') }} needs: - prep-pr - build-test-runner @@ -251,9 +253,9 @@ jobs: max_attempts: 3 command: vdev e2e run ${{ matrix.service }} ${{ runner.debug == '1' && '--always-show-logs' || '' }} - otel-demo: - name: OTel Demo trace validation - if: startsWith(github.event.review.body, '/ci-run-e2e-opentelemetry-demo') + otel-traces-multiservice: + name: Multiservice OpenTelemetry trace validation + if: startsWith(github.event.review.body, '/ci-run-e2e-opentelemetry-traces-multiservice') needs: - prep-pr - build-test-runner @@ -282,37 +284,37 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} commit_sha: ${{ github.event.review.commit_id }} - - name: OTel Demo trace validation + - name: Multiservice OpenTelemetry trace validation run: | - mkdir -p target/otel-demo-evidence + mkdir -p target/otel-traces-multiservice-evidence set -o pipefail - vdev e2e run opentelemetry-demo --retries 0 --always-show-logs 2>&1 | tee target/otel-demo-evidence/runner.log + vdev e2e run opentelemetry-traces-multiservice --retries 0 --always-show-logs 2>&1 | tee target/otel-traces-multiservice-evidence/runner.log - - name: Collect OTel Demo evidence + - name: Collect multiservice trace evidence if: always() run: | - mkdir -p target/otel-demo-evidence - git rev-parse HEAD > target/otel-demo-evidence/revision.txt - cp -R tests/e2e/opentelemetry-demo/config tests/e2e/opentelemetry-demo/data target/otel-demo-evidence/ - if docker volume inspect opentelemetry_demo_evidence >/dev/null 2>&1; then + mkdir -p target/otel-traces-multiservice-evidence + git rev-parse HEAD > target/otel-traces-multiservice-evidence/revision.txt + cp -R tests/e2e/opentelemetry-traces-multiservice/config tests/e2e/opentelemetry-traces-multiservice/data target/otel-traces-multiservice-evidence/ + if docker volume inspect opentelemetry_traces_multiservice_evidence >/dev/null 2>&1; then docker run --rm \ - -v opentelemetry_demo_evidence:/output/opentelemetry-demo:ro \ - -v "$PWD/target/otel-demo-evidence:/evidence" \ - alpine:3.20 sh -c 'if [ -d /output/opentelemetry-demo ]; then cp -R /output/opentelemetry-demo/. /evidence/; fi' + -v opentelemetry_traces_multiservice_evidence:/output/opentelemetry-traces-multiservice:ro \ + -v "$PWD/target/otel-traces-multiservice-evidence:/evidence" \ + alpine:3.20 sh -c 'if [ -d /output/opentelemetry-traces-multiservice ]; then cp -R /output/opentelemetry-traces-multiservice/. /evidence/; fi' fi - summaries=(target/otel-demo-evidence/*/summary.md) + summaries=(target/otel-traces-multiservice-evidence/*/summary.md) if [ -f "${summaries[0]}" ]; then cat "${summaries[@]}" >> "$GITHUB_STEP_SUMMARY" else - echo 'OTel Demo did not produce a validation summary. See runner.log and the failed job steps.' >> "$GITHUB_STEP_SUMMARY" + echo 'Multiservice trace test did not produce a validation summary. See runner.log and the failed job steps.' >> "$GITHUB_STEP_SUMMARY" fi - - name: Upload OTel Demo evidence + - name: Upload multiservice trace evidence if: always() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: otel-demo-${{ github.event.review.commit_id }} - path: target/otel-demo-evidence/ + name: otel-traces-multiservice-${{ github.event.review.commit_id }} + path: target/otel-traces-multiservice-evidence/ retention-days: 14 update-pr-status: @@ -322,7 +324,7 @@ jobs: needs: - integration-tests - e2e-tests - - otel-demo + - otel-traces-multiservice if: always() && (startsWith(github.event.review.body, '/ci-run-integration') || contains(github.event.review.body, '/ci-run-all') || contains(github.event.review.body, '/ci-run-e2e')) permissions: statuses: write # Required to set final commit status diff --git a/tests/e2e/opentelemetry-demo/README.md b/tests/e2e/opentelemetry-traces-multiservice/README.md similarity index 91% rename from tests/e2e/opentelemetry-demo/README.md rename to tests/e2e/opentelemetry-traces-multiservice/README.md index 20cf4b28c4b13..2f95721deca8a 100644 --- a/tests/e2e/opentelemetry-demo/README.md +++ b/tests/e2e/opentelemetry-traces-multiservice/README.md @@ -41,7 +41,7 @@ writes `output.jsonl`. ## Validations -The [Rust test](../opentelemetry/demo/mod.rs) verifies: +The [Rust test](../opentelemetry/multiservice_traces/mod.rs) verifies: - Completion: requires the workload marker, allows Kafka consumers to finish, stops the input, and waits up to 120 seconds for Vector to drain. @@ -67,16 +67,16 @@ The [Rust test](../opentelemetry/demo/mod.rs) verifies: With Docker available, run both transports: ```shell -cargo vdev e2e run opentelemetry-demo --retries 0 --always-show-logs +cargo vdev e2e run opentelemetry-traces-multiservice --retries 0 --always-show-logs ``` To run one transport, add `-e 0.159.0-otlphttp` (HTTP) or `-e 0.159.0-otlp` (gRPC). In CI, a Vector-team member can submit a PR review starting with -`/ci-run-e2e-opentelemetry-demo` to test the reviewed commit. +`/ci-run-e2e-opentelemetry-traces-multiservice` to test the reviewed commit. Comments, “run all” commands, automatic PR CI, and schedules do not trigger it. Read the results on the CI job's summary page. Download the -`otel-demo-` artifact for input/output captures, `coverage.json`, +`otel-traces-multiservice-` artifact for input/output captures, `coverage.json`, `differences.txt`, configs, and runner logs. Results are separated by transport; failed runs may leave partial results. diff --git a/tests/e2e/opentelemetry-demo/architecture.png b/tests/e2e/opentelemetry-traces-multiservice/architecture.png similarity index 100% rename from tests/e2e/opentelemetry-demo/architecture.png rename to tests/e2e/opentelemetry-traces-multiservice/architecture.png diff --git a/tests/e2e/opentelemetry-demo/config/compose.yaml b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml similarity index 93% rename from tests/e2e/opentelemetry-demo/config/compose.yaml rename to tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml index 248f4a07f3b50..233fa79fc6c11 100644 --- a/tests/e2e/opentelemetry-demo/config/compose.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml @@ -39,7 +39,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" cart: image: ghcr.io/open-telemetry/demo:3.1.0-cart depends_on: @@ -72,7 +72,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" checkout: image: ghcr.io/open-telemetry/demo:3.1.0-checkout healthcheck: @@ -144,7 +144,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" currency: image: ghcr.io/open-telemetry/demo:3.1.0-currency healthcheck: @@ -177,7 +177,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" email: image: ghcr.io/open-telemetry/demo:3.1.0-email healthcheck: @@ -213,7 +213,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" frontend: image: ghcr.io/open-telemetry/demo:3.1.0-frontend healthcheck: @@ -287,7 +287,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" payment: image: ghcr.io/open-telemetry/demo:3.1.0-payment healthcheck: @@ -328,7 +328,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" product-catalog: image: ghcr.io/open-telemetry/demo:3.1.0-product-catalog healthcheck: @@ -376,7 +376,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" volumes: - "../data/otel-config.yml:/otel-config.yml:ro" quote: @@ -414,7 +414,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" recommendation: image: ghcr.io/open-telemetry/demo:3.1.0-recommendation healthcheck: @@ -456,7 +456,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" shipping: image: ghcr.io/open-telemetry/demo:3.1.0-shipping healthcheck: @@ -498,7 +498,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" accounting: image: ghcr.io/open-telemetry/demo:3.1.0-accounting depends_on: @@ -527,7 +527,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" fraud-detection: image: ghcr.io/open-telemetry/demo:3.1.0-fraud-detection depends_on: @@ -558,7 +558,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" kafka: image: ghcr.io/open-telemetry/demo:3.1.0-kafka healthcheck: @@ -588,7 +588,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" flagd: image: ghcr.io/open-feature/flagd:v0.16.0 command: @@ -610,7 +610,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" volumes: - "../data/demo.flagd.json:/etc/flagd/demo.flagd.json:ro" astronomy-db: @@ -638,7 +638,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" volumes: - "../data/init.sql:/docker-entrypoint-initdb.d/init.sql:ro" valkey-cart: @@ -661,7 +661,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" load-generator: image: ghcr.io/open-telemetry/demo:3.1.0-load-generator depends_on: @@ -704,7 +704,7 @@ services: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on labels: - vector.otel-demo.producer: "true" + vector.otel-traces-multiservice.producer: "true" command: - "-f" - "/usr/src/app/scenario.py" @@ -716,15 +716,15 @@ services: - DemoUser volumes: - "../data/scenario.py:/usr/src/app/scenario.py:ro" - - opentelemetry_demo_evidence:/output/opentelemetry-demo + - opentelemetry_traces_multiservice_evidence:/output/opentelemetry-traces-multiservice prepare-output: image: alpine:3.20 command: - sh - "-c" - - rm -rf /output/opentelemetry-demo/${CONFIG_INGRESS_EXPORTER} && mkdir -p /output/opentelemetry-demo/${CONFIG_INGRESS_EXPORTER} + - rm -rf /output/opentelemetry-traces-multiservice/${CONFIG_INGRESS_EXPORTER} && mkdir -p /output/opentelemetry-traces-multiservice/${CONFIG_INGRESS_EXPORTER} volumes: - - opentelemetry_demo_evidence:/output/opentelemetry-demo + - opentelemetry_traces_multiservice_evidence:/output/opentelemetry-traces-multiservice otel-collector: build: context: "../../../.." @@ -742,7 +742,7 @@ services: condition: service_started volumes: - "../data/collector-source.yaml:/etc/otelcol-contrib/config.yaml:ro" - - opentelemetry_demo_evidence:/output/opentelemetry-demo + - opentelemetry_traces_multiservice_evidence:/output/opentelemetry-traces-multiservice healthcheck: test: - CMD-SHELL @@ -765,7 +765,7 @@ services: condition: service_completed_successfully volumes: - "../data/collector-sink.yaml:/etc/otelcol-contrib/config.yaml:ro" - - opentelemetry_demo_evidence:/output/opentelemetry-demo + - opentelemetry_traces_multiservice_evidence:/output/opentelemetry-traces-multiservice healthcheck: test: - CMD-SHELL @@ -793,14 +793,14 @@ services: command: - sh - "-c" - - test -f /output/opentelemetry-demo/${CONFIG_INGRESS_EXPORTER}/workload-complete + - test -f /output/opentelemetry-traces-multiservice/${CONFIG_INGRESS_EXPORTER}/workload-complete depends_on: load-generator: condition: service_completed_successfully volumes: - - opentelemetry_demo_evidence:/output/opentelemetry-demo + - opentelemetry_traces_multiservice_evidence:/output/opentelemetry-traces-multiservice volumes: - opentelemetry_demo_evidence: + opentelemetry_traces_multiservice_evidence: external: true networks: default: diff --git a/tests/e2e/opentelemetry-demo/config/test.yaml b/tests/e2e/opentelemetry-traces-multiservice/config/test.yaml similarity index 68% rename from tests/e2e/opentelemetry-demo/config/test.yaml rename to tests/e2e/opentelemetry-traces-multiservice/config/test.yaml index 88c4fe40825e6..c563965beed21 100644 --- a/tests/e2e/opentelemetry-demo/config/test.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/config/test.yaml @@ -2,12 +2,12 @@ features: - e2e-tests-opentelemetry test: e2e -test_filter: "opentelemetry::demo::" +test_filter: "opentelemetry::multiservice_traces::" runner: needs_docker_socket: true volumes: - opentelemetry_demo_evidence: /output/opentelemetry-demo + opentelemetry_traces_multiservice_evidence: /output/opentelemetry-traces-multiservice matrix: collector_version: ["0.159.0"] diff --git a/tests/e2e/opentelemetry-demo/data/collector-sink.yaml b/tests/e2e/opentelemetry-traces-multiservice/data/collector-sink.yaml similarity index 75% rename from tests/e2e/opentelemetry-demo/data/collector-sink.yaml rename to tests/e2e/opentelemetry-traces-multiservice/data/collector-sink.yaml index 14d467ccce164..5e42e4822b26f 100644 --- a/tests/e2e/opentelemetry-demo/data/collector-sink.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/data/collector-sink.yaml @@ -10,7 +10,7 @@ receivers: exporters: file: - path: /output/opentelemetry-demo/${env:CONFIG_INGRESS_EXPORTER}/output.jsonl + path: /output/opentelemetry-traces-multiservice/${env:CONFIG_INGRESS_EXPORTER}/output.jsonl flush_interval: 100ms service: diff --git a/tests/e2e/opentelemetry-demo/data/collector-source.yaml b/tests/e2e/opentelemetry-traces-multiservice/data/collector-source.yaml similarity index 89% rename from tests/e2e/opentelemetry-demo/data/collector-source.yaml rename to tests/e2e/opentelemetry-traces-multiservice/data/collector-source.yaml index ce584f6260821..fe7a87927c5ab 100644 --- a/tests/e2e/opentelemetry-demo/data/collector-source.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/data/collector-source.yaml @@ -12,7 +12,7 @@ receivers: exporters: file: - path: /output/opentelemetry-demo/${env:CONFIG_INGRESS_EXPORTER}/input.jsonl + path: /output/opentelemetry-traces-multiservice/${env:CONFIG_INGRESS_EXPORTER}/input.jsonl flush_interval: 100ms otlphttp: endpoint: http://vector:4318 diff --git a/tests/e2e/opentelemetry-demo/data/demo.flagd.json b/tests/e2e/opentelemetry-traces-multiservice/data/demo.flagd.json similarity index 100% rename from tests/e2e/opentelemetry-demo/data/demo.flagd.json rename to tests/e2e/opentelemetry-traces-multiservice/data/demo.flagd.json diff --git a/tests/e2e/opentelemetry-demo/data/init.sql b/tests/e2e/opentelemetry-traces-multiservice/data/init.sql similarity index 100% rename from tests/e2e/opentelemetry-demo/data/init.sql rename to tests/e2e/opentelemetry-traces-multiservice/data/init.sql diff --git a/tests/e2e/opentelemetry-demo/data/otel-config.yml b/tests/e2e/opentelemetry-traces-multiservice/data/otel-config.yml similarity index 100% rename from tests/e2e/opentelemetry-demo/data/otel-config.yml rename to tests/e2e/opentelemetry-traces-multiservice/data/otel-config.yml diff --git a/tests/e2e/opentelemetry-demo/data/scenario.py b/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py similarity index 91% rename from tests/e2e/opentelemetry-demo/data/scenario.py rename to tests/e2e/opentelemetry-traces-multiservice/data/scenario.py index ce0fa88735a2c..730be7df0af50 100644 --- a/tests/e2e/opentelemetry-demo/data/scenario.py +++ b/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py @@ -29,7 +29,7 @@ def transactions(self): response.success() trace.get_tracer_provider().shutdown() - directory = Path("/output/opentelemetry-demo") / os.environ["CONFIG_INGRESS_EXPORTER"] + directory = Path("/output/opentelemetry-traces-multiservice") / os.environ["CONFIG_INGRESS_EXPORTER"] (directory / "workload-complete").touch() self.environment.runner.quit() diff --git a/tests/e2e/opentelemetry-demo/data/vector.yaml b/tests/e2e/opentelemetry-traces-multiservice/data/vector.yaml similarity index 100% rename from tests/e2e/opentelemetry-demo/data/vector.yaml rename to tests/e2e/opentelemetry-traces-multiservice/data/vector.yaml diff --git a/tests/e2e/opentelemetry/mod.rs b/tests/e2e/opentelemetry/mod.rs index 92f33c0d241bc..1f73d3e835e69 100644 --- a/tests/e2e/opentelemetry/mod.rs +++ b/tests/e2e/opentelemetry/mod.rs @@ -1,7 +1,7 @@ -pub mod demo; pub mod logs; pub mod metrics; pub mod metrics_native; +pub mod multiservice_traces; pub mod traces; use std::{io, path::Path, process::Command}; diff --git a/tests/e2e/opentelemetry/demo/mod.rs b/tests/e2e/opentelemetry/multiservice_traces/mod.rs similarity index 96% rename from tests/e2e/opentelemetry/demo/mod.rs rename to tests/e2e/opentelemetry/multiservice_traces/mod.rs index 8b3ee7996b278..5c01dd1d7bda4 100644 --- a/tests/e2e/opentelemetry/demo/mod.rs +++ b/tests/e2e/opentelemetry/multiservice_traces/mod.rs @@ -19,8 +19,8 @@ use vector_lib::opentelemetry::proto::{ use crate::opentelemetry::parse_export_traces_request; -const OUTPUT: &str = "/output/opentelemetry-demo"; -const NETWORK: &str = "vector-integration-tests-opentelemetry-demo"; +const OUTPUT: &str = "/output/opentelemetry-traces-multiservice"; +const NETWORK: &str = "vector-integration-tests-opentelemetry-traces-multiservice"; const REQUIRED_SERVICES: &[&str] = &[ "ad", "cart", @@ -245,7 +245,7 @@ fn read_capture(directory: &Path, name: &str) -> Result Result<(), String> { +async fn validate_multiservice_traces() -> Result<(), String> { let exporter = std::env::var("CONFIG_INGRESS_EXPORTER").map_err(|error| error.to_string())?; let transport = match exporter.as_str() { "otlphttp" => "HTTP", @@ -255,13 +255,13 @@ async fn validate_demo() -> Result<(), String> { let directory = Path::new(OUTPUT).join(&exporter); if !directory.join("workload-complete").exists() { return Err( - "Demo workload did not complete; run cargo vdev e2e run opentelemetry-demo".into(), + "Demo workload did not complete; run cargo vdev e2e run opentelemetry-traces-multiservice".into(), ); } let docker = Docker::connect_with_socket_defaults().map_err(|error| error.to_string())?; // Give asynchronous Kafka consumers time to process the final checkout. thread::sleep(Duration::from_secs(5)); - stop_containers(&docker, "vector.otel-demo.producer=true").await?; + stop_containers(&docker, "vector.otel-traces-multiservice.producer=true").await?; stop_containers(&docker, "com.docker.compose.service=otel-collector").await?; let input = read_capture(&directory, "input.jsonl")?; let input_coverage = coverage(&input); @@ -313,7 +313,7 @@ async fn validate_demo() -> Result<(), String> { )); } let summary = format!( - "# OTel Demo trace validation\n\nDemo: 3.1.0; Vector ingress: {transport}\n\n```json\n{}\n```\n\n{}\n", + "# Multiservice OpenTelemetry trace validation\n\nDemo: 3.1.0; Vector ingress: {transport}\n\n```json\n{}\n```\n\n{}\n", serde_json::to_string_pretty(&input_coverage).unwrap(), if failures.is_empty() { "PASS: captured trace semantics and multiplicities match.".into() @@ -330,8 +330,8 @@ async fn validate_demo() -> Result<(), String> { } #[tokio::test] -async fn demo_trace_round_trip() { - validate_demo() +async fn trace_round_trip() { + validate_multiservice_traces() .await .unwrap_or_else(|error| panic!("{error}")); } From f0aa5baef2d9262acfb412a54366662c7d37125b Mon Sep 17 00:00:00 2001 From: Tess Neau Date: Wed, 7 Oct 2026 18:20:19 +0200 Subject: [PATCH 04/10] Use cart failure flag for multiservice trace errors --- .../opentelemetry-traces-multiservice/README.md | 9 ++++++--- .../data/demo.flagd.json | 2 +- .../data/scenario.py | 17 +++++------------ 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/tests/e2e/opentelemetry-traces-multiservice/README.md b/tests/e2e/opentelemetry-traces-multiservice/README.md index 2f95721deca8a..a098ebd672f31 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/README.md +++ b/tests/e2e/opentelemetry-traces-multiservice/README.md @@ -18,9 +18,12 @@ fixture-based trace tests. Trace and span counts in the diagram are examples from local runs, not assertions. [scenario.py](data/scenario.py) runs one simulated shopper through three rounds of ad, -recommendation, cart, and multi-item checkout requests, then a missing-product -request to generate errors. Checkout also exercises the Kafka accounting and -fraud-detection consumers. +recommendation, cart, and multi-item checkout requests. Checkout also exercises +the Kafka accounting and fraud-detection consumers. + +[demo.flagd.json](data/demo.flagd.json) uses the Demo's default flags except +`cartFailure: 100%`. This generates cart-emptying error spans while checkout +continues to email and Kafka. The [ingress Collector](data/collector-source.yaml) writes `input.jsonl` and forwards traces to Vector. The [matrix](config/test.yaml) runs each transport diff --git a/tests/e2e/opentelemetry-traces-multiservice/data/demo.flagd.json b/tests/e2e/opentelemetry-traces-multiservice/data/demo.flagd.json index 1b8ab340b2d27..c1227a3748ea8 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/data/demo.flagd.json +++ b/tests/e2e/opentelemetry-traces-multiservice/data/demo.flagd.json @@ -48,7 +48,7 @@ } }, "cartFailure": { - "defaultVariant": "off", + "defaultVariant": "100%", "description": "Fail cart service n% of the time", "state": "ENABLED", "variants": { diff --git a/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py b/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py index 730be7df0af50..73570ee25403c 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py +++ b/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py @@ -1,4 +1,8 @@ -"""Bounded transactions using the pinned demo's instrumented Locust user.""" +"""Run a fixed workload using the demo's instrumented Locust user. + +Unlike the default random, continuous workload, this stops after three shopping +rounds and writes a completion marker so trace validation can start. +""" import os from pathlib import Path @@ -17,17 +21,6 @@ def transactions(self): self.view_cart() self.checkout_multi() - # The catalog's not-found RPC exercises real error spans without a fault flag. - with self.tracer.start_as_current_span("user_missing_product"): - with self.client.get( - "/api/products/vector-e2e-missing", catch_response=True - ) as response: - if response.status_code < 400: - response.failure("missing product unexpectedly succeeded") - self.environment.process_exit_code = 1 - else: - response.success() - trace.get_tracer_provider().shutdown() directory = Path("/output/opentelemetry-traces-multiservice") / os.environ["CONFIG_INGRESS_EXPORTER"] (directory / "workload-complete").touch() From d3d0e8bd973b7d7cc4bf33c0ecd7ff1ed4b3cdd2 Mon Sep 17 00:00:00 2001 From: Tess Neau Date: Thu, 8 Oct 2026 10:45:51 +0200 Subject: [PATCH 05/10] Allow more time for multiservice trace workload in CI --- .../e2e/opentelemetry-traces-multiservice/config/compose.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml index 233fa79fc6c11..7e3df27d2890c 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml @@ -711,7 +711,8 @@ services: - "--headless" - "--users=1" - "--spawn-rate=1" - - "--run-time=90s" + # cartFailure connection retries can be slow in CI. The scenario exits when done. + - "--run-time=15m" - "--stop-timeout=15" - DemoUser volumes: From bbecc34aa62c362db740af94acea9747c16b525f Mon Sep 17 00:00:00 2001 From: Tess Neau Date: Thu, 8 Oct 2026 19:02:29 +0200 Subject: [PATCH 06/10] test(opentelemetry): shorten multiservice trace workload runtime --- .../e2e/opentelemetry-traces-multiservice/config/compose.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml index 7e3df27d2890c..949557fc4c41e 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml @@ -711,8 +711,8 @@ services: - "--headless" - "--users=1" - "--spawn-rate=1" - # cartFailure connection retries can be slow in CI. The scenario exits when done. - - "--run-time=15m" + # The CI workload took about 5.5 minutes. Leave room for slower cartFailure retries. + - "--run-time=8m" - "--stop-timeout=15" - DemoUser volumes: From d67df6e1d33864ab39b67b0c49b6d87120f8c144 Mon Sep 17 00:00:00 2001 From: Tess Neau Date: Thu, 8 Oct 2026 19:05:33 +0200 Subject: [PATCH 07/10] fix(tests): fail quote readiness check on refused connections --- tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml index 949557fc4c41e..6271fba72a9fa 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml @@ -386,7 +386,7 @@ services: - CMD - php - "-r" - - fsockopen('localhost', 8090) or die('fail'); + - fsockopen('localhost', 8090) or exit(1); timeout: 5s interval: 5s retries: 20 From 300e9018038f9536ef200386064306b29fff17b8 Mon Sep 17 00:00:00 2001 From: Tess Neau Date: Fri, 9 Oct 2026 16:00:19 +0200 Subject: [PATCH 08/10] fix(tests): exit multiservice workload promptly and capture container states --- .../config/compose.yaml | 4 +-- .../data/scenario.py | 4 ++- vdev/src/testing/integration.rs | 28 +++++++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml index 6271fba72a9fa..f88b4493c4428 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml @@ -711,8 +711,8 @@ services: - "--headless" - "--users=1" - "--spawn-rate=1" - # The CI workload took about 5.5 minutes. Leave room for slower cartFailure retries. - - "--run-time=8m" + # Safety limit. The scenario exits after three shopping rounds. + - "--run-time=15m" - "--stop-timeout=15" - DemoUser volumes: diff --git a/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py b/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py index 73570ee25403c..3b70a4e7fef05 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py +++ b/tests/e2e/opentelemetry-traces-multiservice/data/scenario.py @@ -7,6 +7,7 @@ import os from pathlib import Path +import gevent from locust import task from locustfile import WebsiteUser from opentelemetry import trace @@ -24,7 +25,8 @@ def transactions(self): trace.get_tracer_provider().shutdown() directory = Path("/output/opentelemetry-traces-multiservice") / os.environ["CONFIG_INGRESS_EXPORTER"] (directory / "workload-complete").touch() - self.environment.runner.quit() + # Quit outside this user's task so stopping users can complete. + gevent.spawn(self.environment.runner.quit) # Locust adds inherited tasks during class creation, even when tasks = []. diff --git a/vdev/src/testing/integration.rs b/vdev/src/testing/integration.rs index 9fc9f39a8b0fe..367bb73654218 100644 --- a/vdev/src/testing/integration.rs +++ b/vdev/src/testing/integration.rs @@ -15,7 +15,7 @@ use crate::{ app::CommandExt as _, testing::{ build::ALL_INTEGRATIONS_FEATURE_FLAG, - docker::{CONTAINER_TOOL, DOCKER_SOCKET}, + docker::{CONTAINER_TOOL, DOCKER_SOCKET, docker_command}, }, utils::environment::{Environment, extract_present, rename_environment_keys}, }; @@ -25,7 +25,6 @@ const E2E_FEATURE_FLAG: &str = "all-e2e-tests"; /// Check if a Docker image exists locally fn docker_image_exists(image_name: &str) -> Result { - use crate::testing::docker::docker_command; let output = docker_command(["images", "--format", "{{.Repository}}:{{.Tag}}"]).check_output()?; Ok(output.lines().any(|line| line == image_name)) @@ -381,6 +380,11 @@ impl Compose { } fn logs(&self, environment: &Environment, project_name: &str) -> Result { + // Preserve exit and OOM details before cleanup removes the containers. + if let Err(error) = self.container_states(project_name) { + warn!("Failed to collect container states: {error}"); + } + let mut command = self.command(project_name); command.arg("logs"); command.envs(extract_present(environment)); @@ -389,6 +393,26 @@ impl Compose { .with_context(|| "Failed to collect compose logs") } + fn container_states(&self, project_name: &str) -> Result<()> { + let containers = docker_command([ + "ps", + "--all", + "--quiet", + "--filter", + &format!("label=com.docker.compose.project={project_name}"), + ]) + .check_output()?; + + if !containers.trim().is_empty() { + info!("Container states for compose project '{project_name}':"); + docker_command(["inspect", "--format", "{{.Name}} {{json .State}}"]) + .args(containers.split_whitespace()) + .check_run()?; + } + + Ok(()) + } + fn command(&self, project_name: &str) -> Command { let mut command = Command::new(CONTAINER_TOOL.clone()); command.arg("compose"); From f78f44467c113b96cc34f8f12b3488e12cd2bc88 Mon Sep 17 00:00:00 2001 From: Tess Neau Date: Fri, 9 Oct 2026 16:43:46 +0200 Subject: [PATCH 09/10] fix(tests): increase multiservice demo memory limits --- .../opentelemetry-traces-multiservice/config/compose.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml index f88b4493c4428..941fb17875874 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/config/compose.yaml @@ -24,7 +24,8 @@ services: options: max-file: "2" max-size: 5m - mem_limit: "314572800" + # The demo's 300 MiB limit caused OOM kills in CI. + mem_limit: "536870912" environment: - AD_PORT=9555 - AD_PROMETHEUS_PORT=9465 @@ -656,7 +657,8 @@ services: options: max-file: "2" max-size: 5m - mem_limit: "20971520" + # The demo's 20 MiB limit caused OOM kills in CI. + mem_limit: "67108864" environment: - OTEL_BSP_SCHEDULE_DELAY=1000 - OTEL_TRACES_SAMPLER=always_on From 6cf64848c078afee3d57b178a68e48ef6e09f1fd Mon Sep 17 00:00:00 2001 From: Tess Neau Date: Fri, 9 Oct 2026 18:02:12 +0200 Subject: [PATCH 10/10] chore(vdev): add opt-in build cache preservation --- .../config/test.yaml | 2 ++ vdev/src/testing/config.rs | 3 +++ vdev/src/testing/runner.rs | 16 +++++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/e2e/opentelemetry-traces-multiservice/config/test.yaml b/tests/e2e/opentelemetry-traces-multiservice/config/test.yaml index c563965beed21..f812e7e970750 100644 --- a/tests/e2e/opentelemetry-traces-multiservice/config/test.yaml +++ b/tests/e2e/opentelemetry-traces-multiservice/config/test.yaml @@ -5,6 +5,8 @@ test: e2e test_filter: "opentelemetry::multiservice_traces::" runner: + # Reuse compiled tests between HTTP and gRPC runs. Captures are still cleared. + preserve_build_cache: true needs_docker_socket: true volumes: opentelemetry_traces_multiservice_evidence: /output/opentelemetry-traces-multiservice diff --git a/vdev/src/testing/config.rs b/vdev/src/testing/config.rs index e7eaab7296899..ccb57afad938d 100644 --- a/vdev/src/testing/config.rs +++ b/vdev/src/testing/config.rs @@ -178,6 +178,9 @@ pub struct IntegrationRunnerConfig { /// The set of volumes that need to be mounted into the runner. #[serde(default)] pub volumes: BTreeMap, + /// Keep compiled artifacts in a separate volume so output cleanup preserves them. + #[serde(default)] + pub preserve_build_cache: bool, /// Does the test runner need access to the host's docker socket? #[serde(default)] pub needs_docker_socket: bool, diff --git a/vdev/src/testing/runner.rs b/vdev/src/testing/runner.rs index e47d1e025089e..9c81f7dd4f775 100644 --- a/vdev/src/testing/runner.rs +++ b/vdev/src/testing/runner.rs @@ -19,6 +19,7 @@ use crate::{ const MOUNT_PATH: &str = "/home/vector"; const TARGET_PATH: &str = "/home/target"; const VOLUME_TARGET: &str = "vector_target"; +const VOLUME_BUILD_CACHE: &str = "vector_build_cache"; const VOLUME_CARGO_GIT: &str = "vector_cargo_git"; const VOLUME_CARGO_REGISTRY: &str = "vector_cargo_registry"; const RUNNER_HOSTNAME: &str = "runner"; @@ -91,6 +92,8 @@ pub trait ContainerTestRunner: TestRunner { fn volumes(&self) -> Vec; + fn target_volume(&self) -> &str; + fn state(&self) -> Result { let mut command = docker_command(["ps", "-a", "--format", "{{.Names}} {{.State}}"]); let container_name = self.container_name(); @@ -150,6 +153,7 @@ pub trait ContainerTestRunner: TestRunner { let mut volumes = HashSet::new(); volumes.insert(VOLUME_TARGET); + volumes.insert(self.target_volume()); volumes.insert(VOLUME_CARGO_GIT); volumes.insert(VOLUME_CARGO_REGISTRY); for volume in command.check_output()?.lines() { @@ -230,7 +234,7 @@ pub trait ContainerTestRunner: TestRunner { "--volume", &format!("{}:{MOUNT_PATH}", app::path()), "--volume", - &format!("{VOLUME_TARGET}:{TARGET_PATH}"), + &format!("{}:{TARGET_PATH}", self.target_volume()), "--volume", &format!("{VOLUME_CARGO_GIT}:/usr/local/cargo/git"), "--volume", @@ -300,6 +304,7 @@ pub(super) struct IntegrationTestRunner { // The integration is None when compiling the runner image with the `all-integration-tests` feature. integration: Option, needs_docker_socket: bool, + preserve_build_cache: bool, network: Option, volumes: Vec, } @@ -327,6 +332,7 @@ impl IntegrationTestRunner { Ok(Self { integration, needs_docker_socket: config.needs_docker_socket, + preserve_build_cache: config.preserve_build_cache, network, volumes, }) @@ -403,6 +409,14 @@ impl ContainerTestRunner for IntegrationTestRunner { fn volumes(&self) -> Vec { self.volumes.clone() } + + fn target_volume(&self) -> &str { + if self.preserve_build_cache { + VOLUME_BUILD_CACHE + } else { + VOLUME_TARGET + } + } } pub struct LocalTestRunner;