123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- package searcher
- import (
- "testing"
- "time"
- )
- // TestCache tests the basic functionality of the optimized cache
- func TestCache(t *testing.T) {
- cache := NewCache(100)
- defer cache.Close()
- req := &SearchRequest{
- Query: "test",
- Limit: 10,
- Offset: 0,
- }
- result := &SearchResult{
- TotalHits: 5,
- Hits: []*SearchHit{
- {ID: "doc1", Score: 1.0},
- {ID: "doc2", Score: 0.9},
- },
- }
- // Test cache miss
- cached := cache.Get(req)
- if cached != nil {
- t.Error("expected cache miss")
- }
- // Test cache put
- cache.Put(req, result, 1*time.Minute)
- // Test cache hit
- cached = cache.Get(req)
- if cached == nil {
- t.Fatal("expected cache hit")
- }
- if !cached.FromCache {
- t.Error("result should be marked as from cache")
- }
- // Test stats
- stats := cache.GetStats()
- if stats == nil {
- t.Fatal("stats should not be nil")
- }
- t.Logf("Cache stats: Size=%d, HitRate=%.2f", stats.Size, stats.HitRate)
- }
- func BenchmarkCacheKeyGeneration(b *testing.B) {
- cache := NewCache(1000)
- defer cache.Close()
- req := &SearchRequest{
- Query: "benchmark test query",
- Limit: 100,
- Offset: 0,
- SortBy: "score",
- SortOrder: SortOrderDesc,
- IPAddresses: []string{"192.168.1.1", "10.0.0.1"},
- StatusCodes: []int{200, 404, 500},
- Methods: []string{"GET", "POST"},
- }
- b.ResetTimer()
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- _ = cache.GenerateKey(req)
- }
- }
- // New tests to ensure cache key considers LogPaths and is order-insensitive
- func TestCacheKeyIncludesLogPathsAndOrderInsensitive(t *testing.T) {
- cache := NewCache(100)
- defer cache.Close()
- st := int64(1000)
- et := int64(2000)
- reqA := &SearchRequest{
- Query: "q",
- Limit: 10,
- Offset: 0,
- StartTime: &st,
- EndTime: &et,
- UseMainLogPath: true,
- LogPaths: []string{"/var/log/nginx/a.log", "/var/log/nginx/b.log"},
- Methods: []string{"GET"},
- StatusCodes: []int{200, 404},
- }
- reqB := &SearchRequest{
- Query: "q",
- Limit: 10,
- Offset: 0,
- StartTime: &st,
- EndTime: &et,
- UseMainLogPath: true,
- LogPaths: []string{"/var/log/nginx/b.log", "/var/log/nginx/a.log"}, // reversed order
- Methods: []string{"GET"},
- StatusCodes: []int{404, 200}, // different order
- }
- keyA := cache.GenerateKey(reqA)
- keyB := cache.GenerateKey(reqB)
- if keyA != keyB {
- t.Fatalf("expected identical cache keys for order-insensitive params, got A=%s B=%s", keyA, keyB)
- }
- // Different log path should yield different key
- reqC := &SearchRequest{
- Query: "q",
- Limit: 10,
- Offset: 0,
- StartTime: &st,
- EndTime: &et,
- UseMainLogPath: true,
- LogPaths: []string{"/var/log/nginx/a.log"}, // different set
- Methods: []string{"GET"},
- StatusCodes: []int{200, 404},
- }
- keyC := cache.GenerateKey(reqC)
- if keyA == keyC {
- t.Fatalf("expected different cache keys when LogPaths differ, got A=%s C=%s", keyA, keyC)
- }
- }
- func BenchmarkCacheOperations(b *testing.B) {
- cache := NewCache(10000)
- defer cache.Close()
- req := &SearchRequest{
- Query: "benchmark",
- Limit: 50,
- }
- result := &SearchResult{
- TotalHits: 100,
- Hits: []*SearchHit{
- {ID: "doc1", Score: 1.0},
- {ID: "doc2", Score: 0.9},
- },
- }
- b.Run("Put", func(b *testing.B) {
- b.ResetTimer()
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- testReq := &SearchRequest{
- Query: req.Query + string(rune(i%1000)),
- Limit: req.Limit,
- Offset: i,
- }
- cache.Put(testReq, result, 1*time.Minute)
- }
- })
- b.Run("Get", func(b *testing.B) {
- // Pre-populate cache
- cache.Put(req, result, 1*time.Minute)
- b.ResetTimer()
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- _ = cache.Get(req)
- }
- })
- }
|