@@ -26,8 +26,8 @@ import (
26
26
"github.com/prometheus/prometheus/util/testutil"
27
27
)
28
28
29
- func TestHeadReadWriter_WriteChunk_Chunk_IterateChunks (t * testing.T ) {
30
- hrw := testHeadReadWriter (t )
29
+ func TestChunkDiskMapper_WriteChunk_Chunk_IterateChunks (t * testing.T ) {
30
+ hrw := testChunkDiskMapper (t )
31
31
defer func () {
32
32
testutil .Ok (t , hrw .Close ())
33
33
}()
@@ -157,23 +157,20 @@ func TestHeadReadWriter_WriteChunk_Chunk_IterateChunks(t *testing.T) {
157
157
158
158
}
159
159
160
- // TestHeadReadWriter_Truncate tests
160
+ // TestChunkDiskMapper_Truncate tests
161
161
// * If truncation is happening properly based on the time passed.
162
162
// * The active file is not deleted even if the passed time makes it eligible to be deleted.
163
163
// * Empty current file does not lead to creation of another file after truncation.
164
164
// * Non-empty current file leads to creation of another file after truncation.
165
- func TestHeadReadWriter_Truncate (t * testing.T ) {
166
- hrw := testHeadReadWriter (t )
165
+ func TestChunkDiskMapper_Truncate (t * testing.T ) {
166
+ hrw := testChunkDiskMapper (t )
167
167
defer func () {
168
168
testutil .Ok (t , hrw .Close ())
169
169
}()
170
170
171
171
timeRange := 0
172
172
fileTimeStep := 100
173
- totalFiles := 7
174
- startIndexAfter1stTruncation , startIndexAfter2ndTruncation := 3 , 6
175
- filesDeletedAfter1stTruncation , filesDeletedAfter2ndTruncation := 2 , 5
176
- var timeToTruncate , timeToTruncateAfterRestart int64
173
+ var thirdFileMinT , sixthFileMinT int64
177
174
178
175
addChunk := func () int {
179
176
mint := timeRange + 1 // Just after the new file cut.
@@ -188,51 +185,36 @@ func TestHeadReadWriter_Truncate(t *testing.T) {
188
185
return mint
189
186
}
190
187
191
- cutFile := func (i int ) {
192
- testutil .Ok (t , hrw .CutNewFile ())
193
-
194
- mint := addChunk ()
195
-
196
- if i == startIndexAfter1stTruncation {
197
- timeToTruncate = int64 (mint )
198
- } else if i == startIndexAfter2ndTruncation {
199
- timeToTruncateAfterRestart = int64 (mint )
200
- }
201
- }
202
-
203
- // Cut segments.
204
- for i := 1 ; i <= totalFiles ; i ++ {
205
- cutFile (i )
206
- }
207
-
208
- // Verifying the files.
209
- verifyFiles := func (remainingFiles , startIndex int ) {
188
+ verifyFiles := func (remainingFiles []int ) {
210
189
t .Helper ()
211
190
212
191
files , err := ioutil .ReadDir (hrw .dir .Name ())
213
192
testutil .Ok (t , err )
214
- testutil .Equals (t , remainingFiles , len (files ), "files on disk" )
215
- testutil .Equals (t , remainingFiles , len (hrw .mmappedChunkFiles ), "hrw.mmappedChunkFiles" )
216
- testutil .Equals (t , remainingFiles , len (hrw .closers ), "closers" )
193
+ testutil .Equals (t , len ( remainingFiles ) , len (files ), "files on disk" )
194
+ testutil .Equals (t , len ( remainingFiles ) , len (hrw .mmappedChunkFiles ), "hrw.mmappedChunkFiles" )
195
+ testutil .Equals (t , len ( remainingFiles ) , len (hrw .closers ), "closers" )
217
196
218
- for i := 1 ; i <= totalFiles ; i ++ {
197
+ for _ , i := range remainingFiles {
219
198
_ , ok := hrw .mmappedChunkFiles [i ]
220
- if i < startIndex {
221
- testutil .Equals (t , false , ok )
222
- } else {
223
- testutil .Equals (t , true , ok )
224
- }
199
+ testutil .Equals (t , true , ok )
225
200
}
226
201
}
227
202
228
- // Verify the number of segments.
229
- verifyFiles (totalFiles , 1 )
203
+ // Create segments 1 to 7.
204
+ for i := 1 ; i <= 7 ; i ++ {
205
+ testutil .Ok (t , hrw .CutNewFile ())
206
+ mint := int64 (addChunk ())
207
+ if i == 3 {
208
+ thirdFileMinT = mint
209
+ } else if i == 6 {
210
+ sixthFileMinT = mint
211
+ }
212
+ }
213
+ verifyFiles ([]int {1 , 2 , 3 , 4 , 5 , 6 , 7 })
230
214
231
215
// Truncating files.
232
- testutil .Ok (t , hrw .Truncate (timeToTruncate ))
233
- totalFiles ++ // Truncation creates a new file as the last file is not empty.
234
- verifyFiles (totalFiles - filesDeletedAfter1stTruncation , startIndexAfter1stTruncation )
235
- addChunk () // Add a chunk so that new file is not truncated.
216
+ testutil .Ok (t , hrw .Truncate (thirdFileMinT ))
217
+ verifyFiles ([]int {3 , 4 , 5 , 6 , 7 , 8 })
236
218
237
219
dir := hrw .dir .Name ()
238
220
testutil .Ok (t , hrw .Close ())
@@ -246,29 +228,31 @@ func TestHeadReadWriter_Truncate(t *testing.T) {
246
228
testutil .Ok (t , hrw .IterateAllChunks (func (_ , _ uint64 , _ , _ int64 , _ uint16 ) error { return nil }))
247
229
testutil .Assert (t , hrw .fileMaxtSet , "" )
248
230
249
- // Truncating files after restart. As the last file was empty, this creates no new files.
250
- testutil .Ok (t , hrw .Truncate (timeToTruncateAfterRestart ))
251
- verifyFiles (totalFiles - filesDeletedAfter2ndTruncation , startIndexAfter2ndTruncation )
231
+ verifyFiles ([]int {3 , 4 , 5 , 6 , 7 , 8 })
232
+ // New file is created after restart even if last file was empty.
233
+ addChunk ()
234
+ verifyFiles ([]int {3 , 4 , 5 , 6 , 7 , 8 , 9 })
252
235
253
- // First chunk after restart creates a new file.
236
+ // Truncating files after restart.
237
+ testutil .Ok (t , hrw .Truncate (sixthFileMinT ))
238
+ verifyFiles ([]int {6 , 7 , 8 , 9 , 10 })
239
+
240
+ // As the last file was empty, this creates no new files.
241
+ testutil .Ok (t , hrw .Truncate (sixthFileMinT + 1 ))
242
+ verifyFiles ([]int {6 , 7 , 8 , 9 , 10 })
254
243
addChunk ()
255
- totalFiles ++
256
244
257
245
// Truncating till current time should not delete the current active file.
258
- testutil .Ok (t , hrw .Truncate (int64 (timeRange + fileTimeStep )))
259
- verifyFiles (2 , totalFiles ) // One file is the active file and one was newly created.
246
+ testutil .Ok (t , hrw .Truncate (int64 (timeRange + ( 2 * fileTimeStep ) )))
247
+ verifyFiles ([] int { 10 , 11 } ) // One file is the previously active file and one currently created.
260
248
}
261
249
262
- // TestHeadReadWriter_Truncate_NoUnsequentialFiles tests
263
- // that truncation leaves no unsequential files on disk, mainly under the following case
264
- // * There is an empty file in between the sequence while the truncation
265
- // deletes files only up to a sequence before that (i.e. stops deleting
266
- // after it has found a file that is not deletable).
267
- // This tests https://github.com/prometheus/prometheus/issues/7412 where
268
- // the truncation used to check all the files for deletion and end up
269
- // deleting empty files in between and breaking the sequence.
270
- func TestHeadReadWriter_Truncate_NoUnsequentialFiles (t * testing.T ) {
271
- hrw := testHeadReadWriter (t )
250
+ // TestChunkDiskMapper_Truncate_PreservesFileSequence tests that truncation doesn't poke
251
+ // holes into the file sequence, even if there are empty files in between non-empty files.
252
+ // This test exposes https://github.com/prometheus/prometheus/issues/7412 where the truncation
253
+ // simply deleted all empty files instead of stopping once it encountered a non-empty file.
254
+ func TestChunkDiskMapper_Truncate_PreservesFileSequence (t * testing.T ) {
255
+ hrw := testChunkDiskMapper (t )
272
256
defer func () {
273
257
testutil .Ok (t , hrw .Close ())
274
258
}()
@@ -296,7 +280,6 @@ func TestHeadReadWriter_Truncate_NoUnsequentialFiles(t *testing.T) {
296
280
nonEmptyFile () // 5.
297
281
emptyFile () // 6.
298
282
299
- // Verifying the files.
300
283
verifyFiles := func (remainingFiles []int ) {
301
284
t .Helper ()
302
285
@@ -308,7 +291,7 @@ func TestHeadReadWriter_Truncate_NoUnsequentialFiles(t *testing.T) {
308
291
309
292
for _ , i := range remainingFiles {
310
293
_ , ok := hrw .mmappedChunkFiles [i ]
311
- testutil .Equals (t , true , ok )
294
+ testutil .Assert (t , ok , "remaining file %d not in hrw.mmappedChunkFiles" , i )
312
295
}
313
296
}
314
297
@@ -339,7 +322,7 @@ func TestHeadReadWriter_Truncate_NoUnsequentialFiles(t *testing.T) {
339
322
// TestHeadReadWriter_TruncateAfterIterateChunksError tests for
340
323
// https://github.com/prometheus/prometheus/issues/7753
341
324
func TestHeadReadWriter_TruncateAfterFailedIterateChunks (t * testing.T ) {
342
- hrw := testHeadReadWriter (t )
325
+ hrw := testChunkDiskMapper (t )
343
326
defer func () {
344
327
testutil .Ok (t , hrw .Close ())
345
328
}()
@@ -365,7 +348,7 @@ func TestHeadReadWriter_TruncateAfterFailedIterateChunks(t *testing.T) {
365
348
}
366
349
367
350
func TestHeadReadWriter_ReadRepairOnEmptyLastFile (t * testing.T ) {
368
- hrw := testHeadReadWriter (t )
351
+ hrw := testChunkDiskMapper (t )
369
352
defer func () {
370
353
testutil .Ok (t , hrw .Close ())
371
354
}()
@@ -433,7 +416,7 @@ func TestHeadReadWriter_ReadRepairOnEmptyLastFile(t *testing.T) {
433
416
434
417
}
435
418
436
- func testHeadReadWriter (t * testing.T ) * ChunkDiskMapper {
419
+ func testChunkDiskMapper (t * testing.T ) * ChunkDiskMapper {
437
420
tmpdir , err := ioutil .TempDir ("" , "data" )
438
421
testutil .Ok (t , err )
439
422
t .Cleanup (func () {
0 commit comments