github.com/chenbh/concourse/v6@v6.4.2/atc/wrappa/concurrent_request_limits_wrappa_test.go (about)

     1  package wrappa_test
     2  
     3  import (
     4  	"net/http"
     5  	"net/http/httptest"
     6  
     7  	"code.cloudfoundry.org/lager"
     8  	"code.cloudfoundry.org/lager/lagertest"
     9  	"github.com/chenbh/concourse/v6/atc"
    10  	"github.com/chenbh/concourse/v6/atc/metric"
    11  	"github.com/chenbh/concourse/v6/atc/wrappa"
    12  	"github.com/chenbh/concourse/v6/atc/wrappa/wrappafakes"
    13  
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  	. "github.com/onsi/gomega/gstruct"
    17  )
    18  
    19  var _ = Describe("Concurrent Request Limits Wrappa", func() {
    20  	var (
    21  		fakeHandler *wrappafakes.FakeHandler
    22  		fakePolicy  *wrappafakes.FakeConcurrentRequestPolicy
    23  		fakePool    *wrappafakes.FakePool
    24  		testLogger  *lagertest.TestLogger
    25  		handler     http.Handler
    26  		request     *http.Request
    27  	)
    28  
    29  	BeforeEach(func() {
    30  		fakeHandler = new(wrappafakes.FakeHandler)
    31  		testLogger = lagertest.NewTestLogger("test")
    32  		request, _ = http.NewRequest("GET", "localhost:8080", nil)
    33  	})
    34  
    35  	AfterEach(func() {
    36  		metric.ConcurrentRequests = map[string]*metric.Gauge{}
    37  	})
    38  
    39  	givenConcurrentRequestLimit := func(limit int) {
    40  		fakePolicy = new(wrappafakes.FakeConcurrentRequestPolicy)
    41  		fakePool = new(wrappafakes.FakePool)
    42  		fakePolicy.HandlerPoolReturns(fakePool, true)
    43  		fakePool.SizeReturns(limit)
    44  
    45  		handler = wrappa.NewConcurrentRequestLimitsWrappa(testLogger, fakePolicy).
    46  			Wrap(map[string]http.Handler{
    47  				atc.ListAllJobs: fakeHandler,
    48  			})[atc.ListAllJobs]
    49  	}
    50  
    51  	Context("when the limit is reached", func() {
    52  		BeforeEach(func() {
    53  			givenConcurrentRequestLimit(1)
    54  			fakePool.TryAcquireReturns(false)
    55  		})
    56  
    57  		It("responds with a 503", func() {
    58  			recorder := httptest.NewRecorder()
    59  			handler.ServeHTTP(recorder, request)
    60  
    61  			Expect(recorder.Code).To(Equal(http.StatusServiceUnavailable))
    62  		})
    63  
    64  		It("logs an INFO message", func() {
    65  			handler.ServeHTTP(httptest.NewRecorder(), request)
    66  
    67  			Expect(testLogger.Logs()).To(ConsistOf(
    68  				MatchFields(IgnoreExtras, Fields{
    69  					"Message":  Equal("test.concurrent-request-limit-reached"),
    70  					"LogLevel": Equal(lager.INFO),
    71  				}),
    72  			))
    73  		})
    74  
    75  		It("increments the 'limitHit' counter", func() {
    76  			handler.ServeHTTP(httptest.NewRecorder(), request)
    77  			handler.ServeHTTP(httptest.NewRecorder(), request)
    78  
    79  			Expect(metric.ConcurrentRequestsLimitHit[atc.ListAllJobs].Delta()).To(Equal(float64(2)))
    80  		})
    81  	})
    82  
    83  	Context("when the limit is not reached", func() {
    84  		BeforeEach(func() {
    85  			givenConcurrentRequestLimit(1)
    86  			fakePool.TryAcquireReturns(true)
    87  		})
    88  
    89  		It("invokes the wrapped handler", func() {
    90  			handler.ServeHTTP(httptest.NewRecorder(), request)
    91  
    92  			Expect(fakeHandler.ServeHTTPCallCount()).To(Equal(1), "wrapped handler not invoked")
    93  		})
    94  
    95  		It("releases the pool", func() {
    96  			handler.ServeHTTP(httptest.NewRecorder(), request)
    97  
    98  			Expect(fakePool.ReleaseCallCount()).To(Equal(1))
    99  		})
   100  
   101  		It("records the number of requests in-flight", func() {
   102  			handler.ServeHTTP(httptest.NewRecorder(), request)
   103  			handler.ServeHTTP(httptest.NewRecorder(), request)
   104  
   105  			Expect(metric.ConcurrentRequests[atc.ListAllJobs].Max()).To(Equal(float64(1)))
   106  		})
   107  	})
   108  
   109  	Context("when the endpoint is disabled", func() {
   110  		BeforeEach(func() {
   111  			givenConcurrentRequestLimit(0)
   112  		})
   113  
   114  		It("responds with a 501", func() {
   115  			recorder := httptest.NewRecorder()
   116  			handler.ServeHTTP(recorder, request)
   117  
   118  			Expect(recorder.Code).To(Equal(http.StatusNotImplemented))
   119  		})
   120  
   121  		It("logs a DEBUG message", func() {
   122  			handler.ServeHTTP(httptest.NewRecorder(), request)
   123  
   124  			Expect(testLogger.Logs()).To(ConsistOf(
   125  				MatchFields(IgnoreExtras, Fields{
   126  					"Message":  Equal("test.endpoint-disabled"),
   127  					"LogLevel": Equal(lager.DEBUG),
   128  				}),
   129  			))
   130  		})
   131  
   132  		It("increments the 'limitHit' counter", func() {
   133  			handler.ServeHTTP(httptest.NewRecorder(), request)
   134  			handler.ServeHTTP(httptest.NewRecorder(), request)
   135  
   136  			Expect(metric.ConcurrentRequestsLimitHit[atc.ListAllJobs].Delta()).To(Equal(float64(2)))
   137  		})
   138  	})
   139  })