miniredis/stream_test.go
Harmen cbe380f58d
xreadgroup block (#210)
support "block" and "noack" in "xreadgroup"
2021-05-19 14:33:58 +02:00

175 lines
4.1 KiB
Go

package miniredis
import (
"testing"
"time"
)
func TestStreamID(t *testing.T) {
test := func(a, b string, want int) {
if have := streamCmp(a, b); have != want {
t.Errorf("cmp(%q, %q) have %d, want %d", a, b, have, want)
}
}
test("1-1", "2-1", -1)
test("1-1", "1-1", 0)
test("1-1", "0-1", 1)
test("1-1", "1-2", -1)
test("1-1", "1-1", 0)
test("1-1", "1-0", 1)
}
func TestFormatStreamID(t *testing.T) {
if have, _ := formatStreamID("1-1"); have != "1-1" {
t.Errorf("have %q, want %q", have, "1-1")
}
if have, _ := formatStreamID("1"); have != "1-0" {
t.Errorf("have %q, want %q", have, "1-0")
}
if have, _ := formatStreamID("1-002"); have != "1-2" {
t.Errorf("have %q, want %q", have, "1-2")
}
if _, err := formatStreamID("1-foo"); err != errInvalidEntryID {
t.Errorf("have %s, want %s", err, errInvalidEntryID)
}
if _, err := formatStreamID("foo"); err != errInvalidEntryID {
t.Errorf("have %s, want %s", err, errInvalidEntryID)
}
}
func TestStreamKey(t *testing.T) {
now := time.Now()
t.Run("add", func(t *testing.T) {
s := newStreamKey()
id, err := s.add("123-123", []string{"k", "v"}, now)
ok(t, err)
equalStr(t, "123-123", id)
equals(t, 1, len(s.entries))
})
t.Run("after", func(t *testing.T) {
s := newStreamKey()
s.add("123-123", []string{"k", "v"}, now)
s.add("123-128", []string{"k", "v"}, now)
s.add("123-129", []string{"k", "v"}, now)
equals(t, 3, len(s.after("0")))
equals(t, 3, len(s.after("123-122")))
equals(t, 2, len(s.after("123-123")))
equals(t, 2, len(s.after("123-124")))
equals(t, 1, len(s.after("123-128")))
equals(t, 0, len(s.after("123-129")))
equals(t, 0, len(s.after("999-999")))
})
t.Run("get", func(t *testing.T) {
s := newStreamKey()
s.add("123-123", []string{"k", "v"}, now)
s.add("123-128", []string{"k", "w"}, now)
s.add("123-129", []string{"k", "y"}, now)
i, entry := s.get("0")
equals(t, 0, i)
equals(t, (*StreamEntry)(nil), entry)
i, entry = s.get("123-123")
equals(t, 0, i)
equalStr(t, "123-123", entry.ID)
i, entry = s.get("123-124")
equals(t, 0, i)
equals(t, (*StreamEntry)(nil), entry)
i, entry = s.get("123-129")
equals(t, 2, i)
equalStr(t, "123-129", entry.ID)
i, entry = s.get("999-999")
equals(t, 0, i)
equals(t, (*StreamEntry)(nil), entry)
})
t.Run("delete", func(t *testing.T) {
s := newStreamKey()
s.add("123-123", []string{"k", "v"}, now)
s.add("123-124", []string{"k", "v"}, now)
s.add("123-125", []string{"k", "v"}, now)
equals(t, 3, len(s.entries))
n, err := s.delete([]string{"123-124"})
ok(t, err)
equals(t, 1, n)
equals(t, 2, len(s.entries))
n, err = s.delete([]string{"9-9"})
ok(t, err)
equals(t, 0, n)
n, err = s.delete([]string{"999-999"})
ok(t, err)
equals(t, 0, n)
equals(t, 2, len(s.entries))
})
}
func TestStreamKeyGroup(t *testing.T) {
now := time.Now()
s := newStreamKey()
_, err := s.add("123-123", []string{"k", "v"}, now)
ok(t, err)
ok(t, s.createGroup("mygroup", "$"))
g := s.groups["mygroup"]
{
s.add("999-1", []string{"k", "v"}, now)
ls := g.readGroup(now, "consumer1", ">", 999, false)
equals(t, 1, len(ls))
}
{
s.add("999-2", []string{"k", "v"}, now)
s.add("999-3", []string{"k", "v"}, now)
ls := g.readGroup(now, "consumer1", ">", 1, false)
equals(t, 1, len(ls))
equalStr(t, "999-2", ls[0].ID)
}
// re-read unacked messages
{
ls := g.readGroup(now, "consumer1", "0-0", 999, false)
equals(t, 2, len(ls))
equalStr(t, "999-1", ls[0].ID)
equalStr(t, "999-2", ls[1].ID)
}
// ack
{
n, err := g.ack([]string{"999-2"})
ok(t, err)
equals(t, 1, n)
ls := g.readGroup(now, "consumer1", "0-0", 999, false)
equals(t, 1, len(ls))
equalStr(t, "999-1", ls[0].ID)
}
t.Run("invalid acks", func(t *testing.T) {
n, err := g.ack([]string{"99999-0"})
ok(t, err)
equals(t, 0, n)
})
t.Run("delete last ID", func(t *testing.T) {
s := newStreamKey()
s.add("123-123", []string{"k", "v"}, now)
ok(t, s.createGroup("mygroup", "$"))
g := s.groups["mygroup"]
_, err := s.delete([]string{"123-123"}) // !
ok(t, err)
ls := g.readGroup(now, "consumer1", ">", 999, false)
equals(t, 0, len(ls))
})
}