001 /**
002 * Copyright 2005-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.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/ecl2.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.rice.krad.test;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.junit.Test;
020 import org.junit.runner.RunWith;
021 import org.kuali.rice.core.api.lifecycle.Lifecycle;
022 import org.kuali.rice.core.framework.resourceloader.SpringResourceLoader;
023 import org.kuali.rice.krad.datadictionary.DataDictionary;
024 import org.kuali.rice.krad.util.LegacyUtils;
025 import org.kuali.rice.test.BaselineTestCase;
026 import org.kuali.rice.test.SQLDataLoader;
027 import org.kuali.rice.test.TestUtilities;
028 import org.kuali.rice.test.lifecycles.KEWXmlDataLoaderLifecycle;
029 import org.kuali.rice.test.runners.BootstrapTest;
030 import org.kuali.rice.test.runners.LoadTimeWeavableTestRunner;
031 import org.springframework.context.ConfigurableApplicationContext;
032 import org.springframework.context.support.ClassPathXmlApplicationContext;
033
034 import javax.xml.namespace.QName;
035 import java.lang.annotation.Retention;
036 import java.lang.annotation.Target;
037 import java.util.HashSet;
038 import java.util.List;
039
040 import static java.lang.annotation.ElementType.METHOD;
041 import static java.lang.annotation.ElementType.TYPE;
042 import static java.lang.annotation.RetentionPolicy.RUNTIME;
043
044 /**
045 * Default test base for a full KRAD enabled integration test
046 *
047 * @author Kuali Rice Team (rice.collab@kuali.org)
048 */
049 @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.ROLLBACK_CLEAR_DB)
050 @RunWith(LoadTimeWeavableTestRunner.class)
051 @BootstrapTest(KRADTestCase.BootstrapTest.class)
052 public abstract class KRADTestCase extends BaselineTestCase {
053 private static final String SQL_FILE = "classpath:org/kuali/rice/krad/test/DefaultSuiteTestData.sql";
054 private static final String XML_FILE = "classpath:org/kuali/rice/krad/test/DefaultSuiteTestData.xml";
055 private static final String KRAD_MODULE_NAME = "krad";
056
057 protected DataDictionary dd;
058
059 protected static SpringResourceLoader kradTestHarnessSpringResourceLoader;
060
061 private boolean legacyContext = false;
062
063 public KRADTestCase() {
064 super(KRAD_MODULE_NAME);
065 }
066
067 /**
068 * propagate constructor
069 * @param moduleName - the name of the module
070 */
071 public KRADTestCase(String moduleName) {
072 super(moduleName);
073 }
074
075 protected ConfigurableApplicationContext getKRADTestHarnessContext() {
076 return kradTestHarnessSpringResourceLoader.getContext();
077 }
078
079 @Override
080 public void setUp() throws Exception {
081 super.setUp();
082 setUpLegacyContext();
083
084 }
085
086 @Override
087 public void tearDown() throws Exception {
088 try {
089 tearDownLegacyContext();
090 } finally {
091 super.tearDown(); //To change body of overridden methods use File | Settings | File Templates.
092 }
093 }
094
095 protected void setUpLegacyContext() {
096 if (getTestMethod().getAnnotation(Legacy.class) != null || getClass().getAnnotation(Legacy.class) != null) {
097 LegacyUtils.beginLegacyContext();
098 legacyContext = true;
099 }
100 }
101
102 protected void tearDownLegacyContext() {
103 if (getTestMethod().getAnnotation(Legacy.class) != null || getClass().getAnnotation(Legacy.class) != null) {
104 if (legacyContext) {
105 LegacyUtils.endLegacyContext();
106 legacyContext = false;
107 }
108 }
109 }
110
111 @Override
112 protected void setUpInternal() throws Exception {
113 super.setUpInternal();
114
115 List<Class> classes = TestUtilities.getHierarchyClassesToHandle(getClass(),
116 new Class[]{TestDictionaryConfig.class}, new HashSet<String>());
117
118 // if annotation is present then initialize test data dictionary (setup once per suite)
119 if (!classes.isEmpty()) {
120 ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("TestDataDictionary.xml");
121 dd = (DataDictionary) context.getBean("testDataDictionary");
122
123 // add any additional dictionary files required by the test
124 for (Class c : classes) {
125 if (c.isAnnotationPresent(TestDictionaryConfig.class)) {
126 TestDictionaryConfig testDictionaryConfig = (TestDictionaryConfig) c.getAnnotation(
127 TestDictionaryConfig.class);
128
129 String namespaceCode = testDictionaryConfig.namespaceCode();
130 String dictionaryFileString = testDictionaryConfig.dataDictionaryFiles();
131
132 String[] dictionaryFiles = StringUtils.split(dictionaryFileString, ",");
133 for (String dictionaryFile : dictionaryFiles) {
134 LOG.info("Adding test data dictionary file: " + dictionaryFile);
135
136 dd.addConfigFileLocation(namespaceCode, dictionaryFile);
137 }
138 }
139 }
140
141 dd.parseDataDictionaryConfigurationFiles(false);
142 dd.validateDD(false); // Validation performs some necessary post-processing of the beans - we need to run this each time we add new files
143 dd.performBeanOverrides();
144 }
145 }
146
147 /**
148 * Returns an instance of the bean with the given id that has been configured in the test dictionary
149 *
150 * @param id - id of the bean definition
151 * @return Object instance of the given bean class, or null if not found or dictionary is not loaded
152 */
153 protected Object getTestDictionaryObject(String id) {
154 if (dd != null) {
155 return dd.getDictionaryObject(id);
156 }
157
158 return null;
159 }
160
161 @Override
162 protected List<Lifecycle> getSuiteLifecycles() {
163 List<Lifecycle> suiteLifecycles = super.getSuiteLifecycles();
164 suiteLifecycles.add(new KEWXmlDataLoaderLifecycle(XML_FILE));
165
166 return suiteLifecycles;
167 }
168
169 @Override
170 protected void loadSuiteTestData() throws Exception {
171 super.loadSuiteTestData();
172 new SQLDataLoader(SQL_FILE, ";").runSql();
173 }
174
175 @Override
176 protected Lifecycle getLoadApplicationLifecycle() {
177 // cache the KRAD test harness spring resource loader
178 // this is not great because it doesn't conform to the lifecycle
179 // ...but why are we creating sub-resourceloaders instead of just adding locations to the test harness context?
180 if (kradTestHarnessSpringResourceLoader == null) {
181 kradTestHarnessSpringResourceLoader = new SpringResourceLoader(new QName("KRADTestResourceLoader"),
182 "classpath:KRADTestHarnessSpringBeans.xml", null);
183 kradTestHarnessSpringResourceLoader.setParentSpringResourceLoader(getTestHarnessSpringResourceLoader());
184 }
185 return kradTestHarnessSpringResourceLoader;
186 }
187
188 /**
189 * Annotation which indicates that a Legacy Context should be used for this individual test method or for all tests
190 * in an annotated class.
191 *
192 * @see org.kuali.rice.krad.util.LegacyUtils#doInLegacyContext(java.util.concurrent.Callable)
193 */
194 @Target({TYPE, METHOD})
195 @Retention(RUNTIME)
196 public @interface Legacy {}
197
198 public static final class BootstrapTest extends KRADTestCase {
199 @Test
200 public void bootstrapTest() {};
201 }
202
203 }