public void PlanTwoJobsWithMultipleTranscodingPluginsTest()
        {
            var wfsPluginMock = CreateWfsMock("1");

            wfsPluginMock.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var ffmpegPluginMock = CreateFFMpegMock("1");

            ffmpegPluginMock.SetupGet(p => p.Busy).Returns(false);
            ffmpegPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var planner = new SimplePlanner(new List <IPlugin> {
                wfsPluginMock.Object, ffmpegPluginMock.Object
            }, JobRepository, Logging, _callBackService.Object);
            var audioJob = CreateNewFFMpegJob();
            var videoJob = CreateNewWfsJob();

            JobRepository.Add(audioJob);
            JobRepository.Add(videoJob);
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(2));
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(0));
            planner.Calculate();
            ffmpegPluginMock.Verify(x => x.CheckAndEstimate(It.IsAny <ExecutionTask>()), Times.Once(), "ffmpeg plugin should only be called once");
            wfsPluginMock.Verify(x => x.CheckAndEstimate(It.IsAny <ExecutionTask>()), Times.Once(), "Wfs plugin should only be called once");
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(0));
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(2));
            var dbAudioJob = JobRepository.ActiveJobs().First(j =>
                                                              j.Plan.Tasks.First().PluginUrn == ffmpegPluginMock.Object.Urn);
            var dbVideoJob = JobRepository.ActiveJobs().First(j =>
                                                              j.Plan.Tasks.First().PluginUrn == wfsPluginMock.Object.Urn);

            Assert.That(dbAudioJob.Urn, Is.EqualTo(audioJob.Urn));
            Assert.That(dbVideoJob.Urn, Is.EqualTo(videoJob.Urn));
        }
        public void PlanAJobWithMuxingTest()
        {
            var wfsPluginMock = CreateWfsMock("1");

            wfsPluginMock.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var ffmpegPluginMock = CreateFFMpegMock("1");

            ffmpegPluginMock.SetupGet(p => p.Busy).Returns(false);
            ffmpegPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var planner = new SimplePlanner(new List <IPlugin> {
                wfsPluginMock.Object, ffmpegPluginMock.Object
            }, JobRepository, Logging, _callBackService.Object);
            var audioJob = CreateNewAudioMuxJob();

            JobRepository.Add(audioJob);
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(1));
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(0));
            planner.Calculate();
            ffmpegPluginMock.Verify(x => x.CheckAndEstimate(It.IsAny <ExecutionTask>()), Times.Exactly(1), "ffmpeg plugin should only be called once for muxing");
            wfsPluginMock.Verify(x => x.CheckAndEstimate(It.IsAny <ExecutionTask>()), Times.Exactly(1), "Wfs plugin should only be called once for transcoding");
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(0));
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(1));
            var dbMuxJob = JobRepository.ActiveJobs().First();

            Assert.That(dbMuxJob.Plan.Tasks.Count(), Is.EqualTo(2));
            Assert.That(dbMuxJob.Plan.Tasks[0].PluginUrn, Is.EqualTo(ffmpegPluginMock.Object.Urn));
            Assert.That(dbMuxJob.Plan.Tasks[1].PluginUrn, Is.EqualTo(wfsPluginMock.Object.Urn));
        }
        public void CalculateDoesNotReserveTheLastFFmpegPluginForHighPriorityOnly()
        {
            var wfsPluginMock = CreateFFMpegMock("1");

            wfsPluginMock.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);

            var wfsPluginMock2 = CreateFFMpegMock("2");

            wfsPluginMock2.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock2.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var planner = new SimplePlanner(new List <IPlugin> {
                wfsPluginMock.Object, wfsPluginMock2.Object
            }, JobRepository, Logging, _callBackService.Object);

            var jobMedium = CreateNewFFMpegJob();

            jobMedium.Priority = Priority.medium;
            JobRepository.Add(jobMedium);

            var jobLow = CreateNewFFMpegJob();

            jobLow.Priority = Priority.low;
            JobRepository.Add(jobLow);
            planner.Calculate();

            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(0));
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(2));
        }
        public void OnlyHighPriorityJobsWillBeGivenTheLastWfsNode()
        {
            var wfsPluginMock = CreateWfsMock("1");

            wfsPluginMock.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var planner = new SimplePlanner(new List <IPlugin> {
                wfsPluginMock.Object
            }, JobRepository, Logging, _callBackService.Object);
            var jobMedium = CreateNewWfsJob();

            jobMedium.Priority = Priority.medium;
            JobRepository.Add(jobMedium);
            planner.Calculate();

            // Medium prio job will be started with only one wfs node
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(0));
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(1));
            JobRepository.Reset();
            jobMedium          = CreateNewWfsJob();
            jobMedium.Priority = Priority.medium;
            JobRepository.Add(jobMedium);
            var jobHigh = CreateNewWfsJob();

            jobHigh.Priority = Priority.high;

            JobRepository.Add(jobHigh);
            planner.Calculate();

            // High prio job will start with one wfs node
            Assert.That(JobRepository.ActiveJobs().First().Urn, Is.EqualTo(jobHigh.Urn));
            Assert.That(JobRepository.WaitingJobs().First().Urn, Is.EqualTo(jobMedium.Urn));

            JobRepository.ActiveJobs().First().Plan.GetCurrentTask().State = ExecutionState.Done;
            JobRepository.ActiveJobs().First().Plan.MoveToNextTask();

            JobRepository.Reset();
            var wfsPluginMock2 = CreateWfsMock("2");

            wfsPluginMock2.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock2.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            planner = new SimplePlanner(new List <IPlugin> {
                wfsPluginMock.Object, wfsPluginMock2.Object
            }, JobRepository, Logging, _callBackService.Object);

            var jobMedium2 = CreateNewWfsJob();

            jobMedium2.Priority = Priority.medium;
            JobRepository.Add(jobMedium2);
            planner.Calculate();

            // Medium prio job will start with two wfs nodes
            Assert.That(JobRepository.ActiveJobs().First().Urn, Is.EqualTo(jobMedium2.Urn));
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(0));
        }
Example #5
0
        public override void Calculate()
        {
            // TODO: cancel, pause, retry , resume...

            var currentPlans = JobRepository.ActiveJobs(); //TODO: check already running task before planning next.
            var waiting      = JobRepository.WaitingJobs().OrderBy(j => j.DueDate).GetEnumerator();

            if (!waiting.MoveNext())
            {
                return;
            }
            foreach (var freePlugin in Plugins.Where(p => !p.Busy && p.PluginType == DummyLogoPP.Type))
            {
                var tcPlugin = Plugins.First(p => p.PluginType == DummyTCOnly.Type);
                var et1      = new ExecutionTask
                {
                    From = new Essence(waiting.Current.Source),
                    To   = new Essence(waiting.Current.Source)
                    {
                        Flags = waiting.Current.Destination.Flags, Files = null
                    },
                    PluginUrn = freePlugin.Urn
                };
                var et2 = new ExecutionTask
                {
                    From      = new Essence(et1.To),
                    To        = new Essence(waiting.Current.Destination),
                    PluginUrn = tcPlugin.Urn
                };
                if (!freePlugin.CheckAndEstimate(et1))
                {
                    continue;
                }
                if (!tcPlugin.CheckAndEstimate(et2))
                {
                    continue;
                }
                var ep = new ExecutionPlan {
                    Tasks = new List <ExecutionTask> {
                        et1, et2
                    }
                };
                waiting.Current.Plan = ep;
                JobRepository.Update(waiting.Current);
                if (!waiting.MoveNext())
                {
                    break;
                }
            }
        }
        public void MaxFiveMinutesJobsWillBeTreatedAsHighPriorityJobsAndBeGivenTheLastWfsNode()
        {
            var wfsPluginMock = CreateWfsMock("1");

            wfsPluginMock.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var wfsPluginMock2 = CreateWfsMock("2");

            wfsPluginMock2.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock2.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var planner = new SimplePlanner(new List <IPlugin> {
                wfsPluginMock.Object, wfsPluginMock2.Object
            }, JobRepository, Logging, _callBackService.Object);

            var jobHighPrio = CreateNewWfsJob();

            jobHighPrio.Priority = Priority.high;
            JobRepository.Add(jobHighPrio);

            var jobMediumPrioLong = CreateNewWfsJob();

            jobMediumPrioLong.Priority        = Priority.medium;
            jobMediumPrioLong.Source.Duration = 300001;
            JobRepository.Add(jobMediumPrioLong);
            planner.Calculate();

            // Medium prio long job (more than 5 min) will not start if one node left
            Assert.That(JobRepository.WaitingJobs().First().Urn, Is.EqualTo(jobMediumPrioLong.Urn));

            JobRepository.Reset();
            var jobMediumPrioShort = CreateNewWfsJob();

            jobMediumPrioShort.Priority        = Priority.medium;
            jobMediumPrioShort.Source.Duration = 30000;
            JobRepository.Add(jobMediumPrioShort);
            JobRepository.Add(jobHighPrio);
            planner.Calculate();

            // Medium prio short job (less than 5 min) will start if one node left
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(0));
            Assert.That(JobRepository.ActiveJobs().Select(t => t.Urn == jobMediumPrioShort.Urn), Is.Not.Null);
        }
        public void PlanOneJobTest()
        {
            var wfsPluginMock = CreateWfsMock("1");

            wfsPluginMock.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var planner = new SimplePlanner(new List <IPlugin> {
                wfsPluginMock.Object
            }, JobRepository, Logging, _callBackService.Object);
            var job    = CreateNewWfsJob();
            var jobUrn = job.Urn;

            JobRepository.Add(job);
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(1));
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(0));
            planner.Calculate();
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(0));
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(1));
            Assert.That(JobRepository.ActiveJobs().First().Urn, Is.EqualTo(jobUrn));
        }
Example #8
0
        private Dictionary <string, PluginStats> GetPluginStats()
        {
            var pluginTypes = Plugins.Select(p => p.PluginType).Distinct();

            // these plugins is already in use or planed to be used in the future, count'em as busy.
            var reservedPluginUrns = JobRepository.ActiveJobs()
                                     .SelectMany(j => j.Plan.Tasks.Where(t => t.State != ExecutionState.Done).Select(t => t.PluginUrn))
                                     .Distinct();

            return(pluginTypes.ToDictionary(type => type, type => new PluginStats()
            {
                TotalCount = Plugins.Count(p => p.PluginType == type),
                BusyCount = Plugins.Count(
                    p => p.PluginType == type &&
                    (p.Busy || (p.AsyncOperation && reservedPluginUrns.Contains(p.Urn)))),
                FreePlugin = new Stack <IPlugin>(Plugins.Where(
                                                     p => p.PluginType == type &&
                                                     !(p.Busy || (p.AsyncOperation && reservedPluginUrns.Contains(p.Urn)))))
            }));
        }
        public void EssenceGetsCleanedOnUpdate()
        {
            var originJob = ActiveJob();
            int essenceAmount;

            JobRepository.Add(originJob);
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(1));
            Assert.That(JobRepository.DoneJobs(), Is.Empty);
            Assert.That(JobRepository.WaitingJobs(), Is.Empty);
            var jobFromRepo = JobRepository.Get(originJob.Urn);

            jobFromRepo.Plan.GetCurrentTask().State = ExecutionState.Done;
            jobFromRepo.Plan.MoveToNextTask();
            JobRepository.Update(jobFromRepo);
            using (var db = new MarvinEntities())
            {
                essenceAmount = db.essence.Count();
            }
            //There should only be four essencefiles (two job essence and two task essence)
            Assert.That(essenceAmount, Is.EqualTo(4));
        }
        public void PlanAnAudioJobWhileMuxingTest()
        {
            var wfsPluginMock = CreateWfsMock("1");

            wfsPluginMock.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var ffmpegPluginMock = CreateFFMpegMock("1");

            ffmpegPluginMock.SetupGet(p => p.Busy).Returns(false);
            ffmpegPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var planner = new SimplePlanner(new List <IPlugin> {
                wfsPluginMock.Object, ffmpegPluginMock.Object
            }, JobRepository, Logging, _callBackService.Object);

            //Plan the mux job
            var muxJob = CreateNewAudioMuxJob();

            JobRepository.Add(muxJob);
            planner.Calculate();

            //Advance muxjob progress to wfs, leaving the ffmpeg plugin free
            var dbMuxJob = JobRepository.ActiveJobs().First();

            dbMuxJob.Plan.Tasks[0].State = ExecutionState.Done;
            dbMuxJob.Plan.Tasks[1].State = ExecutionState.Running;
            JobRepository.Update(dbMuxJob);

            //Plan the audio trancoding job
            var audioJob = CreateNewFFMpegJob();

            JobRepository.Add(audioJob);
            planner.Calculate();

            //Check both jobs are running
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(0));
            Assert.That(JobRepository.ActiveJobs().Count(), Is.EqualTo(2));
        }
Example #11
0
        public override void Calculate()
        {
            // TODO: cancel, pause, retry , resume...

            var currentPlans = JobRepository.ActiveJobs(); //TODO: check already running task before planning next.
            var waiting      = JobRepository.WaitingJobs().OrderBy(j => j.DueDate).GetEnumerator();

            if (!waiting.MoveNext())
            {
                return;
            }
            foreach (var freePlugin in Plugins.Where(p => !p.Busy))
            {
                var et = new ExecutionTask
                {
                    From      = new Essence(waiting.Current.Source),
                    To        = new Essence(waiting.Current.Destination),
                    PluginUrn = freePlugin.Urn
                };
                if (!freePlugin.CheckAndEstimate(et))
                {
                    continue;
                }
                var ep = new ExecutionPlan {
                    Tasks = new List <ExecutionTask> {
                        et
                    }
                };
                waiting.Current.Plan = ep;
                JobRepository.Update(waiting.Current);
                if (!waiting.MoveNext())
                {
                    break;
                }
            }
        }
        public void PrioritySortTest()
        {
            var jobDue1DayLow = CreateNewWfsJob(dueDate: TimeProvider.GetUtcNow().AddDays(1));

            jobDue1DayLow.Priority = Priority.low;
            JobRepository.Add(jobDue1DayLow);
            var jobDue1DayHigh = CreateNewWfsJob(dueDate: TimeProvider.GetUtcNow().AddDays(1));

            jobDue1DayHigh.Priority = Priority.high;
            JobRepository.Add(jobDue1DayHigh);
            var jobDueNowDayLow = CreateNewWfsJob();

            jobDueNowDayLow.Priority = Priority.low;
            JobRepository.Add(jobDueNowDayLow);
            var jobDueNowDayHigh = CreateNewWfsJob();

            jobDueNowDayHigh.Priority = Priority.high;
            JobRepository.Add(jobDueNowDayHigh);
            Assert.That(JobRepository.WaitingJobs().Count(), Is.EqualTo(4));

            var wfsPluginMock  = CreateWfsMock("1");
            var wfsPluginMock2 = CreateWfsMock("2");

            wfsPluginMock.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            wfsPluginMock2.SetupGet(p => p.Busy).Returns(false);
            wfsPluginMock2.Setup(p => p.CheckAndEstimate(It.IsAny <ExecutionTask>())).Returns(true);
            var planner = new SimplePlanner(new List <IPlugin> {
                wfsPluginMock.Object, wfsPluginMock2.Object
            }, JobRepository, Logging, _callBackService.Object);

            planner.Calculate();
            var activeJob = JobRepository.ActiveJobs().First(m => m.Id == jobDueNowDayHigh.Id);

            Assert.That(activeJob.Urn, Is.EqualTo(jobDueNowDayHigh.Urn));
            activeJob.Plan.GetCurrentTask().State = ExecutionState.Done;
            activeJob.Plan.MoveToNextTask();
            JobRepository.Update(activeJob);

            planner.Calculate();
            activeJob = JobRepository.ActiveJobs().First(m => m.Id == jobDue1DayHigh.Id);
            Assert.That(activeJob.Urn, Is.EqualTo(jobDue1DayHigh.Urn));
            activeJob.Plan.GetCurrentTask().State = ExecutionState.Done;
            activeJob.Plan.MoveToNextTask();
            JobRepository.Update(activeJob);

            planner.Calculate();
            activeJob = JobRepository.ActiveJobs().First(m => m.Id == jobDueNowDayLow.Id);
            Assert.That(activeJob.Urn, Is.EqualTo(jobDueNowDayLow.Urn));
            activeJob.Plan.GetCurrentTask().State = ExecutionState.Done;
            activeJob.Plan.MoveToNextTask();
            JobRepository.Update(activeJob);

            planner.Calculate();
            activeJob = JobRepository.ActiveJobs().First(m => m.Id == jobDue1DayLow.Id);
            Assert.That(activeJob.Urn, Is.EqualTo(jobDue1DayLow.Urn));
            activeJob.Plan.GetCurrentTask().State = ExecutionState.Done;
            activeJob.Plan.MoveToNextTask();
            JobRepository.Update(activeJob);

            Assert.That(JobRepository.WaitingJobs(), Is.Empty);
            Assert.That(JobRepository.ActiveJobs(), Is.Empty);
            Assert.That(JobRepository.DoneJobs().Count(), Is.EqualTo(4));
        }