From 46dd86cdaea86c65ae9e363d8f10e6c73e8ddc4d Mon Sep 17 00:00:00 2001 From: Haelnorr Date: Tue, 18 Feb 2025 23:18:02 +1100 Subject: [PATCH] Added tests to ensure SIGUSR1 and SIGUSR2 will toggle db lock --- Makefile | 2 ++ db/connection.go | 1 - main.go | 10 ++++---- main_test.go | 60 ++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 66dd5b8..e23833d 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,8 @@ test: go mod tidy && \ templ generate && \ go generate && \ + go test . + go test ./db go test ./middleware clean: diff --git a/db/connection.go b/db/connection.go index 56652e2..78e4071 100644 --- a/db/connection.go +++ b/db/connection.go @@ -4,7 +4,6 @@ import ( "context" "database/sql" "fmt" - "os" "time" "github.com/pkg/errors" diff --git a/main.go b/main.go index 9fdb6c0..ede093c 100644 --- a/main.go +++ b/main.go @@ -67,16 +67,14 @@ func handleMaintSignals( case syscall.SIGUSR1: if atomic.LoadUint32(&maint) != 1 { atomic.StoreUint32(&maint, 1) - log := logger.With().Logger().Output(os.Stdout) - log.Info().Msg("Signal received: Starting maintenance") - log.Info().Msg("Attempting to acquire database lock") + logger.Info().Msg("Signal received: Starting maintenance") + logger.Info().Msg("Attempting to acquire database lock") conn.Pause(config.DBLockTimeout * time.Second) } case syscall.SIGUSR2: if atomic.LoadUint32(&maint) != 0 { - log := logger.With().Logger().Output(os.Stdout) - log.Info().Msg("Signal received: Maintenance over") - log.Info().Msg("Releasing database lock") + logger.Info().Msg("Signal received: Maintenance over") + logger.Info().Msg("Releasing database lock") conn.Resume() atomic.StoreUint32(&maint, 0) } diff --git a/main_test.go b/main_test.go index ccb1d48..e806e32 100644 --- a/main_test.go +++ b/main_test.go @@ -1,12 +1,17 @@ package main import ( + "bytes" "context" "fmt" "net/http" "os" + "strings" + "syscall" "testing" "time" + + "github.com/stretchr/testify/require" ) func Test_main(t *testing.T) { @@ -14,13 +19,60 @@ func Test_main(t *testing.T) { ctx, cancel := context.WithCancel(ctx) t.Cleanup(cancel) args := map[string]string{} - go run(ctx, os.Stdout, args) + var stdout bytes.Buffer + go run(ctx, &stdout, args) - // wait for the server to become available waitForReady(ctx, 10*time.Second, "http://localhost:3333/healthz") - // do tests - fmt.Println("Tests starting") + t.Run("SIGUSR1 puts database into global lock", func(t *testing.T) { + done := make(chan bool) + go func() { + expected := "Global database lock acquired" + for { + if strings.Contains(stdout.String(), expected) { + done <- true + return + } + time.Sleep(100 * time.Millisecond) + } + }() + + proc, err := os.FindProcess(os.Getpid()) + require.NoError(t, err) + proc.Signal(syscall.SIGUSR1) + + select { + case <-done: + t.Log("found") + case <-time.After(250 * time.Millisecond): + t.Errorf("Not found") + } + }) + + t.Run("SIGUSR2 releases database global lock", func(t *testing.T) { + done := make(chan bool) + go func() { + expected := "Global database lock released" + for { + if strings.Contains(stdout.String(), expected) { + done <- true + return + } + time.Sleep(100 * time.Millisecond) + } + }() + + proc, err := os.FindProcess(os.Getpid()) + require.NoError(t, err) + proc.Signal(syscall.SIGUSR2) + + select { + case <-done: + t.Log("found") + case <-time.After(250 * time.Millisecond): + t.Errorf("Not found") + } + }) } func waitForReady(