1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.portal.service.daemon;
35
36 import java.time.Duration;
37 import java.time.Instant;
38 import java.util.List;
39 import java.util.concurrent.AbstractExecutorService;
40 import java.util.concurrent.BlockingQueue;
41 import java.util.concurrent.BrokenBarrierException;
42 import java.util.concurrent.ExecutorService;
43 import java.util.concurrent.Executors;
44 import java.util.concurrent.ForkJoinPool;
45 import java.util.concurrent.LinkedBlockingQueue;
46 import java.util.concurrent.TimeUnit;
47 import java.util.concurrent.TimeoutException;
48 import java.util.function.Consumer;
49
50 import fr.paris.lutece.test.LuteceTestCase;
51
52 public class DaemonSchedulerTest extends LuteceTestCase
53 {
54 private static final class TestExecutorService extends AbstractExecutorService
55 {
56 private final Consumer<Runnable> _executor;
57
58 public TestExecutorService( Consumer<Runnable> executor )
59 {
60 _executor = executor;
61 }
62
63 @Override
64 public void execute( Runnable command )
65 {
66 _executor.accept( command );
67 }
68
69 @Override
70 public List<Runnable> shutdownNow( )
71 {
72 return null;
73 }
74
75 @Override
76 public void shutdown( )
77 {
78 }
79
80 @Override
81 public boolean isTerminated( )
82 {
83 return false;
84 }
85
86 @Override
87 public boolean isShutdown( )
88 {
89 return false;
90 }
91
92 @Override
93 public boolean awaitTermination( long timeout, TimeUnit unit ) throws InterruptedException
94 {
95 return true;
96 }
97 }
98
99 public void testEnqueue( )
100 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
101 {
102 testEnqueue( false );
103 }
104
105 public void testEnqueueDaemonThrows( )
106 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
107 {
108 testEnqueue( true );
109 }
110
111
112
113
114
115
116
117
118
119
120
121 private void testEnqueue( boolean shouldThrow )
122 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
123 {
124 String strMethodName = new Object( )
125 {
126 }.getClass( ).getEnclosingMethod( ).getName( );
127 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
128 ExecutorService executor = Executors.newSingleThreadExecutor( );
129 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
130 try
131 {
132 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName + shouldThrow );
133 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
134 testDaemon.setRunThrows( shouldThrow );
135 scheduler.enqueue( entry, 0L, TimeUnit.MILLISECONDS );
136 assertFalse( testDaemon.hasRun( ) );
137 testDaemon.go( 250L, TimeUnit.MILLISECONDS );
138 testDaemon.waitForCompletion( );
139 assertTrue( testDaemon.hasRun( ) );
140 }
141 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
142 {
143 fail( e.getMessage( ) );
144 }
145 finally
146 {
147 scheduler.shutdown( );
148 }
149 }
150
151 public void testEnqueueDelay( )
152 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
153 {
154 testEnqueueDelay( false );
155 }
156
157 public void testEnqueueDelayDaemonThrows( )
158 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
159 {
160 testEnqueueDelay( true );
161 }
162
163
164
165
166
167
168
169
170
171
172
173 private void testEnqueueDelay( boolean shouldThrow )
174 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
175 {
176 String strMethodName = new Object( )
177 {
178 }.getClass( ).getEnclosingMethod( ).getName( );
179 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
180 ExecutorService executor = Executors.newSingleThreadExecutor( );
181 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
182 try
183 {
184 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName + shouldThrow );
185 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
186 testDaemon.setRunThrows( shouldThrow );
187 Instant start = Instant.now( );
188 assertTrue( scheduler.enqueue( entry, 500L, TimeUnit.MILLISECONDS ) );
189 assertFalse( testDaemon.hasRun( ) );
190 testDaemon.go( );
191 assertTrue( 500L <= Duration.between( start, Instant.now( ) ).toMillis( ) );
192 testDaemon.waitForCompletion( );
193 assertTrue( testDaemon.hasRun( ) );
194 }
195 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
196 {
197 fail( e.getMessage( ) );
198 }
199 finally
200 {
201 scheduler.shutdown( );
202 }
203 }
204
205
206
207
208
209
210
211
212
213
214
215 public void testEnqueueDelayIllegalState( )
216 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
217 {
218 String strMethodName = new Object( )
219 {
220 }.getClass( ).getEnclosingMethod( ).getName( );
221 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
222 ExecutorService executor = Executors.newSingleThreadExecutor( );
223 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
224 scheduler.shutdown( );
225 try
226 {
227 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName );
228 scheduler.enqueue( entry, 500L, TimeUnit.MILLISECONDS );
229 fail( "Should not be able to enqueue after shutdown" );
230 }
231 catch( IllegalStateException e )
232 {
233
234 }
235 finally
236 {
237 scheduler.shutdown( );
238 }
239 }
240
241 private DaemonEntry getDaemonEntry( String name ) throws ClassNotFoundException, InstantiationException, IllegalAccessException
242 {
243 DaemonEntry entry = new DaemonEntry( );
244 entry.setId( name );
245 entry.setIsRunning( true );
246 entry.setPluginName( "core" );
247 entry.setClassName( TestDaemon.class.getName( ) );
248 entry.loadDaemon( );
249 entry.setInterval( 1 );
250 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
251 testDaemon.setPluginName( "core" );
252 return entry;
253 }
254
255 public void testEnqueueFull( )
256 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
257 {
258 testEnqueueFull( false );
259 }
260
261 public void testEnqueueFullDaemonThrows( )
262 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
263 {
264 testEnqueueFull( true );
265 }
266
267
268
269
270
271
272
273
274
275
276
277 private void testEnqueueFull( boolean shouldThrow )
278 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
279 {
280 String strMethodName = new Object( )
281 {
282 }.getClass( ).getEnclosingMethod( ).getName( );
283 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( 1 );
284 ExecutorService executor = new TestExecutorService( runnable -> runnable.run( ) );
285 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
286 try
287 {
288 DaemonEntry executing = getDaemonEntry( "JUNIT-executing" + strMethodName + shouldThrow );
289 TestDaemon./../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon executingDaemon = (TestDaemon) executing.getDaemon( );
290 executingDaemon.setRunThrows( shouldThrow );
291 assertTrue( scheduler.enqueue( executing, 0L, TimeUnit.MILLISECONDS ) );
292 executingDaemon.go( );
293 DaemonEntry inqueue = getDaemonEntry( "JUNIT-inqueue" );
294 TestDaemon/../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon inqueueDaemon = (TestDaemon) inqueue.getDaemon( );
295 inqueueDaemon.setRunThrows( shouldThrow );
296 assertTrue( scheduler.enqueue( inqueue, 0L, TimeUnit.MILLISECONDS ) );
297 DaemonEntry refused = getDaemonEntry( "JUNIT-refused" );
298 assertFalse( scheduler.enqueue( refused, 0L, TimeUnit.MILLISECONDS ) );
299 executingDaemon.waitForCompletion( );
300 inqueueDaemon.go( );
301 inqueueDaemon.waitForCompletion( );
302 }
303 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
304 {
305 fail( e.getMessage( ) );
306 }
307 finally
308 {
309 scheduler.shutdown( );
310 }
311 }
312
313 public void testSchedule( )
314 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
315 {
316 testSchedule( false );
317 }
318
319 public void testSchedulDaemonThrows( )
320 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
321 {
322 testSchedule( true );
323 }
324
325
326
327
328
329
330
331
332
333
334
335 private void testSchedule( boolean shouldThrow )
336 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
337 {
338 String strMethodName = new Object( )
339 {
340 }.getClass( ).getEnclosingMethod( ).getName( );
341 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
342 ExecutorService executor = Executors.newSingleThreadExecutor( );
343 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
344 try
345 {
346 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName + shouldThrow );
347 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
348 testDaemon.setRunThrows( shouldThrow );
349 Instant start = Instant.now( );
350 scheduler.schedule( entry, 0L, TimeUnit.MILLISECONDS );
351 assertFalse( testDaemon.hasRun( ) );
352 testDaemon.go( );
353 System.out.println( "Daemon took " + Duration.between( start, Instant.now( ) ).toNanos( ) + "ns to execute" );
354 testDaemon.waitForCompletion( );
355 assertTrue( testDaemon.hasRun( ) );
356 testDaemon.go( );
357 assertTrue( 1000L <= Duration.between( start, Instant.now( ) ).toMillis( ) );
358 testDaemon.waitForCompletion( );
359 assertTrue( testDaemon.hasRun( ) );
360 }
361 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
362 {
363 fail( e.getMessage( ) );
364 }
365 finally
366 {
367 scheduler.shutdown( );
368 }
369 }
370
371 public void testScheduleDelay( )
372 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
373 {
374 testScheduleDelay( false );
375 }
376
377 public void testScheduleDelayDaemonThrows( )
378 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
379 {
380 testScheduleDelay( true );
381 }
382
383
384
385
386
387
388
389
390
391
392
393 private void testScheduleDelay( boolean shouldThrow )
394 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
395 {
396 String strMethodName = new Object( )
397 {
398 }.getClass( ).getEnclosingMethod( ).getName( );
399 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
400 ExecutorService executor = Executors.newSingleThreadExecutor( );
401 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
402 try
403 {
404 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName + shouldThrow );
405 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
406 testDaemon.setRunThrows( shouldThrow );
407 Instant start = Instant.now( );
408 scheduler.schedule( entry, 500L, TimeUnit.MILLISECONDS );
409 assertFalse( testDaemon.hasRun( ) );
410 testDaemon.go( );
411 assertTrue( 500L <= Duration.between( start, Instant.now( ) ).toMillis( ) );
412 testDaemon.waitForCompletion( );
413 assertTrue( testDaemon.hasRun( ) );
414 }
415 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
416 {
417 fail( e.getMessage( ) );
418 }
419 finally
420 {
421 scheduler.shutdown( );
422 }
423 }
424
425 public void testScheduleTwice( )
426 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
427 {
428 testScheduleTwice( false );
429 }
430
431 public void testScheduleTwiceDaemonThrows( )
432 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
433 {
434 testScheduleTwice( true );
435 }
436
437
438
439
440
441
442
443
444
445
446
447 private void testScheduleTwice( boolean shouldThrow )
448 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
449 {
450 String strMethodName = new Object( )
451 {
452 }.getClass( ).getEnclosingMethod( ).getName( );
453 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
454 ExecutorService executor = Executors.newSingleThreadExecutor( );
455 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
456 try
457 {
458 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName + shouldThrow );
459 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
460 testDaemon.setRunThrows( shouldThrow );
461 Instant start = Instant.now( );
462 scheduler.schedule( entry, 0L, TimeUnit.MICROSECONDS );
463 scheduler.schedule( entry, 500L, TimeUnit.MILLISECONDS );
464 assertFalse( testDaemon.hasRun( ) );
465 testDaemon.go( );
466 testDaemon.waitForCompletion( );
467 assertTrue( testDaemon.hasRun( ) );
468 testDaemon.go( );
469 long timeForSecondRun = Duration.between( start, Instant.now( ) ).toMillis( );
470 assertTrue( "Second run was " + timeForSecondRun + "ms after start", 1000L <= timeForSecondRun );
471 testDaemon.waitForCompletion( );
472 assertTrue( testDaemon.hasRun( ) );
473 }
474 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
475 {
476 fail( e.getMessage( ) );
477 }
478 finally
479 {
480 scheduler.shutdown( );
481 }
482 }
483
484
485
486
487
488
489
490
491
492
493
494 public void testUnScheduleNotScheduled( ) throws ClassNotFoundException, InstantiationException, IllegalAccessException
495 {
496 String strMethodName = new Object( )
497 {
498 }.getClass( ).getEnclosingMethod( ).getName( );
499 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
500 ExecutorService executor = Executors.newSingleThreadExecutor( );
501 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
502 try
503 {
504 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName );
505 scheduler.unSchedule( entry );
506
507 }
508 catch( Exception e )
509 {
510 fail( );
511 }
512 finally
513 {
514 scheduler.shutdown( );
515 }
516 }
517
518 public void testUnSchedule( )
519 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
520 {
521 testUnSchedule( false );
522 }
523
524 public void testUnScheduleDaemonThrows( )
525 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
526 {
527 testUnSchedule( true );
528 }
529
530
531
532
533
534
535
536
537
538
539
540 private void testUnSchedule( boolean shouldThrow )
541 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
542 {
543 String strMethodName = new Object( )
544 {
545 }.getClass( ).getEnclosingMethod( ).getName( );
546 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
547 ExecutorService executor = Executors.newSingleThreadExecutor( );
548 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
549 try
550 {
551 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName + shouldThrow );
552 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
553 testDaemon.setRunThrows( shouldThrow );
554 scheduler.schedule( entry, 0L, TimeUnit.MILLISECONDS );
555 assertFalse( testDaemon.hasRun( ) );
556 testDaemon.go( );
557 testDaemon.waitForCompletion( );
558 assertTrue( testDaemon.hasRun( ) );
559 assertEquals( 0, testDaemon.getStopCallNumber( ) );
560 Thread.sleep( 10L );
561 scheduler.unSchedule( entry );
562 assertEquals( 1, testDaemon.getStopCallNumber( ) );
563 try
564 {
565 testDaemon.go( 1100L, TimeUnit.MILLISECONDS );
566 fail( "Daemon executed after unscheduling" );
567 }
568 catch( TimeoutException e )
569 {
570
571 }
572 }
573 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
574 {
575 fail( e.getMessage( ) );
576 }
577 finally
578 {
579 scheduler.shutdown( );
580 }
581 }
582
583 public void testUnScheduleWhileRunning( )
584 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
585 {
586 testUnScheduleWhileRunning( false );
587 }
588
589 public void testUnScheduleWhileRunningDaemonThrows( )
590 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
591 {
592 testUnScheduleWhileRunning( true );
593 }
594
595
596
597
598
599
600
601
602
603
604
605 private void testUnScheduleWhileRunning( boolean shouldThrow )
606 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
607 {
608 String strMethodName = new Object( )
609 {
610 }.getClass( ).getEnclosingMethod( ).getName( );
611 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
612 ExecutorService executor = Executors.newSingleThreadExecutor( );
613 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
614 try
615 {
616 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName + shouldThrow );
617 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
618 testDaemon.setRunThrows( shouldThrow );
619 scheduler.schedule( entry, 0L, TimeUnit.MILLISECONDS );
620 assertFalse( testDaemon.hasRun( ) );
621 testDaemon.go( );
622 assertEquals( 0, testDaemon.getStopCallNumber( ) );
623
624 scheduler.unSchedule( entry );
625 Thread.sleep( 10L );
626 assertEquals( "Stopping should wait for execution end", 0, testDaemon.getStopCallNumber( ) );
627 testDaemon.waitForCompletion( );
628 assertTrue( testDaemon.hasRun( ) );
629 Thread.sleep( 10L );
630 assertEquals( 1, testDaemon.getStopCallNumber( ) );
631 try
632 {
633 testDaemon.go( 1100L, TimeUnit.MILLISECONDS );
634 fail( "Daemon executed after unscheduling" );
635 }
636 catch( TimeoutException e )
637 {
638
639 }
640 }
641 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
642 {
643 fail( e.getMessage( ) );
644 }
645 finally
646 {
647 scheduler.shutdown( );
648 }
649 }
650
651 public void testEnqueueWhileRunning( )
652 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
653 {
654 testEnqueueWhileRunning( false );
655 }
656
657 public void testEnqueueWhileRunningDaemonThrows( )
658 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
659 {
660 testEnqueueWhileRunning( true );
661 }
662
663
664
665
666
667
668
669
670
671
672
673 private void testEnqueueWhileRunning( boolean shouldThrow )
674 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
675 {
676 String strMethodName = new Object( )
677 {
678 }.getClass( ).getEnclosingMethod( ).getName( );
679 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
680 ExecutorService executor = Executors.newCachedThreadPool( );
681 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
682 try
683 {
684 DaemonEntry executing = getDaemonEntry( "JUNIT-executing" + strMethodName + shouldThrow );
685 TestDaemon./../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon executingDaemon = (TestDaemon) executing.getDaemon( );
686 executingDaemon.setRunThrows( shouldThrow );
687 assertTrue( scheduler.enqueue( executing, 0L, TimeUnit.MILLISECONDS ) );
688 executingDaemon.go( );
689 assertTrue( scheduler.enqueue( executing, 0L, TimeUnit.MILLISECONDS ) );
690 try
691 {
692 executingDaemon.go( 200, TimeUnit.MILLISECONDS );
693 fail( "Daemon started execution while already running" );
694 }
695 catch( TimeoutException e )
696 {
697 executingDaemon.resetGo( );
698 }
699 executingDaemon.waitForCompletion( );
700 executingDaemon.go( );
701 executingDaemon.waitForCompletion( );
702 }
703 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
704 {
705 fail( e.getMessage( ) );
706 }
707 finally
708 {
709 scheduler.shutdown( );
710 }
711 }
712
713 public void testEnqueueCoalesce( )
714 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
715 {
716 testEnqueueCoalesce( false );
717 }
718
719 public void testEnqueueCoalesceDaemonThrows( )
720 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
721 {
722 testEnqueueCoalesce( true );
723 }
724
725
726
727
728
729
730
731
732
733
734
735 private void testEnqueueCoalesce( boolean shouldThrow )
736 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
737 {
738 String strMethodName = new Object( )
739 {
740 }.getClass( ).getEnclosingMethod( ).getName( );
741 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
742 ExecutorService executor = new TestExecutorService( runnable -> runnable.run( ) );
743 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
744 try
745 {
746 DaemonEntry executing = getDaemonEntry( "JUNIT-executing" + strMethodName + shouldThrow );
747 TestDaemon./../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon executingDaemon = (TestDaemon) executing.getDaemon( );
748 executingDaemon.setRunThrows( shouldThrow );
749 assertTrue( scheduler.enqueue( executing, 0L, TimeUnit.MILLISECONDS ) );
750 executingDaemon.go( );
751 DaemonEntry inqueue = getDaemonEntry( "JUNIT-inqueue" );
752 TestDaemon/../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon inqueueDaemon = (TestDaemon) inqueue.getDaemon( );
753 inqueueDaemon.setRunThrows( shouldThrow );
754 assertTrue( scheduler.enqueue( inqueue, 0L, TimeUnit.MILLISECONDS ) );
755 assertTrue( scheduler.enqueue( inqueue, 0L, TimeUnit.MILLISECONDS ) );
756 executingDaemon.waitForCompletion( );
757 inqueueDaemon.go( );
758 inqueueDaemon.waitForCompletion( );
759 try
760 {
761 inqueueDaemon.go( 200, TimeUnit.MILLISECONDS );
762 fail( "Daemon started twice but should have been coalesced" );
763 }
764 catch( TimeoutException e )
765 {
766
767 }
768 }
769 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
770 {
771 fail( e.getMessage( ) );
772 }
773 finally
774 {
775 scheduler.shutdown( );
776 }
777 }
778
779 public void testShutdown( )
780 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
781 {
782 testShutdown( false );
783 }
784
785 public void testShutdownThrows( )
786 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
787 {
788 testShutdown( true );
789 }
790
791
792
793
794
795
796
797
798
799
800
801 private void testShutdown( boolean shouldThrow )
802 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
803 {
804 String strMethodName = new Object( )
805 {
806 }.getClass( ).getEnclosingMethod( ).getName( );
807 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
808 ExecutorService executor = Executors.newCachedThreadPool( );
809 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
810 try
811 {
812 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName + shouldThrow );
813 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
814 testDaemon.setStopThrows( shouldThrow );
815 scheduler.schedule( entry, 0L, TimeUnit.MILLISECONDS );
816 DaemonEntry entry2 = getDaemonEntry( "JUNIT2" );
817 TestDaemon../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon2 = (TestDaemon) entry2.getDaemon( );
818 testDaemon2.setStopThrows( shouldThrow );
819 scheduler.schedule( entry2, 0L, TimeUnit.MILLISECONDS );
820 assertFalse( testDaemon.hasRun( ) );
821 assertFalse( testDaemon2.hasRun( ) );
822 testDaemon.go( 250L, TimeUnit.MILLISECONDS );
823 testDaemon2.go( 250L, TimeUnit.MILLISECONDS );
824 testDaemon.waitForCompletion( );
825 testDaemon2.waitForCompletion( );
826 assertTrue( testDaemon.hasRun( ) );
827 assertTrue( testDaemon2.hasRun( ) );
828 Thread.sleep( 10L );
829
830 scheduler.shutdown( );
831 assertEquals( 1, testDaemon.getStopCallNumber( ) );
832 assertEquals( 1, testDaemon2.getStopCallNumber( ) );
833 }
834 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
835 {
836 fail( e.getMessage( ) );
837 }
838 finally
839 {
840 scheduler.shutdown( );
841 }
842 }
843
844 public void testShutdownWhileRunning( )
845 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
846 {
847 testShutdownWhileRunning( false );
848 }
849
850 public void testShutdownWhileRunningThrows( )
851 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
852 {
853 testShutdownWhileRunning( true );
854 }
855
856
857
858
859
860
861
862
863
864
865
866 private void testShutdownWhileRunning( boolean shouldThrow )
867 throws ClassNotFoundException, InstantiationException, IllegalAccessException, InterruptedException, BrokenBarrierException, TimeoutException
868 {
869 String strMethodName = new Object( )
870 {
871 }.getClass( ).getEnclosingMethod( ).getName( );
872 BlockingQueue<DaemonEntry> queue = new LinkedBlockingQueue<>( );
873 ExecutorService executor = new TestExecutorService( runnable -> ForkJoinPool.commonPool( ).execute( runnable ) );
874 DaemonScheduler scheduler = new DaemonScheduler( queue, executor );
875 try
876 {
877 DaemonEntry entry = getDaemonEntry( "JUNIT" + strMethodName + shouldThrow );
878 TestDaemon/../../../fr/paris/lutece/portal/service/daemon/TestDaemon.html#TestDaemon">TestDaemon testDaemon = (TestDaemon) entry.getDaemon( );
879 testDaemon.setStopThrows( shouldThrow );
880 scheduler.schedule( entry, 0L, TimeUnit.MILLISECONDS );
881 assertFalse( testDaemon.hasRun( ) );
882 testDaemon.go( 250L, TimeUnit.MILLISECONDS );
883 scheduler.shutdown( );
884 assertEquals( 0, testDaemon.getStopCallNumber( ) );
885 testDaemon.waitForCompletion( );
886 assertTrue( testDaemon.hasRun( ) );
887 Thread.sleep( 10L );
888
889 assertEquals( 1, testDaemon.getStopCallNumber( ) );
890 }
891 catch( InterruptedException | BrokenBarrierException | TimeoutException e )
892 {
893 fail( e.getMessage( ) );
894 }
895 finally
896 {
897 scheduler.shutdown( );
898 }
899 }
900 }