github.com/uber-go/tally/v4@v4.1.17/m3/thriftudp/multitransport_test.go (about)

     1  // Copyright (c) 2021 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package thriftudp
    22  
    23  import (
    24  	"fmt"
    25  	"testing"
    26  
    27  	"github.com/stretchr/testify/assert"
    28  	"github.com/uber-go/tally/v4/thirdparty/github.com/apache/thrift/lib/go/thrift"
    29  )
    30  
    31  func TestNewTMultiUDPClientTransport(t *testing.T) {
    32  	trans, err := NewTMultiUDPClientTransport([]string{"127.0.0.1:9090", "127.0.0.1:9090"}, "")
    33  	assert.NotNil(t, trans)
    34  	assert.Nil(t, err)
    35  	trans.Close()
    36  }
    37  
    38  func TestNewTMultiUDPClientTransportBadAddress(t *testing.T) {
    39  	trans, err := NewTMultiUDPClientTransport([]string{"not an address"}, "")
    40  	assert.Nil(t, trans)
    41  	assert.NotNil(t, err)
    42  }
    43  
    44  func TestTMultiUDPTransportOpen(t *testing.T) {
    45  	trans, err := NewTMultiUDPClientTransport([]string{}, "")
    46  	assert.Nil(t, err)
    47  
    48  	trans.transports = []thrift.TTransport{newMockTransport(), newMockTransport()}
    49  	assert.Nil(t, trans.Open())
    50  
    51  	trans.Close()
    52  }
    53  
    54  func TestTMultiUDPTransportOpenFail(t *testing.T) {
    55  	trans, err := NewTMultiUDPClientTransport([]string{}, "")
    56  	assert.Nil(t, err)
    57  
    58  	trans.transports = []thrift.TTransport{newMockTransport(), newMockTransport()}
    59  	trans.transports[1].(*mockTransport).openError = fmt.Errorf("error")
    60  	assert.NotNil(t, trans.Open())
    61  	trans.Close()
    62  }
    63  
    64  func TestTMultiUDPTransportIsOpen(t *testing.T) {
    65  	trans, err := NewTMultiUDPClientTransport([]string{}, "")
    66  	assert.Nil(t, err)
    67  
    68  	trans.transports = []thrift.TTransport{newMockTransport(), newMockTransport()}
    69  	trans.transports[0].(*mockTransport).currentlyOpen = true
    70  	trans.transports[1].(*mockTransport).currentlyOpen = true
    71  	assert.True(t, trans.IsOpen())
    72  	trans.Close()
    73  }
    74  
    75  func TestTMultiUDPTransportIsNotOpen(t *testing.T) {
    76  	trans, err := NewTMultiUDPClientTransport([]string{}, "")
    77  	assert.Nil(t, err)
    78  
    79  	trans.transports = []thrift.TTransport{newMockTransport(), newMockTransport()}
    80  	assert.False(t, trans.IsOpen())
    81  	trans.Close()
    82  }
    83  
    84  func TestTMultiUDPTransportReadNotSupported(t *testing.T) {
    85  	trans, err := NewTMultiUDPClientTransport([]string{}, "")
    86  	assert.Nil(t, err)
    87  
    88  	n, err := trans.Read([]byte{})
    89  	assert.Equal(t, int(0), n)
    90  	assert.NotNil(t, err)
    91  	trans.Close()
    92  }
    93  
    94  func TestTMultiUDPTransportRemainingBytesNotSupported(t *testing.T) {
    95  	trans, err := NewTMultiUDPClientTransport([]string{}, "")
    96  	assert.Nil(t, err)
    97  
    98  	n := trans.RemainingBytes()
    99  	assert.Equal(t, uint64(0), n)
   100  	trans.Close()
   101  }
   102  
   103  func TestTMultiUDPTransportWrite(t *testing.T) {
   104  	trans, err := NewTMultiUDPClientTransport([]string{}, "")
   105  	assert.Nil(t, err)
   106  
   107  	trans.transports = []thrift.TTransport{newMockTransport(), newMockTransport()}
   108  	trans.transports[0].(*mockTransport).onWrite = func(buf []byte) (int, error) {
   109  		return len(buf), nil
   110  	}
   111  	trans.transports[1].(*mockTransport).onWrite = func(buf []byte) (int, error) {
   112  		return len(buf), nil
   113  	}
   114  
   115  	b := []byte{1, 2, 3}
   116  	n, err := trans.Write(b)
   117  	assert.Equal(t, int(len(b)), n)
   118  	assert.Nil(t, err)
   119  
   120  	trans.Flush()
   121  	trans.Close()
   122  }
   123  
   124  func TestTMultiUDPTransportWriteError(t *testing.T) {
   125  	trans, err := NewTMultiUDPClientTransport([]string{}, "")
   126  	assert.Nil(t, err)
   127  
   128  	trans.transports = []thrift.TTransport{newMockTransport(), newMockTransport()}
   129  	trans.transports[0].(*mockTransport).onWrite = func(buf []byte) (int, error) {
   130  		return 0, fmt.Errorf("error")
   131  	}
   132  	trans.transports[1].(*mockTransport).onWrite = func(buf []byte) (int, error) {
   133  		return len(buf), nil
   134  	}
   135  
   136  	b := []byte{1, 2, 3}
   137  	n, err := trans.Write(b)
   138  	assert.Equal(t, int(0), n)
   139  	assert.NotNil(t, err)
   140  	trans.Close()
   141  }
   142  
   143  type mockTransport struct {
   144  	currentlyOpen    bool
   145  	onRead           func(buf []byte) (int, error)
   146  	onRemainingBytes func() uint64
   147  	onWrite          func(buf []byte) (int, error)
   148  	onFlush          func() error
   149  	openError        error
   150  	closeError       error
   151  }
   152  
   153  func newMockTransport() *mockTransport {
   154  	return &mockTransport{}
   155  }
   156  
   157  func (m *mockTransport) Open() error {
   158  	if m.openError != nil {
   159  		return m.openError
   160  	}
   161  	m.currentlyOpen = true
   162  	return nil
   163  }
   164  
   165  func (m *mockTransport) IsOpen() bool {
   166  	return m.currentlyOpen
   167  }
   168  
   169  func (m *mockTransport) Close() error {
   170  	if m.closeError != nil {
   171  		return m.closeError
   172  	}
   173  	m.currentlyOpen = false
   174  	return nil
   175  }
   176  
   177  func (m *mockTransport) Read(buf []byte) (int, error) {
   178  	if m.onRead != nil {
   179  		return m.onRead(buf)
   180  	}
   181  	return 0, fmt.Errorf("no mock Read implementation")
   182  }
   183  
   184  func (m *mockTransport) RemainingBytes() uint64 {
   185  	if m.onRemainingBytes != nil {
   186  		return m.onRemainingBytes()
   187  	}
   188  	return 0
   189  }
   190  
   191  func (m *mockTransport) Write(buf []byte) (int, error) {
   192  	if m.onWrite != nil {
   193  		return m.onWrite(buf)
   194  	}
   195  	return 0, fmt.Errorf("no mock Write implementation")
   196  }
   197  
   198  func (m *mockTransport) Flush() error {
   199  	if m.onFlush != nil {
   200  		return m.onFlush()
   201  	}
   202  	return fmt.Errorf("no mock Flush implementation")
   203  }