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  }