22
22
import java .lang .annotation .RetentionPolicy ;
23
23
import java .lang .annotation .Target ;
24
24
import java .lang .reflect .Method ;
25
+ import java .util .Calendar ;
26
+ import java .util .Date ;
25
27
import java .util .List ;
26
28
import java .util .Properties ;
29
+ import java .util .TimeZone ;
27
30
28
31
import org .junit .Test ;
29
32
33
36
import org .springframework .beans .factory .config .PropertyPlaceholderConfigurer ;
34
37
import org .springframework .beans .factory .support .RootBeanDefinition ;
35
38
import org .springframework .context .support .StaticApplicationContext ;
39
+ import org .springframework .scheduling .Trigger ;
40
+ import org .springframework .scheduling .TriggerContext ;
36
41
import org .springframework .scheduling .config .CronTask ;
37
42
import org .springframework .scheduling .config .IntervalTask ;
38
43
import org .springframework .scheduling .config .ScheduledTaskRegistrar ;
44
+ import org .springframework .scheduling .support .CronTrigger ;
39
45
import org .springframework .scheduling .support .ScheduledMethodRunnable ;
46
+ import org .springframework .scheduling .support .SimpleTriggerContext ;
40
47
import org .springframework .tests .Assume ;
41
48
import org .springframework .tests .TestGroup ;
42
49
47
54
* @author Juergen Hoeller
48
55
* @author Chris Beams
49
56
* @author Sam Brannen
57
+ * @author Stevo Slavić
50
58
*/
51
59
public class ScheduledAnnotationBeanPostProcessorTests {
52
60
@@ -128,16 +136,13 @@ public void fixedRateTaskWithInitialDelay() {
128
136
assertEquals (3000L , task .getInterval ());
129
137
}
130
138
131
- // TODO Reinstate repeated @Scheduled tests once we have full Java 8 support in the
132
- // IDEs.
133
- // @Test
134
- // public void severalFixedRatesWithRepeatedScheduledAnnotation() {
135
- // BeanDefinition processorDefinition = new
136
- // RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
137
- // BeanDefinition targetDefinition = new RootBeanDefinition(
138
- // SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean.class);
139
- // severalFixedRates(context, processorDefinition, targetDefinition);
140
- // }
139
+ @ Test
140
+ public void severalFixedRatesWithRepeatedScheduledAnnotation () {
141
+ BeanDefinition processorDefinition = new
142
+ RootBeanDefinition (ScheduledAnnotationBeanPostProcessor .class );
143
+ BeanDefinition targetDefinition = new RootBeanDefinition (SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean .class );
144
+ severalFixedRates (context , processorDefinition , targetDefinition );
145
+ }
141
146
142
147
@ Test
143
148
public void severalFixedRatesWithSchedulesContainerAnnotation () {
@@ -207,6 +212,63 @@ public void cronTask() throws InterruptedException {
207
212
Thread .sleep (10000 );
208
213
}
209
214
215
+ @ Test
216
+ public void cronTaskWithZone () throws InterruptedException {
217
+ Assume .group (TestGroup .LONG_RUNNING );
218
+
219
+ BeanDefinition processorDefinition = new RootBeanDefinition (ScheduledAnnotationBeanPostProcessor .class );
220
+ BeanDefinition targetDefinition = new RootBeanDefinition (
221
+ ScheduledAnnotationBeanPostProcessorTests .CronWithTimezoneTestBean .class );
222
+ context .registerBeanDefinition ("postProcessor" , processorDefinition );
223
+ context .registerBeanDefinition ("target" , targetDefinition );
224
+ context .refresh ();
225
+ Object postProcessor = context .getBean ("postProcessor" );
226
+ Object target = context .getBean ("target" );
227
+ ScheduledTaskRegistrar registrar = (ScheduledTaskRegistrar )
228
+ new DirectFieldAccessor (postProcessor ).getPropertyValue ("registrar" );
229
+ @ SuppressWarnings ("unchecked" )
230
+ List <CronTask > cronTasks = (List <CronTask >)
231
+ new DirectFieldAccessor (registrar ).getPropertyValue ("cronTasks" );
232
+ assertEquals (1 , cronTasks .size ());
233
+ CronTask task = cronTasks .get (0 );
234
+ ScheduledMethodRunnable runnable = (ScheduledMethodRunnable ) task .getRunnable ();
235
+ Object targetObject = runnable .getTarget ();
236
+ Method targetMethod = runnable .getMethod ();
237
+ assertEquals (target , targetObject );
238
+ assertEquals ("cron" , targetMethod .getName ());
239
+ assertEquals ("0 0 0-4,6-23 * * ?" , task .getExpression ());
240
+ Trigger trigger = task .getTrigger ();
241
+ assertNotNull (trigger );
242
+ assertTrue (trigger instanceof CronTrigger );
243
+ CronTrigger cronTrigger = (CronTrigger ) trigger ;
244
+ Calendar cal = Calendar .getInstance (TimeZone .getTimeZone ("GMT+10" ));
245
+ cal .clear ();
246
+ cal .set (2013 , 3 , 15 , 4 , 0 ); // 15-04-2013 4:00 GMT+10
247
+ Date lastScheduledExecutionTime = cal .getTime ();
248
+ Date lastActualExecutionTime = cal .getTime ();
249
+ cal .add (Calendar .MINUTE , 30 ); // 4:30
250
+ Date lastCompletionTime = cal .getTime ();
251
+ TriggerContext triggerContext = new SimpleTriggerContext (lastScheduledExecutionTime , lastActualExecutionTime , lastCompletionTime );
252
+ cal .add (Calendar .MINUTE , 30 );
253
+ cal .add (Calendar .HOUR_OF_DAY , 1 ); // 6:00
254
+ Date nextExecutionTime = cronTrigger .nextExecutionTime (triggerContext );
255
+ assertEquals (cal .getTime (), nextExecutionTime ); // assert that 6:00 is next execution time
256
+ Thread .sleep (10000 );
257
+ }
258
+
259
+ @ Test (expected = BeanCreationException .class )
260
+ public void cronTaskWithInvalidZone () throws InterruptedException {
261
+ Assume .group (TestGroup .LONG_RUNNING );
262
+
263
+ BeanDefinition processorDefinition = new RootBeanDefinition (ScheduledAnnotationBeanPostProcessor .class );
264
+ BeanDefinition targetDefinition = new RootBeanDefinition (
265
+ ScheduledAnnotationBeanPostProcessorTests .CronWithInvalidTimezoneTestBean .class );
266
+ context .registerBeanDefinition ("postProcessor" , processorDefinition );
267
+ context .registerBeanDefinition ("target" , targetDefinition );
268
+ context .refresh ();
269
+ Thread .sleep (10000 );
270
+ }
271
+
210
272
@ Test
211
273
public void metaAnnotationWithFixedRate () {
212
274
BeanDefinition processorDefinition = new RootBeanDefinition (ScheduledAnnotationBeanPostProcessor .class );
@@ -453,23 +515,42 @@ public void fixedRate() {
453
515
}
454
516
455
517
456
- // TODO Reinstate repeated @Scheduled tests once we have full Java 8 support in the
457
- // IDEs.
458
- // static class SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean {
459
- //
460
- // @Scheduled(fixedRate=4000)
461
- // @Scheduled(fixedRate=4000, initialDelay=2000)
462
- // public void fixedRate() {
463
- // }
464
- // }
518
+ static class SeveralFixedRatesWithRepeatedScheduledAnnotationTestBean {
519
+
520
+ // can use Java 8 repeated @Scheduled once we have Eclipse IDE support for it
521
+ @ Schedules ({
522
+ @ Scheduled (fixedRate =4000 ),
523
+ @ Scheduled (fixedRate =4000 , initialDelay =2000 )
524
+ })
525
+ public void fixedRate () {
526
+ }
527
+ }
528
+
465
529
466
530
static class CronTestBean {
467
531
468
532
@ Scheduled (cron ="*/7 * * * * ?" )
469
533
public void cron () throws IOException {
470
534
throw new IOException ("no no no" );
471
535
}
536
+ }
537
+
538
+
539
+ static class CronWithTimezoneTestBean {
540
+
541
+ @ Scheduled (cron ="0 0 0-4,6-23 * * ?" , zone = "GMT+10" )
542
+ public void cron () throws IOException {
543
+ throw new IOException ("no no no" );
544
+ }
545
+ }
546
+
547
+
548
+ static class CronWithInvalidTimezoneTestBean {
472
549
550
+ @ Scheduled (cron ="0 0 0-4,6-23 * * ?" , zone = "FOO" )
551
+ public void cron () throws IOException {
552
+ throw new IOException ("no no no" );
553
+ }
473
554
}
474
555
475
556
@@ -478,7 +559,6 @@ static class EmptyAnnotationTestBean {
478
559
@ Scheduled
479
560
public void invalid () {
480
561
}
481
-
482
562
}
483
563
484
564
@@ -487,7 +567,6 @@ static class InvalidCronTestBean {
487
567
@ Scheduled (cron ="abc" )
488
568
public void invalid () {
489
569
}
490
-
491
570
}
492
571
493
572
@@ -497,7 +576,6 @@ static class NonVoidReturnTypeTestBean {
497
576
public String invalid () {
498
577
return "oops" ;
499
578
}
500
-
501
579
}
502
580
503
581
@@ -506,7 +584,6 @@ static class NonEmptyParamListTestBean {
506
584
@ Scheduled (fixedRate =3000 )
507
585
public void invalid (String oops ) {
508
586
}
509
-
510
587
}
511
588
512
589
0 commit comments