001    /******************************************************************************
002     * Copyright (C) MActor Developers. All rights reserved.                        *
003     * ---------------------------------------------------------------------------*
004     * This file is part of MActor.                                               *
005     *                                                                            *
006     * MActor is free software; you can redistribute it and/or modify             *
007     * it under the terms of the GNU General Public License as published by       *
008     * the Free Software Foundation; either version 2 of the License, or          *
009     * (at your option) any later version.                                        *
010     *                                                                            *
011     * MActor is distributed in the hope that it will be useful,                  *
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
014     * GNU General Public License for more details.                               *
015     *                                                                            *
016     * You should have received a copy of the GNU General Public License          *
017     * along with MActor; if not, write to the Free Software                      *
018     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA *
019     ******************************************************************************/
020    package org.mactor.framework;
021    
022    import java.util.LinkedList;
023    import java.util.List;
024    
025    import org.apache.log4j.Logger;
026    import org.mactor.framework.TestEngineThreadPool.TestRunnable;
027    import org.mactor.framework.data.DataTable;
028    import org.mactor.framework.spec.GlobalConfig;
029    import org.mactor.framework.spec.ProjectContext;
030    import org.mactor.framework.spec.TestSpec;
031    
032    /**
033     * 
034     * @author Lars Ivar Almli
035     */
036    public class TestRunner {
037            protected static Logger log = Logger.getLogger(TestRunner.class);
038            private boolean terminate = false;
039            int numberOfTestThreads;
040            TestSpec testSpec;
041            DataTable testData;
042            private String instanceId = AppUtil.getNextId("TR");
043            TestEngineThreadPool pool;
044            int errorCount = 0;
045            List<TestRunnable> jobs = new LinkedList<TestRunnable>();
046            GlobalConfig gc;
047            EventReporter reporter;
048            public TestRunner(int numberOfTestThreads, TestSpec testSpec, DataTable testData, TestFeedbackListener fl) throws MactorException {
049                    super();
050                    if (numberOfTestThreads < 1)
051                            numberOfTestThreads = 1;
052                    reporter = new EventReporter(instanceId, fl);
053                    this.numberOfTestThreads = numberOfTestThreads;
054                    this.testSpec = testSpec;
055                    this.testData = testData;
056                    pool = new TestEngineThreadPool(numberOfTestThreads);
057                    gc = ProjectContext.getGlobalInstance().loadGlobalConfig();
058            }
059            boolean started = false;
060            private Object lock = new Object();
061            private boolean completed = false;
062            public void start() throws MactorException {
063                    if (started)
064                            throw new MactorException("The test runner can only be used once");
065                    started = true;
066                    new Thread(new Runnable() {
067                            public void run() {
068                                    reporter.start();
069                                    try {
070                                            try {
071                                                    int dataCount = testData.getRowCount();
072                                                    for (int i = 0; (i < dataCount) && !terminate; i++) {
073                                                            TestContextImpl context = new TestContextImpl(gc, testSpec);
074                                                            context.setValues(testData.getRowData(i));
075                                                            TestRunnable r = new TestRunnable(i, new TestEngine(instanceId, context, reporter));
076                                                            jobs.add(r);
077                                                            pool.addJob(r);
078                                                    }
079                                            } catch (MactorException me) {
080                                                    log.warn("Exception while initializing test", me);
081                                            }
082                                            pool.join();
083                                            for (TestRunnable runnable : jobs) {
084                                                    if (!runnable.isSucces())
085                                                            errorCount++;
086                                            }
087                                    } finally {
088                                            reporter.stop();
089                                            synchronized (lock) {
090                                                    completed = true;
091                                                    lock.notifyAll();
092                                            }
093                                    }
094                            }
095                    }).start();
096            }
097            public int waitForCompletion() {
098                    try {
099                            synchronized (lock) {
100                                    if (!completed)
101                                            lock.wait();
102                            }
103                    } catch (InterruptedException ie) {
104                    }
105                    return errorCount;
106            }
107            public void stop() {
108                    terminate = true;
109                    pool.terminate();
110                    reporter.stop();
111            }
112            @Override
113            protected void finalize() throws Throwable {
114                    super.finalize();
115            }
116    }