/// <summary> /// Adds a stage runner to the execution list which will be sorted based on stage and priority. /// </summary> /// <param name="runner">The stage runner to add to the list.</param> /// <returns>The builder.</returns> public IRunnerBuilder AddStageRunner(IStageRunner runner) { // Add stage to configuration _config.StageRunners.Add(runner ?? throw new ArgumentNullException(nameof(runner))); return(this); }
public void GetStageRunnerWithSuccess(StageRunnerState state, IStageRunner parser, Exception e) { "Given the stage runner state" .x(() => state.Should().BeNull()); "And a mocked parser stage runner" .x(() => { var parserMock = new Mock <IStageRunner>(); parserMock.SetupGet(r => r.Stages).Returns(Stages.Parse); parser = parserMock.Object; }); "When constructing the stage runner state with the mocked stage runner" .x(() => e = Record.Exception(() => state = new StageRunnerState() { StageRunner = parser })); "Then the stage runner state constructor should succeed" .x(() => e.Should().BeNull()); "And the stage runner should be set to the expected value" .x(() => { state.StageRunner.Should().NotBeNull(); state.StageRunner.Stages.Should().HaveFlag(Stages.Parse); state.StageRunner.Stages.Should().NotHaveFlag(Stages.Discover); state.StageRunner.Stages.Should().NotHaveFlag(Stages.Analyze); state.StageRunner.Stages.Should().NotHaveFlag(Stages.Report); state.StageRunner.Stages.Should().NotHaveFlag(Stages.Convert); state.StageRunner.Stages.Should().NotHaveFlag(Stages.Verify); }); }
public void GetStageRunnerExecutionStateWithSuccess(StageState state, IStageRunner discoverer, IStageRunner parser, Exception e) { "Given the stage state" .x(() => state.Should().BeNull()); "And a mocked discoverer stage runner" .x(() => { var discovererMock = new Mock <IStageRunner>(); discovererMock.SetupGet(r => r.Stages).Returns(Stages.Discover); discoverer = discovererMock.Object; }); "And a mocked parser stage runner" .x(() => { var parserMock = new Mock <IStageRunner>(); parserMock.SetupGet(r => r.Stages).Returns(Stages.Parse); parser = parserMock.Object; }); "When constructing the stage state with state runner execution state" .x(() => { e = Record.Exception(() => { state = new StageState(); state.ExecutionState.Add(new StageRunnerState() { State = State.Running, Started = DateTimeOffset.MaxValue, StageRunner = discoverer }); state.ExecutionState.Add(new StageRunnerState() { State = State.Ready, Started = DateTimeOffset.MaxValue, StageRunner = parser }); }); }); "Then the stage state constructor should succeed" .x(() => e.Should().BeNull()); "And the stage runners should be set to the expected value" .x(() => { state.ExecutionState.Should().NotBeNull().And.HaveCount(2); state.ExecutionState[0].Should().NotBeNull(); state.ExecutionState[0].State.Should().Be(State.Running); state.ExecutionState[0].Started.Should().Be(DateTimeOffset.MaxValue); state.ExecutionState[0].StageRunner.Should().NotBeNull(); state.ExecutionState[0].StageRunner.Stages.Should().HaveFlag(Stages.Discover); state.ExecutionState[1].Should().NotBeNull(); state.ExecutionState[1].State.Should().Be(State.Ready); state.ExecutionState[1].Started.Should().Be(DateTimeOffset.MaxValue); state.ExecutionState[1].StageRunner.Should().NotBeNull(); state.ExecutionState[1].StageRunner.Stages.Should().HaveFlag(Stages.Parse); }); }
public void AddStageRunnerWithSuccess(IRunnerBuilder builder, IStageRunner runner, Exception e) { "Given a runner builder" .x(() => builder = new RunnerBuilder()); "And a stage runner" .x(() => runner = _mockStageRunners.First().Object); "When adding a stage runner" .x(() => e = Record.Exception(() => builder.AddStageRunner(runner))); "Then the add method should succeed" .x(() => e.Should().BeNull()); }
public void AddStageRunnerWithNullRunner(IRunnerBuilder builder, IStageRunner runner, Exception e) { "Given a runner builder" .x(() => builder = new RunnerBuilder()); "And a null runner" .x(() => runner.Should().BeNull()); "When adding a stage runner" .x(() => e = Record.Exception(() => builder.AddStageRunner(runner))); "Then the add method should throw an exception" .x(() => e.Should().NotBeNull().And.Subject.Should().BeOfType <ArgumentNullException>().Which.ParamName.Should().Be("runner")); }
public void AddTwoStageRunnersWithSuccess(IRunnerBuilder builder, IStageRunner runner1, IStageRunner runner2, Exception e1, Exception e2) { "Given a runner builder" .x(() => builder = new RunnerBuilder()); "And a first stage runner" .x(() => runner1 = _mockStageRunners.First().Object); "And a second stage runner" .x(() => runner2 = _mockStageRunners.Last().Object); "When adding first stage runner" .x(() => e1 = Record.Exception(() => builder.AddStageRunner(runner1))); "And adding second stage runner" .x(() => e2 = Record.Exception(() => builder.AddStageRunner(runner2))); "Then the first add method should succeed" .x(() => e1.Should().BeNull()); "And the second add method should succeed" .x(() => e2.Should().BeNull()); }
public BuildReport Run() { BuildReport report = new BuildReport(); Project projectToBuild = projectRegistry.GetProject(projectId); Log(Level.Info, "Starting the build runner"); lock (this) { // construct a graph of build stages foreach (BuildStage stage in projectToBuild.BuildStages) { BuildDependencyGraph(stage); } Log(Level.Debug, "Constructed build stages dependency graph"); } while (true) { Log(Level.Debug, "New cycle started"); lock (this) { // retrieve the fresh info about stage statuses foreach (BuildStage stage in stagesOrdered) { StageStatus status = GetStageStatus(stage); if (status.Outcome == BuildOutcome.InProgress) { status.StageRunner.UpdateStatus(status); } Log(Level.Info, "Build stage '{0}' status: {1}", status.Stage.StageId, status.Outcome); } } // check if the traffic buildTrafficSignals has signalled the runner to stop BuildTrafficCopSignal signal = buildTrafficSignals.WaitForControlSignal(TimeSpan.Zero); if (signal == BuildTrafficCopSignal.Stop) { break; } bool stagesPending = false; lock (this) { // check if any of the stages can be started foreach (BuildStage stage in stagesOrdered) { StageStatus status = stagesStatuses[stage.StageId]; if (status.Outcome == BuildOutcome.Initial) { bool someDependenciesFailed = false; bool allDependenciesSuccessful = true; // check dependecy stages foreach (BuildStage dependency in stage.DependsOn) { StageStatus dependencyStatus = GetStageStatus(dependency); if (dependencyStatus.Outcome == BuildOutcome.Failed) { // this stage will not be executed, so go to the next one someDependenciesFailed = true; allDependenciesSuccessful = false; break; } else if (dependencyStatus.Outcome == BuildOutcome.Successful) { continue; } allDependenciesSuccessful = false; } if (someDependenciesFailed) { status.MarkAsNotExecuted(); } else if (allDependenciesSuccessful) { // we can start this stage Log(Level.Info, "Starting stage '{0}'", status.Stage.StageId); IStageRunner stageRunner = this.buildStageRunnerFactory.CreateStageRunner(status.Stage); status.PrepareToStart(stageRunner); stageRunner.StartStage(); // update the status immediatelly stageRunner.UpdateStatus(status); stagesPending = true; } else { stagesPending = true; } } } } if (stagesPending) { Log(Level.Debug, "Some build stages are still pending"); } else { Log(Level.Debug, "The build has been executed"); break; } Log(Level.Debug, "Waiting for the traffic cop"); // check if the traffic buildTrafficSignals has signalled the runner to stop signal = buildTrafficSignals.WaitForControlSignal(pollPeriod); if (signal == BuildTrafficCopSignal.Stop) { break; } } Log(Level.Info, "Stopping the build runner"); foreach (BuildStage stage in stagesOrdered) { BuildStageReport stageReport = new BuildStageReport(); stageReport.StageOutcome = GetStageStatus(stage).Outcome; report.StageReports.Add(stage.StageId, stageReport); } return(report); }
public void PrepareToStart(IStageRunner stageRunner) { this.stageRunner = stageRunner; }