summaryrefslogtreecommitdiff
path: root/internal/storage/excluded_host_test.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-16 08:43:55 +0300
committerPaul Buetow <paul@buetow.org>2026-04-16 08:43:55 +0300
commitedeffd05dc62c4c3d747cc41067bf4e1814f300a (patch)
tree11881c2f5a40013b3885e4a6b51b8a4f00e56f80 /internal/storage/excluded_host_test.go
parent71211a54519e13c9ba5ba928352fa4fef001240b (diff)
Add excluded_hosts feature: store in SQLite, expose CLI subcommands
Adds an excluded_host table to the SQLite schema and three new CLI subcommands (exclude, unexclude, list-excluded) so operators can mark hosts that are no longer expected to send updates. The IsExcludedHost and LoadExcludedHosts storage helpers are ready for the Prometheus alerting endpoint (task d4). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/storage/excluded_host_test.go')
-rw-r--r--internal/storage/excluded_host_test.go148
1 files changed, 148 insertions, 0 deletions
diff --git a/internal/storage/excluded_host_test.go b/internal/storage/excluded_host_test.go
new file mode 100644
index 0000000..6af53a5
--- /dev/null
+++ b/internal/storage/excluded_host_test.go
@@ -0,0 +1,148 @@
+package storage
+
+import (
+ "context"
+ "path/filepath"
+ "testing"
+)
+
+func TestAddExcludedHost(t *testing.T) {
+ db, err := Open(context.Background(), filepath.Join(t.TempDir(), "test.db"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer db.Close()
+ ctx := context.Background()
+ if err := CreateSchema(ctx, db); err != nil {
+ t.Fatal(err)
+ }
+ if err := AddExcludedHost(ctx, db, "host1", "decommissioned"); err != nil {
+ t.Fatal(err)
+ }
+ hosts, err := LoadExcludedHosts(ctx, db)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(hosts) != 1 {
+ t.Fatalf("len=%d, want 1", len(hosts))
+ }
+ if hosts[0].Host != "host1" || hosts[0].Reason != "decommissioned" {
+ t.Fatalf("unexpected host entry: %+v", hosts[0])
+ }
+}
+
+func TestAddExcludedHost_idempotent(t *testing.T) {
+ db, err := Open(context.Background(), filepath.Join(t.TempDir(), "test.db"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer db.Close()
+ ctx := context.Background()
+ if err := CreateSchema(ctx, db); err != nil {
+ t.Fatal(err)
+ }
+ if err := AddExcludedHost(ctx, db, "host1", "first"); err != nil {
+ t.Fatal(err)
+ }
+ if err := AddExcludedHost(ctx, db, "host1", "second"); err != nil {
+ t.Fatal(err)
+ }
+ hosts, err := LoadExcludedHosts(ctx, db)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(hosts) != 1 {
+ t.Fatalf("len=%d, want 1", len(hosts))
+ }
+ if hosts[0].Reason != "second" {
+ t.Fatalf("reason=%q, want second", hosts[0].Reason)
+ }
+}
+
+func TestRemoveExcludedHost(t *testing.T) {
+ db, err := Open(context.Background(), filepath.Join(t.TempDir(), "test.db"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer db.Close()
+ ctx := context.Background()
+ if err := CreateSchema(ctx, db); err != nil {
+ t.Fatal(err)
+ }
+ if err := AddExcludedHost(ctx, db, "host1", ""); err != nil {
+ t.Fatal(err)
+ }
+ if err := RemoveExcludedHost(ctx, db, "host1"); err != nil {
+ t.Fatal(err)
+ }
+ hosts, err := LoadExcludedHosts(ctx, db)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(hosts) != 0 {
+ t.Fatalf("len=%d, want 0", len(hosts))
+ }
+}
+
+func TestRemoveExcludedHost_nonexistent(t *testing.T) {
+ db, err := Open(context.Background(), filepath.Join(t.TempDir(), "test.db"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer db.Close()
+ ctx := context.Background()
+ if err := CreateSchema(ctx, db); err != nil {
+ t.Fatal(err)
+ }
+ if err := RemoveExcludedHost(ctx, db, "ghost"); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestIsExcludedHost(t *testing.T) {
+ db, err := Open(context.Background(), filepath.Join(t.TempDir(), "test.db"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer db.Close()
+ ctx := context.Background()
+ if err := CreateSchema(ctx, db); err != nil {
+ t.Fatal(err)
+ }
+ if err := AddExcludedHost(ctx, db, "host1", ""); err != nil {
+ t.Fatal(err)
+ }
+ yes, err := IsExcludedHost(ctx, db, "host1")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !yes {
+ t.Fatal("expected host1 to be excluded")
+ }
+ no, err := IsExcludedHost(ctx, db, "other")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if no {
+ t.Fatal("expected other to not be excluded")
+ }
+}
+
+func TestLoadExcludedHosts_empty(t *testing.T) {
+ db, err := Open(context.Background(), filepath.Join(t.TempDir(), "test.db"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer db.Close()
+ ctx := context.Background()
+ if err := CreateSchema(ctx, db); err != nil {
+ t.Fatal(err)
+ }
+ hosts, err := LoadExcludedHosts(ctx, db)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(hosts) != 0 {
+ t.Fatalf("len=%d, want 0", len(hosts))
+ }
+}