package mock import ( "context" "net" "os" "path/filepath" "testing" "tera-clone/services/tera-api/internal/domain" "tera-clone/services/tera-api/internal/logservice" "tera-clone/services/tera-api/internal/logstorage" ) func TestClearPortInvalidatesOtherStoreCacheAndContinuesCapture(t *testing.T) { journal, err := logstorage.Open(logstorage.Options{Root: t.TempDir(), Clock: fixedClock}) if err != nil { t.Fatal(err) } socketDir, err := os.MkdirTemp("", "clear-sock-") if err != nil { t.Fatal(err) } defer os.RemoveAll(socketDir) socket := filepath.Join(socketDir, "clear.sock") listener, err := net.Listen("unix", socket) if err != nil { t.Fatal(err) } done := make(chan error, 1) go func() { done <- (logservice.Server{Store: journal}).Serve(listener) }() defer func() { _ = listener.Close(); <-done }() options := StoreOptions{LogJournal: logservice.NewClient(socket)} first, err := NewStoreWithOptions(fixedClock, options) if err != nil { t.Fatal(err) } defer first.Close() second, err := NewStoreWithOptions(fixedClock, options) if err != nil { t.Fatal(err) } defer second.Close() ctx := context.Background() for _, ch := range []string{"CH01", "CH02"} { if _, err := first.RecordPortLog(ctx, domain.PortLogEvent{Channel: ch, EventType: "command", Command: "show version", ReturnValue: "ok", Message: "command completed", Actor: "tester"}); err != nil { t.Fatal(err) } } if rows, err := second.PortLogEvents(ctx, domain.PortLogFilter{}); err != nil || len(rows) != 2 { t.Fatalf("prime cache = %d, %v", len(rows), err) } if result, err := first.ClearPortLogs(ctx, "CH01"); err != nil || result.Deleted != 1 { t.Fatalf("clear = %+v, %v", result, err) } if rows, err := second.PortLogEvents(ctx, domain.PortLogFilter{}); err != nil || len(rows) != 1 || rows[0].Channel != "CH02" { t.Fatalf("stale cache after clear = %+v, %v", rows, err) } if _, err := second.RecordPortLog(ctx, domain.PortLogEvent{Channel: "CH01", EventType: "command", Command: "new command", ReturnValue: "ok", Message: "command completed", Actor: "tester"}); err != nil { t.Fatal(err) } if rows, err := first.PortLogEvents(ctx, domain.PortLogFilter{}); err != nil || len(rows) != 2 { t.Fatalf("post-clear capture = %+v, %v", rows, err) } } func TestPreLogClearAdministratorStoreMigratesWithoutInvalidatingAccounts(t *testing.T) { options := StoreOptions{AuthPath: filepath.Join(t.TempDir(), "auth.json")} first, err := NewStoreWithOptions(fixedClock, options) if err != nil { t.Fatal(err) } defer first.Close() admin := first.authUsers["admin"] admin.Permissions = preLogClearAdministratorPermissions() first.authUsers["admin"] = admin if err := first.persistAuthStoreLocked(); err != nil { t.Fatal(err) } second, err := NewStoreWithOptions(fixedClock, options) if err != nil { t.Fatalf("previous admin store would fail to start: %v", err) } defer second.Close() if !matchesPermissions(second.authUsers["admin"].Permissions, permissionsForRole("administrator")) { t.Fatal("administrator clear permission not migrated") } }