package storage import ( "context" "encoding/json" "os" "testing" "git.tornberg.me/go-otel/internal/websocket" ) func TestFileStore(t *testing.T) { filename := "test-otel.log" defer func() { _ = os.Remove(filename) }() fs := NewFileStore(filename) ctx := context.Background() entry1 := websocket.HistoryEntry{ Type: "logs", Timestamp: 100, Data: json.RawMessage(`{"msg":"hello world"}`), } entry2 := websocket.HistoryEntry{ Type: "traces", Timestamp: 200, Data: json.RawMessage(`{"msg":"trace event"}`), } if err := fs.Append(ctx, entry1); err != nil { t.Fatalf("failed to append entry1: %v", err) } if err := fs.Append(ctx, entry2); err != nil { t.Fatalf("failed to append entry2: %v", err) } // Test GetHistory (limit 1) history, err := fs.GetHistory(ctx, 1) if err != nil { t.Fatalf("GetHistory failed: %v", err) } if len(history) != 1 { t.Errorf("expected 1 entry, got %d", len(history)) } // Should be latest entry if history[0].Type != "traces" { t.Errorf("expected latest entry type 'traces', got %s", history[0].Type) } // Test Search results, err := fs.Search(ctx, SearchOptions{Query: "hello"}, 10) if err != nil { t.Fatalf("Search failed: %v", err) } if len(results) != 1 { t.Errorf("expected 1 result for search 'hello', got %d", len(results)) } // Check content of result data, _ := json.Marshal(results[0].Data) if string(data) != `{"msg":"hello world"}` { t.Errorf("unexpected data content: %s", string(data)) } } func TestFileStoreSearchFilters(t *testing.T) { filename := "test-otel-filters.log" defer func() { _ = os.Remove(filename) }() fs := NewFileStore(filename) ctx := context.Background() entries := []websocket.HistoryEntry{ {Type: "logs", Timestamp: 100, Data: json.RawMessage(`{"msg":"first log"}`)}, {Type: "traces", Timestamp: 200, Data: json.RawMessage(`{"msg":"a trace"}`)}, {Type: "logs", Timestamp: 300, Data: json.RawMessage(`{"msg":"second log"}`)}, } for _, e := range entries { if err := fs.Append(ctx, e); err != nil { t.Fatalf("failed to append entry: %v", err) } } // Filter by type only results, err := fs.Search(ctx, SearchOptions{Type: "logs"}, 10) if err != nil { t.Fatalf("Search failed: %v", err) } if len(results) != 2 { t.Fatalf("expected 2 log entries, got %d", len(results)) } for _, r := range results { if r.Type != "logs" { t.Errorf("expected type 'logs', got %s", r.Type) } } // Filter by time range: only the entry at Timestamp=200 should match results, err = fs.Search(ctx, SearchOptions{Since: 150, Until: 250}, 10) if err != nil { t.Fatalf("Search failed: %v", err) } if len(results) != 1 || results[0].Timestamp != 200 { t.Fatalf("expected single entry at timestamp 200, got %+v", results) } // Combine type and query filters results, err = fs.Search(ctx, SearchOptions{Type: "logs", Query: "second"}, 10) if err != nil { t.Fatalf("Search failed: %v", err) } if len(results) != 1 || results[0].Timestamp != 300 { t.Fatalf("expected single entry at timestamp 300, got %+v", results) } }