node_unsynced_online_test.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package service
  2. import (
  3. "fmt"
  4. "reflect"
  5. "testing"
  6. "github.com/mhsanaei/3x-ui/v3/internal/database"
  7. "github.com/mhsanaei/3x-ui/v3/internal/database/model"
  8. "github.com/mhsanaei/3x-ui/v3/internal/web/runtime"
  9. "github.com/mhsanaei/3x-ui/v3/internal/xray"
  10. )
  11. func useOnlineTestProcess(t *testing.T) *xray.Process {
  12. t.Helper()
  13. previousProcess, previousResult := xrayState.snapshot()
  14. process := xray.NewTestProcess(nil, "")
  15. xrayState.replace(process)
  16. t.Cleanup(func() {
  17. xrayState.mu.Lock()
  18. xrayState.process = previousProcess
  19. xrayState.result = previousResult
  20. xrayState.mu.Unlock()
  21. })
  22. return process
  23. }
  24. // Only a failed snapshot fetch used to clear a node's online set, so a node the
  25. // sync stopped reaching (disabled, marked offline, deleted) kept its clients online.
  26. func TestRetainSyncedNodeOnlineClientsDropsUnsyncedNodes(t *testing.T) {
  27. setupConflictDB(t)
  28. process := useOnlineTestProcess(t)
  29. svc := InboundService{}
  30. for id := 1; id <= 4; id++ {
  31. guid := fmt.Sprintf("g%d", id)
  32. svc.SetNodeOnlineTree(id, map[string][]string{guid: {guid + "@x"}})
  33. process.SetNodeActiveInboundTree(id, map[string][]string{guid: {"in-" + guid}})
  34. }
  35. svc.RetainSyncedNodeOnlineClients([]*model.Node{
  36. {Id: 1, Enable: true, Status: "online"},
  37. {Id: 2, Enable: false, Status: "online"},
  38. {Id: 3, Enable: true, Status: "offline"},
  39. })
  40. if got, want := svc.GetOnlineClientsByGuid(), map[string][]string{"g1": {"g1@x"}}; !reflect.DeepEqual(got, want) {
  41. t.Errorf("online by guid = %v, want %v", got, want)
  42. }
  43. if got, want := svc.GetActiveInboundsByGuid(), map[string][]string{"g1": {"in-g1"}}; !reflect.DeepEqual(got, want) {
  44. t.Errorf("active inbounds by guid = %v, want %v", got, want)
  45. }
  46. }
  47. func TestSetRemoteTrafficFailureClearsNodeOnlineClients(t *testing.T) {
  48. setupConflictDB(t)
  49. useOnlineTestProcess(t)
  50. svc := InboundService{}
  51. svc.SetNodeOnlineTree(7, map[string][]string{"g7": {"a@x"}})
  52. if err := database.GetDB().Exec("DROP TABLE inbounds").Error; err != nil {
  53. t.Fatalf("drop inbounds: %v", err)
  54. }
  55. if _, err := svc.SetRemoteTraffic(7, &runtime.TrafficSnapshot{}, false, false); err == nil {
  56. t.Fatal("SetRemoteTraffic succeeded without an inbounds table")
  57. }
  58. if got := svc.GetOnlineClientsByGuid(); len(got) != 0 {
  59. t.Errorf("online by guid after a failed merge = %v, want none", got)
  60. }
  61. }