package contract import ( "errors" "strings" "testing" "time" ) func validVisit() Visit { return Visit{EventID: "evt-1", OccurredAt: time.Now(), CameraID: "entrance"} } func TestTopicMustCarryClientAndSite(t *testing.T) { got, err := ParseTopic("bv/acme.store1/visit") if err != nil { t.Fatal(err) } if got.Client != "acme" || got.Site != "store1" || got.Kind != "visit" { t.Fatalf("%+v", got) } if got.Username != "acme.store1" { t.Fatalf("username %q must match what the broker authenticated", got.Username) } } func TestTopicWithExtraDotsIsRejected(t *testing.T) { // Splitting on the FIRST dot would read "acme.store.1" as client "acme", // site "store.1" - a different site than the broker authenticated, and a // way to write rows against a tenant you do not own. for _, topic := range []string{ "bv/acme.store.1/visit", "bv/acme/visit", "bv/.store1/visit", "bv/acme./visit", "other/acme.store1/visit", "bv/acme.store1", } { if _, err := ParseTopic(topic); err == nil { t.Errorf("%q was accepted", topic) } } } func TestCommandSubtopicSurvivesParsing(t *testing.T) { got, err := ParseTopic("bv/acme.store1/cmd/reload/now") if err != nil { t.Fatal(err) } if got.Kind != "cmd" || got.Rest != "reload/now" { t.Fatalf("%+v", got) } } func TestEventIDIsRequired(t *testing.T) { // It is the idempotency key. Without it an at-least-once redelivery // silently doubles a store's footfall - the one number they pay for. v := validVisit() v.EventID = " " assertPermanent(t, v.Validate(), "event_id") } func TestAFutureTimestampIsRejectedNotClamped(t *testing.T) { // A site with a skewed clock would otherwise park a visit at the top of // every "recent" report forever. Clamping it silently makes the report a // lie that looks fine. v := validVisit() v.OccurredAt = time.Now().Add(72 * time.Hour) assertPermanent(t, v.Validate(), "clock") } func TestSlightlyFutureIsToleratedForClockSkew(t *testing.T) { v := validVisit() v.OccurredAt = time.Now().Add(30 * time.Minute) if err := v.Validate(); err != nil { t.Fatalf("ordinary clock skew rejected: %v", err) } } func TestWrongLengthEmbeddingIsRejected(t *testing.T) { // A wrong-length vector cannot be compared with anything and would sit in // the gallery poisoning every future search. v := validVisit() v.Model = "w600k_r50.onnx" v.Embedding = make([]float32, 128) assertPermanent(t, v.Validate(), "dimensions") } func TestEmbeddingWithoutAModelTagIsRejected(t *testing.T) { // Vectors from different encoders occupy different spaces. An untagged one // cannot be stored safely because nothing later can tell what it is. v := validVisit() v.Embedding = make([]float32, EmbeddingDim) assertPermanent(t, v.Validate(), "model tag") } func TestAVisitWithNoEmbeddingIsValid(t *testing.T) { // A site may be configured to keep templates local and send only counts. v := validVisit() if err := v.Validate(); err != nil { t.Fatalf("counts-only visit rejected: %v", err) } } func TestValidationFailuresArePermanentSoTheQueueDrains(t *testing.T) { // If a malformed message were retried forever, one bad payload at the head // would stop every good one behind it - the same failure the agent's spool // quarantine exists to prevent. v := Visit{} if !errors.Is(v.Validate(), ErrPermanent) { t.Fatal("a malformed visit was not marked permanent") } } func assertPermanent(t *testing.T, err error, want string) { t.Helper() if err == nil { t.Fatalf("expected an error mentioning %q", want) } if !errors.Is(err, ErrPermanent) { t.Fatalf("error is not permanent: %v", err) } if !strings.Contains(err.Error(), want) { t.Fatalf("error %q does not mention %q", err, want) } }