git.colasdn.top/newrelic/go-agent@v3.26.0+incompatible/internal/adaptive_sampler_test.go (about)

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package internal
     5  
     6  import (
     7  	"testing"
     8  	"time"
     9  )
    10  
    11  func assert(t testing.TB, expectTrue bool) {
    12  	if h, ok := t.(interface {
    13  		Helper()
    14  	}); ok {
    15  		h.Helper()
    16  	}
    17  	if !expectTrue {
    18  		t.Error(expectTrue)
    19  	}
    20  }
    21  
    22  func TestDefaultReplyValidSampler(t *testing.T) {
    23  	reply := ConnectReplyDefaults()
    24  	assert(t, !reply.AdaptiveSampler.ComputeSampled(1.0, time.Now()))
    25  }
    26  
    27  func TestAdaptiveSampler(t *testing.T) {
    28  	start := time.Now()
    29  	sampler := NewAdaptiveSampler(60*time.Second, 2, start)
    30  
    31  	// first period -- we're guaranteed to get 2 sampled
    32  	// due to our target, and we'll send through a total of 4
    33  	assert(t, sampler.ComputeSampled(0.0, start))
    34  	assert(t, sampler.ComputeSampled(0.0, start))
    35  	sampler.ComputeSampled(0.0, start)
    36  	sampler.ComputeSampled(0.0, start)
    37  
    38  	// Next period!  4 calls in the last period means a new sample ratio
    39  	// of 1/2.  Nothing with a priority less than the ratio will get through
    40  	now := start.Add(61 * time.Second)
    41  	assert(t, !sampler.ComputeSampled(0.0, now))
    42  	assert(t, !sampler.ComputeSampled(0.0, now))
    43  	assert(t, !sampler.ComputeSampled(0.0, now))
    44  	assert(t, !sampler.ComputeSampled(0.0, now))
    45  	assert(t, !sampler.ComputeSampled(0.49, now))
    46  	assert(t, !sampler.ComputeSampled(0.49, now))
    47  
    48  	// but these two will get through, and we'll still be under
    49  	// our target rate so there's no random sampling to deal with
    50  	assert(t, sampler.ComputeSampled(0.55, now))
    51  	assert(t, sampler.ComputeSampled(1.0, now))
    52  
    53  	// Next period!  8 calls in the last period means a new sample ratio
    54  	// of 1/4.
    55  	now = start.Add(121 * time.Second)
    56  	assert(t, !sampler.ComputeSampled(0.0, now))
    57  	assert(t, !sampler.ComputeSampled(0.5, now))
    58  	assert(t, !sampler.ComputeSampled(0.7, now))
    59  	assert(t, sampler.ComputeSampled(0.8, now))
    60  }
    61  
    62  func TestAdaptiveSamplerSkipPeriod(t *testing.T) {
    63  	start := time.Now()
    64  	sampler := NewAdaptiveSampler(60*time.Second, 2, start)
    65  
    66  	// same as the previous test, we know we can get two through
    67  	// and we'll send a total of 4 through
    68  	assert(t, sampler.ComputeSampled(0.0, start))
    69  	assert(t, sampler.ComputeSampled(0.0, start))
    70  	sampler.ComputeSampled(0.0, start)
    71  	sampler.ComputeSampled(0.0, start)
    72  
    73  	// Two periods later!  Since there was a period with no samples, priorityMin
    74  	// should be zero
    75  
    76  	now := start.Add(121 * time.Second)
    77  	assert(t, sampler.ComputeSampled(0.0, now))
    78  	assert(t, sampler.ComputeSampled(0.0, now))
    79  }
    80  
    81  func TestAdaptiveSamplerTarget(t *testing.T) {
    82  	var target uint64
    83  	target = 20
    84  	start := time.Now()
    85  	sampler := NewAdaptiveSampler(60*time.Second, target, start)
    86  
    87  	// we should always sample up to the number of target events
    88  	for i := 0; uint64(i) < target; i++ {
    89  		assert(t, sampler.ComputeSampled(0.0, start))
    90  	}
    91  
    92  	// but now further calls to ComputeSampled are subject to exponential backoff.
    93  	// this means their sampling is subject to a bit of randomness and we have no
    94  	// guarantee of a true or false sample, just an increasing unlikeliness that
    95  	// things will be sampled
    96  }