110 lines
3.7 KiB
Go
110 lines
3.7 KiB
Go
package main
|
|
|
|
// Benchmarks for round-3 item 22 (per-request full-clone cost). Not run
|
|
// by `go test` without -bench. The seed is synthetic data at the scale
|
|
// fixed for this round's acceptance: 20 servers / 40 customers /
|
|
// 40 nodes / ~160 bindings (20-agent steady-state tests use the same
|
|
// scale).
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http/httptest"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func perfSeedData() *Data {
|
|
d := EmptyData()
|
|
d.Users = []*User{{ID: "usr_1", Username: "admin", PasswordHash: "x", Role: "owner", Status: "active", CreatedAt: NowISO()}}
|
|
for i := 0; i < 20; i++ {
|
|
d.Servers = append(d.Servers, &Server{
|
|
ID: fmt.Sprintf("srv_%d", i), Name: fmt.Sprintf("S%d", i), PublicAddress: "203.0.113.1",
|
|
Status: "online", LastSeenAt: StrPtr(NowISO()), PortRangeStart: 20000, PortRangeEnd: 50000,
|
|
Labels: []string{}, CreatedAt: NowISO(), UpdatedAt: NowISO(),
|
|
})
|
|
}
|
|
for i := 0; i < 40; i++ {
|
|
d.Customers = append(d.Customers, &Customer{
|
|
ID: fmt.Sprintf("cus_%d", i), Name: fmt.Sprintf("C%d", i), Status: "active",
|
|
SubscriptionToken: fmt.Sprintf("tok-%032d", i),
|
|
Credentials: &Credentials{ClientID: NewUUID(), RelayPassword: "FRYXGBkaGxwdHh8gISIjJA==", ShortID: "abcd0001"},
|
|
Tags: []string{}, CreatedAt: NowISO(), UpdatedAt: NowISO(),
|
|
})
|
|
}
|
|
protocols := []string{"vless-reality-vision", "shadowsocks-2022-aes128", "socks5-auth", "vless-ws", "hysteria2"}
|
|
for i := 0; i < 40; i++ {
|
|
node := &Node{
|
|
ID: fmt.Sprintf("nod_%d", i), Name: fmt.Sprintf("N%d", i), ServerID: fmt.Sprintf("srv_%d", i%20),
|
|
Protocol: protocols[i%len(protocols)], Topology: "direct", NetworkMode: "ipv4", Port: 23000 + i,
|
|
Status: "active", ResourceID: fmt.Sprintf("res_%d", i), Artifacts: map[string]json.RawMessage{},
|
|
}
|
|
if node.Protocol == "socks5-auth" {
|
|
node.SocksUser, node.SocksPassword = "ngs_fixed", "fixedpass"
|
|
}
|
|
if IsRealityProtocol(node.Protocol) {
|
|
node.Reality = &RealityConfig{KeyID: fmt.Sprintf("reality-nod_%d", i), ServerName: "www.tesla.com", DestPort: 443}
|
|
}
|
|
d.Nodes = append(d.Nodes, node)
|
|
for j := 0; j < 4; j++ {
|
|
d.NodeClients = append(d.NodeClients, &NodeClient{
|
|
ID: fmt.Sprintf("nc_%d_%d", i, j), NodeID: node.ID,
|
|
CustomerID: fmt.Sprintf("cus_%d", (i+j)%40), Status: "active",
|
|
CreatedAt: NowISO(), UpdatedAt: NowISO(),
|
|
})
|
|
}
|
|
}
|
|
return d
|
|
}
|
|
|
|
func BenchmarkCloneJSONRoundTrip(b *testing.B) {
|
|
d := perfSeedData()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = d.cloneViaJSON()
|
|
}
|
|
}
|
|
|
|
func BenchmarkCloneFast(b *testing.B) {
|
|
d := perfSeedData()
|
|
b.ReportAllocs()
|
|
for i := 0; i < b.N; i++ {
|
|
_ = d.Clone()
|
|
}
|
|
}
|
|
|
|
func BenchmarkAdminGET(b *testing.B) {
|
|
cookieSecure = false
|
|
store := NewStore(filepath.Join(b.TempDir(), "nexusgate.json"))
|
|
if err := store.Init(); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
seed := perfSeedData()
|
|
seed.Users[0].PasswordHash = HashSecret("password12345")
|
|
if _, err := store.Transaction(func(d *Data) (any, error) { *d = *seed; return nil, nil }); err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
app := NewApp(store, NewSessionManager(12), NewOrchestrator(store))
|
|
login := httptest.NewRequest("POST", "/api/auth/login", strings.NewReader(`{"username":"admin","password":"password12345"}`))
|
|
rec := httptest.NewRecorder()
|
|
app.ServeHTTP(rec, login)
|
|
if rec.Code != 200 {
|
|
b.Fatalf("login %d", rec.Code)
|
|
}
|
|
cookie := strings.Split(rec.Header().Get("Set-Cookie"), ";")[0]
|
|
for _, path := range []string{"/api/overview", "/api/servers", "/api/customers", "/api/nodes", "/api/jobs"} {
|
|
b.Run(strings.TrimPrefix(path, "/api/"), func(b *testing.B) {
|
|
for i := 0; i < b.N; i++ {
|
|
req := httptest.NewRequest("GET", path, nil)
|
|
req.Header.Set("Cookie", cookie)
|
|
rec := httptest.NewRecorder()
|
|
app.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
b.Fatalf("%s -> %d", path, rec.Code)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|