| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- package mtglib
-
- import (
- "encoding/json"
- "net/http"
- "net/http/httptest"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- )
-
- func TestNewProxyStats(t *testing.T) {
- t.Parallel()
-
- stats := NewProxyStats()
- assert.NotNil(t, stats)
- assert.NotNil(t, stats.users)
- assert.False(t, stats.startedAt.IsZero())
- }
-
- func TestPreRegister(t *testing.T) {
- t.Parallel()
-
- stats := NewProxyStats()
- stats.PreRegister("alice")
- stats.PreRegister("bob")
-
- stats.mu.RLock()
- defer stats.mu.RUnlock()
-
- assert.Contains(t, stats.users, "alice")
- assert.Contains(t, stats.users, "bob")
- assert.Equal(t, int64(0), stats.users["alice"].connections.Load())
- }
-
- func TestOnConnectDisconnect(t *testing.T) {
- t.Parallel()
-
- stats := NewProxyStats()
- stats.PreRegister("alice")
-
- stats.OnConnect("alice")
- assert.Equal(t, int64(1), stats.users["alice"].connections.Load())
-
- stats.OnConnect("alice")
- assert.Equal(t, int64(2), stats.users["alice"].connections.Load())
-
- stats.OnDisconnect("alice")
- assert.Equal(t, int64(1), stats.users["alice"].connections.Load())
-
- stats.OnDisconnect("alice")
- assert.Equal(t, int64(0), stats.users["alice"].connections.Load())
- }
-
- func TestAddBytes(t *testing.T) {
- t.Parallel()
-
- stats := NewProxyStats()
- stats.PreRegister("alice")
-
- stats.AddBytesIn("alice", 100)
- stats.AddBytesIn("alice", 200)
- stats.AddBytesOut("alice", 50)
-
- st := stats.users["alice"]
- assert.Equal(t, int64(300), st.bytesIn.Load())
- assert.Equal(t, int64(50), st.bytesOut.Load())
- }
-
- func TestUpdateLastSeen(t *testing.T) {
- t.Parallel()
-
- stats := NewProxyStats()
- stats.PreRegister("alice")
-
- before := time.Now()
- stats.UpdateLastSeen("alice")
- after := time.Now()
-
- lastSeen := stats.users["alice"].lastSeen.Load().(time.Time)
- assert.False(t, lastSeen.Before(before))
- assert.False(t, lastSeen.After(after))
- }
-
- func TestGetOrCreateLazy(t *testing.T) {
- t.Parallel()
-
- stats := NewProxyStats()
-
- // getOrCreate should create a new entry on first access.
- stats.OnConnect("new-user")
- assert.Equal(t, int64(1), stats.users["new-user"].connections.Load())
- }
-
- func TestServeHTTPBasic(t *testing.T) {
- t.Parallel()
-
- stats := NewProxyStats()
- stats.PreRegister("alice")
- stats.PreRegister("bob")
-
- stats.OnConnect("alice")
- stats.OnConnect("alice")
- stats.OnConnect("bob")
- stats.AddBytesIn("alice", 1024)
- stats.AddBytesOut("alice", 512)
- stats.UpdateLastSeen("alice")
-
- rec := httptest.NewRecorder()
- req := httptest.NewRequest(http.MethodGet, "/stats", nil)
-
- stats.ServeHTTP(rec, req)
-
- assert.Equal(t, http.StatusOK, rec.Code)
- assert.Equal(t, "application/json", rec.Header().Get("Content-Type"))
-
- var resp StatsResponse
- err := json.Unmarshal(rec.Body.Bytes(), &resp)
- require.NoError(t, err)
-
- assert.Equal(t, int64(3), resp.TotalConnections)
- assert.False(t, resp.StartedAt.IsZero())
- assert.GreaterOrEqual(t, resp.UptimeSeconds, int64(0))
-
- alice, ok := resp.Users["alice"]
- require.True(t, ok)
- assert.Equal(t, int64(2), alice.Connections)
- assert.Equal(t, int64(1024), alice.BytesIn)
- assert.Equal(t, int64(512), alice.BytesOut)
- assert.NotNil(t, alice.LastSeen)
-
- bob, ok := resp.Users["bob"]
- require.True(t, ok)
- assert.Equal(t, int64(1), bob.Connections)
- assert.Equal(t, int64(0), bob.BytesIn)
- assert.Equal(t, int64(0), bob.BytesOut)
- assert.Nil(t, bob.LastSeen)
- }
-
- func TestServeHTTPEmpty(t *testing.T) {
- t.Parallel()
-
- stats := NewProxyStats()
-
- rec := httptest.NewRecorder()
- req := httptest.NewRequest(http.MethodGet, "/stats", nil)
-
- stats.ServeHTTP(rec, req)
-
- assert.Equal(t, http.StatusOK, rec.Code)
-
- var resp StatsResponse
- err := json.Unmarshal(rec.Body.Bytes(), &resp)
- require.NoError(t, err)
-
- assert.Empty(t, resp.Users)
- assert.Equal(t, int64(0), resp.TotalConnections)
- }
-
- func TestServeHTTPLastSeenZeroIsNull(t *testing.T) {
- t.Parallel()
-
- stats := NewProxyStats()
- stats.PreRegister("alice")
-
- rec := httptest.NewRecorder()
- req := httptest.NewRequest(http.MethodGet, "/stats", nil)
-
- stats.ServeHTTP(rec, req)
-
- var raw map[string]json.RawMessage
- require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &raw))
-
- var users map[string]json.RawMessage
- require.NoError(t, json.Unmarshal(raw["users"], &users))
-
- var aliceRaw map[string]json.RawMessage
- require.NoError(t, json.Unmarshal(users["alice"], &aliceRaw))
-
- assert.Equal(t, "null", string(aliceRaw["last_seen"]))
- }
|