Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

proxy_stats_test.go 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package mtglib
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "net/http/httptest"
  6. "testing"
  7. "time"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. )
  11. func TestNewProxyStats(t *testing.T) {
  12. t.Parallel()
  13. stats := NewProxyStats()
  14. assert.NotNil(t, stats)
  15. assert.NotNil(t, stats.users)
  16. assert.False(t, stats.startedAt.IsZero())
  17. }
  18. func TestPreRegister(t *testing.T) {
  19. t.Parallel()
  20. stats := NewProxyStats()
  21. stats.PreRegister("alice")
  22. stats.PreRegister("bob")
  23. stats.mu.RLock()
  24. defer stats.mu.RUnlock()
  25. assert.Contains(t, stats.users, "alice")
  26. assert.Contains(t, stats.users, "bob")
  27. assert.Equal(t, int64(0), stats.users["alice"].connections.Load())
  28. }
  29. func TestOnConnectDisconnect(t *testing.T) {
  30. t.Parallel()
  31. stats := NewProxyStats()
  32. stats.PreRegister("alice")
  33. stats.OnConnect("alice")
  34. assert.Equal(t, int64(1), stats.users["alice"].connections.Load())
  35. stats.OnConnect("alice")
  36. assert.Equal(t, int64(2), stats.users["alice"].connections.Load())
  37. stats.OnDisconnect("alice")
  38. assert.Equal(t, int64(1), stats.users["alice"].connections.Load())
  39. stats.OnDisconnect("alice")
  40. assert.Equal(t, int64(0), stats.users["alice"].connections.Load())
  41. }
  42. func TestAddBytes(t *testing.T) {
  43. t.Parallel()
  44. stats := NewProxyStats()
  45. stats.PreRegister("alice")
  46. stats.AddBytesIn("alice", 100)
  47. stats.AddBytesIn("alice", 200)
  48. stats.AddBytesOut("alice", 50)
  49. st := stats.users["alice"]
  50. assert.Equal(t, int64(300), st.bytesIn.Load())
  51. assert.Equal(t, int64(50), st.bytesOut.Load())
  52. }
  53. func TestUpdateLastSeen(t *testing.T) {
  54. t.Parallel()
  55. stats := NewProxyStats()
  56. stats.PreRegister("alice")
  57. before := time.Now()
  58. stats.UpdateLastSeen("alice")
  59. after := time.Now()
  60. lastSeen := stats.users["alice"].lastSeen.Load().(time.Time)
  61. assert.False(t, lastSeen.Before(before))
  62. assert.False(t, lastSeen.After(after))
  63. }
  64. func TestGetOrCreateLazy(t *testing.T) {
  65. t.Parallel()
  66. stats := NewProxyStats()
  67. // getOrCreate should create a new entry on first access.
  68. stats.OnConnect("new-user")
  69. assert.Equal(t, int64(1), stats.users["new-user"].connections.Load())
  70. }
  71. func TestServeHTTPBasic(t *testing.T) {
  72. t.Parallel()
  73. stats := NewProxyStats()
  74. stats.PreRegister("alice")
  75. stats.PreRegister("bob")
  76. stats.OnConnect("alice")
  77. stats.OnConnect("alice")
  78. stats.OnConnect("bob")
  79. stats.AddBytesIn("alice", 1024)
  80. stats.AddBytesOut("alice", 512)
  81. stats.UpdateLastSeen("alice")
  82. rec := httptest.NewRecorder()
  83. req := httptest.NewRequest(http.MethodGet, "/stats", nil)
  84. stats.ServeHTTP(rec, req)
  85. assert.Equal(t, http.StatusOK, rec.Code)
  86. assert.Equal(t, "application/json", rec.Header().Get("Content-Type"))
  87. var resp StatsResponse
  88. err := json.Unmarshal(rec.Body.Bytes(), &resp)
  89. require.NoError(t, err)
  90. assert.Equal(t, int64(3), resp.TotalConnections)
  91. assert.False(t, resp.StartedAt.IsZero())
  92. assert.GreaterOrEqual(t, resp.UptimeSeconds, int64(0))
  93. alice, ok := resp.Users["alice"]
  94. require.True(t, ok)
  95. assert.Equal(t, int64(2), alice.Connections)
  96. assert.Equal(t, int64(1024), alice.BytesIn)
  97. assert.Equal(t, int64(512), alice.BytesOut)
  98. assert.NotNil(t, alice.LastSeen)
  99. bob, ok := resp.Users["bob"]
  100. require.True(t, ok)
  101. assert.Equal(t, int64(1), bob.Connections)
  102. assert.Equal(t, int64(0), bob.BytesIn)
  103. assert.Equal(t, int64(0), bob.BytesOut)
  104. assert.Nil(t, bob.LastSeen)
  105. }
  106. func TestServeHTTPEmpty(t *testing.T) {
  107. t.Parallel()
  108. stats := NewProxyStats()
  109. rec := httptest.NewRecorder()
  110. req := httptest.NewRequest(http.MethodGet, "/stats", nil)
  111. stats.ServeHTTP(rec, req)
  112. assert.Equal(t, http.StatusOK, rec.Code)
  113. var resp StatsResponse
  114. err := json.Unmarshal(rec.Body.Bytes(), &resp)
  115. require.NoError(t, err)
  116. assert.Empty(t, resp.Users)
  117. assert.Equal(t, int64(0), resp.TotalConnections)
  118. }
  119. func TestServeHTTPLastSeenZeroIsNull(t *testing.T) {
  120. t.Parallel()
  121. stats := NewProxyStats()
  122. stats.PreRegister("alice")
  123. rec := httptest.NewRecorder()
  124. req := httptest.NewRequest(http.MethodGet, "/stats", nil)
  125. stats.ServeHTTP(rec, req)
  126. var raw map[string]json.RawMessage
  127. require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &raw))
  128. var users map[string]json.RawMessage
  129. require.NoError(t, json.Unmarshal(raw["users"], &users))
  130. var aliceRaw map[string]json.RawMessage
  131. require.NoError(t, json.Unmarshal(users["alice"], &aliceRaw))
  132. assert.Equal(t, "null", string(aliceRaw["last_seen"]))
  133. }