ScuttleBot

scuttlebot / internal / config / history_test.go
Source Blame History 104 lines
17e2c1d… lmata 1 package config
17e2c1d… lmata 2
17e2c1d… lmata 3 import (
17e2c1d… lmata 4 "os"
17e2c1d… lmata 5 "path/filepath"
17e2c1d… lmata 6 "testing"
17e2c1d… lmata 7 "time"
17e2c1d… lmata 8 )
17e2c1d… lmata 9
17e2c1d… lmata 10 func TestSnapshotAndPrune(t *testing.T) {
17e2c1d… lmata 11 dir := t.TempDir()
17e2c1d… lmata 12 histDir := filepath.Join(dir, "history")
17e2c1d… lmata 13 configPath := filepath.Join(dir, "scuttlebot.yaml")
17e2c1d… lmata 14
17e2c1d… lmata 15 // No-op when config file doesn't exist yet.
17e2c1d… lmata 16 if err := SnapshotConfig(histDir, configPath); err != nil {
17e2c1d… lmata 17 t.Fatalf("SnapshotConfig (no file): %v", err)
17e2c1d… lmata 18 }
17e2c1d… lmata 19
17e2c1d… lmata 20 // Write a config file and snapshot it.
17e2c1d… lmata 21 if err := os.WriteFile(configPath, []byte("bridge:\n enabled: true\n"), 0o600); err != nil {
17e2c1d… lmata 22 t.Fatal(err)
17e2c1d… lmata 23 }
17e2c1d… lmata 24 if err := SnapshotConfig(histDir, configPath); err != nil {
17e2c1d… lmata 25 t.Fatalf("SnapshotConfig: %v", err)
17e2c1d… lmata 26 }
17e2c1d… lmata 27
17e2c1d… lmata 28 entries, err := ListHistory(histDir, "scuttlebot.yaml")
17e2c1d… lmata 29 if err != nil {
17e2c1d… lmata 30 t.Fatal(err)
17e2c1d… lmata 31 }
17e2c1d… lmata 32 if len(entries) != 1 {
17e2c1d… lmata 33 t.Fatalf("want 1 snapshot, got %d", len(entries))
17e2c1d… lmata 34 }
17e2c1d… lmata 35 if entries[0].Size == 0 {
17e2c1d… lmata 36 t.Error("snapshot size should be non-zero")
17e2c1d… lmata 37 }
17e2c1d… lmata 38 if entries[0].Timestamp.IsZero() {
17e2c1d… lmata 39 t.Error("snapshot timestamp should be set")
17e2c1d… lmata 40 }
17e2c1d… lmata 41 }
17e2c1d… lmata 42
17e2c1d… lmata 43 func TestPruneHistory(t *testing.T) {
17e2c1d… lmata 44 dir := t.TempDir()
17e2c1d… lmata 45 base := "scuttlebot.yaml"
17e2c1d… lmata 46 keep := 3
17e2c1d… lmata 47
17e2c1d… lmata 48 // Write 5 snapshot files with distinct timestamps.
17e2c1d… lmata 49 for i := range 5 {
17e2c1d… lmata 50 stamp := time.Now().Add(time.Duration(i) * time.Second).Format(historyTimestampFormat)
17e2c1d… lmata 51 name := filepath.Join(dir, base+"."+stamp)
17e2c1d… lmata 52 if err := os.WriteFile(name, []byte("v"), 0o600); err != nil {
17e2c1d… lmata 53 t.Fatal(err)
17e2c1d… lmata 54 }
17e2c1d… lmata 55 // Ensure distinct mtime ordering.
17e2c1d… lmata 56 time.Sleep(2 * time.Millisecond)
17e2c1d… lmata 57 }
17e2c1d… lmata 58
17e2c1d… lmata 59 if err := PruneHistory(dir, base, keep); err != nil {
17e2c1d… lmata 60 t.Fatal(err)
17e2c1d… lmata 61 }
17e2c1d… lmata 62
17e2c1d… lmata 63 entries, err := ListHistory(dir, base)
17e2c1d… lmata 64 if err != nil {
17e2c1d… lmata 65 t.Fatal(err)
17e2c1d… lmata 66 }
17e2c1d… lmata 67 if len(entries) != keep {
17e2c1d… lmata 68 t.Errorf("want %d entries after prune, got %d", keep, len(entries))
17e2c1d… lmata 69 }
17e2c1d… lmata 70 }
17e2c1d… lmata 71
17e2c1d… lmata 72 func TestConfigSaveRoundTrip(t *testing.T) {
17e2c1d… lmata 73 dir := t.TempDir()
17e2c1d… lmata 74 path := filepath.Join(dir, "scuttlebot.yaml")
17e2c1d… lmata 75
17e2c1d… lmata 76 var cfg Config
17e2c1d… lmata 77 cfg.Defaults()
17e2c1d… lmata 78 cfg.Topology.Channels = []StaticChannelConfig{
17e2c1d… lmata 79 {Name: "#general", Topic: "Fleet coordination", Autojoin: []string{"bridge"}},
17e2c1d… lmata 80 }
17e2c1d… lmata 81 cfg.Topology.Types = []ChannelTypeConfig{
17e2c1d… lmata 82 {Name: "task", Prefix: "task.", Ephemeral: true, TTL: Duration{72 * time.Hour}},
17e2c1d… lmata 83 }
17e2c1d… lmata 84
17e2c1d… lmata 85 if err := cfg.Save(path); err != nil {
17e2c1d… lmata 86 t.Fatalf("Save: %v", err)
17e2c1d… lmata 87 }
17e2c1d… lmata 88
17e2c1d… lmata 89 var loaded Config
17e2c1d… lmata 90 loaded.Defaults()
17e2c1d… lmata 91 if err := loaded.LoadFile(path); err != nil {
17e2c1d… lmata 92 t.Fatalf("LoadFile: %v", err)
17e2c1d… lmata 93 }
17e2c1d… lmata 94
17e2c1d… lmata 95 if len(loaded.Topology.Channels) != 1 || loaded.Topology.Channels[0].Name != "#general" {
17e2c1d… lmata 96 t.Errorf("topology channels not round-tripped: %+v", loaded.Topology.Channels)
17e2c1d… lmata 97 }
17e2c1d… lmata 98 if len(loaded.Topology.Types) != 1 || loaded.Topology.Types[0].Name != "task" {
17e2c1d… lmata 99 t.Errorf("topology types not round-tripped: %+v", loaded.Topology.Types)
17e2c1d… lmata 100 }
17e2c1d… lmata 101 if loaded.Topology.Types[0].TTL.Duration != 72*time.Hour {
17e2c1d… lmata 102 t.Errorf("TTL = %v, want 72h", loaded.Topology.Types[0].TTL.Duration)
17e2c1d… lmata 103 }
17e2c1d… lmata 104 }

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button