github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/worker/transport/hijackable_client_test.go (about)

     1  package transport_test
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  	"net/url"
     7  	"time"
     8  
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  
    12  	"github.com/pf-qiu/concourse/v6/atc/db"
    13  	"github.com/pf-qiu/concourse/v6/atc/db/dbfakes"
    14  	"github.com/pf-qiu/concourse/v6/atc/worker/transport"
    15  	"github.com/pf-qiu/concourse/v6/atc/worker/transport/transportfakes"
    16  	"github.com/concourse/retryhttp"
    17  	"github.com/concourse/retryhttp/retryhttpfakes"
    18  )
    19  
    20  var _ = Describe("HijackableClient #Do", func() {
    21  	var (
    22  		request              http.Request
    23  		fakeDB               *transportfakes.FakeTransportDB
    24  		savedWorker          *dbfakes.FakeWorker
    25  		savedWorkerAddress   string
    26  		fakeHijackableClient *retryhttpfakes.FakeHijackableClient
    27  		hijackableClient     retryhttp.HijackableClient
    28  		response             *http.Response
    29  		err                  error
    30  		fakeHijackCloser     *retryhttpfakes.FakeHijackCloser
    31  		actualHijackCloser   retryhttp.HijackCloser
    32  	)
    33  
    34  	BeforeEach(func() {
    35  		fakeDB = new(transportfakes.FakeTransportDB)
    36  		fakeHijackableClient = new(retryhttpfakes.FakeHijackableClient)
    37  		fakeHijackCloser = new(retryhttpfakes.FakeHijackCloser)
    38  		hijackableClient = transport.NewHijackableClient("some-worker", fakeDB, fakeHijackableClient)
    39  		requestUrl, err := url.Parse("http://1.2.3.4/something")
    40  		Expect(err).NotTo(HaveOccurred())
    41  
    42  		request = http.Request{
    43  			URL: requestUrl,
    44  		}
    45  
    46  		savedWorkerAddress = "some-garden-addr"
    47  		savedWorker = new(dbfakes.FakeWorker)
    48  		savedWorker.GardenAddrReturns(&savedWorkerAddress)
    49  		savedWorker.ExpiresAtReturns(time.Now().Add(123 * time.Minute))
    50  		savedWorker.StateReturns(db.WorkerStateRunning)
    51  
    52  		fakeDB.GetWorkerReturns(savedWorker, true, nil)
    53  
    54  		fakeHijackableClient.DoReturns(&http.Response{StatusCode: http.StatusTeapot}, fakeHijackCloser, nil)
    55  	})
    56  
    57  	JustBeforeEach(func() {
    58  		response, actualHijackCloser, err = hijackableClient.Do(&request)
    59  	})
    60  
    61  	It("returns the response", func() {
    62  		Expect(err).NotTo(HaveOccurred())
    63  		Expect(actualHijackCloser).To(Equal(fakeHijackCloser))
    64  		Expect(response).To(Equal(&http.Response{StatusCode: http.StatusTeapot}))
    65  	})
    66  
    67  	It("sends the request with worker's garden address", func() {
    68  		Expect(fakeHijackableClient.DoCallCount()).To(Equal(1))
    69  		actualRequest := fakeHijackableClient.DoArgsForCall(0)
    70  		Expect(actualRequest.URL.Host).To(Equal(*savedWorker.GardenAddr()))
    71  		Expect(actualRequest.URL.Path).To(Equal("/something"))
    72  	})
    73  
    74  	Context("when the lookup of the worker in the db errors", func() {
    75  		var expectedErr error
    76  		BeforeEach(func() {
    77  			expectedErr = errors.New("some-db-error")
    78  			fakeDB.GetWorkerReturns(nil, true, expectedErr)
    79  		})
    80  
    81  		It("throws an error", func() {
    82  			Expect(err).To(HaveOccurred())
    83  			Expect(err.Error()).To(ContainSubstring(expectedErr.Error()))
    84  		})
    85  	})
    86  
    87  	Context("when the worker is not found in the db", func() {
    88  		BeforeEach(func() {
    89  			fakeDB.GetWorkerReturns(nil, false, nil)
    90  		})
    91  
    92  		It("throws an error", func() {
    93  			Expect(err).To(HaveOccurred())
    94  			Expect(err).To(Equal(transport.WorkerMissingError{WorkerName: "some-worker"}))
    95  		})
    96  	})
    97  
    98  	Context("when the worker is stalled in the db", func() {
    99  		BeforeEach(func() {
   100  			stalledWorker := new(dbfakes.FakeWorker)
   101  			stalledWorker.StateReturns(db.WorkerStateStalled)
   102  			fakeDB.GetWorkerReturns(stalledWorker, true, nil)
   103  		})
   104  
   105  		It("throws a descriptive error", func() {
   106  			Expect(err).To(HaveOccurred())
   107  			Expect(err).To(Equal(transport.WorkerUnreachableError{
   108  				WorkerName:  "some-worker",
   109  				WorkerState: "stalled",
   110  			}))
   111  		})
   112  	})
   113  
   114  	It("reuses the request cached host on subsequent calls", func() {
   115  		Expect(fakeDB.GetWorkerCallCount()).To(Equal(1))
   116  		_, _, err := hijackableClient.Do(&request)
   117  		Expect(err).NotTo(HaveOccurred())
   118  		Expect(fakeDB.GetWorkerCallCount()).To(Equal(1))
   119  	})
   120  
   121  	Context("when inner Do fails", func() {
   122  		BeforeEach(func() {
   123  			fakeHijackableClient.DoReturns(nil, nil, errors.New("some-error"))
   124  		})
   125  
   126  		It("updates cached request host", func() {
   127  			Expect(fakeDB.GetWorkerCallCount()).To(Equal(1))
   128  			_, _, err := hijackableClient.Do(&request)
   129  			Expect(err).To(HaveOccurred())
   130  			Expect(fakeDB.GetWorkerCallCount()).To(Equal(2))
   131  		})
   132  	})
   133  })