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.List; 023 024 import org.apache.log4j.Logger; 025 import org.mactor.framework.TestEngineThreadPool.TestRunnable; 026 import org.mactor.framework.spec.GlobalConfig; 027 import org.mactor.framework.spec.ProjectContext; 028 import org.mactor.framework.spec.TestSpec; 029 030 /** 031 * 032 * @author Lars Ivar Almli 033 */ 034 public class MockRunner { 035 protected static Logger log = Logger.getLogger(MockRunner.class); 036 private boolean stopped = false; 037 int numberOfTestThreads; 038 List<TestSpec> testSpecs; 039 TestEngineThreadPool pool; 040 int errorCount = 0; 041 GlobalConfig gc; 042 EventReporter reporter; 043 private String mockInstanceId = AppUtil.getNextId("M"); 044 public MockRunner(int numberOfTestThreads, List<TestSpec> testSpecs, TestFeedbackListener fl) throws MactorException { 045 super(); 046 if (numberOfTestThreads < 1) 047 numberOfTestThreads = 1; 048 reporter = new EventReporter(mockInstanceId, fl); 049 this.numberOfTestThreads = numberOfTestThreads; 050 this.testSpecs = testSpecs; 051 pool = new TestEngineThreadPool(numberOfTestThreads); 052 gc = ProjectContext.getGlobalInstance().loadGlobalConfig(); 053 } 054 boolean started = false; 055 public void start() throws MactorException { 056 if (started) 057 throw new MactorException("The mock runner can only be used once"); 058 started = true; 059 new Thread(new Runnable() { 060 public void run() { 061 runMock(); 062 } 063 }).start(); 064 } 065 private void runMock() { 066 try { 067 reporter.start(); 068 while (!stopped) { 069 for (TestSpec ts : testSpecs) { 070 if (stopped) 071 break; 072 TestContextImpl context = new TestContextImpl(gc, ts); 073 TestRunnable r = new TestRunnable(0, new TestEngine(mockInstanceId, context, reporter)); 074 pool.addJob(r); // blocks until a thread is available.. 075 } 076 } 077 } catch (Throwable t) { 078 if (stopped) 079 log.info("Mock runner stopped"); 080 else 081 log.error("Mock runner terminated due to an unhandled exception:" + t.getMessage(), t); 082 } finally { 083 reporter.stop(); 084 } 085 } 086 private Object lock = new Object(); 087 public void waitForCompletion() { 088 synchronized (lock) { 089 if (stopped) 090 return; 091 try { 092 lock.wait(); 093 } catch (InterruptedException ie) { 094 } 095 } 096 } 097 public void stop() { 098 stopped = true; 099 try { 100 pool.terminate(); 101 reporter.stop(); 102 } finally { 103 synchronized (lock) { 104 lock.notifyAll(); 105 } 106 } 107 } 108 @Override 109 protected void finalize() throws Throwable { 110 super.finalize(); 111 } 112 }