Conversation
Adds three packages for converting Go test results to OTel spans: - gotest: streaming go test -json to OTel span converter - gotestmain: TestMain helper for in-process instrumentation - cmd/otelgotest: go test -exec wrapper for zero-config use Each test becomes a span with subtest nesting, pass/fail/skip status, log output as span events, and optional OTel log record routing via SpanStdio. When no OTLP endpoint is configured, tests run with no overhead. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Adds a junit package that parses JUnit XML via go-junit and emits OTel spans mirroring the suite/test hierarchy. Each suite becomes a parent span with child spans per test case, carrying pass/fail/skip status, test output as span events, and optional log records via SpanStdio. The cmd/oteljunit CLI reads JUnit XML from files or stdin and exports the spans to the configured OTLP endpoint. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Replace the hand-crafted JUnit XML with output from go-junit-report run against the sample test suite. Adjust tests to match the real format: empty suite name (falls back to "suite"), generic failure messages, no per-test system-out, flat subtest names. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Add go:generate directive that pipes gotest/testdata/sample.jsonl through go-junit-report to produce the JUnit XML fixture. Track go-junit-report as a tool dependency in go.mod. The JSON parser produces richer output than piping raw test output: suite names, classnames, per-test system-out, and failure bodies are all populated. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Add the sample test source to gotest/testdata/sample/ and a go:generate directive that runs it with go test -json to produce sample.jsonl. The JUnit fixture chains from the same source: go generate ./gotest/ # sample_test.go -> sample.jsonl go generate ./junit/ # sample.jsonl -> sample.xml Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Stop splitting test names on '/' for span names since JUnit can't express hierarchy anyway. Parse the timestamp attribute from the testsuite XML element to set proper start/end times on spans instead of calculating backwards from time.Now(). Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Handle package-level JSON events (start/pass/fail) to create a parent span per package instead of emitting all test spans at the top level. Top-level tests are parented under their package span, subtests remain nested under their parent test. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Add a Unix socket sideband so that test binaries using oteltestctx can adopt span contexts created by otelgotest. When otelgotest creates a test span from JSON events, it registers the span context in a SpanContextRegistry. A socket server responds to requests from the test binary with the traceparent for each test. This lets in-process instrumented operations (e.g. Dagger calls) descend from the externally created test span without any configuration flags. Also fixes otelgotest package detection to use the full import path by walking up to go.mod from the working directory. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Move the oteltest middleware into this repo as oteltestctx so it can share types with gotest and evolve the socket protocol without a circular dependency. WithTracing checks OTEL_TEST_SOCKET and adopts the external span context when available, falling back to local span creation. The socket is skipped when a custom TracerProvider is provided (e.g. unit tests with span recorders). Subprocess tests clear the env var to avoid connecting to the parent's socket. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Apply the same testify error message cleaning used in oteltestctx to gotest's extractErrorOutput. Strips verbose Error Trace and Test sections, keeping only the Error and Messages content for the span status description. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Verify that testify-formatted error messages in test2json output are cleaned to just the Error/Messages content for span status descriptions, both standalone and mixed with regular log noise. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Go's testing.decorate adds 4 spaces of indentation to continuation lines of multi-line error messages. This caused cleanTestifyMessage to miss the tab-prefixed testify sections since lines started with spaces instead of tabs. Strip leading spaces before checking for the tab pattern. Updated integration tests to use the realistic format with the 4-space prefix. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Replace the go test -exec wrapper with a drop-in go test replacement that runs go test -json internally. This preserves test caching, which the -exec approach unconditionally invalidated. The socket protocol for cross-process span context propagation now uses package-qualified keys (e.g., "example.com/pkg/TestFoo") so that a single shared socket works across all packages without collisions. The oteltestctx package auto-detects its package path at init time via debug.ReadBuildInfo. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Packages with no test files emit a skip action at the package level. The span is started but never ended because there is no handler for the skip case. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Packages with no test files emit a skip action at the package level. Handle it by ending the span with the skipped status. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Remove AddEvent from gotest and junit — SpanStdio is the sole OTel log mechanism. Remove WithLogging from oteltestctx — gotest.Run handles test output logging externally. Previously each output line generated a span event, a SpanStdio log record from gotest.Run, and another SpanStdio log record from WithLogging, tripling OTel updates and causing O(N²) rendering in Dagger's progress view. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
go test -json always forces -test.v=test2json, making testing.Verbose() return true. While we can't change that, we can control the reconstructed human-readable output. In non-verbose mode (the default), per-test output is buffered and only flushed for failing tests. Package-level output passes through unconditionally. otelgotest now detects -v in user args and sets WithVerbose accordingly. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
go test and JUnit OpenTelemetry emittinggo test & JUnit OpenTelemetry emitting
Keep a leading go -C flag ahead of the injected -json flag so commands like otelgotest -C ./foo/bar ./... translate to a valid go test invocation. Add unit coverage for both -C forms and the existing non--C behavior. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
Derive test hierarchy from go test -json run, pause, cont, and completion events instead of splitting ev.Test on '/'. This keeps slash-containing leaf names attached to their real parents and avoids misparenting ambiguous or interleaved parallel subtests. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
When users pass -json, keep printing the raw go test JSON stream to stdout while still parsing it for spans. This preserves the requested output mode the same way we already handle -v. Signed-off-by: Alex Suraci <suraci.alex@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds two CLIs:
./cmd/otelgotest: a drop-ingo testreplacement that emits test data to OpenTelemetryotelgotest ./...(same flags asgo test, just passes through)./cmd/oteljunit: loads JUnit XML and re-emits it to OpenTelemetryoteljunit report.xmlAnd a handful of packages:
./oteltestctx: replacesgithub.com/dagger/testctx/oteltestand coordinates withotelgotestvia a Unix domain socket to propagateotelgotest-created span context down into each test'scontext.Context./gotest: reads ago test -jsonstream and re-emits it to OTel (logic behindotelgotest)./gotestmain: provides aTestMainwrapper that wires up OTel, mostly redundant but doesn't hurt to have as an option./junit: logic behindoteljunit