From c508b01cc536c163dfa31c1485e81c47b7fe0624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C5=A0tibran=C3=BD?= Date: Mon, 18 Aug 2025 16:27:57 +0200 Subject: [PATCH] chore: Close bleve indexes created in temp dir. (#109799) * Close indexes created in temp dir. --- pkg/storage/unified/search/bleve.go | 2 +- .../unified/search/bleve_integration_test.go | 4 ++ .../unified/search/bleve_performance_test.go | 13 ++---- .../unified/search/bleve_search_test.go | 42 +++++++------------ pkg/storage/unified/search/bleve_test.go | 12 +++--- .../unified/sql/test/benchmark_test.go | 2 + .../unified/sql/test/integration_test.go | 2 + 7 files changed, 33 insertions(+), 44 deletions(-) diff --git a/pkg/storage/unified/search/bleve.go b/pkg/storage/unified/search/bleve.go index 01dcc3cabd9..6c0ca8a14ff 100644 --- a/pkg/storage/unified/search/bleve.go +++ b/pkg/storage/unified/search/bleve.go @@ -532,7 +532,7 @@ func (b *bleveBackend) findPreviousFileBasedIndex(resourceDir string, resourceVe return idx, indexName } -func (b *bleveBackend) closeAllIndexes() { +func (b *bleveBackend) CloseAllIndexes() { b.cacheMx.Lock() defer b.cacheMx.Unlock() diff --git a/pkg/storage/unified/search/bleve_integration_test.go b/pkg/storage/unified/search/bleve_integration_test.go index 043b7642dac..7c3ca33f095 100644 --- a/pkg/storage/unified/search/bleve_integration_test.go +++ b/pkg/storage/unified/search/bleve_integration_test.go @@ -25,6 +25,8 @@ func TestBleveSearchBackend(t *testing.T) { require.NoError(t, err) require.NotNil(t, backend) + t.Cleanup(backend.CloseAllIndexes) + return backend }, &unitest.TestOptions{ NSPrefix: "bleve-test", @@ -48,5 +50,7 @@ func TestSearchBackendBenchmark(t *testing.T) { require.NoError(t, err) require.NotNil(t, backend) + t.Cleanup(backend.CloseAllIndexes) + unitest.BenchmarkSearchBackend(t, backend, opts) } diff --git a/pkg/storage/unified/search/bleve_performance_test.go b/pkg/storage/unified/search/bleve_performance_test.go index e1ae015efd2..d6cb840647e 100644 --- a/pkg/storage/unified/search/bleve_performance_test.go +++ b/pkg/storage/unified/search/bleve_performance_test.go @@ -3,7 +3,6 @@ package search_test import ( "context" "fmt" - "os" "runtime" "testing" "time" @@ -14,14 +13,14 @@ import ( "github.com/stretchr/testify/require" ) -func setupIndex() (resource.ResourceIndex, string) { +func setupIndex(b testing.TB) resource.ResourceIndex { // size := 1000000 // TODO: 200k documents standard size? size := 200000 // batchSize := 1000 slower 8s (for 200k documents) - 34s (for 1M documents) // batchSize := 10000 // faster 5s (for 200k documents) - 27s (for 1M documents) batchSize := 100000 // fasterer 3.5s (for 200k documents) - 27s (for 1M documents) writer := newTestWriter(size, batchSize) - return newTestDashboardsIndex(nil, 1, int64(size), int64(batchSize), writer) + return newTestDashboardsIndex(b, 1, int64(size), int64(batchSize), writer) } const maxAllowedTime = 20 * time.Millisecond // Reasonable (can vary per env) performance threshold per query (e.g., 20ms) @@ -37,13 +36,7 @@ func BenchmarkBleveQuery(b *testing.B) { var memStatsAfterIndex runtime.MemStats runtime.ReadMemStats(&memStatsStart) - testIndex, testIndexDir := setupIndex() - defer func() { - err := os.RemoveAll(testIndexDir) - if err != nil { - fmt.Printf("Error removing index directory: %v\n", err) - } - }() + testIndex := setupIndex(b) runtime.ReadMemStats(&memStatsAfterIndex) diff --git a/pkg/storage/unified/search/bleve_search_test.go b/pkg/storage/unified/search/bleve_search_test.go index e5bfc81a338..865f570389a 100644 --- a/pkg/storage/unified/search/bleve_search_test.go +++ b/pkg/storage/unified/search/bleve_search_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "log" - "os" "testing" "github.com/blevesearch/bleve/v2" @@ -30,7 +29,7 @@ func TestCanSearchByTitle(t *testing.T) { } t.Run("when query is empty, sort documents by title instead of search score", func(t *testing.T) { - index, _ := newTestDashboardsIndex(t, threshold, 2, 2, noop) + index := newTestDashboardsIndex(t, threshold, 2, 2, noop) err := index.BulkIndex(&resource.BulkIndexRequest{ Items: []*resource.BulkIndexItem{ { @@ -74,7 +73,7 @@ func TestCanSearchByTitle(t *testing.T) { }) t.Run("will boost phrase match query over match query results", func(t *testing.T) { - index, _ := newTestDashboardsIndex(t, threshold, 2, 2, noop) + index := newTestDashboardsIndex(t, threshold, 2, 2, noop) err := index.BulkIndex(&resource.BulkIndexRequest{ Items: []*resource.BulkIndexItem{ { @@ -118,7 +117,7 @@ func TestCanSearchByTitle(t *testing.T) { }) t.Run("will prioritize matches", func(t *testing.T) { - index, _ := newTestDashboardsIndex(t, threshold, 2, 2, noop) + index := newTestDashboardsIndex(t, threshold, 2, 2, noop) err := index.BulkIndex(&resource.BulkIndexRequest{ Items: []*resource.BulkIndexItem{ { @@ -161,7 +160,7 @@ func TestCanSearchByTitle(t *testing.T) { }) t.Run("will boost exact match query over match phrase query results", func(t *testing.T) { - index, _ := newTestDashboardsIndex(t, threshold, 2, 2, noop) + index := newTestDashboardsIndex(t, threshold, 2, 2, noop) err := index.BulkIndex(&resource.BulkIndexRequest{ Items: []*resource.BulkIndexItem{ { @@ -205,7 +204,7 @@ func TestCanSearchByTitle(t *testing.T) { }) t.Run("title with numbers will match document", func(t *testing.T) { - index, _ := newTestDashboardsIndex(t, threshold, 2, 2, noop) + index := newTestDashboardsIndex(t, threshold, 2, 2, noop) err := index.BulkIndex(&resource.BulkIndexRequest{ Items: []*resource.BulkIndexItem{ { @@ -246,7 +245,7 @@ func TestCanSearchByTitle(t *testing.T) { }) t.Run("title will match escaped characters", func(t *testing.T) { - index, _ := newTestDashboardsIndex(t, threshold, 2, 2, noop) + index := newTestDashboardsIndex(t, threshold, 2, 2, noop) err := index.BulkIndex(&resource.BulkIndexRequest{ Items: []*resource.BulkIndexItem{ { @@ -293,7 +292,7 @@ func TestCanSearchByTitle(t *testing.T) { }) t.Run("title search will match document", func(t *testing.T) { - index, _ := newTestDashboardsIndex(t, threshold, 2, 2, noop) + index := newTestDashboardsIndex(t, threshold, 2, 2, noop) err := index.BulkIndex(&resource.BulkIndexRequest{ Items: []*resource.BulkIndexItem{ { @@ -358,7 +357,7 @@ func TestCanSearchByTitle(t *testing.T) { }) t.Run("title search will NOT match documents", func(t *testing.T) { - index, _ := newTestDashboardsIndex(t, threshold, 2, 2, noop) + index := newTestDashboardsIndex(t, threshold, 2, 2, noop) err := index.BulkIndex(&resource.BulkIndexRequest{ Items: []*resource.BulkIndexItem{ { @@ -427,7 +426,7 @@ func TestCanSearchByTitle(t *testing.T) { }) t.Run("title search with character will match one document", func(t *testing.T) { - index, _ := newTestDashboardsIndex(t, threshold, 2, 2, noop) + index := newTestDashboardsIndex(t, threshold, 2, 2, noop) err := index.BulkIndex(&resource.BulkIndexRequest{ Items: []*resource.BulkIndexItem{ { @@ -520,22 +519,21 @@ func newQueryByTitle(query string) *resourcepb.ResourceSearchRequest { } } -func newTestDashboardsIndex(t TB, threshold int64, size int64, batchSize int64, writer IndexWriter) (resource.ResourceIndex, string) { +func newTestDashboardsIndex(t testing.TB, threshold int64, size int64, batchSize int64, writer IndexWriter) resource.ResourceIndex { key := &resourcepb.ResourceKey{ Namespace: "default", Group: "dashboard.grafana.app", Resource: "dashboards", } - tmpdir, err := os.MkdirTemp("", "grafana-bleve-test") - require.NoError(t, err) - backend, err := search.NewBleveBackend(search.BleveOptions{ - Root: tmpdir, + Root: t.TempDir(), FileThreshold: threshold, // use in-memory for tests BatchSize: int(batchSize), }, tracing.NewNoopTracerService(), featuremgmt.WithFeatures(), nil) require.NoError(t, err) + t.Cleanup(backend.CloseAllIndexes) + rv := int64(10) ctx := identity.WithRequester(context.Background(), &user.SignedInUser{Namespace: "ns"}) @@ -556,7 +554,7 @@ func newTestDashboardsIndex(t TB, threshold int64, size int64, batchSize int64, }, size, rv, info.Fields, "test", writer) require.NoError(t, err) - return index, tmpdir + return index } type IndexWriter func(index resource.ResourceIndex) (int64, error) @@ -603,15 +601,3 @@ func debugIndexedTerms(index bleve.Index, field string) { } } } - -// TB is an interface that works for both *testing.T and *testing.B -type TB interface { - Log(args ...interface{}) - Logf(format string, args ...interface{}) - Error(args ...interface{}) - Errorf(format string, args ...interface{}) - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) - Helper() - FailNow() -} diff --git a/pkg/storage/unified/search/bleve_test.go b/pkg/storage/unified/search/bleve_test.go index a5acceaecc8..e28d8a80cb8 100644 --- a/pkg/storage/unified/search/bleve_test.go +++ b/pkg/storage/unified/search/bleve_test.go @@ -50,6 +50,8 @@ func TestBleveBackend(t *testing.T) { }, tracing.NewNoopTracerService(), featuremgmt.WithFeatures(), nil) require.NoError(t, err) + t.Cleanup(backend.CloseAllIndexes) + rv := int64(10) ctx := identity.WithRequester(context.Background(), &user.SignedInUser{Namespace: "ns"}) var dashboardsIndex resource.ResourceIndex @@ -753,7 +755,7 @@ func setupBleveBackend(t *testing.T, fileThreshold int, cacheTTL time.Duration, }, tracing.NewNoopTracerService(), featuremgmt.WithFeatures(), metrics) require.NoError(t, err) require.NotNil(t, backend) - t.Cleanup(backend.closeAllIndexes) + t.Cleanup(backend.CloseAllIndexes) return backend, reg } @@ -841,9 +843,9 @@ func TestFileIndexIsReusedOnSameSizeAndRV(t *testing.T) { index_server_open_indexes{index_storage="file"} 1 `), "index_server_open_indexes")) - backend1.closeAllIndexes() + backend1.CloseAllIndexes() - // Verify that there are no open indexes after closeAllIndexes call. + // Verify that there are no open indexes after CloseAllIndexes call. require.NoError(t, testutil.GatherAndCompare(reg1, bytes.NewBufferString(` # HELP index_server_open_indexes Number of open indexes per storage type. An open index corresponds to single resource group. # TYPE index_server_open_indexes gauge @@ -881,7 +883,7 @@ func TestFileIndexIsNotReusedOnDifferentSize(t *testing.T) { backend1, _ := setupBleveBackend(t, 5, time.Nanosecond, tmpDir) _, err := backend1.BuildIndex(context.Background(), ns, 10, 100, nil, "test", indexTestDocs(ns, 10)) require.NoError(t, err) - backend1.closeAllIndexes() + backend1.CloseAllIndexes() // We open new backend using same directory, but with different size. Index should be rebuilt. backend2, _ := setupBleveBackend(t, 5, time.Nanosecond, tmpDir) @@ -906,7 +908,7 @@ func TestFileIndexIsNotReusedOnDifferentRV(t *testing.T) { backend1, _ := setupBleveBackend(t, 5, time.Nanosecond, tmpDir) _, err := backend1.BuildIndex(context.Background(), ns, 10, 100, nil, "test", indexTestDocs(ns, 10)) require.NoError(t, err) - backend1.closeAllIndexes() + backend1.CloseAllIndexes() // We open new backend using same directory, but with different RV. Index should be rebuilt. backend2, _ := setupBleveBackend(t, 5, time.Nanosecond, tmpDir) diff --git a/pkg/storage/unified/sql/test/benchmark_test.go b/pkg/storage/unified/sql/test/benchmark_test.go index fe1b219c751..1fe29d3b594 100644 --- a/pkg/storage/unified/sql/test/benchmark_test.go +++ b/pkg/storage/unified/sql/test/benchmark_test.go @@ -77,6 +77,8 @@ func TestIntegrationBenchmarkResourceServer(t *testing.T) { require.NoError(t, err) require.NotNil(t, search) + t.Cleanup(search.CloseAllIndexes) + // Create a new resource backend dbstore := db.InitTestDB(t) eDB, err := dbimpl.ProvideResourceDB(dbstore, setting.NewCfg(), nil) diff --git a/pkg/storage/unified/sql/test/integration_test.go b/pkg/storage/unified/sql/test/integration_test.go index c03915164f8..159f7b97a83 100644 --- a/pkg/storage/unified/sql/test/integration_test.go +++ b/pkg/storage/unified/sql/test/integration_test.go @@ -121,6 +121,8 @@ func TestIntegrationSearchAndStorage(t *testing.T) { require.NoError(t, err) require.NotNil(t, search) + t.Cleanup(search.CloseAllIndexes) + // Create a new resource backend dbstore := db.InitTestDB(t) eDB, err := dbimpl.ProvideResourceDB(dbstore, setting.NewCfg(), nil)