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