123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- package indexer
- import (
- "fmt"
- "testing"
- "time"
- )
- func TestPersistenceManager_Creation(t *testing.T) {
- // Test default config
- pm := NewPersistenceManager(nil)
- if pm == nil {
- t.Fatal("Expected non-nil persistence manager")
- }
-
- if pm.maxBatchSize != 1000 {
- t.Errorf("Expected default batch size 1000, got %d", pm.maxBatchSize)
- }
-
- if pm.flushInterval != 30*time.Second {
- t.Errorf("Expected default flush interval 30s, got %v", pm.flushInterval)
- }
-
- // Test custom config
- config := &IncrementalIndexConfig{
- MaxBatchSize: 500,
- FlushInterval: 15 * time.Second,
- CheckInterval: 2 * time.Minute,
- MaxAge: 7 * 24 * time.Hour,
- }
-
- pm2 := NewPersistenceManager(config)
- if pm2.maxBatchSize != 500 {
- t.Errorf("Expected custom batch size 500, got %d", pm2.maxBatchSize)
- }
-
- if pm2.flushInterval != 15*time.Second {
- t.Errorf("Expected custom flush interval 15s, got %v", pm2.flushInterval)
- }
- }
- func TestIncrementalIndexConfig_Default(t *testing.T) {
- config := DefaultIncrementalConfig()
-
- if config.MaxBatchSize != 1000 {
- t.Errorf("Expected default MaxBatchSize 1000, got %d", config.MaxBatchSize)
- }
-
- if config.FlushInterval != 30*time.Second {
- t.Errorf("Expected default FlushInterval 30s, got %v", config.FlushInterval)
- }
-
- if config.CheckInterval != 5*time.Minute {
- t.Errorf("Expected default CheckInterval 5m, got %v", config.CheckInterval)
- }
-
- if config.MaxAge != 30*24*time.Hour {
- t.Errorf("Expected default MaxAge 30 days, got %v", config.MaxAge)
- }
- }
- func TestGetMainLogPathFromFile(t *testing.T) {
- testCases := []struct {
- input string
- expected string
- }{
- {"/var/log/nginx/access.log", "/var/log/nginx/access.log"},
- {"/var/log/nginx/access.log.1", "/var/log/nginx/access.log"},
- {"/var/log/nginx/access.log.2.gz", "/var/log/nginx/access.log"},
- {"/var/log/nginx/access.1.log", "/var/log/nginx/access.log"},
- {"/var/log/nginx/access.2.log.gz", "/var/log/nginx/access.log"},
- {"/var/log/nginx/access.3.log.bz2", "/var/log/nginx/access.log"},
- {"/var/log/nginx/error.log.10", "/var/log/nginx/error.log"},
- {"/var/log/nginx/error.1.log.xz", "/var/log/nginx/error.log"},
- {"/var/log/nginx/access.log.20231201", "/var/log/nginx/access.log"},
- {"/var/log/nginx/access.log.2023-12-01", "/var/log/nginx/access.log"},
- {"/var/log/nginx/custom.log.99", "/var/log/nginx/custom.log"},
- {"/logs/app.5.log.lz4", "/logs/app.log"},
- }
-
- for _, tc := range testCases {
- result := getMainLogPathFromFile(tc.input)
- if result != tc.expected {
- t.Errorf("getMainLogPathFromFile(%s) = %s, expected %s", tc.input, result, tc.expected)
- }
- }
- }
- func TestIsDatePattern(t *testing.T) {
- testCases := []struct {
- input string
- expected bool
- }{
- {"20231201", true}, // YYYYMMDD
- {"2023-12-01", true}, // YYYY-MM-DD
- {"2023.12.01", true}, // YYYY.MM.DD
- {"231201", true}, // YYMMDD
- {"access", false}, // Not a date
- {"123", false}, // Too short
- {"12345678901", false}, // Too long
- {"2023-13-01", true}, // Would match pattern (validation not checked)
- {"log", false}, // Text
- {"1", false}, // Single digit
- }
-
- for _, tc := range testCases {
- result := isDatePattern(tc.input)
- if result != tc.expected {
- t.Errorf("isDatePattern(%s) = %v, expected %v", tc.input, result, tc.expected)
- }
- }
- }
- func TestLogFileInfo_Structure(t *testing.T) {
- // Test LogFileInfo struct initialization
- info := &LogFileInfo{
- Path: "/var/log/nginx/access.log",
- LastModified: time.Now().Unix(),
- LastSize: 1024,
- LastIndexed: time.Now().Unix(),
- LastPosition: 512,
- }
-
- if info.Path != "/var/log/nginx/access.log" {
- t.Errorf("Expected path to be set correctly")
- }
-
- if info.LastSize != 1024 {
- t.Errorf("Expected LastSize 1024, got %d", info.LastSize)
- }
-
- if info.LastPosition != 512 {
- t.Errorf("Expected LastPosition 512, got %d", info.LastPosition)
- }
-
- // Checksum field removed from LogFileInfo
- }
- // Mock tests (without database dependency)
- func TestPersistenceManager_CacheOperations(t *testing.T) {
- pm := NewPersistenceManager(nil)
-
- // Test initial cache state
- if len(pm.enabledPaths) != 0 {
- t.Errorf("Expected empty cache initially, got %d entries", len(pm.enabledPaths))
- }
-
- // Simulate cache operations
- pm.enabledPaths["/test/path1"] = true
- pm.enabledPaths["/test/path2"] = false
-
- if len(pm.enabledPaths) != 2 {
- t.Errorf("Expected 2 cache entries, got %d", len(pm.enabledPaths))
- }
-
- // Test RefreshCache method preparation (would need database in real scenario)
- pm.enabledPaths = make(map[string]bool)
- if len(pm.enabledPaths) != 0 {
- t.Errorf("Expected cache to be cleared")
- }
- }
- func TestPersistenceManager_ConfigValidation(t *testing.T) {
- // Test with various configurations
- configs := []*IncrementalIndexConfig{
- {
- MaxBatchSize: 100,
- FlushInterval: 5 * time.Second,
- CheckInterval: 1 * time.Minute,
- MaxAge: 1 * time.Hour,
- },
- {
- MaxBatchSize: 10000,
- FlushInterval: 5 * time.Minute,
- CheckInterval: 30 * time.Minute,
- MaxAge: 90 * 24 * time.Hour,
- },
- }
-
- for i, config := range configs {
- pm := NewPersistenceManager(config)
- if pm.maxBatchSize != config.MaxBatchSize {
- t.Errorf("Config %d: Expected MaxBatchSize %d, got %d", i, config.MaxBatchSize, pm.maxBatchSize)
- }
-
- if pm.flushInterval != config.FlushInterval {
- t.Errorf("Config %d: Expected FlushInterval %v, got %v", i, config.FlushInterval, pm.flushInterval)
- }
- }
- }
- func TestGetMainLogPathFromFile_EdgeCases(t *testing.T) {
- edgeCases := []struct {
- input string
- expected string
- description string
- }{
- {
- "/var/log/nginx/access.999.log.gz",
- "/var/log/nginx/access.log",
- "High rotation number with compression",
- },
- {
- "/var/log/nginx/access.log.2023.12.01.gz",
- "/var/log/nginx/access.log",
- "Date-based rotation with compression",
- },
- {
- "/single/file.log",
- "/single/file.log",
- "No rotation pattern",
- },
- {
- "/path/with.dots.in.name.log.1",
- "/path/with.dots.in.name.log",
- "Multiple dots in filename",
- },
- {
- "/var/log/nginx/access.log.1000",
- "/var/log/nginx/access.log.1000",
- "Number too high for rotation (should not match)",
- },
- }
-
- for _, tc := range edgeCases {
- result := getMainLogPathFromFile(tc.input)
- if result != tc.expected {
- t.Errorf("%s: getMainLogPathFromFile(%s) = %s, expected %s",
- tc.description, tc.input, result, tc.expected)
- }
- }
- }
- func TestPersistenceManager_Close(t *testing.T) {
- pm := NewPersistenceManager(nil)
-
- // Add some cache entries
- pm.enabledPaths["/test/path1"] = true
- pm.enabledPaths["/test/path2"] = false
-
- // Close should clean up
- err := pm.Close()
- if err != nil {
- t.Errorf("Expected no error on close, got %v", err)
- }
-
- // Cache should be cleared
- if pm.enabledPaths != nil {
- t.Errorf("Expected cache to be nil after close")
- }
- }
- // Benchmark tests for performance validation
- func BenchmarkGetMainLogPathFromFile(b *testing.B) {
- testPaths := []string{
- "/var/log/nginx/access.log",
- "/var/log/nginx/access.log.1",
- "/var/log/nginx/access.log.2.gz",
- "/var/log/nginx/access.1.log",
- "/var/log/nginx/access.2.log.gz",
- "/var/log/nginx/error.log.20231201",
- }
-
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- path := testPaths[i%len(testPaths)]
- _ = getMainLogPathFromFile(path)
- }
- }
- func BenchmarkIsDatePattern(b *testing.B) {
- testStrings := []string{
- "20231201",
- "2023-12-01",
- "access",
- "log",
- "231201",
- "notadate",
- }
-
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- s := testStrings[i%len(testStrings)]
- _ = isDatePattern(s)
- }
- }
- func BenchmarkPersistenceManager_CacheAccess(b *testing.B) {
- pm := NewPersistenceManager(nil)
-
- // Populate cache
- for i := 0; i < 1000; i++ {
- pm.enabledPaths[fmt.Sprintf("/path/file%d.log", i)] = i%2 == 0
- }
-
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- path := fmt.Sprintf("/path/file%d.log", i%1000)
- _ = pm.enabledPaths[path]
- }
- }
|