github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/igm/sockjs-go.v2/sockjs/session_test.go (about) 1 package sockjs 2 3 import ( 4 "io" 5 "runtime" 6 "sync" 7 "testing" 8 "time" 9 ) 10 11 func newTestSession() *session { 12 // session with long expiration and heartbeats with ID 13 return newSession("sessionId", 1000*time.Second, 1000*time.Second) 14 } 15 16 func TestSession_Create(t *testing.T) { 17 session := newTestSession() 18 session.sendMessage("this is a message") 19 if len(session.sendBuffer) != 1 { 20 t.Errorf("Session send buffer should contain 1 message") 21 } 22 session.sendMessage("another message") 23 if len(session.sendBuffer) != 2 { 24 t.Errorf("Session send buffer should contain 2 messages") 25 } 26 if session.state != sessionOpening { 27 t.Errorf("Session in wrong state %v, should be %v", session.state, sessionOpening) 28 } 29 } 30 31 func TestSession_ConcurrentSend(t *testing.T) { 32 session := newTestSession() 33 done := make(chan bool) 34 for i := 0; i < 100; i++ { 35 go func() { 36 session.sendMessage("message D") 37 done <- true 38 }() 39 } 40 for i := 0; i < 100; i++ { 41 <-done 42 } 43 if len(session.sendBuffer) != 100 { 44 t.Errorf("Session send buffer should contain 102 messages") 45 } 46 } 47 48 func TestSession_AttachReceiver(t *testing.T) { 49 session := newTestSession() 50 recv := &testReceiver{} 51 // recv := &mockRecv{ 52 // _sendFrame: func(frame string) { 53 // if frame != "o" { 54 // t.Errorf("Incorrect open header received") 55 // } 56 // }, 57 // _sendBulk: func(...string) {}, 58 // } 59 if err := session.attachReceiver(recv); err != nil { 60 t.Errorf("Should not return error") 61 } 62 if session.state != sessionActive { 63 t.Errorf("Session in wrong state after receiver attached %d, should be %d", session.state, sessionActive) 64 } 65 session.detachReceiver() 66 // recv = &mockRecv{ 67 // _sendFrame: func(frame string) { 68 // t.Errorf("No frame shold be send, got '%s'", frame) 69 // }, 70 // _sendBulk: func(...string) {}, 71 // } 72 if err := session.attachReceiver(recv); err != nil { 73 t.Errorf("Should not return error") 74 } 75 } 76 77 func TestSession_Timeout(t *testing.T) { 78 sess := newSession("id", 10*time.Millisecond, 10*time.Second) 79 select { 80 case <-sess.closeCh: 81 case <-time.After(20 * time.Millisecond): 82 t.Errorf("sess close notification channel should close") 83 } 84 sess.Lock() 85 if sess.state != sessionClosed { 86 t.Errorf("Session did not timeout") 87 } 88 sess.Unlock() 89 } 90 91 func TestSession_TimeoutOfClosedSession(t *testing.T) { 92 defer func() { 93 if r := recover(); r != nil { 94 t.Errorf("Unexcpected error '%v'", r) 95 } 96 }() 97 sess := newSession("id", 1*time.Millisecond, time.Second) 98 sess.closing() 99 time.Sleep(1 * time.Millisecond) 100 sess.closing() 101 } 102 103 func TestSession_AttachReceiverAndCheckHeartbeats(t *testing.T) { 104 defer func() { 105 if r := recover(); r != nil { 106 t.Errorf("Unexcpected error '%v'", r) 107 } 108 }() 109 session := newSession("id", time.Second, 10*time.Millisecond) // 10ms heartbeats 110 recv := newTestReceiver() 111 defer close(recv.doneCh) 112 session.attachReceiver(recv) 113 time.Sleep(120 * time.Millisecond) 114 recv.Lock() 115 if len(recv.frames) < 10 || len(recv.frames) > 13 { // should get around 10 heartbeats (120ms/10ms) 116 t.Fatalf("Wrong number of frames received, got '%d'", len(recv.frames)) 117 } 118 for i := 1; i < len(recv.frames); i++ { 119 if recv.frames[i] != "h" { 120 t.Errorf("Heartbeat no received") 121 } 122 } 123 } 124 125 func TestSession_AttachReceiverAndRefuse(t *testing.T) { 126 session := newTestSession() 127 if err := session.attachReceiver(newTestReceiver()); err != nil { 128 t.Errorf("Should not return error") 129 } 130 var a sync.WaitGroup 131 a.Add(100) 132 for i := 0; i < 100; i++ { 133 go func() { 134 defer a.Done() 135 if err := session.attachReceiver(newTestReceiver()); err != errSessionReceiverAttached { 136 t.Errorf("Should return error as another receiver is already attached") 137 } 138 }() 139 } 140 a.Wait() 141 } 142 143 func TestSession_DetachRecevier(t *testing.T) { 144 session := newTestSession() 145 session.detachReceiver() 146 session.detachReceiver() // idempotent operation 147 session.attachReceiver(newTestReceiver()) 148 session.detachReceiver() 149 150 } 151 152 func TestSession_SendWithRecv(t *testing.T) { 153 session := newTestSession() 154 session.sendMessage("message A") 155 session.sendMessage("message B") 156 if len(session.sendBuffer) != 2 { 157 t.Errorf("There should be 2 messages in buffer, but there are %d", len(session.sendBuffer)) 158 } 159 recv := newTestReceiver() 160 defer close(recv.doneCh) 161 162 session.attachReceiver(recv) 163 if len(recv.frames[1:]) != 2 { 164 t.Errorf("Reciver should get 2 message frames from session, got %d", len(recv.frames)) 165 } 166 session.sendMessage("message C") 167 if len(recv.frames[1:]) != 3 { 168 t.Errorf("Reciver should get 3 message frames from session, got %d", len(recv.frames)) 169 } 170 session.sendMessage("message D") 171 if len(recv.frames[1:]) != 4 { 172 t.Errorf("Reciver should get 4 frames from session, got %d", len(recv.frames)) 173 } 174 if len(session.sendBuffer) != 0 { 175 t.Errorf("Send buffer should be empty now, but there are %d messaged", len(session.sendBuffer)) 176 } 177 } 178 179 func TestSession_Recv(t *testing.T) { 180 defer func() { 181 if r := recover(); r != nil { 182 t.Errorf("Panic should not happen") 183 } 184 }() 185 session := newTestSession() 186 go func() { 187 session.accept("message A") 188 session.accept("message B") 189 if err := session.accept("message C"); err != io.ErrClosedPipe { 190 t.Errorf("Session should not accept new messages if closed, got '%v' expected '%v'", err, io.ErrClosedPipe) 191 } 192 }() 193 if msg, _ := session.Recv(); msg != "message A" { 194 t.Errorf("Got %s, should be %s", msg, "message A") 195 } 196 if msg, _ := session.Recv(); msg != "message B" { 197 t.Errorf("Got %s, should be %s", msg, "message B") 198 } 199 session.close() 200 } 201 202 func TestSession_Closing(t *testing.T) { 203 session := newTestSession() 204 session.closing() 205 if _, err := session.Recv(); err == nil { 206 t.Errorf("Session's receive buffer channel should close") 207 } 208 if err := session.sendMessage("some message"); err != ErrSessionNotOpen { 209 t.Errorf("Session should not accept new message after close") 210 } 211 } 212 213 // Session as Session Tests 214 func TestSession_AsSession(t *testing.T) { var _ Session = newSession("id", 0, 0) } 215 216 func TestSession_SessionRecv(t *testing.T) { 217 s := newTestSession() 218 go func() { 219 s.accept("message 1") 220 }() 221 msg, err := s.Recv() 222 if msg != "message 1" || err != nil { 223 t.Errorf("Should receive a message without error, got '%s' err '%v'", msg, err) 224 } 225 go func() { 226 s.closing() 227 _, err := s.Recv() 228 if err != ErrSessionNotOpen { 229 t.Errorf("Session not in correct state, got '%v', expected '%v'", err, ErrSessionNotOpen) 230 } 231 }() 232 _, err = s.Recv() 233 if err != ErrSessionNotOpen { 234 t.Errorf("Session not in correct state, got '%v', expected '%v'", err, ErrSessionNotOpen) 235 } 236 } 237 238 func TestSession_SessionSend(t *testing.T) { 239 s := newTestSession() 240 err := s.Send("message A") 241 if err != nil { 242 t.Errorf("Session should take messages by default") 243 } 244 if len(s.sendBuffer) != 1 || s.sendBuffer[0] != "message A" { 245 t.Errorf("Message not properly queued in session, got '%v'", s.sendBuffer) 246 } 247 } 248 249 func TestSession_SessionClose(t *testing.T) { 250 s := newTestSession() 251 s.state = sessionActive 252 recv := newTestReceiver() 253 s.attachReceiver(recv) 254 err := s.Close(1, "some reason") 255 if len(recv.frames) != 1 || recv.frames[0] != "c[1,\"some reason\"]" { 256 t.Errorf("Expected close frame, got '%v'", recv.frames) 257 } 258 if err != nil { 259 t.Errorf("Should not get any error, got '%s'", err) 260 } 261 if s.closeFrame != "c[1,\"some reason\"]" { 262 t.Errorf("Incorrect closeFrame, got '%s'", s.closeFrame) 263 } 264 if s.state != sessionClosing { 265 t.Errorf("Incorrect session state, expected 'sessionClosing', got '%v'", s.state) 266 } 267 // all the consequent receivers trying to attach shoult get the same close frame 268 var i = 100 269 for i > 0 { 270 recv := newTestReceiver() 271 err := s.attachReceiver(recv) 272 if err != nil { 273 // give a chance to a receiver to detach 274 runtime.Gosched() 275 continue 276 } 277 i-- 278 if len(recv.frames) != 1 || recv.frames[0] != "c[1,\"some reason\"]" { 279 t.Errorf("Close frame not received by recv, frames '%v'", recv.frames) 280 } 281 } 282 if err := s.Close(1, "some other reson"); err != ErrSessionNotOpen { 283 t.Errorf("Expected error, got '%v'", err) 284 } 285 } 286 287 func TestSession_SessionSessionId(t *testing.T) { 288 s := newTestSession() 289 if s.ID() != "sessionId" { 290 t.Errorf("Unexpected session ID, got '%s', expected '%s'", s.ID(), "sessionId") 291 } 292 } 293 294 func newTestReceiver() *testReceiver { 295 return &testReceiver{ 296 doneCh: make(chan struct{}), 297 interruptCh: make(chan struct{}), 298 } 299 } 300 301 type testReceiver struct { 302 sync.Mutex 303 doneCh, interruptCh chan struct{} 304 frames []string 305 } 306 307 func (t *testReceiver) doneNotify() <-chan struct{} { return t.doneCh } 308 func (t *testReceiver) interruptedNotify() <-chan struct{} { return t.interruptCh } 309 func (t *testReceiver) close() { close(t.doneCh) } 310 func (t *testReceiver) canSend() bool { 311 select { 312 case <-t.doneCh: 313 return false // already closed 314 default: 315 return true 316 } 317 } 318 func (t *testReceiver) sendBulk(messages ...string) { 319 for _, m := range messages { 320 t.sendFrame(m) 321 } 322 } 323 func (t *testReceiver) sendFrame(frame string) { 324 t.Lock() 325 defer t.Unlock() 326 t.frames = append(t.frames, frame) 327 }