Quick start
Generate the starter project with otel-test init and run its three tests.
Create a project
mkdir my-collector-tests && cd my-collector-tests
otel-test initotel-test v0.1.0
created ./otel-test.yaml
created ./collector.yaml
created ./fixtures/login-span.json
created ./fixtures/login-log.json
created ./fixtures/healthz-span.json
Next: run `otel-test test`Run the tests
otel-test testotel-test v0.1.0
Collector: v0.164.0
Config: collector.yaml
Tests: 3
✓ passwords are removed from spans
✓ passwords are removed from logs
✓ health checks are dropped
3 passed, 0 failed
Time: 8.50sThe first run downloads the Collector first. Each test starts its own Collector and observes it for the test's timeout (2 s in this project), so expect a few seconds per test.
Break something
Open collector.yaml and delete the rule that removes password:
processors:
attributes/redact:
actions:
- key: password
action: delete
- key: user.name
action: hashRun the tests again:
✗ passwords are removed from spans
✗ attribute password is absent
Expected: password absent from every span
Actual: 1 of 1 spans failed
span "POST /login" at otlp_http/backend: password = "hunter2" (item)
✗ passwords are removed from logs
✗ attribute password is absent
Expected: password absent from every log record
Actual: 1 of 1 log records failed
log record "login attempt" at otlp_http/backend: password = "hunter2" (item)
✓ health checks are dropped
1 passed, 2 failed
Time: 9.27s
error: 2 test(s) failedotel-test exits with code 1, so a CI job fails.
What init generated
The starter config is a production-style Collector config. It deletes passwords, hashes user names and drops health checks:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
attributes/redact:
actions:
- key: password
action: delete
- key: user.name
action: hash
filter/healthz:
error_mode: ignore
traces:
span:
- attributes["http.route"] == "/healthz"
batch:
timeout: 200ms
exporters:
otlp_http/backend:
endpoint: https://otlp.example.com
headers:
authorization: "Bearer ${env:BACKEND_TOKEN}"
service:
pipelines:
traces:
receivers: [otlp]
processors: [filter/healthz, attributes/redact, batch]
exporters: [otlp_http/backend]
logs:
receivers: [otlp]
processors: [attributes/redact, batch]
exporters: [otlp_http/backend]The tests:
collector: ./collector.yaml
defaults:
timeout: 2s
tests:
- name: passwords are removed from spans
input: fixtures/login-span.json
expect:
- attribute: password
absent: true
- attribute: http.route
equals: /login
- exporter: otlp_http/backend
count: 1
- name: passwords are removed from logs
input: fixtures/login-log.json
expect:
- attribute: password
absent: true
- attribute: user.name
matches: "[0-9a-f]{64}"
- name: health checks are dropped
input: fixtures/healthz-span.json
expect:
- dropped: trueBACKEND_TOKEN doesn't need to be set. Tracelet replaces the exporter, so its headers are never used.
init refuses to overwrite existing files. Pass --force to overwrite them, or give a directory:
otel-test init my-tests.
Next steps
- Write your first test against your own config.
- Run
otel-test validateto see how your config is rewritten. Seeotel-test validate. - Browse the examples.