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  }