github.com/yandex/pandora@v0.5.32/core/schedule/schedule_test.go (about)

     1  package schedule
     2  
     3  import (
     4  	"sort"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/yandex/pandora/core"
    10  	"github.com/yandex/pandora/core/coretest"
    11  )
    12  
    13  func Test_unlimited(t *testing.T) {
    14  	conf := UnlimitedConfig{50 * time.Millisecond}
    15  	testee := NewUnlimitedConf(conf)
    16  	start := time.Now()
    17  	finish := start.Add(conf.Duration)
    18  	assert.Equal(t, -1, testee.Left())
    19  	testee.Start(start)
    20  	var i int
    21  	for prev := time.Now(); ; i++ {
    22  		left := testee.Left()
    23  		x, ok := testee.Next()
    24  		if !ok {
    25  			break
    26  		}
    27  		assert.Equal(t, -1, left)
    28  		assert.True(t, x.After(prev))
    29  		assert.True(t, x.Before(finish))
    30  	}
    31  	assert.Equal(t, 0, testee.Left())
    32  	assert.Greater(t, i, 50)
    33  }
    34  
    35  func TestOnce(t *testing.T) {
    36  	t.Run("started", func(t *testing.T) {
    37  		testee := NewOnce(1)
    38  		coretest.ExpectScheduleNexts(t, testee, 0, 0)
    39  	})
    40  
    41  	t.Run("unstarted", func(t *testing.T) {
    42  		testee := NewOnce(1)
    43  		start := time.Now()
    44  		x1, ok := testee.Next()
    45  		threshold := time.Since(start)
    46  
    47  		assert.True(t, ok)
    48  		assert.WithinDuration(t, start, x1, threshold)
    49  
    50  		x2, ok := testee.Next()
    51  		assert.False(t, ok)
    52  		assert.Equal(t, x1, x2)
    53  	})
    54  
    55  }
    56  
    57  func TestConst(t *testing.T) {
    58  	tests := []struct {
    59  		name           string
    60  		conf           ConstConfig
    61  		wantN          int64
    62  		wantAssertNext []time.Duration
    63  	}{
    64  		{
    65  			name: "non-zero ops",
    66  			conf: ConstConfig{
    67  				Ops:      1,
    68  				Duration: 2 * time.Second,
    69  			},
    70  			wantN: 2,
    71  			wantAssertNext: []time.Duration{
    72  				0, time.Second, 2 * time.Second,
    73  			},
    74  		},
    75  		{
    76  			name: "zero ops",
    77  			conf: ConstConfig{
    78  				Ops:      0,
    79  				Duration: 2 * time.Second,
    80  			},
    81  			wantN: 0,
    82  			wantAssertNext: []time.Duration{
    83  				2 * time.Second,
    84  			},
    85  		},
    86  	}
    87  	for _, tt := range tests {
    88  		t.Run(tt.name, func(t *testing.T) {
    89  
    90  			testee := NewConstConf(tt.conf)
    91  			underlying := testee.(*doAtSchedule)
    92  
    93  			assert.Equal(t, tt.wantN, underlying.n)
    94  			coretest.ExpectScheduleNexts(t, testee, tt.wantAssertNext...)
    95  		})
    96  	}
    97  }
    98  
    99  func TestLine(t *testing.T) {
   100  	tests := []struct {
   101  		name           string
   102  		conf           LineConfig
   103  		wantN          int64
   104  		wantAssertNext []time.Duration
   105  		assert         func(t *testing.T, testee core.Schedule, underlying *doAtSchedule)
   106  	}{
   107  		{
   108  			name: "too small ops",
   109  			conf: LineConfig{
   110  				From:     0,
   111  				To:       1.999,
   112  				Duration: time.Second,
   113  			},
   114  			wantN:          0,
   115  			wantAssertNext: []time.Duration{time.Second},
   116  		},
   117  		{
   118  			name: "const ops",
   119  			conf: LineConfig{
   120  				From:     1,
   121  				To:       1,
   122  				Duration: 2 * time.Second,
   123  			},
   124  			wantN:          2,
   125  			wantAssertNext: []time.Duration{0, time.Second, 2 * time.Second},
   126  		},
   127  		{
   128  			name: "zero start",
   129  			conf: LineConfig{
   130  				From:     0,
   131  				To:       1,
   132  				Duration: 2 * time.Second,
   133  			},
   134  			wantN:          1,
   135  			wantAssertNext: []time.Duration{0, 2 * time.Second},
   136  		},
   137  	}
   138  	for _, tt := range tests {
   139  		t.Run(tt.name, func(t *testing.T) {
   140  			testee := NewLineConf(tt.conf)
   141  			underlying := testee.(*doAtSchedule)
   142  
   143  			assert.Equal(t, tt.wantN, underlying.n)
   144  			coretest.ExpectScheduleNexts(t, testee, tt.wantAssertNext...)
   145  		})
   146  	}
   147  }
   148  
   149  func TestLineNonZeroStart(t *testing.T) {
   150  	testee := NewLineConf(LineConfig{
   151  		From:     2,
   152  		To:       8,
   153  		Duration: 2 * time.Second,
   154  	})
   155  	underlying := testee.(*doAtSchedule)
   156  
   157  	assert.Equal(t, int64(10), underlying.n)
   158  
   159  	start := time.Now()
   160  	testee.Start(start)
   161  
   162  	var (
   163  		i  int
   164  		xs []time.Time
   165  		x  time.Time
   166  	)
   167  	for ok := true; ok; i++ {
   168  		x, ok = testee.Next()
   169  		xs = append(xs, x)
   170  	}
   171  	assert.Equal(t, 11, i)
   172  	assert.True(t, sort.SliceIsSorted(xs, func(i, j int) bool {
   173  		return xs[i].Before(xs[j])
   174  	}))
   175  	assert.Equal(t, xs[len(xs)-1], start.Add(2*time.Second))
   176  }
   177  
   178  func TestStep(t *testing.T) {
   179  	conf := StepConfig{
   180  		From:     1,
   181  		To:       2,
   182  		Step:     1,
   183  		Duration: 2 * time.Second,
   184  	}
   185  	testee := NewStepConf(conf)
   186  	assert.Equal(t, 6, testee.Left())
   187  }
   188  
   189  func TestInstanceStep(t *testing.T) {
   190  	conf := InstanceStepConfig{
   191  		From:         1,
   192  		To:           3,
   193  		Step:         1,
   194  		StepDuration: 2 * time.Second,
   195  	}
   196  	testee := NewInstanceStepConf(conf)
   197  	assert.Equal(t, 3, testee.Left())
   198  }
   199  
   200  func BenchmarkLineSchedule(b *testing.B) {
   201  	schedule := NewLine(0, float64(b.N), 2*time.Second)
   202  	benchmarkScheduleNext(b, schedule)
   203  }
   204  
   205  func BenchmarkLineScheduleParallel(b *testing.B) {
   206  	schedule := NewLine(0, float64(b.N), 2*time.Second)
   207  	benchmarkScheduleNextParallel(b, schedule)
   208  }
   209  
   210  func BenchmarkUnlimitedSchedule(b *testing.B) {
   211  	schedule := NewUnlimited(time.Minute)
   212  	benchmarkScheduleNext(b, schedule)
   213  }
   214  
   215  func BenchmarkUnlimitedScheduleParallel(b *testing.B) {
   216  	schedule := NewUnlimited(time.Minute)
   217  	benchmarkScheduleNextParallel(b, schedule)
   218  }
   219  
   220  func benchmarkScheduleNextParallel(b *testing.B, schedule core.Schedule) {
   221  	run := func(pb *testing.PB) {
   222  		for pb.Next() {
   223  			schedule.Next()
   224  		}
   225  	}
   226  	schedule.Start(time.Now())
   227  	b.ReportAllocs()
   228  	b.ResetTimer()
   229  	b.RunParallel(run)
   230  }
   231  
   232  func benchmarkScheduleNext(b *testing.B, schedule core.Schedule) {
   233  	schedule.Start(time.Now())
   234  	b.ReportAllocs()
   235  	b.ResetTimer()
   236  	for i := 0; i < b.N; i++ {
   237  		schedule.Next()
   238  	}
   239  }