github.com/instana/go-sensor@v1.62.2-0.20240520081010-4919868049e1/delayed_spans_test.go (about) 1 // (c) Copyright IBM Corp. 2022 2 3 package instana 4 5 import ( 6 "context" 7 "fmt" 8 "net/http" 9 "net/http/httptest" 10 "sync" 11 "sync/atomic" 12 "testing" 13 14 "github.com/instana/go-sensor/acceptor" 15 "github.com/instana/go-sensor/autoprofile" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 func TestAppendALotDelayedSpans(t *testing.T) { 20 ds := &delayedSpans{ 21 spans: make(chan *spanS, maxDelayedSpans), 22 } 23 24 i := 0 25 for i <= 2*maxDelayedSpans { 26 ds.append(&spanS{}) 27 i++ 28 } 29 30 assert.Len(t, ds.spans, maxDelayedSpans) 31 } 32 33 func resetDelayedSpans() { 34 delayed = &delayedSpans{ 35 spans: make(chan *spanS, maxDelayedSpans), 36 } 37 } 38 39 func TestPartiallyFlushDelayedSpans(t *testing.T) { 40 defer resetDelayedSpans() 41 42 recorder := NewTestRecorder() 43 s := NewSensorWithTracer(NewTracerWithEverything(&Options{ 44 Service: "go-sensor-test", 45 Tracer: TracerOptions{ 46 Secrets: DefaultSecretsMatcher(), 47 }, 48 }, recorder)) 49 defer ShutdownSensor() 50 51 generateSomeTraffic(s, maxDelayedSpans) 52 53 assert.Len(t, delayed.spans, maxDelayedSpans) 54 55 notReadyAfter := maxDelayedSpans / 10 56 sensor.agent = &eventuallyNotReadyClient{ 57 notReadyAfter: uint64(notReadyAfter), 58 } 59 60 delayed.flush() 61 62 assert.Len(t, delayed.spans, maxDelayedSpans-notReadyAfter) 63 } 64 65 func TestFlushDelayedSpans(t *testing.T) { 66 defer resetDelayedSpans() 67 68 recorder := NewTestRecorder() 69 s := NewSensorWithTracer(NewTracerWithEverything(&Options{ 70 Service: "go-sensor-test", 71 Tracer: TracerOptions{ 72 Secrets: DefaultSecretsMatcher(), 73 }, 74 }, recorder)) 75 defer ShutdownSensor() 76 77 generateSomeTraffic(s, maxDelayedSpans) 78 79 assert.Len(t, delayed.spans, maxDelayedSpans) 80 81 sensor.agent = alwaysReadyClient{} 82 83 delayed.flush() 84 85 assert.Len(t, delayed.spans, 0) 86 } 87 88 func TestParallelFlushDelayedSpans(t *testing.T) { 89 defer resetDelayedSpans() 90 91 m, _ := NamedMatcher(ContainsIgnoreCaseMatcher, []string{"q", "secret"}) 92 93 recorder := NewTestRecorder() 94 s := NewSensorWithTracer(NewTracerWithEverything(&Options{ 95 Service: "go-sensor-test", 96 Tracer: TracerOptions{ 97 Secrets: m, 98 }, 99 }, recorder)) 100 defer ShutdownSensor() 101 102 generateSomeTraffic(s, maxDelayedSpans*2) 103 104 assert.Len(t, delayed.spans, maxDelayedSpans) 105 106 workers := 15 107 worker := 0 108 wg := sync.WaitGroup{} 109 wg.Add(workers) 110 111 sensor.agent = alwaysReadyClient{} 112 113 for worker < workers { 114 go func() { 115 delayed.flush() 116 wg.Done() 117 }() 118 worker++ 119 } 120 121 wg.Wait() 122 123 recordedSpans := recorder.GetQueuedSpans() 124 assert.Equal(t, maxDelayedSpans, len(recordedSpans)) 125 126 for _, v := range recordedSpans { 127 if v, ok := v.Data.(HTTPSpanData); ok { 128 assert.Equal(t, "q=%3Credacted%3E&secret=%3Credacted%3E", v.Tags.Params) 129 } else { 130 assert.Fail(t, "wrong span type") 131 } 132 } 133 } 134 135 type eventuallyNotReadyClient struct { 136 notReadyAfter uint64 137 ops uint64 138 } 139 140 func (e *eventuallyNotReadyClient) Ready() bool { 141 n := atomic.AddUint64(&e.ops, 1) 142 return n <= e.notReadyAfter 143 } 144 145 func (*eventuallyNotReadyClient) SendMetrics(data acceptor.Metrics) error { return nil } 146 func (*eventuallyNotReadyClient) SendEvent(event *EventData) error { return nil } 147 func (*eventuallyNotReadyClient) SendSpans(spans []Span) error { return nil } 148 func (*eventuallyNotReadyClient) SendProfiles(profiles []autoprofile.Profile) error { return nil } 149 func (*eventuallyNotReadyClient) Flush(context.Context) error { return nil } 150 151 func generateSomeTraffic(s TracerLogger, amount int) { 152 h := TracingNamedHandlerFunc(s, "action", "/{action}", func(w http.ResponseWriter, req *http.Request) { 153 fmt.Fprintln(w, "Ok") 154 }) 155 156 req := httptest.NewRequest(http.MethodGet, "/test?q=term&secret=mypassword", nil) 157 158 rec := httptest.NewRecorder() 159 160 for i := 0; i < amount; i++ { 161 h.ServeHTTP(rec, req) 162 } 163 }