From 19bcabbf79c005e9b1abb64fb870b5292ae7fb03 Mon Sep 17 00:00:00 2001 From: Nedyalko Andreev Date: Thu, 4 Mar 2021 14:47:23 +0200 Subject: [PATCH] Fix linter issues and slightly improve some tests --- output/cloud/data.go | 8 +++++--- output/cloud/data_test.go | 26 ++++++++++++++++---------- output/cloud/output_test.go | 12 ++++++++---- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/output/cloud/data.go b/output/cloud/data.go index ee6ce33e8f8..807b742415c 100644 --- a/output/cloud/data.go +++ b/output/cloud/data.go @@ -245,7 +245,9 @@ func (d durations) Less(i, j int) bool { return d[i] < d[j] } // Used when there are fewer samples in the bucket (so we can interpolate) // and for benchmark comparisons and verification of the quickselect // algorithm (it should return exactly the same results if interpolation isn't used). -func (d durations) SortGetNormalBounds(radius, iqrLowerCoef, iqrUpperCoef float64, interpolate bool) (min, max time.Duration) { +func (d durations) SortGetNormalBounds( + radius, iqrLowerCoef, iqrUpperCoef float64, interpolate bool, +) (min, max time.Duration) { if len(d) == 0 { return } @@ -276,7 +278,7 @@ func (d durations) SortGetNormalBounds(radius, iqrLowerCoef, iqrUpperCoef float6 min = q1 - time.Duration(iqrLowerCoef*iqr) // lower fence, anything below this is an outlier max = q3 + time.Duration(iqrUpperCoef*iqr) // upper fence, anything above this is an outlier - return + return min, max } // Reworked and translated in Go from: @@ -288,7 +290,7 @@ func (d durations) SortGetNormalBounds(radius, iqrLowerCoef, iqrUpperCoef float6 // that only depends on the sort.Interface methods, but that would // probably introduce some performance overhead because of the // dynamic dispatch. -func (d durations) quickSelect(k int) time.Duration { +func (d durations) quickSelect(k int) time.Duration { //nolint:gocognit n := len(d) l := 0 ir := n - 1 diff --git a/output/cloud/data_test.go b/output/cloud/data_test.go index 7472cc09404..c3f053f30e5 100644 --- a/output/cloud/data_test.go +++ b/output/cloud/data_test.go @@ -233,10 +233,10 @@ func TestMetricAggregation(t *testing.T) { // I've not used that after the initial tests because it's a big // external dependency that's not really needed for the tests at // this point. -func getDurations(count int, min, multiplier float64) durations { +func getDurations(r *rand.Rand, count int, min, multiplier float64) durations { data := make(durations, count) for j := 0; j < count; j++ { - data[j] = time.Duration(min + rand.Float64()*multiplier) + data[j] = time.Duration(min + r.Float64()*multiplier) //nolint:gosec } return data } @@ -246,10 +246,14 @@ func BenchmarkDurationBounds(b *testing.B) { iqrLowerCoef := 1.5 iqrUpperCoef := 1.5 + seed := time.Now().UnixNano() + r := rand.New(rand.NewSource(seed)) //nolint:gosec + b.Logf("Random source seeded with %d\n", seed) + getData := func(b *testing.B, count int) durations { b.StopTimer() defer b.StartTimer() - return getDurations(count, 0.1*float64(time.Second), float64(time.Second)) + return getDurations(r, count, 0.1*float64(time.Second), float64(time.Second)) } for count := 100; count <= 5000; count += 500 { @@ -277,11 +281,15 @@ func BenchmarkDurationBounds(b *testing.B) { func TestQuickSelectAndBounds(t *testing.T) { t.Parallel() + + seed := time.Now().UnixNano() + r := rand.New(rand.NewSource(seed)) //nolint:gosec + t.Logf("Random source seeded with %d\n", seed) + mult := time.Millisecond - for _, count := range []int{1, 2, 3, 4, 5, 10, 15, 20, 25, 50, 100, 250 + rand.Intn(100)} { + for _, count := range []int{1, 2, 3, 4, 5, 10, 15, 20, 25, 50, 100, 250 + r.Intn(100)} { count := count t.Run(fmt.Sprintf("simple-%d", count), func(t *testing.T) { - t.Parallel() data := make(durations, count) for i := 0; i < count; i++ { data[i] = time.Duration(i) * mult @@ -290,13 +298,11 @@ func TestQuickSelectAndBounds(t *testing.T) { for i := 0; i < 10; i++ { dataCopy := make(durations, count) assert.Equal(t, count, copy(dataCopy, data)) - k := rand.Intn(count) + k := r.Intn(count) assert.Equal(t, dataCopy.quickSelect(k), time.Duration(k)*mult) } }) t.Run(fmt.Sprintf("random-%d", count), func(t *testing.T) { - t.Parallel() - testCases := []struct{ r, l, u float64 }{ {0.25, 1.5, 1.5}, // Textbook {0.25, 1.5, 1.3}, // Defaults @@ -306,7 +312,7 @@ func TestQuickSelectAndBounds(t *testing.T) { for tcNum, tc := range testCases { tc := tc - data := getDurations(count, 0.3*float64(time.Second), 2*float64(time.Second)) + data := getDurations(r, count, 0.3*float64(time.Second), 2*float64(time.Second)) dataForSort := make(durations, count) dataForSelect := make(durations, count) assert.Equal(t, count, copy(dataForSort, data)) @@ -320,7 +326,7 @@ func TestQuickSelectAndBounds(t *testing.T) { assert.Equal(t, sortMin, selectMin) assert.Equal(t, sortMax, selectMax) - k := rand.Intn(count) + k := r.Intn(count) assert.Equal(t, dataForSort[k], dataForSelect.quickSelect(k)) assert.Equal(t, dataForSort[k], data.quickSelect(k)) }) diff --git a/output/cloud/output_test.go b/output/cloud/output_test.go index 5e25965f0d6..5bbd9b9ead6 100644 --- a/output/cloud/output_test.go +++ b/output/cloud/output_test.go @@ -126,8 +126,8 @@ func getSampleChecker(t *testing.T, expSamples <-chan []Sample) http.HandlerFunc } } -func skewTrail(t httpext.Trail, minCoef, maxCoef float64) httpext.Trail { - coef := minCoef + rand.Float64()*(maxCoef-minCoef) +func skewTrail(r *rand.Rand, t httpext.Trail, minCoef, maxCoef float64) httpext.Trail { + coef := minCoef + r.Float64()*(maxCoef-minCoef) addJitter := func(d *time.Duration) { *d = time.Duration(float64(*d) * coef) } @@ -158,6 +158,10 @@ func TestCloudOutput(t *testing.T) { } func runCloudOutputTestCase(t *testing.T, minSamples int) { + seed := time.Now().UnixNano() + r := rand.New(rand.NewSource(seed)) //nolint:gosec + t.Logf("Random source seeded with %d\n", seed) + tb := httpmultibin.NewHTTPMultiBin(t) tb.Mux.HandleFunc("/v1/tests", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, err := fmt.Fprintf(w, `{ @@ -254,7 +258,7 @@ func runCloudOutputTestCase(t *testing.T, minSamples int) { trails := []stats.SampleContainer{} durations := make([]time.Duration, len(trails)) for i := int64(0); i < out.config.AggregationMinSamples.Int64; i++ { - similarTrail := skewTrail(simpleTrail, 1.0, 1.0+smallSkew) + similarTrail := skewTrail(r, simpleTrail, 1.0, 1.0+smallSkew) trails = append(trails, &similarTrail) durations = append(durations, similarTrail.Duration) } @@ -269,7 +273,7 @@ func runCloudOutputTestCase(t *testing.T, minSamples int) { assert.InEpsilon(t, normal, stats.ToD(aggr.Max), smallSkew) } - outlierTrail := skewTrail(simpleTrail, 2.0+smallSkew, 3.0+smallSkew) + outlierTrail := skewTrail(r, simpleTrail, 2.0+smallSkew, 3.0+smallSkew) trails = append(trails, &outlierTrail) out.AddMetricSamples(trails) expSamples <- []Sample{