// internal check for success within retry loop Expect(attempt3Step.ResultCallCount()).To(Equal(1)) attempt3Step.ResultReturns(true) var foo interface{} destination := &foo Expect(step.Result(destination)).To(BeTrue()) Expect(attempt3Step.ResultCallCount()).To(Equal(2)) Expect(attempt3Step.ResultArgsForCall(1)).To(Equal(destination)) }) }) }) }) Describe("releasing", func() { It("releases all sources", func() { Expect(attempt1Step.ReleaseCallCount()).To(Equal(0)) Expect(attempt2Step.ReleaseCallCount()).To(Equal(0)) Expect(attempt3Step.ReleaseCallCount()).To(Equal(0)) step.Release() Expect(attempt1Step.ReleaseCallCount()).To(Equal(1)) Expect(attempt2Step.ReleaseCallCount()).To(Equal(1)) Expect(attempt3Step.ReleaseCallCount()).To(Equal(1)) }) }) })
Task: &atc.TaskPlan{ Name: "some-resource", Config: &atc.TaskConfig{}, }, }, }, } build, err := execEngine.CreateBuild(logger, buildModel, plan) Expect(err).NotTo(HaveOccurred()) build.Resume(logger) Expect(inputStep.RunCallCount()).To(Equal(1)) Expect(inputStep.ReleaseCallCount()).To(Equal(1)) Expect(taskStep.RunCallCount()).To(Equal(1)) Expect(taskStep.ReleaseCallCount()).To(Equal(1)) }) It("runs the success hooks, and completion hooks", func() { plan := atc.Plan{ Location: &atc.Location{}, Ensure: &atc.EnsurePlan{ Step: atc.Plan{ OnSuccess: &atc.OnSuccessPlan{ Step: atc.Plan{ Location: &atc.Location{}, Get: &atc.GetPlan{ Name: "some-input",
ensureStep.Run(signals, ready) ensureStep.Result(&succeeded) Expect(bool(succeeded)).To(BeFalse()) }) }) }) Describe("Release", func() { var ( signals chan os.Signal ready chan struct{} ) Context("when both step and hook are run", func() { BeforeEach(func() { signals = make(chan os.Signal, 1) ready = make(chan struct{}, 1) step.ResultStub = successResult(true) }) It("calls release on both step and hook", func() { ensureStep.Run(signals, ready) ensureStep.Release() Expect(step.ReleaseCallCount()).To(Equal(1)) Expect(hook.ReleaseCallCount()).To(Equal(1)) }) }) }) }) })
BeforeEach(func() { assertNotReleased := func(signals <-chan os.Signal, ready chan<- struct{}) error { defer GinkgoRecover() Consistently(inputStep.ReleaseCallCount).Should(BeZero()) Consistently(taskStep.ReleaseCallCount).Should(BeZero()) Consistently(outputStep.ReleaseCallCount).Should(BeZero()) return nil } inputStep.RunStub = assertNotReleased taskStep.RunStub = assertNotReleased outputStep.RunStub = assertNotReleased }) It("releases all sources", func() { Ω(inputStep.ReleaseCallCount()).Should(Equal(1)) Ω(taskStep.ReleaseCallCount()).Should(Equal(1)) Ω(outputStep.ReleaseCallCount()).Should(BeNumerically(">", 0)) }) }) Context("when the task is privileged", func() { BeforeEach(func() { privileged = true }) It("constructs the task step privileged", func() { Ω(fakeFactory.TaskCallCount()).Should(Equal(1)) _, _, _, privileged, _, _ := fakeFactory.TaskArgsForCall(0) Ω(privileged).Should(Equal(exec.Privileged(true)))
var ( signals chan os.Signal ready chan struct{} ) Context("when both step and hook are run", func() { BeforeEach(func() { signals = make(chan os.Signal, 1) ready = make(chan struct{}, 1) step.ResultStub = successResult(true) }) It("calls release on both step and hook", func() { onSuccessStep.Run(signals, ready) onSuccessStep.Release() Ω(step.ReleaseCallCount()).Should(Equal(1)) Ω(hook.ReleaseCallCount()).Should(Equal(1)) }) }) Context("when only step runs", func() { BeforeEach(func() { signals = make(chan os.Signal, 1) ready = make(chan struct{}, 1) step.ResultStub = successResult(false) }) It("calls release on step", func() { onSuccessStep.Run(signals, ready) onSuccessStep.Release() Ω(step.ReleaseCallCount()).Should(Equal(1)) Ω(hook.ReleaseCallCount()).Should(Equal(0))
BeforeEach(func() { assertNotReleased := func(signals <-chan os.Signal, ready chan<- struct{}) error { defer GinkgoRecover() Consistently(inputStep.ReleaseCallCount).Should(BeZero()) Consistently(taskStep.ReleaseCallCount).Should(BeZero()) Consistently(outputStep.ReleaseCallCount).Should(BeZero()) return nil } inputStep.RunStub = assertNotReleased taskStep.RunStub = assertNotReleased outputStep.RunStub = assertNotReleased }) It("releases all sources", func() { Ω(inputStep.ReleaseCallCount()).Should(Equal(1)) Ω(taskStep.ReleaseCallCount()).Should(Equal(1)) Ω(outputStep.ReleaseCallCount()).Should(Equal(3)) // put + get }) }) Context("when the task is privileged", func() { BeforeEach(func() { privileged = true }) It("constructs the task step privileged", func() { Ω(fakeFactory.TaskCallCount()).Should(Equal(1)) _, _, _, privileged, _, _ := fakeFactory.TaskArgsForCall(0) Ω(privileged).Should(Equal(exec.Privileged(true)))
step = conditional.Using(inStep, repo) process = ifrit.Invoke(step) }) itDoesNothing := func() { It("succeeds", func() { Eventually(process.Wait()).Should(Receive(BeNil())) }) It("does not use the step's artifact source", func() { Ω(fakeStepFactory.UsingCallCount()).Should(BeZero()) }) Describe("releasing", func() { It("does not release the input source", func() { Ω(inStep.ReleaseCallCount()).Should(Equal(0)) }) }) Describe("getting the result", func() { It("fails", func() { var success Success Ω(step.Result(&success)).Should(BeFalse()) }) }) } itDoesAThing := func() { It("succeeds", func() { Eventually(process.Wait()).Should(Receive(BeNil())) })
Location: &atc.Location{}, Task: &atc.TaskPlan{ Name: "some-resource", Config: &atc.TaskConfig{}, }, }, }, } build, err := execEngine.CreateBuild(buildModel, plan) Ω(err).ShouldNot(HaveOccurred()) build.Resume(logger) Ω(inputStep.RunCallCount()).Should(Equal(1)) Ω(inputStep.ReleaseCallCount()).Should((BeNumerically(">", 0))) Ω(taskStep.RunCallCount()).Should(Equal(0)) Ω(fakeDelegate.FinishCallCount()).Should(Equal(1)) _, err, succeeded, aborted := fakeDelegate.FinishArgsForCall(0) Ω(err.Error()).Should(ContainSubstring(exec.ErrStepTimedOut.Error())) Ω(succeeded).Should(Equal(exec.Success(false))) Ω(aborted).Should(BeFalse()) }) }) }) })
It("exits with an error including the original message", func() { var err error Eventually(process.Wait()).Should(Receive(&err)) Ω(err.Error()).Should(ContainSubstring("nope A")) Ω(err.Error()).Should(ContainSubstring("nope B")) }) }) Describe("releasing", func() { It("releases all sources", func() { err := step.Release() Ω(err).ShouldNot(HaveOccurred()) Ω(outStepA.ReleaseCallCount()).Should(Equal(1)) Ω(outStepB.ReleaseCallCount()).Should(Equal(1)) }) Context("when the sources fail to release", func() { disasterA := errors.New("nope A") disasterB := errors.New("nope B") BeforeEach(func() { outStepA.ReleaseReturns(disasterA) outStepB.ReleaseReturns(disasterB) }) It("returns an error describing the failures", func() { err := step.Release() Ω(err).Should(HaveOccurred())
startNextStep <- nil finishNextStep <- nil }) It("exits successfully", func() { Eventually(process.Wait()).Should(Receive(BeNil())) }) Describe("releasing", func() { It("releases all sources", func() { Eventually(process.Wait()).Should(Receive(BeNil())) err := step.Release() Ω(err).ShouldNot(HaveOccurred()) Ω(outStep.ReleaseCallCount()).Should(Equal(2)) Ω(successStep.ReleaseCallCount()).Should(Equal(1)) Ω(nextStep.ReleaseCallCount()).Should(Equal(1)) }) Context("when releasing the sources fails", func() { disasterA := errors.New("nope A") disasterB := errors.New("nope B") disasterC := errors.New("nope C") BeforeEach(func() { outStep.ReleaseReturns(disasterA) successStep.ReleaseReturns(disasterB) nextStep.ReleaseReturns(disasterC) })
Get: &atc.GetPlan{ Name: "some-input", }, }, }, }, Next: atc.Plan{ Task: &atc.TaskPlan{ Name: "some-resource", Config: &atc.TaskConfig{}, }, }, }, } build, err := execEngine.CreateBuild(buildModel, plan) Ω(err).ShouldNot(HaveOccurred()) build.Resume(logger) Ω(inputStep.RunCallCount()).Should(Equal(1)) Ω(inputStep.ReleaseCallCount()).Should(Equal(3)) Ω(taskStep.RunCallCount()).Should(Equal(1)) Ω(taskStep.ReleaseCallCount()).Should(Equal(1)) }) }) }) })
}) It("runs the next step", func() { plan := planFactory.NewPlan(atc.OnSuccessPlan{ Step: planFactory.NewPlan(atc.TryPlan{ Step: planFactory.NewPlan(atc.GetPlan{ Name: "some-input", }), }), Next: planFactory.NewPlan(atc.TaskPlan{ Name: "some-resource", Config: &atc.TaskConfig{}, }), }) build, err := execEngine.CreateBuild(logger, buildModel, plan) Expect(err).NotTo(HaveOccurred()) build.Resume(logger) Expect(inputStep.RunCallCount()).To(Equal(1)) Expect(inputStep.ReleaseCallCount()).To(BeNumerically(">", 0)) Expect(taskStep.RunCallCount()).To(Equal(1)) Expect(inputStep.ReleaseCallCount()).To(BeNumerically(">", 0)) }) }) }) })
}) It("exits with an error including the original message", func() { var err error Eventually(process.Wait()).Should(Receive(&err)) Expect(err.Error()).To(ContainSubstring("nope A")) Expect(err.Error()).To(ContainSubstring("nope B")) }) }) Describe("releasing", func() { It("releases all sources", func() { step.Release() Expect(outStepA.ReleaseCallCount()).To(Equal(1)) Expect(outStepB.ReleaseCallCount()).To(Equal(1)) }) }) Describe("getting a result", func() { Context("when the result type is bad", func() { It("returns false", func() { result := "this-is-bad" Expect(step.Result(&result)).To(BeFalse()) }) }) Context("when getting a Success result", func() { var result Success
Next: atc.Plan{ Task: &atc.TaskPlan{ Name: "some-resource", Config: &atc.TaskConfig{}, }, }, }, } build, err := execEngine.CreateBuild(buildModel, plan) Ω(err).ShouldNot(HaveOccurred()) build.Resume(logger) Ω(inputStep.RunCallCount()).Should(Equal(1)) Ω(inputStep.ReleaseCallCount()).Should(Equal(2)) Ω(taskStep.RunCallCount()).Should(Equal(0)) Ω(fakeDelegate.FinishCallCount()).Should(Equal(1)) _, err, succeeded, aborted := fakeDelegate.FinishArgsForCall(0) Ω(err.Error()).Should(ContainSubstring(exec.ErrStepTimedOut.Error())) Ω(succeeded).Should(Equal(exec.Success(false))) Ω(aborted).Should(BeFalse()) }) }) }) })