Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REFACTOR] Structure and packages refactor #7

Merged
merged 6 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
- edited
- closed
push:
branches:
- '*'
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'

Expand Down Expand Up @@ -51,9 +53,10 @@ jobs:
go-version: '1.22'

- name: Verify functionality
run: go test -v ./tests/...
run: go test -v ./...

publish_release:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
needs:
- verify_backend_quality
- verify_backend_functionality
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.env
vendor/
travelis.log
logs/
test_logs/
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ gosec:
@gosec -quiet ./...

test:
go test -v ./tests/...
go test -v ./...

validate:
make linter
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/goccy/go-json v0.10.3
github.com/joho/godotenv v1.5.1
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
)

Expand All @@ -15,6 +16,7 @@ require (
github.com/bytedance/sonic/loader v0.2.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.5 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
Expand All @@ -31,6 +33,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sagikazarmark/locafero v0.6.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
Expand Down
25 changes: 0 additions & 25 deletions main.go

This file was deleted.

47 changes: 21 additions & 26 deletions main.go.bkup
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
// package main
package main

// import (
// "fmt"
// "log"
import (
"log"

// "github.com/gin-gonic/gin"
// controller "github.com/lookinlabs/status-page-middleware/controller"
// "github.com/lookinlabs/status-page-middleware/pkg/endpoints"
// "github.com/lookinlabs/status-page-middleware/pkg/logger"
// "github.com/lookinlabs/status-page-middleware/view"
// )
"github.com/gin-gonic/gin"
controller "github.com/lookinlabs/status-page-middleware/controller"
"github.com/lookinlabs/status-page-middleware/pkg/endpoints"
)

// func main() {
// router := gin.Default()
func main() {
router := gin.Default()
router.GET("/ping", controller.Ping)
router.POST("/v2/ping", controller.PingV2)
router.POST("/v3/ping", controller.PingV3)
handler, err := endpoints.NewStatusPageController("pkg/config/endpoints.json")
if err != nil {
log.Fatalf("Failed to initialize StatusPageController: %v", err)
}
handler.StatusPageMiddleware(router)

// router.GET("/ping", controller.Ping)
// router.POST("/v2/ping", controller.PingV2)
// router.POST("/v3/ping", controller.PingV3)

// endpoints.StatusPageMiddleware(router)
// data, err := view.StatusPageHTML.ReadFile("html/status.html")
// if err != nil {
// log.Fatalf("Failed to read embedded file: %v", err)
// }
// fmt.Println(string(data))
// if err := router.Run(":8080"); err != nil {
// logger.Fatalf("StatusMiddleware: Failed to run server: %v", err)
// }
// }
if err := router.Run(":8080"); err != nil {
log.Fatalf("Failed to run server: %v", err)
}
}
9 changes: 4 additions & 5 deletions tests/checks_test.go → pkg/checks/checks_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package tests
package checks

import (
"sync"
"testing"

"github.com/lookinlabs/status-page-middleware/pkg/checks"
"github.com/lookinlabs/status-page-middleware/pkg/model"
)

Expand All @@ -29,21 +28,21 @@ func TestChecks(testCase *testing.T) {
Username: "your_username",
Password: "your_password",
}
status, _ := checks.HTTP("http://localhost:8080/ping", method, headers, body, basicAuth)
status, _ := HTTP("http://localhost:8080/ping", method, headers, body, basicAuth)
if status != "up" && status != "down" {
httpCase.Errorf("Expected status to be 'up' or 'down', got %s", status)
}
})

runTest("DNS Check", func(dnsCase *testing.T) {
status, _ := checks.DNS("http://localhost:3000/ping")
status, _ := DNS("http://localhost:3000/ping")
if status != "up" && status != "down" {
dnsCase.Errorf("Expected status to be 'up' or 'down', got %s", status)
}
})

runTest("TCP Check", func(tcpCase *testing.T) {
status, _ := checks.TCP("http://localhost:3000")
status, _ := TCP("http://localhost:3000")
if status != "up" && status != "down" {
tcpCase.Errorf("Expected status to be 'up' or 'down', got %s", status)
}
Expand Down
64 changes: 64 additions & 0 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package config

import (
"os"
"path/filepath"
"sync"
"testing"

"github.com/lookinlabs/status-page-middleware/pkg/helpers"
"github.com/stretchr/testify/assert"
)

func TestConfig(test *testing.T) {
var wg sync.WaitGroup
wg.Add(2) // We have two tests to run in parallel

go func() {
defer wg.Done()
testLoadStatusPage(test)
}()

go func() {
defer wg.Done()
testLoadEndpoints(test)
}()

wg.Wait()
}

func testLoadStatusPage(test *testing.T) {
// Set up environment variables for testing
envVars := map[string]string{
"STATUS_PAGE_CONFIG_PATH": "testdata/endpoints.json",
"STATUS_PAGE_TEMPLATE_PATH": "testdata/status.html",
"STATUS_PAGE_PATH": "/teststatus",
}
defer helpers.SetEnv(envVars)()

env, err := LoadStatusPage()
assert.NoError(test, err)
assert.Equal(test, "testdata/endpoints.json", env.StatusPageConfigPath)
assert.Equal(test, "testdata/status.html", env.StatusPageTemplatePath)
assert.Equal(test, "/teststatus", env.StatusPagePath)
}

func testLoadEndpoints(test *testing.T) {
// Create a temporary JSON file for testing
filePath := filepath.Join(os.TempDir(), "test_endpoints.json")
data := `[
{"name": "service1", "url": "http://service1.com"},
{"name": "service2", "url": "http://service2.com"}
]`
err := os.WriteFile(filePath, []byte(data), 0o644)
assert.NoError(test, err)
defer os.Remove(filePath)

services, err := LoadEndpoints(filePath)
assert.NoError(test, err)
assert.Len(test, services, 2)
assert.Equal(test, "service1", services[0].Name)
assert.Equal(test, "http://service1.com", services[0].URL)
assert.Equal(test, "service2", services[1].Name)
assert.Equal(test, "http://service2.com", services[1].URL)
}
4 changes: 2 additions & 2 deletions pkg/config/endpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@
"type": "dns"
},
{
"name": "Api TCP Check",
"name": "Api Fail TCP Check",
"url": "http://localhost:8081/ping",
"type": "tcp"
},
{
"name": "Api 2 TCP Check",
"name": "Api 2 Fail TCP Check",
"url": "http://localhost:8082/ping",
"type": "tcp"
}
Expand Down
94 changes: 94 additions & 0 deletions pkg/endpoints/endpoint_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package endpoints

import (
"log"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"sync"
"testing"

"github.com/gin-gonic/gin"
"github.com/lookinlabs/status-page-middleware/pkg/helpers"
"github.com/stretchr/testify/assert"
)

func TestEndpoints(test *testing.T) {
// Set up environment variables for testing
envVars := map[string]string{
"STATUS_PAGE_CONFIG_PATH": "testdata/endpoints.json",
"STATUS_PAGE_TEMPLATE_PATH": "testdata/status.html",
"STATUS_PAGE_PATH": "/teststatus",
}
defer helpers.SetEnv(envVars)()

// Create a temporary JSON file for testing
filePath := filepath.Join(os.TempDir(), "test_endpoints.json")
data := `[
{"name": "service1", "url": "http://service1.com"},
{"name": "service2", "url": "http://service2.com"}
]`
err := os.WriteFile(filePath, []byte(data), 0o644)
assert.NoError(test, err)
defer os.Remove(filePath)

// WaitGroup to synchronize goroutines
var wg sync.WaitGroup
wg.Add(2)

// Run testNewStatusPageController in a goroutine
go func() {
defer wg.Done()
testNewStatusPageController(test, filePath)
}()

// Run testStatusPageMiddleware in a goroutine
go func() {
defer wg.Done()
testStatusPageMiddleware(test, filePath)
}()

// Wait for both goroutines to finish
wg.Wait()
}

func testNewStatusPageController(test *testing.T, filePath string) {
// Initialize the StatusPageController
handler, err := NewStatusPageController(filePath)
if err != nil {
log.Fatalf("Failed to initialize StatusPageController: %v", err)
}

assert.NoError(test, err)
assert.NotNil(test, handler)
assert.Len(test, handler.services, 2)
assert.Equal(test, "service1", handler.services[0].Name)
assert.Equal(test, "http://service1.com", handler.services[0].URL)
assert.Equal(test, "service2", handler.services[1].Name)
assert.Equal(test, "http://service2.com", handler.services[1].URL)
}

func testStatusPageMiddleware(test *testing.T, testFilePath string) {
// Initialize the StatusPageController
handler, err := NewStatusPageController(testFilePath)
if err != nil {
log.Fatalf("Failed to initialize StatusPageController: %v", err)
}
assert.NoError(test, err)
assert.NotNil(test, handler)

// Set up the Gin router and apply the middleware
router := gin.Default()
handler.StatusPageMiddleware(router)

// Create a test HTTP server
response := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/teststatus", nil)
router.ServeHTTP(response, req)

assert.Equal(test, http.StatusOK, response.Code)
assert.Contains(test, response.Body.String(), "<title>Status Page</title>")
assert.Contains(test, response.Body.String(), "service1")
assert.Contains(test, response.Body.String(), "service2")
}
2 changes: 0 additions & 2 deletions pkg/endpoints/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package endpoints

import (
"html/template"
"net/http"
"os"

"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -60,7 +59,6 @@ func (controller *StatusPage) getStatusPage() gin.HandlerFunc {
return func(ctx *gin.Context) {
if ctx.Request.URL.Path == controller.env.StatusPagePath {
status.Services(controller.env, controller.services, ctx)
ctx.HTML(http.StatusOK, "status.html", gin.H{})
ctx.Abort()
} else {
ctx.Next()
Expand Down
24 changes: 24 additions & 0 deletions pkg/helpers/set_env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package helpers

import (
"os"

"github.com/lookinlabs/status-page-middleware/pkg/logger"
)

// SetEnv sets environment variables for testing and returns a function to unset them
func SetEnv(envVars map[string]string) func() {
for key, value := range envVars {
if err := os.Setenv(key, value); err != nil {
logger.Errorf("StatusMiddleware: Failed to set environment variable %s: %v", key, err)
}
}

return func() {
for key := range envVars {
if err := os.Unsetenv(key); err != nil {
logger.Errorf("StatusMiddleware: Failed to unset environment variable %s: %v", key, err)
}
}
}
}
Loading