package logstorage import ( "os" "testing" "time" ) func TestClearAllPortsAndLinksRemainDeletedAfterRestart(t *testing.T) { root := t.TempDir() s := openTestStore(t, Options{Root: root}) now := time.Now() for _, channel := range []string{"CH01", "CH48"} { if _, err := s.Append(ClassPort, now, map[string]string{"channel": channel}); err != nil { t.Fatal(err) } } for _, class := range []string{ClassAudit, ClassSystem, ClassLink} { if _, err := s.Append(class, now, map[string]string{"message": "old"}); err != nil { t.Fatal(err) } } oldLinks, err := os.ReadFile(s.activePath(ClassLink)) if err != nil { t.Fatal(err) } if n, err := s.ClearPort("ALL"); err != nil || n != 2 { t.Fatalf("all ports: %d %v", n, err) } if rows, err := s.Read(ClassLink); err != nil || len(rows) != 1 { t.Fatalf("link deleted by port clear: %v %v", rows, err) } if n, err := s.ClearLink(); err != nil || n != 1 { t.Fatalf("links: %d %v", n, err) } // Simulate a crash after the checkpoint committed but before segment compaction. if err := os.WriteFile(s.activePath(ClassLink), oldLinks, 0600); err != nil { t.Fatal(err) } s = openTestStore(t, Options{Root: root}) for _, class := range []string{ClassPort, ClassLink} { if rows, err := s.Read(class); err != nil || len(rows) != 0 { t.Fatalf("resurrected %s: %v %v", class, rows, err) } } for _, class := range []string{ClassSystem, ClassAudit} { if rows, err := s.Read(class); err != nil || len(rows) != 1 { t.Fatalf("lost %s: %v %v", class, rows, err) } } event, err := s.Append(ClassLink, now, map[string]string{"message": "new"}) if err != nil || event.Sequence != 2 { t.Fatalf("link sequence: %+v %v", event, err) } event, err = s.Append(ClassPort, now, map[string]string{"channel": "CH48"}) if err != nil || event.Sequence != 3 { t.Fatalf("port sequence: %+v %v", event, err) } if rows, err := s.Read(ClassLink); err != nil || len(rows) != 1 { t.Fatalf("new link missing: %v %v", rows, err) } }