1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.rice.test;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.log4j.Logger;
20  import org.apache.log4j.PropertyConfigurator;
21  import org.junit.After;
22  import org.junit.Before;
23  import org.kuali.rice.core.api.config.property.Config;
24  import org.kuali.rice.core.api.config.property.ConfigContext;
25  import org.kuali.rice.core.api.lifecycle.BaseLifecycle;
26  import org.kuali.rice.core.api.lifecycle.Lifecycle;
27  import org.kuali.rice.core.framework.resourceloader.SpringResourceLoader;
28  import org.kuali.rice.core.impl.config.property.JAXBConfigImpl;
29  import org.kuali.rice.test.data.PerSuiteUnitTestData;
30  import org.kuali.rice.test.lifecycles.PerSuiteDataLoaderLifecycle;
31  import org.springframework.beans.factory.BeanCreationNotAllowedException;
32  import org.springframework.core.io.FileSystemResourceLoader;
33  import org.springframework.core.io.Resource;
34  import org.springframework.core.io.ResourceLoader;
35  
36  import javax.xml.namespace.QName;
37  import java.io.File;
38  import java.io.IOException;
39  import java.util.ArrayList;
40  import java.util.Collections;
41  import java.util.HashSet;
42  import java.util.LinkedList;
43  import java.util.List;
44  import java.util.Properties;
45  import java.util.Set;
46  
47  import static org.junit.Assert.assertNotNull;
48  import static org.junit.Assert.fail;
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  public abstract class RiceTestCase extends BaseRiceTestCase {
61  
62      protected static final Logger LOG = Logger.getLogger(RiceTestCase.class);
63  
64      private static final String ALT_LOG4J_CONFIG_LOCATION_PROP = "alt.log4j.config.location";
65      private static final String DEFAULT_LOG4J_CONFIG = "classpath:rice-testharness-default-log4j.properties";
66      protected static final String DEFAULT_TEST_HARNESS_SPRING_BEANS = "classpath:TestHarnessSpringBeans.xml";
67      protected static boolean SUITE_LIFE_CYCLES_RAN = false;
68      protected static boolean SUITE_LIFE_CYCLES_FAILED = false;
69      protected static String failedSuiteTestName;
70  
71      protected List<Lifecycle> perTestLifeCycles = new LinkedList<Lifecycle>();
72  
73      protected List<Lifecycle> suiteLifeCycles = new LinkedList<Lifecycle>();
74  
75      private static Set<String> perSuiteDataLoaderLifecycleNamesRun = new HashSet<String>();
76  
77      private List<String> reports = new ArrayList<String>();
78  
79      private SpringResourceLoader testHarnessSpringResourceLoader;
80      private boolean clearTables = true;
81  
82      private long testStart;
83      private long testEnd;
84  
85      @Override
86  	@Before
87      public void setUp() throws Exception {
88          testStart = System.currentTimeMillis();
89          try {
90              configureLogging();
91              logBeforeRun();
92  
93              final long initTime = System.currentTimeMillis();
94  
95              setUpInternal();
96  
97              report("Time to start all Lifecycles: " + (System.currentTimeMillis() - initTime));
98          } catch (Throwable e) {
99              e.printStackTrace();
100             tearDown();
101             throw new RuntimeException(e);
102         }
103     }
104 
105     
106 
107 
108 
109 
110 
111 
112     protected void setUpInternal() throws Exception {
113         assertNotNull(getModuleName());
114         setModuleName(getModuleName());
115         setBaseDirSystemProperty(getModuleName());
116 
117         this.perTestLifeCycles = getPerTestLifecycles();
118         this.suiteLifeCycles = getSuiteLifecycles();
119 
120         if (SUITE_LIFE_CYCLES_FAILED) {
121         	fail("Suite Lifecycles startup failed on test " + failedSuiteTestName + "!!!  Please see logs for details.");
122         }
123         if (!SUITE_LIFE_CYCLES_RAN) {
124 	        try {
125     	        startLifecycles(this.suiteLifeCycles);
126         	    SUITE_LIFE_CYCLES_RAN = true;
127         	} catch (Throwable e) {
128         		e.printStackTrace();
129                 SUITE_LIFE_CYCLES_RAN = false;
130                 SUITE_LIFE_CYCLES_FAILED = true;
131                 failedSuiteTestName = getFullTestName();
132                 tearDown();
133                 stopLifecycles(this.suiteLifeCycles);
134                 throw new RuntimeException(e);
135             }
136         }
137 
138         startSuiteDataLoaderLifecycles();
139 
140         startLifecycles(this.perTestLifeCycles);
141 
142     }
143 
144     
145 
146 
147 
148 
149 
150 
151     protected void startSuiteDataLoaderLifecycles() throws Exception {
152         List<Class> classes = TestUtilities.getHierarchyClassesToHandle(getClass(), new Class[] { PerSuiteUnitTestData.class }, perSuiteDataLoaderLifecycleNamesRun);
153         for (Class c: classes) {
154             new PerSuiteDataLoaderLifecycle(c).start();
155             perSuiteDataLoaderLifecycleNamesRun.add(c.getName());
156         }
157     }
158 
159     
160 
161 
162 
163     protected void setBaseDirSystemProperty(String moduleBaseDir) {
164         if (System.getProperty("basedir") == null) {
165         	final String userDir = System.getProperty("user.dir");
166         	
167             System.setProperty("basedir", userDir + ((userDir.endsWith(File.separator + "it" + File.separator + moduleBaseDir)) ? "" : File.separator + "it" + File.separator + moduleBaseDir));
168         }
169     }
170 
171     
172 
173 
174 
175 
176 
177 
178 
179 
180     protected String getUserDir() {
181         return System.getProperty("user.dir");
182     }
183 
184     protected void setModuleName(String moduleName) {
185         if (System.getProperty("module.name") == null) {
186             System.setProperty("module.name", moduleName);
187         }
188     }
189 
190     @Override
191 	@After
192     public void tearDown() throws Exception {
193     	
194     	ThreadMonitor.tearDown(60000);
195         try {
196             stopLifecycles(this.perTestLifeCycles);
197         
198         } catch (BeanCreationNotAllowedException bcnae) {
199             LOG.warn("BeanCreationNotAllowedException during stopLifecycles during tearDown " + bcnae.getMessage());
200         }
201         testEnd = System.currentTimeMillis();
202         report("Total time to run test: " + (testEnd - testStart));
203         logAfterRun();
204     }
205 
206     protected void logBeforeRun() {
207         LOG.info("##############################################################");
208         LOG.info("# Starting test " + getFullTestName() + "...");
209         LOG.info("# " + dumpMemory());
210         LOG.info("##############################################################");
211     }
212 
213     protected void logAfterRun() {
214         LOG.info("##############################################################");
215         LOG.info("# ...finished test " + getFullTestName());
216         LOG.info("# " + dumpMemory());
217         for (final String report : this.reports) {
218             LOG.info("# " + report);
219         }
220         LOG.info("##############################################################\n\n\n");
221     }
222     
223     protected String getFullTestName() {
224     	return getClass().getSimpleName() + "." + getName();
225     }
226 
227     
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 
239 
240 
241 	protected void configureLogging() throws IOException {
242         ResourceLoader resourceLoader = new FileSystemResourceLoader();
243         String altLog4jConfigLocation = System.getProperty(ALT_LOG4J_CONFIG_LOCATION_PROP);
244         Resource log4jConfigResource = null;
245         if (!StringUtils.isEmpty(altLog4jConfigLocation)) { 
246             log4jConfigResource = resourceLoader.getResource(altLog4jConfigLocation);
247         }
248         if (log4jConfigResource == null || !log4jConfigResource.exists()) {
249             System.out.println("Alternate Log4j config resource does not exist! " + altLog4jConfigLocation);
250             System.out.println("Using default log4j configuration: " + DEFAULT_LOG4J_CONFIG);
251             log4jConfigResource = resourceLoader.getResource(DEFAULT_LOG4J_CONFIG);
252         } else {
253             System.out.println("Using alternate log4j configuration at: " + altLog4jConfigLocation);
254         }
255         Properties p = new Properties();
256         p.load(log4jConfigResource.getInputStream());
257         PropertyConfigurator.configure(p);
258     }
259 
260 	
261 
262 
263     protected void startLifecycles(List<Lifecycle> lifecycles) throws Exception {
264         for (Lifecycle lifecycle : lifecycles) {
265                 lifecycle.start();
266         }
267     }
268 
269     
270 
271 
272 
273     protected void stopLifecycles(List<Lifecycle> lifecycles) throws Exception {
274         int lifecyclesSize = lifecycles.size() - 1;
275         for (int i = lifecyclesSize; i >= 0; i--) {
276             try {
277             	if (lifecycles.get(i) == null) {
278             		LOG.warn("Attempted to stop a null lifecycle");
279             	} else {
280             		if (lifecycles.get(i).isStarted()) {
281                         LOG.warn("Attempting to stop a lifecycle " + lifecycles.get(i).getClass());
282             			lifecycles.get(i).stop();
283             		}
284             	}
285             } catch (Exception e) {
286                 LOG.error("Failed to shutdown one of the lifecycles!", e);
287             }
288         }
289     }
290 
291     
292 
293 
294     protected List<Lifecycle> getSuiteLifecycles() {
295         List<Lifecycle> lifecycles = new LinkedList<Lifecycle>();
296         
297         
298 
299 
300         lifecycles.add(new BaseLifecycle() {
301             @Override
302 			public void start() throws Exception {
303                 Config config = getTestHarnessConfig();
304                 ConfigContext.init(config);
305                 super.start();
306             }
307         });
308         
309         
310 
311 
312         lifecycles.add(getTestHarnessSpringResourceLoader());
313         
314         
315 
316 
317 
318         lifecycles.add(new BaseLifecycle() {
319             @Override
320 			public void start() throws Exception {
321                 TestHarnessServiceLocator.setContext(getTestHarnessSpringResourceLoader().getContext());
322                 super.start();
323             }
324         });
325         
326         
327 
328 
329         if (clearTables) {
330         	lifecycles.add(new ClearDatabaseLifecycle());
331         }
332         
333         
334 
335 
336         lifecycles.add(new BaseLifecycle() {
337         	@Override
338 			public void start() throws Exception {
339         		loadSuiteTestData();
340         		super.start();
341         	}
342         });
343         
344         Lifecycle loadApplicationLifecycle = getLoadApplicationLifecycle();
345         if (loadApplicationLifecycle != null) {
346         	lifecycles.add(loadApplicationLifecycle);
347         }
348         return lifecycles;
349     }
350     
351     
352 
353 
354 
355 
356 
357     protected Lifecycle getLoadApplicationLifecycle() {
358     	
359     	return null;
360     }
361 
362     
363 
364 
365     protected List<Lifecycle> getPerTestLifecycles() {
366     	List<Lifecycle> lifecycles = new LinkedList<Lifecycle>();
367         lifecycles.add(getPerTestDataLoaderLifecycle());
368         lifecycles.add(new BaseLifecycle() {
369             @Override
370 			public void start() throws Exception {
371                 loadPerTestData();
372                 super.start();
373             }
374         });
375         return lifecycles;
376     }
377     
378     
379 
380 
381     protected void loadSuiteTestData() throws Exception {
382     	
383     }
384     
385     
386 
387 
388     protected void loadPerTestData() throws Exception {
389     	
390     }
391 
392     protected void report(final String report) {
393         this.reports.add(report);
394     }
395 
396     protected String dumpMemory() {
397         final long total = Runtime.getRuntime().totalMemory();
398         final long free = Runtime.getRuntime().freeMemory();
399         final long max = Runtime.getRuntime().maxMemory();
400         return "[Memory] max: " + max + ", total: " + total + ", free: " + free;
401     }
402 
403     public SpringResourceLoader getTestHarnessSpringResourceLoader() {
404         if (testHarnessSpringResourceLoader == null) {
405             testHarnessSpringResourceLoader = new SpringResourceLoader(new QName("TestHarnessSpringContext"), getTestHarnessSpringBeansLocation(), null);
406         }
407         return testHarnessSpringResourceLoader;
408     }
409 
410     
411 
412 
413 
414 
415     protected List<String> getTestHarnessSpringBeansLocation() {
416         return Collections.singletonList( DEFAULT_TEST_HARNESS_SPRING_BEANS );
417     }
418 
419     protected Config getTestHarnessConfig() throws Exception {
420         Config config = new JAXBConfigImpl(getConfigLocations(), System.getProperties());
421         config.parseConfig();
422         return config;
423     }
424 
425     
426 
427 
428 
429 
430     protected List<String> getConfigLocations() {
431         List<String> configLocations = new ArrayList<String>();
432         configLocations.add(getRiceMasterDefaultConfigFile());
433         configLocations.add(getModuleTestConfigLocation());
434         return configLocations;
435     }
436     
437     protected String getModuleTestConfigLocation() {
438         return "classpath:META-INF/" + getModuleName().toLowerCase() + "-test-config.xml";
439     }
440 
441     protected String getRiceMasterDefaultConfigFile() {
442         return "classpath:META-INF/test-config-defaults.xml";
443     }
444 
445     
446 
447 
448 
449 
450     protected abstract String getModuleName();
451 
452     protected void setClearTables(boolean clearTables) {
453     	this.clearTables = clearTables;
454     }
455     
456 }