Added tests to ensure SIGUSR1 and SIGUSR2 will toggle db lock

This commit is contained in:
2025-02-18 23:18:02 +11:00
parent 789d1e75a7
commit 46dd86cdae
4 changed files with 62 additions and 11 deletions

View File

@@ -23,6 +23,8 @@ test:
go mod tidy && \ go mod tidy && \
templ generate && \ templ generate && \
go generate && \ go generate && \
go test .
go test ./db
go test ./middleware go test ./middleware
clean: clean:

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
"os"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"

10
main.go
View File

@@ -67,16 +67,14 @@ func handleMaintSignals(
case syscall.SIGUSR1: case syscall.SIGUSR1:
if atomic.LoadUint32(&maint) != 1 { if atomic.LoadUint32(&maint) != 1 {
atomic.StoreUint32(&maint, 1) atomic.StoreUint32(&maint, 1)
log := logger.With().Logger().Output(os.Stdout) logger.Info().Msg("Signal received: Starting maintenance")
log.Info().Msg("Signal received: Starting maintenance") logger.Info().Msg("Attempting to acquire database lock")
log.Info().Msg("Attempting to acquire database lock")
conn.Pause(config.DBLockTimeout * time.Second) conn.Pause(config.DBLockTimeout * time.Second)
} }
case syscall.SIGUSR2: case syscall.SIGUSR2:
if atomic.LoadUint32(&maint) != 0 { if atomic.LoadUint32(&maint) != 0 {
log := logger.With().Logger().Output(os.Stdout) logger.Info().Msg("Signal received: Maintenance over")
log.Info().Msg("Signal received: Maintenance over") logger.Info().Msg("Releasing database lock")
log.Info().Msg("Releasing database lock")
conn.Resume() conn.Resume()
atomic.StoreUint32(&maint, 0) atomic.StoreUint32(&maint, 0)
} }

View File

@@ -1,12 +1,17 @@
package main package main
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
"strings"
"syscall"
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/require"
) )
func Test_main(t *testing.T) { func Test_main(t *testing.T) {
@@ -14,13 +19,60 @@ func Test_main(t *testing.T) {
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
t.Cleanup(cancel) t.Cleanup(cancel)
args := map[string]string{} 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") waitForReady(ctx, 10*time.Second, "http://localhost:3333/healthz")
// do tests t.Run("SIGUSR1 puts database into global lock", func(t *testing.T) {
fmt.Println("Tests starting") 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( func waitForReady(