refactor(store): shared storetest.BaseMock replaces 5 duplicated mocks
CI / test (pull_request) Successful in 1m57s
CI / lint (pull_request) Successful in 1m16s
CI / vulncheck (pull_request) Successful in 1m1s

New internal/store/storetest/mock.go provides BaseMock implementing
the full Store interface with no-op defaults and optional Func field
overrides. Each test file embeds BaseMock and shadows only the methods
it needs.

Removes ~400 lines of duplicated stub methods across 6 test files.
Adding a Store method now requires one addition (BaseMock) instead
of editing 6 files.
This commit was merged in pull request #107.
This commit is contained in:
2026-06-11 16:09:29 -04:00
parent 0974ab2b4c
commit 2b357341c8
7 changed files with 297 additions and 400 deletions
+4 -5
View File
@@ -9,22 +9,21 @@ import (
"time"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/models"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/store"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/store/storetest"
"github.com/charmbracelet/ssh"
gossh "golang.org/x/crypto/ssh"
)
// kcMockStore implements only what keyCache and userInvalidatingStore touch;
// any other Store method panics via the embedded nil interface.
// kcMockStore embeds BaseMock for default no-ops; only GetAllUsers is
// overridden because the tests mutate users/err between calls.
type kcMockStore struct {
store.Store
storetest.BaseMock
users []models.User
err error
}
func (m *kcMockStore) GetAllUsers(_ context.Context) ([]models.User, error) { return m.users, m.err }
func (m *kcMockStore) DeleteUser(_ context.Context, _ int) error { return nil }
func testKey(t *testing.T) (string, ssh.PublicKey) {
t.Helper()
+2 -89
View File
@@ -12,100 +12,13 @@ import (
"gitea.lerkolabs.com/lerkolabs/uptop/internal/models"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/monitor"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/store/storetest"
)
// --- Mock Store (minimal, for monitor.NewEngine) ---
type mockStore struct {
sites []models.Site
storetest.BaseMock
}
func (m *mockStore) Init(_ context.Context) error { return nil }
func (m *mockStore) GetSites(_ context.Context) ([]models.Site, error) { return m.sites, nil }
func (m *mockStore) AddSite(_ context.Context, _ models.Site) error { return nil }
func (m *mockStore) UpdateSite(_ context.Context, _ models.Site) error { return nil }
func (m *mockStore) UpdateSitePaused(_ context.Context, _ int, _ bool) error { return nil }
func (m *mockStore) DeleteSite(_ context.Context, _ int) error { return nil }
func (m *mockStore) GetAllAlerts(_ context.Context) ([]models.AlertConfig, error) { return nil, nil }
func (m *mockStore) GetAlert(_ context.Context, _ int) (models.AlertConfig, error) {
return models.AlertConfig{}, nil
}
func (m *mockStore) AddAlert(_ context.Context, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *mockStore) UpdateAlert(_ context.Context, _ int, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *mockStore) DeleteAlert(_ context.Context, _ int) error { return nil }
func (m *mockStore) GetAllUsers(_ context.Context) ([]models.User, error) { return nil, nil }
func (m *mockStore) AddUser(_ context.Context, _ string, _ string, _ string) error { return nil }
func (m *mockStore) UpdateUser(_ context.Context, _ int, _ string, _ string, _ string) error {
return nil
}
func (m *mockStore) DeleteUser(_ context.Context, _ int) error { return nil }
func (m *mockStore) SaveCheck(_ context.Context, _ int, _ int64, _ bool) error { return nil }
func (m *mockStore) SaveCheckFromNode(_ context.Context, _ int, _ string, _ int64, _ bool) error {
return nil
}
func (m *mockStore) LoadAllHistory(_ context.Context, _ int) (map[int][]models.CheckRecord, error) {
return nil, nil
}
func (m *mockStore) ExportData(_ context.Context) (models.Backup, error) { return models.Backup{}, nil }
func (m *mockStore) ImportData(_ context.Context, _ models.Backup) error { return nil }
func (m *mockStore) GetSiteByName(_ context.Context, _ string) (models.Site, error) {
return models.Site{}, nil
}
func (m *mockStore) GetAlertByName(_ context.Context, _ string) (models.AlertConfig, error) {
return models.AlertConfig{}, nil
}
func (m *mockStore) AddSiteReturningID(_ context.Context, _ models.Site) (int, error) { return 0, nil }
func (m *mockStore) AddAlertReturningID(_ context.Context, _ string, _ string, _ map[string]string) (int, error) {
return 0, nil
}
func (m *mockStore) RegisterNode(_ context.Context, _ models.ProbeNode) error { return nil }
func (m *mockStore) GetNode(_ context.Context, _ string) (models.ProbeNode, error) {
return models.ProbeNode{}, nil
}
func (m *mockStore) GetAllNodes(_ context.Context) ([]models.ProbeNode, error) { return nil, nil }
func (m *mockStore) UpdateNodeLastSeen(_ context.Context, _ string) error { return nil }
func (m *mockStore) DeleteNode(_ context.Context, _ string) error { return nil }
func (m *mockStore) LoadAlertHealth(_ context.Context) (map[int]models.AlertHealthRecord, error) {
return nil, nil
}
func (m *mockStore) SaveAlertHealth(_ context.Context, _ models.AlertHealthRecord) error { return nil }
func (m *mockStore) SaveLog(_ context.Context, _ string) error { return nil }
func (m *mockStore) PruneLogs(_ context.Context) error { return nil }
func (m *mockStore) PruneCheckHistory(_ context.Context) error { return nil }
func (m *mockStore) PruneStateChanges(_ context.Context) error { return nil }
func (m *mockStore) LoadLogs(_ context.Context, _ int) ([]string, error) { return nil, nil }
func (m *mockStore) GetActiveMaintenanceWindows(_ context.Context) ([]models.MaintenanceWindow, error) {
return nil, nil
}
func (m *mockStore) GetAllMaintenanceWindows(_ context.Context, _ int) ([]models.MaintenanceWindow, error) {
return nil, nil
}
func (m *mockStore) AddMaintenanceWindow(_ context.Context, _ models.MaintenanceWindow) error {
return nil
}
func (m *mockStore) EndMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *mockStore) DeleteMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *mockStore) PruneExpiredMaintenanceWindows(_ context.Context, _ time.Duration) (int64, error) {
return 0, nil
}
func (m *mockStore) IsMonitorInMaintenance(_ context.Context, _ int) (bool, error) { return false, nil }
func (m *mockStore) GetPreference(_ context.Context, _ string) (string, error) { return "", nil }
func (m *mockStore) SetPreference(_ context.Context, _ string, _ string) error { return nil }
func (m *mockStore) SaveStateChange(_ context.Context, _ int, _ string, _ string, _ string) error {
return nil
}
func (m *mockStore) GetStateChanges(_ context.Context, _ int, _ int) ([]models.StateChange, error) {
return nil, nil
}
func (m *mockStore) GetStateChangesSince(_ context.Context, _ int, _ time.Time) ([]models.StateChange, error) {
return nil, nil
}
func (m *mockStore) Close() error { return nil }
// --- Cluster Start Tests ---
func TestStart_LeaderMode(t *testing.T) {
+4 -84
View File
@@ -10,97 +10,17 @@ import (
"gitea.lerkolabs.com/lerkolabs/uptop/internal/models"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/monitor"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/store/storetest"
)
type mockStore struct {
storetest.BaseMock
sites []models.Site
}
func (m *mockStore) Init(_ context.Context) error { return nil }
func (m *mockStore) GetSites(_ context.Context) ([]models.Site, error) { return m.sites, nil }
func (m *mockStore) AddSite(_ context.Context, _ models.Site) error { return nil }
func (m *mockStore) UpdateSite(_ context.Context, _ models.Site) error { return nil }
func (m *mockStore) UpdateSitePaused(_ context.Context, _ int, _ bool) error { return nil }
func (m *mockStore) DeleteSite(_ context.Context, _ int) error { return nil }
func (m *mockStore) GetAllAlerts(_ context.Context) ([]models.AlertConfig, error) { return nil, nil }
func (m *mockStore) GetAlert(_ context.Context, _ int) (models.AlertConfig, error) {
return models.AlertConfig{}, nil
func (m *mockStore) GetSites(_ context.Context) ([]models.Site, error) {
return m.sites, nil
}
func (m *mockStore) AddAlert(_ context.Context, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *mockStore) UpdateAlert(_ context.Context, _ int, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *mockStore) DeleteAlert(_ context.Context, _ int) error { return nil }
func (m *mockStore) GetAllUsers(_ context.Context) ([]models.User, error) { return nil, nil }
func (m *mockStore) AddUser(_ context.Context, _ string, _ string, _ string) error { return nil }
func (m *mockStore) UpdateUser(_ context.Context, _ int, _ string, _ string, _ string) error {
return nil
}
func (m *mockStore) DeleteUser(_ context.Context, _ int) error { return nil }
func (m *mockStore) SaveCheck(_ context.Context, _ int, _ int64, _ bool) error { return nil }
func (m *mockStore) LoadAllHistory(_ context.Context, _ int) (map[int][]models.CheckRecord, error) {
return nil, nil
}
func (m *mockStore) ExportData(_ context.Context) (models.Backup, error) { return models.Backup{}, nil }
func (m *mockStore) ImportData(_ context.Context, _ models.Backup) error { return nil }
func (m *mockStore) GetSiteByName(_ context.Context, _ string) (models.Site, error) {
return models.Site{}, nil
}
func (m *mockStore) GetAlertByName(_ context.Context, _ string) (models.AlertConfig, error) {
return models.AlertConfig{}, nil
}
func (m *mockStore) AddSiteReturningID(_ context.Context, _ models.Site) (int, error) { return 0, nil }
func (m *mockStore) AddAlertReturningID(_ context.Context, _ string, _ string, _ map[string]string) (int, error) {
return 0, nil
}
func (m *mockStore) SaveCheckFromNode(_ context.Context, _ int, _ string, _ int64, _ bool) error {
return nil
}
func (m *mockStore) RegisterNode(_ context.Context, _ models.ProbeNode) error { return nil }
func (m *mockStore) GetNode(_ context.Context, _ string) (models.ProbeNode, error) {
return models.ProbeNode{}, nil
}
func (m *mockStore) GetAllNodes(_ context.Context) ([]models.ProbeNode, error) { return nil, nil }
func (m *mockStore) UpdateNodeLastSeen(_ context.Context, _ string) error { return nil }
func (m *mockStore) DeleteNode(_ context.Context, _ string) error { return nil }
func (m *mockStore) LoadAlertHealth(_ context.Context) (map[int]models.AlertHealthRecord, error) {
return nil, nil
}
func (m *mockStore) SaveAlertHealth(_ context.Context, _ models.AlertHealthRecord) error { return nil }
func (m *mockStore) SaveLog(_ context.Context, _ string) error { return nil }
func (m *mockStore) PruneLogs(_ context.Context) error { return nil }
func (m *mockStore) PruneCheckHistory(_ context.Context) error { return nil }
func (m *mockStore) PruneStateChanges(_ context.Context) error { return nil }
func (m *mockStore) LoadLogs(_ context.Context, _ int) ([]string, error) { return nil, nil }
func (m *mockStore) GetActiveMaintenanceWindows(_ context.Context) ([]models.MaintenanceWindow, error) {
return nil, nil
}
func (m *mockStore) GetAllMaintenanceWindows(_ context.Context, _ int) ([]models.MaintenanceWindow, error) {
return nil, nil
}
func (m *mockStore) AddMaintenanceWindow(_ context.Context, _ models.MaintenanceWindow) error {
return nil
}
func (m *mockStore) EndMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *mockStore) DeleteMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *mockStore) PruneExpiredMaintenanceWindows(_ context.Context, _ time.Duration) (int64, error) {
return 0, nil
}
func (m *mockStore) IsMonitorInMaintenance(_ context.Context, _ int) (bool, error) { return false, nil }
func (m *mockStore) GetPreference(_ context.Context, _ string) (string, error) { return "", nil }
func (m *mockStore) SetPreference(_ context.Context, _ string, _ string) error { return nil }
func (m *mockStore) SaveStateChange(_ context.Context, _ int, _ string, _ string, _ string) error {
return nil
}
func (m *mockStore) GetStateChanges(_ context.Context, _ int, _ int) ([]models.StateChange, error) {
return nil, nil
}
func (m *mockStore) GetStateChangesSince(_ context.Context, _ int, _ time.Time) ([]models.StateChange, error) {
return nil, nil
}
func (m *mockStore) Close() error { return nil }
func TestMetricsHandler(t *testing.T) {
ms := &mockStore{
+5 -60
View File
@@ -8,6 +8,7 @@ import (
"time"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/models"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/store/storetest"
)
// --- Mock Store ---
@@ -19,6 +20,7 @@ type savedCheck struct {
}
type mockStore struct {
storetest.BaseMock
mu sync.Mutex
sites []models.Site
alerts map[int]models.AlertConfig
@@ -38,42 +40,8 @@ func newMockStore() *mockStore {
}
}
func (m *mockStore) Init(context.Context) error { return nil }
func (m *mockStore) GetSites(context.Context) ([]models.Site, error) { return m.sites, nil }
func (m *mockStore) AddSite(context.Context, models.Site) error { return nil }
func (m *mockStore) UpdateSite(context.Context, models.Site) error { return nil }
func (m *mockStore) UpdateSitePaused(context.Context, int, bool) error { return nil }
func (m *mockStore) DeleteSite(context.Context, int) error { return nil }
func (m *mockStore) AddAlert(context.Context, string, string, map[string]string) error { return nil }
func (m *mockStore) UpdateAlert(context.Context, int, string, string, map[string]string) error {
return nil
}
func (m *mockStore) DeleteAlert(context.Context, int) error { return nil }
func (m *mockStore) GetAllUsers(context.Context) ([]models.User, error) { return nil, nil }
func (m *mockStore) AddUser(context.Context, string, string, string) error { return nil }
func (m *mockStore) UpdateUser(context.Context, int, string, string, string) error { return nil }
func (m *mockStore) DeleteUser(context.Context, int) error { return nil }
func (m *mockStore) ExportData(context.Context) (models.Backup, error) { return models.Backup{}, nil }
func (m *mockStore) ImportData(context.Context, models.Backup) error { return nil }
func (m *mockStore) GetSiteByName(context.Context, string) (models.Site, error) {
return models.Site{}, nil
}
func (m *mockStore) AddSiteReturningID(context.Context, models.Site) (int, error) { return 0, nil }
func (m *mockStore) AddAlertReturningID(context.Context, string, string, map[string]string) (int, error) {
return 0, nil
}
func (m *mockStore) SaveCheckFromNode(context.Context, int, string, int64, bool) error { return nil }
func (m *mockStore) RegisterNode(context.Context, models.ProbeNode) error { return nil }
func (m *mockStore) GetNode(context.Context, string) (models.ProbeNode, error) {
return models.ProbeNode{}, nil
}
func (m *mockStore) GetAllNodes(context.Context) ([]models.ProbeNode, error) { return nil, nil }
func (m *mockStore) UpdateNodeLastSeen(context.Context, string) error { return nil }
func (m *mockStore) DeleteNode(context.Context, string) error { return nil }
func (m *mockStore) LoadAlertHealth(context.Context) (map[int]models.AlertHealthRecord, error) {
return nil, nil
}
func (m *mockStore) SaveAlertHealth(context.Context, models.AlertHealthRecord) error { return nil }
func (m *mockStore) GetActiveMaintenanceWindows(context.Context) ([]models.MaintenanceWindow, error) {
m.mu.Lock()
defer m.mu.Unlock()
@@ -83,25 +51,6 @@ func (m *mockStore) GetActiveMaintenanceWindows(context.Context) ([]models.Maint
}
return windows, nil
}
func (m *mockStore) GetAllMaintenanceWindows(context.Context, int) ([]models.MaintenanceWindow, error) {
return nil, nil
}
func (m *mockStore) AddMaintenanceWindow(context.Context, models.MaintenanceWindow) error { return nil }
func (m *mockStore) EndMaintenanceWindow(context.Context, int) error { return nil }
func (m *mockStore) DeleteMaintenanceWindow(context.Context, int) error { return nil }
func (m *mockStore) PruneExpiredMaintenanceWindows(context.Context, time.Duration) (int64, error) {
return 0, nil
}
func (m *mockStore) GetPreference(context.Context, string) (string, error) { return "", nil }
func (m *mockStore) SetPreference(context.Context, string, string) error { return nil }
func (m *mockStore) SaveStateChange(context.Context, int, string, string, string) error { return nil }
func (m *mockStore) GetStateChanges(context.Context, int, int) ([]models.StateChange, error) {
return nil, nil
}
func (m *mockStore) GetStateChangesSince(context.Context, int, time.Time) ([]models.StateChange, error) {
return nil, nil
}
func (m *mockStore) Close() error { return nil }
func (m *mockStore) GetAllAlerts(context.Context) ([]models.AlertConfig, error) {
m.mu.Lock()
@@ -154,18 +103,14 @@ func (m *mockStore) SaveLog(_ context.Context, msg string) error {
return nil
}
func (m *mockStore) LoadLogs(_ context.Context, limit int) ([]string, error) {
func (m *mockStore) LoadLogs(_ context.Context, _ int) ([]string, error) {
return m.logs, nil
}
func (m *mockStore) LoadAllHistory(_ context.Context, limit int) (map[int][]models.CheckRecord, error) {
func (m *mockStore) LoadAllHistory(_ context.Context, _ int) (map[int][]models.CheckRecord, error) {
return m.history, nil
}
func (m *mockStore) PruneLogs(context.Context) error { return nil }
func (m *mockStore) PruneCheckHistory(context.Context) error { return nil }
func (m *mockStore) PruneStateChanges(context.Context) error { return nil }
// --- Helpers ---
func newTestEngine(ms *mockStore) *Engine {
+2 -74
View File
@@ -13,11 +13,13 @@ import (
"gitea.lerkolabs.com/lerkolabs/uptop/internal/models"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/monitor"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/store/storetest"
)
// --- Mock Store ---
type mockStore struct {
storetest.BaseMock
mu sync.Mutex
sites []models.Site
alerts []models.AlertConfig
@@ -33,84 +35,10 @@ func newMockStore() *mockStore {
}
}
func (m *mockStore) Init(_ context.Context) error { return nil }
func (m *mockStore) GetSites(_ context.Context) ([]models.Site, error) { return m.sites, nil }
func (m *mockStore) AddSite(_ context.Context, _ models.Site) error { return nil }
func (m *mockStore) UpdateSite(_ context.Context, _ models.Site) error { return nil }
func (m *mockStore) UpdateSitePaused(_ context.Context, _ int, _ bool) error { return nil }
func (m *mockStore) DeleteSite(_ context.Context, _ int) error { return nil }
func (m *mockStore) GetAllAlerts(_ context.Context) ([]models.AlertConfig, error) {
return m.alerts, nil
}
func (m *mockStore) GetAlert(_ context.Context, _ int) (models.AlertConfig, error) {
return models.AlertConfig{}, nil
}
func (m *mockStore) AddAlert(_ context.Context, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *mockStore) UpdateAlert(_ context.Context, _ int, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *mockStore) DeleteAlert(_ context.Context, _ int) error { return nil }
func (m *mockStore) GetAllUsers(_ context.Context) ([]models.User, error) { return nil, nil }
func (m *mockStore) AddUser(_ context.Context, _ string, _ string, _ string) error { return nil }
func (m *mockStore) UpdateUser(_ context.Context, _ int, _ string, _ string, _ string) error {
return nil
}
func (m *mockStore) DeleteUser(_ context.Context, _ int) error { return nil }
func (m *mockStore) SaveCheck(_ context.Context, _ int, _ int64, _ bool) error { return nil }
func (m *mockStore) SaveCheckFromNode(_ context.Context, siteID int, nodeID string, latencyNs int64, isUp bool) error {
return nil
}
func (m *mockStore) LoadAllHistory(_ context.Context, _ int) (map[int][]models.CheckRecord, error) {
return nil, nil
}
func (m *mockStore) GetSiteByName(_ context.Context, _ string) (models.Site, error) {
return models.Site{}, nil
}
func (m *mockStore) GetAlertByName(_ context.Context, _ string) (models.AlertConfig, error) {
return models.AlertConfig{}, nil
}
func (m *mockStore) AddSiteReturningID(_ context.Context, _ models.Site) (int, error) { return 0, nil }
func (m *mockStore) AddAlertReturningID(_ context.Context, _ string, _ string, _ map[string]string) (int, error) {
return 0, nil
}
func (m *mockStore) GetAllNodes(_ context.Context) ([]models.ProbeNode, error) { return nil, nil }
func (m *mockStore) UpdateNodeLastSeen(_ context.Context, _ string) error { return nil }
func (m *mockStore) DeleteNode(_ context.Context, _ string) error { return nil }
func (m *mockStore) LoadAlertHealth(_ context.Context) (map[int]models.AlertHealthRecord, error) {
return nil, nil
}
func (m *mockStore) SaveAlertHealth(_ context.Context, _ models.AlertHealthRecord) error { return nil }
func (m *mockStore) SaveLog(_ context.Context, _ string) error { return nil }
func (m *mockStore) PruneLogs(_ context.Context) error { return nil }
func (m *mockStore) PruneCheckHistory(_ context.Context) error { return nil }
func (m *mockStore) PruneStateChanges(_ context.Context) error { return nil }
func (m *mockStore) LoadLogs(_ context.Context, _ int) ([]string, error) { return nil, nil }
func (m *mockStore) GetAllMaintenanceWindows(_ context.Context, _ int) ([]models.MaintenanceWindow, error) {
return nil, nil
}
func (m *mockStore) AddMaintenanceWindow(_ context.Context, _ models.MaintenanceWindow) error {
return nil
}
func (m *mockStore) EndMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *mockStore) DeleteMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *mockStore) PruneExpiredMaintenanceWindows(_ context.Context, _ time.Duration) (int64, error) {
return 0, nil
}
func (m *mockStore) IsMonitorInMaintenance(_ context.Context, _ int) (bool, error) { return false, nil }
func (m *mockStore) GetPreference(_ context.Context, _ string) (string, error) { return "", nil }
func (m *mockStore) SetPreference(_ context.Context, _ string, _ string) error { return nil }
func (m *mockStore) SaveStateChange(_ context.Context, _ int, _ string, _ string, _ string) error {
return nil
}
func (m *mockStore) GetStateChanges(_ context.Context, _ int, _ int) ([]models.StateChange, error) {
return nil, nil
}
func (m *mockStore) GetStateChangesSince(_ context.Context, _ int, _ time.Time) ([]models.StateChange, error) {
return nil, nil
}
func (m *mockStore) Close() error { return nil }
func (m *mockStore) ExportData(_ context.Context) (models.Backup, error) {
return models.Backup{
+274
View File
@@ -0,0 +1,274 @@
package storetest
import (
"context"
"time"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/models"
)
// BaseMock implements store.Store with no-op defaults. Embed it in test-specific
// mocks and override only the methods you need via the exported Func fields or
// by shadowing the method on the embedding struct.
type BaseMock struct {
GetSitesFunc func(ctx context.Context) ([]models.Site, error)
AddSiteFunc func(ctx context.Context, site models.Site) error
UpdateSiteFunc func(ctx context.Context, site models.Site) error
GetAllAlertsFunc func(ctx context.Context) ([]models.AlertConfig, error)
GetAlertFunc func(ctx context.Context, id int) (models.AlertConfig, error)
GetAllUsersFunc func(ctx context.Context) ([]models.User, error)
GetAllNodesFunc func(ctx context.Context) ([]models.ProbeNode, error)
GetActiveMaintenanceWindowsFunc func(ctx context.Context) ([]models.MaintenanceWindow, error)
GetAllMaintenanceWindowsFunc func(ctx context.Context, limit int) ([]models.MaintenanceWindow, error)
IsMonitorInMaintenanceFunc func(ctx context.Context, id int) (bool, error)
LoadAlertHealthFunc func(ctx context.Context) (map[int]models.AlertHealthRecord, error)
LoadAllHistoryFunc func(ctx context.Context, limit int) (map[int][]models.CheckRecord, error)
SaveCheckFunc func(ctx context.Context, siteID int, latencyNs int64, isUp bool) error
SaveCheckFromNodeFunc func(ctx context.Context, siteID int, nodeID string, latencyNs int64, isUp bool) error
SaveLogFunc func(ctx context.Context, message string) error
SaveStateChangeFunc func(ctx context.Context, siteID int, from, to, reason string) error
SaveAlertHealthFunc func(ctx context.Context, h models.AlertHealthRecord) error
GetStateChangesFunc func(ctx context.Context, siteID, limit int) ([]models.StateChange, error)
GetStateChangesSinceFunc func(ctx context.Context, siteID int, since time.Time) ([]models.StateChange, error)
ExportDataFunc func(ctx context.Context) (models.Backup, error)
ImportDataFunc func(ctx context.Context, data models.Backup) error
RegisterNodeFunc func(ctx context.Context, node models.ProbeNode) error
GetNodeFunc func(ctx context.Context, id string) (models.ProbeNode, error)
GetPreferenceFunc func(ctx context.Context, key string) (string, error)
SetPreferenceFunc func(ctx context.Context, key, value string) error
}
func (m *BaseMock) Init(_ context.Context) error { return nil }
func (m *BaseMock) Close() error { return nil }
func (m *BaseMock) GetSites(ctx context.Context) ([]models.Site, error) {
if m.GetSitesFunc != nil {
return m.GetSitesFunc(ctx)
}
return nil, nil
}
func (m *BaseMock) AddSite(ctx context.Context, site models.Site) error {
if m.AddSiteFunc != nil {
return m.AddSiteFunc(ctx, site)
}
return nil
}
func (m *BaseMock) UpdateSite(ctx context.Context, site models.Site) error {
if m.UpdateSiteFunc != nil {
return m.UpdateSiteFunc(ctx, site)
}
return nil
}
func (m *BaseMock) UpdateSitePaused(_ context.Context, _ int, _ bool) error { return nil }
func (m *BaseMock) DeleteSite(_ context.Context, _ int) error { return nil }
func (m *BaseMock) GetAllAlerts(ctx context.Context) ([]models.AlertConfig, error) {
if m.GetAllAlertsFunc != nil {
return m.GetAllAlertsFunc(ctx)
}
return nil, nil
}
func (m *BaseMock) GetAlert(ctx context.Context, id int) (models.AlertConfig, error) {
if m.GetAlertFunc != nil {
return m.GetAlertFunc(ctx, id)
}
return models.AlertConfig{}, nil
}
func (m *BaseMock) AddAlert(_ context.Context, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *BaseMock) UpdateAlert(_ context.Context, _ int, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *BaseMock) DeleteAlert(_ context.Context, _ int) error { return nil }
func (m *BaseMock) GetSiteByName(_ context.Context, _ string) (models.Site, error) {
return models.Site{}, nil
}
func (m *BaseMock) GetAlertByName(_ context.Context, _ string) (models.AlertConfig, error) {
return models.AlertConfig{}, nil
}
func (m *BaseMock) AddSiteReturningID(_ context.Context, _ models.Site) (int, error) { return 0, nil }
func (m *BaseMock) AddAlertReturningID(_ context.Context, _ string, _ string, _ map[string]string) (int, error) {
return 0, nil
}
func (m *BaseMock) GetAllUsers(ctx context.Context) ([]models.User, error) {
if m.GetAllUsersFunc != nil {
return m.GetAllUsersFunc(ctx)
}
return nil, nil
}
func (m *BaseMock) AddUser(_ context.Context, _ string, _ string, _ string) error { return nil }
func (m *BaseMock) UpdateUser(_ context.Context, _ int, _ string, _ string, _ string) error {
return nil
}
func (m *BaseMock) DeleteUser(_ context.Context, _ int) error { return nil }
func (m *BaseMock) SaveCheck(ctx context.Context, siteID int, latencyNs int64, isUp bool) error {
if m.SaveCheckFunc != nil {
return m.SaveCheckFunc(ctx, siteID, latencyNs, isUp)
}
return nil
}
func (m *BaseMock) SaveCheckFromNode(ctx context.Context, siteID int, nodeID string, latencyNs int64, isUp bool) error {
if m.SaveCheckFromNodeFunc != nil {
return m.SaveCheckFromNodeFunc(ctx, siteID, nodeID, latencyNs, isUp)
}
return nil
}
func (m *BaseMock) LoadAllHistory(ctx context.Context, limit int) (map[int][]models.CheckRecord, error) {
if m.LoadAllHistoryFunc != nil {
return m.LoadAllHistoryFunc(ctx, limit)
}
return nil, nil
}
func (m *BaseMock) PruneCheckHistory(_ context.Context) error { return nil }
func (m *BaseMock) SaveStateChange(ctx context.Context, siteID int, from, to, reason string) error {
if m.SaveStateChangeFunc != nil {
return m.SaveStateChangeFunc(ctx, siteID, from, to, reason)
}
return nil
}
func (m *BaseMock) GetStateChanges(ctx context.Context, siteID, limit int) ([]models.StateChange, error) {
if m.GetStateChangesFunc != nil {
return m.GetStateChangesFunc(ctx, siteID, limit)
}
return nil, nil
}
func (m *BaseMock) GetStateChangesSince(ctx context.Context, siteID int, since time.Time) ([]models.StateChange, error) {
if m.GetStateChangesSinceFunc != nil {
return m.GetStateChangesSinceFunc(ctx, siteID, since)
}
return nil, nil
}
func (m *BaseMock) PruneStateChanges(_ context.Context) error { return nil }
func (m *BaseMock) RegisterNode(ctx context.Context, node models.ProbeNode) error {
if m.RegisterNodeFunc != nil {
return m.RegisterNodeFunc(ctx, node)
}
return nil
}
func (m *BaseMock) GetNode(ctx context.Context, id string) (models.ProbeNode, error) {
if m.GetNodeFunc != nil {
return m.GetNodeFunc(ctx, id)
}
return models.ProbeNode{}, nil
}
func (m *BaseMock) GetAllNodes(ctx context.Context) ([]models.ProbeNode, error) {
if m.GetAllNodesFunc != nil {
return m.GetAllNodesFunc(ctx)
}
return nil, nil
}
func (m *BaseMock) UpdateNodeLastSeen(_ context.Context, _ string) error { return nil }
func (m *BaseMock) DeleteNode(_ context.Context, _ string) error { return nil }
func (m *BaseMock) LoadAlertHealth(ctx context.Context) (map[int]models.AlertHealthRecord, error) {
if m.LoadAlertHealthFunc != nil {
return m.LoadAlertHealthFunc(ctx)
}
return nil, nil
}
func (m *BaseMock) SaveAlertHealth(ctx context.Context, h models.AlertHealthRecord) error {
if m.SaveAlertHealthFunc != nil {
return m.SaveAlertHealthFunc(ctx, h)
}
return nil
}
func (m *BaseMock) SaveLog(ctx context.Context, message string) error {
if m.SaveLogFunc != nil {
return m.SaveLogFunc(ctx, message)
}
return nil
}
func (m *BaseMock) LoadLogs(_ context.Context, _ int) ([]string, error) { return nil, nil }
func (m *BaseMock) PruneLogs(_ context.Context) error { return nil }
func (m *BaseMock) GetActiveMaintenanceWindows(ctx context.Context) ([]models.MaintenanceWindow, error) {
if m.GetActiveMaintenanceWindowsFunc != nil {
return m.GetActiveMaintenanceWindowsFunc(ctx)
}
return nil, nil
}
func (m *BaseMock) GetAllMaintenanceWindows(ctx context.Context, limit int) ([]models.MaintenanceWindow, error) {
if m.GetAllMaintenanceWindowsFunc != nil {
return m.GetAllMaintenanceWindowsFunc(ctx, limit)
}
return nil, nil
}
func (m *BaseMock) AddMaintenanceWindow(_ context.Context, _ models.MaintenanceWindow) error {
return nil
}
func (m *BaseMock) EndMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *BaseMock) DeleteMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *BaseMock) PruneExpiredMaintenanceWindows(_ context.Context, _ time.Duration) (int64, error) {
return 0, nil
}
func (m *BaseMock) IsMonitorInMaintenance(ctx context.Context, id int) (bool, error) {
if m.IsMonitorInMaintenanceFunc != nil {
return m.IsMonitorInMaintenanceFunc(ctx, id)
}
return false, nil
}
func (m *BaseMock) GetPreference(ctx context.Context, key string) (string, error) {
if m.GetPreferenceFunc != nil {
return m.GetPreferenceFunc(ctx, key)
}
return "", nil
}
func (m *BaseMock) SetPreference(ctx context.Context, key, value string) error {
if m.SetPreferenceFunc != nil {
return m.SetPreferenceFunc(ctx, key, value)
}
return nil
}
func (m *BaseMock) ExportData(ctx context.Context) (models.Backup, error) {
if m.ExportDataFunc != nil {
return m.ExportDataFunc(ctx)
}
return models.Backup{}, nil
}
func (m *BaseMock) ImportData(ctx context.Context, data models.Backup) error {
if m.ImportDataFunc != nil {
return m.ImportDataFunc(ctx, data)
}
return nil
}
+4 -86
View File
@@ -8,6 +8,7 @@ import (
"gitea.lerkolabs.com/lerkolabs/uptop/internal/models"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/monitor"
"gitea.lerkolabs.com/lerkolabs/uptop/internal/store/storetest"
tea "github.com/charmbracelet/bubbletea"
zone "github.com/lrstanley/bubblezone"
)
@@ -15,13 +16,14 @@ import (
// --- minimal Store mock for TUI data-flow tests ---
type tuiMockStore struct {
storetest.BaseMock
alerts []models.AlertConfig
users []models.User
nodes []models.ProbeNode
maint []models.MaintenanceWindow
stateChanges []models.StateChange
stateChangeCalls int // counts GetStateChanges hits (to prove View does no IO)
deleteSiteCalls int // counts DeleteSite hits (to prove writes run in Cmds)
stateChangeCalls int
deleteSiteCalls int
}
func (m *tuiMockStore) GetAllAlerts(_ context.Context) ([]models.AlertConfig, error) {
@@ -38,94 +40,10 @@ func (m *tuiMockStore) GetStateChanges(_ context.Context, _ int, _ int) ([]model
func (m *tuiMockStore) GetAllMaintenanceWindows(_ context.Context, _ int) ([]models.MaintenanceWindow, error) {
return m.maint, nil
}
func (m *tuiMockStore) Init(_ context.Context) error { return nil }
func (m *tuiMockStore) GetSites(_ context.Context) ([]models.Site, error) { return nil, nil }
func (m *tuiMockStore) AddSite(_ context.Context, _ models.Site) error { return nil }
func (m *tuiMockStore) UpdateSite(_ context.Context, _ models.Site) error { return nil }
func (m *tuiMockStore) UpdateSitePaused(_ context.Context, _ int, _ bool) error { return nil }
func (m *tuiMockStore) DeleteSite(_ context.Context, _ int) error {
m.deleteSiteCalls++
return nil
}
func (m *tuiMockStore) GetAlert(_ context.Context, _ int) (models.AlertConfig, error) {
return models.AlertConfig{}, nil
}
func (m *tuiMockStore) AddAlert(_ context.Context, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *tuiMockStore) UpdateAlert(_ context.Context, _ int, _ string, _ string, _ map[string]string) error {
return nil
}
func (m *tuiMockStore) DeleteAlert(_ context.Context, _ int) error { return nil }
func (m *tuiMockStore) GetSiteByName(_ context.Context, _ string) (models.Site, error) {
return models.Site{}, nil
}
func (m *tuiMockStore) GetAlertByName(_ context.Context, _ string) (models.AlertConfig, error) {
return models.AlertConfig{}, nil
}
func (m *tuiMockStore) AddSiteReturningID(_ context.Context, _ models.Site) (int, error) {
return 0, nil
}
func (m *tuiMockStore) AddAlertReturningID(_ context.Context, _ string, _ string, _ map[string]string) (int, error) {
return 0, nil
}
func (m *tuiMockStore) AddUser(_ context.Context, _ string, _ string, _ string) error { return nil }
func (m *tuiMockStore) UpdateUser(_ context.Context, _ int, _ string, _ string, _ string) error {
return nil
}
func (m *tuiMockStore) DeleteUser(_ context.Context, _ int) error { return nil }
func (m *tuiMockStore) SaveCheck(_ context.Context, _ int, _ int64, _ bool) error { return nil }
func (m *tuiMockStore) SaveCheckFromNode(_ context.Context, _ int, _ string, _ int64, _ bool) error {
return nil
}
func (m *tuiMockStore) LoadAllHistory(_ context.Context, _ int) (map[int][]models.CheckRecord, error) {
return nil, nil
}
func (m *tuiMockStore) PruneCheckHistory(_ context.Context) error { return nil }
func (m *tuiMockStore) SaveStateChange(_ context.Context, _ int, _ string, _ string, _ string) error {
return nil
}
func (m *tuiMockStore) GetStateChangesSince(_ context.Context, _ int, _ time.Time) ([]models.StateChange, error) {
return nil, nil
}
func (m *tuiMockStore) PruneStateChanges(_ context.Context) error { return nil }
func (m *tuiMockStore) RegisterNode(_ context.Context, _ models.ProbeNode) error { return nil }
func (m *tuiMockStore) GetNode(_ context.Context, _ string) (models.ProbeNode, error) {
return models.ProbeNode{}, nil
}
func (m *tuiMockStore) UpdateNodeLastSeen(_ context.Context, _ string) error { return nil }
func (m *tuiMockStore) DeleteNode(_ context.Context, _ string) error { return nil }
func (m *tuiMockStore) LoadAlertHealth(_ context.Context) (map[int]models.AlertHealthRecord, error) {
return nil, nil
}
func (m *tuiMockStore) SaveAlertHealth(_ context.Context, _ models.AlertHealthRecord) error {
return nil
}
func (m *tuiMockStore) SaveLog(_ context.Context, _ string) error { return nil }
func (m *tuiMockStore) LoadLogs(_ context.Context, _ int) ([]string, error) { return nil, nil }
func (m *tuiMockStore) PruneLogs(_ context.Context) error { return nil }
func (m *tuiMockStore) GetActiveMaintenanceWindows(_ context.Context) ([]models.MaintenanceWindow, error) {
return nil, nil
}
func (m *tuiMockStore) AddMaintenanceWindow(_ context.Context, _ models.MaintenanceWindow) error {
return nil
}
func (m *tuiMockStore) EndMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *tuiMockStore) DeleteMaintenanceWindow(_ context.Context, _ int) error { return nil }
func (m *tuiMockStore) PruneExpiredMaintenanceWindows(_ context.Context, _ time.Duration) (int64, error) {
return 0, nil
}
func (m *tuiMockStore) IsMonitorInMaintenance(_ context.Context, _ int) (bool, error) {
return false, nil
}
func (m *tuiMockStore) GetPreference(_ context.Context, _ string) (string, error) { return "", nil }
func (m *tuiMockStore) SetPreference(_ context.Context, _ string, _ string) error { return nil }
func (m *tuiMockStore) ExportData(_ context.Context) (models.Backup, error) {
return models.Backup{}, nil
}
func (m *tuiMockStore) ImportData(_ context.Context, _ models.Backup) error { return nil }
func (m *tuiMockStore) Close() error { return nil }
func newTestModel(ms *tuiMockStore) Model {
return Model{