package main import ( "fmt" "testing" "time" ) func TestTrafficHistoryFullPaginationAndSnapshot(t *testing.T) { s, a := trafficFixture(t) if _, err := s.SaveTrafficSettings(TrafficSettings{Enabled: true, AgentID: a.ID}); err != nil { t.Fatal(err) } now := time.Now().Unix() batch := TrafficBatch{} for i := 0; i < 137; i++ { batch.Events = append(batch.Events, TrafficEvent{ID: fmt.Sprint(i), Time: now - 60, Kind: "request", IP: "8.8.8.8", Domain: "example.test"}) } batch.Events = append(batch.Events, TrafficEvent{ID: "old-alert", Time: now - 3600, Kind: "alert", IP: "1.1.1.1", Domain: "other.test"}) if err := s.SaveTraffic(a.ID, batch); err != nil { t.Fatal(err) } first, err := s.TrafficHistory("", "request", "", "", "", false, false, false, 0, now, 0) if err != nil || first.Total != 137 || len(first.Events) != 50 { t.Fatalf("first: %+v %v", first, err) } if err := s.SaveTraffic(a.ID, TrafficBatch{Events: []TrafficEvent{{ID: "new", Time: now - 60, Kind: "request", IP: "8.8.8.8"}}}); err != nil { t.Fatal(err) } seen := map[int64]bool{} for page := 0; page < 3; page++ { h, err := s.TrafficHistory("", "request", "", "", "", false, false, false, page, first.Snapshot, first.MaxSequence) if err != nil || h.Total != 137 { t.Fatalf("page %d: %v total %d", page, err, h.Total) } for _, e := range h.Events { if seen[e.Sequence] { t.Fatal("duplicate page event") } seen[e.Sequence] = true } } if len(seen) != 137 { t.Fatalf("missing history: %d", len(seen)) } h, err := s.TrafficHistory("other.test", "alert", "", "", "", false, false, false, 0, now, 0) if err != nil || h.Total != 1 || h.Events[0].ID != "old-alert" { t.Fatalf("old alert missing: %+v %v", h, err) } h, err = s.TrafficHistory("", "alert", "", "", "request", false, false, false, 0, now, 0) if err != nil || h.Total != 0 { t.Fatal("metric must respect global kind filter") } h, err = s.TrafficHistory("example.test", "", "", "", "", false, false, true, 0, now, 0) if err != nil || h.Total != 1 || len(h.IPs) != 1 || h.IPs[0].Requests != 137 { t.Fatalf("IP summary %+v %v", h, err) } h, err = s.TrafficHistory("", "", "ZZ", "", "", false, false, false, 0, now, 0) if err != nil || h.Total != 0 { t.Fatal("country filter ignored") } h, err = s.TrafficHistory("", "", "", "1.1.1.1", "", false, false, false, 0, now, 0) if err != nil || h.Total != 1 { t.Fatal("IP filter ignored") } } func TestCityNamesAndLocalAddresses(t *testing.T) { if cityName(map[string]string{"ru": "Москва", "en": "Moscow"}) != "Москва" || cityName(map[string]string{"en": "Amsterdam"}) != "Amsterdam" { t.Fatal("city localization") } for _, ip := range []string{"192.168.0.10", "127.0.0.1", "::1", "fe80::1", "invalid"} { c, r := lookupTrafficCity(ip) if c != "" || r != "" { t.Fatal("local IP geolocated") } } } func TestTrafficHistoryMonitoringAndAgentIsolation(t *testing.T) { s, a := trafficFixture(t) s.SaveTrafficSettings(TrafficSettings{Enabled: true, AgentID: a.ID, MonitoringRules: []MonitoringRule{{IP: "192.168.0.10"}}}) now := time.Now().Unix() batch := TrafficBatch{Events: []TrafficEvent{{ID: "check", Time: now, Kind: "request", IP: "192.168.0.10"}, {ID: "alert", Time: now, Kind: "alert", IP: "192.168.0.10"}, {ID: "public", Time: now, Kind: "request", IP: "8.8.8.8"}}} if err := s.SaveTraffic(a.ID, batch); err != nil { t.Fatal(err) } token, _ := s.CreateAgentEnrollmentToken() other, err := s.EnrollAgent(agentEnrollmentRequest{Token: token, Name: "other", VMID: 103}) if err != nil { t.Fatal(err) } if err = s.SaveTraffic(other.ID, batch); err != nil { t.Fatal(err) } for _, tc := range []struct { external, hide bool want int64 }{{false, false, 3}, {false, true, 2}, {true, false, 1}, {true, true, 1}} { h, err := s.TrafficHistory("", "", "", "", "", tc.external, tc.hide, false, 0, now, 0) if err != nil || h.Total != tc.want { t.Fatalf("filters %+v total=%d err=%v", tc, h.Total, err) } for _, e := range h.Events { if e.Agent != a.ID { t.Fatal("foreign agent leaked") } } } }