github.com/thanos-io/thanos@v0.32.5/pkg/block/indexheader/reader_pool_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package indexheader 5 6 import ( 7 "context" 8 "path/filepath" 9 "testing" 10 "time" 11 12 "github.com/go-kit/log" 13 promtestutil "github.com/prometheus/client_golang/prometheus/testutil" 14 "github.com/prometheus/prometheus/model/labels" 15 "github.com/thanos-io/objstore/providers/filesystem" 16 17 "github.com/efficientgo/core/testutil" 18 "github.com/thanos-io/thanos/pkg/block" 19 "github.com/thanos-io/thanos/pkg/block/metadata" 20 "github.com/thanos-io/thanos/pkg/testutil/e2eutil" 21 ) 22 23 func TestReaderPool_NewBinaryReader(t *testing.T) { 24 tests := map[string]struct { 25 lazyReaderEnabled bool 26 lazyReaderIdleTimeout time.Duration 27 }{ 28 "lazy reader is disabled": { 29 lazyReaderEnabled: false, 30 }, 31 "lazy reader is enabled but close on idle timeout is disabled": { 32 lazyReaderEnabled: true, 33 lazyReaderIdleTimeout: 0, 34 }, 35 "lazy reader and close on idle timeout are both enabled": { 36 lazyReaderEnabled: true, 37 lazyReaderIdleTimeout: time.Minute, 38 }, 39 } 40 41 ctx := context.Background() 42 43 tmpDir := t.TempDir() 44 45 bkt, err := filesystem.NewBucket(filepath.Join(tmpDir, "bkt")) 46 testutil.Ok(t, err) 47 defer func() { testutil.Ok(t, bkt.Close()) }() 48 49 // Create block. 50 blockID, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ 51 {{Name: "a", Value: "1"}}, 52 {{Name: "a", Value: "2"}}, 53 }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) 54 testutil.Ok(t, err) 55 testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, blockID.String()), metadata.NoneFunc)) 56 57 for testName, testData := range tests { 58 t.Run(testName, func(t *testing.T) { 59 pool := NewReaderPool(log.NewNopLogger(), testData.lazyReaderEnabled, testData.lazyReaderIdleTimeout, NewReaderPoolMetrics(nil)) 60 defer pool.Close() 61 62 r, err := pool.NewBinaryReader(ctx, log.NewNopLogger(), bkt, tmpDir, blockID, 3) 63 testutil.Ok(t, err) 64 defer func() { testutil.Ok(t, r.Close()) }() 65 66 // Ensure it can read data. 67 labelNames, err := r.LabelNames() 68 testutil.Ok(t, err) 69 testutil.Equals(t, []string{"a"}, labelNames) 70 }) 71 } 72 } 73 74 func TestReaderPool_ShouldCloseIdleLazyReaders(t *testing.T) { 75 const idleTimeout = time.Second 76 77 ctx := context.Background() 78 79 tmpDir := t.TempDir() 80 81 bkt, err := filesystem.NewBucket(filepath.Join(tmpDir, "bkt")) 82 testutil.Ok(t, err) 83 defer func() { testutil.Ok(t, bkt.Close()) }() 84 85 // Create block. 86 blockID, err := e2eutil.CreateBlock(ctx, tmpDir, []labels.Labels{ 87 {{Name: "a", Value: "1"}}, 88 {{Name: "a", Value: "2"}}, 89 }, 100, 0, 1000, labels.Labels{{Name: "ext1", Value: "1"}}, 124, metadata.NoneFunc) 90 testutil.Ok(t, err) 91 testutil.Ok(t, block.Upload(ctx, log.NewNopLogger(), bkt, filepath.Join(tmpDir, blockID.String()), metadata.NoneFunc)) 92 93 metrics := NewReaderPoolMetrics(nil) 94 pool := NewReaderPool(log.NewNopLogger(), true, idleTimeout, metrics) 95 defer pool.Close() 96 97 r, err := pool.NewBinaryReader(ctx, log.NewNopLogger(), bkt, tmpDir, blockID, 3) 98 testutil.Ok(t, err) 99 defer func() { testutil.Ok(t, r.Close()) }() 100 101 // Ensure it can read data. 102 labelNames, err := r.LabelNames() 103 testutil.Ok(t, err) 104 testutil.Equals(t, []string{"a"}, labelNames) 105 testutil.Equals(t, float64(1), promtestutil.ToFloat64(metrics.lazyReader.loadCount)) 106 testutil.Equals(t, float64(0), promtestutil.ToFloat64(metrics.lazyReader.unloadCount)) 107 108 // Wait enough time before checking it. 109 time.Sleep(idleTimeout * 2) 110 111 // We expect the reader has been closed, but not released from the pool. 112 testutil.Assert(t, pool.isTracking(r.(*LazyBinaryReader))) 113 testutil.Equals(t, float64(1), promtestutil.ToFloat64(metrics.lazyReader.loadCount)) 114 testutil.Equals(t, float64(1), promtestutil.ToFloat64(metrics.lazyReader.unloadCount)) 115 116 // Ensure it can still read data (will be re-opened). 117 labelNames, err = r.LabelNames() 118 testutil.Ok(t, err) 119 testutil.Equals(t, []string{"a"}, labelNames) 120 testutil.Assert(t, pool.isTracking(r.(*LazyBinaryReader))) 121 testutil.Equals(t, float64(2), promtestutil.ToFloat64(metrics.lazyReader.loadCount)) 122 testutil.Equals(t, float64(1), promtestutil.ToFloat64(metrics.lazyReader.unloadCount)) 123 124 // We expect an explicit call to Close() to close the reader and release it from the pool too. 125 testutil.Ok(t, r.Close()) 126 testutil.Assert(t, !pool.isTracking(r.(*LazyBinaryReader))) 127 testutil.Equals(t, float64(2), promtestutil.ToFloat64(metrics.lazyReader.loadCount)) 128 testutil.Equals(t, float64(2), promtestutil.ToFloat64(metrics.lazyReader.unloadCount)) 129 }