| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- package service
- import (
- "testing"
- "time"
- "github.com/mhsanaei/3x-ui/v3/internal/database"
- "github.com/mhsanaei/3x-ui/v3/internal/database/model"
- "github.com/mhsanaei/3x-ui/v3/internal/xray"
- )
- // A reset of a quota-disabled client must end enabled even when a traffic tick
- // runs between its steps: enabling before zeroing lets the tick re-disable it.
- func TestResetTrafficOfDepletedClientSurvivesTickMidReset(t *testing.T) {
- resets := []struct {
- name string
- run func() error
- }{
- {"single", func() error {
- _, err := (&ClientService{}).ResetTrafficByEmail(&InboundService{}, "d@stale")
- return err
- }},
- {"bulk", func() error {
- _, err := (&ClientService{}).BulkResetTraffic(&InboundService{}, []string{"d@stale"})
- return err
- }},
- }
- for _, reset := range resets {
- t.Run(reset.name, func(t *testing.T) {
- requireResetSurvivesTick(t, reset.run)
- })
- }
- }
- func requireResetSurvivesTick(t *testing.T, reset func() error) {
- t.Helper()
- setupBulkDB(t)
- clients := []model.Client{{Email: "d@stale", ID: "aaaaaaaa-0000-0000-0000-00000000000d", SubID: "sub-d", Enable: false, TotalGB: 1000}}
- ib := mkInbound(t, 23140, model.VLESS, clientsSettings(t, clients))
- if err := (&ClientService{}).SyncInbound(nil, ib.Id, clients); err != nil {
- t.Fatalf("SyncInbound: %v", err)
- }
- row := xray.ClientTraffic{InboundId: ib.Id, Email: "d@stale", Enable: false, Up: 600, Down: 400, Total: 1000}
- if err := database.GetDB().Create(&row).Error; err != nil {
- t.Fatalf("seed client_traffics: %v", err)
- }
- resetTrafficWriterForTest(t)
- StartTrafficWriter()
- parked := make(chan struct{})
- release := make(chan struct{})
- go func() {
- _ = submitTrafficWrite(func() error {
- close(parked)
- <-release
- return nil
- })
- }()
- <-parked
- resetDone := make(chan error, 1)
- go func() { resetDone <- reset() }()
- waitTrafficWriterQueued(t)
- tickDone := make(chan error, 1)
- go func() {
- _, _, err := (&InboundService{}).AddTraffic(nil, nil)
- tickDone <- err
- }()
- deadline := time.Now().Add(5 * time.Second)
- for len(twQueue) < 2 && time.Now().Before(deadline) {
- time.Sleep(time.Millisecond)
- }
- close(release)
- if err := <-resetDone; err != nil {
- t.Fatalf("reset: %v", err)
- }
- if err := <-tickDone; err != nil {
- t.Fatalf("AddTraffic: %v", err)
- }
- var after xray.ClientTraffic
- if err := database.GetDB().Where("email = ?", "d@stale").First(&after).Error; err != nil {
- t.Fatalf("read client_traffics: %v", err)
- }
- c, _ := settingsClient(t, ib.Id, "d@stale")
- rec := lookupClientRecord(t, "d@stale")
- if !after.Enable || !c.Enable || !rec.Enable || after.Up+after.Down != 0 {
- t.Fatalf("after reset: traffic enable=%v used=%d, settings enable=%v, record enable=%v; want all enabled at 0",
- after.Enable, after.Up+after.Down, c.Enable, rec.Enable)
- }
- }
|