Files
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

155 lines
4.2 KiB
Go

package mcp
import (
"container/list"
"strconv"
"testing"
)
func TestPPRWalkCacheLRU(t *testing.T) {
c := newPPRWalkCache()
c.cap = 2
c.put("a", map[string]float64{"x": 1})
c.put("b", map[string]float64{"x": 2})
if _, ok := c.get("a"); !ok {
t.Fatal("a should be present")
}
// Touch a (now MRU), then insert c -> b is LRU and evicted.
c.put("c", map[string]float64{"x": 3})
if _, ok := c.get("b"); ok {
t.Fatal("b should have been evicted (LRU)")
}
if _, ok := c.get("a"); !ok {
t.Fatal("a should survive (was recently used)")
}
if _, ok := c.get("c"); !ok {
t.Fatal("c should be present")
}
}
func TestPPRWalkCacheStats(t *testing.T) {
c := newPPRWalkCache()
c.put("k", map[string]float64{"x": 1})
if _, ok := c.get("k"); !ok {
t.Fatal("hit expected")
}
if _, ok := c.get("miss"); ok {
t.Fatal("miss expected")
}
hits, misses, size, capacity, enabled := c.stats()
if hits != 1 || misses != 1 {
t.Fatalf("hits=%d misses=%d, want 1/1", hits, misses)
}
if size != 1 || capacity != 512 || !enabled {
t.Fatalf("size=%d cap=%d enabled=%v", size, capacity, enabled)
}
}
func TestPPRWalkCacheDisabled(t *testing.T) {
t.Setenv("GORTEX_PPR_CACHE_DISABLE", "1")
c := newPPRWalkCache()
if c.enabled {
t.Fatal("cache should be disabled")
}
c.put("k", map[string]float64{"x": 1})
if _, ok := c.get("k"); ok {
t.Fatal("disabled cache should never hit")
}
}
func TestPPRWalkCacheEmptyKeyAndScores(t *testing.T) {
c := newPPRWalkCache()
c.put("", map[string]float64{"x": 1}) // empty key ignored
if _, ok := c.get(""); ok {
t.Fatal("empty key should never store")
}
c.put("k", nil) // empty scores ignored
if _, ok := c.get("k"); ok {
t.Fatal("empty scores should not be stored")
}
}
func TestPPRWalkCacheDefaults(t *testing.T) {
// Construction without overriding env carries the memory-bounding
// defaults that keep the cache from ballooning on a large graph.
c := newPPRWalkCache()
if c.maxBytes != pprCacheDefaultMaxBytes {
t.Errorf("default maxBytes=%d, want %d", c.maxBytes, pprCacheDefaultMaxBytes)
}
if c.topK != pprCacheDefaultTopK {
t.Errorf("default topK=%d, want %d", c.topK, pprCacheDefaultTopK)
}
}
func TestPPRWalkCacheEnvOverrides(t *testing.T) {
t.Setenv("GORTEX_PPR_CACHE_MAX_MB", "8")
t.Setenv("GORTEX_PPR_CACHE_TOPK", "0") // 0 = unbounded is a valid override
c := newPPRWalkCache()
if c.maxBytes != 8<<20 {
t.Errorf("maxBytes=%d, want %d", c.maxBytes, 8<<20)
}
if c.topK != 0 {
t.Errorf("topK=%d, want 0", c.topK)
}
}
// newTestPPRCache builds a cache with explicit bounds, bypassing the
// environment so the test is hermetic.
func newTestPPRCache(cap int, maxBytes int64) *pprWalkCache {
return &pprWalkCache{
ll: list.New(),
m: make(map[string]*list.Element),
cap: cap,
maxBytes: maxBytes,
enabled: true,
}
}
func scoresOfSize(n int) map[string]float64 {
m := make(map[string]float64, n)
for i := range n {
m["id"+strconv.Itoa(i)] = float64(i + 1)
}
return m
}
func TestPPRCache_ByteBudgetEvicts(t *testing.T) {
// Each 10-score entry costs 10*pprCacheBytesPerScore. Budget for two;
// the entry-count ceiling is high so the byte budget is what governs.
per := int64(10) * pprCacheBytesPerScore
c := newTestPPRCache(1000, 2*per)
for i := range 5 {
c.put("k"+strconv.Itoa(i), scoresOfSize(10))
}
if _, _, size, _, _ := c.stats(); size != 2 {
t.Fatalf("byte budget should cap the cache at 2 entries, got %d", size)
}
if c.curBytes > c.maxBytes {
t.Fatalf("curBytes %d exceeds budget %d", c.curBytes, c.maxBytes)
}
if _, ok := c.get("k4"); !ok {
t.Errorf("most-recent key k4 should survive")
}
if _, ok := c.get("k0"); ok {
t.Errorf("oldest key k0 should have been evicted")
}
}
func TestPPRCache_ReputSameSizeKeepsByteAccounting(t *testing.T) {
c := newTestPPRCache(1000, 1<<30)
c.put("a", scoresOfSize(10))
before := c.curBytes
// Re-putting an existing key replaces its scores and re-accounts its
// bytes in place — no double counting.
c.put("a", scoresOfSize(10))
if c.curBytes != before {
t.Errorf("re-put of same-size entry changed curBytes: before=%d after=%d", before, c.curBytes)
}
if _, _, size, _, _ := c.stats(); size != 1 {
t.Errorf("re-put must not add a second entry, size=%d", size)
}
}