xray_config_scale_test.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package service
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "testing"
  6. "time"
  7. "github.com/mhsanaei/3x-ui/v3/internal/database"
  8. "github.com/mhsanaei/3x-ui/v3/internal/database/model"
  9. )
  10. // TestGetXrayConfigScale measures building the full Xray config (the path
  11. // every restart/reconcile takes) and, separately, how much of the per-inbound
  12. // settings rebuild is spent on indented vs plain JSON marshaling.
  13. func TestGetXrayConfigScale(t *testing.T) {
  14. setupScaleDB(t)
  15. svc := &XrayService{}
  16. shapes := []struct {
  17. name string
  18. inbounds int
  19. }{{"single", 1}, {"spread50", 50}}
  20. for _, n := range scaleSizes(t, 10000, 100000) {
  21. for _, shape := range shapes {
  22. t.Run(fmt.Sprintf("N=%d_%s", n, shape.name), func(t *testing.T) {
  23. ds := seedScaleDataset(t, n, shape.inbounds)
  24. const reps = 3
  25. start := time.Now()
  26. for range reps {
  27. cfg, err := svc.GetXrayConfig()
  28. if err != nil {
  29. t.Fatalf("GetXrayConfig: %v", err)
  30. }
  31. if len(cfg.InboundConfigs) < shape.inbounds {
  32. t.Fatalf("config has %d inbounds, want >= %d", len(cfg.InboundConfigs), shape.inbounds)
  33. }
  34. }
  35. t.Logf("N=%-7d shape=%-8s GetXrayConfig=%v/run",
  36. n, shape.name, (time.Since(start) / reps).Round(time.Millisecond))
  37. var ib model.Inbound
  38. if err := database.GetDB().First(&ib, ds.inboundIds[0]).Error; err != nil {
  39. t.Fatalf("load inbound: %v", err)
  40. }
  41. settings := map[string]any{}
  42. if err := json.Unmarshal([]byte(ib.Settings), &settings); err != nil {
  43. t.Fatalf("unmarshal settings: %v", err)
  44. }
  45. start = time.Now()
  46. if _, err := json.Marshal(settings); err != nil {
  47. t.Fatalf("marshal settings: %v", err)
  48. }
  49. plain := time.Since(start)
  50. start = time.Now()
  51. if _, err := json.MarshalIndent(settings, "", " "); err != nil {
  52. t.Fatalf("marshal indent settings: %v", err)
  53. }
  54. indented := time.Since(start)
  55. t.Logf("N=%-7d shape=%-8s settingsMarshal plain=%-9v indent=%v",
  56. n, shape.name, plain.Round(time.Millisecond), indented.Round(time.Millisecond))
  57. })
  58. }
  59. }
  60. }