github.com/glide-im/glide@v1.6.0/pkg/gate/user_client_test.go (about) 1 package gate 2 3 import ( 4 "github.com/glide-im/glide/pkg/conn" 5 "github.com/glide-im/glide/pkg/messages" 6 "github.com/stretchr/testify/assert" 7 "log" 8 "testing" 9 "time" 10 ) 11 12 func mockMsgHandler(cliInfo *Info, message *messages.GlideMessage) { 13 } 14 15 func TestClient_RunReadHeartbeatTimeout(t *testing.T) { 16 fn, ch := mockReadFn() 17 go func() { 18 time.Sleep(time.Millisecond * 100) 19 ch <- messages.NewMessage(1, messages.ActionHeartbeat, nil) 20 time.Sleep(time.Millisecond * 100) 21 ch <- messages.NewMessage(1, messages.ActionHeartbeat, nil) 22 time.Sleep(time.Millisecond * 100) 23 ch <- messages.NewMessage(1, messages.ActionHeartbeat, nil) 24 }() 25 26 client := NewClient(&mockConnection{ 27 writeDelayMilliSec: 200, 28 mockRead: fn, 29 }, mockGateway{}, mockMsgHandler).(*UserClient) 30 31 client.config.ClientHeartbeatDuration = time.Millisecond * 200 32 client.Run() 33 34 time.Sleep(time.Second * 1) 35 client.Exit() 36 } 37 38 func TestClient_RunServerHeartbeat(t *testing.T) { 39 fn, _ := mockReadFn() 40 client := NewClientWithConfig(&mockConnection{ 41 writeDelayMilliSec: 100, 42 mockRead: fn, 43 }, mockGateway{}, mockMsgHandler, &ClientConfig{ 44 ServerHeartbeatDuration: time.Millisecond * 400, 45 CloseImmediately: true, 46 }) 47 client.Run() 48 49 time.Sleep(time.Second * 1) 50 client.Exit() 51 } 52 53 func TestClient_RunServerHeartbeatTimeout(t *testing.T) { 54 fn, _ := mockReadFn() 55 client := NewClientWithConfig(&mockConnection{ 56 writeDelayMilliSec: 100, 57 mockRead: fn, 58 }, mockGateway{}, mockMsgHandler, &ClientConfig{ 59 ClientHeartbeatDuration: defaultHeartbeatDuration, 60 ServerHeartbeatDuration: time.Millisecond * 100, 61 HeartbeatLostLimit: 3, 62 CloseImmediately: true, 63 }) 64 client.Run() 65 66 time.Sleep(time.Second * 1) 67 } 68 69 func TestClient_ExitImmediately(t *testing.T) { 70 71 fn, ch := mockReadFn() 72 go func() { 73 time.Sleep(time.Second * 1) 74 ch <- messages.NewMessage(1, messages.ActionHeartbeat, nil) 75 }() 76 77 client := NewClient(&mockConnection{ 78 writeDelayMilliSec: 200, 79 mockRead: fn, 80 }, mockGateway{}, mockMsgHandler).(*UserClient) 81 client.config.CloseImmediately = true 82 client.Run() 83 84 for i := 0; i < 10; i++ { 85 err := client.EnqueueMessage(messages.NewMessage(1, messages.ActionHeartbeat, nil)) 86 if err != nil { 87 t.Error(err) 88 } 89 } 90 time.Sleep(time.Millisecond * 450) 91 client.Exit() 92 93 assert.Equal(t, client.queuedMessage, int64(8)) 94 } 95 96 func TestClient_Exit(t *testing.T) { 97 fn, _ := mockReadFn() 98 99 client := NewClient(&mockConnection{ 100 writeDelayMilliSec: 10, 101 mockRead: fn, 102 }, mockGateway{}, mockMsgHandler).(*UserClient) 103 client.config.CloseImmediately = false 104 client.Run() 105 106 for i := 0; i < 20; i++ { 107 err := client.EnqueueMessage(messages.NewMessage(1, messages.ActionHeartbeat, nil)) 108 if err != nil { 109 t.Error(err) 110 } 111 } 112 client.Exit() 113 assert.False(t, client.IsRunning()) 114 assert.Error(t, client.EnqueueMessage(messages.NewMessage(1, messages.ActionHeartbeat, nil))) 115 assert.Equal(t, client.state, stateClosed) 116 117 time.Sleep(time.Millisecond * 300) 118 119 assert.Equal(t, client.queuedMessage, int64(0)) 120 } 121 122 func mockReadFn() (func() ([]byte, error), chan<- *messages.GlideMessage) { 123 ch := make(chan *messages.GlideMessage) 124 return func() ([]byte, error) { 125 m := <-ch 126 encode, err := messages.JsonCodec.Encode(m) 127 return encode, err 128 }, ch 129 } 130 131 type mockConnection struct { 132 writeDelayMilliSec time.Duration 133 mockRead func() ([]byte, error) 134 } 135 136 func (m *mockConnection) Write(data []byte) error { 137 time.Sleep(time.Millisecond * m.writeDelayMilliSec) 138 log.Println("runWrite:", string(data)) 139 return nil 140 } 141 142 func (m *mockConnection) Read() ([]byte, error) { 143 for { 144 return m.mockRead() 145 } 146 } 147 148 func (m *mockConnection) Close() error { 149 log.Println("close connection") 150 return nil 151 } 152 153 func (m *mockConnection) GetConnInfo() *conn.ConnectionInfo { 154 return &conn.ConnectionInfo{ 155 Ip: "127.0.0.1", 156 Port: 9999, 157 Addr: "[::1]:9999", 158 } 159 } 160 161 type mockGateway struct { 162 } 163 164 func (m mockGateway) UpdateClient(id ID, info *ClientSecrets) error { 165 //TODO implement me 166 panic("implement me") 167 } 168 169 func (m mockGateway) GetClient(id ID) Client { 170 //TODO implement me 171 panic("implement me") 172 } 173 174 func (m mockGateway) GetAll() map[ID]Info { 175 //TODO implement me 176 panic("implement me") 177 } 178 179 func (m mockGateway) SetMessageHandler(h MessageHandler) { 180 //TODO implement me 181 panic("implement me") 182 } 183 184 func (m mockGateway) AddClient(cs Client) { 185 //TODO implement me 186 panic("implement me") 187 } 188 189 func (m mockGateway) SetClientID(old ID, new_ ID) error { 190 return nil 191 } 192 193 func (m mockGateway) ExitClient(id ID) error { 194 log.Println("exit client:", id) 195 return nil 196 } 197 198 func (m mockGateway) EnqueueMessage(id ID, message *messages.GlideMessage) error { 199 return nil 200 }