diff --git a/backend/liveness/liveness.go b/backend/liveness/liveness.go new file mode 100644 index 0000000..36051af --- /dev/null +++ b/backend/liveness/liveness.go @@ -0,0 +1,54 @@ +package liveness + +import ( + "net/http" + "sync" + + "github.com/gin-gonic/gin" +) + +type HealthCheck interface { + SetStatus(status string) + GetStatus() string + HealthCheckHandler() gin.HandlerFunc +} + +type healthCheck struct { + status string + sync sync.Mutex +} + +func New() HealthCheck { + return &healthCheck{ + status: "ok", + } +} + +func (hc *healthCheck) SetStatus(status string) { + hc.sync.Lock() + defer hc.sync.Unlock() + + hc.status = status +} + +func (hc *healthCheck) GetStatus() string { + hc.sync.Lock() + defer hc.sync.Unlock() + + return hc.status +} + +func (hc *healthCheck) HealthCheckHandler() gin.HandlerFunc { + return func(c *gin.Context) { + switch hc.GetStatus() { + case "nok": + c.JSON(http.StatusInternalServerError, gin.H{ + "status": hc.GetStatus(), + }) + default: + c.JSON(http.StatusOK, gin.H{ + "status": hc.GetStatus(), + }) + } + } +} diff --git a/backend/liveness/liveness_test.go b/backend/liveness/liveness_test.go new file mode 100644 index 0000000..f4a47cf --- /dev/null +++ b/backend/liveness/liveness_test.go @@ -0,0 +1,131 @@ +package liveness + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/gin-gonic/gin" +) + +func TestHealthCheck_GetStatus(t *testing.T) { + var hc HealthCheck + + type fields struct { + status string + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "Test GetStatus with status ok", + fields: fields{ + status: "ok", + }, + want: "ok", + }, + { + name: "Test GetStatus with status nok", + fields: fields{ + status: "nok", + }, + want: "nok", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hc = &healthCheck{ + status: tt.fields.status, + } + if got := hc.GetStatus(); got != tt.want { + t.Errorf("HealthCheck.GetStatus() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestHealthCheck_SetStatus(t *testing.T) { + hc := New() + + type args struct { + status string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "Test SetStatus with status ok", + args: args{ + status: "ok", + }, + want: "ok", + }, + { + name: "Test SetStatus with status nok", + args: args{ + status: "nok", + }, + want: "nok", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hc.SetStatus(tt.args.status) + if got := hc.GetStatus(); got != tt.want { + t.Errorf("HealthCheck.GetStatus() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestHealthCheck_HealthCheckHandler(t *testing.T) { + r := gin.Default() + hc := New() + r.GET("/health", hc.HealthCheckHandler()) + type args struct { + status string + } + tests := []struct { + name string + args args + want string + statusCode int + }{ + { + name: "Test respond with status ok", + args: args{ + status: "ok", + }, + want: `{"status":"ok"}`, + statusCode: http.StatusOK, + }, + { + name: "Test respond with status nok", + args: args{ + status: "nok", + }, + want: `{"status":"nok"}`, + statusCode: http.StatusInternalServerError, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hc.SetStatus(tt.args.status) + + w := httptest.NewRecorder() + req, _ := http.NewRequest("GET", "/health", nil) + r.ServeHTTP(w, req) + + if got := w.Code; got != tt.statusCode { + t.Errorf("HealthCheck response status code = %v, want %v", got, tt.statusCode) + } + if got := w.Body.String(); got != tt.want { + t.Errorf("HealthCheck response = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/backend/main.go b/backend/main.go index 98fb588..3e5de2e 100644 --- a/backend/main.go +++ b/backend/main.go @@ -9,6 +9,7 @@ import ( "time" "github.com/gin-gonic/gin" + "github.com/vcscsvcscs/GenerationsHeritage/backend/liveness" ) var ( @@ -40,13 +41,11 @@ func main() { gin.DefaultWriter = io.MultiWriter(f) } } - log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) log.SetOutput(gin.DefaultErrorWriter) + + hc := liveness.New() + router := gin.Default() - router.GET("/health", func(c *gin.Context) { - c.JSON(200, gin.H{ - "message": "ok", - }) - }) + router.GET("/health", hc.HealthCheckHandler()) }