mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
Finish implementation of stable metrics static analysis
Handle "DeprecatedVersion" field Fix kube metrics framework path Implement handling prometheus util functions for generating buckets
This commit is contained in:
parent
d6035f3e0d
commit
53fc6f9b58
@ -171,7 +171,6 @@ test/images/agnhost/pause
|
|||||||
test/images/agnhost/serve-hostname
|
test/images/agnhost/serve-hostname
|
||||||
test/images/agnhost/webhook
|
test/images/agnhost/webhook
|
||||||
test/images/pets/peer-finder
|
test/images/pets/peer-finder
|
||||||
test/instrumentation
|
|
||||||
test/integration/apiserver
|
test/integration/apiserver
|
||||||
test/integration/apiserver/admissionwebhook
|
test/integration/apiserver/admissionwebhook
|
||||||
test/integration/auth
|
test/integration/auth
|
||||||
|
@ -63,4 +63,5 @@ go_test(
|
|||||||
srcs = ["main_test.go"],
|
srcs = ["main_test.go"],
|
||||||
data = glob(["testdata/**"]),
|
data = glob(["testdata/**"]),
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
|
deps = ["//vendor/github.com/prometheus/client_golang/prometheus:go_default_library"],
|
||||||
)
|
)
|
||||||
|
@ -24,12 +24,14 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"k8s.io/component-base/metrics"
|
"k8s.io/component-base/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func decodeMetricCalls(fs []*ast.CallExpr, metricsImportName string) ([]metric, []error) {
|
func decodeMetricCalls(fs []*ast.CallExpr, metricsImportName, prometheusImportName string) ([]metric, []error) {
|
||||||
finder := metricDecoder{
|
finder := metricDecoder{
|
||||||
metricsImportName: metricsImportName,
|
kubeMetricsImportName: metricsImportName,
|
||||||
|
prometheusImportName: prometheusImportName,
|
||||||
}
|
}
|
||||||
ms := make([]metric, 0, len(fs))
|
ms := make([]metric, 0, len(fs))
|
||||||
errors := []error{}
|
errors := []error{}
|
||||||
@ -45,7 +47,8 @@ func decodeMetricCalls(fs []*ast.CallExpr, metricsImportName string) ([]metric,
|
|||||||
}
|
}
|
||||||
|
|
||||||
type metricDecoder struct {
|
type metricDecoder struct {
|
||||||
metricsImportName string
|
kubeMetricsImportName string
|
||||||
|
prometheusImportName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *metricDecoder) decodeNewMetricCall(fc *ast.CallExpr) (metric, error) {
|
func (c *metricDecoder) decodeNewMetricCall(fc *ast.CallExpr) (metric, error) {
|
||||||
@ -60,7 +63,7 @@ func (c *metricDecoder) decodeNewMetricCall(fc *ast.CallExpr) (metric, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return m, newDecodeErrorf(fc, errNotDirectCall)
|
return m, newDecodeErrorf(fc, errNotDirectCall)
|
||||||
}
|
}
|
||||||
if functionImport.String() != c.metricsImportName {
|
if functionImport.String() != c.kubeMetricsImportName {
|
||||||
return m, newDecodeErrorf(fc, errNotDirectCall)
|
return m, newDecodeErrorf(fc, errNotDirectCall)
|
||||||
}
|
}
|
||||||
switch functionName {
|
switch functionName {
|
||||||
@ -157,7 +160,7 @@ func (c *metricDecoder) decodeOpts(expr ast.Expr) (metric, error) {
|
|||||||
key := fmt.Sprintf("%v", kv.Key)
|
key := fmt.Sprintf("%v", kv.Key)
|
||||||
|
|
||||||
switch key {
|
switch key {
|
||||||
case "Namespace", "Subsystem", "Name", "Help":
|
case "Namespace", "Subsystem", "Name", "Help", "DeprecatedVersion":
|
||||||
k, ok := kv.Value.(*ast.BasicLit)
|
k, ok := kv.Value.(*ast.BasicLit)
|
||||||
if !ok {
|
if !ok {
|
||||||
return m, newDecodeErrorf(expr, errNonStringAttribute)
|
return m, newDecodeErrorf(expr, errNonStringAttribute)
|
||||||
@ -173,18 +176,20 @@ func (c *metricDecoder) decodeOpts(expr ast.Expr) (metric, error) {
|
|||||||
m.Subsystem = value
|
m.Subsystem = value
|
||||||
case "Name":
|
case "Name":
|
||||||
m.Name = value
|
m.Name = value
|
||||||
|
case "DeprecatedVersion":
|
||||||
|
m.DeprecatedVersion = value
|
||||||
case "Help":
|
case "Help":
|
||||||
m.Help = value
|
m.Help = value
|
||||||
}
|
}
|
||||||
case "Buckets":
|
case "Buckets":
|
||||||
buckets, err := decodeBuckets(kv)
|
buckets, err := c.decodeBuckets(kv.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return m, err
|
return m, err
|
||||||
}
|
}
|
||||||
sort.Float64s(buckets)
|
sort.Float64s(buckets)
|
||||||
m.Buckets = buckets
|
m.Buckets = buckets
|
||||||
case "StabilityLevel":
|
case "StabilityLevel":
|
||||||
level, err := decodeStabilityLevel(kv.Value, c.metricsImportName)
|
level, err := decodeStabilityLevel(kv.Value, c.kubeMetricsImportName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return m, err
|
return m, err
|
||||||
}
|
}
|
||||||
@ -196,13 +201,46 @@ func (c *metricDecoder) decodeOpts(expr ast.Expr) (metric, error) {
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeBuckets(kv *ast.KeyValueExpr) ([]float64, error) {
|
func (c *metricDecoder) decodeBuckets(expr ast.Expr) ([]float64, error) {
|
||||||
cl, ok := kv.Value.(*ast.CompositeLit)
|
switch v := expr.(type) {
|
||||||
if !ok {
|
case *ast.CompositeLit:
|
||||||
return nil, newDecodeErrorf(kv, errBuckets)
|
return decodeListOfFloats(v.Elts)
|
||||||
|
case *ast.SelectorExpr:
|
||||||
|
variableName := v.Sel.String()
|
||||||
|
importName, ok := v.X.(*ast.Ident)
|
||||||
|
if ok && importName.String() == c.prometheusImportName && variableName == "DefBuckets" {
|
||||||
|
return prometheus.DefBuckets, nil
|
||||||
|
}
|
||||||
|
case *ast.CallExpr:
|
||||||
|
se, ok := v.Fun.(*ast.SelectorExpr)
|
||||||
|
if !ok {
|
||||||
|
return nil, newDecodeErrorf(v, errBuckets)
|
||||||
|
}
|
||||||
|
functionName := se.Sel.String()
|
||||||
|
functionImport, ok := se.X.(*ast.Ident)
|
||||||
|
if !ok {
|
||||||
|
return nil, newDecodeErrorf(v, errBuckets)
|
||||||
|
}
|
||||||
|
if functionImport.String() != c.prometheusImportName {
|
||||||
|
return nil, newDecodeErrorf(v, errBuckets)
|
||||||
|
}
|
||||||
|
firstArg, secondArg, thirdArg, err := decodeBucketArguments(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch functionName {
|
||||||
|
case "LinearBuckets":
|
||||||
|
return prometheus.LinearBuckets(firstArg, secondArg, thirdArg), nil
|
||||||
|
case "ExponentialBuckets":
|
||||||
|
return prometheus.ExponentialBuckets(firstArg, secondArg, thirdArg), nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buckets := make([]float64, len(cl.Elts))
|
return nil, newDecodeErrorf(expr, errBuckets)
|
||||||
for i, elt := range cl.Elts {
|
}
|
||||||
|
|
||||||
|
func decodeListOfFloats(exprs []ast.Expr) ([]float64, error) {
|
||||||
|
buckets := make([]float64, len(exprs))
|
||||||
|
for i, elt := range exprs {
|
||||||
bl, ok := elt.(*ast.BasicLit)
|
bl, ok := elt.(*ast.BasicLit)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, newDecodeErrorf(bl, errBuckets)
|
return nil, newDecodeErrorf(bl, errBuckets)
|
||||||
@ -219,6 +257,37 @@ func decodeBuckets(kv *ast.KeyValueExpr) ([]float64, error) {
|
|||||||
return buckets, nil
|
return buckets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeBucketArguments(fc *ast.CallExpr) (float64, float64, int, error) {
|
||||||
|
if len(fc.Args) != 3 {
|
||||||
|
return 0, 0, 0, newDecodeErrorf(fc, errBuckets)
|
||||||
|
}
|
||||||
|
strArgs := make([]string, len(fc.Args))
|
||||||
|
for i, elt := range fc.Args {
|
||||||
|
bl, ok := elt.(*ast.BasicLit)
|
||||||
|
if !ok {
|
||||||
|
return 0, 0, 0, newDecodeErrorf(bl, errBuckets)
|
||||||
|
}
|
||||||
|
if bl.Kind != token.FLOAT && bl.Kind != token.INT {
|
||||||
|
return 0, 0, 0, newDecodeErrorf(bl, errBuckets)
|
||||||
|
}
|
||||||
|
strArgs[i] = bl.Value
|
||||||
|
}
|
||||||
|
firstArg, err := strconv.ParseFloat(strArgs[0], 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, 0, newDecodeErrorf(fc.Args[0], errBuckets)
|
||||||
|
}
|
||||||
|
secondArg, err := strconv.ParseFloat(strArgs[1], 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, 0, newDecodeErrorf(fc.Args[1], errBuckets)
|
||||||
|
}
|
||||||
|
thirdArg, err := strconv.ParseInt(strArgs[2], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, 0, newDecodeErrorf(fc.Args[2], errBuckets)
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstArg, secondArg, int(thirdArg), nil
|
||||||
|
}
|
||||||
|
|
||||||
func decodeStabilityLevel(expr ast.Expr, metricsFrameworkImportName string) (*metrics.StabilityLevel, error) {
|
func decodeStabilityLevel(expr ast.Expr, metricsFrameworkImportName string) (*metrics.StabilityLevel, error) {
|
||||||
se, ok := expr.(*ast.SelectorExpr)
|
se, ok := expr.(*ast.SelectorExpr)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -30,9 +30,9 @@ const (
|
|||||||
errInvalidNewMetricCall = "Invalid new metric call, please ensure code compiles"
|
errInvalidNewMetricCall = "Invalid new metric call, please ensure code compiles"
|
||||||
errNonStringAttribute = "Non string attribute it not supported"
|
errNonStringAttribute = "Non string attribute it not supported"
|
||||||
errFieldNotSupported = "Field %s is not supported"
|
errFieldNotSupported = "Field %s is not supported"
|
||||||
errBuckets = "Buckets were not set to list of floats"
|
errBuckets = "Buckets should be set to list of floats, result from function call of prometheus.LinearBuckets or prometheus.ExponentialBuckets"
|
||||||
errLabels = "Labels were not set to list of strings"
|
errLabels = "Labels were not set to list of strings"
|
||||||
errImport = `Importing through "." metrics framework is not supported`
|
errImport = `Importing using "." is not supported`
|
||||||
)
|
)
|
||||||
|
|
||||||
type decodeError struct {
|
type decodeError struct {
|
||||||
|
@ -31,9 +31,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
metricFrameworkPath = `"k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"`
|
kubeMetricImportPath = `"k8s.io/component-base/metrics"`
|
||||||
// Should equal to final directory name of metricFrameworkPath
|
// Should equal to final directory name of kubeMetricImportPath
|
||||||
defaultFrameworkImportName = "metrics"
|
kubeMetricsDefaultImportName = "metrics"
|
||||||
|
prometheusImportPath = `"github.com/prometheus/client_golang/prometheus"`
|
||||||
|
// Should equal to final directory name of kubeMetricImportPath
|
||||||
|
prometheusDefaultImportName = "prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -67,7 +70,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func searchPathForStableMetrics(path string) ([]metric, []error) {
|
func searchPathForStableMetrics(path string) ([]metric, []error) {
|
||||||
ms := []metric{}
|
metrics := []metric{}
|
||||||
errors := []error{}
|
errors := []error{}
|
||||||
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
||||||
if strings.HasPrefix(path, "vendor") {
|
if strings.HasPrefix(path, "vendor") {
|
||||||
@ -78,13 +81,13 @@ func searchPathForStableMetrics(path string) ([]metric, []error) {
|
|||||||
}
|
}
|
||||||
ms, es := searchFileForStableMetrics(path, nil)
|
ms, es := searchFileForStableMetrics(path, nil)
|
||||||
errors = append(errors, es...)
|
errors = append(errors, es...)
|
||||||
ms = append(ms, ms...)
|
metrics = append(metrics, ms...)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errors = append(errors, err)
|
errors = append(errors, err)
|
||||||
}
|
}
|
||||||
return ms, errors
|
return metrics, errors
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass either only filename of existing file or src including source code in any format and a filename that it comes from
|
// Pass either only filename of existing file or src including source code in any format and a filename that it comes from
|
||||||
@ -94,26 +97,30 @@ func searchFileForStableMetrics(filename string, src interface{}) ([]metric, []e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return []metric{}, []error{err}
|
return []metric{}, []error{err}
|
||||||
}
|
}
|
||||||
metricsImportName, err := getMetricsFrameworkImportName(tree)
|
metricsImportName, err := getLocalNameOfImportedPackage(tree, kubeMetricImportPath, kubeMetricsDefaultImportName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []metric{}, addFileInformationToErrors([]error{err}, fileset)
|
return []metric{}, addFileInformationToErrors([]error{err}, fileset)
|
||||||
}
|
}
|
||||||
if metricsImportName == "" {
|
if metricsImportName == "" {
|
||||||
return []metric{}, []error{}
|
return []metric{}, []error{}
|
||||||
}
|
}
|
||||||
|
prometheusImportName, err := getLocalNameOfImportedPackage(tree, prometheusImportPath, prometheusDefaultImportName)
|
||||||
|
if err != nil {
|
||||||
|
return []metric{}, addFileInformationToErrors([]error{err}, fileset)
|
||||||
|
}
|
||||||
|
|
||||||
stableMetricsFunctionCalls, errors := findStableMetricDeclaration(tree, metricsImportName)
|
stableMetricsFunctionCalls, errors := findStableMetricDeclaration(tree, metricsImportName)
|
||||||
metrics, es := decodeMetricCalls(stableMetricsFunctionCalls, metricsImportName)
|
metrics, es := decodeMetricCalls(stableMetricsFunctionCalls, metricsImportName, prometheusImportName)
|
||||||
errors = append(errors, es...)
|
errors = append(errors, es...)
|
||||||
return metrics, addFileInformationToErrors(errors, fileset)
|
return metrics, addFileInformationToErrors(errors, fileset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMetricsFrameworkImportName(tree *ast.File) (string, error) {
|
func getLocalNameOfImportedPackage(tree *ast.File, importPath, defaultImportName string) (string, error) {
|
||||||
var importName string
|
var importName string
|
||||||
for _, im := range tree.Imports {
|
for _, im := range tree.Imports {
|
||||||
if im.Path.Value == metricFrameworkPath {
|
if im.Path.Value == importPath {
|
||||||
if im.Name == nil {
|
if im.Name == nil {
|
||||||
importName = defaultFrameworkImportName
|
importName = defaultImportName
|
||||||
} else {
|
} else {
|
||||||
if im.Name.Name == "." {
|
if im.Name.Name == "." {
|
||||||
return "", newDecodeErrorf(im, errImport)
|
return "", newDecodeErrorf(im, errImport)
|
||||||
|
@ -20,6 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const fakeFilename = "testdata/metric.go"
|
const fakeFilename = "testdata/metric.go"
|
||||||
@ -33,7 +35,7 @@ func TestSkipMetrics(t *testing.T) {
|
|||||||
testName: "Skip alpha metric with local variable",
|
testName: "Skip alpha metric with local variable",
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var name = "metric"
|
var name = "metric"
|
||||||
var _ = metrics.NewCounter(
|
var _ = metrics.NewCounter(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
@ -46,7 +48,7 @@ var _ = metrics.NewCounter(
|
|||||||
testName: "Skip alpha metric created via function call",
|
testName: "Skip alpha metric created via function call",
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
func getName() string {
|
func getName() string {
|
||||||
return "metric"
|
return "metric"
|
||||||
}
|
}
|
||||||
@ -61,7 +63,7 @@ var _ = metrics.NewCounter(
|
|||||||
testName: "Skip metric without stability set",
|
testName: "Skip metric without stability set",
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewCounter(
|
var _ = metrics.NewCounter(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
Name: "metric",
|
Name: "metric",
|
||||||
@ -123,22 +125,24 @@ func TestStableMetric(t *testing.T) {
|
|||||||
{
|
{
|
||||||
testName: "Counter",
|
testName: "Counter",
|
||||||
metric: metric{
|
metric: metric{
|
||||||
Name: "metric",
|
Name: "metric",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
StabilityLevel: "STABLE",
|
StabilityLevel: "STABLE",
|
||||||
Help: "help",
|
DeprecatedVersion: "1.16",
|
||||||
Type: counterMetricType,
|
Help: "help",
|
||||||
|
Type: counterMetricType,
|
||||||
},
|
},
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewCounter(
|
var _ = metrics.NewCounter(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
Name: "metric",
|
Name: "metric",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Help: "help",
|
Help: "help",
|
||||||
|
DeprecatedVersion: "1.16",
|
||||||
StabilityLevel: metrics.STABLE,
|
StabilityLevel: metrics.STABLE,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -146,23 +150,25 @@ var _ = metrics.NewCounter(
|
|||||||
{
|
{
|
||||||
testName: "CounterVec",
|
testName: "CounterVec",
|
||||||
metric: metric{
|
metric: metric{
|
||||||
Name: "metric",
|
Name: "metric",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
Labels: []string{"label-1"},
|
Labels: []string{"label-1"},
|
||||||
StabilityLevel: "STABLE",
|
StabilityLevel: "STABLE",
|
||||||
Help: "help",
|
DeprecatedVersion: "1.16",
|
||||||
Type: counterMetricType,
|
Help: "help",
|
||||||
|
Type: counterMetricType,
|
||||||
},
|
},
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewCounterVec(
|
var _ = metrics.NewCounterVec(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
Name: "metric",
|
Name: "metric",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
Help: "help",
|
Help: "help",
|
||||||
|
DeprecatedVersion: "1.16",
|
||||||
StabilityLevel: metrics.STABLE,
|
StabilityLevel: metrics.STABLE,
|
||||||
},
|
},
|
||||||
[]string{"label-1"},
|
[]string{"label-1"},
|
||||||
@ -171,22 +177,24 @@ var _ = metrics.NewCounterVec(
|
|||||||
{
|
{
|
||||||
testName: "Gauge",
|
testName: "Gauge",
|
||||||
metric: metric{
|
metric: metric{
|
||||||
Name: "gauge",
|
Name: "gauge",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
StabilityLevel: "STABLE",
|
StabilityLevel: "STABLE",
|
||||||
Help: "help",
|
DeprecatedVersion: "1.16",
|
||||||
Type: gaugeMetricType,
|
Help: "help",
|
||||||
|
Type: gaugeMetricType,
|
||||||
},
|
},
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewGauge(
|
var _ = metrics.NewGauge(
|
||||||
&metrics.GaugeOpts{
|
&metrics.GaugeOpts{
|
||||||
Name: "gauge",
|
Name: "gauge",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
Help: "help",
|
Help: "help",
|
||||||
|
DeprecatedVersion: "1.16",
|
||||||
StabilityLevel: metrics.STABLE,
|
StabilityLevel: metrics.STABLE,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -194,23 +202,25 @@ var _ = metrics.NewGauge(
|
|||||||
{
|
{
|
||||||
testName: "GaugeVec",
|
testName: "GaugeVec",
|
||||||
metric: metric{
|
metric: metric{
|
||||||
Name: "gauge",
|
Name: "gauge",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
StabilityLevel: "STABLE",
|
StabilityLevel: "STABLE",
|
||||||
Help: "help",
|
DeprecatedVersion: "1.16",
|
||||||
Type: gaugeMetricType,
|
Help: "help",
|
||||||
Labels: []string{"label-1", "label-2"},
|
Type: gaugeMetricType,
|
||||||
|
Labels: []string{"label-1", "label-2"},
|
||||||
},
|
},
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewGaugeVec(
|
var _ = metrics.NewGaugeVec(
|
||||||
&metrics.GaugeOpts{
|
&metrics.GaugeOpts{
|
||||||
Name: "gauge",
|
Name: "gauge",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
Help: "help",
|
Help: "help",
|
||||||
|
DeprecatedVersion: "1.16",
|
||||||
StabilityLevel: metrics.STABLE,
|
StabilityLevel: metrics.STABLE,
|
||||||
},
|
},
|
||||||
[]string{"label-2", "label-1"},
|
[]string{"label-2", "label-1"},
|
||||||
@ -219,17 +229,18 @@ var _ = metrics.NewGaugeVec(
|
|||||||
{
|
{
|
||||||
testName: "Histogram",
|
testName: "Histogram",
|
||||||
metric: metric{
|
metric: metric{
|
||||||
Name: "histogram",
|
Name: "histogram",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
StabilityLevel: "STABLE",
|
DeprecatedVersion: "1.16",
|
||||||
Buckets: []float64{0.001, 0.01, 0.1, 1, 10, 100},
|
StabilityLevel: "STABLE",
|
||||||
Help: "help",
|
Buckets: []float64{0.001, 0.01, 0.1, 1, 10, 100},
|
||||||
Type: histogramMetricType,
|
Help: "help",
|
||||||
|
Type: histogramMetricType,
|
||||||
},
|
},
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewHistogram(
|
var _ = metrics.NewHistogram(
|
||||||
&metrics.HistogramOpts{
|
&metrics.HistogramOpts{
|
||||||
Name: "histogram",
|
Name: "histogram",
|
||||||
@ -237,6 +248,7 @@ var _ = metrics.NewHistogram(
|
|||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
StabilityLevel: metrics.STABLE,
|
StabilityLevel: metrics.STABLE,
|
||||||
Help: "help",
|
Help: "help",
|
||||||
|
DeprecatedVersion: "1.16",
|
||||||
Buckets: []float64{0.001, 0.01, 0.1, 1, 10, 100},
|
Buckets: []float64{0.001, 0.01, 0.1, 1, 10, 100},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -244,18 +256,19 @@ var _ = metrics.NewHistogram(
|
|||||||
{
|
{
|
||||||
testName: "HistogramVec",
|
testName: "HistogramVec",
|
||||||
metric: metric{
|
metric: metric{
|
||||||
Name: "histogram",
|
Name: "histogram",
|
||||||
Namespace: "namespace",
|
Namespace: "namespace",
|
||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
StabilityLevel: "STABLE",
|
DeprecatedVersion: "1.16",
|
||||||
Buckets: []float64{0.001, 0.01, 0.1, 1, 10, 100},
|
StabilityLevel: "STABLE",
|
||||||
Help: "help",
|
Buckets: []float64{0.001, 0.01, 0.1, 1, 10, 100},
|
||||||
Type: histogramMetricType,
|
Help: "help",
|
||||||
Labels: []string{"label-1", "label-2"},
|
Type: histogramMetricType,
|
||||||
|
Labels: []string{"label-1", "label-2"},
|
||||||
},
|
},
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewHistogramVec(
|
var _ = metrics.NewHistogramVec(
|
||||||
&metrics.HistogramOpts{
|
&metrics.HistogramOpts{
|
||||||
Name: "histogram",
|
Name: "histogram",
|
||||||
@ -263,6 +276,7 @@ var _ = metrics.NewHistogramVec(
|
|||||||
Subsystem: "subsystem",
|
Subsystem: "subsystem",
|
||||||
StabilityLevel: metrics.STABLE,
|
StabilityLevel: metrics.STABLE,
|
||||||
Help: "help",
|
Help: "help",
|
||||||
|
DeprecatedVersion: "1.16",
|
||||||
Buckets: []float64{0.001, 0.01, 0.1, 1, 10, 100},
|
Buckets: []float64{0.001, 0.01, 0.1, 1, 10, 100},
|
||||||
},
|
},
|
||||||
[]string{"label-2", "label-1"},
|
[]string{"label-2", "label-1"},
|
||||||
@ -277,13 +291,73 @@ var _ = metrics.NewHistogramVec(
|
|||||||
},
|
},
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import custom "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import custom "k8s.io/component-base/metrics"
|
||||||
var _ = custom.NewCounter(
|
var _ = custom.NewCounter(
|
||||||
&custom.CounterOpts{
|
&custom.CounterOpts{
|
||||||
Name: "metric",
|
Name: "metric",
|
||||||
StabilityLevel: custom.STABLE,
|
StabilityLevel: custom.STABLE,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
`},
|
||||||
|
{
|
||||||
|
testName: "Histogram with linear buckets",
|
||||||
|
metric: metric{
|
||||||
|
Name: "histogram",
|
||||||
|
StabilityLevel: "STABLE",
|
||||||
|
Buckets: prometheus.LinearBuckets(1, 1, 3),
|
||||||
|
Type: histogramMetricType,
|
||||||
|
},
|
||||||
|
src: `
|
||||||
|
package test
|
||||||
|
import "k8s.io/component-base/metrics"
|
||||||
|
import "github.com/prometheus/client_golang/prometheus"
|
||||||
|
var _ = metrics.NewHistogram(
|
||||||
|
&metrics.HistogramOpts{
|
||||||
|
Name: "histogram",
|
||||||
|
StabilityLevel: metrics.STABLE,
|
||||||
|
Buckets: prometheus.LinearBuckets(1, 1, 3),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
`},
|
||||||
|
{
|
||||||
|
testName: "Histogram with exponential buckets",
|
||||||
|
metric: metric{
|
||||||
|
Name: "histogram",
|
||||||
|
StabilityLevel: "STABLE",
|
||||||
|
Buckets: prometheus.ExponentialBuckets(1, 2, 3),
|
||||||
|
Type: histogramMetricType,
|
||||||
|
},
|
||||||
|
src: `
|
||||||
|
package test
|
||||||
|
import "k8s.io/component-base/metrics"
|
||||||
|
import "github.com/prometheus/client_golang/prometheus"
|
||||||
|
var _ = metrics.NewHistogram(
|
||||||
|
&metrics.HistogramOpts{
|
||||||
|
Name: "histogram",
|
||||||
|
StabilityLevel: metrics.STABLE,
|
||||||
|
Buckets: prometheus.ExponentialBuckets(1, 2, 3),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
`},
|
||||||
|
{
|
||||||
|
testName: "Histogram with default buckets",
|
||||||
|
metric: metric{
|
||||||
|
Name: "histogram",
|
||||||
|
StabilityLevel: "STABLE",
|
||||||
|
Buckets: prometheus.DefBuckets,
|
||||||
|
Type: histogramMetricType,
|
||||||
|
},
|
||||||
|
src: `
|
||||||
|
package test
|
||||||
|
import "k8s.io/component-base/metrics"
|
||||||
|
import "github.com/prometheus/client_golang/prometheus"
|
||||||
|
var _ = metrics.NewHistogram(
|
||||||
|
&metrics.HistogramOpts{
|
||||||
|
Name: "histogram",
|
||||||
|
StabilityLevel: metrics.STABLE,
|
||||||
|
Buckets: prometheus.DefBuckets,
|
||||||
|
},
|
||||||
|
)
|
||||||
`},
|
`},
|
||||||
} {
|
} {
|
||||||
t.Run(test.testName, func(t *testing.T) {
|
t.Run(test.testName, func(t *testing.T) {
|
||||||
@ -315,7 +389,7 @@ func TestIncorrectStableMetricDeclarations(t *testing.T) {
|
|||||||
err: fmt.Errorf("testdata/metric.go:4:9: Stable summary metric is not supported"),
|
err: fmt.Errorf("testdata/metric.go:4:9: Stable summary metric is not supported"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewSummary(
|
var _ = metrics.NewSummary(
|
||||||
&metrics.SummaryOpts{
|
&metrics.SummaryOpts{
|
||||||
StabilityLevel: metrics.STABLE,
|
StabilityLevel: metrics.STABLE,
|
||||||
@ -327,7 +401,7 @@ var _ = metrics.NewSummary(
|
|||||||
err: fmt.Errorf("testdata/metric.go:7:4: Non string attribute it not supported"),
|
err: fmt.Errorf("testdata/metric.go:7:4: Non string attribute it not supported"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
const name = "metric"
|
const name = "metric"
|
||||||
var _ = metrics.NewCounter(
|
var _ = metrics.NewCounter(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
@ -341,7 +415,7 @@ var _ = metrics.NewCounter(
|
|||||||
err: fmt.Errorf("testdata/metric.go:9:4: Non string attribute it not supported"),
|
err: fmt.Errorf("testdata/metric.go:9:4: Non string attribute it not supported"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
func getName() string {
|
func getName() string {
|
||||||
return "metric"
|
return "metric"
|
||||||
}
|
}
|
||||||
@ -357,7 +431,7 @@ var _ = metrics.NewCounter(
|
|||||||
err: fmt.Errorf("testdata/metric.go:7:4: Non string attribute it not supported"),
|
err: fmt.Errorf("testdata/metric.go:7:4: Non string attribute it not supported"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
import "k8s.io/kubernetes/utils"
|
import "k8s.io/kubernetes/utils"
|
||||||
var _ = metrics.NewCounter(
|
var _ = metrics.NewCounter(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
@ -371,7 +445,7 @@ var _ = metrics.NewCounter(
|
|||||||
err: fmt.Errorf("testdata/metric.go:9:20: StabilityLevel should be passed STABLE, ALPHA or removed"),
|
err: fmt.Errorf("testdata/metric.go:9:20: StabilityLevel should be passed STABLE, ALPHA or removed"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
func getMetricStability() metrics.StabilityLevel {
|
func getMetricStability() metrics.StabilityLevel {
|
||||||
return metrics.STABLE
|
return metrics.STABLE
|
||||||
}
|
}
|
||||||
@ -386,7 +460,7 @@ var _ = metrics.NewCounter(
|
|||||||
err: fmt.Errorf("testdata/metric.go:6:20: StabilityLevel should be passed STABLE, ALPHA or removed"),
|
err: fmt.Errorf("testdata/metric.go:6:20: StabilityLevel should be passed STABLE, ALPHA or removed"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewCounter(
|
var _ = metrics.NewCounter(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
StabilityLevel: "stable",
|
StabilityLevel: "stable",
|
||||||
@ -398,7 +472,7 @@ var _ = metrics.NewCounter(
|
|||||||
err: fmt.Errorf("testdata/metric.go:6:20: StabilityLevel should be passed STABLE, ALPHA or removed"),
|
err: fmt.Errorf("testdata/metric.go:6:20: StabilityLevel should be passed STABLE, ALPHA or removed"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewCounter(
|
var _ = metrics.NewCounter(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
StabilityLevel: metrics.UNKNOWN,
|
StabilityLevel: metrics.UNKNOWN,
|
||||||
@ -410,7 +484,7 @@ var _ = metrics.NewCounter(
|
|||||||
err: fmt.Errorf("testdata/metric.go:7:20: StabilityLevel should be passed STABLE, ALPHA or removed"),
|
err: fmt.Errorf("testdata/metric.go:7:20: StabilityLevel should be passed STABLE, ALPHA or removed"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var stable = metrics.STABLE
|
var stable = metrics.STABLE
|
||||||
var _ = metrics.NewCounter(
|
var _ = metrics.NewCounter(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
@ -423,7 +497,7 @@ var _ = metrics.NewCounter(
|
|||||||
err: fmt.Errorf("testdata/metric.go:6:10: Opts for STABLE metric was not directly passed to new metric function"),
|
err: fmt.Errorf("testdata/metric.go:6:10: Opts for STABLE metric was not directly passed to new metric function"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewCounter(getStableCounterOpts())
|
var _ = metrics.NewCounter(getStableCounterOpts())
|
||||||
func getStableCounterOpts() *metrics.CounterOpts {
|
func getStableCounterOpts() *metrics.CounterOpts {
|
||||||
return &metrics.CounterOpts{
|
return &metrics.CounterOpts{
|
||||||
@ -433,10 +507,10 @@ func getStableCounterOpts() *metrics.CounterOpts {
|
|||||||
`},
|
`},
|
||||||
{
|
{
|
||||||
testName: "error . package import of metric framework",
|
testName: "error . package import of metric framework",
|
||||||
err: fmt.Errorf(`testdata/metric.go:3:8: Importing through "." metrics framework is not supported`),
|
err: fmt.Errorf(`testdata/metric.go:3:8: Importing using "." is not supported`),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import . "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import . "k8s.io/component-base/metrics"
|
||||||
var _ = NewCounter(
|
var _ = NewCounter(
|
||||||
&CounterOpts{
|
&CounterOpts{
|
||||||
StabilityLevel: STABLE,
|
StabilityLevel: STABLE,
|
||||||
@ -448,7 +522,7 @@ var _ = NewCounter(
|
|||||||
err: fmt.Errorf("testdata/metric.go:4:9: Opts for STABLE metric was not directly passed to new metric function"),
|
err: fmt.Errorf("testdata/metric.go:4:9: Opts for STABLE metric was not directly passed to new metric function"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = RegisterMetric(
|
var _ = RegisterMetric(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
StabilityLevel: metrics.STABLE,
|
StabilityLevel: metrics.STABLE,
|
||||||
@ -460,7 +534,7 @@ var _ = RegisterMetric(
|
|||||||
err: fmt.Errorf("testdata/metric.go:4:9: Opts for STABLE metric was not directly passed to new metric function"),
|
err: fmt.Errorf("testdata/metric.go:4:9: Opts for STABLE metric was not directly passed to new metric function"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = test.RegisterMetric(
|
var _ = test.RegisterMetric(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
StabilityLevel: metrics.STABLE,
|
StabilityLevel: metrics.STABLE,
|
||||||
@ -472,12 +546,57 @@ var _ = test.RegisterMetric(
|
|||||||
err: fmt.Errorf("testdata/metric.go:6:4: Positional arguments are not supported"),
|
err: fmt.Errorf("testdata/metric.go:6:4: Positional arguments are not supported"),
|
||||||
src: `
|
src: `
|
||||||
package test
|
package test
|
||||||
import "k8s.io/kubernetes/staging/src/k8s.io/component-base/metrics"
|
import "k8s.io/component-base/metrics"
|
||||||
var _ = metrics.NewCounter(
|
var _ = metrics.NewCounter(
|
||||||
&metrics.CounterOpts{
|
&metrics.CounterOpts{
|
||||||
"counter",
|
"counter",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
`},
|
||||||
|
{
|
||||||
|
testName: "error stable historgram with unknown prometheus bucket variable",
|
||||||
|
err: fmt.Errorf("testdata/metric.go:9:13: Buckets should be set to list of floats, result from function call of prometheus.LinearBuckets or prometheus.ExponentialBuckets"),
|
||||||
|
src: `
|
||||||
|
package test
|
||||||
|
import "k8s.io/component-base/metrics"
|
||||||
|
import "github.com/prometheus/client_golang/prometheus"
|
||||||
|
var _ = metrics.NewHistogram(
|
||||||
|
&metrics.HistogramOpts{
|
||||||
|
Name: "histogram",
|
||||||
|
StabilityLevel: metrics.STABLE,
|
||||||
|
Buckets: prometheus.FakeBuckets,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
`},
|
||||||
|
{
|
||||||
|
testName: "error stable historgram with unknown bucket variable",
|
||||||
|
err: fmt.Errorf("testdata/metric.go:9:13: Buckets should be set to list of floats, result from function call of prometheus.LinearBuckets or prometheus.ExponentialBuckets"),
|
||||||
|
src: `
|
||||||
|
package test
|
||||||
|
import "k8s.io/component-base/metrics"
|
||||||
|
var buckets = []float64{1, 2, 3}
|
||||||
|
var _ = metrics.NewHistogram(
|
||||||
|
&metrics.HistogramOpts{
|
||||||
|
Name: "histogram",
|
||||||
|
StabilityLevel: metrics.STABLE,
|
||||||
|
Buckets: buckets,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
`},
|
||||||
|
{
|
||||||
|
testName: "error stable historgram with unknown bucket variable from unknown library",
|
||||||
|
err: fmt.Errorf("testdata/metric.go:9:13: Buckets should be set to list of floats, result from function call of prometheus.LinearBuckets or prometheus.ExponentialBuckets"),
|
||||||
|
src: `
|
||||||
|
package test
|
||||||
|
import "k8s.io/component-base/metrics"
|
||||||
|
import "github.com/fake_prometheus/prometheus"
|
||||||
|
var _ = metrics.NewHistogram(
|
||||||
|
&metrics.HistogramOpts{
|
||||||
|
Name: "histogram",
|
||||||
|
StabilityLevel: metrics.STABLE,
|
||||||
|
Buckets: prometheus.DefBuckets,
|
||||||
|
},
|
||||||
|
)
|
||||||
`},
|
`},
|
||||||
} {
|
} {
|
||||||
t.Run(test.testName, func(t *testing.T) {
|
t.Run(test.testName, func(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user