From 60161f97c4ea00fac899ec060d3a24bec3a3c1eb Mon Sep 17 00:00:00 2001 From: Oleksandr Redko Date: Wed, 4 Mar 2026 18:20:31 +0200 Subject: [PATCH] refactor: replace uint64 and int32 with atomic types in tests (#7941) Because [atomic types](https://go.dev/doc/go1.19#atomic_types) are easier to use. --- .../otlp/otlplog/otlploggrpc/exporter_test.go | 6 +++--- .../otlp/otlplog/otlploghttp/exporter_test.go | 6 +++--- internal/global/trace_test.go | 12 +++++------ sdk/log/exporter_test.go | 21 ++++++++----------- sdk/metric/internal/aggregate/atomic_test.go | 6 +++--- sdk/metric/pipeline_registry_test.go | 12 +++++------ sdk/trace/trace_test.go | 6 +++--- 7 files changed, 33 insertions(+), 36 deletions(-) diff --git a/exporters/otlp/otlplog/otlploggrpc/exporter_test.go b/exporters/otlp/otlplog/otlploggrpc/exporter_test.go index 5c59af73d..d7de26eb9 100644 --- a/exporters/otlp/otlplog/otlploggrpc/exporter_test.go +++ b/exporters/otlp/otlplog/otlploggrpc/exporter_test.go @@ -124,7 +124,7 @@ func TestExporterConcurrentSafe(t *testing.T) { var wg sync.WaitGroup ctx, cancel := context.WithCancel(t.Context()) - runs := new(uint64) + var runs atomic.Uint64 for range goroutines { wg.Go(func() { r := make([]sdklog.Record, 1) @@ -135,13 +135,13 @@ func TestExporterConcurrentSafe(t *testing.T) { default: _ = e.Export(ctx, r) _ = e.ForceFlush(ctx) - atomic.AddUint64(runs, 1) + runs.Add(1) } } }) } - for atomic.LoadUint64(runs) == 0 { + for runs.Load() == 0 { runtime.Gosched() } diff --git a/exporters/otlp/otlplog/otlploghttp/exporter_test.go b/exporters/otlp/otlplog/otlploghttp/exporter_test.go index 84f814753..150587936 100644 --- a/exporters/otlp/otlplog/otlploghttp/exporter_test.go +++ b/exporters/otlp/otlplog/otlploghttp/exporter_test.go @@ -92,7 +92,7 @@ func TestExporterConcurrentSafe(t *testing.T) { var wg sync.WaitGroup ctx, cancel := context.WithCancel(t.Context()) - runs := new(uint64) + var runs atomic.Uint64 for range goroutines { wg.Go(func() { r := make([]log.Record, 1) @@ -103,13 +103,13 @@ func TestExporterConcurrentSafe(t *testing.T) { default: _ = e.Export(ctx, r) _ = e.ForceFlush(ctx) - atomic.AddUint64(runs, 1) + runs.Add(1) } } }) } - for atomic.LoadUint64(runs) == 0 { + for runs.Load() == 0 { runtime.Gosched() } diff --git a/internal/global/trace_test.go b/internal/global/trace_test.go index bd9768905..2a6fc701c 100644 --- a/internal/global/trace_test.go +++ b/internal/global/trace_test.go @@ -140,10 +140,10 @@ func TestTraceProviderDelegatesConcurrentSafe(t *testing.T) { <-time.After(100 * time.Millisecond) // Configure it with a spy. - called := int32(0) + var called atomic.Int32 SetTracerProvider(fnTracerProvider{ tracer: func(name string, _ ...trace.TracerOption) trace.Tracer { - newVal := atomic.AddInt32(&called, 1) + newVal := called.Add(1) assert.Equal(t, "abc", name) if newVal == 10 { // Signal the goroutine to finish. @@ -156,7 +156,7 @@ func TestTraceProviderDelegatesConcurrentSafe(t *testing.T) { // Wait for the go routine to finish <-done - assert.LessOrEqual(t, int32(10), atomic.LoadInt32(&called), "expected configured TraceProvider to be called") + assert.LessOrEqual(t, int32(10), called.Load(), "expected configured TraceProvider to be called") } func TestTracerDelegatesConcurrentSafe(t *testing.T) { @@ -184,13 +184,13 @@ func TestTracerDelegatesConcurrentSafe(t *testing.T) { <-time.After(100 * time.Millisecond) // Configure it with a spy. - called := int32(0) + var called atomic.Int32 SetTracerProvider(fnTracerProvider{ tracer: func(name string, _ ...trace.TracerOption) trace.Tracer { assert.Equal(t, "abc", name) return fnTracer{ start: func(ctx context.Context, spanName string, _ ...trace.SpanStartOption) (context.Context, trace.Span) { - newVal := atomic.AddInt32(&called, 1) + newVal := called.Add(1) assert.Equal(t, "name", spanName) if newVal == 10 { // Signal the goroutine to finish. @@ -205,7 +205,7 @@ func TestTracerDelegatesConcurrentSafe(t *testing.T) { // Wait for the go routine to finish <-done - assert.LessOrEqual(t, int32(10), atomic.LoadInt32(&called), "expected configured TraceProvider to be called") + assert.LessOrEqual(t, int32(10), called.Load(), "expected configured TraceProvider to be called") } func TestTraceProviderDelegatesSameInstance(t *testing.T) { diff --git a/sdk/log/exporter_test.go b/sdk/log/exporter_test.go index 352c55b7b..95de096b1 100644 --- a/sdk/log/exporter_test.go +++ b/sdk/log/exporter_test.go @@ -33,7 +33,7 @@ type testExporter struct { ExportTrigger chan struct{} // Counts of method calls. - exportN, shutdownN, forceFlushN *int32 + exportN, shutdownN, forceFlushN atomic.Int32 stopped atomic.Bool inputMu sync.Mutex @@ -43,11 +43,8 @@ type testExporter struct { func newTestExporter(err error) *testExporter { e := &testExporter{ - Err: err, - exportN: new(int32), - shutdownN: new(int32), - forceFlushN: new(int32), - input: make(chan instruction), + Err: err, + input: make(chan instruction), } e.done = run(e.input) @@ -81,7 +78,7 @@ func (e *testExporter) Records() [][]Record { } func (e *testExporter) Export(ctx context.Context, r []Record) error { - atomic.AddInt32(e.exportN, 1) + e.exportN.Add(1) if e.ExportTrigger != nil { select { case <-e.ExportTrigger: @@ -98,7 +95,7 @@ func (e *testExporter) Export(ctx context.Context, r []Record) error { } func (e *testExporter) ExportN() int { - return int(atomic.LoadInt32(e.exportN)) + return int(e.exportN.Load()) } func (e *testExporter) Stop() { @@ -113,21 +110,21 @@ func (e *testExporter) Stop() { } func (e *testExporter) Shutdown(context.Context) error { - atomic.AddInt32(e.shutdownN, 1) + e.shutdownN.Add(1) return e.Err } func (e *testExporter) ShutdownN() int { - return int(atomic.LoadInt32(e.shutdownN)) + return int(e.shutdownN.Load()) } func (e *testExporter) ForceFlush(context.Context) error { - atomic.AddInt32(e.forceFlushN, 1) + e.forceFlushN.Add(1) return e.Err } func (e *testExporter) ForceFlushN() int { - return int(atomic.LoadInt32(e.forceFlushN)) + return int(e.forceFlushN.Load()) } func TestChunker(t *testing.T) { diff --git a/sdk/metric/internal/aggregate/atomic_test.go b/sdk/metric/internal/aggregate/atomic_test.go index a395bee4c..9164cf2d1 100644 --- a/sdk/metric/internal/aggregate/atomic_test.go +++ b/sdk/metric/internal/aggregate/atomic_test.go @@ -78,12 +78,12 @@ func benchmarkAtomicCounter[N int64 | float64](b *testing.B) { func TestHotColdWaitGroupConcurrentSafe(t *testing.T) { var wg sync.WaitGroup hcwg := &hotColdWaitGroup{} - var data [2]uint64 + var data [2]atomic.Uint64 for range 5 { wg.Go(func() { hotIdx := hcwg.start() defer hcwg.done(hotIdx) - atomic.AddUint64(&data[hotIdx], 1) + data[hotIdx].Add(1) }) } for range 2 { @@ -92,7 +92,7 @@ func TestHotColdWaitGroupConcurrentSafe(t *testing.T) { // reading without using atomics should not panic since we are // reading from the cold element, and have waited for all writes to // finish. - t.Logf("read value %+v", data[readIdx]) + t.Logf("read value %+v", data[readIdx].Load()) }) } wg.Wait() diff --git a/sdk/metric/pipeline_registry_test.go b/sdk/metric/pipeline_registry_test.go index e7b3fb957..0287cc1b4 100644 --- a/sdk/metric/pipeline_registry_test.go +++ b/sdk/metric/pipeline_registry_test.go @@ -596,26 +596,26 @@ func TestPipelineRegistryCreateAggregatorsIncompatibleInstrument(t *testing.T) { type logCounter struct { logr.LogSink - errN uint32 - infoN uint32 + errN atomic.Uint32 + infoN atomic.Uint32 } func (l *logCounter) Info(level int, msg string, keysAndValues ...any) { - atomic.AddUint32(&l.infoN, 1) + l.infoN.Add(1) l.LogSink.Info(level, msg, keysAndValues...) } func (l *logCounter) InfoN() int { - return int(atomic.SwapUint32(&l.infoN, 0)) + return int(l.infoN.Swap(0)) } func (l *logCounter) Error(err error, msg string, keysAndValues ...any) { - atomic.AddUint32(&l.errN, 1) + l.errN.Add(1) l.LogSink.Error(err, msg, keysAndValues...) } func (l *logCounter) ErrorN() int { - return int(atomic.SwapUint32(&l.errN, 0)) + return int(l.errN.Swap(0)) } func TestResolveAggregatorsDuplicateErrors(t *testing.T) { diff --git a/sdk/trace/trace_test.go b/sdk/trace/trace_test.go index f05384e49..a0af6172f 100644 --- a/sdk/trace/trace_test.go +++ b/sdk/trace/trace_test.go @@ -1180,9 +1180,9 @@ func TestRecordingSpanRuntimeTracerTaskEnd(t *testing.T) { tp := NewTracerProvider(WithSampler(AlwaysSample())) tr := tp.Tracer("TestRecordingSpanRuntimeTracerTaskEnd") - var n uint64 + var n atomic.Uint64 executionTracerTaskEnd := func() { - atomic.AddUint64(&n, 1) + n.Add(1) } _, apiSpan := tr.Start(t.Context(), "foo") s, ok := apiSpan.(*recordingSpan) @@ -1193,7 +1193,7 @@ func TestRecordingSpanRuntimeTracerTaskEnd(t *testing.T) { s.executionTracerTaskEnd = executionTracerTaskEnd s.End() - if n != 1 { + if n.Load() != 1 { t.Error("recording span did not end runtime trace task") } }