blob: 8379fd3628215136122e7d093fc57f52c0a2ccb3 [file] [log] [blame]
Tim Windelschmidt01491a72025-07-23 21:49:11 +02001// Copyright The Monogon Project Authors.
2// SPDX-License-Identifier: Apache-2.0
3
4package logtree
5
6import (
7 "fmt"
8 "strings"
9 "testing"
10)
11
12func TestJournalStartPosition(t *testing.T) {
13 lt := New()
14
15 for i := 0; i < 100; i += 1 {
16 e := &entry{
17 origin: "main",
18 leveled: testPayload(fmt.Sprintf("test %d", i)),
19 }
20 lt.journal.append(e)
21 }
22
23 type tCase struct {
24 name string
25
26 count int
27 direction ReadDirection
28 pos int
29
30 expectedCount int
31 expectedFirst string
32 expectedLast string
33 }
34
35 for _, tc := range []tCase{
36 {
37 name: "fetch all before id 0",
38 count: BacklogAllAvailable,
39 direction: ReadDirectionBefore,
40 pos: 0,
41
42 expectedCount: 0,
43 expectedFirst: "UNREACHABLE",
44 expectedLast: "UNREACHABLE",
45 },
46 {
47 name: "fetch all after id 0",
48 count: BacklogAllAvailable,
49 direction: ReadDirectionAfter,
50 pos: 0,
51
52 expectedCount: 100,
53 expectedFirst: "test 0",
54 expectedLast: "test 99",
55 },
56
57 {
58 name: "fetch all before id 10",
59 count: BacklogAllAvailable,
60 direction: ReadDirectionBefore,
61 pos: 10,
62
63 expectedCount: 10,
64 expectedFirst: "test 0",
65 expectedLast: "test 9",
66 },
67 {
68 name: "fetch all after id 10",
69 count: BacklogAllAvailable,
70 direction: ReadDirectionAfter,
71 pos: 10,
72
73 expectedCount: 90,
74 expectedFirst: "test 10",
75 expectedLast: "test 99",
76 },
77
78 {
79 name: "fetch 10 before id 0",
80 count: 10,
81 direction: ReadDirectionBefore,
82 pos: 0,
83
84 expectedCount: 0,
85 expectedFirst: "UNREACHABLE",
86 expectedLast: "UNREACHABLE",
87 },
88 {
89 name: "fetch 10 after id 0",
90 count: 10,
91 direction: ReadDirectionAfter,
92 pos: 0,
93
94 expectedCount: 10,
95 expectedFirst: "test 0",
96 expectedLast: "test 9",
97 },
98
99 {
100 name: "fetch 10 before id 3",
101 count: 10,
102 direction: ReadDirectionBefore,
103 pos: 3,
104
105 expectedCount: 3,
106 expectedFirst: "test 0",
107 expectedLast: "test 2",
108 },
109 {
110 name: "fetch 10 after id 3",
111 count: 10,
112 direction: ReadDirectionAfter,
113 pos: 3,
114
115 expectedCount: 10,
116 expectedFirst: "test 3",
117 expectedLast: "test 12",
118 },
119 {
120 name: "fetch 43 before id 47",
121 count: 43,
122 direction: ReadDirectionBefore,
123 pos: 47,
124
125 expectedCount: 43,
126 expectedFirst: "test 4",
127 expectedLast: "test 46",
128 },
129 } {
130 t.Run(tc.name, func(t *testing.T) {
131 lr, _ := lt.Read("main",
132 WithBacklog(tc.count),
133 WithStartPosition(tc.pos, tc.direction),
134 )
135 if l := len(lr.Backlog); l != tc.expectedCount {
136 t.Fatalf("expected %d entries, got %d", tc.expectedCount, l)
137 }
138 if len(lr.Backlog) == 0 {
139 // If there is nothing to test against, skip to next test.
140 return
141 }
142 if first := strings.Join(lr.Backlog[0].Leveled.messages, "\n"); first != tc.expectedFirst {
143 t.Errorf("wanted first entry %q, got %q", tc.expectedFirst, first)
144 }
145 if last := strings.Join(lr.Backlog[len(lr.Backlog)-1].Leveled.messages, "\n"); last != tc.expectedLast {
146 t.Errorf("wanted last entry %q, got %q", tc.expectedLast, last)
147 }
148 for i, entry := range lr.Backlog {
149 // If we skip messages and are reading oldest first, adapt the
150 // id to the expected position
151 if tc.pos != 0 && tc.direction == ReadDirectionAfter {
152 i = tc.pos + i
153 }
154 if tc.count != BacklogAllAvailable && tc.pos != 0 && tc.direction == ReadDirectionBefore {
155 // Limit the negative offset to 0
156 i = max(0, tc.pos-tc.count) + i
157 }
158 want := fmt.Sprintf("test %d", i)
159 got := strings.Join(entry.Leveled.messages, "\n")
160 if want != got {
161 t.Errorf("wanted entry %q, got %q", want, got)
162 }
163 }
164 })
165 }
166}