All checks were successful
check / check (push) Successful in 1m0s
Remove the `Buildarch` field from the globals package and all references throughout the codebase. **Changes:** - Removed `Buildarch` package-level var and struct field from `internal/globals/globals.go` - Removed `Buildarch` from the `New()` constructor - Removed `globals.Buildarch = runtime.GOARCH` and unused `runtime` import from `cmd/webhooker/main.go` - Removed `buildarch` from logger startup output in `internal/logger/logger.go` - Removed all `Buildarch` test setup and assertions from globals, logger, database, and webhook_db_manager tests All tests pass, `make check` passes, `docker build .` succeeds. closes [issue #30](#30) <!-- session: agent:sdlc-manager:subagent:5cae6803-6bdf-467d-9a56-43f135521e5f --> Co-authored-by: clawbot <clawbot@noreply.git.eeqj.de> Reviewed-on: #31 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org>
273 lines
7.0 KiB
Go
273 lines
7.0 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/fx/fxtest"
|
|
"sneak.berlin/go/webhooker/internal/config"
|
|
"sneak.berlin/go/webhooker/internal/globals"
|
|
"sneak.berlin/go/webhooker/internal/logger"
|
|
)
|
|
|
|
func setupTestWebhookDBManager(t *testing.T) (*WebhookDBManager, *fxtest.Lifecycle) {
|
|
t.Helper()
|
|
|
|
lc := fxtest.NewLifecycle(t)
|
|
|
|
globals.Appname = "webhooker-test"
|
|
globals.Version = "test"
|
|
|
|
g, err := globals.New(lc)
|
|
require.NoError(t, err)
|
|
|
|
l, err := logger.New(lc, logger.LoggerParams{Globals: g})
|
|
require.NoError(t, err)
|
|
|
|
dataDir := filepath.Join(t.TempDir(), "events")
|
|
|
|
cfg := &config.Config{
|
|
DataDir: dataDir,
|
|
}
|
|
|
|
mgr, err := NewWebhookDBManager(lc, WebhookDBManagerParams{
|
|
Config: cfg,
|
|
Logger: l,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
return mgr, lc
|
|
}
|
|
|
|
func TestWebhookDBManager_CreateAndGetDB(t *testing.T) {
|
|
mgr, lc := setupTestWebhookDBManager(t)
|
|
ctx := context.Background()
|
|
require.NoError(t, lc.Start(ctx))
|
|
defer func() { require.NoError(t, lc.Stop(ctx)) }()
|
|
|
|
webhookID := uuid.New().String()
|
|
|
|
// DB should not exist yet
|
|
assert.False(t, mgr.DBExists(webhookID))
|
|
|
|
// Create the DB
|
|
err := mgr.CreateDB(webhookID)
|
|
require.NoError(t, err)
|
|
|
|
// DB file should now exist
|
|
assert.True(t, mgr.DBExists(webhookID))
|
|
|
|
// Get the DB again (should use cached connection)
|
|
db, err := mgr.GetDB(webhookID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, db)
|
|
|
|
// Verify we can write an event
|
|
event := &Event{
|
|
WebhookID: webhookID,
|
|
EntrypointID: uuid.New().String(),
|
|
Method: "POST",
|
|
Headers: `{"Content-Type":["application/json"]}`,
|
|
Body: `{"test": true}`,
|
|
ContentType: "application/json",
|
|
}
|
|
require.NoError(t, db.Create(event).Error)
|
|
assert.NotEmpty(t, event.ID)
|
|
|
|
// Verify we can read it back
|
|
var readEvent Event
|
|
require.NoError(t, db.First(&readEvent, "id = ?", event.ID).Error)
|
|
assert.Equal(t, webhookID, readEvent.WebhookID)
|
|
assert.Equal(t, "POST", readEvent.Method)
|
|
assert.Equal(t, `{"test": true}`, readEvent.Body)
|
|
}
|
|
|
|
func TestWebhookDBManager_DeleteDB(t *testing.T) {
|
|
mgr, lc := setupTestWebhookDBManager(t)
|
|
ctx := context.Background()
|
|
require.NoError(t, lc.Start(ctx))
|
|
defer func() { require.NoError(t, lc.Stop(ctx)) }()
|
|
|
|
webhookID := uuid.New().String()
|
|
|
|
// Create the DB and write some data
|
|
require.NoError(t, mgr.CreateDB(webhookID))
|
|
db, err := mgr.GetDB(webhookID)
|
|
require.NoError(t, err)
|
|
|
|
event := &Event{
|
|
WebhookID: webhookID,
|
|
EntrypointID: uuid.New().String(),
|
|
Method: "POST",
|
|
Body: `{"test": true}`,
|
|
ContentType: "application/json",
|
|
}
|
|
require.NoError(t, db.Create(event).Error)
|
|
|
|
// Delete the DB
|
|
require.NoError(t, mgr.DeleteDB(webhookID))
|
|
|
|
// File should no longer exist
|
|
assert.False(t, mgr.DBExists(webhookID))
|
|
|
|
// Verify the file is actually gone from disk
|
|
dbPath := mgr.dbPath(webhookID)
|
|
_, err = os.Stat(dbPath)
|
|
assert.True(t, os.IsNotExist(err))
|
|
}
|
|
|
|
func TestWebhookDBManager_LazyCreation(t *testing.T) {
|
|
mgr, lc := setupTestWebhookDBManager(t)
|
|
ctx := context.Background()
|
|
require.NoError(t, lc.Start(ctx))
|
|
defer func() { require.NoError(t, lc.Stop(ctx)) }()
|
|
|
|
webhookID := uuid.New().String()
|
|
|
|
// GetDB should lazily create the database
|
|
db, err := mgr.GetDB(webhookID)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, db)
|
|
|
|
// File should now exist
|
|
assert.True(t, mgr.DBExists(webhookID))
|
|
}
|
|
|
|
func TestWebhookDBManager_DeliveryWorkflow(t *testing.T) {
|
|
mgr, lc := setupTestWebhookDBManager(t)
|
|
ctx := context.Background()
|
|
require.NoError(t, lc.Start(ctx))
|
|
defer func() { require.NoError(t, lc.Stop(ctx)) }()
|
|
|
|
webhookID := uuid.New().String()
|
|
targetID := uuid.New().String()
|
|
|
|
db, err := mgr.GetDB(webhookID)
|
|
require.NoError(t, err)
|
|
|
|
// Create an event
|
|
event := &Event{
|
|
WebhookID: webhookID,
|
|
EntrypointID: uuid.New().String(),
|
|
Method: "POST",
|
|
Headers: `{"Content-Type":["application/json"]}`,
|
|
Body: `{"payload": "test"}`,
|
|
ContentType: "application/json",
|
|
}
|
|
require.NoError(t, db.Create(event).Error)
|
|
|
|
// Create a delivery
|
|
delivery := &Delivery{
|
|
EventID: event.ID,
|
|
TargetID: targetID,
|
|
Status: DeliveryStatusPending,
|
|
}
|
|
require.NoError(t, db.Create(delivery).Error)
|
|
|
|
// Query pending deliveries
|
|
var pending []Delivery
|
|
require.NoError(t, db.Where("status = ?", DeliveryStatusPending).
|
|
Preload("Event").
|
|
Find(&pending).Error)
|
|
require.Len(t, pending, 1)
|
|
assert.Equal(t, event.ID, pending[0].EventID)
|
|
assert.Equal(t, "POST", pending[0].Event.Method)
|
|
|
|
// Create a delivery result
|
|
result := &DeliveryResult{
|
|
DeliveryID: delivery.ID,
|
|
AttemptNum: 1,
|
|
Success: true,
|
|
StatusCode: 200,
|
|
Duration: 42,
|
|
}
|
|
require.NoError(t, db.Create(result).Error)
|
|
|
|
// Update delivery status
|
|
require.NoError(t, db.Model(delivery).Update("status", DeliveryStatusDelivered).Error)
|
|
|
|
// Verify no more pending deliveries
|
|
var stillPending []Delivery
|
|
require.NoError(t, db.Where("status = ?", DeliveryStatusPending).Find(&stillPending).Error)
|
|
assert.Empty(t, stillPending)
|
|
}
|
|
|
|
func TestWebhookDBManager_MultipleWebhooks(t *testing.T) {
|
|
mgr, lc := setupTestWebhookDBManager(t)
|
|
ctx := context.Background()
|
|
require.NoError(t, lc.Start(ctx))
|
|
defer func() { require.NoError(t, lc.Stop(ctx)) }()
|
|
|
|
webhook1 := uuid.New().String()
|
|
webhook2 := uuid.New().String()
|
|
|
|
// Create DBs for two webhooks
|
|
require.NoError(t, mgr.CreateDB(webhook1))
|
|
require.NoError(t, mgr.CreateDB(webhook2))
|
|
|
|
db1, err := mgr.GetDB(webhook1)
|
|
require.NoError(t, err)
|
|
db2, err := mgr.GetDB(webhook2)
|
|
require.NoError(t, err)
|
|
|
|
// Write events to each webhook's DB
|
|
event1 := &Event{
|
|
WebhookID: webhook1,
|
|
EntrypointID: uuid.New().String(),
|
|
Method: "POST",
|
|
Body: `{"webhook": 1}`,
|
|
ContentType: "application/json",
|
|
}
|
|
event2 := &Event{
|
|
WebhookID: webhook2,
|
|
EntrypointID: uuid.New().String(),
|
|
Method: "PUT",
|
|
Body: `{"webhook": 2}`,
|
|
ContentType: "application/json",
|
|
}
|
|
require.NoError(t, db1.Create(event1).Error)
|
|
require.NoError(t, db2.Create(event2).Error)
|
|
|
|
// Verify isolation: each DB only has its own events
|
|
var count1 int64
|
|
db1.Model(&Event{}).Count(&count1)
|
|
assert.Equal(t, int64(1), count1)
|
|
|
|
var count2 int64
|
|
db2.Model(&Event{}).Count(&count2)
|
|
assert.Equal(t, int64(1), count2)
|
|
|
|
// Delete webhook1's DB, webhook2 should be unaffected
|
|
require.NoError(t, mgr.DeleteDB(webhook1))
|
|
assert.False(t, mgr.DBExists(webhook1))
|
|
assert.True(t, mgr.DBExists(webhook2))
|
|
|
|
// webhook2's data should still be accessible
|
|
var events []Event
|
|
require.NoError(t, db2.Find(&events).Error)
|
|
assert.Len(t, events, 1)
|
|
assert.Equal(t, "PUT", events[0].Method)
|
|
}
|
|
|
|
func TestWebhookDBManager_CloseAll(t *testing.T) {
|
|
mgr, lc := setupTestWebhookDBManager(t)
|
|
ctx := context.Background()
|
|
require.NoError(t, lc.Start(ctx))
|
|
|
|
// Create a few DBs
|
|
for i := 0; i < 3; i++ {
|
|
require.NoError(t, mgr.CreateDB(uuid.New().String()))
|
|
}
|
|
|
|
// CloseAll should close all connections without error
|
|
require.NoError(t, mgr.CloseAll())
|
|
|
|
// Stop lifecycle (CloseAll already called, but shouldn't panic)
|
|
require.NoError(t, lc.Stop(ctx))
|
|
}
|