mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-01 22:46:38 +08:00
16bb9e5879
- Implemented TrendChart component for visualizing traffic and capacity trends. - Enhanced DashboardOverview and NodeDetailPage components to display 24-hour request and capacity trends. - Updated types to include traffic and capacity trend data structures. - Created observability trends service to aggregate traffic and capacity data. - Added tests for traffic report generation and trend data handling. - Introduced new dependencies for charting (echarts and echarts-for-react).
78 lines
3.0 KiB
Go
78 lines
3.0 KiB
Go
package observability
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"atsflare-agent/internal/config"
|
|
"atsflare-agent/internal/state"
|
|
)
|
|
|
|
func TestBuildTrafficReportAggregatesManagedAccessLog(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
routeConfigPath := filepath.Join(tempDir, "conf.d", "atsflare_routes.conf")
|
|
if err := os.MkdirAll(filepath.Dir(routeConfigPath), 0o755); err != nil {
|
|
t.Fatalf("MkdirAll failed: %v", err)
|
|
}
|
|
logPath := filepath.Join(filepath.Dir(routeConfigPath), "atsflare_access.log")
|
|
content := []byte(
|
|
"{\"ts\":\"2026-03-14T08:00:00Z\",\"host\":\"app.example.com\",\"remote_addr\":\"10.0.0.1\",\"status\":200}\n" +
|
|
"{\"ts\":\"2026-03-14T08:00:05Z\",\"host\":\"app.example.com\",\"remote_addr\":\"10.0.0.2\",\"status\":503}\n" +
|
|
"{\"ts\":\"2026-03-14T08:00:08Z\",\"host\":\"api.example.com\",\"remote_addr\":\"10.0.0.1\",\"status\":200}\n",
|
|
)
|
|
if err := os.WriteFile(logPath, content, 0o644); err != nil {
|
|
t.Fatalf("WriteFile failed: %v", err)
|
|
}
|
|
|
|
stateStore := state.NewStore(filepath.Join(tempDir, "state.json"))
|
|
report := BuildTrafficReport(&config.Config{RouteConfigPath: routeConfigPath}, stateStore)
|
|
if report == nil {
|
|
t.Fatal("expected traffic report")
|
|
}
|
|
if report.RequestCount != 3 || report.ErrorCount != 1 || report.UniqueVisitorCount != 2 {
|
|
t.Fatalf("unexpected traffic report counters: %+v", report)
|
|
}
|
|
if report.StatusCodes["200"] != 2 || report.StatusCodes["503"] != 1 {
|
|
t.Fatalf("unexpected status codes: %+v", report.StatusCodes)
|
|
}
|
|
if report.TopDomains["app.example.com"] != 2 || report.TopDomains["api.example.com"] != 1 {
|
|
t.Fatalf("unexpected top domains: %+v", report.TopDomains)
|
|
}
|
|
|
|
snapshot, err := stateStore.Load()
|
|
if err != nil {
|
|
t.Fatalf("Load failed: %v", err)
|
|
}
|
|
if snapshot.AccessLogOffset != int64(len(content)) {
|
|
t.Fatalf("unexpected access log offset: %d", snapshot.AccessLogOffset)
|
|
}
|
|
|
|
secondReport := BuildTrafficReport(&config.Config{RouteConfigPath: routeConfigPath}, stateStore)
|
|
if secondReport != nil {
|
|
t.Fatalf("expected no report without appended lines, got %+v", secondReport)
|
|
}
|
|
}
|
|
|
|
func TestBuildTrafficReportResetsOffsetAfterTruncate(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
routeConfigPath := filepath.Join(tempDir, "conf.d", "atsflare_routes.conf")
|
|
if err := os.MkdirAll(filepath.Dir(routeConfigPath), 0o755); err != nil {
|
|
t.Fatalf("MkdirAll failed: %v", err)
|
|
}
|
|
logPath := filepath.Join(filepath.Dir(routeConfigPath), "atsflare_access.log")
|
|
if err := os.WriteFile(logPath, []byte("{\"ts\":\"2026-03-14T09:00:00Z\",\"host\":\"app.example.com\",\"remote_addr\":\"10.0.0.3\",\"status\":200}\n"), 0o644); err != nil {
|
|
t.Fatalf("WriteFile failed: %v", err)
|
|
}
|
|
|
|
stateStore := state.NewStore(filepath.Join(tempDir, "state.json"))
|
|
if err := stateStore.Save(&state.Snapshot{AccessLogOffset: 4096}); err != nil {
|
|
t.Fatalf("Save failed: %v", err)
|
|
}
|
|
|
|
report := BuildTrafficReport(&config.Config{RouteConfigPath: routeConfigPath}, stateStore)
|
|
if report == nil || report.RequestCount != 1 {
|
|
t.Fatalf("expected one request after truncate reset, got %+v", report)
|
|
}
|
|
}
|