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 }