1package exec_test 2 3import ( 4 "context" 5 "errors" 6 7 "github.com/concourse/concourse/atc/exec" 8 "github.com/concourse/concourse/atc/exec/build" 9 "github.com/concourse/concourse/atc/exec/execfakes" 10 . "github.com/onsi/ginkgo" 11 . "github.com/onsi/gomega" 12) 13 14var _ = Describe("On Failure Step", func() { 15 var ( 16 ctx context.Context 17 cancel func() 18 19 step *execfakes.FakeStep 20 hook *execfakes.FakeStep 21 22 repo *build.Repository 23 state *execfakes.FakeRunState 24 25 onFailureStep exec.Step 26 27 stepErr error 28 ) 29 30 BeforeEach(func() { 31 ctx, cancel = context.WithCancel(context.Background()) 32 33 step = &execfakes.FakeStep{} 34 hook = &execfakes.FakeStep{} 35 36 repo = build.NewRepository() 37 state = new(execfakes.FakeRunState) 38 state.ArtifactRepositoryReturns(repo) 39 40 onFailureStep = exec.OnFailure(step, hook) 41 }) 42 43 AfterEach(func() { 44 cancel() 45 }) 46 47 JustBeforeEach(func() { 48 stepErr = onFailureStep.Run(ctx, state) 49 }) 50 51 Context("when the step fails", func() { 52 BeforeEach(func() { 53 step.SucceededReturns(false) 54 }) 55 56 It("runs the failure hook", func() { 57 Expect(step.RunCallCount()).To(Equal(1)) 58 Expect(hook.RunCallCount()).To(Equal(1)) 59 }) 60 61 It("runs the hook with the run state", func() { 62 Expect(hook.RunCallCount()).To(Equal(1)) 63 64 _, argsState := hook.RunArgsForCall(0) 65 Expect(argsState).To(Equal(state)) 66 }) 67 68 It("propagates the context to the hook", func() { 69 runCtx, _ := hook.RunArgsForCall(0) 70 Expect(runCtx).To(Equal(ctx)) 71 }) 72 73 It("succeeds", func() { 74 Expect(stepErr).ToNot(HaveOccurred()) 75 }) 76 }) 77 78 Context("when the step errors", func() { 79 disaster := errors.New("disaster") 80 81 BeforeEach(func() { 82 step.RunReturns(disaster) 83 }) 84 85 It("does not run the failure hook", func() { 86 Expect(step.RunCallCount()).To(Equal(1)) 87 Expect(hook.RunCallCount()).To(Equal(0)) 88 }) 89 90 It("returns the error", func() { 91 Expect(stepErr).To(Equal(disaster)) 92 }) 93 }) 94 95 Context("when the step succeeds", func() { 96 BeforeEach(func() { 97 step.SucceededReturns(true) 98 }) 99 100 It("does not run the failure hook", func() { 101 Expect(step.RunCallCount()).To(Equal(1)) 102 Expect(hook.RunCallCount()).To(Equal(0)) 103 }) 104 105 It("returns nil", func() { 106 Expect(stepErr).To(BeNil()) 107 }) 108 }) 109 110 It("propagates the context to the step", func() { 111 runCtx, _ := step.RunArgsForCall(0) 112 Expect(runCtx).To(Equal(ctx)) 113 }) 114 115 Describe("Succeeded", func() { 116 Context("when step fails and hook fails", func() { 117 BeforeEach(func() { 118 step.SucceededReturns(false) 119 hook.SucceededReturns(false) 120 }) 121 122 It("returns false", func() { 123 Expect(onFailureStep.Succeeded()).To(BeFalse()) 124 }) 125 }) 126 127 Context("when step fails and hook succeeds", func() { 128 BeforeEach(func() { 129 step.SucceededReturns(false) 130 hook.SucceededReturns(true) 131 }) 132 133 It("returns false", func() { 134 Expect(onFailureStep.Succeeded()).To(BeFalse()) 135 }) 136 }) 137 138 Context("when step succeeds", func() { 139 BeforeEach(func() { 140 step.SucceededReturns(true) 141 }) 142 143 It("returns true", func() { 144 Expect(onFailureStep.Succeeded()).To(BeTrue()) 145 }) 146 }) 147 }) 148}) 149