82 lines
3.0 KiB
Go
82 lines
3.0 KiB
Go
/*
|
|
Copyright 2019 The Kubernetes 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 metrics
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"time"
|
|
|
|
e2elog "k8s.io/kubernetes/test/e2e/framework/log"
|
|
)
|
|
|
|
const (
|
|
// SingleCallTimeout is how long to try single API calls (like 'get' or 'list'). Used to prevent
|
|
// transient failures from failing tests.
|
|
// TODO: client should not apply this timeout to Watch calls. Increased from 30s until that is fixed.
|
|
SingleCallTimeout = 5 * time.Minute
|
|
)
|
|
|
|
// VerifyLatencyWithinThreshold verifies whether 50, 90 and 99th percentiles of a latency metric are
|
|
// within the expected threshold.
|
|
func VerifyLatencyWithinThreshold(threshold, actual LatencyMetric, metricName string) error {
|
|
if actual.Perc50 > threshold.Perc50 {
|
|
return fmt.Errorf("too high %v latency 50th percentile: %v", metricName, actual.Perc50)
|
|
}
|
|
if actual.Perc90 > threshold.Perc90 {
|
|
return fmt.Errorf("too high %v latency 90th percentile: %v", metricName, actual.Perc90)
|
|
}
|
|
if actual.Perc99 > threshold.Perc99 {
|
|
return fmt.Errorf("too high %v latency 99th percentile: %v", metricName, actual.Perc99)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// PodLatencyData encapsulates pod startup latency information.
|
|
type PodLatencyData struct {
|
|
// Name of the pod
|
|
Name string
|
|
// Node this pod was running on
|
|
Node string
|
|
// Latency information related to pod startuptime
|
|
Latency time.Duration
|
|
}
|
|
|
|
// LatencySlice is an array of PodLatencyData which encapsulates pod startup latency information.
|
|
type LatencySlice []PodLatencyData
|
|
|
|
func (a LatencySlice) Len() int { return len(a) }
|
|
func (a LatencySlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
func (a LatencySlice) Less(i, j int) bool { return a[i].Latency < a[j].Latency }
|
|
|
|
// ExtractLatencyMetrics returns latency metrics for each percentile(50th, 90th and 99th).
|
|
func ExtractLatencyMetrics(latencies []PodLatencyData) LatencyMetric {
|
|
length := len(latencies)
|
|
perc50 := latencies[int(math.Ceil(float64(length*50)/100))-1].Latency
|
|
perc90 := latencies[int(math.Ceil(float64(length*90)/100))-1].Latency
|
|
perc99 := latencies[int(math.Ceil(float64(length*99)/100))-1].Latency
|
|
perc100 := latencies[length-1].Latency
|
|
return LatencyMetric{Perc50: perc50, Perc90: perc90, Perc99: perc99, Perc100: perc100}
|
|
}
|
|
|
|
// PrintLatencies outputs latencies to log with readable format.
|
|
func PrintLatencies(latencies []PodLatencyData, header string) {
|
|
metrics := ExtractLatencyMetrics(latencies)
|
|
e2elog.Logf("10%% %s: %v", header, latencies[(len(latencies)*9)/10:])
|
|
e2elog.Logf("perc50: %v, perc90: %v, perc99: %v", metrics.Perc50, metrics.Perc90, metrics.Perc99)
|
|
}
|