Skip to content

Commit

Permalink
test: ut supplementary for pkg/network
Browse files Browse the repository at this point in the history
test: ut supplementary for pkg/network
  • Loading branch information
BaiZe1998 committed Sep 25, 2022
1 parent 74d61a3 commit 03baf95
Show file tree
Hide file tree
Showing 3 changed files with 333 additions and 14 deletions.
57 changes: 57 additions & 0 deletions pkg/network/dialer/dialer_test.go
@@ -0,0 +1,57 @@
/*
* Copyright 2022 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dialer

import (
"crypto/tls"
"errors"
"net"
"testing"
"time"

"github.com/cloudwego/hertz/pkg/common/test/assert"
"github.com/cloudwego/hertz/pkg/network"
)

func TestDialer(t *testing.T) {
SetDialer(&mockDialer{})
dialer := DefaultDialer()
assert.DeepEqual(t, &mockDialer{}, dialer)

_, err := AddTLS(nil, nil)
assert.NotNil(t, err)

_, err = DialConnection("", "", 0, nil)
assert.NotNil(t, err)

_, err = DialTimeout("", "", 0, nil)
assert.NotNil(t, err)
}

type mockDialer struct{}

func (m *mockDialer) DialConnection(network, address string, timeout time.Duration, tlsConfig *tls.Config) (conn network.Conn, err error) {
return nil, errors.New("method not implement")
}

func (m *mockDialer) DialTimeout(network, address string, timeout time.Duration, tlsConfig *tls.Config) (conn net.Conn, err error) {
return nil, errors.New("method not implement")
}

func (m *mockDialer) AddTLS(conn network.Conn, tlsConfig *tls.Config) (network.Conn, error) {
return nil, errors.New("method not implement")
}
205 changes: 205 additions & 0 deletions pkg/network/netpoll/connection_test.go
@@ -0,0 +1,205 @@
/*
* Copyright 2022 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package netpoll

import (
"errors"
"net"
"testing"
"time"

"github.com/cloudwego/hertz/pkg/common/test/assert"
"github.com/cloudwego/netpoll"
)

func TestReadBytes(t *testing.T) {
c := &mockConn{[]byte("abcdefg"), nil, 0}
conn := newConn(c)
assert.DeepEqual(t, 7, conn.Len())

b, _ := conn.Peek(1)
assert.DeepEqual(t, []byte{'a'}, b)

readByte, _ := conn.ReadByte()
assert.DeepEqual(t, byte('a'), readByte)

readBinary, _ := conn.ReadBinary(2)
assert.DeepEqual(t, []byte{'b', 'c'}, readBinary)
}

func TestPeekRelease(t *testing.T) {
c := &mockConn{[]byte("abcdefg"), nil, 0}
conn := newConn(c)

// release the buf
conn.Release()
_, err := conn.Peek(1)
assert.DeepEqual(t, errors.New("peek error"), err)

assert.DeepEqual(t, errors.New("skip error"), conn.Skip(2))
}

func TestWriteLogin(t *testing.T) {
c := &mockConn{nil, []byte("abcdefg"), 0}
conn := newConn(c)
buf, _ := conn.Malloc(10)
assert.DeepEqual(t, 10, len(buf))
n, _ := conn.WriteBinary([]byte("abcdefg"))
assert.DeepEqual(t, 7, n)
assert.DeepEqual(t, errors.New("flush error"), conn.Flush())
}

func TestHandleSpecificError(t *testing.T) {
conn := &Conn{}
assert.DeepEqual(t, false, conn.HandleSpecificError(nil, ""))
assert.DeepEqual(t, true, conn.HandleSpecificError(netpoll.ErrConnClosed, ""))
}

type mockConn struct {
readBuf []byte
writeBuf []byte
// index for the first readable byte in readBuf
off int
}

// mockConn's methods is simplified for unit test
// Peek returns the next n bytes without advancing the reader
func (m *mockConn) Peek(n int) (b []byte, err error) {
if m.off+n < len(m.readBuf) {
return m.readBuf[m.off : m.off+n], nil
}
return nil, errors.New("peek error")
}

// Skip discards the next n bytes
func (m *mockConn) Skip(n int) error {
if m.off+n < len(m.readBuf) {
m.off += n
return nil
}
return errors.New("skip error")
}

// Release the memory space occupied by all read slices
func (m *mockConn) Release() error {
m.readBuf = nil
m.off = 0
return nil
}

// Len returns the total length of the readable data in the reader
func (m *mockConn) Len() int {
return len(m.readBuf) - m.off
}

// ReadByte is used to read one byte with advancing the read pointer
func (m *mockConn) ReadByte() (byte, error) {
if m.off < len(m.readBuf) {
m.off++
return m.readBuf[m.off-1], nil
}
return 0, errors.New("readByte error")
}

// ReadBinary is used to read next n byte with copy, and the read pointer will be advanced
func (m *mockConn) ReadBinary(n int) (b []byte, err error) {
if m.off+n < len(m.readBuf) {
m.off += n
return m.readBuf[m.off-n : m.off], nil
}
return nil, errors.New("readByte error")
}

// Malloc will provide a n bytes buffer to send data
func (m *mockConn) Malloc(n int) (buf []byte, err error) {
m.writeBuf = make([]byte, n)
return m.writeBuf, nil
}

// WriteBinary will use the user buffer to flush
func (m *mockConn) WriteBinary(b []byte) (n int, err error) {
return len(b), nil
}

// Flush will send data to the peer end
func (m *mockConn) Flush() error {
return errors.New("flush error")
}

func (m *mockConn) HandleSpecificError(err error, rip string) (needIgnore bool) {
panic("implement me")
}

func (m *mockConn) Read(b []byte) (n int, err error) {
panic("implement me")
}

func (m *mockConn) Write(b []byte) (n int, err error) {
panic("implement me")
}

func (m *mockConn) Close() error {
panic("implement me")
}

func (m *mockConn) LocalAddr() net.Addr {
panic("implement me")
}

func (m *mockConn) RemoteAddr() net.Addr {
panic("implement me")
}

func (m *mockConn) SetDeadline(deadline time.Time) error {
panic("implement me")
}

func (m *mockConn) SetReadDeadline(deadline time.Time) error {
panic("implement me")
}

func (m *mockConn) SetWriteDeadline(deadline time.Time) error {
panic("implement me")
}

func (m *mockConn) Reader() netpoll.Reader {
panic("implement me")
}

func (m *mockConn) Writer() netpoll.Writer {
panic("implement me")
}

func (m *mockConn) IsActive() bool {
panic("implement me")
}

func (m *mockConn) SetReadTimeout(timeout time.Duration) error {
panic("implement me")
}

func (m *mockConn) SetIdleTimeout(timeout time.Duration) error {
panic("implement me")
}

func (m *mockConn) SetOnRequest(on netpoll.OnRequest) error {
panic("implement me")
}

func (m *mockConn) AddCloseCallback(callback netpoll.CloseCallback) error {
panic("implement me")
}
85 changes: 71 additions & 14 deletions pkg/network/standard/connection_test.go
Expand Up @@ -18,6 +18,8 @@ package standard

import (
"bytes"
"crypto/tls"
"errors"
"io"
"net"
"strings"
Expand Down Expand Up @@ -231,8 +233,48 @@ func TestWriteLogic(t *testing.T) {
}
}

func TestInitializeConn(t *testing.T) {
c := mockConn{
localAddr: &mockAddr{
network: "tcp",
address: "192.168.0.10:80",
},
remoteAddr: &mockAddr{
network: "tcp",
address: "192.168.0.20:80",
},
}
conn := newConn(&c, 8192)
// check the assignment
assert.DeepEqual(t, errors.New("conn: deadline not supported"), conn.SetDeadline(time.Time{}))
assert.DeepEqual(t, errors.New("conn: deadline not supported"), conn.SetReadDeadline(time.Time{}))
assert.DeepEqual(t, errors.New("conn: deadline not supported"), conn.SetWriteDeadline(time.Time{}))
assert.DeepEqual(t, errors.New("conn: deadline not supported"), conn.SetReadTimeout(time.Duration(1)*time.Second))
assert.DeepEqual(t, errors.New("conn: deadline not supported"), conn.SetReadTimeout(time.Duration(-1)*time.Second))
assert.DeepEqual(t, errors.New("conn: method not supported"), conn.Close())
assert.DeepEqual(t, &mockAddr{network: "tcp", address: "192.168.0.10:80"}, conn.LocalAddr())
assert.DeepEqual(t, &mockAddr{network: "tcp", address: "192.168.0.20:80"}, conn.RemoteAddr())
}

func TestInitializeTLSConn(t *testing.T) {
c := mockConn{}
tlsConn := newTLSConn(&c, 8192).(*TLSConn)
assert.DeepEqual(t, errors.New("conn: method not supported"), tlsConn.Handshake())
assert.DeepEqual(t, tls.ConnectionState{}, tlsConn.ConnectionState())
}

type mockConn struct {
buffer bytes.Buffer
buffer bytes.Buffer
localAddr net.Addr
remoteAddr net.Addr
}

func (m *mockConn) Handshake() error {
return errors.New("conn: method not supported")
}

func (m *mockConn) ConnectionState() tls.ConnectionState {
return tls.ConnectionState{}
}

func (m mockConn) Read(b []byte) (n int, err error) {
Expand All @@ -243,7 +285,6 @@ func (m mockConn) Read(b []byte) (n int, err error) {
if len(b) < 1024 {
return 100, nil
}

if len(b) < 5000 {
return 4096, nil
}
Expand All @@ -255,26 +296,42 @@ func (m *mockConn) Write(b []byte) (n int, err error) {
return m.buffer.Write(b)
}

func (m mockConn) Close() error {
panic("implement me")
func (m *mockConn) Close() error {
return errors.New("conn: method not supported")
}

func (m *mockConn) LocalAddr() net.Addr {
return m.localAddr
}

func (m *mockConn) RemoteAddr() net.Addr {
return m.remoteAddr
}

func (m *mockConn) SetDeadline(deadline time.Time) error {
if err := m.SetWriteDeadline(deadline); err != nil {
return err
}
return m.SetWriteDeadline(deadline)
}

func (m mockConn) LocalAddr() net.Addr {
panic("implement me")
func (m *mockConn) SetReadDeadline(deadline time.Time) error {
return errors.New("conn: deadline not supported")
}

func (m mockConn) RemoteAddr() net.Addr {
panic("implement me")
func (m *mockConn) SetWriteDeadline(deadline time.Time) error {
return errors.New("conn: deadline not supported")
}

func (m mockConn) SetDeadline(t time.Time) error {
panic("implement me")
type mockAddr struct {
network string
address string
}

func (m mockConn) SetReadDeadline(t time.Time) error {
panic("implement me")
func (m *mockAddr) Network() string {
return m.network
}

func (m mockConn) SetWriteDeadline(t time.Time) error {
panic("implement me")
func (m *mockAddr) String() string {
return m.address
}

0 comments on commit 03baf95

Please sign in to comment.