Update of /cvsroot/smartfrog/core/components/junit/src/org/smartfrog/services/junit In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3389/src/org/smartfrog/services/junit Modified Files: components.sf TestSuiteComponent.java TestSuite.java TestRunnerComponent.java TestRunner.java Added Files: RunnerConfiguration.java Log Message: junit test harness compiles but not tried running yet.Will need some tests :) Index: TestRunnerComponent.java =================================================================== RCS file: /cvsroot/smartfrog/core/components/junit/src/org/smartfrog/services/junit/TestRunnerComponent.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TestRunnerComponent.java 14 May 2004 15:36:54 -0000 1.1 --- TestRunnerComponent.java 19 May 2004 15:56:38 -0000 1.2 *************** *** 23,31 **** --- 23,36 ---- import org.smartfrog.sfcore.common.SmartFrogInitException; import org.smartfrog.sfcore.compound.CompoundImpl; + import org.smartfrog.sfcore.utils.ComponentHelper; + import org.smartfrog.sfcore.prim.Prim; import java.rmi.RemoteException; + import java.util.Enumeration; + import java.util.logging.Logger; /** * This is the test runner. + * It keeps all its public state in a configuration object that can be got/cloned and serialized to suites * created 15-Apr-2004 15:44:41 */ *************** *** 33,53 **** public class TestRunnerComponent extends CompoundImpl implements TestRunner { public TestRunnerComponent() throws RemoteException { } /** * who listens to the tests? */ ! private TestListener listener; ! ! /** ! * flag to identify whether the task should fail when it is time ! */ ! private boolean keepGoing = true; - /** - * fork into a new process? - */ - private boolean fork = false; /** --- 38,55 ---- public class TestRunnerComponent extends CompoundImpl implements TestRunner { + private Logger log; + private ComponentHelper helper; + public TestRunnerComponent() throws RemoteException { + helper = new ComponentHelper(this); + log=helper.getLogger(); } /** * who listens to the tests? + * This is potentially remote */ ! private RunnerConfiguration configuration=new RunnerConfiguration(); /** *************** *** 57,61 **** */ private void validate() throws SmartFrogInitException { ! if (fork == true) { throw new SmartFrogInitException("forking is not yet implemented"); } --- 59,63 ---- */ private void validate() throws SmartFrogInitException { ! if (configuration.getFork() == true) { throw new SmartFrogInitException("forking is not yet implemented"); } *************** *** 87,124 **** public synchronized void sfStart() throws SmartFrogException, RemoteException { super.sfStart(); ! Object o = sfResolve(ATTRIBUTE_LISTENER, listener, true); if (!(o instanceof TestListener)) { throw new SmartFrogException("The attribute " + ATTRIBUTE_LISTENER + "must refer to an implementation of TestListener"); } ! listener = (TestListener) o; ! fork = sfResolve(ATTRIBUTE_FORK, fork, false); ! keepGoing = sfResolve(ATTRIBUTE_KEEPGOING, keepGoing, false); validate(); } public TestListener getListener() { ! return listener; } public void setListener(TestListener listener) { ! this.listener = listener; } public boolean getKeepGoing() { ! return keepGoing; } public void setKeepGoing(boolean keepGoing) { ! this.keepGoing = keepGoing; } public boolean getFork() { ! return fork; } public void setFork(boolean fork) { ! this.fork = fork; } } --- 89,146 ---- public synchronized void sfStart() throws SmartFrogException, RemoteException { + //this will deploy all our children, including the test suites super.sfStart(); ! Object o = sfResolve(ATTRIBUTE_LISTENER, configuration.getListener(), true); if (!(o instanceof TestListener)) { throw new SmartFrogException("The attribute " + ATTRIBUTE_LISTENER + "must refer to an implementation of TestListener"); } ! configuration.setListener((TestListener) o); ! configuration.setFork(sfResolve(ATTRIBUTE_FORK, configuration.getFork(), false)); ! configuration.setKeepGoing(sfResolve(ATTRIBUTE_KEEPGOING, configuration.getKeepGoing(), false)); validate(); + //TODO: execute the tests in all the suites attached to this class + } + + protected void runAllTests() throws SmartFrogException, RemoteException { + Enumeration e=sfChildren(); + while (e.hasMoreElements()) { + Object o = (Object) e.nextElement(); + if(o instanceof TestSuite) { + TestSuite suiteComponent=(TestSuite) o; + suiteComponent.bind(getConfiguration()); + suiteComponent.runTests(); + } + } } public TestListener getListener() { ! return configuration.getListener(); } + public void setListener(TestListener listener) { ! configuration.setListener(listener); } public boolean getKeepGoing() { ! return configuration.getKeepGoing(); } public void setKeepGoing(boolean keepGoing) { ! configuration.setKeepGoing(keepGoing); } public boolean getFork() { ! return configuration.getFork(); } public void setFork(boolean fork) { ! configuration.setFork(fork); ! } ! ! ! public RunnerConfiguration getConfiguration() { ! return configuration; } } Index: TestSuiteComponent.java =================================================================== RCS file: /cvsroot/smartfrog/core/components/junit/src/org/smartfrog/services/junit/TestSuiteComponent.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** TestSuiteComponent.java 14 May 2004 15:36:55 -0000 1.1 --- TestSuiteComponent.java 19 May 2004 15:56:38 -0000 1.2 *************** *** 22,52 **** import org.smartfrog.sfcore.common.SmartFrogException; import org.smartfrog.sfcore.prim.PrimImpl; import java.rmi.RemoteException; import java.util.List; /** ! * Implementation of the test suite component * created 14-May-2004 15:14:23 */ ! public class TestSuiteComponent extends PrimImpl implements TestSuite { ! ! public TestSuiteComponent() throws RemoteException { ! } ! /* ! TestSuiteSchema extends Schema { ! class extends OptionalString; ! if extends OptionalBoolean; ! unless extends OptionalBoolean; ! subpackages extends OptionalBoolean; ! package extends String; ! excludes extends OptionalList; ! public synchronized void sfDeploy() throws SmartFrogException, RemoteException { ! super.sfDeploy(); ! } ! */ private String testClass; --- 22,52 ---- import org.smartfrog.sfcore.common.SmartFrogException; import org.smartfrog.sfcore.prim.PrimImpl; + import org.smartfrog.sfcore.utils.ComponentHelper; + import org.smartfrog.sfcore.security.SFClassLoader; import java.rmi.RemoteException; import java.util.List; + import java.util.logging.Logger; + import java.util.logging.Level; + import java.lang.reflect.Method; + import java.lang.reflect.InvocationTargetException; + + import junit.framework.Test; + import junit.framework.TestResult; + import junit.framework.AssertionFailedError; + + /** ! * Implementation of the test suite component. ! * This is where tests are actually run; we bring up Junit internally and run it here * created 14-May-2004 15:14:23 */ ! public class TestSuiteComponent extends PrimImpl implements TestSuite, junit.framework.TestListener { ! private Logger log; ! private ComponentHelper helper; private String testClass; *************** *** 60,63 **** --- 60,76 ---- private List excludes; + RunnerConfiguration configuration; + + private int errors = 0; + private int failures = 0; + private int testsRun = 0; + + + + public TestSuiteComponent() throws RemoteException { + helper = new ComponentHelper(this); + log = helper.getLogger(); + } + public String getTestClass() throws RemoteException { return testClass; *************** *** 101,104 **** --- 114,127 ---- /** + * bind to the configuration. A null parameter means 'stop binding' + * + * @param configuration + * @throws java.rmi.RemoteException + */ + public void bind(RunnerConfiguration configuration) throws RemoteException { + this.configuration = configuration; + } + + /** * Can be called to start components. Subclasses should override to provide * functionality Do not block in this call, but spawn off any main loops! *************** *** 113,115 **** --- 136,271 ---- + /** + * run the test + * + * @return true iff all tests passed + * @throws java.rmi.RemoteException + */ + public boolean runTests() throws RemoteException, SmartFrogException { + if(configuration==null || getListener()==null) { + throw new SmartFrogException("TestSuite has not been configured yet"); + } + + return false; + } + + /** + * test a single class + * @param classname + * @throws ClassNotFoundException + * @throws IllegalAccessException + * @throws InvocationTargetException + */ + void testSingleClass(String classname) throws ClassNotFoundException, IllegalAccessException, + InvocationTargetException { + Test tests; + Class clazz=loadTestClass(classname); + tests=extractTest(clazz); + TestResult result=new TestResult(); + result.addListener(this); + tests.run(result); + + } + + + /** + * load the test class, using the secure classloader framework. + * + * @param classname + * @return + * @throws ClassNotFoundException + */ + private Class loadTestClass(String classname) throws ClassNotFoundException { + //Class.forName(classname); + Class clazz=SFClassLoader.forName(classname); + return clazz; + } + + /** + * get the tests from the class, either as a suite or as introspected tests + * @param clazz + * @return the test + * @throws IllegalAccessException + * @throws InvocationTargetException + */ + private Test extractTest(Class clazz) throws IllegalAccessException, InvocationTargetException { + //todo: verify that the class implements test or testsuite + try { + // check if there is a suite method + Method method = clazz.getMethod("suite", new Class[0]); + return (Test) method.invoke(null, new Class[0]); + } catch (NoSuchMethodException e) { + //if not, assume that it is a testclass and do it that way + return new junit.framework.TestSuite(clazz); + } + } + + /** + * get our listener + * @return + */ + TestListener getListener() { + return configuration.getListener(); + } + + /** + * An error occurred. + */ + public void addError(Test test, Throwable throwable) { + errors++; + TestInfo info=new TestInfo(test,throwable); + try { + getListener().addError(info); + } catch (RemoteException e) { + IgnoreRemoteFault(e); + } + } + + /** + * ignore a remote fault by logging it + * @param e + */ + private void IgnoreRemoteFault(RemoteException e) { + log.log(Level.WARNING,"",e); + } + + /** + * A failure occurred. + */ + public void addFailure(Test test, AssertionFailedError error) { + failures++; + TestInfo info = new TestInfo(test, error); + try { + getListener().addFailure(info); + } catch (RemoteException e) { + IgnoreRemoteFault(e); + } + } + + /** + * A test ended. + */ + public void endTest(Test test) { + testsRun++; + TestInfo info = new TestInfo(test); + try { + getListener().endTest(info); + } catch (RemoteException e) { + IgnoreRemoteFault(e); + } + } + + /** + * A test started. + */ + public void startTest(Test test) { + TestInfo info = new TestInfo(test); + try { + getListener().startTest(info); + } catch (RemoteException e) { + IgnoreRemoteFault(e); + } + } + + } Index: TestSuite.java =================================================================== RCS file: /cvsroot/smartfrog/core/components/junit/src/org/smartfrog/services/junit/TestSuite.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TestSuite.java 14 May 2004 15:36:55 -0000 1.2 --- TestSuite.java 19 May 2004 15:56:38 -0000 1.3 *************** *** 20,23 **** --- 20,25 ---- package org.smartfrog.services.junit; + import org.smartfrog.sfcore.common.SmartFrogException; + import java.rmi.Remote; import java.rmi.RemoteException; *************** *** 68,70 **** --- 70,86 ---- void setExcludes(List excludes) throws RemoteException; + /** + * bind to the configuration. A null parameter means 'stop binding' + * @param configuration + * @throws RemoteException + */ + void bind(RunnerConfiguration configuration) throws RemoteException; + + /** + * run the test + * @return true iff all tests passed + * @throws RemoteException + */ + boolean runTests() throws RemoteException, SmartFrogException; + } Index: components.sf =================================================================== RCS file: /cvsroot/smartfrog/core/components/junit/src/org/smartfrog/services/junit/components.sf,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** components.sf 14 May 2004 15:36:55 -0000 1.1 --- components.sf 19 May 2004 15:56:38 -0000 1.2 *************** *** 97,101 **** * the base test runner has a console listener automatically */ ! TestRunner extends Prim { sfClass "org.smartfrog.services.junit.TestRunnerComponent"; testRunnerSchema extends TestRunnerSchema; --- 97,101 ---- * the base test runner has a console listener automatically */ ! TestRunner extends Compound { sfClass "org.smartfrog.services.junit.TestRunnerComponent"; testRunnerSchema extends TestRunnerSchema; --- NEW FILE: RunnerConfiguration.java --- /** (C) Copyright 1998-2004 Hewlett-Packard Development Company, LP This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For more information: www.smartfrog.org */ package org.smartfrog.services.junit; import java.io.Serializable; /** * created 17-May-2004 17:22:03 * The clone policy creates a shallow clone */ public class RunnerConfiguration implements Serializable, Cloneable { /** * who listens to the tests? * This is potentially remote */ private TestListener listener; /** * flag to identify whether the task should fail when it is time */ private boolean keepGoing = true; /** * fork into a new process? */ private boolean fork = false; public TestListener getListener() { return listener; } public void setListener(TestListener listener) { this.listener = listener; } public boolean getKeepGoing() { return keepGoing; } public void setKeepGoing(boolean keepGoing) { this.keepGoing = keepGoing; } public boolean getFork() { return fork; } public void setFork(boolean fork) { this.fork = fork; } /** * the shallow clone copies all the simple settings, but shares the test listener. * @return * @throws CloneNotSupportedException */ protected Object clone() throws CloneNotSupportedException { return super.clone(); } } Index: TestRunner.java =================================================================== RCS file: /cvsroot/smartfrog/core/components/junit/src/org/smartfrog/services/junit/TestRunner.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TestRunner.java 14 May 2004 15:36:54 -0000 1.2 --- TestRunner.java 19 May 2004 15:56:38 -0000 1.3 *************** *** 55,57 **** --- 55,59 ---- void setFork(boolean fork) throws RemoteException; + + } |