81 lines
2.8 KiB
Go
81 lines
2.8 KiB
Go
package e2e
|
|
|
|
import (
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.veillax.com/Veillax/blacktip"
|
|
"git.veillax.com/Veillax/reef/model"
|
|
)
|
|
|
|
// Traffic through an edge shows up in Hammerhead's charts, with the client address named.
|
|
func TestTrafficAnalyticsFlow(t *testing.T) {
|
|
w := setup(t, blacktip.TraefikConfig{})
|
|
target := freeRun(t, 1)
|
|
pub := freeRun(t, 1)
|
|
if pub == target {
|
|
pub = freeRun(t, 2) + 1
|
|
}
|
|
tcpOn(t, target)
|
|
var m model.Mapping
|
|
if code, raw := w.admin.do("POST", "/api/orgs/"+w.org+"/mappings", map[string]any{"proto": "tcp", "edgeId": w.edge, "bindIp": "127.0.0.1", "port": pub,
|
|
"targets": tgt(w.local, target), "enabled": true}, &m); code != 200 {
|
|
t.Fatalf("open: %d %s", code, raw)
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
if got := tcpAsk(t, "127.0.0.1:"+strconv.Itoa(pub), "hello"); got == "" {
|
|
t.Fatal("no answer through the edge")
|
|
}
|
|
}
|
|
|
|
type detail struct {
|
|
Total struct{ Conns, BytesIn, BytesOut int64 } `json:"total"`
|
|
Points []struct{ Conns int64 } `json:"points"`
|
|
Sources []struct {
|
|
IP string
|
|
Conns int64
|
|
} `json:"sources"`
|
|
}
|
|
var d detail
|
|
for i := 0; ; i++ { // the edge reports every 20 seconds
|
|
d = detail{}
|
|
if code, _ := w.admin.do("GET", "/api/orgs/"+w.org+"/traffic/"+m.ID+"?range=1h", nil, &d); code == 200 && d.Total.Conns >= 3 {
|
|
break
|
|
}
|
|
if i >= 450 {
|
|
t.Fatal("timed out waiting for the edge to report the traffic")
|
|
}
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
if d.Total.BytesIn < 15 || d.Total.BytesOut == 0 || len(d.Points) != 60 {
|
|
t.Errorf("totals: %+v with %d points", d.Total, len(d.Points))
|
|
}
|
|
if len(d.Sources) != 1 || d.Sources[0].IP != "127.0.0.1" || d.Sources[0].Conns < 3 {
|
|
t.Errorf("sources: %+v", d.Sources)
|
|
}
|
|
|
|
var all detail
|
|
if code, raw := w.admin.do("GET", "/api/orgs/"+w.org+"/traffic/all?range=24h", nil, &all); code != 200 || all.Total.Conns < 3 || len(all.Points) != 24 {
|
|
t.Errorf("organization total: %d %s", code, raw)
|
|
}
|
|
if code, _ := w.admin.do("GET", "/api/orgs/"+w.org+"/traffic/"+m.ID+"?range=5y", nil, nil); code != 400 {
|
|
t.Errorf("bad range: %d", code)
|
|
}
|
|
if code, _ := w.admin.do("GET", "/api/orgs/"+w.org+"/traffic/nope", nil, nil); code != 404 {
|
|
t.Errorf("unknown port: %d", code)
|
|
}
|
|
|
|
alerts := "/api/orgs/" + w.org + "/alerts"
|
|
if code, _ := w.admin.do("PUT", alerts+"/traffic", map[string]any{"spikeFactor": 1}, nil); code != 400 {
|
|
t.Errorf("a spike of 1x was accepted: %d", code)
|
|
}
|
|
if code, raw := w.admin.do("PUT", alerts+"/traffic", map[string]any{"spikeFactor": 5, "dailyMb": 2048}, nil); code != 200 {
|
|
t.Fatalf("save traffic alerts: %d %s", code, raw)
|
|
}
|
|
var ov struct{ Settings map[string]int }
|
|
if code, _ := w.admin.do("GET", alerts, nil, &ov); code != 200 || ov.Settings["spikeFactor"] != 5 || ov.Settings["dailyMb"] != 2048 || ov.Settings["debounceMin"] != 2 {
|
|
t.Errorf("settings after save: %d %+v", code, ov.Settings)
|
|
}
|
|
}
|