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 }