From 8e00ba29ca9fe845fdebdd586ed1505a2d6ee5d8 Mon Sep 17 00:00:00 2001 From: qiuming520 Date: Tue, 5 Jul 2022 11:38:33 +0800 Subject: [PATCH] add some unit tests for pkg/api (#4994) Signed-off-by: qiuming520 --- pkg/api/alerting/v2alpha1/types_test.go | 384 ++++++++++++++++++++++++ pkg/api/auditing/v1alpha1/types_test.go | 46 +++ pkg/api/events/v1alpha1/types_test.go | 47 +++ pkg/api/logging/v1alpha2/types_test.go | 77 +++++ pkg/api/metering/v1alpha1/types_test.go | 51 ++++ 5 files changed, 605 insertions(+) create mode 100644 pkg/api/alerting/v2alpha1/types_test.go create mode 100644 pkg/api/auditing/v1alpha1/types_test.go create mode 100644 pkg/api/events/v1alpha1/types_test.go create mode 100644 pkg/api/logging/v1alpha2/types_test.go create mode 100644 pkg/api/metering/v1alpha1/types_test.go diff --git a/pkg/api/alerting/v2alpha1/types_test.go b/pkg/api/alerting/v2alpha1/types_test.go new file mode 100644 index 000000000..fa441f586 --- /dev/null +++ b/pkg/api/alerting/v2alpha1/types_test.go @@ -0,0 +1,384 @@ +package v2alpha1 + +import ( + "errors" + "fmt" + "net/http" + "testing" + "time" + + "github.com/emicklei/go-restful" + "github.com/prometheus/prometheus/rules" + "github.com/stretchr/testify/assert" +) + +var ( + alertingRule = &AlertingRule{ + Id: "ca7f09e76954e67c", + Name: "test-cpu-usage-high", + Query: `namespace:workload_cpu_usage:sum{namespace="test"} > 1`, + Duration: "1m", + Annotations: map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + }, + Labels: map[string]string{ + "flags": "The flags is here", + "cpu_num": "The cpu_num is here", + }, + } + + postableAlertingRule = &PostableAlertingRule{ + AlertingRule: *alertingRule, + } + + gettableAlertingRule = &GettableAlertingRule{ + AlertingRule: *alertingRule, + Health: string(rules.HealthGood), + State: rules.StateInactive.String(), + } + + gettableAlertingRules = []*GettableAlertingRule{ + { + AlertingRule: *alertingRule, + Health: string(rules.HealthGood), + State: rules.StateInactive.String(), + EvaluationDurationSeconds: 1, + LastEvaluation: &time.Time{}, + }, + { + AlertingRule: AlertingRule{ + Id: "ca7f09e76954e688", + Name: "test-cpu-usage-high-2", + Query: `namespace:workload_cpu_usage:sum{namespace="test"} > 1`, + Duration: "1m", + Annotations: map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + }, + Labels: map[string]string{ + "flags": "The flags is here", + "cpu_num": "The cpu_num is here", + }, + }, + State: rules.StateInactive.String(), + Health: string(rules.HealthGood), + EvaluationDurationSeconds: 0, + LastEvaluation: &time.Time{}, + }, + } + + alertingRuleQueryParams = &AlertingRuleQueryParams{ + NameContainFilter: "test-cpu-usage-high", + State: rules.StateInactive.String(), + Health: string(rules.HealthGood), + LabelEqualFilters: map[string]string{ + "flags": "The flags is here", + "cpu_num": "The cpu_num is here", + }, + LabelContainFilters: map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + }, + PageNum: 1, + Limit: 10, + SortField: "name", + SortType: "desc", + } +) + +func TestPostableAlertingRule_Validate(t *testing.T) { + // validate AlertingRule name field + // Name is empty + postableAlertingRule.Name = "" + err := postableAlertingRule.Validate() + assert.Equal(t, "name can not be empty", err.Error()) + + // Name do not match regx + postableAlertingRule.Name = "TestCPUUsageHigh" + err = postableAlertingRule.Validate() + assert.Equal(t, "rule name must match regular expression ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", err.Error()) + + // validate AlertingRule Query field + postableAlertingRule.Name = "test-cpu-usage-high" + // Query is empty + postableAlertingRule.Query = "" + err = postableAlertingRule.Validate() + assert.Equal(t, "query can not be empty", err.Error()) + + postableAlertingRule.Query = `namespace:workload_cpu_usage:sum{namespace="test"} > 1` + // test no error + + err = postableAlertingRule.Validate() + assert.Empty(t, err) + +} + +func TestAlertQueryParams_Filter(t *testing.T) { + // empty + gettableAlertingRules := []*GettableAlertingRule{} + queryParams := &AlertingRuleQueryParams{} + ret := queryParams.Filter(gettableAlertingRules) + assert.Empty(t, ret) + + queryParams.NameContainFilter = "test-cpu-usage-high" + gettableAlertingRules = []*GettableAlertingRule{ + gettableAlertingRule, + } + ret = queryParams.Filter(gettableAlertingRules) + assert.NotEmpty(t, ret) +} + +func TestAlertQueryParams_match(t *testing.T) { + // empty + rule := &GettableAlertingRule{} + queryParams := &AlertingRuleQueryParams{} + ret := queryParams.matches(rule) + assert.True(t, ret) + + // Not empty + // test false case + queryParams.NameContainFilter = "test-cpu" + ret = queryParams.matches(rule) + assert.False(t, ret) + + //test true case + rule = gettableAlertingRule + queryParams.NameContainFilter = "test-cpu-usage-high" + ret = queryParams.matches(rule) + assert.True(t, ret) +} + +func TestAlertingRuleIdCompare(t *testing.T) { + leftId := "test-id-1" + rightId := "test-id-2" + + ret := AlertingRuleIdCompare(leftId, rightId) + assert.True(t, ret) +} + +func TestAlertQueryParams_Sort(t *testing.T) { + queryParams := alertingRuleQueryParams + rules := []*GettableAlertingRule{ + gettableAlertingRule, + gettableAlertingRule, + } + + // sort by name + queryParams.Sort(rules) + + // sort by lastEvaluation + queryParams.SortField = "lastEvaluation" + queryParams.Sort(rules) + + // sort by evaluationTime + queryParams.SortField = "evaluationTime" + queryParams.Sort(rules) +} + +func TestAlertQueryParams_Sub(t *testing.T) { + rules := gettableAlertingRules + queryParams := alertingRuleQueryParams + queryParams.Sub(rules) +} + +var ( + alertQueryParams = &AlertQueryParams{ + State: rules.StateFiring.String(), + LabelEqualFilters: map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + }, + LabelContainFilters: map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + }, + PageNum: 1, + Limit: 10, + } + + alert = &Alert{ + RuleId: "ca7f09e76954e67c", + RuleName: "test-cpu-usage-high", + State: rules.StateFiring.String(), + Value: `namespace:workload_cpu_usage:sum{namespace="test"} > 1`, + Annotations: map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + }, + Labels: map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + }, + ActiveAt: &time.Time{}, + } + + alerts = []*Alert{ + alert, + { + RuleId: "ca7f09e76954e699", + RuleName: "test-cpu-usage-high-2", + State: rules.StateFiring.String(), + Value: `namespace:workload_cpu_usage:sum{namespace="test"} > 1`, + Annotations: map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + }, + Labels: map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + }, + ActiveAt: &time.Time{}, + }, + } +) + +func TestAlertingRuleQueryParams_Filter(t *testing.T) { + // empty + // Alert Array is empty + loacalAlerts := []*Alert{} + queryParam := &AlertQueryParams{} + ret := queryParam.Filter(loacalAlerts) + assert.Empty(t, ret) + + // Alert Array has nil + loacalAlerts = []*Alert{nil} + ret = queryParam.Filter(loacalAlerts) + assert.Empty(t, ret) + + // all pass + loacalAlerts = alerts + ret = queryParam.Filter(loacalAlerts) + assert.NotEmpty(t, ret) +} + +func TestAlertingRuleQueryParams_matches(t *testing.T) { + loacalAlert := alert + queryParam := alertQueryParams + queryParam.LabelEqualFilters = map[string]string{ + "flags": "The flags is here", + "cpu_num": "The cpu_num is here", + } + ret := queryParam.matches(loacalAlert) + assert.False(t, ret) + + queryParam.LabelEqualFilters = map[string]string{ + "alias": "The alias is here", + "description": "The description is here", + } + ret = queryParam.matches(loacalAlert) + assert.True(t, ret) +} + +func TestAlertingRuleQueryParams_Sort(t *testing.T) { + loacalAlerts := alerts + queryParam := alertQueryParams + queryParam.Sort(loacalAlerts) +} + +func TestAlertingRuleQueryParams_Sub(t *testing.T) { + loacalAlerts := alerts + queryParam := alertQueryParams + queryParam.Sub(loacalAlerts) +} + +var ( + succBulkItemResponse = BulkItemResponse{ + RuleName: "test-cpu-usage-high", + Status: StatusSuccess, + Result: ResultCreated, + ErrorType: "", + Error: nil, + ErrorStr: "", + } + + errBulkItemResponse = BulkItemResponse{ + RuleName: "test-mem-usage-high", + Status: StatusError, + Result: ResultUpdated, + ErrorType: ErrBadData, + Error: errors.New(string(ErrBadData)), + ErrorStr: string(ErrBadData), + } + + bulkResponse = BulkResponse{ + Items: []*BulkItemResponse{ + &succBulkItemResponse, + &errBulkItemResponse, + }, + } +) + +func TestParseAlertingRuleQueryParams(t *testing.T) { + queryParam := "name=test-cpu&state=firing&health=ok&sort_field=lastEvaluation&sort_type=desc&label_filters=name~test" + req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost/alerting.kubesphere.io/v2alpha1/rules?%s", queryParam), nil) + if err != nil { + t.Fatal(err) + } + + expected := AlertingRuleQueryParams{ + NameContainFilter: "test-cpu", + State: "firing", + Health: "ok", + LabelEqualFilters: make(map[string]string), + LabelContainFilters: map[string]string{"name": "test"}, + + PageNum: 1, + Limit: 10, + SortField: "lastEvaluation", + SortType: "desc", + } + + request := restful.NewRequest(req) + actual, err := ParseAlertingRuleQueryParams(request) + assert.NoError(t, err) + assert.Equal(t, &expected, actual) +} + +func TestParseAlertQueryParams(t *testing.T) { + queryParam := "state=firing&label_filters=name~test" + req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost/alerting.kubesphere.io/v2alpha1/alerts?%s", queryParam), nil) + if err != nil { + t.Fatal(err) + } + + expected := AlertQueryParams{ + State: "firing", + LabelEqualFilters: make(map[string]string), + LabelContainFilters: map[string]string{"name": "test"}, + + PageNum: 1, + Limit: 10, + } + + request := restful.NewRequest(req) + actual, err := ParseAlertQueryParams(request) + assert.NoError(t, err) + assert.Equal(t, &expected, actual) +} + +func TestBulkResponse_MakeBulkResponse(t *testing.T) { + br := bulkResponse.MakeBulkResponse() + assert.True(t, br.Errors) +} + +func TestBulkResponse_NewBulkItemSuccessResponse(t *testing.T) { + ruleName := "test-cpu-usage-high" + result := ResultCreated + ret := NewBulkItemSuccessResponse(ruleName, result) + assert.Equal(t, ResultCreated, ret.Result) +} + +func TestBulkResponse_NewBulkItemErrorServerResponse(t *testing.T) { + ruleName := "test-cpu-usage-high" + err := errors.New(string(ErrBadData)) + ret := NewBulkItemErrorServerResponse(ruleName, err) + assert.Equal(t, errors.New(string(ErrBadData)), ret.Error) +} + +func TestContainsCaseInsensitive(t *testing.T) { + left := "left" + right := "RIGHT" + ret := containsCaseInsensitive(left, right) + assert.False(t, ret) +} diff --git a/pkg/api/auditing/v1alpha1/types_test.go b/pkg/api/auditing/v1alpha1/types_test.go new file mode 100644 index 000000000..5c47a196f --- /dev/null +++ b/pkg/api/auditing/v1alpha1/types_test.go @@ -0,0 +1,46 @@ +package v1alpha1 + +import ( + "fmt" + "net/http" + "testing" + "time" + + "github.com/emicklei/go-restful" + "github.com/stretchr/testify/assert" +) + +func TestParseQueryParameter(t *testing.T) { + queryParam := "operation=query&workspace_filter=my-ws,demo-ws&workspace_search=my,demo&objectref_namespace_filter=my-ns,my-test&objectref_namespace_search=my&objectref_name_filter=my-ref,demo-ref&objectref_name_search=ref&source_ip_search=192.168.&user_filter=user1&user_search=my,demo&group_search=my,demo&start_time=1136214245&end_time=1136214245&from=0&sort=desc" + req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost/tenant.kubesphere.io/v2alpha1/auditing/events?%s", queryParam), nil) + if err != nil { + t.Fatal(err) + } + + expected := Query{ + Operation: "query", + WorkspaceFilter: "my-ws,demo-ws", + WorkspaceSearch: "my,demo", + ObjectRefNamespaceFilter: "my-ns,my-test", + ObjectRefNamespaceSearch: "my", + ObjectRefNameFilter: "my-ref,demo-ref", + ObjectRefNameSearch: "ref", + UserFilter: "user1", + UserSearch: "my,demo", + GroupSearch: "my,demo", + SourceIpSearch: "192.168.", + + StartTime: time.Unix(1136214245, 0), + EndTime: time.Unix(1136214245, 0), + + Interval: "15m", + Sort: "desc", + From: int64(0), + Size: int64(10), + } + + request := restful.NewRequest(req) + actual, err := ParseQueryParameter(request) + assert.NoError(t, err) + assert.Equal(t, &expected, actual) +} diff --git a/pkg/api/events/v1alpha1/types_test.go b/pkg/api/events/v1alpha1/types_test.go new file mode 100644 index 000000000..571c5ebf8 --- /dev/null +++ b/pkg/api/events/v1alpha1/types_test.go @@ -0,0 +1,47 @@ +package v1alpha1 + +import ( + "fmt" + "net/http" + "testing" + "time" + + "github.com/emicklei/go-restful" + "github.com/stretchr/testify/assert" +) + +func TestParseQueryParameter(t *testing.T) { + queryParam := "operation=query&workspace_filter=my-ws,demo-ws&workspace_search=my,demo&involved_object_namespace_filter=my-ns,my-test&involved_object_namespace_search=my&involved_object_name_filter=my-involvedObject,demo-involvedObject&involved_object_name_search=involvedObject&involved_object_kind_filter=involvedObject.kind&reason_filter=reason.filter&reason_search=reason&message_search=message&type_filter=Normal&interval=15m&start_time=1136214245&end_time=1136214245&from=0&sort=desc" + req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost/tenant.kubesphere.io/v2alpha1/events?%s", queryParam), nil) + if err != nil { + t.Fatal(err) + } + + expected := Query{ + Operation: "query", + WorkspaceFilter: "my-ws,demo-ws", + WorkspaceSearch: "my,demo", + InvolvedObjectNamespaceFilter: "my-ns,my-test", + InvolvedObjectNamespaceSearch: "my", + InvolvedObjectNameFilter: "my-involvedObject,demo-involvedObject", + InvolvedObjectNameSearch: "involvedObject", + InvolvedObjectKindFilter: "involvedObject.kind", + ReasonFilter: "reason.filter", + ReasonSearch: "reason", + MessageSearch: "message", + TypeFilter: "Normal", + + StartTime: time.Unix(1136214245, 0), + EndTime: time.Unix(1136214245, 0), + + Interval: "15m", + Sort: "desc", + From: int64(0), + Size: int64(10), + } + + request := restful.NewRequest(req) + actual, err := ParseQueryParameter(request) + assert.NoError(t, err) + assert.Equal(t, &expected, actual) +} diff --git a/pkg/api/logging/v1alpha2/types_test.go b/pkg/api/logging/v1alpha2/types_test.go new file mode 100644 index 000000000..69f7dc66c --- /dev/null +++ b/pkg/api/logging/v1alpha2/types_test.go @@ -0,0 +1,77 @@ +package v1alpha2 + +import ( + "fmt" + "net/http" + "testing" + "time" + + "github.com/emicklei/go-restful" + "github.com/stretchr/testify/assert" +) + +func TestParseQueryParameter(t *testing.T) { + // default operation -- query + defaultParam := "namespaces=default,my-ns,my-test&namespace_query=default,my&workloads=my-wl,demo-wl&workload_query=wl&pods=my-po,demo-po&pod_query=po&containers=my-cont,demo-cont&container_query=cont&log_query=ERR&start_time=1136214245&end_time=1136214245&from=0&sort=desc" + req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost/tenant.kubesphere.io/v2alpha1/logs?%s", defaultParam), nil) + if err != nil { + t.Fatal(err) + } + + expected := Query{ + Operation: OperationQuery, + NamespaceFilter: "default,my-ns,my-test", + NamespaceSearch: "default,my", + WorkloadFilter: "my-wl,demo-wl", + WorkloadSearch: "wl", + PodFilter: "my-po,demo-po", + PodSearch: "po", + ContainerFilter: "my-cont,demo-cont", + ContainerSearch: "cont", + LogSearch: "ERR", + + StartTime: time.Unix(1136214245, 0), + EndTime: time.Unix(1136214245, 0), + + Sort: OrderDescending, + From: int64(0), + Size: int64(10), + } + + request := restful.NewRequest(req) + actual, err := ParseQueryParameter(request) + assert.NoError(t, err) + assert.Equal(t, &expected, actual) + + // histogram operation + queryParamInterval := "operation=histogram&interval=15m&" + defaultParam + reqInterval, err := http.NewRequest("GET", fmt.Sprintf("http://localhost/tenant.kubesphere.io/v2alpha1/logs?%s", queryParamInterval), nil) + if err != nil { + t.Fatal(err) + } + + expected = Query{ + Operation: OperationHistogram, + NamespaceFilter: "default,my-ns,my-test", + NamespaceSearch: "default,my", + WorkloadFilter: "my-wl,demo-wl", + WorkloadSearch: "wl", + PodFilter: "my-po,demo-po", + PodSearch: "po", + ContainerFilter: "my-cont,demo-cont", + ContainerSearch: "cont", + LogSearch: "ERR", + + StartTime: time.Unix(1136214245, 0), + EndTime: time.Unix(1136214245, 0), + + Interval: DefaultInterval, + From: int64(0), + Size: int64(0), + } + + requestInterval := restful.NewRequest(reqInterval) + actual, err = ParseQueryParameter(requestInterval) + assert.NoError(t, err) + assert.Equal(t, &expected, actual) +} diff --git a/pkg/api/metering/v1alpha1/types_test.go b/pkg/api/metering/v1alpha1/types_test.go new file mode 100644 index 000000000..b1f013bf1 --- /dev/null +++ b/pkg/api/metering/v1alpha1/types_test.go @@ -0,0 +1,51 @@ +package v1alpha1 + +import ( + "fmt" + "net/http" + "testing" + + "github.com/emicklei/go-restful" + "github.com/stretchr/testify/assert" + + "kubesphere.io/kubesphere/pkg/simple/client/monitoring" +) + +func TestParseQueryParameter(t *testing.T) { + queryParam := "level=LevelCluster&operation=query&time=1559347600&start=1559347200&end=1561939200&step=10m&sort_metric=meter_workspace_cpu_usage&sort_type=desc&page=1&limit=5&metrics_filter=meter_workspace_cpu_usage|meter_workspace_memory_usage&resources_filter=cpu&workspace=my-ws&namespace=my-ns&node=my-node&kind=deployment&workload=my-wl&pod=my-pod&applications=nignx&services=my-svc&storageclass=nfs&pvc_filter=my-pvc&cluster=my-cluster" + req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost/tenant.kubesphere.io/v2alpha1/metering?%s", queryParam), nil) + if err != nil { + t.Fatal(err) + } + + expected := Query{ + Level: monitoring.Level(1), + Operation: "query", + LabelSelector: "", + Time: "1559347600", + Start: "1559347200", + End: "1561939200", + Step: "10m", + Target: "meter_workspace_cpu_usage", + Order: "desc", + Page: "1", + Limit: "5", + MetricFilter: "meter_workspace_cpu_usage|meter_workspace_memory_usage", + ResourceFilter: "cpu", + NodeName: "my-node", + WorkspaceName: "my-ws", + NamespaceName: "my-ns", + WorkloadKind: "deployment", + WorkloadName: "my-wl", + PodName: "my-pod", + Applications: "nignx", + Services: "my-svc", + StorageClassName: "nfs", + PVCFilter: "my-pvc", + Cluster: "my-cluster", + } + + request := restful.NewRequest(req) + actual := ParseQueryParameter(request) + assert.Equal(t, &expected, actual) +}