1 package org.apachi.onami.lifecycle.warmup;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertTrue;
25
26 import java.util.HashSet;
27 import java.util.Set;
28 import java.util.concurrent.CountDownLatch;
29 import java.util.concurrent.TimeUnit;
30 import java.util.concurrent.TimeoutException;
31 import java.util.concurrent.atomic.AtomicInteger;
32
33 import org.apache.onami.lifecycle.core.LifeCycleStageModule;
34 import org.apache.onami.lifecycle.core.StageHandler;
35 import org.apache.onami.lifecycle.core.Stager;
36 import org.apache.onami.lifecycle.warmup.WarmUp;
37 import org.apache.onami.lifecycle.warmup.WarmUpModule;
38 import org.apache.onami.lifecycle.warmup.WarmUper;
39 import org.junit.Test;
40
41 import com.google.inject.AbstractModule;
42 import com.google.inject.Guice;
43 import com.google.inject.Injector;
44 import com.google.inject.Module;
45
46 public class TestWarmUpManager
47 {
48
49 @SuppressWarnings( "ThrowableResultOfMethodCallIgnored" )
50 @Test
51 public void testErrors()
52 throws Exception
53 {
54 AbstractModule module = new AbstractModule()
55 {
56 @Override
57 protected void configure()
58 {
59 bind( WarmUpWithException.class ).asEagerSingleton();
60 }
61 };
62 Injector injector = Guice.createInjector( new WarmUpModule(), module );
63
64 final AtomicInteger errorCount = new AtomicInteger( 0 );
65 StageHandler stageHandler = new StageHandler()
66 {
67 @Override
68 public <I> void onSuccess( I injectee )
69 {
70 }
71
72 @Override
73 public <I, E extends Throwable> void onError( I injectee, E error )
74 {
75 errorCount.incrementAndGet();
76 }
77 };
78 injector.getInstance( LifeCycleStageModule.key( WarmUp.class ) ).stage( stageHandler );
79 assertEquals( 1, errorCount.get() );
80 }
81
82 @Test
83 public void testDag1()
84 throws Exception
85 {
86 Module module = new AbstractModule()
87 {
88 @Override
89 protected void configure()
90 {
91 bind( CountDownLatch.class ).toInstance( new CountDownLatch( 3 ) );
92 }
93 };
94 Injector injector = Guice.createInjector( new WarmUpModule(), module );
95 injector.getInstance( Dag1.A.class );
96 injector.getInstance( LifeCycleStageModule.key( WarmUp.class ) ).stage();
97 Recorder recorder = injector.getInstance( Recorder.class );
98
99 System.out.println( recorder.getRecordings() );
100 System.out.println( recorder.getConcurrents() );
101
102 assertSingleExecution( recorder );
103 assertNotConcurrent( recorder, "A", "B" );
104 assertNotConcurrent( recorder, "A", "C" );
105
106 assertEquals( 0, recorder.getInterruptions().size() );
107 assertOrdering( recorder, "A", "B" );
108 assertOrdering( recorder, "A", "C" );
109 }
110
111 @Test
112 public void testDag2()
113 throws Exception
114 {
115 Injector injector = Guice.createInjector( new WarmUpModule() );
116 injector.getInstance( Dag2.A1.class );
117 injector.getInstance( Dag2.A2.class );
118 injector.getInstance( Dag2.A3.class );
119 injector.getInstance( LifeCycleStageModule.key( WarmUp.class ) ).stage();
120 Recorder recorder = injector.getInstance( Recorder.class );
121
122 System.out.println( recorder.getRecordings() );
123 System.out.println( recorder.getConcurrents() );
124
125 assertSingleExecution( recorder );
126
127 assertNotConcurrent( recorder, "A1", "B1" );
128 assertNotConcurrent( recorder, "A1", "B2" );
129 assertNotConcurrent( recorder, "B1", "C1" );
130 assertNotConcurrent( recorder, "B2", "C1" );
131 assertNotConcurrent( recorder, "A2", "B2" );
132 assertNotConcurrent( recorder, "A2", "B3" );
133 assertNotConcurrent( recorder, "B2", "C2" );
134 assertNotConcurrent( recorder, "B3", "C2" );
135 assertNotConcurrent( recorder, "A3", "B3" );
136 assertNotConcurrent( recorder, "A3", "B4" );
137 assertNotConcurrent( recorder, "B3", "C3" );
138 assertNotConcurrent( recorder, "B4", "C3" );
139
140 assertEquals( 0, recorder.getInterruptions().size() );
141 assertOrdering( recorder, "A1", "B1" );
142 assertOrdering( recorder, "B1", "C1" );
143 assertOrdering( recorder, "A1", "B2" );
144 assertOrdering( recorder, "B2", "C1" );
145 assertOrdering( recorder, "A2", "B2" );
146 assertOrdering( recorder, "B2", "C2" );
147 assertOrdering( recorder, "A2", "B3" );
148 assertOrdering( recorder, "B3", "C2" );
149 assertOrdering( recorder, "A3", "B3" );
150 assertOrdering( recorder, "B3", "C3" );
151 assertOrdering( recorder, "A3", "B4" );
152 assertOrdering( recorder, "B4", "C3" );
153 }
154
155 @Test
156 public void testDag3()
157 throws Exception
158 {
159 Injector injector = Guice.createInjector( new WarmUpModule() );
160 injector.getInstance( Dag3.A.class );
161 injector.getInstance( LifeCycleStageModule.key( WarmUp.class ) ).stage();
162 Recorder recorder = injector.getInstance( Recorder.class );
163
164 System.out.println( recorder.getRecordings() );
165 System.out.println( recorder.getConcurrents() );
166
167 assertSingleExecution( recorder );
168
169 assertNotConcurrent( recorder, "C", "D" );
170 assertNotConcurrent( recorder, "B", "D" );
171 assertNotConcurrent( recorder, "A", "B" );
172 assertNotConcurrent( recorder, "A", "C" );
173
174 assertEquals( 0, recorder.getInterruptions().size() );
175 assertOrdering( recorder, "A", "C" );
176 assertOrdering( recorder, "C", "D" );
177 assertOrdering( recorder, "A", "D" );
178 assertOrdering( recorder, "B", "D" );
179 }
180
181 @Test
182 public void testDag4()
183 throws Exception
184 {
185 Module module = new AbstractModule()
186 {
187 @Override
188 protected void configure()
189 {
190 RecorderSleepSettings recorderSleepSettings = new RecorderSleepSettings();
191 recorderSleepSettings.setBaseSleepFor( "E", 1, TimeUnit.MILLISECONDS );
192 recorderSleepSettings.setRandomize( false );
193 bind( RecorderSleepSettings.class ).toInstance( recorderSleepSettings );
194 }
195 };
196 Injector injector = Guice.createInjector( new WarmUpModule(), module );
197 injector.getInstance( Dag4.A.class );
198 injector.getInstance( LifeCycleStageModule.key( WarmUp.class ) ).stage();
199 Recorder recorder = injector.getInstance( Recorder.class );
200
201 System.out.println( recorder.getRecordings() );
202 System.out.println( recorder.getConcurrents() );
203
204 assertSingleExecution( recorder );
205 assertEquals( 0, recorder.getInterruptions().size() );
206 assertOrdering( recorder, "D", "E" );
207 assertOrdering( recorder, "C", "E" );
208 assertOrdering( recorder, "B", "D" );
209 assertOrdering( recorder, "A", "B" );
210 }
211
212 @Test
213 public void testFlat()
214 throws Exception
215 {
216 Injector injector = Guice.createInjector( new WarmUpModule() );
217 Recorder recorder = injector.getInstance( Recorder.class );
218 injector.getInstance( Flat.A.class ).recorder = recorder;
219 injector.getInstance( Flat.B.class ).recorder = recorder;
220 injector.getInstance( LifeCycleStageModule.key( WarmUp.class ) ).stage();
221
222 System.out.println( recorder.getRecordings() );
223 System.out.println( recorder.getConcurrents() );
224
225 assertSingleExecution( recorder );
226 assertEquals( 0, recorder.getInterruptions().size() );
227 assertTrue( recorder.getRecordings().indexOf( "A" ) >= 0 );
228 assertTrue( recorder.getRecordings().indexOf( "B" ) >= 0 );
229 }
230
231 @Test
232 public void testStuck()
233 throws Exception
234 {
235 final CountDownLatch latch = new CountDownLatch( 3 );
236 Module module = new AbstractModule()
237 {
238 @Override
239 protected void configure()
240 {
241 RecorderSleepSettings recorderSleepSettings = new RecorderSleepSettings();
242 recorderSleepSettings.setBaseSleepFor( "C", 1, TimeUnit.DAYS );
243 bind( RecorderSleepSettings.class ).toInstance( recorderSleepSettings );
244 bind( CountDownLatch.class ).toInstance( latch );
245 }
246 };
247 Injector injector = Guice.createInjector( new TestWarmUpModule(), module );
248 injector.getInstance( Dag1.A.class );
249 Stager<WarmUp> stager = injector.getInstance( LifeCycleStageModule.key( WarmUp.class ) );
250
251 boolean succeeded;
252 try
253 {
254 stager.stage();
255 succeeded = true;
256 }
257 catch ( RuntimeException e )
258 {
259 succeeded = false;
260 assertTrue( e.getCause() instanceof TimeoutException );
261 }
262
263
264 latch.await( 2, TimeUnit.SECONDS );
265
266 Recorder recorder = injector.getInstance( Recorder.class );
267
268 System.out.println( recorder.getRecordings() );
269 System.out.println( recorder.getConcurrents() );
270
271 assertSingleExecution( recorder );
272 assertFalse( succeeded );
273 assertTrue( recorder.getRecordings().toString(), recorder.getRecordings().contains( "C" ) );
274
275
276 assertTrue( recorder.getInterruptions().toString(),
277 recorder.getInterruptions().contains( "C" ) );
278 }
279
280 private void assertSingleExecution( Recorder recorder )
281 {
282 Set<String> duplicateCheck = new HashSet<String>();
283 for ( String s : recorder.getRecordings() )
284 {
285 assertFalse( s + " ran more than once: " + recorder.getRecordings(), duplicateCheck.contains( s ) );
286 duplicateCheck.add( s );
287 }
288 }
289
290 private void assertOrdering( Recorder recorder, String base, String dependency )
291 {
292 int baseIndex = recorder.getRecordings().indexOf( base );
293 int dependencyIndex = recorder.getRecordings().indexOf( dependency );
294
295 assertTrue( baseIndex >= 0 );
296 assertTrue( dependencyIndex >= 0 );
297 assertTrue( "baseIndex: " + baseIndex + " - dependencyIndex: " + dependencyIndex,
298 baseIndex > dependencyIndex );
299 }
300
301 private void assertNotConcurrent( Recorder recorder, String task1, String task2 )
302 {
303 for ( Set<String> s : recorder.getConcurrents() )
304 {
305 assertTrue( String.format( "Incorrect concurrency for %s and %s: %s", task1, task2, s ),
306 !s.contains( task1 ) || !s.contains( task2 ) );
307 }
308 }
309
310 private static class TestWarmUpModule extends LifeCycleStageModule
311 {
312
313 @Override
314 protected void configureBindings()
315 {
316 WarmUper<WarmUp> stager = new WarmUper<WarmUp>( WarmUp.class, TimeUnit.SECONDS.toMillis( 1 ) );
317 bindStager( stager ).mappingWith( stager );
318 }
319
320 }
321
322 }