Return a value when atleast one of the metrics returns a value (#47)

* Return a value when atleast one of the metrics returns a value

Signed-off-by: Arjun Naik <arjun.rn@gmail.com>

* Added test for max weighted collector

Signed-off-by: Arjun Naik <arjun.rn@gmail.com>
This commit is contained in:
Arjun
2019-04-26 17:54:25 +02:00
committed by GitHub
parent f097e63401
commit 2eed3e64d0
2 changed files with 92 additions and 3 deletions

View File

@@ -2,8 +2,10 @@ package collector
import (
"fmt"
"k8s.io/apimachinery/pkg/api/resource"
"strings"
"time"
"k8s.io/apimachinery/pkg/api/resource"
)
// MaxWeightedCollector is a simple aggregator collector that returns the maximum value
@@ -25,18 +27,29 @@ func NewMaxWeightedCollector(interval time.Duration, weight float64, collectors
// GetMetrics gets metrics from all collectors and return the higest value.
func (c *MaxWeightedCollector) GetMetrics() ([]CollectedMetric, error) {
errors := make([]error, 0)
collectedMetrics := make([]CollectedMetric, 0)
for _, collector := range c.collectors {
values, err := collector.GetMetrics()
if err != nil {
return nil, err
errors = append(errors, err)
continue
}
for _, v := range values {
collectedMetrics = append(collectedMetrics, v)
}
}
if len(collectedMetrics) == 0 {
return nil, fmt.Errorf("no metrics collected, cannot determine max")
if len(errors) == 0 {
return nil, fmt.Errorf("no metrics collected, cannot determine max")
} else {
errorStrings := make([]string, len(errors))
for i, e := range errors {
errorStrings[i] = e.Error()
}
allErrors := strings.Join(errorStrings, ",")
return nil, fmt.Errorf("could not determine maximum due to errors: %s", allErrors)
}
}
max := collectedMetrics[0]
for _, value := range collectedMetrics {

View File

@@ -0,0 +1,76 @@
package collector
import (
"fmt"
"testing"
"time"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/metrics/pkg/apis/custom_metrics"
)
type dummyCollector struct {
value int64
}
func (c dummyCollector) Interval() time.Duration {
return time.Second
}
func (c dummyCollector) GetMetrics() ([]CollectedMetric, error) {
if c.value > 0 {
quantity := resource.NewQuantity(c.value, resource.DecimalSI)
return []CollectedMetric{
{
Custom: custom_metrics.MetricValue{
Value: *quantity,
},
},
}, nil
} else {
return nil, fmt.Errorf("test error")
}
}
func TestMaxCollector(t *testing.T) {
for _, tc := range []struct {
name string
values []int64
expected int
weight float64
}{
{
name: "basic",
values: []int64{100, 10, 9},
expected: 100,
weight: 1,
},
{
name: "weighted",
values: []int64{100, 10, 9},
expected: 20,
weight: 0.2,
},
{
name: "with error",
values: []int64{-1, 10, 9},
expected: 5,
weight: 0.5,
},
} {
t.Run(tc.name, func(t *testing.T) {
collectors := make([]Collector, len(tc.values))
for i, v := range tc.values {
collectors[i] = dummyCollector{value: v}
}
wc := NewMaxWeightedCollector(time.Second, tc.weight, collectors...)
metrics, err := wc.GetMetrics()
require.NoError(t, err)
require.Len(t, metrics, 1)
require.EqualValues(t, tc.expected, metrics[0].Custom.Value.Value())
})
}
}