View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.test;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.junit.Test;
20  import org.junit.runner.RunWith;
21  import org.kuali.rice.core.api.lifecycle.Lifecycle;
22  import org.kuali.rice.core.framework.resourceloader.SpringResourceLoader;
23  import org.kuali.rice.krad.datadictionary.DataDictionary;
24  import org.kuali.rice.krad.util.LegacyUtils;
25  import org.kuali.rice.test.BaselineTestCase;
26  import org.kuali.rice.test.SQLDataLoader;
27  import org.kuali.rice.test.TestUtilities;
28  import org.kuali.rice.test.lifecycles.KEWXmlDataLoaderLifecycle;
29  import org.kuali.rice.test.runners.BootstrapTest;
30  import org.kuali.rice.test.runners.LoadTimeWeavableTestRunner;
31  import org.springframework.context.ConfigurableApplicationContext;
32  import org.springframework.context.support.ClassPathXmlApplicationContext;
33  
34  import javax.xml.namespace.QName;
35  import java.lang.annotation.Retention;
36  import java.lang.annotation.Target;
37  import java.util.HashSet;
38  import java.util.List;
39  
40  import static java.lang.annotation.ElementType.METHOD;
41  import static java.lang.annotation.ElementType.TYPE;
42  import static java.lang.annotation.RetentionPolicy.RUNTIME;
43  
44  /**
45   * Default test base for a full KRAD enabled integration test
46   *
47   * @author Kuali Rice Team (rice.collab@kuali.org)
48   */
49  @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.ROLLBACK_CLEAR_DB)
50  @RunWith(LoadTimeWeavableTestRunner.class)
51  @BootstrapTest(KRADTestCase.BootstrapTest.class)
52  public abstract class KRADTestCase extends BaselineTestCase {
53      private static final String SQL_FILE = "classpath:org/kuali/rice/krad/test/DefaultSuiteTestData.sql";
54      private static final String XML_FILE = "classpath:org/kuali/rice/krad/test/DefaultSuiteTestData.xml";
55      private static final String KRAD_MODULE_NAME = "krad";
56  
57      protected DataDictionary dd;
58  
59      protected static SpringResourceLoader kradTestHarnessSpringResourceLoader;
60  
61      private boolean legacyContext = false;
62  
63      public KRADTestCase() {
64          super(KRAD_MODULE_NAME);
65      }
66  
67      /**
68       * propagate constructor
69       * @param moduleName - the name of the module
70       */
71      public KRADTestCase(String moduleName) {
72          super(moduleName);
73      }
74  
75      protected ConfigurableApplicationContext getKRADTestHarnessContext() {
76          return kradTestHarnessSpringResourceLoader.getContext();
77      }
78  
79      @Override
80      public void setUp() throws Exception {
81          super.setUp();
82          setUpLegacyContext();
83  
84      }
85  
86      @Override
87      public void tearDown() throws Exception {
88          try {
89              tearDownLegacyContext();
90          } finally {
91              super.tearDown();    //To change body of overridden methods use File | Settings | File Templates.
92          }
93      }
94  
95      protected void setUpLegacyContext() {
96          if (getTestMethod().getAnnotation(Legacy.class) != null || getClass().getAnnotation(Legacy.class) != null) {
97              LegacyUtils.beginLegacyContext();
98              legacyContext = true;
99          }
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.getDictionaryBean(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 }