package db import ( "testing" ) func TestEngineBasic(t *testing.T) { dir := t.TempDir() e, err := NewEngine(dir) if err != nil { t.Fatalf("Failed to create engine: %v", err) } defer e.Close() e.Set("node1.ip", "192.168.1.1", 100) e.Set("node2.ip", "192.168.1.2", 101) val, ok := e.Get("node1.ip") if !ok || val != "192.168.1.1" { t.Errorf("Expected 192.168.1.1, got %v", val) } val, ok = e.Get("node2.ip") if !ok || val != "192.168.1.2" { t.Errorf("Expected 192.168.1.2, got %v", val) } } func TestEngineQuery(t *testing.T) { dir := t.TempDir() e, err := NewEngine(dir) if err != nil { t.Fatalf("Failed to create engine: %v", err) } defer e.Close() // Seed data e.Set("prod.node1.config", "ver=1.0", 10) e.Set("prod.node2.config", "ver=1.0", 11) e.Set("dev.node1.config", "ver=2.0-beta", 12) e.Set("test.node1.config", "ver=1.0", 13) e.Set("prod.db.config", "host=localhost", 14) tests := []struct { sql string expected int }{ {`key like "prod.*"`, 3}, {`key like "prod.*" and value = "ver=1.0"`, 2}, {`value = "ver=1.0"`, 3}, {`CommitIndex > 11`, 3}, // 12, 13, 14 {`CommitIndex >= 11`, 4}, // 11, 12, 13, 14 {`CommitIndex < 12`, 2}, // 10, 11 {`key like "*.config"`, 5}, {`key = "prod.node1.config"`, 1}, {`key like "prod.*" and CommitIndex > 10`, 2}, // node2(11), db(14) } for i, tt := range tests { res, err := e.Query(tt.sql) if err != nil { t.Errorf("Test %d: Query failed: %v", i, err) continue } if len(res) != tt.expected { t.Errorf("Test %d: Query '%s' expected %d results, got %d. Results: %+v", i, tt.sql, tt.expected, len(res), res) } } } func TestSnapshotRestore(t *testing.T) { dir := t.TempDir() e, err := NewEngine(dir) if err != nil { t.Fatalf("Failed to create engine: %v", err) } // No defer close here, we want to simulate restart e.Set("k1", "v1", 1) e.Set("k2", "v2", 2) data, err := e.Snapshot() if err != nil { t.Fatalf("Snapshot failed: %v", err) } e.Close() // Create new engine pointing to same dir (simulating restart/restore) e2, err := NewEngine(dir) if err != nil { t.Fatalf("Failed to open engine: %v", err) } defer e2.Close() if err := e2.Restore(data); err != nil { t.Fatalf("Restore failed: %v", err) } val, ok := e2.Get("k1") if !ok || val != "v1" { t.Errorf("Restored k1 wrong: %v", val) } val, ok = e2.Get("k2") if !ok || val != "v2" { t.Errorf("Restored k2 wrong: %v", val) } } func TestWildcardMatch(t *testing.T) { tests := []struct { str, pat string match bool }{ {"abc", "abc", true}, {"abc", "a*", true}, {"abc", "*c", true}, {"abc", "a*c", true}, {"abc", "ab?", true}, {"abc", "abd", false}, {"prod.node1.config", "prod.*", true}, } for _, tt := range tests { if got := WildcardMatch(tt.str, tt.pat); got != tt.match { t.Errorf("Match(%q, %q) = %v; want %v", tt.str, tt.pat, got, tt.match) } } }