Example #1
0
	Context("when attempt 1 succeeds", func() {
		BeforeEach(func() {
			attempt1Step.ResultStub = successResult(true)
		})

		Describe("Run", func() {
			var process ifrit.Process

			JustBeforeEach(func() {
				process = ifrit.Invoke(step)
			})

			It("returns nil having only run the first attempt", func() {
				Expect(<-process.Wait()).ToNot(HaveOccurred())

				Expect(attempt1Step.RunCallCount()).To(Equal(1))
				Expect(attempt2Step.RunCallCount()).To(Equal(0))
				Expect(attempt3Step.RunCallCount()).To(Equal(0))
			})

			Describe("Result", func() {
				It("delegates to attempt 1", func() {
					<-process.Wait()

					// internal check for success within retry loop
					Expect(attempt1Step.ResultCallCount()).To(Equal(1))

					attempt1Step.ResultReturns(true)

					var foo interface{}
					destination := &foo
Example #2
0
							Location: &atc.Location{},
							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{
Example #3
0
		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")
		}

		process := ifrit.Background(ensureStep)

		process.Signal(os.Kill)

		Eventually(step.RunCallCount).Should(Equal(1))
Example #4
0
		})

		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))
					_, cbErr, _, _ := fakeDelegate.FinishArgsForCall(0)
					Ω(cbErr).Should(MatchError(ContainSubstring(disaster.Error())))
				})
			})

			Context("when executing the task succeeds", func() {
				BeforeEach(func() {
					taskStep.RunReturns(nil)
					taskStep.ResultStub = successResult(true)
				})
Example #5
0
		argsPrev, argsRepo := successFactory.UsingArgsForCall(0)
		Ω(argsPrev).Should(Equal(step))
		Ω(argsRepo).Should(Equal(repo))

		Eventually(process.Wait()).Should(Receive(noError()))
	})

	It("does not run the success hook if the step errors", func() {
		step.RunReturns(errors.New("disaster"))

		process := ifrit.Background(onSuccessStep)

		Eventually(step.RunCallCount).Should(Equal(1))
		Eventually(process.Wait()).Should(Receive(errorMatching("disaster")))
		Ω(hook.RunCallCount()).Should(Equal(0))
	})

	It("does not run the success hook if the step fails", func() {
		step.ResultStub = successResult(false)

		process := ifrit.Background(onSuccessStep)

		Eventually(step.RunCallCount).Should(Equal(1))
		Eventually(process.Wait()).Should(Receive(noError()))
		Ω(hook.RunCallCount()).Should(Equal(0))
	})

	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)
Example #6
0
				wg.Done()
				wg.Wait()
				close(ready)
				return nil
			}

			outStepB.RunStub = func(signals <-chan os.Signal, ready chan<- struct{}) error {
				wg.Done()
				wg.Wait()
				close(ready)
				return nil
			}
		})

		It("happens concurrently", func() {
			Ω(outStepA.RunCallCount()).Should(Equal(1))
			Ω(outStepB.RunCallCount()).Should(Equal(1))
		})
	})

	Describe("signalling", func() {
		var receivedSignals chan os.Signal

		BeforeEach(func() {
			receivedSignals = make(chan os.Signal, 2)

			outStepA.RunStub = func(signals <-chan os.Signal, ready chan<- struct{}) error {
				close(ready)
				receivedSignals <- <-signals
				return ErrInterrupted
			}
Example #7
0
							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(1))
				Ω(taskStep.ReleaseCallCount()).Should(BeNumerically(">", 0))
			})

			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{
Example #8
0
							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())
			})
		})
	})
})
Example #9
0
		inStep = new(fakes.FakeStep)
		repo = NewSourceRepository()
	})

	JustBeforeEach(func() {
		step = identity.Using(inStep, repo)
	})

	Describe("Run", func() {
		It("is a no-op", func() {
			ready := make(chan struct{})
			signals := make(chan os.Signal)

			err := step.Run(signals, ready)
			Ω(err).ShouldNot(HaveOccurred())

			Ω(inStep.RunCallCount()).Should(BeZero())
		})
	})

	Describe("Result", func() {
		It("calls through to the input source", func() {
			var result int
			step.Result(&result)

			Ω(inStep.ResultCallCount()).Should(Equal(1))
			Ω(inStep.ResultArgsForCall(0)).Should(Equal(&result))
		})
	})
})
Example #10
0
			})

			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))
			})
		})
	})
})
Example #11
0
				wg.Done()
				wg.Wait()
				close(ready)
				return nil
			}

			outStepB.RunStub = func(signals <-chan os.Signal, ready chan<- struct{}) error {
				wg.Done()
				wg.Wait()
				close(ready)
				return nil
			}
		})

		It("happens concurrently", func() {
			Expect(outStepA.RunCallCount()).To(Equal(1))
			Expect(outStepB.RunCallCount()).To(Equal(1))
		})
	})

	Describe("signalling", func() {
		var receivedSignals chan os.Signal
		var actuallyExit chan struct{}

		BeforeEach(func() {
			receivedSignals = make(chan os.Signal, 2)
			actuallyExit = make(chan struct{}, 1)

			outStepA.RunStub = func(signals <-chan os.Signal, ready chan<- struct{}) error {
				close(ready)
				receivedSignals <- <-signals
Example #12
0
		inStep = new(fakes.FakeStep)
		repo = NewSourceRepository()
	})

	JustBeforeEach(func() {
		step = identity.Using(inStep, repo)
	})

	Describe("Run", func() {
		It("is a no-op", func() {
			ready := make(chan struct{})
			signals := make(chan os.Signal)

			err := step.Run(signals, ready)
			Expect(err).NotTo(HaveOccurred())

			Expect(inStep.RunCallCount()).To(BeZero())
		})
	})

	Describe("Result", func() {
		It("calls through to the input source", func() {
			var result int
			step.Result(&result)

			Expect(inStep.ResultCallCount()).To(Equal(1))
			Expect(inStep.ResultArgsForCall(0)).To(Equal(&result))
		})
	})
})