It("provides the step as the previous step to the hook", func() { process := ifrit.Background(ensureStep) Eventually(step.RunCallCount).Should(Equal(1)) Eventually(hookFactory.UsingCallCount).Should(Equal(1)) argsPrev, argsRepo := hookFactory.UsingArgsForCall(0) Expect(argsPrev).To(Equal(step)) Expect(argsRepo).To(Equal(repo)) Eventually(process.Wait()).Should(Receive(noError())) }) It("runs the ensured hook even if the step errors", func() { step.RunReturns(errors.New("disaster")) process := ifrit.Background(ensureStep) Eventually(step.RunCallCount).Should(Equal(1)) Eventually(process.Wait()).Should(Receive(errorMatching(ContainSubstring("disaster")))) Expect(hook.RunCallCount()).To(Equal(1)) }) It("propagates signals to the first step when first step is running", func() { step.RunStub = func(signals <-chan os.Signal, ready chan<- struct{}) error { close(ready) <-signals return errors.New("interrupted")
attempt2Step.ResultReturns(true) var foo interface{} destination := &foo Expect(step.Result(destination)).To(BeTrue()) Expect(attempt2Step.ResultCallCount()).To(Equal(2)) Expect(attempt2Step.ResultArgsForCall(1)).To(Equal(destination)) }) }) }) }) Context("when attempt 1 errors, and attempt 2 succeeds", func() { BeforeEach(func() { attempt1Step.RunReturns(errors.New("nope")) attempt2Step.ResultStub = successResult(true) }) Describe("Run", func() { var process ifrit.Process JustBeforeEach(func() { process = ifrit.Invoke(step) }) It("returns nil having only run the first and second attempts", func() { Expect(<-process.Wait()).ToNot(HaveOccurred()) Expect(attempt1Step.RunCallCount()).To(Equal(1)) Expect(attempt2Step.RunCallCount()).To(Equal(1))
inputStepFactory.UsingReturns(inputStep) fakeFactory.GetReturns(inputStepFactory) outputStepFactory = new(execfakes.FakeStepFactory) outputStep = new(execfakes.FakeStep) outputStep.ResultStub = successResult(true) outputStepFactory.UsingReturns(outputStep) fakeFactory.PutReturns(outputStepFactory) dependentStepFactory = new(execfakes.FakeStepFactory) dependentStep = new(execfakes.FakeStep) dependentStep.ResultStub = successResult(true) dependentStepFactory.UsingReturns(dependentStep) fakeFactory.DependentGetReturns(dependentStepFactory) taskStep.RunReturns(nil) inputStep.RunReturns(nil) outputStep.RunReturns(nil) }) Context("constructing steps", func() { var ( fakeDelegate *fakes.FakeBuildDelegate fakeInputDelegate *execfakes.FakeGetDelegate fakeExecutionDelegate *execfakes.FakeTaskDelegate ) BeforeEach(func() { fakeDelegate = new(fakes.FakeBuildDelegate) fakeDelegateFactory.DelegateReturns(fakeDelegate)
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))) }) }) Context("when the input succeeds", func() { BeforeEach(func() { inputStep.RunReturns(nil) }) Context("when executing the task errors", func() { disaster := errors.New("oh no!") BeforeEach(func() { taskStep.RunReturns(disaster) }) It("does not run any outputs", func() { Ω(outputStep.RunCallCount()).Should(BeZero()) }) It("finishes with error", func() { Ω(fakeDelegate.FinishCallCount()).Should(Equal(1))
process.Signal(os.Kill) var receivedError error Eventually(process.Wait()).Should(Receive(&receivedError)) Ω(receivedError).ShouldNot(BeNil()) Ω(receivedError.Error()).Should(ContainSubstring(ErrInterrupted.Error())) }) }) Context("when the step returns an error", func() { var someError error BeforeEach(func() { someError = errors.New("some error") runStep.ResultStub = successResult(false) runStep.RunReturns(someError) }) It("returns the error", func() { var receivedError error Eventually(process.Wait()).Should(Receive(&receivedError)) Ω(receivedError).ShouldNot(BeNil()) Ω(receivedError).Should(Equal(someError)) }) }) Context("result", func() { It("is not successful", func() { Eventually(runStep.RunCallCount).Should(Equal(1)) var receivedError error
}) It("propagates to all sources", func() { interruptedErr := errors.New("sources failed:\ninterrupted\ninterrupted") process.Signal(os.Interrupt) Eventually(process.Wait()).Should(Receive(Equal(interruptedErr))) }) }) Context("when sources fail", func() { disasterA := errors.New("nope A") disasterB := errors.New("nope B") BeforeEach(func() { outStepA.RunReturns(disasterA) outStepB.RunReturns(disasterB) }) 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()
}) It("deletegates to the inner step", func() { x := new(ExitStatus) result := step.Result(x) Expect(result).Should(Equal(true)) Expect(*x).Should(Equal(ExitStatus(exitCode))) }) }) }) Describe("Run", func() { Context("when the inner step is interrupted", func() { BeforeEach(func() { runStep.ResultStub = successResult(false) runStep.RunReturns(ErrInterrupted) }) It("propagates the error", func() { err := step.Run(nil, nil) Expect(err).To(Equal(ErrInterrupted)) }) }) Context("when the inner step returns any other error", func() { BeforeEach(func() { runStep.ResultStub = successResult(false) runStep.RunReturns(errors.New("some error")) }) It("swallows the error", func() {