obstest

package
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 3, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package obstest records what the library actually emits, so that a spec can assert on a signal rather than on a method having been called.

It exists because two exit criteria — the metric set flowing, and one trace spanning receive through send — rested on no-op providers, which exercise every call site and assert nothing about the result. A no-op provider cannot distinguish "the counter was incremented with the right name and labels" from "a method was called".

Why this is hand-written rather than the OpenTelemetry SDK

The SDK has a manual reader and a span recorder built for exactly this, and using them would cost a consumer five modules in their build list: the SDK, the metric SDK, an experimental metric package, google/uuid and goleak. The testing frameworks this project mandates already put sixteen unlinked modules into a consumer's graph, which the dependency ledger discloses rather than hides, and adding five more for an assertion this size is a poor trade.

The cost of writing it instead is small because the OpenTelemetry API ships no-op implementations designed to be embedded: each type below embeds the no-op and overrides only the handful of methods a spec reads. New API methods therefore arrive as no-ops rather than as build failures, which is the right default for a recorder.

Nothing here is a general-purpose OpenTelemetry implementation. It records what was emitted, in order, with attributes flattened to strings, and it is safe for concurrent use because the library emits from several goroutines.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Measurement

type Measurement struct {
	// Instrument is the metric name, exactly as the library registered it.
	Instrument string
	// Value is the amount added or recorded.
	Value float64
	// Attrs are the observation's attributes, flattened to strings so a spec
	// can compare them without reproducing OpenTelemetry's value model.
	Attrs map[string]string
}

Measurement is one recorded observation.

func (Measurement) Attr

func (m Measurement) Attr(key string) string

Attr returns one attribute's value, or the empty string.

type Metrics

type Metrics struct {
	embedded.MeterProvider
	// contains filtered or unexported fields
}

Metrics is a metric.MeterProvider that records every observation.

func NewMetrics

func NewMetrics() *Metrics

NewMetrics returns a recording meter provider.

func (*Metrics) All

func (m *Metrics) All() []Measurement

All returns every observation, in the order it was recorded.

func (*Metrics) Meter

func (m *Metrics) Meter(name string, options ...metric.MeterOption) metric.Meter

Meter returns a recording meter. The name is ignored: this library uses one.

func (*Metrics) Observations

func (m *Metrics) Observations(instrument string) []Measurement

Observations returns the observations of one instrument.

func (*Metrics) Registered

func (m *Metrics) Registered() []string

Registered reports every instrument name the library created, sorted. It is what a spec asserts the catalogue against: an instrument that is never created cannot ever be emitted, and that failure is silent at runtime.

func (*Metrics) Total

func (m *Metrics) Total(instrument string) float64

Total sums one instrument's observations, which is what a counter means.

type Span

type Span struct {
	// Name is the span name as the library asked for it.
	Name string

	// TraceID and SpanID are the recorded identity. They are minted by this
	// package's own provider, so a spec can assert two spans share a trace.
	TraceID trace.TraceID

	// SpanID identifies this span within TraceID.
	SpanID trace.SpanID

	// ParentID is the enclosing span, zero for a root. It is what a spec
	// asserting on span structure reads.
	ParentID trace.SpanID
	// Attrs are the span's attributes, flattened to strings.
	Attrs map[string]string
	// Links are the span contexts this span was linked to, which is how a
	// client's morph timing rejoins the trace that produced the patch.
	Links []trace.SpanContext

	// Ended reports whether End was called. A span recorded but never ended is
	// a leak the library would otherwise ship silently, so it is observable
	// here rather than inferred.
	Ended bool
}

Span is one recorded span.

func (Span) Attr

func (s Span) Attr(key string) string

Attr returns one attribute's value, or the empty string.

type Traces

type Traces struct {
	traceembedded.TracerProvider
	// contains filtered or unexported fields
}

Traces is a trace.TracerProvider that records every span.

func NewTraces

func NewTraces() *Traces

NewTraces returns a recording tracer provider. Every span it creates shares one trace identifier, because this library is the trace root and the property under test is that one trace spans the whole path.

func (*Traces) Describe

func (t *Traces) Describe() string

Describe renders the recorded spans for a failure message, because a trace assertion that fails without saying what was recorded costs a rerun.

func (*Traces) Named

func (t *Traces) Named(name string) []Span

Named returns the spans with one name.

func (*Traces) Names

func (t *Traces) Names() []string

Names returns every span name recorded, in creation order and with duplicates removed.

func (*Traces) Spans

func (t *Traces) Spans() []Span

Spans returns every span created, in creation order.

func (*Traces) Tracer

func (t *Traces) Tracer(name string, options ...trace.TracerOption) trace.Tracer

Tracer returns a recording tracer. The name is ignored: this library uses one.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL