public void RunAllMissions_ShouldOnlyFinishMissionWhenAllMissionsAreDone()
        {
            // Arrange
            var runner            = new MissionRunner();
            var mission1          = new ControlledMission("Mission1");
            var mission2          = new ControlledMission("Mission2");
            var dependantMission  = new ControlledMission("Mission3", new[] { "Mission1", "Mission2" });
            var dependantMission2 = new ControlledMission("Mission4", new[] { "Mission3", "Mission2" });

            runner.RegisterMission(mission1);
            runner.RegisterMission(mission2);
            runner.RegisterMission(dependantMission);
            runner.RegisterMission(dependantMission2);

            // Act
            var finishedMission = runner.PerformAllMissions();

            // Assert
            mission1.FinishPerforming();
            mission2.FinishPerforming();
            dependantMission.FinishPerforming();
            Assert.IsFalse(finishedMission.Wait(100));

            dependantMission2.FinishPerforming();
            Assert.IsTrue(finishedMission.Wait(100));
        }
        private static List <ControlledMission> GenerateManyRandomMissions(int missionCount)
        {
            var allMissions  = new List <ControlledMission>();
            var random       = new Random();
            var freeMissions = random.Next(1, Math.Min(missionCount, 100));

            for (int i = 0; i < freeMissions; i++)
            {
                var controlledMission = new ControlledMission(i.ToString(), true);
                allMissions.Add(controlledMission);
            }

            var existingMissionCount = freeMissions;

            for (int i = freeMissions; i < missionCount; i++)
            {
                var dependencies    = new List <string>();
                var dependencyCount = random.Next(10, 100);
                for (int j = 0; j < dependencyCount; j++)
                {
                    dependencies.Add(random.Next(0, existingMissionCount - 1).ToString());
                }

                var controlledMission = new ControlledMission(i.ToString(), dependencies, true);
                allMissions.Add(controlledMission);

                existingMissionCount++;
            }

            return(allMissions);
        }
        public void RunAllMissions_ShouldRunAllPossibleMissionsAtAGivenTime()
        {
            // Arrange
            var runner           = new MissionRunner();
            var mission1         = new ControlledMission("Mission1");
            var mission2         = new ControlledMission("Mission2");
            var dependantMission = new ControlledMission("Mission3", new[] { "Mission2" }, true);

            runner.RegisterMission(mission1);
            runner.RegisterMission(mission2);
            runner.RegisterMission(dependantMission);

            // Act
            runner.PerformAllMissions();

            // Assert
            Assert.IsTrue(mission1.IsPerformed);
            Assert.IsTrue(mission2.IsPerformed);
            Assert.IsFalse(dependantMission.IsPerformed);

            mission2.FinishPerforming();
            Assert.IsTrue(dependantMission.IsPerformed);

            mission1.FinishPerforming();
        }
        public void RegisterMission_ShouldThrowExceptionForNonExistingDependency()
        {
            // Arrange
            var runner           = new MissionRunner();
            var dependantMission = new ControlledMission("Mission2", new[] { "Mission1" });

            // Act
            runner.RegisterMission(dependantMission);
        }
        public void RegisterMission_ShouldThrowExceptionForMissionsWithSameName()
        {
            // Arrange
            var runner   = new MissionRunner();
            var mission1 = new ControlledMission("Mission");
            var mission2 = new ControlledMission("Mission");

            runner.RegisterMission(mission1);

            // Act
            runner.RegisterMission(mission2);
        }
        public void RunAllMissions_ShouldRunSingleRegisteredMission()
        {
            // Arrange
            var runner  = new MissionRunner();
            var mission = new ControlledMission("Mission1", true);

            runner.RegisterMission(mission);

            // Act
            runner.PerformAllMissions();

            // Assert
            Assert.IsTrue(mission.IsPerformed);
        }
        public void GetMissionRunState_ReturnRunningWhileMissionIsInProgress()
        {
            // Arrange
            var runner  = new MissionRunner();
            var mission = new ControlledMission("One Thing");

            runner.RegisterMission(mission);
            runner.PerformAllMissions();

            // Assert
            Assert.IsTrue(mission.IsPerformed);
            Assert.AreEqual(RunState.RUNNING, runner.GetMissionRunState("One Thing"));
            mission.FinishPerforming();
        }
        public void GetMissionRunState_ReturnFinishedAfterTaskIsDone()
        {
            // Arrange
            var runner  = new MissionRunner();
            var mission = new ControlledMission("One Thing");

            runner.RegisterMission(mission);
            mission.FinishPerforming();
            var performanceTask = runner.PerformAllMissions();

            performanceTask.Wait(100);

            // Assert
            Assert.AreEqual(RunState.FINISHED, runner.GetMissionRunState("One Thing"));
        }
        public void GetMissionRunState_ReturnFinishedEvenIfOtherTasksAreWorking()
        {
            // Arrange
            var runner           = new MissionRunner();
            var mission          = new ControlledMission("One Thing");
            var dependantMission = new ControlledMission("Dep", new[] { "One Thing" });

            runner.RegisterMission(mission);
            runner.RegisterMission(dependantMission);
            runner.PerformAllMissions();
            mission.FinishPerforming();

            // Assert
            Assert.IsTrue(mission.IsPerformed);
            Assert.AreEqual(RunState.FINISHED, runner.GetMissionRunState("One Thing"));
        }
        public void GetMissionRunState_ReturnWaitingWhileWaitingOnADependency()
        {
            // Arrange
            var runner           = new MissionRunner();
            var mission          = new ControlledMission("One Thing");
            var dependantMission = new ControlledMission("Dep", new[] { "One Thing" }, true);

            runner.RegisterMission(mission);
            runner.RegisterMission(dependantMission);
            runner.PerformAllMissions();

            // Assert
            Assert.IsTrue(mission.IsPerformed);
            Assert.AreEqual(RunState.WAITING, runner.GetMissionRunState("Dep"));
            mission.FinishPerforming();
        }
        public void RunAllMissions_MissionWithDoubleDependencyShouldWork()
        {
            // Arrange
            var runner           = new MissionRunner();
            var mission1         = new ControlledMission("Mission1", true);
            var dependantMission = new ControlledMission("Mission2", new[] { "Mission1", "Mission1" }, true);

            runner.RegisterMission(mission1);
            runner.RegisterMission(dependantMission);

            // Act
            runner.PerformAllMissions();

            // Assert
            Assert.IsTrue(dependantMission.IsPerformed);
        }
        public void RegisterMission_RegisteringMissionWithInvalidDependencyShouldNotAddToRunner()
        {
            // Arrange
            var runner  = new MissionRunner();
            var mission = new ControlledMission("Mission", new[] { "NoMission" }, true);

            // Act
            try
            {
                runner.RegisterMission(mission);
            }
            catch (ArgumentException) { }

            // Assert
            var isDone = runner.PerformAllMissions().Wait(100);

            Assert.IsTrue(isDone);
            Assert.AreEqual(0, mission.RunCounter);
        }
        public void RunAllMissions_ShouldWaitForDependencyToRunMission()
        {
            // Arrange
            var runner            = new MissionRunner();
            var controlledMission = new ControlledMission("Mission1");
            var dependantMission  = new ControlledMission("Mission2", new[] { "Mission1" }, true);

            runner.RegisterMission(controlledMission);
            runner.RegisterMission(dependantMission);

            // Act
            runner.PerformAllMissions();

            // Assert
            Assert.IsTrue(controlledMission.IsPerformed);
            Assert.IsFalse(dependantMission.IsPerformed);
            controlledMission.FinishPerforming();
            Assert.IsTrue(dependantMission.IsPerformed);
        }
        public void RunAllMissions_RunningAMissionWithManyDependenciesShouldNotCauseRace()
        {
            // Arrange
            var runner       = new MissionRunner();
            var dependencies = new List <string>();

            for (int i = 0; i < 100; i++)
            {
                var mission = new ControlledMission(i.ToString(), true);
                runner.RegisterMission(mission);
                dependencies.Add(mission.Name);
            }
            var dependantMission = new ControlledMission("Mission", dependencies, true);

            runner.RegisterMission(dependantMission);

            // Act
            runner.PerformAllMissions();

            // Assert
            Assert.IsTrue(dependantMission.IsPerformed);
        }
        public void RunAllMissions_ShouldWaitForAllDependencies()
        {
            // Arrange
            var runner           = new MissionRunner();
            var mission1         = new ControlledMission("Mission1");
            var mission2         = new ControlledMission("Mission2");
            var dependantMission = new ControlledMission("Mission3", new[] { "Mission1", "Mission2" }, true);

            runner.RegisterMission(mission1);
            runner.RegisterMission(mission2);
            runner.RegisterMission(dependantMission);

            // Act
            runner.PerformAllMissions();

            // Assert
            mission2.FinishPerforming();
            Assert.IsFalse(dependantMission.IsPerformed);

            mission1.FinishPerforming();
            Assert.IsTrue(dependantMission.IsPerformed);
        }
        public void RunAllMissions_RunningTwiceShouldRunAllMissionsTwiceInTheRightOrder()
        {
            // Arrange
            var runner            = new MissionRunner();
            var mission1          = new ControlledMission("Mission1");
            var mission2          = new ControlledMission("Mission2");
            var dependantMission  = new ControlledMission("Mission3", new[] { "Mission1", "Mission2" });
            var dependantMission2 = new ControlledMission("Mission4", new[] { "Mission3", "Mission2" });
            var allMissions       = new[] { mission1, mission2, dependantMission, dependantMission2 };

            foreach (var mission in allMissions)
            {
                runner.RegisterMission(mission);
            }

            // Act
            var finishedMission = runner.PerformAllMissions();

            foreach (var mission in allMissions)
            {
                mission.FinishPerforming();
            }
            finishedMission.Wait();
            finishedMission = runner.PerformAllMissions();

            // Assert
            Assert.AreEqual(1, dependantMission.RunCounter);
            mission1.FinishPerforming();
            mission2.FinishPerforming();
            dependantMission.FinishPerforming();
            Assert.IsFalse(finishedMission.Wait(100));

            dependantMission2.FinishPerforming();
            Assert.IsTrue(finishedMission.Wait(100));
            Assert.IsTrue(allMissions.All(t => t.RunCounter == 2));
        }