001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.opensource.org/licenses/ecl1.php
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.kuali.test;
017:
018: import java.util.HashMap;
019: import java.util.Iterator;
020: import java.util.Map;
021:
022: import org.apache.log4j.Level;
023: import org.apache.log4j.Logger;
024: import org.junit.After;
025: import org.junit.Before;
026: import org.kuali.core.util.ErrorMap;
027: import org.kuali.core.util.GlobalVariables;
028: import org.kuali.rice.testharness.KNSTestCase;
029: import org.kuali.rice.testharness.TransactionalLifecycle;
030:
031: /**
032: * This class is the superclass for all test cases which may require the use of
033: * services, or datasources, or any of the other expensive/time-consuming
034: * infrastructure.
035: * <p>
036: * For test methods or classes with the {@link RelatesTo} annotation, this class
037: * also wraps any test errors or failures with a notice that the listed JIRA
038: * issues are related. This is to help developers see on test reports what work
039: * may be in progress or recently done for this problem. It will help
040: * distinguish tests which have already been investigated from ones which still
041: * need to be. Test errors before the setUp method, e.g., in connecting to the
042: * database to start a test transaction or to Workflow for a user session, are
043: * not wrapped with these notices. Tests not extending KualiTestBase also do not
044: * get these notices. For the sake of speed, the current JIRA status of the
045: * related issues are not checked. The original Throwable is the cause of the
046: * wrapper, so it appears next in the stacktrace on the test report.
047: * <p>
048: * If the {@value #SKIP_OPEN_OR_IN_PROGRESS_OR_REOPENED_JIRA_ISSUES} system
049: * property is set, then this class passes (without running its contents) any
050: * test that {@link RelatesTo} a JIRA issue that is currently open or
051: * in-progress or reopened. This is an alternative to
052: * {@link org.kuali.test.suite.OpenOrInProgressOrReopenedSuite} for Anthill to
053: * retain the same format of its test report while not revealing any failures of
054: * such tests. When using this system property, keep in mind that it takes well
055: * over a minute to get the list of open issues from JIRA. The list is cached
056: * statically, so it's insignificant to add a minute or two to the time it takes
057: * for the whole Anthill build. But, developers will probably not want to add
058: * this system property to their own environments, because of this delay and so
059: * that they can still work on those tests.
060: *
061: * @see KNSWithTestSpringContext
062: *
063: *
064: */
065:
066: public abstract class KNSTestBase extends KNSTestCase implements
067: KNSTestConstants {
068:
069: public static final String SKIP_OPEN_OR_IN_PROGRESS_OR_REOPENED_JIRA_ISSUES = "org.kuali.test.KualiTestBase.skipOpenOrInProgressOrReopenedJiraIssues";
070:
071: private static final Map<String, Level> changedLogLevels = new HashMap<String, Level>();
072:
073: private TransactionalLifecycle transactionalLifecycle;
074:
075: /**
076: * Changes the logging-level associated with the given loggerName to the
077: * given level. The original logging-level is saved, and will be
078: * automatically restored at the end of each test.
079: *
080: * @param loggerName
081: * name of the logger whose level to change
082: * @param newLevel
083: * the level to change to
084: */
085: protected void setLogLevel(String loggerName, Level newLevel) {
086: Logger logger = Logger.getLogger(loggerName);
087:
088: if (!changedLogLevels.containsKey(loggerName)) {
089: Level originalLevel = logger.getLevel();
090: changedLogLevels.put(loggerName, originalLevel);
091: }
092:
093: logger.setLevel(newLevel);
094: }
095:
096: /**
097: * Restores the logging-levels changed through calls to setLogLevel to their
098: * original values.
099: */
100: protected void resetLogLevels() {
101: for (Iterator i = changedLogLevels.entrySet().iterator(); i
102: .hasNext();) {
103: Map.Entry e = (Map.Entry) i.next();
104:
105: String loggerName = (String) e.getKey();
106: Level originalLevel = (Level) e.getValue();
107:
108: Logger.getLogger(loggerName).setLevel(originalLevel);
109: }
110: changedLogLevels.clear();
111: }
112:
113: @Before
114: public void setUp() throws Exception {
115: super .setUp();
116: final boolean needsSpring = getClass().isAnnotationPresent(
117: KNSWithTestSpringContext.class);
118: GlobalVariables.setErrorMap(new ErrorMap());
119: if (needsSpring) {
120: transactionalLifecycle = new TransactionalLifecycle();
121: transactionalLifecycle.start();
122: }
123: }
124:
125: @After
126: public void tearDown() throws Exception {
127: final boolean needsSpring = getClass().isAnnotationPresent(
128: KNSWithTestSpringContext.class);
129: resetLogLevels();
130: if (needsSpring) {
131: transactionalLifecycle.stop();
132: }
133: GlobalVariables.setErrorMap(new ErrorMap());
134: super.tearDown();
135: }
136: }
|