@AutowiredprivateTriggerServicetriggerService;@TestvoidtestRunTriggerDirectly(){// GIVEN// setup your test and create any triggers neededvartrigger=TriggerBuilder.<Vehicle>newTrigger("task2").id("my-id")// will overwrite existing triggers.state(newVehicle("funny")).build();// WHEN create and directly run this triggertriggerService.run(triggerService.queue(trigger));// THEN// any asserts you might need}@TestvoidtestRunUnknownTriggersCreated(){// GIVEN// setup your test call any method which might create triggers// WHEN run next pending trigger synchronouslytriggerService.run(triggerService.lockNextTrigger("test"));// THEN// any asserts you might need}
Sometimes it might be useful quickly to execute all running tasks. This sample adds a method e.g. to your base test class which will trigger any task which is now due to be executed.
@AutowiredprotectedTriggerServicetriggerService;/** * Run all pending triggers synchronously */protectedintwaitForDbSchedulerTasks(){RunningTriggerEntityt;intcount=0;while((t=triggerService.lockNextTrigger("test"))!=null){triggerService.run(t);++count;}returncount;}
It is also possible to define a test scheduler and use the async way to execute any triggers (without the spring scheduler which would trigger them automatically).
Note
Any errors are now in the log and are handled by the framework with retries etc.
@ConfigurationpublicstaticclassTestConfig{// @Primary // if more than one@Bean(name="schedulerB",initMethod="start",destroyMethod="stop")SchedulerServiceschedulerB(MeterRegistrymeterRegistry,TriggerServicetriggerService,EditSchedulerStatusComponenteditSchedulerStatus,TransactionTemplatetrx)throwsUnknownHostException{returnSchedulerConfig.newSchedulerService("schedulerB",meterRegistry,triggerService,editSchedulerStatus,SchedulerThreadFactory.VIRTUAL_THREAD_POOL_FACTORY,7,Duration.ofSeconds(1),trx);}}
Now the PersistentTaskService has a method to trigger or to trigger and to wait for the result:
@AutowiredprivatePersistentTaskServicepersistentTaskService;@TestvoidtestFoo(){// GIVEN// setup your test and create any triggers needed// WHEN run any pending triggers asynchronously - but with and waitvartriggerKeys=persistentTaskService.executeTriggersAndWait();// OR queue all triggers asynchronously - and return the futuresvarfutureTriggerKeys=persistentTaskService.executeTriggers();// THEN// any asserts you might need}
Waiting for all task which might trigger other tasks¶
In some cases we have longer running triggers which may trigger new jobs. As so we have to wait.
Awaitility.await().atMost(Duration.ofMillis(1500)).until(()->{// set the max wait time as neededwaitForDbSchedulerTasks();return//* insert here your assert for the last task you wait for */;});
During the setup and cleanup it is possible to cancel any pending triggers, pick what is needed in your case. In general it is usually enough in your tests to wait for any pending triggers and cancel any others.
@AutowiredprotectedTriggerServicetriggerService;@AutowiredprotectedPersistentTaskTestServicepersistentTaskTestService;@BeforeEachpublicvoidbeforeEach(){triggerService.deleteAll();try{persistentTaskTestService.awaitRunningTriggers();}catch(Exceptione){System.err.println("awaitRunningTriggers has an error, do we care? No! "+e.getMessage());}}
@AutowiredprotectedSchedulerServiceschedulerService;@AutowiredprotectedTriggerServicetriggerService;@AutowiredprotectedTaskServicetaskService;@AutowiredprotectedHistoryServicehistoryService;@AutowiredprivateThreadPoolTaskExecutortriggerHistoryExecutor;@BeforeEachpublicvoidbeforeEach()throwsException{triggerService.deleteAll();historyService.deleteAll();// restore any changes to the thread countschedulerService.setMaxThreads(10);// optional only needed if you shutdownschedulerService.start();}@AfterEachpublicvoidafterEach()throwsException{// will cancel any pending tasks, optionalschedulerService.shutdownNow();// use .stop() if you want to wait// ensure the history is written completelyawaitHistoryThreads();}protectedvoidawaitHistoryThreads(){Awaitility.await().until(()->triggerHistoryExecutor.getActiveCount()==0);}