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.web.system;
35
36 import java.io.File;
37 import java.io.FileInputStream;
38 import java.io.FileNotFoundException;
39 import java.io.FileOutputStream;
40 import java.io.IOException;
41 import java.util.Properties;
42 import java.util.concurrent.BrokenBarrierException;
43 import java.util.concurrent.TimeUnit;
44 import java.util.concurrent.TimeoutException;
45
46 import org.springframework.mock.web.MockHttpServletRequest;
47
48 import fr.paris.lutece.portal.business.user.AdminUser;
49 import fr.paris.lutece.portal.service.admin.AccessDeniedException;
50 import fr.paris.lutece.portal.service.admin.PasswordResetException;
51 import fr.paris.lutece.portal.service.daemon.AppDaemonService;
52 import fr.paris.lutece.portal.service.daemon.DaemonEntry;
53 import fr.paris.lutece.portal.service.daemon.TestDaemon;
54 import fr.paris.lutece.portal.service.datastore.DatastoreService;
55 import fr.paris.lutece.portal.service.security.SecurityTokenService;
56 import fr.paris.lutece.portal.service.util.AppPropertiesService;
57 import fr.paris.lutece.portal.service.util.AppLogService;
58 import fr.paris.lutece.test.LuteceTestCase;
59 import fr.paris.lutece.test.Utils;
60
61 public class DaemonsJspBeanTest extends LuteceTestCase
62 {
63 private static final String TEMPLATE_MANAGE_DAEMONS = "admin/system/manage_daemons.html";
64 private static final String JUNIT_DAEMON = "JUNIT";
65 private static final String DAEMON_INTERVAL_DSKEY = "core.daemon." + JUNIT_DAEMON + ".interval";
66 private DaemonsJspBean bean;
67 private DaemonEntry _entry;
68 private String origMaxInitialStartDelay;
69 private TestDaemon _testDaemon;
70
71 @Override
72 protected void setUp( ) throws Exception
73 {
74 super.setUp( );
75 origMaxInitialStartDelay = setInitialStartDelay( );
76 assertEquals( "Failed to adjust daemon initial start delay", 1, AppPropertiesService.getPropertyInt( "daemon.maxInitialStartDelay", 3000 ) );
77 bean = new DaemonsJspBean( );
78 _entry = new DaemonEntry( );
79 _entry.setId( JUNIT_DAEMON );
80 _entry.setNameKey( JUNIT_DAEMON );
81 _entry.setDescriptionKey( JUNIT_DAEMON );
82 _entry.setClassName( TestDaemon.class.getName( ) );
83 _entry.setPluginName( "core" );
84
85 DatastoreService.setInstanceDataValue( DAEMON_INTERVAL_DSKEY, "1" );
86 AppDaemonService.registerDaemon( _entry );
87 _testDaemon = (TestDaemon) AppDaemonService.getDaemon( JUNIT_DAEMON );
88 }
89
90 private String setInitialStartDelay( ) throws FileNotFoundException, IOException
91 {
92 File propertiesFile = new File( getResourcesDir( ) + "/WEB-INF/conf/daemons.properties" );
93 Properties props = new Properties( );
94 try ( FileInputStream is = new FileInputStream( propertiesFile ) )
95 {
96 props.load( is );
97 }
98 String orig = props.getProperty( "daemon.maxInitialStartDelay" );
99 props.setProperty( "daemon.maxInitialStartDelay", "1" );
100 try ( FileOutputStream out = new FileOutputStream( propertiesFile ) )
101 {
102 props.store( out, "junit" );
103 }
104 AppPropertiesService.reloadAll( );
105 return orig;
106 }
107
108 @Override
109 protected void tearDown( ) throws Exception
110 {
111
112
113
114
115
116
117
118
119
120
121
122
123
124 _testDaemon.resetGo( );
125 _testDaemon.resetCompletion( );
126
127 DatastoreService.removeInstanceData( DAEMON_INTERVAL_DSKEY );
128 AppDaemonService.stopDaemon( JUNIT_DAEMON );
129 AppDaemonService.unregisterDaemon( JUNIT_DAEMON );
130 restoreInitialStartDelay( origMaxInitialStartDelay );
131 assertEquals( "Failed to restore daemon initial start delay", origMaxInitialStartDelay,
132 AppPropertiesService.getProperty( "daemon.maxInitialStartDelay" ) );
133 super.tearDown( );
134 }
135
136 private void restoreInitialStartDelay( String orig ) throws FileNotFoundException, IOException
137 {
138 File propertiesFile = new File( getResourcesDir( ) + "/WEB-INF/conf/daemons.properties" );
139 Properties props = new Properties( );
140 try ( FileInputStream is = new FileInputStream( propertiesFile ) )
141 {
142 props.load( is );
143 }
144 if ( orig == null )
145 {
146 props.remove( "daemon.maxInitialStartDelay" );
147 }
148 else
149 {
150 props.setProperty( "daemon.maxInitialStartDelay", orig );
151 }
152 try ( FileOutputStream out = new FileOutputStream( propertiesFile ) )
153 {
154 props.store( out, "junit" );
155 }
156 AppPropertiesService.reloadAll( );
157 }
158
159 public void testDoDaemonActionStart( ) throws InterruptedException, BrokenBarrierException, TimeoutException, AccessDeniedException
160 {
161 long lReadyTime;
162 long lScheduledTime;
163 assertFalse( _entry.isRunning( ) );
164 MockHttpServletRequest request = new MockHttpServletRequest( );
165 request.setParameter( "action", "START" );
166 request.setParameter( "daemon", JUNIT_DAEMON );
167 request.setParameter( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_DAEMONS ) );
168 lReadyTime = System.nanoTime( );
169 bean.doDaemonAction( request );
170
171 assertTrue( _entry.isRunning( ) );
172 _testDaemon.go( );
173 lScheduledTime = System.nanoTime( );
174 AppLogService.info( "Daemon scheduled after {} ms", ( ( lScheduledTime - lReadyTime ) / 1000000 ) );
175
176 _testDaemon.waitForCompletion( );
177
178 lReadyTime = System.nanoTime( );
179 _testDaemon.go( );
180 lScheduledTime = System.nanoTime( );
181 long lRescheduleDurationMilliseconds = ( ( lScheduledTime - lReadyTime ) / 1000000 );
182 long lMarginMilliseconds = 250;
183 AppLogService.info( "Daemon scheduled after {} ms", lRescheduleDurationMilliseconds );
184
185 _testDaemon.waitForCompletion( );
186
187
188 assertTrue( "Daemon should be re-scheduled approximately 1 second after the end of the previous run, but got " + lRescheduleDurationMilliseconds + "ms",
189 1000 - lMarginMilliseconds <= lRescheduleDurationMilliseconds && lRescheduleDurationMilliseconds <= 1000 + lMarginMilliseconds );
190 }
191
192 public void testDoDaemonActionStartInvalidToken( ) throws InterruptedException, BrokenBarrierException, TimeoutException, AccessDeniedException
193 {
194 assertFalse( _entry.isRunning( ) );
195 MockHttpServletRequest request = new MockHttpServletRequest( );
196 request.setParameter( "action", "START" );
197 request.setParameter( "daemon", JUNIT_DAEMON );
198 request.setParameter( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_DAEMONS ) + "b" );
199 try
200 {
201 bean.doDaemonAction( request );
202 fail( "Should have thrown" );
203 }
204 catch( AccessDeniedException e )
205 {
206 assertFalse( _entry.isRunning( ) );
207 try
208 {
209
210 _testDaemon.go( 2500, TimeUnit.MILLISECONDS );
211 fail( "Daemon running be should not" );
212 }
213 catch( TimeoutException te )
214 {
215
216 }
217 }
218 }
219
220 public void testDoDaemonActionStartNoToken( ) throws InterruptedException, BrokenBarrierException, TimeoutException, AccessDeniedException
221 {
222 assertFalse( _entry.isRunning( ) );
223 MockHttpServletRequest request = new MockHttpServletRequest( );
224 request.setParameter( "action", "START" );
225 request.setParameter( "daemon", JUNIT_DAEMON );
226 try
227 {
228 bean.doDaemonAction( request );
229 fail( "Should have thrown" );
230 }
231 catch( AccessDeniedException e )
232 {
233 assertFalse( _entry.isRunning( ) );
234 try
235 {
236
237 _testDaemon.go( 2500, TimeUnit.MILLISECONDS );
238 fail( "Daemon running be should not" );
239 }
240 catch( TimeoutException te )
241 {
242
243 }
244 }
245 }
246
247 public void testDoDaemonActionStop( ) throws InterruptedException, BrokenBarrierException, TimeoutException, AccessDeniedException
248 {
249 assertFalse( _entry.isRunning( ) );
250 AppDaemonService.startDaemon( JUNIT_DAEMON );
251
252
253 _testDaemon.go( );
254 _testDaemon.waitForCompletion( );
255
256 MockHttpServletRequest request = new MockHttpServletRequest( );
257 request.setParameter( "action", "STOP" );
258 request.setParameter( "daemon", JUNIT_DAEMON );
259 request.setParameter( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_DAEMONS ) );
260 bean.doDaemonAction( request );
261 assertFalse( _entry.isRunning( ) );
262 try
263 {
264
265
266 _testDaemon.go( 2500, TimeUnit.MILLISECONDS );
267 fail( "Daemon still running after stop" );
268 }
269 catch( TimeoutException e )
270 {
271
272 }
273 }
274
275 public void testDoDaemonActionStopInvalidToken( ) throws InterruptedException, BrokenBarrierException, TimeoutException, AccessDeniedException
276 {
277 assertFalse( _entry.isRunning( ) );
278 AppDaemonService.startDaemon( JUNIT_DAEMON );
279
280
281 _testDaemon.go( );
282 _testDaemon.waitForCompletion( );
283
284 MockHttpServletRequest request = new MockHttpServletRequest( );
285 request.setParameter( "action", "STOP" );
286 request.setParameter( "daemon", JUNIT_DAEMON );
287 request.setParameter( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_DAEMONS ) + "b" );
288 try
289 {
290 bean.doDaemonAction( request );
291 fail( "Should have thrown" );
292 }
293 catch( AccessDeniedException e )
294 {
295 assertTrue( _entry.isRunning( ) );
296 _testDaemon.go( );
297 _testDaemon.waitForCompletion( );
298 }
299 }
300
301 public void testDoDaemonActionStopNoToken( ) throws InterruptedException, BrokenBarrierException, TimeoutException, AccessDeniedException
302 {
303 assertFalse( _entry.isRunning( ) );
304 AppDaemonService.startDaemon( JUNIT_DAEMON );
305
306
307 _testDaemon.go( );
308 _testDaemon.waitForCompletion( );
309
310 MockHttpServletRequest request = new MockHttpServletRequest( );
311 request.setParameter( "action", "STOP" );
312 request.setParameter( "daemon", JUNIT_DAEMON );
313 try
314 {
315 bean.doDaemonAction( request );
316 fail( "Should have thrown" );
317 }
318 catch( AccessDeniedException e )
319 {
320 assertTrue( _entry.isRunning( ) );
321 _testDaemon.go( );
322 _testDaemon.waitForCompletion( );
323 }
324 }
325
326 public void testDoDaemonActionRun( ) throws InterruptedException, BrokenBarrierException, TimeoutException, AccessDeniedException
327 {
328 long lReadyTime;
329 long lScheduledTime;
330 assertFalse( _entry.isRunning( ) );
331 _entry.setInterval( 1000 );
332
333 lReadyTime = System.nanoTime( );
334 AppDaemonService.startDaemon( JUNIT_DAEMON );
335
336
337 _testDaemon.go( );
338 lScheduledTime = System.nanoTime( );
339 AppLogService.info( "Daemon scheduled after {} ms", ( ( lScheduledTime - lReadyTime ) / 1000000 ) );
340
341 _testDaemon.waitForCompletion( );
342
343 MockHttpServletRequest request = new MockHttpServletRequest( );
344 request.setParameter( "action", "RUN" );
345
346 request.setParameter( "daemon", JUNIT_DAEMON );
347 request.setParameter( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_DAEMONS ) );
348 lReadyTime = System.nanoTime( );
349 bean.doDaemonAction( request );
350
351 _testDaemon.go( );
352 lScheduledTime = System.nanoTime( );
353 AppLogService.info( "Daemon scheduled after {} ms", ( ( lScheduledTime - lReadyTime ) / 1000000 ) );
354
355 _testDaemon.waitForCompletion( );
356 }
357
358 public void testDoDaemonActionRunInvalidToken( ) throws InterruptedException, BrokenBarrierException, TimeoutException, AccessDeniedException
359 {
360 long lReadyTime;
361 long lScheduledTime;
362 assertFalse( _entry.isRunning( ) );
363 _entry.setInterval( 1000 );
364
365 lReadyTime = System.nanoTime( );
366 AppDaemonService.startDaemon( JUNIT_DAEMON );
367
368
369 _testDaemon.go( );
370 lScheduledTime = System.nanoTime( );
371 AppLogService.info( "Daemon scheduled after {} ms", ( ( lScheduledTime - lReadyTime ) / 1000000 ) );
372
373 _testDaemon.waitForCompletion( );
374
375 MockHttpServletRequest request = new MockHttpServletRequest( );
376 request.setParameter( "action", "RUN" );
377
378 request.setParameter( "daemon", JUNIT_DAEMON );
379 request.setParameter( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_DAEMONS ) + "b" );
380
381 try
382 {
383 bean.doDaemonAction( request );
384 fail( "Should have thrown" );
385 }
386 catch( AccessDeniedException e )
387 {
388 try
389 {
390
391 _testDaemon.go( 1, TimeUnit.SECONDS );
392 fail( "Daemon should not have run" );
393 }
394 catch( TimeoutException te )
395 {
396
397 }
398 }
399 }
400
401 public void testDoDaemonActionRunNoToken( ) throws InterruptedException, BrokenBarrierException, TimeoutException, AccessDeniedException
402 {
403 long lReadyTime;
404 long lScheduledTime;
405 assertFalse( _entry.isRunning( ) );
406 _entry.setInterval( 1000 );
407
408 lReadyTime = System.nanoTime( );
409 AppDaemonService.startDaemon( JUNIT_DAEMON );
410
411
412 _testDaemon.go( );
413 lScheduledTime = System.nanoTime( );
414 AppLogService.info( "Daemon scheduled after {} ms", ( ( lScheduledTime - lReadyTime ) / 1000000 ) );
415
416 _testDaemon.waitForCompletion( );
417
418 MockHttpServletRequest request = new MockHttpServletRequest( );
419 request.setParameter( "action", "RUN" );
420
421 request.setParameter( "daemon", JUNIT_DAEMON );
422
423 try
424 {
425 bean.doDaemonAction( request );
426 fail( "Should have thrown" );
427 }
428 catch( AccessDeniedException e )
429 {
430 try
431 {
432
433 _testDaemon.go( 1, TimeUnit.SECONDS );
434 fail( "Daemon should not have run" );
435 }
436 catch( TimeoutException te )
437 {
438
439 }
440 }
441 }
442
443 public void testDoDaemonActionUpdateInterval( ) throws AccessDeniedException
444 {
445 final long lTestInterval = 314159L;
446 MockHttpServletRequest request = new MockHttpServletRequest( );
447 request.setParameter( "action", "UPDATE_INTERVAL" );
448 request.setParameter( "daemon", JUNIT_DAEMON );
449 request.setParameter( "interval", Long.toString( lTestInterval ) );
450 request.setParameter( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_DAEMONS ) );
451 bean.doDaemonAction( request );
452 assertEquals( lTestInterval, _entry.getInterval( ) );
453 }
454
455 public void testDoDaemonActionUpdateIntervalInvalidToken( ) throws AccessDeniedException
456 {
457 final long lTestInterval = 314159L;
458 MockHttpServletRequest request = new MockHttpServletRequest( );
459 request.setParameter( "action", "UPDATE_INTERVAL" );
460 request.setParameter( "daemon", JUNIT_DAEMON );
461 request.setParameter( "interval", Long.toString( lTestInterval ) );
462 request.setParameter( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_DAEMONS ) + "b" );
463 try
464 {
465 bean.doDaemonAction( request );
466 fail( "Should have thrown" );
467 }
468 catch( AccessDeniedException e )
469 {
470 assertEquals( 1, _entry.getInterval( ) );
471 }
472 }
473
474 public void testDoDaemonActionUpdateIntervalNoToken( ) throws AccessDeniedException
475 {
476 final long lTestInterval = 314159L;
477 MockHttpServletRequest request = new MockHttpServletRequest( );
478 request.setParameter( "action", "UPDATE_INTERVAL" );
479 request.setParameter( "daemon", JUNIT_DAEMON );
480 request.setParameter( "interval", Long.toString( lTestInterval ) );
481
482 try
483 {
484 bean.doDaemonAction( request );
485 fail( "Should have thrown" );
486 }
487 catch( AccessDeniedException e )
488 {
489 assertEquals( 1, _entry.getInterval( ) );
490 }
491 }
492
493 public void testDoDaemonActionUnknown( ) throws AccessDeniedException
494 {
495 try
496 {
497 MockHttpServletRequest request = new MockHttpServletRequest( );
498 request.setParameter( "action", "UNKNOWN" );
499 bean.doDaemonAction( request );
500
501 }
502 catch( Exception e )
503 {
504 fail( e.getMessage( ) );
505 }
506 }
507
508 public void testGetManageDaemons( ) throws PasswordResetException, AccessDeniedException
509 {
510 MockHttpServletRequest request = new MockHttpServletRequest( );
511 Utils.registerAdminUserWithRigth( request, new AdminUser( ), DaemonsJspBean.RIGHT_DAEMONS_MANAGEMENT );
512 bean.init( request, DaemonsJspBean.RIGHT_DAEMONS_MANAGEMENT );
513 assertNotNull( bean.getManageDaemons( request ) );
514 }
515 }