public void GetJobRunById()
        {
            using (this.GivenRunningServerWithWebApi())
            {
                var client = new JobbrClient(this.BackendAddress);

                var job = new Job();
                this.JobStorage.AddJob(job);

                var trigger = new RecurringTrigger();
                this.JobStorage.AddTrigger(job.Id, trigger);

                var jobRun = new JobRun {
                    Job = new Job {
                        Id = job.Id
                    }, Trigger = new RecurringTrigger {
                        Id = trigger.Id
                    }
                };
                this.JobStorage.AddJobRun(jobRun);

                var jobRunDto = client.GetJobRunById(jobRun.Id);

                Assert.IsNotNull(jobRunDto);
                Assert.AreEqual(jobRun.Id, jobRunDto.JobRunId);
                Assert.AreEqual(jobRun.Job.Id, jobRunDto.JobId);
                Assert.AreEqual(jobRun.Trigger.Id, jobRunDto.TriggerId);
            }
        }
        public void GetJobRunsByTriggerId()
        {
            using (this.GivenRunningServerWithWebApi())
            {
                var client = new JobbrClient(this.BackendAddress);

                var job = new Job();
                this.JobStorage.AddJob(job);

                var trigger = new RecurringTrigger();
                this.JobStorage.AddTrigger(job.Id, trigger);

                var jobRun = new JobRun {
                    Job = new Job {
                        Id = job.Id
                    }, Trigger = new RecurringTrigger {
                        Id = trigger.Id
                    }
                };
                this.JobStorage.AddJobRun(jobRun);

                var jobRun2 = new JobRun {
                    Job = new Job {
                        Id = job.Id
                    }, Trigger = new RecurringTrigger {
                        Id = trigger.Id
                    }
                };
                this.JobStorage.AddJobRun(jobRun2);

                var jobRuns = client.GetJobRunsByTriggerId(job.Id, trigger.Id);

                Assert.AreEqual(2, jobRuns.TotalItems);
            }
        }
        private bool ApplyOtherChanges(RecurringTrigger fromDb, RecurringTrigger updatedOne)
        {
            bool hadChanges = false;

            if (!string.Equals(fromDb.Definition, updatedOne.Definition, StringComparison.OrdinalIgnoreCase))
            {
                fromDb.Definition = updatedOne.Definition;
                hadChanges        = true;
            }

            if (fromDb.NoParallelExecution != updatedOne.NoParallelExecution)
            {
                fromDb.NoParallelExecution = updatedOne.NoParallelExecution;
                hadChanges = true;
            }

            if (fromDb.StartDateTimeUtc != updatedOne.StartDateTimeUtc)
            {
                fromDb.StartDateTimeUtc = updatedOne.StartDateTimeUtc;
                hadChanges = true;
            }

            if (fromDb.EndDateTimeUtc != updatedOne.EndDateTimeUtc)
            {
                fromDb.EndDateTimeUtc = updatedOne.EndDateTimeUtc;
                hadChanges            = true;
            }

            if (this.ApplyBaseChanges(fromDb, updatedOne))
            {
                hadChanges = true;
            }

            return(hadChanges);
        }
        public void NoParallelExecutionDisabled_ForceNewPlanWhileJobIsStillRunning_NextJobRunIsCreated()
        {
            var initialDate = new DateTime(2017, 02, 01, 15, 42, 12, DateTimeKind.Utc);

            this.currentTimeProvider.Set(initialDate);

            var recurringTrigger = new RecurringTrigger {
                Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, NoParallelExecution = false
            };

            this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger);

            // Simulate that the jobRun has started
            var addedJobRun = this.repository.GetJobRunsByTriggerId(recurringTrigger.JobId, recurringTrigger.Id).Single();

            addedJobRun.State = JobRunStates.Processing;
            this.repository.Update(addedJobRun);

            // Make sure the cron in the recurring trigger will base on an updated "now"
            this.currentTimeProvider.Set(initialDate.AddHours(2));
            this.periodicTimer.CallbackOnce();

            var jobRuns = this.repository.GetJobRuns();

            Assert.AreEqual(2, jobRuns.Count);
            Assert.AreEqual(2, this.lastIssuedPlan.Count, "Since one JobRun has completed, there should be now 2 jobruns");
            Assert.AreEqual(2, this.repository.GetJobRuns().Count, "The recurring trigger should should have triggered 2");

            Assert.AreEqual(jobRuns[0].Id, this.lastIssuedPlan[0].Id);
            Assert.AreEqual(jobRuns[1].Id, this.lastIssuedPlan[1].Id);
        }
Exemple #5
0
        public void JobService_ExistingRecurringTriggerIsUpdated_UpdateIsPersisted()
        {
            var demoJob         = new Job();
            var storageProvider = this.Services.JobStorageProvider;

            storageProvider.AddJob(demoJob);

            var definition1 = "1 1 1 1 1";
            var definition2 = "1 1 1 1 3";

            var initialTrigger = new RecurringTrigger {
                JobId = demoJob.Id, Definition = definition1, IsActive = true
            };

            storageProvider.AddTrigger(demoJob.Id, initialTrigger);

            var updatedTrigger = new RecurringTrigger {
                Id = initialTrigger.Id, JobId = demoJob.Id, Definition = definition2, IsActive = true
            };

            this.Services.JobManagementService.UpdateTriggerDefinition(demoJob.Id, updatedTrigger.Id, updatedTrigger.Definition);

            var assertTrigger = (RecurringTrigger)storageProvider.GetTriggerById(demoJob.Id, initialTrigger.Id);

            Assert.AreEqual(definition2, assertTrigger.Definition);
        }
        public void Delete_Job_Run()
        {
            using (this.GivenRunningServerWithWebApi())
            {
                var client = new JobbrClient(this.BackendAddress);

                var job = new Job();
                this.JobStorage.AddJob(job);

                var trigger = new RecurringTrigger();
                this.JobStorage.AddTrigger(job.Id, trigger);

                var jobRun = new JobRun {
                    Job = new Job {
                        Id = job.Id
                    }, Trigger = new RecurringTrigger {
                        Id = trigger.Id
                    }, State = JobRunStates.Completed
                };
                this.JobStorage.AddJobRun(jobRun);

                client.DeleteJobRun(jobRun.Id);

                var jobRun2 = this.JobStorage.GetJobRunById(jobRun.Id);

                Assert.IsTrue(jobRun2.Deleted);
            }
        }
        public void RecurringTrigger_WhenAddedBeforeStart_ShouldTriggerOneRun()
        {
            this.scheduler.Stop();

            var futureDate = new DateTime(2017, 02, 01, 15, 42, 12, DateTimeKind.Utc);

            this.currentTimeProvider.Set(futureDate);

            var recurringTrigger = new RecurringTrigger {
                Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true
            };

            // This triggers the first jobrun
            this.repository.SaveAddTrigger(this.demoJob1Id, recurringTrigger);

            this.scheduler.Start();

            var jobRuns = this.repository.GetJobRuns();

            Assert.AreEqual(1, jobRuns.Count, "There should only be one jobrun");
            Assert.AreEqual(futureDate.Date, jobRuns[0].PlannedStartDateTimeUtc.Date);
            Assert.AreEqual(futureDate.Hour, jobRuns[0].PlannedStartDateTimeUtc.Hour);
            Assert.AreEqual(futureDate.Minute + 1, jobRuns[0].PlannedStartDateTimeUtc.Minute);
            Assert.AreEqual(0, jobRuns[0].PlannedStartDateTimeUtc.Second);
        }
Exemple #8
0
        public void HasTriggerWithJobId_QueryByMatchingJobId_ReturnsListWithSingle()
        {
            // Arrange
            var instantTrigger = new InstantTrigger {
                IsActive = true
            };
            var recurringTrigger = new RecurringTrigger()
            {
                IsActive = true
            };
            var scheduledTrigger = new ScheduledTrigger {
                IsActive = true
            };

            this.Services.JobStorageProvider.AddTrigger(100, instantTrigger);
            this.Services.JobStorageProvider.AddTrigger(200, recurringTrigger);
            this.Services.JobStorageProvider.AddTrigger(300, scheduledTrigger);

            // Act
            var triggers = this.QueryService.GetTriggersByJobId(200, 1, 50).Items;
            var assertingRecurringTrigger = triggers[0] as ComponentModel.Management.Model.RecurringTrigger;

            // Test
            Assert.IsNotNull(triggers);
            Assert.AreEqual(1, triggers.Count);
            Assert.AreEqual(recurringTrigger.Id, assertingRecurringTrigger.Id);
        }
        public void NoParallelExecutionEnabled_TriggerWhileJobIsStillRunning_NextJobRunIsPrevented()
        {
            var initialDate = new DateTime(2017, 02, 01, 15, 42, 12, DateTimeKind.Utc);

            this.currentTimeProvider.Set(initialDate);

            var recurringTrigger = new RecurringTrigger {
                Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, NoParallelExecution = true
            };

            // This triggers the first jobrun
            this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger);

            // Simulate that the jobRun has started
            var addedJobRun = this.repository.GetJobRunsByTriggerId(recurringTrigger.JobId, recurringTrigger.Id).Single();

            addedJobRun.State = JobRunStates.Processing;
            this.repository.Update(addedJobRun);

            // Make sure the cron in the recurring trigger will base on an updated "now"
            this.currentTimeProvider.Set(initialDate.AddHours(2));
            this.periodicTimer.CallbackOnce();

            var jobRuns = this.repository.GetJobRuns();

            Assert.AreEqual(1, jobRuns.Count, "Creating new jobruns should be prevented if a JobRun is not yet completed for the trigger");
            Assert.AreEqual(1, this.lastIssuedPlan.Count, "It doesn't mather how often the Callback for recurring trigger scheduling is called, as long as there is a job running, there shoulnd be any additional jobs");
        }
        public void RecurringTrigger_AfterTwoMinutes_IsPlannedMultipleTimes()
        {
            var dateTimeUtc = new DateTime(2017, 02, 09, 14, 00, 00);

            this.currentTimeProvider.Set(dateTimeUtc);

            var scheduledTrigger = new RecurringTrigger()
            {
                Definition = "* * * * *", JobId = this.demoJob1Id, StartDateTimeUtc = dateTimeUtc, IsActive = true
            };

            this.AddAndSignalNewTrigger(this.demoJob1Id, scheduledTrigger);

            this.currentTimeProvider.AddMinute();
            this.periodicTimer.CallbackOnce();

            this.currentTimeProvider.AddMinute();
            this.periodicTimer.CallbackOnce();

            var jobRuns = this.repository.GetJobRuns();

            var expectedTime1 = dateTimeUtc.AddMinutes(1);
            var expectedTime2 = dateTimeUtc.AddMinutes(2);
            var expectedTime3 = dateTimeUtc.AddMinutes(3);

            Assert.AreEqual(3, jobRuns.Count);

            Assert.AreEqual(expectedTime1, this.lastIssuedPlan[0].PlannedStartDateTimeUtc, "The startdate should match the StartDateTimeUtc + 1 Minute");
            Assert.AreEqual(expectedTime2, this.lastIssuedPlan[1].PlannedStartDateTimeUtc, "The startdate should match the StartDateTimeUtc + 1 Minute");
            Assert.AreEqual(expectedTime3, this.lastIssuedPlan[2].PlannedStartDateTimeUtc, "The startdate should match the StartDateTimeUtc + 1 Minute");
        }
Exemple #11
0
        public void AddTrigger(long jobId, RecurringTrigger trigger)
        {
            var newTriggerId = this.localTriggers.Count + 1;

            trigger.Id    = newTriggerId;
            trigger.JobId = jobId;
            this.localTriggers.Add(trigger);
        }
        internal static RecurringTrigger ConvertToTrigger(RecurringTriggerDto dto)
        {
            var trigger = new RecurringTrigger {
                Definition = dto.Definition, StartDateTimeUtc = dto.StartDateTimeUtc, EndDateTimeUtc = dto.EndDateTimeUtc
            };

            return((RecurringTrigger)MapCommonValues(dto, trigger));
        }
        internal static RecurringTriggerDto ConvertToDto(RecurringTrigger trigger)
        {
            var dto = new RecurringTriggerDto {
                StartDateTimeUtc = trigger.StartDateTimeUtc, EndDateTimeUtc = trigger.EndDateTimeUtc, Definition = trigger.Definition
            };

            return((RecurringTriggerDto)MapCommonValues(trigger, dto));
        }
        public void Update(long jobId, RecurringTrigger trigger)
        {
            using (var connection = this.connectionFactory.Open())
            {
                var entity = trigger.ToEntity();

                connection.Update(entity);
            }
        }
        public void AddTrigger(long jobId, RecurringTrigger trigger)
        {
            var model = this.mapper.Map <RecurringTriggerModel>(trigger);

            this.triggerService.Add(jobId, model);

            trigger.Id    = model.Id;
            trigger.JobId = jobId;
        }
Exemple #16
0
        private bool ApplyOtherChanges(RecurringTrigger fromDb, RecurringTrigger updatedOne)
        {
            if (!string.Equals(fromDb.Definition, updatedOne.Definition, StringComparison.OrdinalIgnoreCase))
            {
                fromDb.Definition = updatedOne.Definition;
                return(true);
            }

            return(false);
        }
Exemple #17
0
        internal PlanResult Plan(RecurringTrigger trigger)
        {
            if (!trigger.IsActive)
            {
                return(PlanResult.FromAction(PlanAction.Obsolete));
            }

            if (trigger.EndDateTimeUtc.HasValue && trigger.EndDateTimeUtc.Value < this.dateTimeProvider.GetUtcNow())
            {
                // This jobrun is not valid anymore
                return(PlanResult.FromAction(PlanAction.Obsolete));
            }

            if (trigger.NoParallelExecution)
            {
                // find jobs that are running right now based on this trigger
                var hasRunningJob = this.jobbrRepository.GetRunningJobs(trigger.JobId, trigger.Id).Any();

                if (hasRunningJob)
                {
                    var job = this.jobbrRepository.GetJob(trigger.JobId);

                    Logger.InfoFormat(
                        "No Parallel Execution: prevented planning of new JobRun for Job '{0}' (JobId: {1}). Caused by trigger with id '{2}' (Type: '{3}', userId: '{4}', userName: '******')",
                        job.UniqueName,
                        job.Id,
                        trigger.Id,
                        trigger.GetType().Name,
                        trigger.UserId,
                        trigger.UserDisplayName);

                    return(PlanResult.FromAction(PlanAction.Blocked));
                }
            }

            DateTime baseTime;

            // Calculate the next occurance based on current time or possible future startdate
            if (trigger.StartDateTimeUtc.HasValue && trigger.StartDateTimeUtc.Value > this.dateTimeProvider.GetUtcNow())
            {
                baseTime = trigger.StartDateTimeUtc.Value;
            }
            else
            {
                baseTime = this.dateTimeProvider.GetUtcNow();
            }

            var schedule = CrontabSchedule.Parse(trigger.Definition);

            return(new PlanResult
            {
                Action = PlanAction.Possible,
                ExpectedStartDateUtc = schedule.GetNextOccurrence(baseTime)
            });
        }
        private void InsertTrigger(RecurringTrigger trigger)
        {
            var entity = trigger.ToEntity();

            if (entity.CreatedDateTimeUtc == default(DateTime))
            {
                entity.CreatedDateTimeUtc = DateTime.UtcNow;
            }

            using (var connection = this.connectionFactory.OpenDbConnection())
            {
                trigger.Id = connection.Insert(entity, true);
            }
        }
        public void RecurringTrigger_StartAndEndDateCoversNow_DoesNotTriggerRun()
        {
            var recurringTrigger = new RecurringTrigger {
                Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, StartDateTimeUtc = DateTime.UtcNow.AddDays(-1), EndDateTimeUtc = DateTime.UtcNow.AddDays(1)
            };

            // This triggers the first jobrun
            this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger);

            this.periodicTimer.CallbackOnce();

            var jobRuns = this.repository.GetJobRuns();

            Assert.AreEqual(1, jobRuns.Count, "The trigger should cause a job run because its valid right now");
        }
Exemple #20
0
        public void Update(long jobId, RecurringTrigger trigger)
        {
            using (var session = this._documentStore.OpenSession())
            {
                var job = session.Load <Model.Job>(jobId);

                var triggerFromDb = job.RecurringTriggers.First(p => p.Id == trigger.Id);
                job.RecurringTriggers.Remove(triggerFromDb);

                var entity = trigger.ToEntity();

                job.RecurringTriggers.Add(entity);

                session.Store(job);
                session.SaveChanges();
            }
        }
Exemple #21
0
        public void HasOneJobWithTrigger_QueryJobByExistingId_ReturnsJobWithTrigger()
        {
            // Arrange
            var job = new Job();

            this.Services.JobStorageProvider.AddJob(job);

            var trigger = new RecurringTrigger()
            {
                Definition = "* * * * *"
            };

            this.Services.JobStorageProvider.AddTrigger(job.Id, trigger);

            // Act
            var result = this.QueryService.GetJobById(job.Id);
        }
        public void GetRecurringTrigger()
        {
            using (this.GivenRunningServerWithWebApi())
            {
                var client = new JobbrClient(this.BackendAddress);

                var job = new Job();
                this.JobStorage.AddJob(job);

                var trigger = new RecurringTrigger();
                this.JobStorage.AddTrigger(job.Id, trigger);

                var triggerDto = client.GetTriggerById <RecurringTriggerDto>(job.Id, trigger.Id);

                Assert.IsNotNull(triggerDto);
                Assert.AreEqual(trigger.Id, triggerDto.Id);
            }
        }
 public static ComponentModel.JobStorage.Model.RecurringTrigger ToModel(this RecurringTrigger src, long jobId)
 {
     return(new ComponentModel.JobStorage.Model.RecurringTrigger
     {
         CreatedDateTimeUtc = src.CreatedDateTimeUtc,
         Parameters = src.Parameters,
         Id = src.Id,
         IsActive = src.IsActive,
         Comment = src.Comment,
         UserId = src.UserId,
         UserDisplayName = src.UserDisplayName,
         StartDateTimeUtc = src.StartDateTimeUtc,
         EndDateTimeUtc = src.EndDateTimeUtc,
         NoParallelExecution = src.NoParallelExecution,
         Definition = src.Definition,
         JobId = jobId
     });
 }
        public void NewRecurringTriggerWithoutSeconds_IsAdded_IsPlannedOnTime()
        {
            var dateTimeUtc = new DateTime(DateTime.UtcNow.Year + 1, 09, 02, 17, 00, 00);

            var scheduledTrigger = new RecurringTrigger()
            {
                Definition = "* * * * *", JobId = this.demoJob1Id, StartDateTimeUtc = dateTimeUtc, IsActive = true
            };

            this.AddAndSignalNewTrigger(this.demoJob1Id, scheduledTrigger);

            var jobRun = this.repository.GetJobRuns().Single();

            var expectedTime = dateTimeUtc.AddMinutes(1);

            Assert.AreEqual(expectedTime, this.lastIssuedPlan.Single().PlannedStartDateTimeUtc, "The startdate should match the StartDateTimeUtc + 1 Minute");
            Assert.AreEqual(jobRun.Id, this.lastIssuedPlan.Single().Id, "The startdate should be considered in the plan");
        }
Exemple #25
0
        public void AddTrigger(long jobId, RecurringTrigger trigger)
        {
            using (var session = this._documentStore.OpenSession())
            {
                var job    = session.Load <Model.Job>(jobId);
                var entity = trigger.ToEntity();
                entity.Id = ++job.LastTriggerId;
                entity.CreatedDateTimeUtc = DateTime.UtcNow;

                job.RecurringTriggers.Add(entity);

                session.Store(job);
                session.SaveChanges();

                trigger.Id = entity.Id;
                trigger.CreatedDateTimeUtc = entity.CreatedDateTimeUtc;
            }
        }
        public void Get_JobRuns_By_State()
        {
            using (this.GivenRunningServerWithWebApi())
            {
                var client = new JobbrClient(this.BackendAddress);

                var job = new Job();
                this.JobStorage.AddJob(job);

                var trigger = new RecurringTrigger();
                this.JobStorage.AddTrigger(job.Id, trigger);

                var jobRun = new JobRun {
                    Job = new Job {
                        Id = job.Id
                    }, Trigger = new RecurringTrigger {
                        Id = trigger.Id
                    }, State = JobRunStates.Completed
                };
                this.JobStorage.AddJobRun(jobRun);

                var jobRun2 = new JobRun {
                    Job = new Job {
                        Id = job.Id
                    }, Trigger = new RecurringTrigger {
                        Id = trigger.Id
                    }, State = JobRunStates.Completed
                };
                this.JobStorage.AddJobRun(jobRun2);

                var jobRun3 = new JobRun {
                    Job = new Job {
                        Id = job.Id
                    }, Trigger = new RecurringTrigger {
                        Id = trigger.Id
                    }, State = JobRunStates.Failed
                };
                this.JobStorage.AddJobRun(jobRun3);

                var jobRuns = client.QueryJobRunsByState("Completed");

                Assert.AreEqual(2, jobRuns.TotalItems);
            }
        }
        public void RecurringTrigger_EndDateInPast_DoesNotTriggerRun()
        {
            var currentNow = new DateTime(2017, 02, 01, 15, 42, 00, DateTimeKind.Utc);

            this.currentTimeProvider.Set(currentNow);

            var recurringTrigger = new RecurringTrigger {
                Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, EndDateTimeUtc = currentNow.AddDays(-1)
            };

            // This triggers the first jobrun
            this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger);

            this.periodicTimer.CallbackOnce();

            var jobRuns = this.repository.GetJobRuns();

            Assert.AreEqual(0, jobRuns.Count, "The trigger is not valid anymore and should not trigger a run");
        }
        public void GivenRecurringTrigger_WhenUpdating_TriggerIsUpdated()
        {
            GivenRavenDb();
            GivenStorageProvider();

            var job1 = new Job {
                UniqueName = "testjob1", Type = "Jobs.Test1"
            };

            this.StorageProvider.AddJob(job1);

            var trigger = new RecurringTrigger();

            this.StorageProvider.AddTrigger(job1.Id, trigger);

            var trigger2 = (RecurringTrigger)this.StorageProvider.GetTriggerById(job1.Id, trigger.Id);

            var startDateTime = DateTime.UtcNow.AddHours(5);
            var endDateTime   = DateTime.UtcNow.AddHours(7);

            trigger2.Comment             = "bla";
            trigger2.IsActive            = true;
            trigger2.Parameters          = "test-parameters";
            trigger2.UserId              = "ozu";
            trigger2.StartDateTimeUtc    = startDateTime;
            trigger2.Definition          = "* * * * *";
            trigger2.EndDateTimeUtc      = endDateTime;
            trigger2.NoParallelExecution = true;

            this.StorageProvider.Update(job1.Id, trigger2);

            var trigger2Reloaded = (RecurringTrigger)this.StorageProvider.GetTriggerById(job1.Id, trigger2.Id);

            Assert.AreEqual("bla", trigger2Reloaded.Comment);
            Assert.IsTrue(trigger2Reloaded.IsActive);
            Assert.AreEqual("test-parameters", trigger2Reloaded.Parameters);
            Assert.AreEqual("ozu", trigger2Reloaded.UserId);
            Assert.AreEqual(startDateTime.ToString(CultureInfo.InvariantCulture), trigger2Reloaded.StartDateTimeUtc.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            Assert.AreEqual(endDateTime.ToString(CultureInfo.InvariantCulture), trigger2Reloaded.EndDateTimeUtc.GetValueOrDefault().ToString(CultureInfo.InvariantCulture));
            Assert.AreEqual("* * * * *", trigger2Reloaded.Definition);
            Assert.IsTrue(trigger2Reloaded.NoParallelExecution);
        }
        public void RecurringTrigger_StartDateInPast_FirstRunIsAtCurrentNow()
        {
            var currentNow = new DateTime(2017, 02, 01, 15, 42, 00, DateTimeKind.Utc);

            this.currentTimeProvider.Set(currentNow);

            var recurringTrigger = new RecurringTrigger {
                Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true, StartDateTimeUtc = currentNow.AddDays(-1)
            };

            // This triggers the first jobrun
            this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger);

            this.periodicTimer.CallbackOnce();

            var jobRuns = this.repository.GetJobRuns();

            Assert.AreEqual(1, jobRuns.Count, "A startdate in the future should trigger the run");
            Assert.AreEqual(currentNow.Date, jobRuns[0].PlannedStartDateTimeUtc.Date);
        }
        public void RecurringTrigger_WhileRunIsIncomplete_ShouldNotRaiseNewRunsAtTheSameTime()
        {
            var futureDate = new DateTime(2017, 02, 01, 15, 42, 12, DateTimeKind.Utc);

            this.currentTimeProvider.Set(futureDate);

            var recurringTrigger = new RecurringTrigger {
                Definition = "* * * * *", JobId = this.demoJob1Id, IsActive = true
            };

            // This triggers the first jobrun
            this.AddAndSignalNewTrigger(this.demoJob1Id, recurringTrigger);

            this.currentTimeProvider.AddSecond();
            this.periodicTimer.CallbackOnce();

            var jobRuns = this.repository.GetJobRuns();

            Assert.AreEqual(1, jobRuns.Count, "The periodic callback should not create new jobruns if they would start at the same time (== planned starttime has not changed)");
        }