bulk_traffic_test.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package service
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/mhsanaei/3x-ui/v3/database"
  6. "github.com/mhsanaei/3x-ui/v3/database/model"
  7. "github.com/mhsanaei/3x-ui/v3/xray"
  8. )
  9. func mkTraffic(t *testing.T, inboundId int, email string, up, down, total, expiry int64, enable bool) {
  10. t.Helper()
  11. row := xray.ClientTraffic{
  12. InboundId: inboundId,
  13. Email: email,
  14. Up: up,
  15. Down: down,
  16. Total: total,
  17. ExpiryTime: expiry,
  18. Enable: enable,
  19. }
  20. if err := database.GetDB().Create(&row).Error; err != nil {
  21. t.Fatalf("create traffic %s: %v", email, err)
  22. }
  23. }
  24. func trafficOf(t *testing.T, email string) xray.ClientTraffic {
  25. t.Helper()
  26. var row xray.ClientTraffic
  27. if err := database.GetDB().Where("email = ?", email).First(&row).Error; err != nil {
  28. t.Fatalf("load traffic %s: %v", email, err)
  29. }
  30. return row
  31. }
  32. func TestBulkResetTrafficZeroesUsageAndReenables(t *testing.T) {
  33. setupBulkDB(t)
  34. svc := &ClientService{}
  35. inboundSvc := &InboundService{}
  36. source := []model.Client{
  37. {Email: "alice@x", ID: "11111111-1111-1111-1111-111111111111", SubID: "sa", Enable: true},
  38. {Email: "bob@x", ID: "22222222-2222-2222-2222-222222222222", SubID: "sb", Enable: true},
  39. {Email: "carol@x", ID: "33333333-3333-3333-3333-333333333333", SubID: "sc", Enable: true},
  40. }
  41. ib := mkInbound(t, 21001, model.VLESS, clientsSettings(t, source))
  42. if err := svc.SyncInbound(nil, ib.Id, source); err != nil {
  43. t.Fatalf("seed linkage: %v", err)
  44. }
  45. mkTraffic(t, ib.Id, "alice@x", 10, 20, 0, 0, false)
  46. mkTraffic(t, ib.Id, "bob@x", 5, 5, 0, 0, true)
  47. mkTraffic(t, ib.Id, "carol@x", 7, 0, 0, 0, true)
  48. affected, err := svc.BulkResetTraffic(inboundSvc, []string{"alice@x", "bob@x"})
  49. if err != nil {
  50. t.Fatalf("BulkResetTraffic: %v", err)
  51. }
  52. if affected != 2 {
  53. t.Fatalf("expected 2 affected, got %d", affected)
  54. }
  55. for _, e := range []string{"alice@x", "bob@x"} {
  56. tr := trafficOf(t, e)
  57. if tr.Up != 0 || tr.Down != 0 {
  58. t.Fatalf("%s: expected up/down 0, got up=%d down=%d", e, tr.Up, tr.Down)
  59. }
  60. if !tr.Enable {
  61. t.Fatalf("%s: expected re-enabled", e)
  62. }
  63. }
  64. carol := trafficOf(t, "carol@x")
  65. if carol.Up != 7 {
  66. t.Fatalf("carol not in list should be untouched, got up=%d", carol.Up)
  67. }
  68. }
  69. func TestDelDepletedRemovesOnlyDepleted(t *testing.T) {
  70. setupBulkDB(t)
  71. svc := &ClientService{}
  72. inboundSvc := &InboundService{}
  73. source := []model.Client{
  74. {Email: "alice@x", ID: "11111111-1111-1111-1111-111111111111", SubID: "sa", Enable: true},
  75. {Email: "bob@x", ID: "22222222-2222-2222-2222-222222222222", SubID: "sb", Enable: true},
  76. {Email: "carol@x", ID: "33333333-3333-3333-3333-333333333333", SubID: "sc", Enable: true},
  77. }
  78. ib := mkInbound(t, 21002, model.VLESS, clientsSettings(t, source))
  79. if err := svc.SyncInbound(nil, ib.Id, source); err != nil {
  80. t.Fatalf("seed linkage: %v", err)
  81. }
  82. past := time.Now().Add(-time.Hour).UnixMilli()
  83. mkTraffic(t, ib.Id, "alice@x", 60, 60, 100, 0, true)
  84. mkTraffic(t, ib.Id, "bob@x", 10, 10, 100, 0, true)
  85. mkTraffic(t, ib.Id, "carol@x", 0, 0, 0, past, true)
  86. deleted, _, err := svc.DelDepleted(inboundSvc)
  87. if err != nil {
  88. t.Fatalf("DelDepleted: %v", err)
  89. }
  90. if deleted != 2 {
  91. t.Fatalf("expected 2 deleted (alice traffic-depleted, carol expired), got %d", deleted)
  92. }
  93. if _, err := svc.GetRecordByEmail(nil, "bob@x"); err != nil {
  94. t.Fatalf("bob should survive: %v", err)
  95. }
  96. for _, e := range []string{"alice@x", "carol@x"} {
  97. if _, err := svc.GetRecordByEmail(nil, e); err == nil {
  98. t.Fatalf("%s should be deleted", e)
  99. }
  100. }
  101. reloaded, _ := inboundSvc.GetInbound(ib.Id)
  102. jsonClients, _ := inboundSvc.GetClients(reloaded)
  103. if len(jsonClients) != 1 || jsonClients[0].Email != "bob@x" {
  104. t.Fatalf("settings JSON should contain only bob, got %d clients", len(jsonClients))
  105. }
  106. }
  107. func TestGetClientTrafficByEmailReadsClientsTable(t *testing.T) {
  108. setupBulkDB(t)
  109. svc := &ClientService{}
  110. inboundSvc := &InboundService{}
  111. source := []model.Client{
  112. {Email: "alice@x", ID: "11111111-1111-1111-1111-111111111111", SubID: "sa", Enable: true},
  113. }
  114. ib := mkInbound(t, 21003, model.VLESS, clientsSettings(t, source))
  115. if err := svc.SyncInbound(nil, ib.Id, source); err != nil {
  116. t.Fatalf("seed linkage: %v", err)
  117. }
  118. mkTraffic(t, ib.Id, "alice@x", 1, 2, 0, 0, true)
  119. tr, err := inboundSvc.GetClientTrafficByEmail("alice@x")
  120. if err != nil {
  121. t.Fatalf("GetClientTrafficByEmail: %v", err)
  122. }
  123. if tr == nil {
  124. t.Fatalf("expected traffic, got nil")
  125. }
  126. if tr.UUID != "11111111-1111-1111-1111-111111111111" {
  127. t.Fatalf("UUID not enriched from clients table, got %q", tr.UUID)
  128. }
  129. if tr.SubId != "sa" {
  130. t.Fatalf("SubId not enriched from clients table, got %q", tr.SubId)
  131. }
  132. }