@@ -292,6 +292,29 @@ public void testScheduleNextJobScheduleExpired() {
292292 Assert .assertNull (actualDate );
293293 }
294294
295+ @ Test
296+ public void testScheduleNextJobNextOccurrenceAfterEndDate () {
297+ Date now = DateUtils .setSeconds (new Date (), 0 );
298+ ResourceScheduleVO schedule = Mockito .mock (ResourceScheduleVO .class );
299+ Mockito .when (schedule .getEnabled ()).thenReturn (true );
300+ Mockito .when (schedule .getSchedule ()).thenReturn ("* * * * *" );
301+ Mockito .when (schedule .getTimeZoneId ()).thenReturn (TimeZone .getTimeZone ("UTC" ).toZoneId ());
302+ // endDate is in the future (now < endDate), but the first occurrence (>= startDate)
303+ // falls after endDate, so no further jobs can ever be scheduled. The schedule's
304+ // declared lifetime hasn't ended yet though, so it must remain enabled until
305+ // endDate actually passes (handled separately by the "end time has passed" branch).
306+ Mockito .when (schedule .getStartDate ()).thenReturn (DateUtils .addDays (now , 10 ));
307+ Mockito .when (schedule .getEndDate ()).thenReturn (DateUtils .addDays (now , 5 ));
308+ Mockito .when (schedule .getResourceId ()).thenReturn (1L );
309+ Mockito .when (userVmManager .getUserVm (Mockito .anyLong ())).thenReturn (Mockito .mock (UserVm .class ));
310+
311+ Date actualDate = vmScheduleWorker .scheduleNextJob (schedule , new Date ());
312+
313+ Assert .assertNull (actualDate );
314+ Mockito .verify (schedule , Mockito .never ()).setEnabled (Mockito .anyBoolean ());
315+ Mockito .verify (resourceScheduleDao , Mockito .never ()).persist (Mockito .any ());
316+ }
317+
295318 @ Test
296319 public void testScheduleNextJobScheduleDisabled () {
297320 ResourceScheduleVO schedule = Mockito .mock (ResourceScheduleVO .class );
0 commit comments