| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package autocomplete
- import (
- "errors"
- "testing"
- "time"
- "github.com/opencost/opencost/core/pkg/filter"
- "github.com/opencost/opencost/core/pkg/opencost"
- "github.com/opencost/opencost/core/pkg/util/httputil"
- )
- func validateTestField(field string) (string, error) {
- if field == "" {
- return "", ErrBadRequest
- }
- return field, nil
- }
- func TestNormalizeRequest(t *testing.T) {
- start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
- req := &Request{
- TenantID: "t1",
- Field: "cluster",
- Search: " x ",
- Limit: 0,
- Window: opencost.NewClosedWindow(start, start.Add(24*time.Hour)),
- }
- field, err := NormalizeRequest(req, validateTestField, NormalizeOptions{RequireTenantID: true})
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- if field != "cluster" || req.Search != "x" || req.Limit != DefaultResultLimit {
- t.Fatalf("unexpected normalized request: %+v", req)
- }
- _, err = NormalizeRequest(req, validateTestField, NormalizeOptions{RequireTenantID: true, EnsureLabelConfig: true})
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- if req.LabelConfig == nil {
- t.Fatal("expected default label config")
- }
- _, err = NormalizeRequest(nil, validateTestField, NormalizeOptions{})
- if err == nil || !errors.Is(err, ErrBadRequest) {
- t.Fatalf("expected nil request error, got %v", err)
- }
- openReq := &Request{Field: "cluster", Window: opencost.NewWindow(&start, nil)}
- _, err = NormalizeRequest(openReq, validateTestField, NormalizeOptions{})
- if err == nil || !errors.Is(err, ErrBadRequest) {
- t.Fatalf("expected open window error, got %v", err)
- }
- _, err = NormalizeRequest(&Request{Field: "cluster", Window: req.Window}, validateTestField, NormalizeOptions{RequireTenantID: true})
- if err == nil || !errors.Is(err, ErrBadRequest) {
- t.Fatalf("expected tenant ID error, got %v", err)
- }
- limitReq := &Request{
- TenantID: "t1",
- Field: "cluster",
- Window: opencost.NewClosedWindow(start, start.Add(24*time.Hour)),
- Limit: MaxResultLimit + 1,
- }
- _, err = NormalizeRequest(limitReq, validateTestField, NormalizeOptions{RequireTenantID: true})
- if err == nil || !errors.Is(err, ErrBadRequest) {
- t.Fatalf("expected limit error, got %v", err)
- }
- }
- func TestDefaultWindowValidator(t *testing.T) {
- start := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
- end := start.Add(time.Hour)
- if err := DefaultWindowValidator(opencost.NewClosedWindow(start, end)); err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- if err := DefaultWindowValidator(opencost.NewWindow(&start, nil)); err == nil {
- t.Fatal("expected open window error")
- }
- }
- func TestParseRequest(t *testing.T) {
- windowStr := "2023-01-01T00:00:00Z,2023-01-02T00:00:00Z"
- qp := httputil.NewQueryParams(map[string][]string{
- "window": {windowStr},
- "field": {"cluster"},
- "search": {" ns "},
- "tenantId": {"t1"},
- })
- got, err := ParseRequest(qp, ParseOptions{}, validateTestField, nil)
- if err != nil {
- t.Fatalf("ParseRequest() error = %v", err)
- }
- if got.Field != "cluster" || got.Search != "ns" || got.TenantID != "t1" {
- t.Fatalf("unexpected request: %+v", got)
- }
- _, err = ParseRequest(httputil.NewQueryParams(map[string][]string{"field": {"cluster"}}), ParseOptions{}, validateTestField, nil)
- if err == nil || !errors.Is(err, ErrBadRequest) {
- t.Fatalf("expected missing window error, got %v", err)
- }
- _, err = ParseRequest(httputil.NewQueryParams(map[string][]string{
- "window": {"bad"},
- "field": {"cluster"},
- }), ParseOptions{}, validateTestField, nil)
- if err == nil || !errors.Is(err, ErrBadRequest) {
- t.Fatalf("expected invalid window error, got %v", err)
- }
- offset := 5 * time.Hour
- _, err = ParseRequest(qp, ParseOptions{UTCOffset: &offset}, validateTestField, nil)
- if err != nil {
- t.Fatalf("ParseRequest with offset error = %v", err)
- }
- noFilterQP := httputil.NewQueryParams(map[string][]string{
- "window": {windowStr},
- "field": {"cluster"},
- "filter": {"cluster:\"prod\""},
- })
- _, err = ParseRequest(noFilterQP, ParseOptions{}, validateTestField, nil)
- if err == nil || !errors.Is(err, ErrBadRequest) {
- t.Fatalf("expected filter parser required error, got %v", err)
- }
- parseFilter := func(filterString string) (filter.Filter, error) {
- if filterString == "bad" {
- return nil, errors.New("bad filter")
- }
- return nil, nil
- }
- badFilterQP := httputil.NewQueryParams(map[string][]string{
- "window": {windowStr},
- "field": {"cluster"},
- "filter": {"bad"},
- })
- _, err = ParseRequest(badFilterQP, ParseOptions{}, validateTestField, parseFilter)
- if err == nil || !errors.Is(err, ErrBadRequest) {
- t.Fatalf("expected filter parse error, got %v", err)
- }
- okFilterQP := httputil.NewQueryParams(map[string][]string{
- "window": {windowStr},
- "field": {"cluster"},
- "filter": {"ok"},
- })
- got, err = ParseRequest(okFilterQP, ParseOptions{}, validateTestField, parseFilter)
- if err != nil {
- t.Fatalf("ParseRequest with filter error = %v", err)
- }
- if got.Field != "cluster" {
- t.Fatalf("unexpected request: %+v", got)
- }
- }
|