001/** 002 * Copyright 2005-2014 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 */ 016package org.kuali.rice.kew.test; 017 018import org.junit.Test; 019import org.junit.runner.RunWith; 020import org.kuali.rice.core.api.lifecycle.BaseLifecycle; 021import org.kuali.rice.core.api.lifecycle.Lifecycle; 022import org.kuali.rice.core.api.util.ClasspathOrFileResourceLoader; 023import org.kuali.rice.core.framework.resourceloader.SpringResourceLoader; 024import org.kuali.rice.coreservice.impl.CoreServiceImplServiceLocator; 025import org.kuali.rice.kew.api.WorkflowRuntimeException; 026import org.kuali.rice.kew.batch.KEWXmlDataLoader; 027import org.kuali.rice.kew.service.KEWServiceLocator; 028import org.kuali.rice.kim.api.role.Role; 029import org.kuali.rice.kim.api.services.KimApiServiceLocator; 030import org.kuali.rice.kim.impl.services.KimImplServiceLocator; 031import org.kuali.rice.krad.data.platform.MaxValueIncrementerFactory; 032import org.kuali.rice.test.BaselineTestCase; 033import org.kuali.rice.test.ClearDatabaseLifecycle; 034import org.kuali.rice.test.SQLDataLoader; 035import org.kuali.rice.test.TestHarnessServiceLocator; 036import org.kuali.rice.test.lifecycles.KEWXmlDataLoaderLifecycle; 037import org.kuali.rice.test.runners.BootstrapTest; 038import org.kuali.rice.test.runners.LoadTimeWeavableTestRunner; 039import org.springframework.cache.CacheManager; 040import org.springframework.transaction.support.TransactionTemplate; 041 042import javax.xml.namespace.QName; 043import java.io.InputStream; 044import java.util.ArrayList; 045import java.util.List; 046 047/** 048 * Useful superclass for all KEW test cases. Handles setup of test utilities and 049 * a test environment. Configures the Spring test environment providing a 050 * template method for custom context files in test mode. Also provides a 051 * template method for running custom transactional setUp. Tear down handles 052 * automatic tear down of objects created inside the test environment. 053 */ 054@BaselineTestCase.BaselineMode(BaselineTestCase.Mode.ROLLBACK_CLEAR_DB) 055@RunWith(LoadTimeWeavableTestRunner.class) 056@BootstrapTest(KEWTestCase.BootstrapTest.class) 057public abstract class KEWTestCase extends BaselineTestCase { 058 059 private static final String SQL_FILE = "classpath:org/kuali/rice/kew/test/DefaultSuiteTestData.sql"; 060 private static final String XML_FILE = "classpath:org/kuali/rice/kew/test/DefaultSuiteTestData.xml"; 061 private static final String KRAD_MODULE_NAME = "kew"; 062 063 public KEWTestCase() { 064 super(KRAD_MODULE_NAME); 065 } 066 067 @Override 068 protected List<Lifecycle> getSuiteLifecycles() { 069 List<Lifecycle> suiteLifecycles = super.getSuiteLifecycles(); 070 suiteLifecycles.add(new KEWXmlDataLoaderLifecycle(XML_FILE)); 071 072 return suiteLifecycles; 073 } 074 075 @Override 076 protected void loadSuiteTestData() throws Exception { 077 super.loadSuiteTestData(); 078 new SQLDataLoader(SQL_FILE, ";").runSql(); 079 } 080 081 082 /** 083 * By default this loads the "default" data set from the DefaultTestData.sql 084 * and DefaultTestData.xml files. Subclasses can override this to change 085 * this behaviour 086 */ 087 protected void loadDefaultTestData() throws Exception { 088 // at this point this is constants. loading these through xml import is 089 // problematic because of cache notification 090 // issues in certain low level constants. 091 new SQLDataLoader( 092 "classpath:org/kuali/rice/kew/test/DefaultPerTestData.sql", ";") 093 .runSql(); 094 095 KEWXmlDataLoader.loadXmlClassLoaderResource(KEWTestCase.class, 096 "DefaultPerTestData.xml"); 097 } 098 099 @Override 100 protected Lifecycle getLoadApplicationLifecycle() { 101 SpringResourceLoader springResourceLoader = new SpringResourceLoader(new QName("KEWTestResourceLoader"), "classpath:org/kuali/rice/kew/config/TestKEWSpringBeans.xml", null); 102 springResourceLoader.setParentSpringResourceLoader(getTestHarnessSpringResourceLoader()); 103 return springResourceLoader; 104 } 105 106 /** 107 * Default implementation does nothing. Subclasses should override this 108 * method if they want to perform setup work inside of a database 109 * transaction. 110 */ 111 protected void setUpAfterDataLoad() throws Exception { 112 // override 113 } 114 115 protected void loadTestData() throws Exception { 116 // override this to load your own test data 117 } 118 119 protected TransactionTemplate getTransactionTemplate() { 120 return TestUtilities.getTransactionTemplate(); 121 } 122 123 /** 124 * Initiates loading of per-test data 125 */ 126 @Override 127 protected void loadPerTestData() throws Exception { 128 final long t1 = System.currentTimeMillis(); 129 loadDefaultTestData(); 130 131 final long t2 = System.currentTimeMillis(); 132 loadTestData(); 133 134 final long t3 = System.currentTimeMillis(); 135 report("Time to load test-specific test data: " + (t3 - t2)); 136 137 setUpAfterDataLoad(); 138 139 final long t4 = System.currentTimeMillis(); 140 report("Time to run test-specific setup: " + (t4 - t3)); 141 } 142 143 /** 144 * Override the standard per-test lifecycles to prepend 145 * ClearDatabaseLifecycle and ClearCacheLifecycle 146 * 147 * @see org.kuali.rice.test.RiceTestCase#getPerTestLifecycles() 148 */ 149 @Override 150 protected List<Lifecycle> getPerTestLifecycles() { 151 List<Lifecycle> lifecycles = new ArrayList<Lifecycle>(); 152 lifecycles.add(new ClearDatabaseLifecycle(getPerTestTablesToClear(), 153 getPerTestTablesNotToClear())); 154 lifecycles.add(new ClearCacheLifecycle()); 155 lifecycles.addAll(super.getPerTestLifecycles()); 156 return lifecycles; 157 } 158 159 /** 160 * Flushes the KEW cache(s) 161 */ 162 public class ClearCacheLifecycle extends BaseLifecycle { 163 @Override 164 public void stop() throws Exception { 165 clearCacheManagers(KimImplServiceLocator.getLocalCacheManager(), KEWServiceLocator.getLocalCacheManager(), 166 CoreServiceImplServiceLocator.getLocalCacheManager()); 167 super.stop(); 168 } 169 } 170 171 protected void clearCacheManagers(CacheManager... cacheManagers) { 172 for (CacheManager cacheManager : cacheManagers) { 173 for (String cacheName : cacheManager.getCacheNames()) { 174 LOG.info("Clearing cache: " + cacheName); 175 cacheManager.getCache(cacheName).clear(); 176 } 177 } 178 } 179 180 /** 181 * Returns the List of tables that should be cleared on every test run. 182 */ 183 protected List<String> getPerTestTablesToClear() { 184 List<String> tablesToClear = new ArrayList<String>(); 185 tablesToClear.add("KREW_.*"); 186 tablesToClear.add("KRSB_.*"); 187 tablesToClear.add("KREN_.*"); 188 tablesToClear.add("KRMS_.*"); 189 return tablesToClear; 190 } 191 192 protected List<String> getPerTestTablesNotToClear() { 193 return new ArrayList<String>(); 194 } 195 196 protected void loadXmlFile(String fileName) { 197 try { 198 KEWXmlDataLoader.loadXmlClassLoaderResource(getClass(), fileName); 199 } catch (Exception e) { 200 throw new WorkflowRuntimeException(e); 201 } 202 } 203 204 protected void loadXmlFile(Class clazz, String fileName) { 205 try { 206 KEWXmlDataLoader.loadXmlClassLoaderResource(clazz, fileName); 207 } catch (Exception e) { 208 throw new WorkflowRuntimeException(e); 209 } 210 } 211 212 protected void loadXmlFileFromFileSystem(String fileName) { 213 try { 214 KEWXmlDataLoader.loadXmlFile(new ClasspathOrFileResourceLoader().getResource(fileName).getURL().getPath()); 215 } catch (Exception e) { 216 throw new WorkflowRuntimeException(e); 217 } 218 } 219 220 protected void loadXmlStream(InputStream xmlStream) { 221 try { 222 KEWXmlDataLoader.loadXmlStream(xmlStream); 223 } catch (Exception e) { 224 throw new WorkflowRuntimeException(e); 225 } 226 } 227 228 protected String getPrincipalIdForName(String principalName) { 229 return KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalName).getPrincipalId(); 230 } 231 232 protected String getPrincipalNameForId(String principalId) { 233 return KimApiServiceLocator.getIdentityService().getPrincipal(principalId).getPrincipalName(); 234 } 235 236 protected String getGroupIdForName(String namespace, String groupName) { 237 return KimApiServiceLocator.getGroupService().getGroupByNamespaceCodeAndName(namespace, groupName).getId(); 238 } 239 240 protected Long getNextSequenceLongValue(String sequenceName) { 241 return Long.valueOf(MaxValueIncrementerFactory.getIncrementer(TestHarnessServiceLocator.getDataSource(), 242 sequenceName).nextLongValue()); 243 } 244 245 protected String getNextSequenceStringValue(String sequenceName) { 246 return MaxValueIncrementerFactory.getIncrementer(TestHarnessServiceLocator.getDataSource(), sequenceName).nextStringValue(); 247 } 248 249 protected String getRoleIdForName(String namespace, String roleName) { 250 Role role = KimApiServiceLocator.getRoleService().getRoleByNamespaceCodeAndName(namespace, roleName); 251 return (role == null) ? null : role.getId(); 252 } 253 254 public static final class BootstrapTest extends KEWTestCase { 255 @Test 256 public void bootstrapTest() {}; 257 } 258 259}