Files
zzet--gortex/internal/indexer/editlatency_measure_test.go
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

81 lines
2.6 KiB
Go

package indexer
import (
"os"
"path/filepath"
"testing"
"time"
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/graph/store_sqlite"
"github.com/zzet/gortex/internal/parser"
"github.com/zzet/gortex/internal/parser/languages"
"go.uber.org/zap"
)
// TestMeasureEditLatency builds a sqlite-backed graph from a real repo and
// times ResolveFileAndIncoming + IndexFile (the per-edit reindex path), with
// the resolver's buildPassIndexes breakdown logged at Debug. It quantifies the
// whole-graph O(graph) cost a single-file edit pays. Opt-in:
//
// GORTEX_MEASURE_REPO=/abs/path [GORTEX_MEASURE_FILE=rel/path.go] \
// go test -run TestMeasureEditLatency -v -count=1 ./internal/indexer/
func TestMeasureEditLatency(t *testing.T) {
repo := os.Getenv("GORTEX_MEASURE_REPO")
if repo == "" {
t.Skip("set GORTEX_MEASURE_REPO=/abs/path to run")
}
editRel := os.Getenv("GORTEX_MEASURE_FILE")
if editRel == "" {
editRel = "internal/resolver/resolver.go"
}
dbPath := os.Getenv("GORTEX_MEASURE_DB")
if dbPath == "" {
dbPath = filepath.Join(t.TempDir(), "store.sqlite")
}
store, err := store_sqlite.Open(dbPath)
if err != nil {
t.Fatal(err)
}
defer store.Close()
prebuilt := store.NodeCount() > 0 // reuse a persisted store across runs
logger, _ := zap.NewDevelopment() // Debug enabled -> buildPassIndexes timing
reg := parser.NewRegistry()
reg.Register(languages.NewGoExtractor())
reg.Register(languages.NewTypeScriptExtractor())
reg.Register(languages.NewPythonExtractor())
cfg := config.Default().Index
cfg.Workers = 8
idx := New(store, reg, cfg, logger)
idx.resolver.SetLogger(logger) // surface buildPassIndexes per-builder timing
if !prebuilt {
t0 := time.Now()
if _, err := idx.IndexCtx(testCtx(), repo); err != nil {
t.Fatalf("index: %v", err)
}
t.Logf("=== indexed %s in %v -- nodes=%d edges=%d", repo, time.Since(t0), store.NodeCount(), store.EdgeCount())
} else {
t.Logf("=== reusing prebuilt store %s -- nodes=%d edges=%d", dbPath, store.NodeCount(), store.EdgeCount())
}
absEdit := filepath.Join(repo, editRel)
if _, err := os.Stat(absEdit); err != nil {
t.Fatalf("edit file not found: %v", err)
}
graphPath := idx.prefixPath(idx.relKey(absEdit))
t.Logf("=== edit target graphPath=%q", graphPath)
// The full edit_file reindex path end-to-end. #0 runs on the freshly
// opened store (cold sqlite cache) = the cold-edit number; #1+ warm.
for i := 0; i < 4; i++ {
tt := time.Now()
if err := idx.IndexFile(absEdit); err != nil {
t.Logf("IndexFile err: %v", err)
}
t.Logf(">>> IndexFile #%d: %v", i, time.Since(tt))
}
}