001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: *
005: * Licensed under the Educational Community License, Version 1.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.opensource.org/licenses/ecl1.php
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.kuali.workflow.test;
018:
019: import java.io.File;
020: import java.io.FileInputStream;
021: import java.io.FileOutputStream;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.util.ArrayList;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028: import java.util.Properties;
029:
030: import org.kuali.rice.config.Config;
031: import org.kuali.rice.config.ConfigurationException;
032: import org.kuali.rice.config.SimpleConfig;
033: import org.kuali.rice.core.Core;
034: import org.kuali.rice.lifecycle.Lifecycle;
035: import org.kuali.rice.resourceloader.GlobalResourceLoader;
036: import org.kuali.rice.resourceloader.ResourceLoader;
037: import org.kuali.rice.test.TestHarnessWebApp;
038: import org.mortbay.jetty.webapp.WebAppClassLoader;
039: import org.springframework.transaction.support.TransactionTemplate;
040:
041: import edu.iu.uis.eden.EdenConstants;
042: import edu.iu.uis.eden.KEWServiceLocator;
043: import edu.iu.uis.eden.batch.FileXmlDocCollection;
044: import edu.iu.uis.eden.batch.XmlDoc;
045: import edu.iu.uis.eden.batch.XmlDocCollection;
046: import edu.iu.uis.eden.exception.WorkflowRuntimeException;
047: import edu.iu.uis.eden.test.OldClearDatabaseLifecycle;
048: import edu.iu.uis.eden.test.OldRiceTestCase;
049: import edu.iu.uis.eden.test.SQLDataLoader;
050: import edu.iu.uis.eden.test.TestUtilities;
051:
052: /**
053: * Useful superclass for all Workflow test cases. Handles setup of test
054: * utilities and a test environment. Configures the Spring test environment
055: * providing a template method for custom context files in test mode. Also
056: * provides a template method for running custom transactional setUp. Tear down
057: * handles automatic tear down of objects created inside the test environment.
058: *
059: * TODO: Extending OldRiceTestCase for now until I have time to go back and update it
060: * for the new RiceTestCase implementation.
061: */
062: public abstract class WorkflowTestCase extends OldRiceTestCase {
063:
064: private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
065: .getLogger(WorkflowTestCase.class);
066:
067: private static final String TEST_CONFIG_LOCATION_PROPERTY = "test.config.location";
068:
069: private List<Lifecycle> lifeCycles;
070:
071: @Override
072: protected Config loadConfig(Config rootConfig) {
073: Config config = super .loadConfig(rootConfig);
074: config.getProperties().put("test.web.app.root", "en");
075: config.getProperties().put("test.context.name", "/en-test");
076: return config;
077: }
078:
079: @Override
080: public void setUp() throws Exception {
081: Properties buildProperties = loadBuildProperties();
082: if (buildProperties.containsKey(TEST_CONFIG_LOCATION_PROPERTY)) {
083: System.setProperty(TEST_CONFIG_LOCATION_PROPERTY,
084: (String) buildProperties
085: .get(TEST_CONFIG_LOCATION_PROPERTY));
086: } else {
087: throw new ConfigurationException(
088: "Could not locate the test.config.location property in your build.properties file.");
089: }
090: System.setProperty(EdenConstants.BOOTSTRAP_SPRING_FILE,
091: "org/kuali/workflow/resources/TestKewSpringBeans.xml");
092: oneTimeInitialization();
093: // from superclass
094: beforeRun();
095: final long startTime = System.currentTimeMillis();
096:
097: final long initTime = System.currentTimeMillis();
098: report("Time to initialize Core: " + (initTime - startTime));
099:
100: new OldClearDatabaseLifecycle(null, getQuartzTables()).start();
101: report("Time to start all Lifecycles: "
102: + (System.currentTimeMillis() - initTime));
103: loadTestDataInternal();
104: }
105:
106: private List<String> getQuartzTables() {
107: List<String> quartzTables = new ArrayList<String>();
108: quartzTables.add("KR_QRTZ_JOB_DETAILS");
109: quartzTables.add("KR_QRTZ_JOB_LISTENERS");
110: quartzTables.add("KR_QRTZ_TRIGGERS");
111: quartzTables.add("KR_QRTZ_SIMPLE_TRIGGERS");
112: quartzTables.add("KR_QRTZ_CRON_TRIGGERS");
113: quartzTables.add("KR_QRTZ_BLOB_TRIGGERS");
114: quartzTables.add("KR_QRTZ_TRIGGER_LISTENERS");
115: quartzTables.add("KR_QRTZ_CALENDARS");
116: quartzTables.add("KR_QRTZ_PAUSED_TRIGGER_GRPS");
117: quartzTables.add("KR_QRTZ_FIRED_TRIGGERS");
118: quartzTables.add("KR_QRTZ_SCHEDULER_STATE");
119: quartzTables.add("KR_QRTZ_LOCKS");
120: return quartzTables;
121: }
122:
123: @Override
124: public void tearDown() throws Exception {
125: KEWServiceLocator.getCacheAdministrator().flushAll();
126: // KEWServiceLocator.getTransactionManager().rollback();
127: }
128:
129: private static boolean initialized = false;
130:
131: protected void oneTimeInitialization() throws Exception {
132: if (!initialized) {
133: final Config riceTestConfig = new SimpleConfig();
134: riceTestConfig.getProperties().putAll(
135: System.getProperties());
136: loadBootstrapConfig(riceTestConfig);
137: Config testConfig = loadConfig(riceTestConfig);
138: testConfig.parseConfig();
139: riceTestConfig.getProperties().putAll(
140: testConfig.getProperties());
141: Core.init(riceTestConfig);
142: verifyTestConfiguration();
143:
144: new TestHarnessWebApp().start();
145:
146: Map<ClassLoader, Config> configs = Core.getCONFIGS();
147: for (Map.Entry<ClassLoader, Config> configEntry : configs
148: .entrySet()) {
149: if (configEntry.getKey() instanceof WebAppClassLoader) {
150: ResourceLoader rl = GlobalResourceLoader
151: .getResourceLoader(configEntry.getKey());
152: if (rl == null) {
153: fail("didn't find resource loader for workflow test harness web app");
154: }
155: GlobalResourceLoader.addResourceLoader(rl);
156: configs.put(Thread.currentThread()
157: .getContextClassLoader(), configEntry
158: .getValue());
159: }
160: }
161:
162: new OldClearDatabaseLifecycle(getQuartzTables()).start();
163: new SQLDataLoader("OneTimeDefaultTestData.sql",
164: WorkflowTestCase.class).runSql();
165: }
166: initialized = true;
167: }
168:
169: @Override
170: public List<Lifecycle> getLifecycles() {
171: List<Lifecycle> lifeCycles = new ArrayList<Lifecycle>();
172: lifeCycles.add(new OldClearDatabaseLifecycle());
173: return lifeCycles;
174: }
175:
176: protected void setUpTransaction() throws Exception {
177: // TestUtilities.waitForCacheNotificationsToClearFromQueue();
178: }
179:
180: protected TransactionTemplate getTransactionTemplate() {
181: return TestUtilities.getTransactionTemplate();
182: }
183:
184: /**
185: * By default this loads the "default" data set from the DefaultTestData.sql
186: * and DefaultTestData.xml files. Subclasses can override this to change
187: * this behaviour
188: */
189: @Override
190: protected void loadDefaultTestData() throws Exception {
191: // Map<ClassLoader, Config> configs = Core.getCONFIGS();
192: // for (Map.Entry<ClassLoader, Config> configEntry : configs.entrySet())
193: // {
194: // if (configEntry.getKey() instanceof WebAppClassLoader) {
195: // ResourceLoader rl =
196: // GlobalResourceLoader.getResourceLoader(configEntry.getKey());
197: // if (rl == null) {
198: // fail("didn't find resource loader for workflow test harness web
199: // app");
200: // }
201: // GlobalResourceLoader.addResourceLoader(rl);
202: // configs.put(Thread.currentThread().getContextClassLoader(),
203: // configEntry.getValue());
204: // }
205: // }
206:
207: super .loadDefaultTestData();
208: // at this point this is constants. loading these through xml import is
209: // problematic because of cache notification
210: // issues in certain low level constants.
211: new SQLDataLoader("DefaultTestData.sql", WorkflowTestCase.class)
212: .runSql();
213: this .loadXmlFile(WorkflowTestCase.class, "DefaultTestData.xml");
214: }
215:
216: protected void loadXmlFile(String fileName) {
217: if (fileName.indexOf('/') < 0) {
218: this .loadXmlFile(getClass(), fileName);
219: } else {
220: loadXmlStream(getClass().getClassLoader()
221: .getResourceAsStream(fileName));
222: }
223: }
224:
225: protected void loadXmlFile(Class clazz, String fileName) {
226: InputStream xmlFile = TestUtilities.loadResource(clazz,
227: fileName);
228: if (xmlFile == null) {
229: throw new WorkflowRuntimeException("Didn't find file "
230: + fileName);
231: }
232: loadXmlStream(xmlFile);
233: }
234:
235: protected void loadXmlFileFromFileSystem(String fileName)
236: throws IOException {
237: loadXmlStream(new FileInputStream(fileName));
238: }
239:
240: protected void loadXmlStream(InputStream xmlStream) {
241: try {
242: List<XmlDocCollection> xmlFiles = new ArrayList<XmlDocCollection>();
243: XmlDocCollection docCollection = getFileXmlDocCollection(
244: xmlStream, "WorkflowUnitTestTemp");
245: xmlFiles.add(docCollection);
246: KEWServiceLocator.getXmlIngesterService().ingest(xmlFiles);
247: for (Iterator iterator = docCollection.getXmlDocs()
248: .iterator(); iterator.hasNext();) {
249: XmlDoc doc = (XmlDoc) iterator.next();
250: if (!doc.isProcessed()) {
251: fail("Failed to ingest xml doc: " + doc.getName());
252: }
253: }
254: } catch (Exception e) {
255: throw new RuntimeException(
256: "Caught exception parsing xml file", e);
257: }
258:
259: }
260:
261: protected FileXmlDocCollection getFileXmlDocCollection(
262: InputStream xmlFile, String tempFileName)
263: throws IOException {
264: if (xmlFile == null) {
265: throw new RuntimeException("Didn't find the xml file "
266: + tempFileName);
267: }
268: File temp = File.createTempFile(tempFileName, ".xml");
269: FileOutputStream fos = new FileOutputStream(temp);
270: int data = -1;
271: while ((data = xmlFile.read()) != -1) {
272: fos.write(data);
273: }
274: fos.close();
275: return new FileXmlDocCollection(temp);
276: }
277: }
|