Example #1
0
        /// <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);
            });
        }
Example #3
0
        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);
            });
        }
Example #4
0
        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());
        }
Example #5
0
        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"));
        }
Example #6
0
        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());
        }
Example #7
0
        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);
        }
Example #8
0
 public void PrepareToStart(IStageRunner stageRunner)
 {
     this.stageRunner = stageRunner;
 }