github.com/cloudwego/hertz@v0.9.3/pkg/network/netpoll/connection_test.go (about)

     1  // Copyright 2022 CloudWeGo Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  //go:build !windows
    17  // +build !windows
    18  
    19  package netpoll
    20  
    21  import (
    22  	"errors"
    23  	"net"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/cloudwego/hertz/pkg/common/test/assert"
    28  	"github.com/cloudwego/netpoll"
    29  )
    30  
    31  func TestReadBytes(t *testing.T) {
    32  	c := &mockConn{[]byte("a"), nil, 0}
    33  	conn := newConn(c)
    34  	assert.DeepEqual(t, 1, conn.Len())
    35  
    36  	b, _ := conn.Peek(1)
    37  	assert.DeepEqual(t, []byte{'a'}, b)
    38  
    39  	readByte, _ := conn.ReadByte()
    40  	assert.DeepEqual(t, byte('a'), readByte)
    41  
    42  	_, err := conn.ReadByte()
    43  	assert.DeepEqual(t, errors.New("readByte error: index out of range"), err)
    44  
    45  	c = &mockConn{[]byte("bcd"), nil, 0}
    46  	conn = newConn(c)
    47  
    48  	readBinary, _ := conn.ReadBinary(2)
    49  	assert.DeepEqual(t, []byte{'b', 'c'}, readBinary)
    50  
    51  	_, err = conn.ReadBinary(2)
    52  	assert.DeepEqual(t, errors.New("readBinary error: index out of range"), err)
    53  }
    54  
    55  func TestPeekRelease(t *testing.T) {
    56  	c := &mockConn{[]byte("abcdefg"), nil, 0}
    57  	conn := newConn(c)
    58  
    59  	// release the buf
    60  	conn.Release()
    61  	_, err := conn.Peek(1)
    62  	assert.DeepEqual(t, errors.New("peek error"), err)
    63  
    64  	assert.DeepEqual(t, errors.New("skip error"), conn.Skip(2))
    65  }
    66  
    67  func TestWriteLogin(t *testing.T) {
    68  	c := &mockConn{nil, []byte("abcdefg"), 0}
    69  	conn := newConn(c)
    70  	buf, _ := conn.Malloc(10)
    71  	assert.DeepEqual(t, 10, len(buf))
    72  	n, _ := conn.WriteBinary([]byte("abcdefg"))
    73  	assert.DeepEqual(t, 7, n)
    74  	assert.DeepEqual(t, errors.New("flush error"), conn.Flush())
    75  }
    76  
    77  func TestHandleSpecificError(t *testing.T) {
    78  	conn := &Conn{}
    79  	assert.DeepEqual(t, false, conn.HandleSpecificError(nil, ""))
    80  	assert.DeepEqual(t, true, conn.HandleSpecificError(netpoll.ErrConnClosed, ""))
    81  }
    82  
    83  type mockConn struct {
    84  	readBuf  []byte
    85  	writeBuf []byte
    86  	// index for the first readable byte in readBuf
    87  	off int
    88  }
    89  
    90  func (m *mockConn) SetWriteTimeout(timeout time.Duration) error {
    91  	// TODO implement me
    92  	panic("implement me")
    93  }
    94  
    95  // mockConn's methods is simplified for unit test
    96  // Peek returns the next n bytes without advancing the reader
    97  func (m *mockConn) Peek(n int) (b []byte, err error) {
    98  	if m.off+n-1 < len(m.readBuf) {
    99  		return m.readBuf[m.off : m.off+n], nil
   100  	}
   101  	return nil, errors.New("peek error")
   102  }
   103  
   104  // Skip discards the next n bytes
   105  func (m *mockConn) Skip(n int) error {
   106  	if m.off+n < len(m.readBuf) {
   107  		m.off += n
   108  		return nil
   109  	}
   110  	return errors.New("skip error")
   111  }
   112  
   113  // Release the memory space occupied by all read slices
   114  func (m *mockConn) Release() error {
   115  	m.readBuf = nil
   116  	m.off = 0
   117  	return nil
   118  }
   119  
   120  // Len returns the total length of the readable data in the reader
   121  func (m *mockConn) Len() int {
   122  	return len(m.readBuf) - m.off
   123  }
   124  
   125  // ReadByte is used to read one byte with advancing the read pointer
   126  func (m *mockConn) ReadByte() (byte, error) {
   127  	if m.off < len(m.readBuf) {
   128  		m.off++
   129  		return m.readBuf[m.off-1], nil
   130  	}
   131  	return 0, errors.New("readByte error: index out of range")
   132  }
   133  
   134  // ReadBinary is used to read next n byte with copy, and the read pointer will be advanced
   135  func (m *mockConn) ReadBinary(n int) (b []byte, err error) {
   136  	if m.off+n < len(m.readBuf) {
   137  		m.off += n
   138  		return m.readBuf[m.off-n : m.off], nil
   139  	}
   140  	return nil, errors.New("readBinary error: index out of range")
   141  }
   142  
   143  // Malloc will provide a n bytes buffer to send data
   144  func (m *mockConn) Malloc(n int) (buf []byte, err error) {
   145  	m.writeBuf = make([]byte, n)
   146  	return m.writeBuf, nil
   147  }
   148  
   149  // WriteBinary will use the user buffer to flush
   150  func (m *mockConn) WriteBinary(b []byte) (n int, err error) {
   151  	return len(b), nil
   152  }
   153  
   154  // Flush will send data to the peer end
   155  func (m *mockConn) Flush() error {
   156  	return errors.New("flush error")
   157  }
   158  
   159  func (m *mockConn) HandleSpecificError(err error, rip string) (needIgnore bool) {
   160  	panic("implement me")
   161  }
   162  
   163  func (m *mockConn) Read(b []byte) (n int, err error) {
   164  	panic("implement me")
   165  }
   166  
   167  func (m *mockConn) Write(b []byte) (n int, err error) {
   168  	panic("implement me")
   169  }
   170  
   171  func (m *mockConn) Close() error {
   172  	panic("implement me")
   173  }
   174  
   175  func (m *mockConn) LocalAddr() net.Addr {
   176  	panic("implement me")
   177  }
   178  
   179  func (m *mockConn) RemoteAddr() net.Addr {
   180  	panic("implement me")
   181  }
   182  
   183  func (m *mockConn) SetDeadline(deadline time.Time) error {
   184  	panic("implement me")
   185  }
   186  
   187  func (m *mockConn) SetReadDeadline(deadline time.Time) error {
   188  	panic("implement me")
   189  }
   190  
   191  func (m *mockConn) SetWriteDeadline(deadline time.Time) error {
   192  	panic("implement me")
   193  }
   194  
   195  func (m *mockConn) Reader() netpoll.Reader {
   196  	panic("implement me")
   197  }
   198  
   199  func (m *mockConn) Writer() netpoll.Writer {
   200  	panic("implement me")
   201  }
   202  
   203  func (m *mockConn) IsActive() bool {
   204  	panic("implement me")
   205  }
   206  
   207  func (m *mockConn) SetReadTimeout(timeout time.Duration) error {
   208  	panic("implement me")
   209  }
   210  
   211  func (m *mockConn) SetIdleTimeout(timeout time.Duration) error {
   212  	panic("implement me")
   213  }
   214  
   215  func (m *mockConn) SetOnRequest(on netpoll.OnRequest) error {
   216  	panic("implement me")
   217  }
   218  
   219  func (m *mockConn) AddCloseCallback(callback netpoll.CloseCallback) error {
   220  	panic("implement me")
   221  }