package broker import ( "testing" "time" "github.com/nats-io/nats.go" "github.com/novox/mesh-controller/internal/testbus" ) // **DEAD_LETTERS and EVENTS take a message's own time to live once updated in place** (novox/hq ADR 0376 §3, §5), // on the pinned server: each made as it was before, without one, is brought to its definition by the controller's // assertion, keeps what it held, and removes a message once its time to live passes. A restricted module stream says // so in its metadata; one without a grant does not. // // go test ./internal/broker/ -run TestTheStreamsTakeAMessagesTimeToLive func TestTheStreamsTakeAMessagesTimeToLive(t *testing.T) { js, err := Dial(testbus.URL(t)) if err != nil { t.Fatal(err) } defer js.Close() for _, s := range MeshStreams() { if s.Name != EventsStream && s.Name != DeadLettersStream { if s.AllowMsgTTL { t.Errorf("%s takes a time to live of a message's own, which nothing asks of it", s.Name) } continue } if !s.AllowMsgTTL { t.Fatalf("%s is not defined to take a message's time to live", s.Name) } _ = js.js.DeleteStream(s.Name) before := s before.AllowMsgTTL = false if err := js.EnsureStream(before); err != nil { t.Fatalf("%s as it was: %v", s.Name, err) } subject := DeadLetterSubject("EVENTS", "ace_reader") if s.Name == EventsStream { subject = "mesh.mod.gitea.event.pull.merged" } if _, err := js.js.Publish(subject, []byte("held")); err != nil { t.Fatal(err) } if err := js.EnsureStream(s); err != nil { t.Fatalf("%s updated in place: %v", s.Name, err) } info, err := js.js.StreamInfo(s.Name) if err != nil || !info.Config.AllowMsgTTL || info.State.Msgs != 1 { t.Fatalf("%s after the update: %+v (%v)", s.Name, info, err) } msg := &nats.Msg{Subject: subject, Data: []byte("brief"), Header: nats.Header{}} msg.Header.Set(nats.MsgTTLHdr, "1s") ack, err := js.js.PublishMsg(msg) if err != nil { t.Fatalf("%s refused a message's time to live: %v", s.Name, err) } deadline := time.Now().Add(8 * time.Second) for { if _, err := js.js.GetMsg(s.Name, ack.Sequence); err != nil { break } if time.Now().After(deadline) { t.Fatalf("%s still holds a message past its time to live", s.Name) } time.Sleep(200 * time.Millisecond) } if info, _ := js.js.StreamInfo(s.Name); info.State.Msgs != 1 { t.Fatalf("%s holds %d, want only the message without an age", s.Name, info.State.Msgs) } _ = js.js.PurgeStream(s.Name) } if !mailStream.Stream().Restricted || newsStream.Stream().Restricted { t.Fatal("a module stream does not say whether it is restricted") } _ = js.js.DeleteStream("MAIL") if err := js.EnsureStream(mailStream.Stream()); err != nil { t.Fatal(err) } defer func() { _ = js.js.DeleteStream("MAIL") }() if info, _ := js.js.StreamInfo("MAIL"); info.Config.Metadata[RestrictedMetadata] != "true" { t.Fatalf("MAIL's metadata: %v", info.Config.Metadata) } }