github.com/grafana/pyroscope@v1.18.0/pkg/metastore/index/tombstones/tombstone_queue_test.go (about)

     1  package tombstones
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  
     9  	metastorev1 "github.com/grafana/pyroscope/api/gen/proto/go/metastore/v1"
    10  	"github.com/grafana/pyroscope/pkg/metastore/index/tombstones/store"
    11  )
    12  
    13  func TestTombstoneIterator(t *testing.T) {
    14  	queue := newTombstoneQueue()
    15  	now := time.Now()
    16  	entries := []*tombstones{
    17  		{
    18  			TombstoneEntry: store.TombstoneEntry{
    19  				Index:      1,
    20  				AppendedAt: now.Add(-5 * time.Hour).UnixNano(),
    21  				Tombstones: &metastorev1.Tombstones{
    22  					Blocks: &metastorev1.BlockTombstones{Name: "block-1"},
    23  				},
    24  			},
    25  		},
    26  		{
    27  			TombstoneEntry: store.TombstoneEntry{
    28  				Index:      2,
    29  				AppendedAt: now.Add(-4 * time.Hour).UnixNano(),
    30  				Tombstones: &metastorev1.Tombstones{
    31  					Blocks: &metastorev1.BlockTombstones{Name: "block-2"},
    32  				},
    33  			},
    34  		},
    35  		{
    36  			TombstoneEntry: store.TombstoneEntry{
    37  				Index:      3,
    38  				AppendedAt: now.Add(-3 * time.Hour).UnixNano(),
    39  				Tombstones: &metastorev1.Tombstones{
    40  					Blocks: &metastorev1.BlockTombstones{Name: "block-3"},
    41  				},
    42  			},
    43  		},
    44  		{
    45  			TombstoneEntry: store.TombstoneEntry{
    46  				Index:      4,
    47  				AppendedAt: now.Add(-2 * time.Hour).UnixNano(),
    48  				Tombstones: &metastorev1.Tombstones{
    49  					Blocks: &metastorev1.BlockTombstones{Name: "block-4"},
    50  				},
    51  			},
    52  		},
    53  		{
    54  			TombstoneEntry: store.TombstoneEntry{
    55  				Index:      5,
    56  				AppendedAt: now.Add(-1 * time.Hour).UnixNano(),
    57  				Tombstones: &metastorev1.Tombstones{
    58  					Blocks: &metastorev1.BlockTombstones{Name: "block-5"},
    59  				},
    60  			},
    61  		},
    62  	}
    63  
    64  	for _, entry := range entries {
    65  		queue.push(entry)
    66  	}
    67  
    68  	t.Run("all entries before current time", func(t *testing.T) {
    69  		iter := &tombstoneIter{
    70  			head:   queue.head,
    71  			before: now.UnixNano(),
    72  		}
    73  		count := 0
    74  		for iter.Next() {
    75  			count++
    76  			assert.Equal(t, entries[count-1].Tombstones, iter.At())
    77  		}
    78  		assert.Equal(t, len(entries), count)
    79  	})
    80  
    81  	t.Run("entries before specific time", func(t *testing.T) {
    82  		cutoffTime := now.Add(-3 * time.Hour)
    83  		iter := &tombstoneIter{
    84  			head:   queue.head,
    85  			before: cutoffTime.UnixNano(),
    86  		}
    87  		expected := []string{"block-1", "block-2"}
    88  		var actual []string
    89  		for iter.Next() {
    90  			actual = append(actual, iter.At().Blocks.Name)
    91  		}
    92  		assert.Equal(t, expected, actual)
    93  	})
    94  
    95  	t.Run("empty queue", func(t *testing.T) {
    96  		emptyQueue := newTombstoneQueue()
    97  		iter := &tombstoneIter{
    98  			head:   emptyQueue.head,
    99  			before: now.UnixNano(),
   100  		}
   101  		assert.False(t, iter.Next())
   102  	})
   103  
   104  	t.Run("no entries before cutoff time", func(t *testing.T) {
   105  		iter := &tombstoneIter{
   106  			head:   queue.head,
   107  			before: now.Add(-10 * time.Hour).UnixNano(),
   108  		}
   109  		assert.False(t, iter.Next())
   110  	})
   111  }
   112  
   113  func TestQueueDelete(t *testing.T) {
   114  	queue := newTombstoneQueue()
   115  	now := time.Now()
   116  
   117  	entry1 := &tombstones{
   118  		TombstoneEntry: store.TombstoneEntry{
   119  			Index:      1,
   120  			AppendedAt: now.Add(-3 * time.Hour).UnixNano(),
   121  			Tombstones: &metastorev1.Tombstones{
   122  				Blocks: &metastorev1.BlockTombstones{Name: "tombstone-1"},
   123  			},
   124  		},
   125  	}
   126  	entry2 := &tombstones{
   127  		TombstoneEntry: store.TombstoneEntry{
   128  			Index:      2,
   129  			AppendedAt: now.Add(-2 * time.Hour).UnixNano(),
   130  			Tombstones: &metastorev1.Tombstones{
   131  				Blocks: &metastorev1.BlockTombstones{Name: "tombstone-2"},
   132  			},
   133  		},
   134  	}
   135  	entry3 := &tombstones{
   136  		TombstoneEntry: store.TombstoneEntry{
   137  			Index:      3,
   138  			AppendedAt: now.Add(-1 * time.Hour).UnixNano(),
   139  			Tombstones: &metastorev1.Tombstones{
   140  				Blocks: &metastorev1.BlockTombstones{Name: "tombstone-3"},
   141  			},
   142  		},
   143  	}
   144  
   145  	queue.push(entry1)
   146  	queue.push(entry2)
   147  	queue.push(entry3)
   148  
   149  	assert.Equal(t, entry1, queue.head)
   150  	assert.Equal(t, entry3, queue.tail)
   151  
   152  	deleted := queue.delete(entry3)
   153  	assert.Equal(t, entry3, deleted)
   154  
   155  	assert.NotNil(t, queue.tail)
   156  	assert.Equal(t, entry2, queue.tail)
   157  
   158  	var count int
   159  	iter := &tombstoneIter{head: queue.head, before: now.UnixNano()}
   160  	for iter.Next() {
   161  		count++
   162  	}
   163  
   164  	assert.Equal(t, 2, count)
   165  }