// Copyright (c) 2020 Gitpod GmbH. All rights reserved. // Licensed under the GNU Affero General Public License (AGPL). // See License-AGPL.txt in the project root for license information. package dropwriter_test import ( "testing" "time" "github.com/gitpod-io/gitpod/supervisor/pkg/dropwriter" ) func TestBucket(t *testing.T) { steps := func(dt time.Duration, c int) []time.Duration { res := make([]time.Duration, c) for i := range res { res[i] = dt } return res } constv := func(v int64, c int) []int64 { res := make([]int64, c) for i := range res { res[i] = v } return res } clock := func(dt []time.Duration) dropwriter.Clock { i := 0 t := time.Time{} return func() time.Time { ot := t t = t.Add(dt[i]) i++ return ot } } tests := []struct { Name string Bucket *dropwriter.Bucket Reqs []int64 Expectations []int64 }{ { Name: "below limit", Bucket: dropwriter.NewBucketClock(20, 15, clock(steps(1300*time.Millisecond, 10))), Reqs: constv(10, 10), Expectations: constv(10, 10), }, { Name: "above limit", Bucket: dropwriter.NewBucketClock(1, 1, clock(steps(1300*time.Millisecond, 10))), Reqs: constv(10, 10), Expectations: constv(1, 10), }, { Name: "upfront peak", Bucket: dropwriter.NewBucketClock(20, 5, clock(steps(1300*time.Millisecond, 10))), Reqs: append(constv(10, 1), constv(1, 9)...), Expectations: append(constv(10, 1), constv(1, 9)...), }, { Name: "mid peak", Bucket: dropwriter.NewBucketClock(20, 5, clock(steps(1300*time.Millisecond, 10))), Reqs: append(constv(1, 4), append(constv(30, 1), constv(1, 5)...)...), Expectations: append(constv(1, 4), append(constv(20, 1), constv(1, 5)...)...), }, } for _, test := range tests { t.Run(test.Name, func(t *testing.T) { for step := range test.Reqs { grant := test.Bucket.TakeAvailable(test.Reqs[step]) if grant != test.Expectations[step] { t.Errorf("step %d: did not receive expected tokens: requested %d, expected %d, received %d", step, test.Reqs[step], test.Expectations[step], grant) } } }) } }