Files
im_server/loadtest/im-pressure/model_test.go
T

145 lines
5.4 KiB
Go

package main
import (
"os"
"path/filepath"
"reflect"
"testing"
)
func TestLoadConfigAppliesBoundedHistoryDefaults(t *testing.T) {
path := filepath.Join(t.TempDir(), "config.json")
raw := []byte(`{"http_base":"https://example.test","endpoints":{"a":["wss://a"],"b":["wss://b"]}}`)
if err := os.WriteFile(path, raw, 0o600); err != nil {
t.Fatal(err)
}
cfg, err := loadConfig(path)
if err != nil {
t.Fatal(err)
}
if cfg.HistoryWorkers != 12 || cfg.HistoryPageSize != 10 || cfg.HistoryInterval != "500ms" ||
cfg.HistoryPageWait != "3s" || cfg.CloseRamp != "10s" ||
cfg.HistorySettle != "5m" || cfg.HistoryTimeout != "3m" ||
cfg.PreflightWorkers != 32 || cfg.WSPingInterval != "20s" {
t.Fatalf("unexpected defaults: %+v", cfg)
}
}
func TestAssignAgentEndpointsDistributesDialIPsAcrossMachines(t *testing.T) {
cfg := &Config{
Endpoints: map[string][]string{"a": {"wss://api.example.test/ws"}, "b": {"wss://api.example.test/ws"}},
DialIPs: map[string][]string{"a": {"192.0.2.1", "192.0.2.2", "192.0.2.3"}, "b": {"192.0.2.1", "192.0.2.2", "192.0.2.3"}},
}
a := []AccountRecord{{Index: 1}, {Index: 2}, {Index: 3}}
b := []AccountRecord{{Index: 1}, {Index: 2}, {Index: 3}}
assignAgentEndpoints(cfg, "a", a)
assignAgentEndpoints(cfg, "b", b)
got := []string{a[0].DialIP, b[0].DialIP, a[1].DialIP, b[1].DialIP, a[2].DialIP, b[2].DialIP}
want := []string{"192.0.2.1", "192.0.2.2", "192.0.2.3", "192.0.2.1", "192.0.2.2", "192.0.2.3"}
if !reflect.DeepEqual(got, want) {
t.Fatalf("unexpected dial IP distribution: got=%v want=%v", got, want)
}
}
func TestLoadConfigRejectsInvalidDialIP(t *testing.T) {
path := filepath.Join(t.TempDir(), "config.json")
raw := []byte(`{"http_base":"https://example.test","endpoints":{"a":["wss://a"],"b":["wss://b"]},"dial_ips":{"a":["not-an-ip"]}}`)
if err := os.WriteFile(path, raw, 0o600); err != nil {
t.Fatal(err)
}
if _, err := loadConfig(path); err == nil {
t.Fatal("invalid dial IP was accepted")
}
}
func TestSingleMachineExampleUsesSixtyPercentCapacity(t *testing.T) {
cfg, err := loadConfig("config.single-machine.example.json")
if err != nil {
t.Fatal(err)
}
if cfg.UsersPerMachine != 600 || cfg.CloseRamp != "60s" {
t.Fatalf("unexpected single-machine capacity: users=%d close_ramp=%s", cfg.UsersPerMachine, cfg.CloseRamp)
}
if len(cfg.Endpoints["a"]) != 1 || len(cfg.Endpoints["b"]) != 1 {
t.Fatalf("single-machine endpoints must define both logical agents: %+v", cfg.Endpoints)
}
}
func TestNewManifestDistributesUsersAndEndpoints(t *testing.T) {
cfg := &Config{Tenant: "006", UsersPerMachine: 3, Endpoints: map[string][]string{
"a": {"ws://a1", "ws://a2"}, "b": {"ws://b1"},
}}
manifest := newManifest(cfg)
if len(manifest.Accounts) != 6 {
t.Fatalf("accounts=%d", len(manifest.Accounts))
}
if got := accountsForMachine(manifest, "a"); got[0].Username != "lta0001" || got[1].Endpoint != "ws://a2" || got[2].Endpoint != "ws://a1" {
t.Fatalf("unexpected A accounts: %+v", got)
}
if err := manifest.validate(); err != nil {
t.Fatal(err)
}
}
func TestManifestRejectsDuplicateAccount(t *testing.T) {
manifest := &Manifest{Version: manifestVersion, Accounts: []AccountRecord{
{Machine: "a", Index: 1, Username: "lta0001"},
{Machine: "a", Index: 1, Username: "duplicate"},
}}
if err := manifest.validate(); err == nil {
t.Fatal("expected duplicate account validation error")
}
}
func TestApplyConfigEndpointsRefreshesManifest(t *testing.T) {
cfg := &Config{Tenant: "006", UsersPerMachine: 1, Endpoints: map[string][]string{
"a": {"ws://new-a"}, "b": {"ws://new-b"},
}}
manifest := &Manifest{Tenant: "006", Accounts: []AccountRecord{
{Machine: "a", Index: 1, Username: "lta0001", Endpoint: "ws://old"},
{Machine: "b", Index: 1, Username: "ltb0001", Endpoint: "ws://old"},
}}
if err := applyConfigEndpoints(cfg, manifest); err != nil {
t.Fatal(err)
}
if manifest.Accounts[0].Endpoint != "ws://new-a" || manifest.Accounts[1].Endpoint != "ws://new-b" {
t.Fatalf("endpoints were not refreshed: %+v", manifest.Accounts)
}
}
func TestRegistrationPhoneUsesDistinctMachineRanges(t *testing.T) {
cfg := &Config{UsersPerMachine: 1000, PhonePrefix: "1990927"}
a, err := registrationPhone(cfg, "a", 1)
if err != nil || a != "19909270001" {
t.Fatalf("machine A phone=%q err=%v", a, err)
}
b, err := registrationPhone(cfg, "b", 1)
if err != nil || b != "19909275001" {
t.Fatalf("machine B phone=%q err=%v", b, err)
}
last, err := registrationPhone(cfg, "b", 1000)
if err != nil || last != "19909276000" {
t.Fatalf("last phone=%q err=%v", last, err)
}
}
func TestReconcileManifestExpandsSmokeRun(t *testing.T) {
existing := &Manifest{Version: manifestVersion, Tenant: "allrich", GroupTopic: "grp-one", Accounts: []AccountRecord{
{Machine: "a", Index: 1, Username: "lta0001", UserID: "usr-a", Token: "token-a", P2PTopic: "p2p-one"},
{Machine: "b", Index: 1, Username: "ltb0001", UserID: "usr-b", Token: "token-b", P2PTopic: "p2p-one"},
}}
cfg := &Config{Tenant: "allrich", UsersPerMachine: 2, PhonePrefix: "1990927", Endpoints: map[string][]string{
"a": {"wss://a"}, "b": {"wss://b"},
}}
expanded, err := reconcileManifest(cfg, existing)
if err != nil {
t.Fatal(err)
}
if len(expanded.Accounts) != 4 || expanded.GroupTopic != "grp-one" || expanded.Accounts[0].Token != "token-a" {
t.Fatalf("unexpected expanded manifest: %+v", expanded)
}
if expanded.Accounts[3].Phone != "19909275002" {
t.Fatalf("machine B phone=%q", expanded.Accounts[3].Phone)
}
}