blob: 8379fd3628215136122e7d093fc57f52c0a2ccb3 [file] [log] [blame]
// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0
package logtree
import (
"fmt"
"strings"
"testing"
)
func TestJournalStartPosition(t *testing.T) {
lt := New()
for i := 0; i < 100; i += 1 {
e := &entry{
origin: "main",
leveled: testPayload(fmt.Sprintf("test %d", i)),
}
lt.journal.append(e)
}
type tCase struct {
name string
count int
direction ReadDirection
pos int
expectedCount int
expectedFirst string
expectedLast string
}
for _, tc := range []tCase{
{
name: "fetch all before id 0",
count: BacklogAllAvailable,
direction: ReadDirectionBefore,
pos: 0,
expectedCount: 0,
expectedFirst: "UNREACHABLE",
expectedLast: "UNREACHABLE",
},
{
name: "fetch all after id 0",
count: BacklogAllAvailable,
direction: ReadDirectionAfter,
pos: 0,
expectedCount: 100,
expectedFirst: "test 0",
expectedLast: "test 99",
},
{
name: "fetch all before id 10",
count: BacklogAllAvailable,
direction: ReadDirectionBefore,
pos: 10,
expectedCount: 10,
expectedFirst: "test 0",
expectedLast: "test 9",
},
{
name: "fetch all after id 10",
count: BacklogAllAvailable,
direction: ReadDirectionAfter,
pos: 10,
expectedCount: 90,
expectedFirst: "test 10",
expectedLast: "test 99",
},
{
name: "fetch 10 before id 0",
count: 10,
direction: ReadDirectionBefore,
pos: 0,
expectedCount: 0,
expectedFirst: "UNREACHABLE",
expectedLast: "UNREACHABLE",
},
{
name: "fetch 10 after id 0",
count: 10,
direction: ReadDirectionAfter,
pos: 0,
expectedCount: 10,
expectedFirst: "test 0",
expectedLast: "test 9",
},
{
name: "fetch 10 before id 3",
count: 10,
direction: ReadDirectionBefore,
pos: 3,
expectedCount: 3,
expectedFirst: "test 0",
expectedLast: "test 2",
},
{
name: "fetch 10 after id 3",
count: 10,
direction: ReadDirectionAfter,
pos: 3,
expectedCount: 10,
expectedFirst: "test 3",
expectedLast: "test 12",
},
{
name: "fetch 43 before id 47",
count: 43,
direction: ReadDirectionBefore,
pos: 47,
expectedCount: 43,
expectedFirst: "test 4",
expectedLast: "test 46",
},
} {
t.Run(tc.name, func(t *testing.T) {
lr, _ := lt.Read("main",
WithBacklog(tc.count),
WithStartPosition(tc.pos, tc.direction),
)
if l := len(lr.Backlog); l != tc.expectedCount {
t.Fatalf("expected %d entries, got %d", tc.expectedCount, l)
}
if len(lr.Backlog) == 0 {
// If there is nothing to test against, skip to next test.
return
}
if first := strings.Join(lr.Backlog[0].Leveled.messages, "\n"); first != tc.expectedFirst {
t.Errorf("wanted first entry %q, got %q", tc.expectedFirst, first)
}
if last := strings.Join(lr.Backlog[len(lr.Backlog)-1].Leveled.messages, "\n"); last != tc.expectedLast {
t.Errorf("wanted last entry %q, got %q", tc.expectedLast, last)
}
for i, entry := range lr.Backlog {
// If we skip messages and are reading oldest first, adapt the
// id to the expected position
if tc.pos != 0 && tc.direction == ReadDirectionAfter {
i = tc.pos + i
}
if tc.count != BacklogAllAvailable && tc.pos != 0 && tc.direction == ReadDirectionBefore {
// Limit the negative offset to 0
i = max(0, tc.pos-tc.count) + i
}
want := fmt.Sprintf("test %d", i)
got := strings.Join(entry.Leveled.messages, "\n")
if want != got {
t.Errorf("wanted entry %q, got %q", want, got)
}
}
})
}
}