github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/exec/timeout_step_test.go (about) 1 package exec_test 2 3 import ( 4 "context" 5 "errors" 6 "time" 7 8 . "github.com/pf-qiu/concourse/v6/atc/exec" 9 "github.com/pf-qiu/concourse/v6/atc/exec/build" 10 "github.com/pf-qiu/concourse/v6/atc/exec/execfakes" 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 ) 14 15 var _ = Describe("Timeout Step", func() { 16 var ( 17 ctx context.Context 18 cancel func() 19 20 fakeStep *execfakes.FakeStep 21 22 repo *build.Repository 23 state *execfakes.FakeRunState 24 25 step Step 26 27 timeoutDuration string 28 29 stepOk bool 30 stepErr error 31 ) 32 33 BeforeEach(func() { 34 ctx, cancel = context.WithCancel(context.Background()) 35 36 fakeStep = new(execfakes.FakeStep) 37 38 repo = build.NewRepository() 39 state = new(execfakes.FakeRunState) 40 state.ArtifactRepositoryReturns(repo) 41 42 timeoutDuration = "1h" 43 }) 44 45 JustBeforeEach(func() { 46 step = Timeout(fakeStep, timeoutDuration) 47 stepOk, stepErr = step.Run(ctx, state) 48 }) 49 50 Context("when the duration is valid", func() { 51 It("runs the step with a deadline", func() { 52 runCtx, _ := fakeStep.RunArgsForCall(0) 53 deadline, ok := runCtx.Deadline() 54 Expect(ok).To(BeTrue()) 55 Expect(deadline).To(BeTemporally("~", time.Now().Add(time.Hour), 10*time.Second)) 56 }) 57 58 Context("when the step returns an error", func() { 59 var someError error 60 61 BeforeEach(func() { 62 someError = errors.New("some error") 63 fakeStep.RunReturns(false, someError) 64 }) 65 66 It("returns the error", func() { 67 Expect(stepErr).NotTo(BeNil()) 68 Expect(stepErr).To(Equal(someError)) 69 }) 70 }) 71 72 Context("when the step exceeds the timeout", func() { 73 BeforeEach(func() { 74 fakeStep.RunReturns(true, context.DeadlineExceeded) 75 }) 76 77 It("returns no error", func() { 78 Expect(stepErr).ToNot(HaveOccurred()) 79 }) 80 81 It("is not successful", func() { 82 Expect(stepOk).To(BeFalse()) 83 }) 84 }) 85 86 Describe("canceling", func() { 87 BeforeEach(func() { 88 cancel() 89 }) 90 91 It("forwards the context down", func() { 92 runCtx, _ := fakeStep.RunArgsForCall(0) 93 Expect(runCtx.Err()).To(Equal(context.Canceled)) 94 }) 95 96 It("is not successful", func() { 97 Expect(stepOk).To(BeFalse()) 98 }) 99 }) 100 101 Context("when the step is successful", func() { 102 BeforeEach(func() { 103 fakeStep.RunReturns(true, nil) 104 }) 105 106 It("is successful", func() { 107 Expect(stepOk).To(BeTrue()) 108 }) 109 }) 110 111 Context("when the step fails", func() { 112 BeforeEach(func() { 113 fakeStep.RunReturns(false, nil) 114 }) 115 116 It("is not successful", func() { 117 Expect(stepOk).To(BeFalse()) 118 }) 119 }) 120 }) 121 122 Context("when the duration is invalid", func() { 123 BeforeEach(func() { 124 timeoutDuration = "nope" 125 }) 126 127 It("errors immediately without running the step", func() { 128 Expect(stepErr).To(HaveOccurred()) 129 Expect(fakeStep.RunCallCount()).To(BeZero()) 130 }) 131 }) 132 })