diff --git a/cmd/uptop/keycache_test.go b/cmd/uptop/keycache_test.go index dc10640..09af153 100644 --- a/cmd/uptop/keycache_test.go +++ b/cmd/uptop/keycache_test.go @@ -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() diff --git a/internal/cluster/cluster_test.go b/internal/cluster/cluster_test.go index a8ea1dd..bb36f4a 100644 --- a/internal/cluster/cluster_test.go +++ b/internal/cluster/cluster_test.go @@ -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) { diff --git a/internal/metrics/prometheus_test.go b/internal/metrics/prometheus_test.go index 9352bc4..ccf3d0f 100644 --- a/internal/metrics/prometheus_test.go +++ b/internal/metrics/prometheus_test.go @@ -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{ diff --git a/internal/monitor/monitor_test.go b/internal/monitor/monitor_test.go index 80c5936..28f4ae0 100644 --- a/internal/monitor/monitor_test.go +++ b/internal/monitor/monitor_test.go @@ -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) GetSites(context.Context) ([]models.Site, error) { return m.sites, 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 { diff --git a/internal/server/server_test.go b/internal/server/server_test.go index ad14ef9..77eb81e 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -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) GetSites(_ context.Context) ([]models.Site, error) { return m.sites, 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{ diff --git a/internal/store/storetest/mock.go b/internal/store/storetest/mock.go new file mode 100644 index 0000000..d8686f9 --- /dev/null +++ b/internal/store/storetest/mock.go @@ -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 +} diff --git a/internal/tui/update_test.go b/internal/tui/update_test.go index cc82a49..f08338d 100644 --- a/internal/tui/update_test.go +++ b/internal/tui/update_test.go @@ -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{