From 04fd6543fd2ccaa7405061e4d34e36d9abe02157 Mon Sep 17 00:00:00 2001 From: yusing Date: Tue, 17 Sep 2024 04:51:26 +0800 Subject: [PATCH] README update for sonarcloud badges, simplify some test code, fixed some sonarlint issues --- Dockerfile | 5 +- README.md | 6 +++ src/api/v1/list.go | 6 +-- src/docker/label_parser_test.go | 86 +++++++++++---------------------- src/error/error_test.go | 44 ++++++++--------- src/utils/testing.go | 46 ++++++++++++++++++ 6 files changed, 106 insertions(+), 87 deletions(-) create mode 100644 src/utils/testing.go diff --git a/Dockerfile b/Dockerfile index 2467d0a2..f17aa7f6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,13 +2,12 @@ FROM golang:1.23.1-alpine AS builder COPY src /src ENV GOCACHE=/root/.cache/go-build WORKDIR /src -RUN --mount=type=cache,target="/go/pkg/mod" \ - go mod download RUN --mount=type=cache,target="/go/pkg/mod" \ --mount=type=cache,target="/root/.cache/go-build" \ + go mod download CGO_ENABLED=0 GOOS=linux go build -pgo=auto -o go-proxy github.com/yusing/go-proxy -FROM alpine:latest +FROM alpine:3.20 LABEL maintainer="yusing@6uo.me" diff --git a/README.md b/README.md index f0ec0045..15fa5f0f 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # go-proxy +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=yusing_go-proxy&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=yusing_go-proxy) +[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=yusing_go-proxy&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=yusing_go-proxy) +[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=yusing_go-proxy&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=yusing_go-proxy) +[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=yusing_go-proxy&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=yusing_go-proxy) +[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=yusing_go-proxy&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=yusing_go-proxy) + A [lightweight](docs/benchmark_result.md), easy-to-use, and efficient reverse proxy and load balancer with a web UI. **Table of content** diff --git a/src/api/v1/list.go b/src/api/v1/list.go index c557ed79..66bf9c06 100644 --- a/src/api/v1/list.go +++ b/src/api/v1/list.go @@ -29,10 +29,10 @@ func List(cfg *config.Config, w http.ResponseWriter, r *http.Request) { func listRoutes(cfg *config.Config, w http.ResponseWriter, r *http.Request) { routes := cfg.RoutesByAlias() - type_filter := r.FormValue("type") - if type_filter != "" { + typeFilter := r.FormValue("type") + if typeFilter != "" { for k, v := range routes { - if v["type"] != type_filter { + if v["type"] != typeFilter { delete(routes, k) } } diff --git a/src/docker/label_parser_test.go b/src/docker/label_parser_test.go index a7ab312b..7dbc2812 100644 --- a/src/docker/label_parser_test.go +++ b/src/docker/label_parser_test.go @@ -7,6 +7,7 @@ import ( "testing" E "github.com/yusing/go-proxy/error" + . "github.com/yusing/go-proxy/utils" ) func makeLabel(namespace string, alias string, field string) string { @@ -18,29 +19,23 @@ func TestHomePageLabel(t *testing.T) { field := "ip" v := "bar" pl, err := ParseLabel(makeLabel(NSHomePage, alias, field), v) - if err.IsNotNil() { - t.Errorf("expected err=nil, got %s", err.Error()) - } + ExpectErrNil(t, err) if pl.Target != alias { - t.Errorf("expected alias=%s, got %s", alias, pl.Target) + t.Errorf("Expected alias=%s, got %s", alias, pl.Target) } if pl.Attribute != field { - t.Errorf("expected field=%s, got %s", field, pl.Target) + t.Errorf("Expected field=%s, got %s", field, pl.Target) } if pl.Value != v { - t.Errorf("expected value=%q, got %s", v, pl.Value) + t.Errorf("Expected value=%q, got %s", v, pl.Value) } } func TestStringProxyLabel(t *testing.T) { v := "bar" pl, err := ParseLabel(makeLabel(NSProxy, "foo", "ip"), v) - if err.IsNotNil() { - t.Errorf("expected err=nil, got %s", err.Error()) - } - if pl.Value != v { - t.Errorf("expected value=%q, got %s", v, pl.Value) - } + ExpectErrNil(t, err) + ExpectEqual(t, pl.Value, v) } func TestBoolProxyLabelValid(t *testing.T) { @@ -57,12 +52,8 @@ func TestBoolProxyLabelValid(t *testing.T) { for k, v := range tests { pl, err := ParseLabel(makeLabel(NSProxy, "foo", "no_tls_verify"), k) - if err.IsNotNil() { - t.Errorf("expected err=nil, got %s", err.Error()) - } - if pl.Value != v { - t.Errorf("expected value=%v, got %v", v, pl.Value) - } + ExpectErrNil(t, err) + ExpectEqual(t, pl.Value, v) } } @@ -71,7 +62,7 @@ func TestBoolProxyLabelInvalid(t *testing.T) { field := "no_tls_verify" _, err := ParseLabel(makeLabel(NSProxy, alias, field), "invalid") if !err.Is(E.ErrInvalid) { - t.Errorf("expected err InvalidProxyLabel, got %s", err.Error()) + t.Errorf("Expected err InvalidProxyLabel, got %s", err.Error()) } } @@ -87,17 +78,12 @@ X-Custom-Header2: boo` } pl, err := ParseLabel(makeLabel(NSProxy, "foo", "set_headers"), v) - if err.IsNotNil() { - t.Errorf("expected err=nil, got %s", err.Error()) - } - hGot, ok := pl.Value.(map[string]string) - if !ok { - t.Errorf("value is not a map[string]string, but %T", pl.Value) - return - } - if !reflect.DeepEqual(h, hGot) { - t.Errorf("expected %v, got %v", h, hGot) + ExpectErrNil(t, err) + hGot := ExpectType[map[string]string](t, pl.Value) + if hGot != nil && !reflect.DeepEqual(h, hGot) { + t.Errorf("Expected %v, got %v", h, hGot) } + } func TestSetHeaderProxyLabelInvalid(t *testing.T) { @@ -110,7 +96,7 @@ func TestSetHeaderProxyLabelInvalid(t *testing.T) { for _, v := range tests { _, err := ParseLabel(makeLabel(NSProxy, "foo", "set_headers"), v) if !err.Is(E.ErrInvalid) { - t.Errorf("expected invalid err for %q, got %s", v, err.Error()) + t.Errorf("Expected invalid err for %q, got %s", v, err.Error()) } } } @@ -123,47 +109,33 @@ func TestHideHeadersProxyLabel(t *testing.T) { ` v = strings.TrimPrefix(v, "\n") pl, err := ParseLabel(makeLabel(NSProxy, "foo", "hide_headers"), v) - if err.IsNotNil() { - t.Errorf("expected err=nil, got %s", err.Error()) - } - sGot, ok := pl.Value.([]string) + ExpectErrNil(t, err) + sGot := ExpectType[[]string](t, pl.Value) sWant := []string{"X-Custom-Header1", "X-Custom-Header2", "X-Custom-Header3"} - if !ok { - t.Errorf("value is not []string, but %T", pl.Value) - } - if !reflect.DeepEqual(sGot, sWant) { - t.Errorf("expected %q, got %q", sWant, sGot) + if sGot != nil { + ExpectEqual(t, sGot, sWant) } } func TestCommaSepProxyLabelSingle(t *testing.T) { v := "a" pl, err := ParseLabel("proxy.aliases", v) - if err.IsNotNil() { - t.Errorf("expected err=nil, got %s", err.Error()) - } - sGot, ok := pl.Value.([]string) + ExpectErrNil(t, err) + sGot := ExpectType[[]string](t, pl.Value) sWant := []string{"a"} - if !ok { - t.Errorf("value is not []string, but %T", pl.Value) - } - if !reflect.DeepEqual(sGot, sWant) { - t.Errorf("expected %q, got %q", sWant, sGot) + if sGot != nil { + ExpectEqual(t, sGot, sWant) } + } func TestCommaSepProxyLabelMulti(t *testing.T) { v := "X-Custom-Header1, X-Custom-Header2,X-Custom-Header3" pl, err := ParseLabel("proxy.aliases", v) - if err.IsNotNil() { - t.Errorf("expected err=nil, got %s", err.Error()) - } - sGot, ok := pl.Value.([]string) + ExpectErrNil(t, err) + sGot := ExpectType[[]string](t, pl.Value) sWant := []string{"X-Custom-Header1", "X-Custom-Header2", "X-Custom-Header3"} - if !ok { - t.Errorf("value is not []string, but %T", pl.Value) - } - if !reflect.DeepEqual(sGot, sWant) { - t.Errorf("expected %q, got %q", sWant, sGot) + if sGot != nil { + ExpectEqual(t, sGot, sWant) } } diff --git a/src/error/error_test.go b/src/error/error_test.go index aa4760d4..582ff483 100644 --- a/src/error/error_test.go +++ b/src/error/error_test.go @@ -1,46 +1,42 @@ -package error +package error_test import ( "testing" + + . "github.com/yusing/go-proxy/error" + . "github.com/yusing/go-proxy/utils" ) -func AssertEq[T comparable](t *testing.T, got, want T) { - t.Helper() - if got != want { - t.Errorf("expected:\n%v, got\n%v", want, got) - } -} - func TestErrorIs(t *testing.T) { - AssertEq(t, Failure("foo").Is(ErrFailure), true) - AssertEq(t, Failure("foo").With("bar").Is(ErrFailure), true) - AssertEq(t, Failure("foo").With("bar").Is(ErrInvalid), false) - AssertEq(t, Failure("foo").With("bar").With("baz").Is(ErrInvalid), false) + ExpectTrue(t, Failure("foo").Is(ErrFailure)) + ExpectTrue(t, Failure("foo").With("bar").Is(ErrFailure)) + ExpectFalse(t, Failure("foo").With("bar").Is(ErrInvalid)) + ExpectFalse(t, Failure("foo").With("bar").With("baz").Is(ErrInvalid)) - AssertEq(t, Invalid("foo", "bar").Is(ErrInvalid), true) - AssertEq(t, Invalid("foo", "bar").Is(ErrFailure), false) + ExpectTrue(t, Invalid("foo", "bar").Is(ErrInvalid)) + ExpectFalse(t, Invalid("foo", "bar").Is(ErrFailure)) - AssertEq(t, Nil().Is(nil), true) - AssertEq(t, Nil().Is(ErrInvalid), false) - AssertEq(t, Invalid("foo", "bar").Is(nil), false) + ExpectTrue(t, Nil().Is(nil)) + ExpectFalse(t, Nil().Is(ErrInvalid)) + ExpectFalse(t, Invalid("foo", "bar").Is(nil)) } func TestNil(t *testing.T) { - AssertEq(t, Nil().IsNil(), true) - AssertEq(t, Nil().IsNotNil(), false) - AssertEq(t, Nil().Error(), "nil") + ExpectTrue(t, Nil().IsNil()) + ExpectFalse(t, Nil().IsNotNil()) + ExpectEqual(t, Nil().Error(), "nil") } func TestErrorSimple(t *testing.T) { ne := Failure("foo bar") - AssertEq(t, ne.Error(), "foo bar failed") + ExpectEqual(t, ne.Error(), "foo bar failed") ne = ne.Subject("baz") - AssertEq(t, ne.Error(), "foo bar failed for \"baz\"") + ExpectEqual(t, ne.Error(), "foo bar failed for \"baz\"") } func TestErrorWith(t *testing.T) { ne := Failure("foo").With("bar").With("baz") - AssertEq(t, ne.Error(), "foo failed:\n - bar\n - baz") + ExpectEqual(t, ne.Error(), "foo failed:\n - bar\n - baz") } func TestErrorNested(t *testing.T) { @@ -76,5 +72,5 @@ func TestErrorNested(t *testing.T) { - inner3 failed for "action 3": - 3 - 3` - AssertEq(t, ne.Error(), want) + ExpectEqual(t, ne.Error(), want) } diff --git a/src/utils/testing.go b/src/utils/testing.go new file mode 100644 index 00000000..b33f4a73 --- /dev/null +++ b/src/utils/testing.go @@ -0,0 +1,46 @@ +package utils + +import ( + "reflect" + "testing" + + E "github.com/yusing/go-proxy/error" +) + +func ExpectErrNil(t *testing.T, err E.NestedError) { + t.Helper() + if err.IsNotNil() { + t.Errorf("expected err=nil, got %s", err.Error()) + } +} + +func ExpectEqual(t *testing.T, got, want any) { + t.Helper() + if !reflect.DeepEqual(got, want) { + t.Errorf("expected:\n%v, got\n%v", want, got) + } +} + +func ExpectTrue(t *testing.T, got bool) { + t.Helper() + if !got { + t.Errorf("expected true, got false") + } +} + +func ExpectFalse(t *testing.T, got bool) { + t.Helper() + if got { + t.Errorf("expected false, got true") + } +} + +func ExpectType[T any](t *testing.T, got any) T { + t.Helper() + tExpect := reflect.TypeFor[T]() + _, ok := got.(T) + if !ok { + t.Errorf("expected type %T, got %T", tExpect, got) + } + return got.(T) +}