From 3ba85691a8dc8183401ffd870c86df9ca4afa765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torjus=20H=C3=A5kestad?= Date: Tue, 3 Feb 2026 18:42:02 +0100 Subject: [PATCH] test: improve file indexing benchmarks - BenchmarkIndexRevisionWithFiles now reports separate timing for options indexing (options_ms) and file indexing (files_ms) - Add BenchmarkIndexFilesOnly to measure file indexing in isolation Run with: go test -bench=BenchmarkIndexFilesOnly -benchtime=1x -timeout=60m ./internal/nixos/... Co-Authored-By: Claude Opus 4.5 --- internal/nixos/indexer_test.go | 46 +++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/internal/nixos/indexer_test.go b/internal/nixos/indexer_test.go index 76cb49b..44b3a88 100644 --- a/internal/nixos/indexer_test.go +++ b/internal/nixos/indexer_test.go @@ -4,6 +4,7 @@ import ( "context" "os/exec" "testing" + "time" "git.t-juice.club/torjus/labmcp/internal/database" ) @@ -86,12 +87,55 @@ func BenchmarkIndexRevisionWithFiles(b *testing.B) { b.Fatalf("IndexRevision failed: %v", err) } + fileStart := time.Now() + fileCount, err := indexer.IndexFiles(ctx, result.Revision.ID, TestNixpkgsRevision) + if err != nil { + b.Fatalf("IndexFiles failed: %v", err) + } + fileDuration := time.Since(fileStart) + + b.ReportMetric(float64(result.OptionCount), "options") + b.ReportMetric(float64(result.Duration.Milliseconds()), "options_ms") + b.ReportMetric(float64(fileCount), "files") + b.ReportMetric(float64(fileDuration.Milliseconds()), "files_ms") + } +} + +// BenchmarkIndexFilesOnly benchmarks only the file indexing phase. +// Assumes options are already indexed. Useful for measuring file indexing in isolation. +// Run with: go test -bench=BenchmarkIndexFilesOnly -benchtime=1x -timeout=60m ./internal/nixos/... +func BenchmarkIndexFilesOnly(b *testing.B) { + if _, err := exec.LookPath("nix-build"); err != nil { + b.Skip("nix-build not found, skipping indexer benchmark") + } + + store, err := database.NewSQLiteStore(":memory:") + if err != nil { + b.Fatalf("Failed to create store: %v", err) + } + defer store.Close() + + ctx := context.Background() + if err := store.Initialize(ctx); err != nil { + b.Fatalf("Failed to initialize store: %v", err) + } + + indexer := NewIndexer(store) + + // Index options first (outside of benchmark timing) + result, err := indexer.IndexRevision(ctx, TestNixpkgsRevision) + if err != nil { + b.Fatalf("IndexRevision failed: %v", err) + } + b.Logf("Pre-indexed %d options", result.OptionCount) + + b.ResetTimer() + for i := 0; i < b.N; i++ { fileCount, err := indexer.IndexFiles(ctx, result.Revision.ID, TestNixpkgsRevision) if err != nil { b.Fatalf("IndexFiles failed: %v", err) } - b.ReportMetric(float64(result.OptionCount), "options") b.ReportMetric(float64(fileCount), "files") } }