Skip to content

Commit 07c3c76

Browse files
chore: Improve test coverage of WAL Manager (#13498)
1 parent b92b07d commit 07c3c76

File tree

1 file changed

+167
-84
lines changed

1 file changed

+167
-84
lines changed

pkg/storage/wal/manager_test.go

+167-84
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,15 @@ import (
1616

1717
func TestManager_Append(t *testing.T) {
1818
m, err := NewManager(Config{
19+
MaxAge: 30 * time.Second,
1920
MaxSegments: 1,
2021
MaxSegmentSize: 1024, // 1KB
2122
}, NewMetrics(nil))
2223
require.NoError(t, err)
2324

2425
// Append some data.
25-
lbs := labels.Labels{{
26-
Name: "foo",
27-
Value: "bar",
28-
}}
29-
entries := []*logproto.Entry{{
30-
Timestamp: time.Now(),
31-
Line: strings.Repeat("a", 1024),
32-
}}
26+
lbs := labels.Labels{{Name: "a", Value: "b"}}
27+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("c", 1024)}}
3328
res, err := m.Append(AppendRequest{
3429
TenantID: "1",
3530
Labels: lbs,
@@ -46,28 +41,30 @@ func TestManager_Append(t *testing.T) {
4641
default:
4742
}
4843

49-
// Flush the data and broadcast that the flush is successful.
50-
it := m.NextPending()
51-
require.NotNil(t, it)
52-
it.Result.SetDone(nil)
44+
// Pretend to flush the data.
45+
res.SetDone(nil)
5346

54-
// Should be able to read from the Done() as it is closed.
47+
// Should be able to read from Done() as it is closed.
5548
select {
5649
case <-res.Done():
5750
default:
5851
t.Fatal("expected closed Done()")
5952
}
6053
require.NoError(t, res.Err())
54+
}
6155

62-
// Return the segment to be written to again.
63-
m.Put(it)
56+
func TestManager_AppendFailed(t *testing.T) {
57+
m, err := NewManager(Config{
58+
MaxAge: 30 * time.Second,
59+
MaxSegments: 1,
60+
MaxSegmentSize: 1024, // 1KB
61+
}, NewMetrics(nil))
62+
require.NoError(t, err)
6463

65-
// Append some more data.
66-
entries = []*logproto.Entry{{
67-
Timestamp: time.Now(),
68-
Line: strings.Repeat("b", 1024),
69-
}}
70-
res, err = m.Append(AppendRequest{
64+
// Append some data.
65+
lbs := labels.Labels{{Name: "a", Value: "b"}}
66+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("c", 1024)}}
67+
res, err := m.Append(AppendRequest{
7168
TenantID: "1",
7269
Labels: lbs,
7370
LabelsStr: lbs.String(),
@@ -76,12 +73,11 @@ func TestManager_Append(t *testing.T) {
7673
require.NoError(t, err)
7774
require.NotNil(t, res)
7875

79-
// Flush the data, but this time broadcast an error that the flush failed.
80-
it = m.NextPending()
81-
require.NotNil(t, it)
82-
it.Result.SetDone(errors.New("failed to flush"))
76+
// Pretend that the flush failed.
77+
res.SetDone(errors.New("failed to flush"))
8378

84-
// Should be able to read from the Done() as it is closed.
79+
// Should be able to read from the Done() as it is closed and assert
80+
// that the error is the expected error.
8581
select {
8682
case <-res.Done():
8783
default:
@@ -90,25 +86,103 @@ func TestManager_Append(t *testing.T) {
9086
require.EqualError(t, res.Err(), "failed to flush")
9187
}
9288

93-
// This test asserts that Append operations return ErrFull if all segments
94-
// are full and waiting to be flushed.
95-
func TestManager_Append_ErrFull(t *testing.T) {
89+
func TestManager_AppendMaxAge(t *testing.T) {
9690
m, err := NewManager(Config{
91+
MaxAge: 100 * time.Millisecond,
92+
MaxSegments: 1,
93+
MaxSegmentSize: 8 * 1024 * 1024, // 8MB
94+
}, NewMetrics(nil))
95+
require.NoError(t, err)
96+
97+
// Append 1B of data.
98+
lbs := labels.Labels{{Name: "a", Value: "b"}}
99+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: "c"}}
100+
res, err := m.Append(AppendRequest{
101+
TenantID: "1",
102+
Labels: lbs,
103+
LabelsStr: lbs.String(),
104+
Entries: entries,
105+
})
106+
require.NoError(t, err)
107+
require.NotNil(t, res)
108+
109+
// The segment that was just appended to has neither reached the maximum
110+
// age nor maximum size to be flushed.
111+
require.Equal(t, 1, m.available.Len())
112+
require.Equal(t, 0, m.pending.Len())
113+
114+
// Wait 100ms and append some more data.
115+
time.Sleep(100 * time.Millisecond)
116+
entries = []*logproto.Entry{{Timestamp: time.Now(), Line: "c"}}
117+
res, err = m.Append(AppendRequest{
118+
TenantID: "1",
119+
Labels: lbs,
120+
LabelsStr: lbs.String(),
121+
Entries: entries,
122+
})
123+
require.NoError(t, err)
124+
require.NotNil(t, res)
125+
126+
// The segment has reached the maximum age and should have been moved to
127+
// pending list to be flushed.
128+
require.Equal(t, 0, m.available.Len())
129+
require.Equal(t, 1, m.pending.Len())
130+
}
131+
132+
func TestManager_AppendMaxSize(t *testing.T) {
133+
m, err := NewManager(Config{
134+
MaxAge: 30 * time.Second,
135+
MaxSegments: 1,
136+
MaxSegmentSize: 1024, // 1KB
137+
}, NewMetrics(nil))
138+
require.NoError(t, err)
139+
140+
// Append 512B of data.
141+
lbs := labels.Labels{{Name: "a", Value: "b"}}
142+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("c", 512)}}
143+
res, err := m.Append(AppendRequest{
144+
TenantID: "1",
145+
Labels: lbs,
146+
LabelsStr: lbs.String(),
147+
Entries: entries,
148+
})
149+
require.NoError(t, err)
150+
require.NotNil(t, res)
151+
152+
// The segment that was just appended to has neither reached the maximum
153+
// age nor maximum size to be flushed.
154+
require.Equal(t, 1, m.available.Len())
155+
require.Equal(t, 0, m.pending.Len())
156+
157+
// Append another 512B of data.
158+
entries = []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("c", 512)}}
159+
res, err = m.Append(AppendRequest{
160+
TenantID: "1",
161+
Labels: lbs,
162+
LabelsStr: lbs.String(),
163+
Entries: entries,
164+
})
165+
require.NoError(t, err)
166+
require.NotNil(t, res)
167+
168+
// The segment has reached the maximum size and should have been moved to
169+
// pending list to be flushed.
170+
require.Equal(t, 0, m.available.Len())
171+
require.Equal(t, 1, m.pending.Len())
172+
}
173+
174+
func TestManager_AppendWALFull(t *testing.T) {
175+
m, err := NewManager(Config{
176+
MaxAge: 30 * time.Second,
97177
MaxSegments: 10,
98178
MaxSegmentSize: 1024, // 1KB
99179
}, NewMetrics(nil))
100180
require.NoError(t, err)
101181

102-
// Should be able to write to all 10 segments of 1KB each.
103-
lbs := labels.Labels{{
104-
Name: "foo",
105-
Value: "bar",
106-
}}
182+
// Should be able to write 100KB of data, 10KB per segment.
183+
lbs := labels.Labels{{Name: "a", Value: "b"}}
107184
for i := 0; i < 10; i++ {
108-
entries := []*logproto.Entry{{
109-
Timestamp: time.Now(),
110-
Line: strings.Repeat("a", 1024),
111-
}}
185+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("c", 1024)}}
112186
res, err := m.Append(AppendRequest{
113187
TenantID: "1",
114188
Labels: lbs,
@@ -119,12 +193,9 @@ func TestManager_Append_ErrFull(t *testing.T) {
119193
require.NotNil(t, res)
120194
}
121195

122-
// Append more data should fail as all segments are full and waiting to be
123-
// flushed.
124-
entries := []*logproto.Entry{{
125-
Timestamp: time.Now(),
126-
Line: strings.Repeat("b", 1024),
127-
}}
196+
// However, appending more data should fail as all segments are full and
197+
// waiting to be flushed.
198+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("c", 1024)}}
128199
res, err := m.Append(AppendRequest{
129200
TenantID: "1",
130201
Labels: lbs,
@@ -137,76 +208,88 @@ func TestManager_Append_ErrFull(t *testing.T) {
137208

138209
func TestManager_NextPending(t *testing.T) {
139210
m, err := NewManager(Config{
140-
MaxAge: DefaultMaxAge,
211+
MaxAge: 30 * time.Second,
141212
MaxSegments: 1,
142213
MaxSegmentSize: 1024, // 1KB
143214
}, NewMetrics(nil))
144215
require.NoError(t, err)
145216

146-
// There should be no items as no data has been written.
217+
// There should be no segments waiting to be flushed as no data has been
218+
// written.
147219
it := m.NextPending()
148220
require.Nil(t, it)
149221

150-
// Append 512B of data. There should still be no items to as the segment is
151-
// not full (1KB).
152-
lbs := labels.Labels{{
153-
Name: "foo",
154-
Value: "bar",
155-
}}
156-
entries := []*logproto.Entry{{
157-
Timestamp: time.Now(),
158-
Line: strings.Repeat("b", 512),
159-
}}
222+
// Append 1KB of data.
223+
lbs := labels.Labels{{Name: "a", Value: "b"}}
224+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("c", 1024)}}
160225
_, err = m.Append(AppendRequest{
161226
TenantID: "1",
162227
Labels: lbs,
163228
LabelsStr: lbs.String(),
164229
Entries: entries,
165230
})
166231
require.NoError(t, err)
232+
233+
// There should be a segment waiting to be flushed.
234+
it = m.NextPending()
235+
require.NotNil(t, it)
236+
237+
// There should be no more segments waiting to be flushed.
167238
it = m.NextPending()
168239
require.Nil(t, it)
240+
}
169241

170-
// Write another 512B of data. There should be an item waiting to be flushed.
171-
entries = []*logproto.Entry{{
172-
Timestamp: time.Now(),
173-
Line: strings.Repeat("b", 512),
174-
}}
175-
_, err = m.Append(AppendRequest{
242+
func TestManager_NexPendingMaxAge(t *testing.T) {
243+
m, err := NewManager(Config{
244+
MaxAge: 100 * time.Millisecond,
245+
MaxSegments: 1,
246+
MaxSegmentSize: 1024, // 1KB
247+
}, NewMetrics(nil))
248+
require.NoError(t, err)
249+
250+
// Append 1B of data.
251+
lbs := labels.Labels{{Name: "a", Value: "b"}}
252+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: "c"}}
253+
res, err := m.Append(AppendRequest{
176254
TenantID: "1",
177255
Labels: lbs,
178256
LabelsStr: lbs.String(),
179257
Entries: entries,
180258
})
181259
require.NoError(t, err)
182-
it = m.NextPending()
183-
require.NotNil(t, it)
260+
require.NotNil(t, res)
184261

185-
// Should not get the same item more than once.
186-
it = m.NextPending()
262+
// The segment that was just appended to has neither reached the maximum
263+
// age nor maximum size to be flushed.
264+
it := m.NextPending()
187265
require.Nil(t, it)
266+
require.Equal(t, 1, m.available.Len())
267+
require.Equal(t, 0, m.pending.Len())
268+
269+
// Wait 100ms. The segment that was just appended to should have reached
270+
// the maximum age.
271+
time.Sleep(100 * time.Millisecond)
272+
it = m.NextPending()
273+
require.NotNil(t, it)
274+
require.Equal(t, 0, m.available.Len())
275+
require.Equal(t, 0, m.pending.Len())
188276
}
189277

190278
func TestManager_Put(t *testing.T) {
191279
m, err := NewManager(Config{
192-
MaxSegments: 10,
280+
MaxAge: 30 * time.Second,
281+
MaxSegments: 1,
193282
MaxSegmentSize: 1024, // 1KB
194283
}, NewMetrics(nil))
195284
require.NoError(t, err)
196285

197-
// There should be 10 available segments, and 0 pending.
198-
require.Equal(t, 10, m.available.Len())
286+
// There should be 1 available and 0 pending segments.
287+
require.Equal(t, 1, m.available.Len())
199288
require.Equal(t, 0, m.pending.Len())
200289

201290
// Append 1KB of data.
202-
lbs := labels.Labels{{
203-
Name: "foo",
204-
Value: "bar",
205-
}}
206-
entries := []*logproto.Entry{{
207-
Timestamp: time.Now(),
208-
Line: strings.Repeat("b", 1024),
209-
}}
291+
lbs := labels.Labels{{Name: "a", Value: "b"}}
292+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("c", 1024)}}
210293
_, err = m.Append(AppendRequest{
211294
TenantID: "1",
212295
Labels: lbs,
@@ -215,23 +298,23 @@ func TestManager_Put(t *testing.T) {
215298
})
216299
require.NoError(t, err)
217300

218-
// 1 segment is full, so there should now be 9 available segments,
219-
// and 1 pending segment.
220-
require.Equal(t, 9, m.available.Len())
301+
// The segment is full, so there should now be 0 available segments and 1
302+
// pending segment.
303+
require.Equal(t, 0, m.available.Len())
221304
require.Equal(t, 1, m.pending.Len())
222305

223306
// Getting the pending segment should remove it from the list.
224307
it := m.NextPending()
225308
require.NotNil(t, it)
226-
require.Equal(t, 9, m.available.Len())
309+
require.Equal(t, 0, m.available.Len())
227310
require.Equal(t, 0, m.pending.Len())
228311

229312
// The segment should contain 1KB of data.
230313
require.Equal(t, int64(1024), it.Writer.InputSize())
231314

232315
// Putting it back should add it to the available list.
233316
m.Put(it)
234-
require.Equal(t, 10, m.available.Len())
317+
require.Equal(t, 1, m.available.Len())
235318
require.Equal(t, 0, m.pending.Len())
236319

237320
// The segment should be reset.
@@ -265,8 +348,8 @@ wal_segments_pending 0
265348
require.NoError(t, testutil.CollectAndCompare(r, strings.NewReader(expected), metricNames...))
266349

267350
// Appending 1KB of data.
268-
lbs := labels.Labels{{Name: "foo", Value: "bar"}}
269-
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("b", 1024)}}
351+
lbs := labels.Labels{{Name: "a", Value: "b"}}
352+
entries := []*logproto.Entry{{Timestamp: time.Now(), Line: strings.Repeat("c", 1024)}}
270353
_, err = m.Append(AppendRequest{
271354
TenantID: "1",
272355
Labels: lbs,

0 commit comments

Comments
 (0)