From 0c2be8b884ac364fa381b198a724571321a60b63 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Mon, 9 Sep 2019 19:08:08 +0200 Subject: [PATCH] add another failing test that shows "data loss" in go context --- experimental/bridge/opentracing/mix_test.go | 92 +++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/experimental/bridge/opentracing/mix_test.go b/experimental/bridge/opentracing/mix_test.go index 46bb3e7c2fb2..37203cd96bde 100644 --- a/experimental/bridge/opentracing/mix_test.go +++ b/experimental/bridge/opentracing/mix_test.go @@ -25,6 +25,8 @@ type mixedAPIsTestCase struct { func getMixedAPIsTestCases() []mixedAPIsTestCase { st := newSimpleTest() cast := newCurrentActiveSpanTest() + coin := newContextIntactTest() + return []mixedAPIsTestCase{ { desc: "simple otel -> ot -> otel", @@ -50,6 +52,18 @@ func getMixedAPIsTestCases() []mixedAPIsTestCase { run: cast.runOTOtelOT, check: cast.check, }, + { + desc: "context intact otel -> ot -> otel", + setup: coin.setup, + run: coin.runOtelOTOtel, + check: coin.check, + }, + { + desc: "context intact ot -> otel -> ot", + setup: coin.setup, + run: coin.runOTOtelOT, + check: coin.check, + }, } } @@ -160,6 +174,84 @@ func (cast *currentActiveSpanTest) recordSpans(ctx context.Context) { cast.recordedActiveOTSpanIDs = append(cast.recordedActiveOTSpanIDs, spanID) } +type contextIntactTest struct { + contextKeyValues []internal.MockContextKeyValue + + recordedContextValues []interface{} + recordIdx int +} + +type coin1Key struct{} + +type coin1Value struct{} + +type coin2Key struct{} + +type coin2Value struct{} + +type coin3Key struct{} + +type coin3Value struct{} + +func newContextIntactTest() *contextIntactTest { + return &contextIntactTest{ + contextKeyValues: []internal.MockContextKeyValue{ + internal.MockContextKeyValue{ + Key: coin1Key{}, + Value: coin1Value{}, + }, + internal.MockContextKeyValue{ + Key: coin2Key{}, + Value: coin2Value{}, + }, + internal.MockContextKeyValue{ + Key: coin3Key{}, + Value: coin3Value{}, + }, + }, + } +} + +func (coin *contextIntactTest) setup(t *testing.T, tracer *internal.MockTracer) { + tracer.SpareContextKeyValues = append(tracer.SpareContextKeyValues, coin.contextKeyValues...) + + coin.recordedContextValues = nil + coin.recordIdx = 0 +} + +func (coin *contextIntactTest) check(t *testing.T, tracer *internal.MockTracer) { + if len(coin.recordedContextValues) != len(coin.contextKeyValues) { + t.Errorf("Expected to have %d recorded context values, got %d", len(coin.contextKeyValues), len(coin.recordedContextValues)) + } + + minLen := min(len(coin.recordedContextValues), len(coin.contextKeyValues)) + for i := 0; i < minLen; i++ { + key := coin.contextKeyValues[i].Key + value := coin.contextKeyValues[i].Value + gotValue := coin.recordedContextValues[i] + if value != gotValue { + t.Errorf("Expected value %#v for key %#v, got %#v", value, key, gotValue) + } + } +} + +func (coin *contextIntactTest) runOtelOTOtel(t *testing.T, ctx context.Context) { + runOtelOTOtel(t, ctx, "coin", coin.recordValue) +} + +func (coin *contextIntactTest) runOTOtelOT(t *testing.T, ctx context.Context) { + runOTOtelOT(t, ctx, "coin", coin.recordValue) +} + +func (coin *contextIntactTest) recordValue(ctx context.Context) { + if coin.recordIdx >= len(coin.contextKeyValues) { + return + } + key := coin.contextKeyValues[coin.recordIdx].Key + coin.recordIdx++ + coin.recordedContextValues = append(coin.recordedContextValues, ctx.Value(key)) +} + func checkTraceAndSpans(t *testing.T, tracer *internal.MockTracer, expectedTraceID otelcore.TraceID, expectedSpanIDs []uint64) { expectedSpanCount := len(expectedSpanIDs)