Trace-based tests

Embed
Preview of the card
<a href="https://forumulate.com/p/watchtower/docs/trace-tests"><img src="https://forumulate.com/api/public/orgs/watchtower/spaces/docs/pages/86974397-2736-4ee4-b38b-399b830d21ee/social-card.svg?v=3e7ae33eec8b" alt="Trace-based tests" width="600" height="315"></a>

A trace test calls your service, then asserts on the response and on the spans the call produced. The runner sends a W3C traceparent it generated, so it knows the trace id, waits until the trace can be queried (poll every 2 s, up to wait_for_trace_s, default 30), and evaluates each trace selector with the trace query language.

Spec

{
  "trigger": {"http": {"method": "POST", "url": "https://shop.example/buy", "headers": {}, "body": ""}},
  "variables": {"env": "prod", "order": {"from_response": "[BODY].id"}},
  "wait_for_trace_s": 30,
  "assertions": [
    {"on": "response", "status": 200, "jsonpath": {"$.id": "abc"}},
    {"on": "trace", "selector": "{ resource.service.name = \"db\" && duration > 100ms }",
     "expect": {"count_gte": 1}}
  ]
}
  • {{var.NAME}} is replaced in the trigger and in selectors. Literal variables exist from the start; from_response ones (any [BODY], [HEADER] placeholder path) after the trigger answered.

  • expect takes one of count_gte, count_eq (0 means "no such span"), max_duration_ms (every matched span), attr: {key, eq} (some matched span has that attribute value).

  • Only HTTP triggers run today; trigger.grpc is rejected.

  • A selector that matches more than 100 traces in the last minute can hide the test's own trace.

Triggers

  • Manual: POST /v1/projects/{p}/trace-tests/{id}/runs, or a suite: POST …/trace-test-suites/{id}/runs.

  • Schedule: a monitor of kind trace_test with the spec as its config, so locations, retries, alerts, history and private probes apply. Public locations refuse private targets.

  • CI: wtctl test run --suite <id> --wait --junit out.xml exits 0 (all passed), 1 (a test failed) or 2 (could not start or finish). The JUnit file has one case per assertion and can be uploaded with wtctl ci upload-junit.

Runs: GET …/trace-test-runs?ref= (a suite run's ref), GET …/trace-test-runs/{id}.

Updated