github.com/xmidt-org/webpa-common@v1.11.9/xlistener/listener_test.go (about) 1 package xlistener 2 3 import ( 4 "crypto/tls" 5 "errors" 6 "net" 7 "testing" 8 9 "github.com/go-kit/kit/metrics/generic" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 "github.com/xmidt-org/webpa-common/logging" 13 ) 14 15 func testNewDefault(t *testing.T) { 16 defer func() { netListen = net.Listen }() 17 18 var ( 19 assert = assert.New(t) 20 require = require.New(t) 21 expectedNext = new(mockListener) 22 ) 23 24 expectedNext.On("Addr").Return(new(net.IPAddr)).Twice() 25 26 netListen = func(network, address string) (net.Listener, error) { 27 assert.Equal("tcp", network) 28 assert.Equal(":http", address) 29 return expectedNext, nil 30 } 31 32 l, err := New(Options{}) 33 require.NoError(err) 34 require.NotNil(l) 35 36 assert.Equal(expectedNext, l.(*listener).Listener) 37 assert.NotNil(l.(*listener).logger) 38 assert.Nil(l.(*listener).semaphore) 39 assert.NotNil(l.(*listener).rejected) 40 assert.NotNil(l.(*listener).active) 41 42 expectedNext.AssertExpectations(t) 43 } 44 45 func testNewCustom(t *testing.T) { 46 defer func() { netListen = net.Listen }() 47 48 var ( 49 assert = assert.New(t) 50 require = require.New(t) 51 52 expectedRejected = generic.NewCounter("test") 53 expectedActive = generic.NewGauge("test") 54 expectedNext = new(mockListener) 55 ) 56 57 expectedNext.On("Addr").Return(new(net.IPAddr)).Twice() 58 59 netListen = func(network, address string) (net.Listener, error) { 60 assert.Equal("tcp4", network) 61 assert.Equal(":8080", address) 62 return expectedNext, nil 63 } 64 65 l, err := New(Options{ 66 Logger: logging.NewTestLogger(nil, t), 67 Rejected: expectedRejected, 68 Active: expectedActive, 69 Network: "tcp4", 70 Address: ":8080", 71 MaxConnections: 10, 72 }) 73 74 require.NoError(err) 75 require.NotNil(l) 76 77 assert.Equal(expectedNext, l.(*listener).Listener) 78 assert.NotNil(l.(*listener).logger) 79 assert.NotNil(l.(*listener).semaphore) 80 81 require.NotNil(l.(*listener).rejected) 82 l.(*listener).rejected.Inc() 83 assert.Equal(1.0, expectedRejected.Value()) 84 85 require.NotNil(l.(*listener).active) 86 l.(*listener).active.Add(10.0) 87 assert.Equal(10.0, expectedActive.Value()) 88 89 expectedNext.AssertExpectations(t) 90 } 91 92 func testNewTLSCustom(t *testing.T) { 93 defer func() { netListen = net.Listen }() 94 95 var ( 96 assert = assert.New(t) 97 require = require.New(t) 98 99 expectedRejected = generic.NewCounter("test") 100 expectedActive = generic.NewGauge("test") 101 expectedNext = new(mockListener) 102 ) 103 104 expectedNext.On("Addr").Return(new(net.IPAddr)).Twice() 105 106 tlsListen = func(network, address string, config *tls.Config) (net.Listener, error) { 107 assert.Equal("tcp4", network) 108 assert.Equal(":8080", address) 109 assert.Equal(true, config.InsecureSkipVerify) 110 return expectedNext, nil 111 } 112 113 l, err := New(Options{ 114 Logger: logging.NewTestLogger(nil, t), 115 Rejected: expectedRejected, 116 Active: expectedActive, 117 Network: "tcp4", 118 Address: ":8080", 119 MaxConnections: 10, 120 Config: &tls.Config{ 121 InsecureSkipVerify: true, 122 }, 123 }) 124 125 require.NoError(err) 126 require.NotNil(l) 127 128 assert.Equal(expectedNext, l.(*listener).Listener) 129 assert.NotNil(l.(*listener).logger) 130 assert.NotNil(l.(*listener).semaphore) 131 132 require.NotNil(l.(*listener).rejected) 133 l.(*listener).rejected.Inc() 134 assert.Equal(1.0, expectedRejected.Value()) 135 136 require.NotNil(l.(*listener).active) 137 l.(*listener).active.Add(10.0) 138 assert.Equal(10.0, expectedActive.Value()) 139 140 expectedNext.AssertExpectations(t) 141 } 142 143 func testNewListenError(t *testing.T) { 144 defer func() { netListen = net.Listen }() 145 146 var ( 147 assert = assert.New(t) 148 expectedError = errors.New("expected") 149 ) 150 151 netListen = func(network, address string) (net.Listener, error) { 152 assert.Equal("tcp", network) 153 assert.Equal(":http", address) 154 return nil, expectedError 155 } 156 157 l, actualError := New(Options{}) 158 assert.Nil(l) 159 assert.Equal(expectedError, actualError) 160 } 161 162 func TestNew(t *testing.T) { 163 t.Run("Default", testNewDefault) 164 t.Run("Custom", testNewCustom) 165 t.Run("tlsCustom", testNewTLSCustom) 166 t.Run("ListenError", testNewListenError) 167 } 168 169 func testListenerAcceptError(t *testing.T, maxConnections int) { 170 defer func() { netListen = net.Listen }() 171 172 var ( 173 assert = assert.New(t) 174 require = require.New(t) 175 176 expectedRejected = generic.NewCounter("test") 177 expectedActive = generic.NewGauge("test") 178 expectedError = errors.New("expected") 179 expectedNext = new(mockListener) 180 ) 181 182 expectedNext.On("Addr").Return(new(net.IPAddr)).Twice() 183 expectedNext.On("Accept").Return(nil, expectedError).Once() 184 185 l, err := New(Options{ 186 Logger: logging.NewTestLogger(nil, t), 187 MaxConnections: maxConnections, 188 Rejected: expectedRejected, 189 Active: expectedActive, 190 Next: expectedNext, 191 }) 192 193 require.NoError(err) 194 require.NotNil(l) 195 196 c, actualError := l.Accept() 197 assert.Nil(c) 198 assert.Equal(expectedError, actualError) 199 assert.Equal(0.0, expectedRejected.Value()) 200 assert.Equal(0.0, expectedActive.Value()) 201 202 expectedNext.AssertExpectations(t) 203 } 204 205 func testListenerAcceptUnlimitedConnections(t *testing.T) { 206 defer func() { netListen = net.Listen }() 207 208 var ( 209 assert = assert.New(t) 210 require = require.New(t) 211 212 expectedRejected = generic.NewCounter("test") 213 expectedActive = generic.NewGauge("test") 214 expectedNext = new(mockListener) 215 216 expectedConn1 = new(mockConn) 217 expectedConn2 = new(mockConn) 218 expectedConnCloseError = errors.New("expected") 219 ) 220 221 expectedNext.On("Addr").Return(new(net.IPAddr)).Twice() 222 expectedConn1.On("RemoteAddr").Return(new(net.IPAddr)).Once() 223 expectedConn2.On("RemoteAddr").Return(new(net.IPAddr)).Once() 224 225 expectedNext.On("Accept").Return(expectedConn1, error(nil)).Once() 226 expectedNext.On("Accept").Return(expectedConn2, error(nil)).Once() 227 228 expectedConn1.On("Close").Return(error(nil)).Once() 229 expectedConn1.On("Close").Return(expectedConnCloseError).Once() 230 expectedConn2.On("Close").Return(error(nil)).Once() 231 expectedConn2.On("Close").Return(expectedConnCloseError).Once() 232 233 l, err := New(Options{ 234 Logger: logging.NewTestLogger(nil, t), 235 Rejected: expectedRejected, 236 Active: expectedActive, 237 Next: expectedNext, 238 }) 239 240 require.NoError(err) 241 require.NotNil(l) 242 243 assert.Zero(expectedRejected.Value()) 244 assert.Zero(expectedActive.Value()) 245 246 actualConn1, actualError := l.Accept() 247 assert.NoError(actualError) 248 require.NotNil(actualConn1) 249 assert.Zero(expectedRejected.Value()) 250 assert.Equal(1.0, expectedActive.Value()) 251 252 actualConn2, actualError := l.Accept() 253 assert.NoError(actualError) 254 require.NotNil(actualConn2) 255 assert.Zero(expectedRejected.Value()) 256 assert.Equal(2.0, expectedActive.Value()) 257 258 assert.NoError(actualConn1.Close()) 259 assert.Zero(expectedRejected.Value()) 260 assert.Equal(1.0, expectedActive.Value()) 261 262 assert.Equal(expectedConnCloseError, actualConn1.Close()) 263 assert.Zero(expectedRejected.Value()) 264 assert.Equal(1.0, expectedActive.Value()) 265 266 assert.NoError(actualConn2.Close()) 267 assert.Zero(expectedRejected.Value()) 268 assert.Zero(expectedActive.Value()) 269 270 assert.Equal(expectedConnCloseError, actualConn2.Close()) 271 assert.Zero(expectedRejected.Value()) 272 assert.Zero(expectedActive.Value()) 273 274 expectedNext.AssertExpectations(t) 275 expectedConn1.AssertExpectations(t) 276 expectedConn2.AssertExpectations(t) 277 } 278 279 func testListenerAcceptMaxConnections(t *testing.T) { 280 defer func() { netListen = net.Listen }() 281 282 var ( 283 assert = assert.New(t) 284 require = require.New(t) 285 286 expectedRejected = generic.NewCounter("test") 287 expectedActive = generic.NewGauge("test") 288 expectedNext = new(mockListener) 289 290 expectedConn1 = new(mockConn) 291 rejectedConn = new(mockConn) 292 expectedConn2 = new(mockConn) 293 expectedConnCloseError = errors.New("expected close error") 294 expectedAcceptError = errors.New("expected accept error") 295 ) 296 297 expectedNext.On("Addr").Return(new(net.IPAddr)).Twice() 298 expectedConn1.On("RemoteAddr").Return(new(net.IPAddr)).Once() 299 rejectedConn.On("RemoteAddr").Return(new(net.IPAddr)).Once() 300 expectedConn2.On("RemoteAddr").Return(new(net.IPAddr)).Once() 301 302 expectedNext.On("Accept").Return(expectedConn1, error(nil)).Once() 303 expectedNext.On("Accept").Return(rejectedConn, error(nil)).Once() 304 expectedNext.On("Accept").Return(nil, expectedAcceptError).Once() 305 expectedNext.On("Accept").Return(expectedConn2, error(nil)).Once() 306 307 expectedConn1.On("Close").Return(error(nil)).Once() 308 expectedConn1.On("Close").Return(expectedConnCloseError).Once() 309 rejectedConn.On("Close").Return(error(nil)).Once() // this should be closed as part of rejecting the connection 310 expectedConn2.On("Close").Return(error(nil)).Once() 311 expectedConn2.On("Close").Return(expectedConnCloseError).Once() 312 313 l, err := New(Options{ 314 Logger: logging.NewTestLogger(nil, t), 315 MaxConnections: 1, 316 Rejected: expectedRejected, 317 Active: expectedActive, 318 Next: expectedNext, 319 }) 320 321 require.NoError(err) 322 require.NotNil(l) 323 324 assert.Zero(expectedRejected.Value()) 325 assert.Zero(expectedActive.Value()) 326 327 actualConn1, actualError := l.Accept() 328 assert.NoError(actualError) 329 require.NotNil(actualConn1) 330 assert.Zero(expectedRejected.Value()) 331 assert.Equal(1.0, expectedActive.Value()) 332 333 actualRejectedConn, actualError := l.Accept() 334 assert.Equal(expectedAcceptError, actualError) 335 assert.Nil(actualRejectedConn) 336 assert.Equal(1.0, expectedRejected.Value()) 337 assert.Equal(1.0, expectedActive.Value()) 338 339 assert.NoError(actualConn1.Close()) 340 assert.Equal(1.0, expectedRejected.Value()) 341 assert.Zero(expectedActive.Value()) 342 343 assert.Equal(expectedConnCloseError, actualConn1.Close()) 344 assert.Equal(1.0, expectedRejected.Value()) 345 assert.Zero(expectedActive.Value()) 346 347 // now, a new connection should be possible 348 actualConn2, actualError := l.Accept() 349 assert.NoError(actualError) 350 require.NotNil(actualConn2) 351 assert.Equal(1.0, expectedRejected.Value()) 352 assert.Equal(1.0, expectedActive.Value()) 353 354 assert.NoError(actualConn2.Close()) 355 assert.Equal(1.0, expectedRejected.Value()) 356 assert.Zero(expectedActive.Value()) 357 358 assert.Equal(expectedConnCloseError, actualConn2.Close()) 359 assert.Equal(1.0, expectedRejected.Value()) 360 assert.Zero(expectedActive.Value()) 361 362 expectedNext.AssertExpectations(t) 363 expectedConn1.AssertExpectations(t) 364 rejectedConn.AssertExpectations(t) 365 expectedConn2.AssertExpectations(t) 366 } 367 368 func TestListener(t *testing.T) { 369 t.Run("Accept", func(t *testing.T) { 370 t.Run("Error", func(t *testing.T) { 371 t.Run("UnlimitedConnections", func(t *testing.T) { testListenerAcceptError(t, 0) }) 372 t.Run("MaxConnections", func(t *testing.T) { testListenerAcceptError(t, 1) }) 373 }) 374 375 t.Run("Success", func(t *testing.T) { 376 t.Run("UnlimitedConnections", testListenerAcceptUnlimitedConnections) 377 t.Run("MaxConnections", testListenerAcceptMaxConnections) 378 }) 379 }) 380 }