diff --git a/internal/config/config_test.go b/internal/config/config_test.go index c22b635a500494cc358d2928a8573d26a30e29b8..399c8954384bf8c2e27707bbf41d5ac95a43f69c 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -19,7 +19,7 @@ func TestVerify(t *testing.T) { got := c.Verify() if err != nil { - t.Errorf("want nil, got %v", got) + t.Fatalf("want nil, got %v", got) } }) @@ -35,7 +35,7 @@ func TestVerify(t *testing.T) { want := errLogLevel if !errors.Is(got, want) { - t.Errorf("want %v, got %v", want, got) + t.Fatalf("want %v, got %v", want, got) } }) } diff --git a/internal/config/toml_test.go b/internal/config/toml_test.go index 2a4c1999693006773b99c5ed0ef000bd58883224..7d64946018f76fa8181750d9f8bbb172ee89b7a5 100644 --- a/internal/config/toml_test.go +++ b/internal/config/toml_test.go @@ -46,7 +46,7 @@ func TestToml(t *testing.T) { } if !reflect.DeepEqual(want, got) { - t.Errorf("want %v, got %v", want, got) + t.Fatalf("want %v, got %v", want, got) } }) } diff --git a/internal/modules/http/probe.go b/internal/modules/http/probe.go index 7e6ca84bae1c94b900de762cca70454a3531e260..d4e2af19b439c0fb06580563cba954ffc4d9a531 100644 --- a/internal/modules/http/probe.go +++ b/internal/modules/http/probe.go @@ -10,24 +10,26 @@ import ( ) type BadStatusCodeError struct { - expected []int - got int + Expected []int + Got int } func (m *BadStatusCodeError) Error() string { - return fmt.Sprintf("bad status code, expected: %d got: %d", m.expected, m.got) + return fmt.Sprintf("bad status code, Expected: %d Got: %d", m.Expected, m.Got) } type BadBodyError struct { - expected string - got string + Expected string + Got string } func (m *BadBodyError) Error() string { - return fmt.Sprintf("bad responde body, expected: %s got: %s", m.expected, m.got) + return fmt.Sprintf("bad responde body, Expected: %s Got: %s", m.Expected, m.Got) } func (c Config) IsUp() error { + logrus.Debugf("the check for %s has begin", c.Target) + r, err := http.Get(c.Target) if err != nil { return err @@ -49,8 +51,8 @@ func (c Config) IsUp() error { if !valid { return &BadStatusCodeError{ - expected: c.Valid, - got: r.StatusCode, + Expected: c.Valid, + Got: r.StatusCode, } } @@ -58,8 +60,8 @@ func (c Config) IsUp() error { body, _ := io.ReadAll(r.Body) if !strings.Contains(string(body), c.Response) { return &BadBodyError{ - expected: c.Response, - got: string(body), + Expected: c.Response, + Got: string(body), } } } diff --git a/internal/modules/http/probe_test.go b/internal/modules/http/probe_test.go deleted file mode 100644 index ee30c080336d9c2be1061125691372e51b485f1e..0000000000000000000000000000000000000000 --- a/internal/modules/http/probe_test.go +++ /dev/null @@ -1,180 +0,0 @@ -package http - -import ( - "errors" - "fmt" - "math/rand/v2" - "net" - "net/http" - "testing" - "time" - - "github.com/sirupsen/logrus" - "gitlab.gnous.eu/ada/status/internal/constant" -) - -type prepare struct { - body string - code int - listen string -} - -func getRandomPort() int { - port := rand.IntN(65535-1024) + 1024 - for isPortAvailable(port) == false { - port = rand.IntN(65535-1024) + 1024 - } - - return port -} - -func isPortAvailable(port int) bool { - l, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port)) - if err != nil { - return false - } - - err = l.Close() - if err != nil { - logrus.Error(err) - } - - return true -} - -func (c prepare) basicHandler(w http.ResponseWriter, _ *http.Request) { - w.WriteHeader(c.code) - _, err := w.Write([]byte(c.body)) - if err != nil { - logrus.Error(err) - } -} - -func (c prepare) prepare() { - mux := http.NewServeMux() - mux.HandleFunc("GET /", c.basicHandler) - httpServer := &http.Server{ - Addr: c.listen, - Handler: mux, - ReadHeaderTimeout: constant.ReadHeaderTimeout, - } - - go func() { - err := httpServer.ListenAndServe() - if err != nil { - logrus.Error(err) - - return - } - }() -} - -func TestVerify(t *testing.T) { //nolint:funlen - t.Parallel() - - t.Run("UP basic", func(t *testing.T) { - t.Parallel() - - port := getRandomPort() - - p := prepare{ - body: "OK", - code: http.StatusOK, - listen: fmt.Sprintf("localhost:%d", port), - } - - p.prepare() - - time.Sleep(1 * time.Second) - c := Config{ - Target: fmt.Sprintf("http://localhost:%d", port), - Valid: []int{200}, - Response: "OK", - } - - err := c.IsUp() - if err != nil { - t.Fatal(err) - } - }) - - t.Run("UP multiple code", func(t *testing.T) { - t.Parallel() - - port := getRandomPort() - - p := prepare{ - body: "OK", - code: http.StatusNotFound, - listen: fmt.Sprintf("localhost:%d", port), - } - - p.prepare() - - time.Sleep(1 * time.Second) - c := Config{ - Target: fmt.Sprintf("http://localhost:%d", port), - Valid: []int{200, 404}, - Response: "", - } - - err := c.IsUp() - if err != nil { - t.Fatal(err) - } - }) - - t.Run("Down bad code", func(t *testing.T) { - t.Parallel() - - port := getRandomPort() - - p := prepare{ - body: "OK", - code: http.StatusBadGateway, - listen: fmt.Sprintf("localhost:%d", port), - } - - p.prepare() - - time.Sleep(1 * time.Second) - c := Config{ - Target: fmt.Sprintf("http://localhost:%d", port), - Valid: []int{200}, - Response: "OK", - } - - got := c.IsUp() - want := &BadStatusCodeError{} - if !errors.As(got, &want) { - t.Errorf("want %v, got %v", want, got) - } - }) - - t.Run("Down bad body", func(t *testing.T) { - t.Parallel() - - port := getRandomPort() - - p := prepare{ - body: "KO", - code: http.StatusOK, - listen: fmt.Sprintf("localhost:%d", port), - } - - p.prepare() - - time.Sleep(1 * time.Second) - c := Config{ - Target: fmt.Sprintf("http://localhost:%d", port), - Valid: []int{200}, - Response: "OK", - } - - got := c.IsUp() - want := &BadBodyError{} - if !errors.As(got, &want) { - t.Errorf("want %v, got %v", want, got) - } - }) -} diff --git a/tests/api/status_test.go b/tests/api/status_test.go new file mode 100644 index 0000000000000000000000000000000000000000..d8661f77062b6bc1d6845083d38d5bcff31e7c58 --- /dev/null +++ b/tests/api/status_test.go @@ -0,0 +1,217 @@ +package api + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "testing" + "time" + + "github.com/sirupsen/logrus" + "gitlab.gnous.eu/ada/status/internal/cache" + "gitlab.gnous.eu/ada/status/internal/constant" + "gitlab.gnous.eu/ada/status/internal/models" + local_http "gitlab.gnous.eu/ada/status/internal/modules/http" + "gitlab.gnous.eu/ada/status/internal/probe" + "gitlab.gnous.eu/ada/status/tests/utils" +) + +func prepare(listen string, handler utils.Handler) { + mux := http.NewServeMux() + mux.HandleFunc("GET /", handler.BasicHandler) + httpServer := &http.Server{ + Addr: listen, + Handler: mux, + ReadHeaderTimeout: constant.ReadHeaderTimeout, + } + + go func() { + err := httpServer.ListenAndServe() + if err != nil { + logrus.Error(err) + + return + } + }() +} + +func TestStatusApi(t *testing.T) { //nolint:funlen + t.Parallel() + + t.Run("Basic up target", func(t *testing.T) { + t.Parallel() + + portTest1 := utils.GetRandomPort() + + cacheConfig := cache.Config{ + Enabled: false, + } + + targets := []probe.Target{{ + Name: "test1", + Description: "This is test one", + Module: "http", + Http: local_http.Config{ + Target: fmt.Sprintf("http://localhost:%d", portTest1), + Valid: []int{200}, + Response: "OK", + }, + }} + + url := fmt.Sprintf("http://%s/api/status", utils.Prepare(targets, cacheConfig)) + + prepare(fmt.Sprintf("localhost:%d", portTest1), utils.Handler{ + Body: "OK", + Code: 200, + }) + + time.Sleep(1 * time.Second) + + r, err := http.Get(url) + if err != nil { + t.Fatalf("Hi, %v", err) + } + + body, _ := io.ReadAll(r.Body) + defer r.Body.Close() + + var got []models.Status + + err = json.Unmarshal(body, &got) + if err != nil { + t.Fatal(err) + } + + want := models.Status{ + Name: targets[0].Name, + Description: targets[0].Description, + Success: true, + Error: "", + Target: targets[0].Http.Target, + } + + if got[0] != want { + t.Fatalf("want %v, got %v", want, got[0]) + } + }) + + t.Run("Basic down bad status code", func(t *testing.T) { + t.Parallel() + + portTest2 := utils.GetRandomPort() + + cacheConfig := cache.Config{ + Enabled: false, + } + + targets := []probe.Target{{ + Name: "test2", + Description: "This is test two", + Module: "http", + Http: local_http.Config{ + Target: fmt.Sprintf("http://localhost:%d", portTest2), + Valid: []int{200}, + Response: "", + }, + }} + + url := fmt.Sprintf("http://%s/api/status", utils.Prepare(targets, cacheConfig)) + + prepare(fmt.Sprintf("localhost:%d", portTest2), utils.Handler{ + Body: "OK", + Code: 503, + }) + + time.Sleep(1 * time.Second) + + r, err := http.Get(url) + if err != nil { + t.Fatalf("Hi, %v", err) + } + + body, _ := io.ReadAll(r.Body) + defer r.Body.Close() + + var got []models.Status + + err = json.Unmarshal(body, &got) + if err != nil { + t.Fatal(err) + } + + wantError := &local_http.BadStatusCodeError{Expected: targets[0].Http.Valid, Got: 503} + + want := models.Status{ + Name: targets[0].Name, + Description: targets[0].Description, + Success: false, + Error: wantError.Error(), + Target: targets[0].Http.Target, + } + + if got[0] != want { + t.Fatalf("want %v, got %v", want, got[0]) + } + }) + + t.Run("Basic down bad body", func(t *testing.T) { + t.Parallel() + + portTest3 := utils.GetRandomPort() + + cacheConfig := cache.Config{ + Enabled: false, + } + + targets := []probe.Target{{ + Name: "test3", + Description: "This is test three", + Module: "http", + Http: local_http.Config{ + Target: fmt.Sprintf("http://localhost:%d", portTest3), + Valid: []int{200}, + Response: "OK", + }, + }} + + url := fmt.Sprintf("http://%s/api/status", utils.Prepare(targets, cacheConfig)) + + prepare(fmt.Sprintf("localhost:%d", portTest3), utils.Handler{ + Body: "KO", + Code: 200, + }) + + time.Sleep(1 * time.Second) + + r, err := http.Get(url) + if err != nil { + t.Fatalf("Hi, %v", err) + } + + body, _ := io.ReadAll(r.Body) + defer r.Body.Close() + + var got []models.Status + + err = json.Unmarshal(body, &got) + if err != nil { + t.Fatal(err) + } + + wantError := &local_http.BadBodyError{Expected: "OK", Got: "KO"} + + want := models.Status{ + Name: targets[0].Name, + Description: targets[0].Description, + Success: false, + Error: wantError.Error(), + Target: targets[0].Http.Target, + } + + if got[0] != want { + t.Fatalf("want %v, got %v", want, got[0]) + } + }) + +} diff --git a/tests/modules/http/probe_test.go b/tests/modules/http/probe_test.go new file mode 100644 index 0000000000000000000000000000000000000000..8d334e2c1bc53fe0961ebc5a74b4b47face7c83a --- /dev/null +++ b/tests/modules/http/probe_test.go @@ -0,0 +1,143 @@ +package http + +import ( + "errors" + "fmt" + "net/http" + "testing" + "time" + + "github.com/sirupsen/logrus" + "gitlab.gnous.eu/ada/status/internal/constant" + local_http "gitlab.gnous.eu/ada/status/internal/modules/http" + "gitlab.gnous.eu/ada/status/tests/utils" +) + +func prepare(listen string, handler utils.Handler) { + mux := http.NewServeMux() + mux.HandleFunc("GET /", handler.BasicHandler) + httpServer := &http.Server{ + Addr: listen, + Handler: mux, + ReadHeaderTimeout: constant.ReadHeaderTimeout, + } + + go func() { + err := httpServer.ListenAndServe() + if err != nil { + logrus.Error(err) + + return + } + }() +} + +func TestVerify(t *testing.T) { //nolint:funlen + t.Parallel() + + t.Run("UP basic", func(t *testing.T) { + t.Parallel() + + port := utils.GetRandomPort() + listen := fmt.Sprintf("localhost:%d", port) + + p := utils.Handler{ + Body: "OK", + Code: http.StatusOK, + } + + prepare(listen, p) + + time.Sleep(1 * time.Second) + c := local_http.Config{ + Target: fmt.Sprintf("http://localhost:%d", port), + Valid: []int{200}, + Response: "OK", + } + + err := c.IsUp() + if err != nil { + t.Fatal(err) + } + }) + + t.Run("UP multiple code", func(t *testing.T) { + t.Parallel() + + port := utils.GetRandomPort() + listen := fmt.Sprintf("localhost:%d", port) + + p := utils.Handler{ + Body: "OK", + Code: http.StatusNotFound, + } + + prepare(listen, p) + + time.Sleep(1 * time.Second) + c := local_http.Config{ + Target: fmt.Sprintf("http://localhost:%d", port), + Valid: []int{200, 404}, + Response: "", + } + + err := c.IsUp() + if err != nil { + t.Fatal(err) + } + }) + + t.Run("Down bad code", func(t *testing.T) { + t.Parallel() + + port := utils.GetRandomPort() + listen := fmt.Sprintf("localhost:%d", port) + + p := utils.Handler{ + Body: "OK", + Code: http.StatusBadGateway, + } + + prepare(listen, p) + + time.Sleep(1 * time.Second) + c := local_http.Config{ + Target: fmt.Sprintf("http://localhost:%d", port), + Valid: []int{200}, + Response: "", + } + + got := c.IsUp() + want := &local_http.BadStatusCodeError{} + if !errors.As(got, &want) { + t.Fatalf("want %v, got %v", want, got) + } + }) + + t.Run("Down bad body", func(t *testing.T) { + t.Parallel() + + port := utils.GetRandomPort() + listen := fmt.Sprintf("localhost:%d", port) + + p := utils.Handler{ + Body: "OK", + Code: http.StatusOK, + } + + prepare(listen, p) + + time.Sleep(1 * time.Second) + c := local_http.Config{ + Target: fmt.Sprintf("http://localhost:%d", port), + Valid: []int{200}, + Response: "KO", + } + + got := c.IsUp() + want := &local_http.BadBodyError{} + if !errors.As(got, &want) { + t.Fatalf("want %v, got %v", want, got) + } + }) +} diff --git a/tests/utils/handler.go b/tests/utils/handler.go new file mode 100644 index 0000000000000000000000000000000000000000..da819883f24752c81bf4a675e0bafeb09b77e9cf --- /dev/null +++ b/tests/utils/handler.go @@ -0,0 +1,20 @@ +package utils + +import ( + "net/http" + + "github.com/sirupsen/logrus" +) + +type Handler struct { + Body string + Code int +} + +func (c Handler) BasicHandler(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(c.Code) + _, err := w.Write([]byte(c.Body)) + if err != nil { + logrus.Error(err) + } +} diff --git a/tests/utils/prepare.go b/tests/utils/prepare.go new file mode 100644 index 0000000000000000000000000000000000000000..1055b7b4aedefd8d76ca99577b8b9af8996d027b --- /dev/null +++ b/tests/utils/prepare.go @@ -0,0 +1,69 @@ +package utils + +import ( + "fmt" + "math/rand/v2" + "net" + + "github.com/sirupsen/logrus" + "gitlab.gnous.eu/ada/status/internal/cache" + "gitlab.gnous.eu/ada/status/internal/config" + "gitlab.gnous.eu/ada/status/internal/log" + "gitlab.gnous.eu/ada/status/internal/probe" + "gitlab.gnous.eu/ada/status/internal/router" +) + +func GetRandomPort() int { + port := rand.IntN(65535-1024) + 1024 + for isPortAvailable(port) == false { + port = rand.IntN(65535-1024) + 1024 + } + + return port +} + +func isPortAvailable(port int) bool { + l, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port)) + if err != nil { + return false + } + + err = l.Close() + if err != nil { + logrus.Error(err) + } + + return true +} + +func Prepare(targets []probe.Target, redis cache.Config) string { + listen := fmt.Sprintf("localhost:%d", GetRandomPort()) + + c := config.Config{ + Log: log.Config{ + Level: "DEBUG", + File: "", + }, + Listen: listen, + Probe: targets, + Redis: redis, + } + + err := c.Verify() + if err != nil { + logrus.Fatal(err) + } + + err = c.Log.Init() + if err != nil { + logrus.Fatal(err) + } + + logrus.Debugf("Loaded config : %v", c) + + go router.Init(c) + + logrus.Debug("Status backend started") + + return listen +}