mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Remove TestTombstoneCleanRetentionLimitsRace
This test ensures that running db.reloadBlocks() and db.CleanTombstones() at the same time doesn't race. The problem is that CleanTombstones() is a public method while reloadBlocks() is internal. CleanTombstones() sets db.cmtx lock while reloadBlocks() is not protected by any locks at all, it expects the public method through which it was called to do it. So having a race between these two is not unexpected and we shouldn't really be testing this. db.cmtx ensures that no other function can be modifying the list of open blocks and so the scenario tested here cannot happen. If it would happen it would be only because some other method doesn't aquire db.ctmx lock, something this test cannot detect. Signed-off-by: Łukasz Mierzwa <l.mierzwa@gmail.com>
This commit is contained in:
parent
b880cea613
commit
92788d313a
|
@ -1350,61 +1350,6 @@ func TestTombstoneCleanFail(t *testing.T) {
|
|||
require.Len(t, intersection(oldBlockDirs, actualBlockDirs), len(actualBlockDirs)-1)
|
||||
}
|
||||
|
||||
// TestTombstoneCleanRetentionLimitsRace tests that a CleanTombstones operation
|
||||
// and retention limit policies, when triggered at the same time,
|
||||
// won't race against each other.
|
||||
func TestTombstoneCleanRetentionLimitsRace(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping test in short mode.")
|
||||
}
|
||||
|
||||
opts := DefaultOptions()
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// We want to make sure that a race doesn't happen when a normal reload and a CleanTombstones()
|
||||
// reload try to delete the same block. Without the correct lock placement, it can happen if a
|
||||
// block is marked for deletion due to retention limits and also has tombstones to be cleaned at
|
||||
// the same time.
|
||||
//
|
||||
// That is something tricky to trigger, so let's try several times just to make sure.
|
||||
for i := 0; i < 20; i++ {
|
||||
t.Run(fmt.Sprintf("iteration%d", i), func(t *testing.T) {
|
||||
db := openTestDB(t, opts, nil)
|
||||
totalBlocks := 20
|
||||
dbDir := db.Dir()
|
||||
// Generate some blocks with old mint (near epoch).
|
||||
for j := 0; j < totalBlocks; j++ {
|
||||
blockDir := createBlock(t, dbDir, genSeries(10, 1, int64(j), int64(j)+1))
|
||||
block, err := OpenBlock(nil, blockDir, nil, nil)
|
||||
require.NoError(t, err)
|
||||
// Cover block with tombstones so it can be deleted with CleanTombstones() as well.
|
||||
tomb := tombstones.NewMemTombstones()
|
||||
tomb.AddInterval(0, tombstones.Interval{Mint: int64(j), Maxt: int64(j) + 1})
|
||||
block.tombstones = tomb
|
||||
|
||||
db.blocks = append(db.blocks, block)
|
||||
}
|
||||
|
||||
wg.Add(2)
|
||||
// Run reload and CleanTombstones together, with a small time window randomization
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
time.Sleep(time.Duration(rand.Float64() * 100 * float64(time.Millisecond)))
|
||||
require.NoError(t, db.reloadBlocks())
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
time.Sleep(time.Duration(rand.Float64() * 100 * float64(time.Millisecond)))
|
||||
require.NoError(t, db.CleanTombstones())
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
require.NoError(t, db.Close())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func intersection(oldBlocks, actualBlocks []string) (intersection []string) {
|
||||
hash := make(map[string]bool)
|
||||
for _, e := range oldBlocks {
|
||||
|
|
Loading…
Reference in a new issue