github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/lib/queueinformer/jitter_test.go (about)

     1  package queueinformer
     2  
     3  import (
     4  	"math"
     5  	"math/rand"
     6  	"reflect"
     7  	"testing"
     8  	"testing/quick"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  type fakeFloat64er float64
    15  
    16  func (f fakeFloat64er) Float64() float64 {
    17  	return float64(f)
    18  }
    19  
    20  func TestResyncWithJitter(t *testing.T) {
    21  	type args struct {
    22  		resyncPeriod time.Duration
    23  		factor       float64
    24  		r            float64
    25  	}
    26  	tests := []struct {
    27  		name string
    28  		args args
    29  		want time.Duration
    30  	}{
    31  		{
    32  			name: "TypicalInput/15Minutes/Min",
    33  			args: args{
    34  				resyncPeriod: 15 * time.Minute,
    35  				factor:       0.2,
    36  				r:            0,
    37  			},
    38  			want: 12 * time.Minute,
    39  		},
    40  		{
    41  			name: "TypicalInput/15Minutes/Mid",
    42  			args: args{
    43  				resyncPeriod: 15 * time.Minute,
    44  				factor:       0.2,
    45  				r:            0.5,
    46  			},
    47  			want: 15 * time.Minute,
    48  		},
    49  		{
    50  			name: "TypicalInput/15Minutes/Max",
    51  			args: args{
    52  				resyncPeriod: 15 * time.Minute,
    53  				factor:       0.2,
    54  				r:            1,
    55  			},
    56  			want: 18 * time.Minute,
    57  		},
    58  		{
    59  			name: "TypicalInput/10Hours/Min",
    60  			args: args{
    61  				resyncPeriod: 10 * time.Hour,
    62  				factor:       0.1,
    63  				r:            0,
    64  			},
    65  			want: 9 * time.Hour,
    66  		},
    67  		{
    68  			name: "TypicalInput/10Hours/Mid",
    69  			args: args{
    70  				resyncPeriod: 10 * time.Hour,
    71  				factor:       0.1,
    72  				r:            0.5,
    73  			},
    74  			want: 10 * time.Hour,
    75  		},
    76  		{
    77  			name: "TypicalInput/10Hours/Max",
    78  			args: args{
    79  				resyncPeriod: 10 * time.Hour,
    80  				factor:       0.1,
    81  				r:            1,
    82  			},
    83  			want: 11 * time.Hour,
    84  		},
    85  		{
    86  			name: "BadInput/BadFactor",
    87  			args: args{
    88  				resyncPeriod: 10 * time.Hour,
    89  				factor:       -0.1,
    90  			},
    91  			want: 10 * time.Hour,
    92  		},
    93  		{
    94  			name: "BadInput/BadResync",
    95  			args: args{
    96  				resyncPeriod: -10 * time.Hour,
    97  				factor:       0.1,
    98  			},
    99  			want: DefaultResyncPeriod,
   100  		},
   101  		{
   102  			name: "BadInput/Big",
   103  			args: args{
   104  				resyncPeriod: time.Duration(math.MaxInt64),
   105  				factor:       1,
   106  				r:            1,
   107  			},
   108  			want: time.Duration(math.MaxInt64),
   109  		},
   110  		{
   111  			name: "SmallInput/Min",
   112  			args: args{
   113  				resyncPeriod: 10 * time.Second,
   114  				factor:       0.5,
   115  				r:            0,
   116  			},
   117  			want: 5 * time.Second,
   118  		},
   119  		{
   120  			name: "SmallInput/Mid",
   121  			args: args{
   122  				resyncPeriod: 10 * time.Second,
   123  				factor:       0.5,
   124  				r:            0.5,
   125  			},
   126  			want: 10 * time.Second,
   127  		},
   128  		{
   129  			name: "SmallInput/Max",
   130  			args: args{
   131  				resyncPeriod: 10 * time.Second,
   132  				factor:       0.5,
   133  				r:            1,
   134  			},
   135  			want: 15 * time.Second,
   136  		},
   137  	}
   138  	for _, tt := range tests {
   139  		t.Run(tt.name, func(t *testing.T) {
   140  			got := resyncWithJitter(tt.args.resyncPeriod, tt.args.factor, fakeFloat64er(tt.args.r))()
   141  			require.Equal(t, tt.want, got)
   142  		})
   143  	}
   144  }
   145  
   146  type float01 float64
   147  
   148  func (float01) Generate(rand *rand.Rand, size int) reflect.Value {
   149  	return reflect.ValueOf(float01(rand.Float64()))
   150  }
   151  
   152  type dur time.Duration
   153  
   154  func (dur) Generate(rand *rand.Rand, size int) reflect.Value {
   155  	return reflect.ValueOf(dur(rand.Uint64() / 2))
   156  }
   157  
   158  func TestGeneratesWithinRange(t *testing.T) {
   159  	f := func(resync dur, factor float01) bool {
   160  		resyncPeriod := time.Duration(resync)
   161  		min := float64(resyncPeriod.Nanoseconds()) * (1 - float64(factor))
   162  		max := float64(resyncPeriod.Nanoseconds()) * (1 + float64(factor))
   163  		d := ResyncWithJitter(resyncPeriod, float64(factor))()
   164  		return min < float64(d.Nanoseconds()) && float64(d.Nanoseconds()) < max
   165  	}
   166  	require.NoError(t, quick.Check(f, nil))
   167  }