// Copyright 2017 The etcd Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package report import ( "fmt" "reflect" "strings" "testing" "time" ) func TestPercentiles(t *testing.T) { nums := make([]float64, 100) nums[99] = 1 // 99-percentile (1 out of 100) data := percentiles(nums) if data[len(pctls)-2] != 1 { t.Fatalf("99-percentile expected 1, got %f", data[len(pctls)-2]) } nums = make([]float64, 1000) nums[999] = 1 // 99.9-percentile (1 out of 1000) data = percentiles(nums) if data[len(pctls)-1] != 1 { t.Fatalf("99.9-percentile expected 1, got %f", data[len(pctls)-1]) } } func TestReport(t *testing.T) { r := NewReportSample("%f") go func() { start := time.Now() for i := 0; i < 5; i++ { end := start.Add(time.Second) r.Results() <- Result{Start: start, End: end} start = end } r.Results() <- Result{Start: start, End: start.Add(time.Second), Err: fmt.Errorf("oops")} close(r.Results()) }() stats := <-r.Stats() stats.TimeSeries = nil // ignore timeseries since it uses wall clock wStats := Stats{ AvgTotal: 5.0, Fastest: 1.0, Slowest: 1.0, Average: 1.0, Stddev: 0.0, Total: stats.Total, RPS: 5.0 / stats.Total.Seconds(), ErrorDist: map[string]int{"oops": 1}, Lats: []float64{1.0, 1.0, 1.0, 1.0, 1.0}, } if !reflect.DeepEqual(stats, wStats) { t.Fatalf("got %+v, want %+v", stats, wStats) } wstrs := []string{ "Stddev:\t0", "Average:\t1.0", "Slowest:\t1.0", "Fastest:\t1.0", } ss := <-r.Run() for i, ws := range wstrs { if !strings.Contains(ss, ws) { t.Errorf("#%d: stats string missing %s", i, ws) } } } func TestWeightedReport(t *testing.T) { r := NewWeightedReport(NewReport("%f"), "%f") go func() { start := time.Now() for i := 0; i < 5; i++ { end := start.Add(time.Second) r.Results() <- Result{Start: start, End: end, Weight: 2.0} start = end } r.Results() <- Result{Start: start, End: start.Add(time.Second), Err: fmt.Errorf("oops")} close(r.Results()) }() stats := <-r.Stats() stats.TimeSeries = nil // ignore timeseries since it uses wall clock wStats := Stats{ AvgTotal: 10.0, Fastest: 0.5, Slowest: 0.5, Average: 0.5, Stddev: 0.0, Total: stats.Total, RPS: 10.0 / stats.Total.Seconds(), ErrorDist: map[string]int{"oops": 1}, Lats: []float64{0.5, 0.5, 0.5, 0.5, 0.5}, } if !reflect.DeepEqual(stats, wStats) { t.Fatalf("got %+v, want %+v", stats, wStats) } }