github.com/grafana/pyroscope@v1.18.0/pkg/compactor/job_test.go (about)

     1  // SPDX-License-Identifier: AGPL-3.0-only
     2  // Provenance-includes-location: https://github.com/grafana/mimir/blob/main/pkg/compactor/job_test.go
     3  // Provenance-includes-license: Apache-2.0
     4  // Provenance-includes-copyright: The Cortex Authors.
     5  
     6  package compactor
     7  
     8  import (
     9  	"context"
    10  	"path"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/oklog/ulid/v2"
    15  	"github.com/pkg/errors"
    16  	"github.com/prometheus/prometheus/model/labels"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  	"github.com/thanos-io/objstore"
    20  
    21  	"github.com/grafana/pyroscope/pkg/phlaredb/block"
    22  	"github.com/grafana/pyroscope/pkg/test/mocks/mockobjstore"
    23  )
    24  
    25  func TestJob_MinCompactionLevel(t *testing.T) {
    26  	job := NewJob("user-1", "group-1", labels.EmptyLabels(), 0, true, 2, 0, "shard-1")
    27  	require.NoError(t, job.AppendMeta(&block.Meta{ULID: ulid.MustNew(1, nil), Compaction: block.BlockMetaCompaction{Level: 2}}))
    28  	assert.Equal(t, 2, job.MinCompactionLevel())
    29  
    30  	require.NoError(t, job.AppendMeta(&block.Meta{ULID: ulid.MustNew(2, nil), Compaction: block.BlockMetaCompaction{Level: 3}}))
    31  	assert.Equal(t, 2, job.MinCompactionLevel())
    32  
    33  	require.NoError(t, job.AppendMeta(&block.Meta{ULID: ulid.MustNew(3, nil), Compaction: block.BlockMetaCompaction{Level: 1}}))
    34  	assert.Equal(t, 1, job.MinCompactionLevel())
    35  }
    36  
    37  func TestJobWaitPeriodElapsed(t *testing.T) {
    38  	type jobBlock struct {
    39  		meta     *block.Meta
    40  		attrs    objstore.ObjectAttributes
    41  		attrsErr error
    42  	}
    43  
    44  	// Blocks with compaction level 1.
    45  	meta1 := &block.Meta{ULID: ulid.MustNew(1, nil), Compaction: block.BlockMetaCompaction{Level: 1}}
    46  	meta2 := &block.Meta{ULID: ulid.MustNew(2, nil), Compaction: block.BlockMetaCompaction{Level: 1}}
    47  
    48  	// Blocks with compaction level 2.
    49  	meta3 := &block.Meta{ULID: ulid.MustNew(3, nil), Compaction: block.BlockMetaCompaction{Level: 2}}
    50  	meta4 := &block.Meta{ULID: ulid.MustNew(4, nil), Compaction: block.BlockMetaCompaction{Level: 2}}
    51  
    52  	tests := map[string]struct {
    53  		waitPeriod      time.Duration
    54  		jobBlocks       []jobBlock
    55  		expectedElapsed bool
    56  		expectedMeta    *block.Meta
    57  		expectedErr     string
    58  	}{
    59  		"wait period disabled": {
    60  			waitPeriod: 0,
    61  			jobBlocks: []jobBlock{
    62  				{meta: meta1, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-20 * time.Minute)}},
    63  				{meta: meta2, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-5 * time.Minute)}},
    64  			},
    65  			expectedElapsed: true,
    66  			expectedMeta:    nil,
    67  		},
    68  		"blocks uploaded since more than the wait period": {
    69  			waitPeriod: 10 * time.Minute,
    70  			jobBlocks: []jobBlock{
    71  				{meta: meta1, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-20 * time.Minute)}},
    72  				{meta: meta2, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-25 * time.Minute)}},
    73  			},
    74  			expectedElapsed: true,
    75  			expectedMeta:    nil,
    76  		},
    77  		"blocks uploaded since less than the wait period": {
    78  			waitPeriod: 10 * time.Minute,
    79  			jobBlocks: []jobBlock{
    80  				{meta: meta1, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-20 * time.Minute)}},
    81  				{meta: meta2, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-5 * time.Minute)}},
    82  			},
    83  			expectedElapsed: false,
    84  			expectedMeta:    meta2,
    85  		},
    86  		"blocks uploaded since less than the wait period but their compaction level is > 1": {
    87  			waitPeriod: 10 * time.Minute,
    88  			jobBlocks: []jobBlock{
    89  				{meta: meta3, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-4 * time.Minute)}},
    90  				{meta: meta4, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-5 * time.Minute)}},
    91  			},
    92  			expectedElapsed: true,
    93  			expectedMeta:    nil,
    94  		},
    95  		"an error occurred while checking the blocks upload timestamp": {
    96  			waitPeriod: 10 * time.Minute,
    97  			jobBlocks: []jobBlock{
    98  				// This block has been uploaded since more than the wait period.
    99  				{meta: meta1, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-20 * time.Minute)}},
   100  
   101  				// This block has been uploaded since less than the wait period, but we failed getting its attributes.
   102  				{meta: meta2, attrs: objstore.ObjectAttributes{LastModified: time.Now().Add(-5 * time.Minute)}, attrsErr: errors.New("mocked error")},
   103  			},
   104  			expectedErr:  "mocked error",
   105  			expectedMeta: meta2,
   106  		},
   107  	}
   108  
   109  	for testName, testData := range tests {
   110  		t.Run(testName, func(t *testing.T) {
   111  			job := NewJob("user-1", "group-1", labels.EmptyLabels(), 0, true, 2, 0, "shard-1")
   112  			for _, b := range testData.jobBlocks {
   113  				require.NoError(t, job.AppendMeta(b.meta))
   114  			}
   115  
   116  			userBucket := &mockobjstore.MockBucket{}
   117  			for _, b := range testData.jobBlocks {
   118  				userBucket.MockAttributes(path.Join(b.meta.ULID.String(), block.MetaFilename), b.attrs, b.attrsErr)
   119  			}
   120  
   121  			elapsed, meta, err := jobWaitPeriodElapsed(context.Background(), job, testData.waitPeriod, userBucket)
   122  			if testData.expectedErr != "" {
   123  				require.Error(t, err)
   124  				assert.ErrorContains(t, err, testData.expectedErr)
   125  				assert.False(t, elapsed)
   126  				assert.Equal(t, testData.expectedMeta, meta)
   127  			} else {
   128  				require.NoError(t, err)
   129  				assert.Equal(t, testData.expectedElapsed, elapsed)
   130  				assert.Equal(t, testData.expectedMeta, meta)
   131  			}
   132  		})
   133  	}
   134  }