<commit_before>/*
 * Copyright 2005-2007 The Kuali Foundation.
 *
 *
 * Licensed under the Educational Community License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.opensource.org/licenses/ecl1.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.workflow.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.junit.Before;
import org.kuali.rice.config.Config;
import org.kuali.rice.core.Core;
import org.kuali.rice.lifecycle.BaseLifecycle;
import org.kuali.rice.lifecycle.Lifecycle;
import org.kuali.rice.resourceloader.GlobalResourceLoader;
import org.kuali.rice.resourceloader.ResourceLoader;
import org.kuali.rice.test.ClearDatabaseLifecycle;
import org.kuali.rice.test.DerbyDBCreationLifecycle;
import org.kuali.rice.test.RiceTestCase;
import org.kuali.rice.test.TestHarnessServiceLocator;
import org.kuali.rice.web.jetty.JettyServer;
import org.mortbay.jetty.webapp.WebAppClassLoader;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import edu.iu.uis.eden.EdenConstants;
import edu.iu.uis.eden.KEWServiceLocator;
import edu.iu.uis.eden.batch.FileXmlDocCollection;
import edu.iu.uis.eden.batch.XmlDoc;
import edu.iu.uis.eden.batch.XmlDocCollection;
import edu.iu.uis.eden.exception.WorkflowRuntimeException;
import edu.iu.uis.eden.test.SQLDataLoader;
import edu.iu.uis.eden.test.TestUtilities;

/**
 * Useful superclass for all Workflow test cases. Handles setup of test
 * utilities and a test environment. Configures the Spring test environment
 * providing a template method for custom context files in test mode. Also
 * provides a template method for running custom transactional setUp. Tear down
 * handles automatic tear down of objects created inside the test environment.
 */
public abstract class WorkflowTestCase extends RiceTestCase {

    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(WorkflowTestCase.class);

    @Override
    protected List<String> getConfigLocations() {
	return Arrays.asList(new String[]{"classpath:META-INF/kew-test-config.xml"});
    }

    @Override
    protected String getDerbySQLFileLocation() {
	return null;
    }

    @Override
    protected String getModuleName() {
	return TestUtils.getModuleName();
    }

    /**
     * Initiates loading of test data within a transaction.
     */
    protected void loadTestDataInternal() throws Exception {
        getTransactionTemplate().execute(new TransactionCallbackWithoutResult() {
            public void doInTransactionWithoutResult(final TransactionStatus status) {
        	try {
        	    setUpTransactionInternal();
        	} catch (Exception e) {
        	    throw new WrappedTransactionRuntimeException(e);
        	}
            }
        });
    }


    protected void setUpTransactionInternal() throws Exception {
        final long t1 = System.currentTimeMillis();

        loadDefaultTestData();

        final long t2 = System.currentTimeMillis();
        report("Time to load default test data: " + (t2 - t1));

        loadTestData();

        final long t3 = System.currentTimeMillis();
        report("Time to load test-specific test data: " + (t3 - t2));

        setUpTransaction();

        final long t4 = System.currentTimeMillis();
        report("Time to run test-specific setup: " + (t4 - t3));
    }

    /**
     * Default implementation does nothing.  Subclasses should override this method if they want to perform setup
     * work inside of a database transaction.
     */
    protected void setUpTransaction() throws Exception {
	// override
    }

    /**
     * @Override
     */
    protected void loadTestData() throws Exception {
        // override this to load your own test data
    }

    protected TransactionTemplate getTransactionTemplate() {
	return TestUtilities.getTransactionTemplate();
    }

    private class WrappedTransactionRuntimeException extends RuntimeException {

        private static final long serialVersionUID = 3097909333572509600L;

        public WrappedTransactionRuntimeException(Exception e) {
            super(e);
        }
    }

    @Before
    @Override
    public void setUp() throws Exception {
	try {
	    System.setProperty(EdenConstants.BOOTSTRAP_SPRING_FILE, "org/kuali/workflow/resources/TestKewSpringBeans.xml");
	    beforeRun();
	    configureLogging();
	    final long initTime = System.currentTimeMillis();
	    this.perTestLifeCycles = getPerTestLifecycles();
	    this.suiteLifeCycles = getSuiteLifecycles();
	    if (!SUITE_LIFE_CYCLES_RAN) {
		startLifecycles(this.suiteLifeCycles);
		SUITE_LIFE_CYCLES_RAN = true;
	    }
	    startLifecycles(this.perTestLifeCycles);
	    report("Time to start all Lifecycles: " + (System.currentTimeMillis() - initTime));
	    loadTestDataInternal();
	} catch (Throwable e) {
	    LOG.error("An error was thrown from test setup, calling tearDown()", e);
	    tearDown();
	    throw new RuntimeException(e);
	}
    }


    @Override
    protected List<Lifecycle> getPerTestLifecycles() {
	List<Lifecycle> lifecycles = new ArrayList<Lifecycle>();
	lifecycles.add(new ClearDatabaseLifecycle(getTablesToClear(), getTablesNotToClear()));
	lifecycles.add(new ClearCacheLifecycle());
	return lifecycles;
    }

    @Override
    protected List<Lifecycle> getSuiteLifecycles() {
	LinkedList<Lifecycle> lifeCycles = new LinkedList<Lifecycle>();
	lifeCycles.add(new Lifecycle() {
	    boolean started = false;
	    public boolean isStarted() {
		return this.started;
	    }
	    public void start() throws Exception {
		setModuleName(getModuleName());
		setBaseDirSystemProperty(getModuleName());
		Config config = getTestHarnessConfig();
		Core.init(config);
		this.started = true;
	    }
	    public void stop() throws Exception {
		this.started = false;
	    }
	});
	lifeCycles.add(getTestHarnessSpringResourceLoader());
	lifeCycles.add(new Lifecycle() {
	    boolean started = false;
	    public boolean isStarted() {
		return this.started;
	    }
	    public void start() throws Exception {
		TestHarnessServiceLocator.setContext(getTestHarnessSpringResourceLoader().getContext());
		this.started = true;
	    }
	    public void stop() throws Exception {
		this.started = false;
	    }
	});
	lifeCycles.add(new DerbyDBCreationLifecycle(getDerbySQLFileLocation()));
	// we want to only clear out the quartz tables one time, therefore we want to pass this lifecycle the
	// opposite of what is passed to the clear database lifecycle that runs on every test execution
	lifeCycles.add(new ClearDatabaseLifecycle(getTablesNotToClear(), getTablesToClear()));
	JettyServer server = new JettyServer(9952, "/en-test", "/../kns/src/test/webapp/en");
	lifeCycles.add(server);
	lifeCycles.add(new InitializeGRL());
	lifeCycles.add(new SuiteDataLoadLifecycle());
	return lifeCycles;
    }

    private class SuiteDataLoadLifecycle extends BaseLifecycle {
	@Override
	public void start() throws Exception {
	    new SQLDataLoader("OneTimeDefaultTestData.sql", WorkflowTestCase.class).runSql();
	    super.start();
	}
    }

    private class InitializeGRL extends BaseLifecycle {
	@Override
	public void start() throws Exception {
	    Map<ClassLoader, Config> configs = Core.getCONFIGS();
	    for (Map.Entry<ClassLoader, Config> configEntry : configs.entrySet()) {
		if (configEntry.getKey() instanceof WebAppClassLoader) {
		    ResourceLoader rl = GlobalResourceLoader.getResourceLoader(configEntry.getKey());
		    if (rl == null) {
			fail("didn't find resource loader for workflow test harness web app");
		    }
		    GlobalResourceLoader.addResourceLoader(rl);
		    configs.put(Thread.currentThread().getContextClassLoader(), configEntry.getValue());
		}
	    }
	    super.start();
	}

    }

    public class ClearCacheLifecycle extends BaseLifecycle {

	@Override
	public void stop() throws Exception {
	    KEWServiceLocator.getCacheAdministrator().flushAll();
	    super.stop();
	}

    }

    /**
     * Returns the List of tables that should be cleared on every test run.
     */
    @Override
    protected List<String> getTablesToClear() {
	List<String> tablesToClear = new ArrayList<String>();
	tablesToClear.add("EN_.*");
	return tablesToClear;
    }


    /**
     * Returns the List of tables that should NOT be cleared on every test run.
     *
     * We only want to clear out the quartz tables one time, otherwise we get weird locking
     * errors if we try to clear out those tables on every run.
     */
    @Override
    protected List<String> getTablesNotToClear() {
	List<String> tablesNotToClear = new ArrayList<String>();
	tablesNotToClear.add("KR_.*");
	return tablesNotToClear;
    }


	/**
	 * By default this loads the "default" data set from the DefaultTestData.sql
	 * and DefaultTestData.xml files. Subclasses can override this to change
	 * this behaviour
	 */
	protected void loadDefaultTestData() throws Exception {
		// at this point this is constants. loading these through xml import is
		// problematic because of cache notification
		// issues in certain low level constants.
		new SQLDataLoader("DefaultTestData.sql", WorkflowTestCase.class).runSql();
		this.loadXmlFile(WorkflowTestCase.class, "DefaultTestData.xml");
	}

	protected void loadXmlFile(String fileName) {
		if (fileName.indexOf('/') < 0) {
			this.loadXmlFile(getClass(), fileName);
		} else {
			loadXmlStream(getClass().getClassLoader().getResourceAsStream(fileName));
		}
	}

	protected void loadXmlFile(Class clazz, String fileName) {
		InputStream xmlFile = TestUtilities.loadResource(clazz, fileName);
		if (xmlFile == null) {
			throw new WorkflowRuntimeException("Didn't find file " + fileName);
		}
		loadXmlStream(xmlFile);
	}<commit_msg>Removed perSuite clear and data load.<commit_after>/*
 * Copyright 2005-2007 The Kuali Foundation.
 *
 *
 * Licensed under the Educational Community License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.opensource.org/licenses/ecl1.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.workflow.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.junit.Before;
import org.kuali.rice.config.Config;
import org.kuali.rice.core.Core;
import org.kuali.rice.lifecycle.BaseLifecycle;
import org.kuali.rice.lifecycle.Lifecycle;
import org.kuali.rice.resourceloader.GlobalResourceLoader;
import org.kuali.rice.resourceloader.ResourceLoader;
import org.kuali.rice.test.ClearDatabaseLifecycle;
import org.kuali.rice.test.DerbyDBCreationLifecycle;
import org.kuali.rice.test.RiceTestCase;
import org.kuali.rice.test.TestHarnessServiceLocator;
import org.kuali.rice.web.jetty.JettyServer;
import org.mortbay.jetty.webapp.WebAppClassLoader;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import edu.iu.uis.eden.EdenConstants;
import edu.iu.uis.eden.KEWServiceLocator;
import edu.iu.uis.eden.batch.FileXmlDocCollection;
import edu.iu.uis.eden.batch.XmlDoc;
import edu.iu.uis.eden.batch.XmlDocCollection;
import edu.iu.uis.eden.exception.WorkflowRuntimeException;
import edu.iu.uis.eden.test.SQLDataLoader;
import edu.iu.uis.eden.test.TestUtilities;

/**
 * Useful superclass for all Workflow test cases. Handles setup of test
 * utilities and a test environment. Configures the Spring test environment
 * providing a template method for custom context files in test mode. Also
 * provides a template method for running custom transactional setUp. Tear down
 * handles automatic tear down of objects created inside the test environment.
 */
public abstract class WorkflowTestCase extends RiceTestCase {

    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(WorkflowTestCase.class);

    @Override
    protected List<String> getConfigLocations() {
	return Arrays.asList(new String[]{"classpath:META-INF/kew-test-config.xml"});
    }

    @Override
    protected String getDerbySQLFileLocation() {
	return null;
    }

    @Override
    protected String getModuleName() {
	return TestUtils.getModuleName();
    }

    /**
     * Initiates loading of test data within a transaction.
     */
    protected void loadTestDataInternal() throws Exception {
        getTransactionTemplate().execute(new TransactionCallbackWithoutResult() {
            public void doInTransactionWithoutResult(final TransactionStatus status) {
        	try {
        	    setUpTransactionInternal();
        	} catch (Exception e) {
        	    throw new WrappedTransactionRuntimeException(e);
        	}
            }
        });
    }


    protected void setUpTransactionInternal() throws Exception {
        final long t1 = System.currentTimeMillis();

        loadDefaultTestData();

        final long t2 = System.currentTimeMillis();
        report("Time to load default test data: " + (t2 - t1));

        loadTestData();

        final long t3 = System.currentTimeMillis();
        report("Time to load test-specific test data: " + (t3 - t2));

        setUpTransaction();

        final long t4 = System.currentTimeMillis();
        report("Time to run test-specific setup: " + (t4 - t3));
    }

    /**
     * Default implementation does nothing.  Subclasses should override this method if they want to perform setup
     * work inside of a database transaction.
     */
    protected void setUpTransaction() throws Exception {
	// override
    }

    /**
     * @Override
     */
    protected void loadTestData() throws Exception {
        // override this to load your own test data
    }

    protected TransactionTemplate getTransactionTemplate() {
	return TestUtilities.getTransactionTemplate();
    }

    private class WrappedTransactionRuntimeException extends RuntimeException {

        private static final long serialVersionUID = 3097909333572509600L;

        public WrappedTransactionRuntimeException(Exception e) {
            super(e);
        }
    }

    @Before
    @Override
    public void setUp() throws Exception {
	try {
	    System.setProperty(EdenConstants.BOOTSTRAP_SPRING_FILE, "org/kuali/workflow/resources/TestKewSpringBeans.xml");
	    beforeRun();
	    configureLogging();
	    final long initTime = System.currentTimeMillis();
	    this.perTestLifeCycles = getPerTestLifecycles();
	    this.suiteLifeCycles = getSuiteLifecycles();
	    if (!SUITE_LIFE_CYCLES_RAN) {
		startLifecycles(this.suiteLifeCycles);
		SUITE_LIFE_CYCLES_RAN = true;
	    }
	    startLifecycles(this.perTestLifeCycles);
	    report("Time to start all Lifecycles: " + (System.currentTimeMillis() - initTime));
	    loadTestDataInternal();
	} catch (Throwable e) {
	    LOG.error("An error was thrown from test setup, calling tearDown()", e);
	    tearDown();
	    throw new RuntimeException(e);
	}
    }


    @Override
    protected List<Lifecycle> getPerTestLifecycles() {
	List<Lifecycle> lifecycles = new ArrayList<Lifecycle>();
	lifecycles.add(new ClearDatabaseLifecycle(getTablesToClear(), getTablesNotToClear()));
	lifecycles.add(new ClearCacheLifecycle());
	return lifecycles;
    }

    @Override
    protected List<Lifecycle> getSuiteLifecycles() {
	LinkedList<Lifecycle> lifeCycles = new LinkedList<Lifecycle>();
	lifeCycles.add(new Lifecycle() {
	    boolean started = false;
	    public boolean isStarted() {
		return this.started;
	    }
	    public void start() throws Exception {
		setModuleName(getModuleName());
		setBaseDirSystemProperty(getModuleName());
		Config config = getTestHarnessConfig();
		Core.init(config);
		this.started = true;
	    }
	    public void stop() throws Exception {
		this.started = false;
	    }
	});
	lifeCycles.add(getTestHarnessSpringResourceLoader());
	lifeCycles.add(new Lifecycle() {
	    boolean started = false;
	    public boolean isStarted() {
		return this.started;
	    }
	    public void start() throws Exception {
		TestHarnessServiceLocator.setContext(getTestHarnessSpringResourceLoader().getContext());
		this.started = true;
	    }
	    public void stop() throws Exception {
		this.started = false;
	    }
	});
	lifeCycles.add(new DerbyDBCreationLifecycle(getDerbySQLFileLocation()));
	// we want to only clear out the quartz tables one time, therefore we want to pass this lifecycle the
	// opposite of what is passed to the clear database lifecycle that runs on every test execution
	JettyServer server = new JettyServer(9952, "/en-test", "/../kns/src/test/webapp/en");
	lifeCycles.add(server);
	lifeCycles.add(new InitializeGRL());
	return lifeCycles;
    }

    private class InitializeGRL extends BaseLifecycle {
	@Override
	public void start() throws Exception {
	    Map<ClassLoader, Config> configs = Core.getCONFIGS();
	    for (Map.Entry<ClassLoader, Config> configEntry : configs.entrySet()) {
		if (configEntry.getKey() instanceof WebAppClassLoader) {
		    ResourceLoader rl = GlobalResourceLoader.getResourceLoader(configEntry.getKey());
		    if (rl == null) {
			fail("didn't find resource loader for workflow test harness web app");
		    }
		    GlobalResourceLoader.addResourceLoader(rl);
		    configs.put(Thread.currentThread().getContextClassLoader(), configEntry.getValue());
		}
	    }
	    super.start();
	}

    }

    public class ClearCacheLifecycle extends BaseLifecycle {

	@Override
	public void stop() throws Exception {
	    KEWServiceLocator.getCacheAdministrator().flushAll();
	    super.stop();
	}

    }

    /**
     * Returns the List of tables that should be cleared on every test run.
     */
    @Override
    protected List<String> getTablesToClear() {
	List<String> tablesToClear = new ArrayList<String>();
	tablesToClear.add("EN_.*");
	return tablesToClear;
    }

	/**
	 * By default this loads the "default" data set from the DefaultTestData.sql
	 * and DefaultTestData.xml files. Subclasses can override this to change
	 * this behaviour
	 */
	protected void loadDefaultTestData() throws Exception {
		// at this point this is constants. loading these through xml import is
		// problematic because of cache notification
		// issues in certain low level constants.
		new SQLDataLoader("DefaultTestData.sql", WorkflowTestCase.class).runSql();
		this.loadXmlFile(WorkflowTestCase.class, "DefaultTestData.xml");
	}

	protected void loadXmlFile(String fileName) {
		if (fileName.indexOf('/') < 0) {
			this.loadXmlFile(getClass(), fileName);
		} else {
			loadXmlStream(getClass().getClassLoader().getResourceAsStream(fileName));
		}
	}

	protected void loadXmlFile(Class clazz, String fileName) {
		InputStream xmlFile = TestUtilities.loadResource(clazz, fileName);
		if (xmlFile == null) {
			throw new WorkflowRuntimeException("Didn't find file " + fileName);
		}
		loadXmlStream(xmlFile);
	}
{'fraction_non_alphanumeric': 0.09657987753273262, 'fraction_numerical': 0.004679643550555086, 'mean_word_length': 3.8545190913484775, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 16}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '256748', 'n_tokens_mistral': 5977, 'n_tokens_neox': 5678, 'n_words': 1526}