github.com/waldiirawan/apm-agent-go/v2@v2.2.2/sampler_test.go (about) 1 // Licensed to Elasticsearch B.V. under one or more contributor 2 // license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright 4 // ownership. Elasticsearch B.V. licenses this file to you under 5 // the Apache License, Version 2.0 (the "License"); you may 6 // not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 package apm_test 19 20 import ( 21 "encoding/binary" 22 "math/rand" 23 "sync" 24 "testing" 25 26 "github.com/stretchr/testify/assert" 27 28 "github.com/waldiirawan/apm-agent-go/v2" 29 ) 30 31 func TestRatioSampler(t *testing.T) { 32 ratio := 0.75 33 s := apm.NewRatioSampler(ratio) 34 35 const ( 36 numGoroutines = 100 37 numIterations = 1000 38 ) 39 40 sampled := make([]int, numGoroutines) 41 var wg sync.WaitGroup 42 for i := 0; i < numGoroutines; i++ { 43 wg.Add(1) 44 go func(i int) { 45 defer wg.Done() 46 47 // fixed seed to avoid intermittent failures 48 rng := rand.New(rand.NewSource(int64(i))) 49 for j := 0; j < numIterations; j++ { 50 var traceContext apm.TraceContext 51 binary.LittleEndian.PutUint64(traceContext.Span[:], rng.Uint64()) 52 result := s.Sample(apm.SampleParams{TraceContext: traceContext}) 53 assert.Equal(t, ratio, result.SampleRate) 54 if result.Sampled { 55 sampled[i]++ 56 } 57 } 58 59 }(i) 60 } 61 wg.Wait() 62 63 var total int 64 for i := 0; i < numGoroutines; i++ { 65 total += sampled[i] 66 } 67 assert.InDelta(t, ratio, float64(total)/(numGoroutines*numIterations), 0.1) 68 } 69 70 func TestRatioSamplerAlways(t *testing.T) { 71 s := apm.NewRatioSampler(1.0) 72 assert.False(t, s.Sample(apm.SampleParams{TraceContext: apm.TraceContext{}}).Sampled) // invalid span ID 73 assert.True(t, s.Sample(apm.SampleParams{TraceContext: apm.TraceContext{ 74 Span: apm.SpanID{0, 0, 0, 0, 0, 0, 0, 1}, 75 }}).Sampled) 76 assert.True(t, s.Sample(apm.SampleParams{TraceContext: apm.TraceContext{ 77 Span: apm.SpanID{255, 255, 255, 255, 255, 255, 255, 255}, 78 }}).Sampled) 79 } 80 81 func TestRatioSamplerNever(t *testing.T) { 82 s := apm.NewRatioSampler(0) 83 assert.False(t, s.Sample(apm.SampleParams{TraceContext: apm.TraceContext{}}).Sampled) // invalid span ID 84 assert.False(t, s.Sample(apm.SampleParams{TraceContext: apm.TraceContext{ 85 Span: apm.SpanID{0, 0, 0, 0, 0, 0, 0, 1}, 86 }}).Sampled) 87 assert.False(t, s.Sample(apm.SampleParams{TraceContext: apm.TraceContext{ 88 Span: apm.SpanID{255, 255, 255, 255, 255, 255, 255, 255}, 89 }}).Sampled) 90 } 91 92 func TestRatioSamplerPrecision(t *testing.T) { 93 ratios := map[float64]float64{ 94 0.00001: 0.0001, 95 0.55554: 0.5555, 96 0.55555: 0.5556, 97 0.55556: 0.5556, 98 } 99 for r, want := range ratios { 100 s := apm.NewRatioSampler(r) 101 got := s.Sample(apm.SampleParams{}).SampleRate 102 assert.Equal(t, want, got) 103 } 104 }