From a3a0371203f30bcad8406a8dd31dd7743a3b95d2 Mon Sep 17 00:00:00 2001 From: huanggze Date: Tue, 14 Jan 2020 16:37:17 +0800 Subject: [PATCH] filter out metrics with empty resource_name when sorting Signed-off-by: huanggze --- pkg/models/metrics/util.go | 6 +- pkg/models/metrics/util_test.go | 315 ++++++++++++++++++++++++++++++++ 2 files changed, 318 insertions(+), 3 deletions(-) create mode 100644 pkg/models/metrics/util_test.go diff --git a/pkg/models/metrics/util.go b/pkg/models/metrics/util.go index bead04ff4..7f1686e7d 100644 --- a/pkg/models/metrics/util.go +++ b/pkg/models/metrics/util.go @@ -126,7 +126,7 @@ func (rawMetrics *Response) SortBy(sortMetricName string, sortType string) (*Res // record the ordering of resource_name to indexMap // example: {"metric":{ResultItemMetricResourceName: "Deployment:xxx"},"value":[1541142931.731,"3"]} resourceName, exist := r.Metric[ResultItemMetricResourceName] - if exist { + if exist && resourceName != "" { if _, exist := indexMap[resourceName]; !exist { indexMap[resourceName] = i i = i + 1 @@ -138,7 +138,7 @@ func (rawMetrics *Response) SortBy(sortMetricName string, sortType string) (*Res // iterator all metric to find max metricItems length for _, r := range metricItem.Data.Result { k, ok := r.Metric[ResultItemMetricResourceName] - if ok { + if ok && k != "" { currentResourceMap[k] = 1 } } @@ -167,7 +167,7 @@ func (rawMetrics *Response) SortBy(sortMetricName string, sortType string) (*Res for j := 0; j < len(re.Data.Result); j++ { r := re.Data.Result[j] k, exist := r.Metric[ResultItemMetricResourceName] - if exist { + if exist && k != "" { index, exist := indexMap[k] if exist { sortedMetric[index] = r diff --git a/pkg/models/metrics/util_test.go b/pkg/models/metrics/util_test.go new file mode 100644 index 000000000..55e6b7fed --- /dev/null +++ b/pkg/models/metrics/util_test.go @@ -0,0 +1,315 @@ +package metrics + +import ( + "kubesphere.io/kubesphere/pkg/api/monitoring/v1alpha2" + "reflect" + "testing" +) + +func TestSortBy(t *testing.T) { + tests := []struct { + description string + rawMetrics *Response + sortMetrics string + sortType string + expected *Response + }{ + { + description: "sort a set of node metrics for node1, node2 and a node with blank name (this should be considered as abnormal).", + rawMetrics: &Response{ + Results: []APIResponse{ + { + MetricName: "node_cpu_usage", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "0.221"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "0.177"}, + }, + { + Metric: map[string]string{"resource_name": ""}, + Value: []interface{}{1578987135.334, ""}, + }, + }, + }, + }, + }, + { + MetricName: "node_memory_total", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "8201043968"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "8201039872"}, + }, + { + Metric: map[string]string{"resource_name": ""}, + Value: []interface{}{1578987135.334, ""}, + }, + }, + }, + }, + }, + { + MetricName: "node_pod_running_count", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "19"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "6"}, + }, + { + Metric: map[string]string{"resource_name": ""}, + Value: []interface{}{1578987135.334, ""}, + }, + }, + }, + }, + }, + }, + }, + sortMetrics: "node_cpu_usage", + sortType: "desc", + expected: &Response{ + Results: []APIResponse{ + { + MetricName: "node_cpu_usage", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "0.221"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "0.177"}, + }, + }, + }, + }, + }, + { + MetricName: "node_memory_total", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "8201043968"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "8201039872"}, + }, + }, + }, + }, + }, + { + MetricName: "node_pod_running_count", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "19"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "6"}, + }, + }, + }, + }, + }, + }, + }, + }, + { + description: "sort a set of node metrics for node1, node2 and node3.", + rawMetrics: &Response{ + Results: []APIResponse{ + { + MetricName: "node_cpu_usage", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "0.221"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "0.177"}, + }, + { + Metric: map[string]string{"resource_name": "node3"}, + Value: []interface{}{1578987135.334, "0.194"}, + }, + }, + }, + }, + }, + { + MetricName: "node_memory_total", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "8201043968"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "8201039872"}, + }, + { + Metric: map[string]string{"resource_name": "node3"}, + Value: []interface{}{1578987135.334, "8201056256"}, + }, + }, + }, + }, + }, + { + MetricName: "node_pod_running_count", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "19"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "6"}, + }, + { + Metric: map[string]string{"resource_name": "node3"}, + Value: []interface{}{1578987135.334, "14"}, + }, + }, + }, + }, + }, + }, + }, + sortMetrics: "node_cpu_usage", + sortType: "desc", + expected: &Response{ + Results: []APIResponse{ + { + MetricName: "node_cpu_usage", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "0.221"}, + }, + { + Metric: map[string]string{"resource_name": "node3"}, + Value: []interface{}{1578987135.334, "0.194"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "0.177"}, + }, + }, + }, + }, + }, + { + MetricName: "node_memory_total", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "8201043968"}, + }, + { + Metric: map[string]string{"resource_name": "node3"}, + Value: []interface{}{1578987135.334, "8201056256"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "8201039872"}, + }, + }, + }, + }, + }, + { + MetricName: "node_pod_running_count", + APIResponse: v1alpha2.APIResponse{ + Status: "success", + Data: v1alpha2.QueryResult{ + ResultType: "vector", + Result: []v1alpha2.QueryValue{ + { + Metric: map[string]string{"resource_name": "node1"}, + Value: []interface{}{1578987135.334, "19"}, + }, + { + Metric: map[string]string{"resource_name": "node3"}, + Value: []interface{}{1578987135.334, "14"}, + }, + { + Metric: map[string]string{"resource_name": "node2"}, + Value: []interface{}{1578987135.334, "6"}, + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, test := range tests { + res, _ := test.rawMetrics.SortBy(test.sortMetrics, test.sortType) + if !reflect.DeepEqual(res, test.expected) { + t.Errorf("got unexpected results: %v", res) + } + } +}