github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/exec/retry_error_step_test.go (about)

     1  package exec_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"net"
     8  	"net/url"
     9  
    10  	. "github.com/pf-qiu/concourse/v6/atc/exec"
    11  	"github.com/pf-qiu/concourse/v6/atc/exec/build"
    12  	"github.com/pf-qiu/concourse/v6/atc/exec/execfakes"
    13  	"github.com/pf-qiu/concourse/v6/atc/worker/transport"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  )
    17  
    18  var _ = Describe("RetryErrorStep", func() {
    19  	var (
    20  		ctx    context.Context
    21  		cancel func()
    22  
    23  		fakeStep *execfakes.FakeStep
    24  
    25  		fakeDelegate        *execfakes.FakeBuildStepDelegate
    26  		fakeDelegateFactory *execfakes.FakeBuildStepDelegateFactory
    27  
    28  		repo  *build.Repository
    29  		state *execfakes.FakeRunState
    30  
    31  		step Step
    32  	)
    33  
    34  	BeforeEach(func() {
    35  		ctx, cancel = context.WithCancel(context.Background())
    36  
    37  		fakeStep = new(execfakes.FakeStep)
    38  		fakeDelegate = new(execfakes.FakeBuildStepDelegate)
    39  		fakeDelegateFactory = new(execfakes.FakeBuildStepDelegateFactory)
    40  		fakeDelegateFactory.BuildStepDelegateReturns(fakeDelegate)
    41  
    42  		repo = build.NewRepository()
    43  		state = new(execfakes.FakeRunState)
    44  		state.ArtifactRepositoryReturns(repo)
    45  
    46  		step = RetryError(fakeStep, fakeDelegateFactory)
    47  	})
    48  
    49  	AfterEach(func() {
    50  		cancel()
    51  	})
    52  
    53  	Describe("Run", func() {
    54  		var runOk bool
    55  		var runErr error
    56  
    57  		JustBeforeEach(func() {
    58  			runOk, runErr = step.Run(ctx, state)
    59  		})
    60  
    61  		Context("when the inner step does not error", func() {
    62  			BeforeEach(func() {
    63  				fakeStep.RunReturns(true, nil)
    64  			})
    65  
    66  			It("returns nil", func() {
    67  				Expect(runErr).To(BeNil())
    68  			})
    69  
    70  			It("does not log", func() {
    71  				Expect(fakeDelegate.ErroredCallCount()).To(Equal(0))
    72  			})
    73  		})
    74  
    75  		Context("when aborted", func() {
    76  			BeforeEach(func() {
    77  				fakeStep.RunReturns(false, context.Canceled)
    78  			})
    79  
    80  			It("propagates the error", func() {
    81  				Expect(runErr).To(Equal(context.Canceled))
    82  			})
    83  		})
    84  
    85  		Context("when worker disappeared", func() {
    86  			cause := transport.WorkerMissingError{WorkerName: "some-worker"}
    87  			BeforeEach(func() {
    88  				fakeStep.RunReturns(false, cause)
    89  			})
    90  
    91  			It("should return retriable", func() {
    92  				Expect(runErr).To(Equal(Retriable{cause}))
    93  			})
    94  
    95  			It("logs 'timeout exceeded'", func() {
    96  				Expect(fakeDelegate.ErroredCallCount()).To(Equal(1))
    97  				_, message := fakeDelegate.ErroredArgsForCall(0)
    98  				Expect(message).To(Equal(fmt.Sprintf("%s, will retry ...", cause.Error())))
    99  			})
   100  
   101  			Context("when build aborted", func(){
   102  				BeforeEach(func(){
   103  					cancel()
   104  				})
   105  
   106  				It("should not retry", func(){
   107  					Expect(runErr).To(Equal(cause))
   108  				})
   109  			})
   110  		})
   111  
   112  		Context("when url.Error error happened", func() {
   113  			cause := &url.Error{Op: "error", URL: "err", Err: errors.New("error")}
   114  			BeforeEach(func() {
   115  				fakeStep.RunReturns(false, cause)
   116  			})
   117  
   118  			It("should return retriable", func() {
   119  				Expect(runErr).To(Equal(Retriable{cause}))
   120  			})
   121  		})
   122  
   123  		Context("when net.Error error happened", func() {
   124  			cause := &net.OpError{Op: "read", Net: "test", Source: nil, Addr: nil, Err: errors.New("test")}
   125  			BeforeEach(func() {
   126  				fakeStep.RunReturns(false, cause)
   127  			})
   128  
   129  			It("should return retriable", func() {
   130  				Expect(runErr).To(Equal(Retriable{cause}))
   131  			})
   132  		})
   133  
   134  		Context("when the inner step returns any other error", func() {
   135  			disaster := errors.New("disaster")
   136  
   137  			BeforeEach(func() {
   138  				fakeStep.RunReturns(false, disaster)
   139  			})
   140  
   141  			It("propagates the error", func() {
   142  				Expect(runErr).To(Equal(disaster))
   143  			})
   144  		})
   145  
   146  		Context("when the wrapped step has succeeded", func() {
   147  			BeforeEach(func() {
   148  				fakeStep.RunReturns(true, nil)
   149  			})
   150  
   151  			It("returns true", func() {
   152  				Expect(runOk).Should(BeTrue())
   153  			})
   154  		})
   155  
   156  		Context("when the wrapped step has failed", func() {
   157  			BeforeEach(func() {
   158  				fakeStep.RunReturns(false, nil)
   159  			})
   160  
   161  			It("returns true", func() {
   162  				Expect(runOk).Should(BeFalse())
   163  			})
   164  		})
   165  	})
   166  })