Main reverted G's half merge (#189, reverted by8afc3ebin #191) and then took the reader release's S1-S5, which copied G's code. G's form holds where they differ (process_bus.go, seats.go, state.go and their tests); the release's kept names stay so main's callers keep building: SeatViewPrefix beside SeatReadPrefix, and QueueInvoke's empty strings on not-ok (with its test TestQueueInvoke). The tree differs from G's headf30dee54only by those and the release's two tests (objects cap option, seat states and stream kinds). Builds: design 47 G (the milestone's sdk part, as atf30dee54) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
64 lines
2.0 KiB
Go
64 lines
2.0 KiB
Go
//go:build integration
|
|
|
|
package bussnap_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/bussnap"
|
|
"git.novox.be/novox/mesh-sdk/go/testbus"
|
|
|
|
"github.com/nats-io/nats.go"
|
|
)
|
|
|
|
// TestOneStreamIsTakenRemovedAndRestored: the take and restore of one stream is mesh-sdk's (design 47 G §655, A-125):
|
|
// a stream's snapshot taken with Into, the stream deleted, and RestoreFile puts it back under its own name with its
|
|
// messages; a second restore over the live name is refused by the server.
|
|
func TestOneStreamIsTakenRemovedAndRestored(t *testing.T) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
nc, err := nats.Connect(testbus.URL(t))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer nc.Close()
|
|
js, err := nc.JetStream()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := js.AddStream(&nats.StreamConfig{Name: "KEPT_one", Subjects: []string{"kept.one.>"}}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, m := range []string{"a", "b", "c"} {
|
|
if _, err := js.Publish("kept.one."+m, []byte(m)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
file, err := bussnap.Into(nc, t.TempDir())(ctx, []string{"KEPT_one"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
m, err := bussnap.ManifestOf(file)
|
|
if err != nil || len(m.Streams) != 1 || m.Streams[0].Name != "KEPT_one" {
|
|
t.Fatalf("the manifest says %+v, %v; want the one stream KEPT_one", m, err)
|
|
}
|
|
if err := bussnap.DeleteStream(ctx, nc, "KEPT_one"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if live, err := bussnap.Live(ctx, nc, "KEPT_one"); err != nil || live {
|
|
t.Fatalf("live after its deletion: %v, %v", live, err)
|
|
}
|
|
if err := bussnap.RestoreFile(ctx, nc, file, t.TempDir(), t.Logf); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
info, err := js.StreamInfo("KEPT_one")
|
|
if err != nil || info.State.Msgs != 3 || info.State.LastSeq != 3 {
|
|
t.Fatalf("restored as %+v, %v; want 3 messages up to sequence 3", info, err)
|
|
}
|
|
if err := bussnap.RestoreFile(ctx, nc, file, t.TempDir(), t.Logf); err == nil {
|
|
t.Fatal("a restore over the live name was taken")
|
|
}
|
|
}
|