Skip to content
quarry Artifact [512496932c]
Login

Artifact [512496932c]

Artifact 512496932cd741f56bc04724143d59012240af42fbe8b649ade3545d966a4c40:


package events

import (
	"bytes"
	"testing"
	"time"

	"github.com/nats-io/nats.go"
)

// A parsed sqlite baseline manifest is well over NATS's 1MB default
// payload cap; the embedded server must accept multi-megabyte events or
// large stores fail ingest at startup.
func TestLargeArtifactPayload(t *testing.T) {
	ev, err := Start(t.TempDir())
	if err != nil {
		t.Fatal(err)
	}
	defer ev.Close()
	big := bytes.Repeat([]byte("F src/very/long/path.c abcdef\n"), 100_000) // ~3MB
	if _, err := ev.JS().Publish("zit.evt.big.artifact", big); err != nil {
		t.Fatalf("publish %d bytes: %v", len(big), err)
	}
}

// Acked events must leave the stream — its disk footprint is the
// in-flight backlog, never the store's history (ticket 151: 5.6GB of
// stream beside a 218MB store).
func TestAckedEventsAreDropped(t *testing.T) {
	ev, err := Start(t.TempDir())
	if err != nil {
		t.Fatal(err)
	}
	defer ev.Close()
	for i := 0; i < 10; i++ {
		if _, err := ev.JS().Publish("zit.evt.wq.artifact", []byte("e")); err != nil {
			t.Fatal(err)
		}
	}
	sub, err := ev.JS().PullSubscribe("zit.evt.wq.>", "indexer-wq")
	if err != nil {
		t.Fatal(err)
	}
	msgs, err := sub.Fetch(10, nats.MaxWait(2*time.Second))
	if err != nil {
		t.Fatal(err)
	}
	for _, m := range msgs {
		if err := m.AckSync(); err != nil {
			t.Fatal(err)
		}
	}
	info, err := ev.JS().StreamInfo(StreamName)
	if err != nil {
		t.Fatal(err)
	}
	if info.State.Msgs != 0 {
		t.Fatalf("stream retains %d acked events", info.State.Msgs)
	}
}

// An existing stream with the old limits retention is dropped and
// recreated on Start; the cursor bucket goes with it so the census
// republishes rather than silently skipping the deleted backlog.
func TestRetentionMigration(t *testing.T) {
	dir := t.TempDir()
	ev, err := Start(dir)
	if err != nil {
		t.Fatal(err)
	}
	// Simulate the pre-151 layout: recreate the stream with limits
	// retention and a stale cursor.
	if err := ev.JS().DeleteStream(StreamName); err != nil {
		t.Fatal(err)
	}
	if _, err := ev.JS().AddStream(&nats.StreamConfig{
		Name: StreamName, Subjects: []string{"zit.evt.>"},
	}); err != nil {
		t.Fatal(err)
	}
	kv, err := ev.Cursors()
	if err != nil {
		t.Fatal(err)
	}
	if _, err := kv.Put("somerepo", []byte(`{"tail":123}`)); err != nil {
		t.Fatal(err)
	}
	ev.Close()

	ev2, err := Start(dir)
	if err != nil {
		t.Fatal(err)
	}
	defer ev2.Close()
	info, err := ev2.JS().StreamInfo(StreamName)
	if err != nil {
		t.Fatal(err)
	}
	if info.Config.Retention != nats.WorkQueuePolicy {
		t.Fatalf("retention not migrated: %v", info.Config.Retention)
	}
	kv2, err := ev2.Cursors()
	if err != nil {
		t.Fatal(err)
	}
	if _, err := kv2.Get("somerepo"); err == nil {
		t.Fatal("stale cursor survived the stream migration")
	}
}