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