github.com/metaworking/channeld@v0.7.3/pkg/channeld/connection_test.go (about)

     1  package channeld
     2  
     3  import (
     4  	"io"
     5  	"log"
     6  	"net"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/gorilla/websocket"
    12  	"github.com/metaworking/channeld/internal/testpb"
    13  	"github.com/metaworking/channeld/pkg/channeldpb"
    14  	"github.com/stretchr/testify/assert"
    15  	"github.com/xtaci/kcp-go"
    16  	"google.golang.org/protobuf/proto"
    17  )
    18  
    19  func init() {
    20  	GlobalSettings.Development = true
    21  	InitLogs()
    22  	InitConnections("../../config/server_conn_fsm_test.json", "../../config/client_non_authoratative_fsm.json")
    23  }
    24  
    25  type pipelineConn struct {
    26  	net.Conn
    27  	r *io.PipeReader
    28  	w *io.PipeWriter
    29  }
    30  
    31  func (c *pipelineConn) Read(b []byte) (n int, err error) {
    32  	return c.r.Read(b)
    33  }
    34  
    35  func (c *pipelineConn) Write(b []byte) (n int, err error) {
    36  	return c.w.Write(b)
    37  }
    38  
    39  func (c *pipelineConn) Close() error {
    40  	err1 := c.r.Close()
    41  	err2 := c.w.Close()
    42  	if err1 != nil {
    43  		return err1
    44  	}
    45  	if err2 != nil {
    46  		return err2
    47  	}
    48  	return nil
    49  }
    50  
    51  func (c *pipelineConn) LocalAddr() net.Addr {
    52  	return nil
    53  }
    54  
    55  func (c *pipelineConn) RemoteAddr() net.Addr {
    56  	return nil
    57  }
    58  
    59  func (c *pipelineConn) SetDeadline(t time.Time) error {
    60  	return nil
    61  }
    62  
    63  func (c *pipelineConn) SetReadDeadline(t time.Time) error {
    64  	return nil
    65  }
    66  
    67  func (c *pipelineConn) SetWriteDeadline(t time.Time) error {
    68  	return nil
    69  }
    70  
    71  func TestReadSize(t *testing.T) {
    72  	var tag []byte
    73  
    74  	tag = []byte{0, 0, 0, 0}
    75  	assert.Equal(t, 0, readSize(tag))
    76  	tag[3] = 1
    77  	assert.Equal(t, 0, readSize(tag))
    78  
    79  	tag = []byte{67, 0, 0, 0}
    80  	assert.Equal(t, 0, readSize(tag))
    81  	tag[3] = 1
    82  	assert.Equal(t, 0, readSize(tag))
    83  
    84  	tag = []byte{67, 72, 78, 0}
    85  	assert.Equal(t, 78<<8, readSize(tag))
    86  	tag[3] = 1
    87  	assert.Equal(t, 78<<8+1, readSize(tag))
    88  
    89  	tag = []byte{67, 72, 0, 0}
    90  	assert.Equal(t, 0, readSize(tag))
    91  	tag[3] = 1
    92  	assert.Equal(t, 1, readSize(tag))
    93  }
    94  
    95  func TestDropPacket(t *testing.T) {
    96  	pipeReader, pipeWriter := io.Pipe()
    97  	c := &Connection{
    98  		conn:       &pipelineConn{r: pipeReader, w: pipeWriter},
    99  		readBuffer: make([]byte, 1024),
   100  		logger:     rootLogger,
   101  	}
   102  
   103  	end := false
   104  	go func() {
   105  		for !end {
   106  			c.receive()
   107  		}
   108  	}()
   109  
   110  	pipeWriter.Write([]byte{1, 2, 3, 4, 5, 6})
   111  	time.Sleep(time.Millisecond * 100)
   112  
   113  	msg := &testpb.TestChannelDataMessage{Text: "abc", Num: 123}
   114  	msgBody, _ := proto.Marshal(msg)
   115  	p := &channeldpb.Packet{
   116  		Messages: []*channeldpb.MessagePack{
   117  			{
   118  				MsgBody: msgBody,
   119  			},
   120  		},
   121  	}
   122  	bytes, _ := proto.Marshal(p)
   123  	size := byte(len(bytes))
   124  	pipeWriter.Write(append([]byte{67, 72, 78, size, 0}, bytes...))
   125  
   126  	time.Sleep(time.Millisecond * 100)
   127  	pipeWriter.Write([]byte{0})
   128  
   129  	end = true
   130  }
   131  
   132  func TestKCPConnection(t *testing.T) {
   133  	const addr string = "127.0.0.1:12108"
   134  	go func() {
   135  		StartListening(channeldpb.ConnectionType_CLIENT, "kcp", addr)
   136  	}()
   137  	sess, err := kcp.DialWithOptions(addr, nil, 0, 0)
   138  	assert.NoError(t, err)
   139  	_, err = sess.Write([]byte("hello"))
   140  	assert.NoError(t, err)
   141  	assert.NoError(t, sess.Close())
   142  }
   143  
   144  func TestWebSocketConnection(t *testing.T) {
   145  	const addr string = "ws://localhost:8080"
   146  	go func() {
   147  		StartListening(channeldpb.ConnectionType_CLIENT, "ws", addr)
   148  	}()
   149  	_, _, err := websocket.DefaultDialer.Dial(addr, nil)
   150  	assert.NoError(t, err)
   151  
   152  	_, _, err = websocket.DefaultDialer.Dial("ws://localhost:8081", nil)
   153  	assert.Error(t, err)
   154  }
   155  
   156  func TestConcurrentAccessConnections(t *testing.T) {
   157  	InitConnections("../../config/server_conn_fsm_test.json", "../../config/client_non_authoratative_fsm.json")
   158  
   159  	wg := sync.WaitGroup{}
   160  
   161  	wg.Add(1)
   162  	go func() {
   163  		for i := 0; i < 100; i++ {
   164  			AddConnection(nil, channeldpb.ConnectionType_CLIENT)
   165  			time.Sleep(1 * time.Millisecond)
   166  		}
   167  		wg.Done()
   168  	}()
   169  
   170  	// Read-Write ratio = 100:1
   171  	for i := 0; i < 100; i++ {
   172  		wg.Add(1)
   173  		go func() {
   174  			counter := 0
   175  			for i := 0; i < 100; i++ {
   176  				if GetConnection(ConnectionId(i)) != nil {
   177  					counter++
   178  				}
   179  				time.Sleep(1 * time.Millisecond)
   180  			}
   181  			log.Println(counter)
   182  			wg.Done()
   183  		}()
   184  	}
   185  
   186  	wg.Wait()
   187  
   188  }