unit testing - Quartz Job Scheduler Not Firing Jobs (C#) -
i've run rather perplexing issue quartz (version 2.2.4) in c# project i'm working on, , in spite of best efforts haven't been able resolve issue.
the project requires several different tasks scheduled independently of one-another; being case i've written class handle setting jobs on 24 hour cycle. class supposed instantiated once each task needs scheduled.
below object in question:
namespace projectfront.utilities { public class quartzscheduler { public const string qb_trigger = "qbtrigger"; public const string qb_job = "qbjob"; public const string qb_group = "qbgroup"; private ischeduler scheduler; private itrigger trigger; private ijobdetail job; private jobkey jobkey; public quartzscheduler(ijob controller, string triggerid, string jobid, string jobgroup, int synchour, int syncminute) { stdschedulerfactory schedulerfactory = new stdschedulerfactory(); schedulerfactory.initialize(); jobkey = new jobkey(jobid, jobgroup); synchour = gethour(synchour); syncminute = getmin(syncminute); scheduler = schedulerfactory.getscheduler(); scheduler.start(); job = jobbuilder.create(controller.gettype()) .storedurably() .withidentity(jobkey) .build(); trigger = triggerbuilder.create() .withidentity(triggerid) .forjob(jobkey) .startnow() .withschedule(cronschedulebuilder.dailyathourandminute(synchour, syncminute)) .build(); scheduler.schedulejob(job, trigger); scheduler.start(); } public void reschedule(int synchour, int syncminute) { scheduler.standby(); synchour = gethour(synchour); syncminute = getmin(syncminute); triggerkey triggerkey = trigger.key; trigger = triggerbuilder.create() .withidentity(triggerkey) .forjob(jobkey) .startnow() .withschedule(cronschedulebuilder.dailyathourandminute(synchour, syncminute)) .build(); scheduler.reschedulejob(triggerkey, trigger); scheduler.start(); } public ischeduler getscheduler() { return scheduler; } public itrigger gettrigger() { return trigger; } private int gethour(int num) { if (num < 4) { return num + 20; } return num - 4; } private int getmin(int num) { while (num >= 60) { num -= 60; } return num; } } }
i've written couple of nunit tests make sure in object works. passes 2 of them, fails third; job exists, , can rescheduled, silently fails fire when triggerjob()
called. rescheduling , waiting fire fails work.
these tests:
namespace unittestproject.backend_unittests.util { public class controllerstub : ijob{ public controllerstub() { } public void execute(ijobexecutioncontext context) { console.writeline("fired!"); console.writeline(datetime.now.tostring()); } } [testfixture] public class qbschedulertest { public static int fired = 0; private quartzscheduler target; private jobkey expectedjob; private controllerstub dummy; [testfixturesetup] public void fixture() { colalias.logmanager.adapter = new colalias.simple.traceloggerfactoryadapter { level = colalias.loglevel.info }; expectedjob = new jobkey(quartzscheduler.qb_job, quartzscheduler.qb_group); } [setup] public void setup() { dummy = new controllerstub(); target = new quartzscheduler(dummy, quartzscheduler.qb_trigger, quartzscheduler.qb_job, quartzscheduler.qb_group, 0, 1); } [teardown] public void teardown() { target.getscheduler().clear(); } [test] public void hasbeenscheduled() { assert.istrue(target.getscheduler().checkexists(expectedjob)); assert.istrue(target.getscheduler().isstarted); assert.istrue(target.getscheduler().getjobgroupnames().contains(quartzscheduler.qb_group)); assert.true(target.gettrigger().jobkey.equals(expectedjob)); assert.null(target.gettrigger().getpreviousfiretimeutc()); assert.istrue(target.gettrigger().getmayfireagain()); } [test] public void canberescheduled() { target.reschedule(1, 0); string actual = target.gettrigger().getnextfiretimeutc().tostring(); assert.istrue(actual.contains("1:00:00 am")); } [test] public void canbeexecuted() { datetimeoffset expected = datetimeoffset.now; expected.addminutes(1); assert.istrue(target.getscheduler().checkexists(expectedjob)); target.reschedule(expected.hour, expected.minute); target.getscheduler().triggerjob(expectedjob); thread.sleep(60500); assert.notnull(target.getscheduler().gettrigger(new triggerkey(quartzscheduler.qb_trigger)).getpreviousfiretimeutc()); } } }
the reason failure i've been able find why job wouldn't activate has been scheduler can't find default constructor. i've tried tests both given method , default constructor, test fails anyway.
i'm @ loss why be. can provide possible suggestions?
edit: making things stranger still, adding console.write()
statement execute()
method causes message appear in console window, changes value of fakecontroller.fired
don't persist, , gettrigger().getpreviousfiringtimeutc()
still returns null!
edit: (updated code) i've narrowed issue down construction of trigger object; target.getscheduler.triggerjob(expectedjob)
cause console.write()
messages appear (though static variable doesn't change value). however, scheduling job shown result in trigger never firing.
the issue construction of trigger's scheduling mechanism not being written correctly. chronschedulebuilder
either not working correctly or else implemented in wrong way.
the final solution replace simple interval scheduler follows:
trigger = triggerbuilder .create() .withidentity(triggerkey) .forjob(jobkey) .withschedule(simpleschedulebuilder .create() .withintervalinhours(24) .repeatforever()) .startat( new datetimeoffset( new datetime( datetimeoffset.now.year, datetimeoffset.now.month, datetimeoffset.now.day, synchour, syncminute, 0, datetimekind.local))) .build();
Comments
Post a Comment