DTF SVN: r18 - trunk/src/org/jboss/dtf/testframework/local.
by dtf-commits@lists.jboss.org
Author: jhalliday
Date: 2008-08-11 10:15:19 -0400 (Mon, 11 Aug 2008)
New Revision: 18
Modified:
trunk/src/org/jboss/dtf/testframework/local/LocalTestManager.java
Log:
Improved handling for config files with relative rather than absolute paths. DTF-4
Modified: trunk/src/org/jboss/dtf/testframework/local/LocalTestManager.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/local/LocalTestManager.java 2008-08-07 15:19:54 UTC (rev 17)
+++ trunk/src/org/jboss/dtf/testframework/local/LocalTestManager.java 2008-08-11 14:15:19 UTC (rev 18)
@@ -30,6 +30,7 @@
import java.net.URL;
import java.util.*;
+import java.io.File;
/**
* A simple DTF test coordinator designed to run DTF tests without requiring a web server, database or
@@ -88,10 +89,10 @@
}
public static LocalTestManager getInstance(String testdefsFile, String productConfigFile, String testnodeConfigFile) throws Exception {
- TestDefinitionRepository testDefinitionRepository = new TestDefinitionRepository(new URL("file://"+testdefsFile));
- TaskDefinitionRepository taskDefinitionRepository = new TaskDefinitionRepository(new URL("file://"+testdefsFile));
+ TestDefinitionRepository testDefinitionRepository = new TestDefinitionRepository(new URL("file://"+(new File(testdefsFile).getAbsolutePath())));
+ TaskDefinitionRepository taskDefinitionRepository = new TaskDefinitionRepository(new URL("file://"+(new File(testdefsFile).getAbsolutePath())));
- return new LocalTestManager(testDefinitionRepository, taskDefinitionRepository, productConfigFile, "file://"+testnodeConfigFile);
+ return new LocalTestManager(testDefinitionRepository, taskDefinitionRepository, productConfigFile, "file://"+(new File(testnodeConfigFile).getAbsolutePath()));
}
public LocalTestManager(TestDefinitionRepository testDefinitionRepository, TaskDefinitionRepository taskDefinitionRepository,
16 years, 4 months
[JBoss JIRA] Created: (DTF-4) add local test node support
by Jonathan Halliday (JIRA)
add local test node support
---------------------------
Key: DTF-4
URL: https://jira.jboss.org/jira/browse/DTF-4
Project: Distributed Testing Framework
Issue Type: Feature Request
Affects Versions: 4_0_0_GA
Reporter: Jonathan Halliday
Assignee: Jonathan Halliday
Fix For: 4_1_0
We (JBossTS) have a substantial investment in DTF tests. However, running these is a complex process, involving building and deploying to a pre-configured DTF instance or installing the DTF locally on the developer's workstation, including tomcat, mysql etc. This makes running DTF tests a non-trivial task usually performed only as part of a product release cycle. It is desirable to make executing DTF tests as easy as running unit tests, to encourage their use for smoke testing and to facilitate running them as part of a nightly build / continuous integration environment such as hudson.
Although DTF has substantial capability to run cross platform tests, we use only a fraction of this in practice. For smoke testing on a developer's workstation it is necessary only to run each task in its own JVM and to detect and skip any tests that would require more than one physical node. For nightly builds, hudson's axes function may be used to run tests across all supported O/S. Other combinatorial possibilities e.g. client and server elements of the same test on different O/S are currently unutilised anyhow.
By using modified versions of TestManager and TestNode, it is feasible to construct a Java class which can ingest existing testdefs, nodeconfig and product config files and manage spawning of the JVMs for Tasks, results collation etc. without requiring any infrastructure such as mysql or tomcat. Further, by wrapping these classes in an appropriate manner it is possible to have DTF tests masquerade as JUnit tests, facilitating integration with existing JUnit tooling e.g. the JUnit ant task. This would allow DTF tests to be run from an ant build script in much the same manner as unit tests.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
16 years, 4 months
DTF SVN: r17 - in trunk/src/org/jboss/dtf/testframework: coordinator and 4 other directories.
by dtf-commits@lists.jboss.org
Author: jhalliday
Date: 2008-08-07 11:19:54 -0400 (Thu, 07 Aug 2008)
New Revision: 17
Added:
trunk/src/org/jboss/dtf/testframework/local/
trunk/src/org/jboss/dtf/testframework/local/JUnitTest.java
trunk/src/org/jboss/dtf/testframework/local/JUnitTestSuite.java
trunk/src/org/jboss/dtf/testframework/local/LocalLoggingService.java
trunk/src/org/jboss/dtf/testframework/local/LocalTestManager.java
trunk/src/org/jboss/dtf/testframework/local/LocalTestNode.java
Modified:
trunk/src/org/jboss/dtf/testframework/coordinator/Action.java
trunk/src/org/jboss/dtf/testframework/coordinator2/TestDefinition.java
trunk/src/org/jboss/dtf/testframework/coordinator2/testmanager/TestManager.java
trunk/src/org/jboss/dtf/testframework/testnode/osspecific/linux/UnitTaskRunner.java
Log:
Added local test manager for executing tests standalone. made some minor chagnes to existing classes to facilitate this. DTF-4.
Modified: trunk/src/org/jboss/dtf/testframework/coordinator/Action.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/coordinator/Action.java 2008-08-04 10:37:32 UTC (rev 16)
+++ trunk/src/org/jboss/dtf/testframework/coordinator/Action.java 2008-08-07 15:19:54 UTC (rev 17)
@@ -103,7 +103,7 @@
*/
public final int getLocationType() throws NoAssociatedData
{
- int returnValue = LOCATION_DEPENDENT;
+ int returnValue = LOCATION_INDEPENDENT; // was LOCATION_DEPENDENT
String location = getLocation();
Modified: trunk/src/org/jboss/dtf/testframework/coordinator2/TestDefinition.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/coordinator2/TestDefinition.java 2008-08-04 10:37:32 UTC (rev 16)
+++ trunk/src/org/jboss/dtf/testframework/coordinator2/TestDefinition.java 2008-08-07 15:19:54 UTC (rev 17)
@@ -296,7 +296,11 @@
}
}
- return nodesRequired;
+ if(nodesRequired == 0) {
+ nodesRequired = 1; // all tasks are flexible so can share a node.
+ }
+
+ return nodesRequired;
}
public void addOSProduct(OSProductCombination p)
Modified: trunk/src/org/jboss/dtf/testframework/coordinator2/testmanager/TestManager.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/coordinator2/testmanager/TestManager.java 2008-08-04 10:37:32 UTC (rev 16)
+++ trunk/src/org/jboss/dtf/testframework/coordinator2/testmanager/TestManager.java 2008-08-07 15:19:54 UTC (rev 17)
@@ -191,7 +191,8 @@
catch (Exception e)
{
_logger.error("ERROR - Failed to initialise test with web logging service:"+e);
- _failed = true;
+ e.printStackTrace();
+ _failed = true;
}
if ( !_failed )
Added: trunk/src/org/jboss/dtf/testframework/local/JUnitTest.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/local/JUnitTest.java (rev 0)
+++ trunk/src/org/jboss/dtf/testframework/local/JUnitTest.java 2008-08-07 15:19:54 UTC (rev 17)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ *
+ * $Id$
+ */
+package org.jboss.dtf.testframework.local;
+
+import junit.framework.TestResult;
+import org.jboss.dtf.testframework.coordinator2.TestDefinition;
+
+/**
+ * An adaptor class that turns a DTF test into a JUnit Test. Handy for integration with things
+ * that understand JUnit but not DTF. See JUnitTestSuite for most of the info.
+ *
+ * @author Jonathan Halliday (jonathan.halliday(a)redhat.com)
+ */
+public class JUnitTest implements junit.framework.Test
+{
+ LocalTestManager localTestManager;
+ TestDefinition testDefinition;
+
+ public JUnitTest(LocalTestManager localTestManager, TestDefinition testDefinition) {
+ this.localTestManager = localTestManager;
+ this.testDefinition = testDefinition;
+ }
+
+ public int countTestCases()
+ {
+ return 1;
+ }
+
+ public void run(TestResult testResult)
+ {
+ testResult.startTest(this);
+
+ try {
+ localTestManager.executeTest(testDefinition);
+ } catch(Throwable t) {
+ testResult.addError(this, t);
+ }
+
+ testResult.endTest(this);
+ }
+}
Added: trunk/src/org/jboss/dtf/testframework/local/JUnitTestSuite.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/local/JUnitTestSuite.java (rev 0)
+++ trunk/src/org/jboss/dtf/testframework/local/JUnitTestSuite.java 2008-08-07 15:19:54 UTC (rev 17)
@@ -0,0 +1,123 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ *
+ * $Id$
+ */
+package org.jboss.dtf.testframework.local;
+
+import junit.framework.TestSuite;
+import junit.framework.Test;
+import org.jboss.dtf.testframework.coordinator2.TestDefinition;
+
+import java.util.List;
+
+/**
+ * An adaptor class that allows DTF tests to be run as though they are JUnit tests, using the
+ * lightweight in-process test runner. This is handy for integration with build tools that
+ * already understand junit but not DTF. Ant is the primary example:
+ *
+ <junit printsummary="yes" haltonfailure="yes">
+
+ <sysproperty key="testdefsFile" value="/home/jhalli/IdeaProjects/jboss/jbossts_trunk/qa/testdefs/jbossts-qa-txcore-testdefs.xml"/>
+ <sysproperty key="productConfigFile" value="/home/jhalli/IdeaProjects/jboss/jbossts_trunk/qa/config/JBossTS_JTA_QA.xml"/>
+ <sysproperty key="testnodeConfigFile" value="/home/jhalli/IdeaProjects/jboss/jbossts_trunk/qa/config/nodeconfig.xml"/>
+
+ <test name="org.jboss.dtf.testframework.local.JUnitTestSuite" outfile="output"/>
+ </junit>
+ *
+ * @author Jonathan Halliday (jonathan.halliday(a)redhat.com)
+ */
+public class JUnitTestSuite extends TestSuite
+{
+ LocalTestManager localTestManager;
+
+ /*
+ * Command line invocation, such as from an ant script or terminal session.
+ *
+ * Requires 3 filepath arguments: The testdefs file to run, the product config file, the node config file.
+ * Requires 1 regexp argument: the testname pattern to match. Runs all matching tests in the testdefs file.
+ *
+ * Sample Usage: java org.jboss.dtf.testframework.local.JUnitTestSuite \
+ * /home/jhalli/IdeaProjects/jboss/jbossts_trunk/qa/testdefs/jbossts-qa-txcore-testdefs.xml \
+ * /home/jhalli/IdeaProjects/jboss/jbossts_trunk/qa/config/JBossTS_JTA_QA.xml \
+ * /home/jhalli/IdeaProjects/jboss/jbossts_trunk/qa/config/nodeconfig.xml
+ * <regexp_testname_pattern>
+ *
+ * Note that LocalTestManager may also be used in like manner, although with slightly different arguments,
+ * just to confuse the unwary.
+ *
+ */
+ public static void main(String args[])
+ {
+ junit.textui.TestRunner.run(new JUnitTestSuite(args[0], args[1], args[2], args[3]));
+ }
+
+ // The suite method is used when frameworks e.g. ant junit task, load the class.
+ // Note that we can't pass function args in the normal way, so we resort to
+ // configuring via system properties instead...
+ public static Test suite()
+ {
+ return new JUnitTestSuite();
+ }
+
+ // The no-args ctor gets its config via system properties instead.
+ public JUnitTestSuite()
+ {
+ super();
+
+ String testdefsFile = System.getProperty("testdefsFile");
+ String productConfigFile = System.getProperty("productConfigFile");
+ String testnodeConfigFile = System.getProperty("testnodeConfigFile");
+ String testnamePattern = System.getProperty("testnamePattern");
+
+ setup(testdefsFile, productConfigFile, testnodeConfigFile, testnamePattern);
+ }
+
+ public JUnitTestSuite(String testdefsFile, String productConfigFile, String testnodeConfigFile, String testnamePattern)
+ {
+ super();
+
+ setup(testdefsFile, productConfigFile, testnodeConfigFile, testnamePattern);
+ }
+
+ private void setup(String testdefsFile, String productConfigFile, String testnodeConfigFile, String testnamePattern)
+ {
+ try
+ {
+ localTestManager = LocalTestManager.getInstance(testdefsFile, productConfigFile, testnodeConfigFile);
+ List<TestDefinition> testDefs = localTestManager.getSingleNodeTestsDefs();
+ for (TestDefinition testDefinition : testDefs)
+ {
+ if(testnamePattern == null || testDefinition.getId().matches(testnamePattern)) {
+ addTest(new JUnitTest(localTestManager, testDefinition));
+ } else {
+ System.out.println("skipping non-matched test "+testDefinition.getId());
+ }
+ }
+ System.out.println("Number of tests to run "+this.testCount());
+ }
+ catch (Exception e)
+ {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+
+}
\ No newline at end of file
Added: trunk/src/org/jboss/dtf/testframework/local/LocalLoggingService.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/local/LocalLoggingService.java (rev 0)
+++ trunk/src/org/jboss/dtf/testframework/local/LocalLoggingService.java 2008-08-07 15:19:54 UTC (rev 17)
@@ -0,0 +1,153 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ *
+ * $Id$
+ */
+package org.jboss.dtf.testframework.local;
+
+import org.jboss.dtf.testframework.utils.logging.LoggingService;
+import org.jboss.dtf.testframework.utils.logging.exception.LoggingServiceException;
+import org.jboss.dtf.testframework.testnode.RunUID;
+
+/**
+ * A lightweight logger for the in-process version of the DTF. Most methods do nothing as they are never called.
+ * For the most part this class exists only to pass on test outcome notifications to the LocalTestManager.
+ * Note that whilst this logging approach is fine for JavaTaskRunner it will fail for UnitTaskRunner since it's
+ * not got a listener for remote connections.
+ *
+ * @author Jonathan Halliday (jonathan.halliday(a)redhat.com)
+ */
+public class LocalLoggingService implements LoggingService
+{
+ private static LocalTestManager localTestManager;
+
+ private static final Object taskCountLock = new Object();
+ private static int taskCount;
+
+ public static LocalTestManager getLocalTestManager() {
+ return localTestManager;
+ }
+
+ public static void setLocalTestManager(LocalTestManager testManager) {
+ localTestManager = testManager;
+ }
+
+ public static int getTaskCount() {
+ synchronized (taskCountLock) {
+ return taskCount;
+ }
+ }
+
+ public static void resetTraskCount() {
+ synchronized (taskCountLock) {
+ taskCount = 0;
+ }
+ }
+
+ /////////////
+
+ public LocalLoggingService() {
+ }
+
+ public void initialise(String loggerURL) throws LoggingServiceException
+ {
+ // System.out.println("LocalLoggingService.initialise");
+ }
+
+ public RunUID initiateTestRun(String testDefinitionURL, String testSelectionURL, String softwareVersion, String distributionList) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.initiateTestRun");
+ return null;
+ }
+
+ public RunUID initiateTestRun(String softwareVersion, String distributionList) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.initiateTestRun");
+ return null;
+ }
+
+ public boolean testRunComplete(RunUID runUID) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.testRunComplete");
+ return false;
+ }
+
+ public boolean logResult(String result, String taskName, String testName, RunUID runUID, String taskPermutationCode, String testPermutationCode) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.logResult: "+result+" from "+testName+" "+taskName);
+
+ synchronized(taskCountLock) {
+ taskCount--;
+ }
+
+ if(localTestManager != null) {
+ localTestManager.logTaskResult(testName, taskName, result);
+ }
+
+ return false;
+ }
+
+ public boolean logTestRunInformation(String information, String taskName, String testName, RunUID runUID, String taskPermutationCode, String testPermutationCode) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.logTestRunInformation");
+ return false;
+ }
+
+ public boolean logInformation(String information, String taskName, String testName, RunUID runUID, String taskPermutationCode, String testPermutationCode) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.logInformation");
+ return false;
+ }
+
+ public boolean initiateTest(String testName, RunUID runUID, String permutationCode, int numberOfTasks) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.initiateTest");
+ return false;
+ }
+
+ public boolean logTestInformation(String testName, RunUID runUID, String permutationCode, String information) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.logTestInformation");
+ return false;
+ }
+
+ public boolean initiateTask(String testName, RunUID runUID, String taskName, String taskPermutationCode, String testPermutationCode) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.initiateTask: "+testName+" "+runUID+" "+taskName+" "+taskPermutationCode+" "+testPermutationCode);
+
+ synchronized(taskCountLock) {
+ taskCount++;
+ }
+
+ return false;
+ }
+
+ public boolean testComplete(String testName, RunUID runUID, String permutationCode) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.testComplete");
+ return false;
+ }
+
+ public boolean logTimeout(String testName, RunUID runUID, String permutationCode) throws LoggingServiceException
+ {
+ System.out.println("LocalLoggingService.logTimeout");
+ return false;
+ }
+}
\ No newline at end of file
Added: trunk/src/org/jboss/dtf/testframework/local/LocalTestManager.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/local/LocalTestManager.java (rev 0)
+++ trunk/src/org/jboss/dtf/testframework/local/LocalTestManager.java 2008-08-07 15:19:54 UTC (rev 17)
@@ -0,0 +1,230 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ *
+ * $Id$
+ */
+package org.jboss.dtf.testframework.local;
+
+import org.jboss.dtf.testframework.coordinator2.TestDefinition;
+import org.jboss.dtf.testframework.coordinator2.TaskDefinition;
+import org.jboss.dtf.testframework.coordinator2.TaskDefinitionRepository;
+import org.jboss.dtf.testframework.coordinator2.TestDefinitionRepository;
+import org.jboss.dtf.testframework.coordinator.*;
+
+import java.net.URL;
+import java.util.*;
+
+/**
+ * A simple DTF test coordinator designed to run DTF tests without requiring a web server, database or
+ * other overheads. It will create an in-process TestNode, so won't run any tests requring more than
+ * one node. It still spawns the test runners as separate processes though.
+ *
+ * We aim to reuse as much unaltered DTF code as possible, as a result of which we have to jump through
+ * a few unweildy hoops to deal with DTF design issues.
+ *
+ * @author Jonathan Halliday (jonathan.halliday(a)redhat.com)
+ */
+public class LocalTestManager
+{
+ private TestDefinitionRepository _testDefinitionRepository;
+ private TaskDefinitionRepository _taskDefinitionRepository;
+ private LocalTestNode _testNode;
+ private int expectedPasses;
+
+ /**
+ * Command line invocation, such as from an ant script or terminal session.
+ *
+ * Requires 3 arguments: The testdefs file to run (URL), the product config file (filepath), the node config file (URL).
+ * Not the most user friendly API, but the one that maps most directly to the way DTF works. This will run all the tests
+ * in the test defs file, on the product given by the product config, using the environment from the node config.
+ *
+ * Sample Usage: java org.jboss.dtf.testframework.local.LocalTestManager \
+ * file:///home/jhalli/IdeaProjects/jboss/jbossts_trunk/qa/testdefs/jbossts-qa-txcore-testdefs.xml \
+ * /home/jhalli/IdeaProjects/jboss/jbossts_trunk/qa/config/JBossTS_JTA_QA.xml \
+ * file:///home/jhalli/IdeaProjects/jboss/jbossts_trunk/qa/config/nodeconfig.xml
+ *
+ * Note that JUnitTestSuite may also be used in like manner, although with slightly different arguments, just to confuse the unwary.
+ *
+ * @param args
+ * @throws Exception
+ */
+ public static void main(String[] args) throws Exception {
+
+ TestDefinitionRepository testDefinitionRepository = new TestDefinitionRepository(new URL(args[0]));
+ TaskDefinitionRepository taskDefinitionRepository = new TaskDefinitionRepository(new URL(args[0]));
+ testDefinitionRepository.verifyRepository(taskDefinitionRepository);
+
+ LocalTestManager test = new LocalTestManager(testDefinitionRepository, taskDefinitionRepository, args[1], args[2]);
+ try {
+ test.runAllTests();
+ } catch(Exception e) {
+ System.out.println("cleaning up...");
+ test = null;
+ System.gc();
+ System.runFinalization();
+ // System.exit(1);
+ // Note that a RMI issue can cause the JVM not to exit properly here in some cases.
+ // probably because we reuse RMI classes but use them locally, so the RMI lifecycle
+ // may not be properly managed. More investigation is needed.
+ throw e;
+ }
+ }
+
+ public static LocalTestManager getInstance(String testdefsFile, String productConfigFile, String testnodeConfigFile) throws Exception {
+ TestDefinitionRepository testDefinitionRepository = new TestDefinitionRepository(new URL("file://"+testdefsFile));
+ TaskDefinitionRepository taskDefinitionRepository = new TaskDefinitionRepository(new URL("file://"+testdefsFile));
+
+ return new LocalTestManager(testDefinitionRepository, taskDefinitionRepository, productConfigFile, "file://"+testnodeConfigFile);
+ }
+
+ public LocalTestManager(TestDefinitionRepository testDefinitionRepository, TaskDefinitionRepository taskDefinitionRepository,
+ String productConfigurationFileName, String testNodeConfigURL) throws Exception
+ {
+ _testDefinitionRepository = testDefinitionRepository;
+ _taskDefinitionRepository = taskDefinitionRepository;
+
+ // Kludge warning: the logging framework loads plugin using Class.forName, so we can't cleanly configure an
+ // instance and pass it in. Thus we use a nasty hack involving static field here...
+ System.setProperty("org.jboss.dtf.testframework.logging.plugin", "org.jboss.dtf.testframework.local.LocalLoggingService");
+ LocalLoggingService.setLocalTestManager(this);
+
+ _testNode = new LocalTestNode(new URL(testNodeConfigURL), productConfigurationFileName);
+ }
+
+ // used by the JUnit integration classes.
+ public List<TestDefinition> getSingleNodeTestsDefs() {
+ Map<String, TestDefinition> testIDs2testDefs = _testDefinitionRepository.getTestDefinitionsMap();
+ List<TestDefinition> testDefs = new LinkedList<TestDefinition>();
+ for(Map.Entry<String,TestDefinition> entry : testIDs2testDefs.entrySet()) {
+ TestDefinition testDefinition = entry.getValue();
+ if(testDefinition.getNumberOfNodesRequired() == 1) {
+ testDefs.add(testDefinition);
+ } else {
+ System.out.println("skipping "+testDefinition.getNumberOfNodesRequired());
+ }
+ }
+ return testDefs;
+ }
+
+ public void runAllTests() throws Exception {
+ Map<String, TestDefinition> testIDs2testDefs = _testDefinitionRepository.getTestDefinitionsMap();
+ for(Map.Entry<String,TestDefinition> entry : testIDs2testDefs.entrySet()) {
+ TestDefinition testDefinition = entry.getValue();
+ executeTest(testDefinition);
+ }
+ }
+
+ /**
+ * Run the given test. If this returns normally rather than throwing an exception,
+ * the test can be assumed to have passed, or at least not actually failed. Probably.
+ * I mean, it's not like this is an exact science or anything :-)
+ *
+ *
+ *
+ * @param testDefinition
+ * @throws Exception
+ */
+ public void executeTest(TestDefinition testDefinition) throws Exception {
+ if(testDefinition == null) {
+ throw new IllegalArgumentException("testDefinition must not be null!");
+ }
+
+ if(testDefinition.getNumberOfNodesRequired() != 1) {
+ System.err.println("Unsupported node count "+testDefinition.getNumberOfNodesRequired()+" for test "+testDefinition.getDescription()+", skipping it");
+ return;
+ }
+
+ ArrayList<Action> actionList = testDefinition.getActionList();
+
+ synchronized(this) {
+ expectedPasses = 0;
+ }
+
+ for(Action action : actionList) {
+
+ TaskDefinition taskDefinition = null;
+ if(action.getType() == Action.PERFORM_TASK || action.getType() == Action.START_TASK) {
+ String groupId = testDefinition.getGroupId();
+ String taskIdToPerform = action.getAssociatedTaskId();
+ taskDefinition = _taskDefinitionRepository.getTaskDefinition(groupId, taskIdToPerform);
+ if (taskDefinition == null)
+ {
+ taskDefinition = _taskDefinitionRepository.getTaskDefinition(taskIdToPerform);
+ }
+ }
+
+ // for each task we start, we expect to recieve a notification that it passed. We keep count
+ // of the number of such notifications outstanding and get upset if it's non-zero at the end.
+
+ switch(action.getType()) {
+ case Action.PERFORM_TASK:
+ System.out.println("PERFORM_TASK "+new Date().toString());
+ _testNode.performTask(testDefinition, taskDefinition, action);
+ synchronized (this) {
+ expectedPasses+=1;
+ }
+ break;
+ case Action.START_TASK:
+ System.out.println("START_TASK "+new Date().toString());
+ _testNode.startTask(testDefinition, taskDefinition, action);
+ synchronized (this) {
+ expectedPasses+=1;
+ }
+ break;
+ case Action.TERMINATE_TASK:
+ System.out.println("TERMINATE_TASK "+new Date().toString());
+ _testNode.terminateTask(action);
+ break;
+ case Action.WAIT_FOR_TASK:
+ System.out.println("WAIT_FOR_TASK "+new Date().toString());
+ _testNode.waitForTask(action);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown Action type "+action.getType());
+ }
+ }
+
+ // make sure the termination state is sane...
+
+ if(_testNode.isActive()) {
+ throw new IllegalStateException("Testnode is active when it should not be!");
+ }
+
+ if(LocalLoggingService.getTaskCount() != 0) {
+ LocalLoggingService.resetTraskCount();
+ throw new IllegalStateException("TaskCount is not zero when it should be!");
+ }
+
+ if(expectedPasses != 0) {
+ throw new Exception("Test failed! "+testDefinition.getId()+" got "+expectedPasses+" fewer task passes than expected");
+ }
+ }
+
+ // the logger calls back into us using this function...
+ public void logTaskResult(String testName, String taskName, String result) {
+
+ if("Passed".equals(result)) {
+ synchronized (this) {
+ expectedPasses-=1;
+ }
+ }
+ }
+
+}
Added: trunk/src/org/jboss/dtf/testframework/local/LocalTestNode.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/local/LocalTestNode.java (rev 0)
+++ trunk/src/org/jboss/dtf/testframework/local/LocalTestNode.java 2008-08-07 15:19:54 UTC (rev 17)
@@ -0,0 +1,595 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ *
+ * $Id$
+ */
+package org.jboss.dtf.testframework.local;
+
+import org.jboss.dtf.testframework.testnode.*;
+import org.jboss.dtf.testframework.coordinator.UnsupportedProduct;
+import org.jboss.dtf.testframework.coordinator.Action;
+import org.jboss.dtf.testframework.coordinator.NoAssociatedData;
+import org.jboss.dtf.testframework.utils.*;
+import org.jboss.dtf.testframework.productrepository.TaskRunnerConfiguration;
+import org.jboss.dtf.testframework.productrepository.NodeConfiguration;
+import org.jboss.dtf.testframework.productrepository.ProductConfiguration;
+import org.jboss.dtf.testframework.coordinator2.TestDefinition;
+import org.jboss.dtf.testframework.coordinator2.TaskDefinition;
+import org.jdom.input.SAXBuilder;
+import org.jdom.Document;
+import org.jdom.Element;
+
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.HashMap;
+import java.io.IOException;
+import java.io.File;
+import java.net.URL;
+
+/**
+ * A modified version of the DTF TestNode, redesigned to run in-process rather than as a remote slave.
+ *
+ * Many methods do nothing, since they are never called. The implementation of the rest is stolen from
+ * the real TestNode code and stripped down by throwing out irrelevant things like the permutation codes.
+ *
+ * @author Jonathan Halliday (jonathan.halliday(a)redhat.com)
+ */
+public class LocalTestNode extends UnicastRemoteObject implements TestNodeInterface
+{
+ private final static String TEST_NODE_NAME = "name";
+ private final static String TEST_NODE_OS_ID = "os";
+
+ private final static String TASK_RUNNER_DEFINITIONS_ELEMENT = "task-runner-definitions";
+ private final static String TASK_RUNNER_ELEMENT = "task-runner";
+ private final static String TASK_RUNNER_NAME_ATTRIBUTE = "name";
+ private final static String TASK_RUNNER_CLASS_ATTRIBUTE = "class";
+ private final static String TASK_RUNNER_LOG_TO_ATTRIBUTE = "log-to";
+ private final static String TASK_RUNNER_PARAM_ELEMENT = "param";
+ private final static String TASK_RUNNER_PARAM_NAME_ATTRIBUTE = "name";
+ private final static String TASK_RUNNER_PARAM_VALUE_ATTRIBUTE = "value";
+
+ private final static String JVM_DEFINITIONS_ELEMENT = "jvm-definitions";
+ private final static String JVM_ELEMENT = "jvm";
+ private final static String VERSION_ATTRIBUTE = "version";
+ private final static String JAVA_HOME_ATTRIBUTE = "java-home";
+ private final static String DEFAULT_ATTRIBUTE = "default";
+
+ private String _osId = null;
+ private String _nodeName = "";
+ private Hashtable _jvms = new Hashtable();
+ private String _defaultJvmId = null;
+ private Hashtable _taskRunners = new Hashtable();
+ private ProductConfiguration _productConfiguration = null;
+
+ private static short _testIdCounter = 0;
+
+ private final HashMap<String, TaskRunner> _activeTaskList = new HashMap<String, TaskRunner>();
+
+ public LocalTestNode(URL configFile, String productConfigurationFileName) throws Exception {
+ super();
+ parseTestNodeConfig(configFile);
+ _productConfiguration = ProductConfiguration.deserializeXML(new File(productConfigurationFileName));
+ }
+
+ public String getName() throws RemoteException
+ {
+ return _nodeName;
+ }
+
+ public String getHostAddress() throws RemoteException
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean ping() throws RemoteException
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public int performTask(String s, Hashtable hashtable, String s1, String s2, String s3, String[] strings, String[] strings1, String s4, int i, TaskIdInterface taskIdInterface, RunUID runUID, String s5, String s6) throws RemoteException, TestNodeBusy, UnsupportedProduct, TaskRunnerNotSupported
+ {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void runTask(String s, Hashtable hashtable, String s1, String s2, String s3, String[] strings, String[] strings1, String s4, int i, int i1, TaskResultListener taskResultListener, TaskIdInterface taskIdInterface, RunUID runUID, String s5, String s6) throws RemoteException, TestNodeBusy, UnsupportedProduct, TaskRunnerNotSupported
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void terminateTask(TaskIdInterface taskIdInterface, String s) throws RemoteException, NoSuchTaskId
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean terminateAllTasks() throws RemoteException
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean updateSoftware() throws RemoteException, TestNodeBusy
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean updateSoftware(String productName, boolean deploySoftware) throws RemoteException
+ {
+ return false; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void shutdown(boolean restart, boolean onComplete) throws RemoteException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public TaskIdInterface generateTaskId(String taskName) throws RemoteException, TestNodeBusy
+ {
+ TaskIdInterface taskId = new TaskId();
+ synchronized(LocalTestNode.class) {
+ _testIdCounter += 1;
+ taskId.setTestId( _testIdCounter );
+ }
+ return taskId;
+ }
+
+ public void initiateTest(String s, TaskIdInterface taskIdInterface) throws RemoteException, TestNodeBusy
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void testFinished(String s, TaskIdInterface taskIdInterface, String s1) throws RemoteException, TasksStillRunning
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public void waitForTask(TaskIdInterface taskIdInterface) throws RemoteException, NoSuchTaskId, InterruptedException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public String[] getActiveTaskList() throws RemoteException
+ {
+ return new String[0]; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public TestNodeDescription getNodeDescription() throws RemoteException
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public RemoteFileReaderInterface getDeployLogOutput(String productName, boolean outOrErr) throws IOException, RemoteException
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ ////////////////
+
+ public int performTask(TestDefinition testDefinition, TaskDefinition taskDefinition, Action action) throws Exception
+ {
+ String[] parameters = getParameters(action, taskDefinition, testDefinition.getNamesRequired());
+ String[] jvmParameters = getJVMParameters(action, taskDefinition, testDefinition.getNamesRequired());
+ String runtimeTaskId = action.getAssociatedRuntimeTaskId();
+
+ // Get the test level runner parameters
+ Hashtable runnerParameters = testDefinition.getParametersForRunner(taskDefinition.getRunner());
+ // If there are task level runner parameters override the test level parameters
+ if (taskDefinition.getRunnerParameters() != null)
+ {
+ runnerParameters = taskDefinition.getRunnerParameters();
+ }
+
+ TaskRunner taskRunner = getTaskRunner(runnerParameters,
+ taskDefinition.getRunner(),
+ testDefinition.getId(),
+ taskDefinition.getClassName(),
+ taskDefinition.getClasspath(),
+ taskDefinition.getId(),
+ parameters,
+ jvmParameters,
+ TestNodeInterface.WAIT_NONE,
+ taskDefinition.getTimeout(),
+ "productName",
+ this.generateTaskId( taskDefinition.getId() ), // TaskIDInterface
+ this, // TestNode
+ new RunUID(0), // RunUID
+ "taskPermutationCode",
+ "testPermutationCode");
+
+
+ synchronized(_activeTaskList)
+ {
+ _activeTaskList.put(runtimeTaskId, taskRunner);
+ }
+
+ taskRunner.start();
+
+ // the TestNode starts the TaskRunner, and then uses a method of the TaskRunner
+ // to wait and check for timeout. (i.e. performTask() is synchronous)
+
+ if (!taskRunner.hasFinished() && taskRunner.waitForReadyOrFinished())
+ {
+ terminateTask(action);
+ return RESULT_TIMEOUT;
+ } else
+ {
+ waitForTask(action);
+ return RESULT_READY;
+ }
+ }
+
+ public void startTask(TestDefinition testDefinition, TaskDefinition taskDefinition, Action action) throws Exception
+ {
+ String[] parameters = getParameters(action, taskDefinition, testDefinition.getNamesRequired());
+ String[] jvmParameters = getJVMParameters(action, taskDefinition, testDefinition.getNamesRequired());
+ String runtimeTaskId = action.getAssociatedRuntimeTaskId();
+
+ // Get the test level runner parameters
+ Hashtable runnerParameters = testDefinition.getParametersForRunner(taskDefinition.getRunner());
+ // If there are task level runner parameters override the test level parameters
+ if (taskDefinition.getRunnerParameters() != null)
+ {
+ runnerParameters = taskDefinition.getRunnerParameters();
+ }
+
+ TaskRunner taskRunner = getTaskRunner(runnerParameters,
+ taskDefinition.getRunner(),
+ testDefinition.getId(),
+ taskDefinition.getClassName(),
+ taskDefinition.getClasspath(),
+ taskDefinition.getId(),
+ parameters,
+ jvmParameters,
+ taskDefinition.getType(),
+ taskDefinition.getTimeout(),
+ "productName",
+ this.generateTaskId( taskDefinition.getId() ), // TaskIDInterface
+ this, // TestNode
+ new RunUID(0), // RunUID
+ "taskPermutationCode",
+ "testPermutationCode");
+
+ synchronized(_activeTaskList)
+ {
+ _activeTaskList.put(runtimeTaskId, taskRunner);
+ }
+
+ taskRunner.start();
+
+ if ( taskDefinition.getType() == TaskDefinition.EXPECT_READY )
+ {
+ taskRunner.waitForReadyOrFinished();
+ }
+ }
+
+ public void waitForTask(Action action) throws NoAssociatedData, NoSuchTaskId, InterruptedException
+ {
+ String runtimeTaskId = action.getAssociatedRuntimeTaskId();
+ TaskRunner taskRunner;
+
+ synchronized(_activeTaskList)
+ {
+ taskRunner = _activeTaskList.get(runtimeTaskId);
+ }
+
+ if (taskRunner == null)
+ {
+ throw new NoSuchTaskId();
+ }
+ else
+ {
+ taskRunner.waitFor();
+ synchronized (_activeTaskList) {
+ _activeTaskList.remove(runtimeTaskId);
+ }
+ }
+ }
+
+ public void terminateTask(Action action) throws NoAssociatedData
+ {
+ String runtimeTaskId = action.getAssociatedRuntimeTaskId();
+ TaskRunner runner = null;
+
+ synchronized(_activeTaskList)
+ {
+ runner = _activeTaskList.get(runtimeTaskId);
+ }
+
+ if (runner != null)
+ {
+ runner.terminate();
+ synchronized (_activeTaskList) {
+ _activeTaskList.remove(runtimeTaskId);
+ }
+ }
+ }
+
+ public boolean isActive() {
+ synchronized (_activeTaskList) {
+ return !_activeTaskList.isEmpty();
+ }
+ }
+
+ private String[] getJVMParameters(Action action, TaskDefinition taskDefinition, int uniqNameCount)
+ throws NoAssociatedData
+ {
+ String[] jvmParameters = taskDefinition.getJVMParameters();
+ long parameterSettings = taskDefinition.getParameterSettings();
+
+ if ( ( ( parameterSettings & TaskDefinition.OVERRIDE_JVM_PARAMETERS ) != 0 ) && ( action.getJVMParameterList().length > 0 ) )
+ {
+ jvmParameters = action.getJVMParameterList();
+ }
+ if ( ( parameterSettings & TaskDefinition.PREPEND_JVM_PARAMETERS ) != 0 )
+ {
+ jvmParameters = ArrayUtils.prependArray(jvmParameters, action.getJVMParameterList());
+ }
+ if ( ( parameterSettings & TaskDefinition.APPEND_JVM_PARAMETERS ) != 0 )
+ {
+ jvmParameters = ArrayUtils.appendArray(jvmParameters, action.getJVMParameterList());
+ }
+ for (int paramCount=0;paramCount<jvmParameters.length;paramCount++)
+ {
+ jvmParameters[paramCount] = ParameterPreprocessor.preprocessParameters(jvmParameters[paramCount], false);
+ }
+
+ StringPreprocessor pre = new StringPreprocessor();
+ for (int nameCount=0;nameCount<uniqNameCount;nameCount++)
+ {
+ pre.addReplacement( ""+(nameCount+1), "value_"+(nameCount+1) );
+ }
+
+ if (jvmParameters!=null)
+ {
+ jvmParameters = pre.preprocessParameters(jvmParameters, false);
+
+ jvmParameters = ParameterPreprocessor.preprocessParameters(jvmParameters, false);
+ }
+
+ return jvmParameters;
+ }
+
+ private String[] getParameters(Action action, TaskDefinition taskDefinition, int uniqNameCount)
+ throws NoAssociatedData
+ {
+ String[] parameters = taskDefinition.getParameters();
+ long parameterSettings = taskDefinition.getParameterSettings();
+
+ if ( ( ( parameterSettings & TaskDefinition.OVERRIDE_PARAMETERS ) != 0 ) && ( action.getParameterList().length > 0 ) )
+ {
+ parameters = action.getParameterList();
+ }
+ if ( ( parameterSettings & TaskDefinition.PREPEND_PARAMETERS ) != 0 )
+ {
+ parameters = ArrayUtils.prependArray(parameters, action.getParameterList());
+ }
+ if ( ( parameterSettings & TaskDefinition.APPEND_PARAMETERS ) != 0 )
+ {
+ parameters = ArrayUtils.appendArray(parameters, action.getParameterList());
+ }
+ for (int paramCount=0;paramCount<parameters.length;paramCount++)
+ {
+ parameters[paramCount] = ParameterPreprocessor.preprocessParameters(parameters[paramCount], false);
+ }
+
+ StringPreprocessor pre = new StringPreprocessor();
+ for (int nameCount=0;nameCount<uniqNameCount;nameCount++)
+ {
+ pre.addReplacement( ""+(nameCount+1), "value_"+(nameCount+1) );
+ }
+
+ // If there are parameters to be passed from the test definition do so
+ if (parameters!=null)
+ {
+ parameters = pre.preprocessParameters(parameters, false);
+ parameters = ParameterPreprocessor.preprocessParameters(parameters, false);
+ }
+
+ return parameters;
+ }
+
+ private TaskRunner getTaskRunner( Hashtable runnerParameters,
+ String type,
+ String testId,
+ String className,
+ String classpathRef,
+ String taskName,
+ String[] parameters,
+ String[] jvmParameters,
+ int testType,
+ int timeoutValue,
+ String productName,
+ TaskIdInterface taskId, // generated by Coordinator side
+ TestNodeInterface associatedTestNode, // this TestNode
+ RunUID runId,
+ String taskPermutationCode,
+ String testPermutationCode) throws TaskRunnerNotSupported
+ {
+ TaskRunner runner = null;
+ TaskRunnerConfiguration info = null;
+
+ try
+ {
+ /** First check the local task runner definitions, use that if one exists **/
+ info = (TaskRunnerConfiguration)_taskRunners.get(type);
+
+ /** If it doesn't exist then check the product configuration **/
+ if (info == null)
+ {
+ info = _productConfiguration.getTaskRunnerConfiguration(type);
+
+ /** If it doesn't exist in the product configuration then we have problems **/
+ if ( info == null )
+ {
+ System.err.println("Task runner "+type+" is not supported by this TestNode");
+ throw new TaskRunnerNotSupported("Task runner "+type+" is not supported by this TestNode");
+ }
+ }
+
+ runner = (TaskRunner)Class.forName(info.getClassname()).newInstance();
+
+ /**
+ * Combine the runner parameters passed from the invocation
+ * with those configured in the test node configuration file
+ */
+ Hashtable combinedRunnerParameters = new Hashtable(info.getParameters());
+
+ if (runnerParameters != null)
+ {
+ combinedRunnerParameters.putAll(runnerParameters);
+ }
+
+ StringPreprocessor pre = new StringPreprocessor();
+
+ NodeConfiguration nodeConfig = _productConfiguration.getNodeConfiguration(_osId);
+
+ /**
+ * If the java home parameter isn't set then set it to the one specified from the coordinator
+ */
+ if ( !combinedRunnerParameters.containsKey(TaskRunner.JAVA_HOME_DIRECTORY_PARAMETER) )
+ {
+ String jvmId = nodeConfig.getJvmId();
+
+ /** If the jvm id has not been configured use the default for the testnode **/
+ if ( ( jvmId == null ) || ( jvmId.length() == 0 ) )
+ {
+ jvmId = _defaultJvmId;
+ }
+
+ //System.out.println("Using jvm id '"+jvmId+"'");
+
+ if ( _jvms.containsKey(jvmId) )
+ {
+ combinedRunnerParameters.put(TaskRunner.JAVA_HOME_DIRECTORY_PARAMETER, _jvms.get(jvmId));
+ }
+ else
+ {
+ throw new TaskRunnerNotSupported("The jvm '"+nodeConfig.getJvmId()+"' is not supported by this testnode");
+ }
+ }
+
+ /** Use the default classpath if none is specified **/
+ String classpathName = (classpathRef == null) ? nodeConfig.getDefaultClasspath() : classpathRef;
+
+ pre.addReplacements(nodeConfig.getPreprocessedSets());
+ String classpath = _productConfiguration.getClasspath( classpathName );
+
+ if ( classpath != null )
+ {
+ pre.addReplacement("CLASSPATH", classpath);
+ }
+
+ parameters = pre.preprocessParameters(parameters);
+ jvmParameters = pre.preprocessParameters(jvmParameters);
+
+ runner.initialise(combinedRunnerParameters, testId, className, classpathRef, taskName, parameters,
+ jvmParameters, testType, timeoutValue, _productConfiguration, nodeConfig, taskId, null, associatedTestNode,
+ runId, taskPermutationCode, testPermutationCode, info.getLogTo(), new ServiceUtils(""));
+ }
+ catch (TaskRunnerNotSupported e)
+ {
+ throw e;
+ }
+ catch (java.lang.Exception e)
+ {
+ System.err.println("ERROR - Cannot create an instance of the task runner '"+info.getClassname()+"'");
+ throw new TaskRunnerNotSupported("Problem in test runner setup: "+e);
+ }
+ return(runner);
+ }
+
+ private void parseTestNodeConfig(URL configFile)
+ {
+ try
+ {
+ SAXBuilder xmlBuilder = new SAXBuilder();
+ Document doc = xmlBuilder.build(configFile);
+
+ // Retrieve root element, then retrieve the test node configuration element
+ Element root = doc.getRootElement();
+ Element testNodeRootElement = root;
+
+ _nodeName = testNodeRootElement.getAttributeValue(TEST_NODE_NAME);
+ _osId = testNodeRootElement.getAttributeValue(TEST_NODE_OS_ID);
+
+ if (_osId == null)
+ {
+ System.err.println("No operating system id. specified - this is required");
+ System.exit(1);
+ }
+
+ Element taskRunnerDefinitions = root.getChild(TASK_RUNNER_DEFINITIONS_ELEMENT);
+ List taskRunnerElements = taskRunnerDefinitions.getChildren(TASK_RUNNER_ELEMENT);
+
+ for (int taskRunnerCount = 0; taskRunnerCount < taskRunnerElements.size(); taskRunnerCount++)
+ {
+ Element taskRunnerElement = (Element) taskRunnerElements.get(taskRunnerCount);
+
+ if (taskRunnerElement != null)
+ {
+ TaskRunnerConfiguration newTaskRunner = new TaskRunnerConfiguration();
+ String name = taskRunnerElement.getAttributeValue(TASK_RUNNER_NAME_ATTRIBUTE);
+ String taskRunnerClass = taskRunnerElement.getAttributeValue(TASK_RUNNER_CLASS_ATTRIBUTE);
+ String loggingResource = taskRunnerElement.getAttributeValue(TASK_RUNNER_LOG_TO_ATTRIBUTE);
+
+ newTaskRunner.setClassname(taskRunnerClass);
+ newTaskRunner.setLogTo(loggingResource);
+
+ List taskRunnerParameterList = taskRunnerElement.getChildren(TASK_RUNNER_PARAM_ELEMENT);
+ for (int count = 0; count < taskRunnerParameterList.size(); count++)
+ {
+ Element parameter = (Element) taskRunnerParameterList.get(count);
+
+ newTaskRunner.setParameter(parameter.getAttributeValue(TASK_RUNNER_PARAM_NAME_ATTRIBUTE),
+ parameter.getAttributeValue(TASK_RUNNER_PARAM_VALUE_ATTRIBUTE));
+ }
+
+ _taskRunners.put(name, newTaskRunner);
+ }
+ }
+
+ /** Get jvm-definitions element **/
+ Element jvmDefinitionsElement = root.getChild(JVM_DEFINITIONS_ELEMENT);
+
+ _defaultJvmId = jvmDefinitionsElement.getAttributeValue(DEFAULT_ATTRIBUTE);
+
+ if (_defaultJvmId == null)
+ {
+ System.err.println("default jvm-definitions node configuration not specified!");
+ System.exit(1);
+ }
+
+ /** Get the jvm elements **/
+ List jvmDefinitionElements = jvmDefinitionsElement.getChildren(JVM_ELEMENT);
+
+ for (int count = 0; count < jvmDefinitionElements.size(); count++)
+ {
+ Element jvmDefinitionElement = (Element) jvmDefinitionElements.get(count);
+
+ _jvms.put(jvmDefinitionElement.getAttributeValue(VERSION_ATTRIBUTE), jvmDefinitionElement.getAttributeValue(JAVA_HOME_ATTRIBUTE));
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/src/org/jboss/dtf/testframework/testnode/osspecific/linux/UnitTaskRunner.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/testnode/osspecific/linux/UnitTaskRunner.java 2008-08-04 10:37:32 UTC (rev 16)
+++ trunk/src/org/jboss/dtf/testframework/testnode/osspecific/linux/UnitTaskRunner.java 2008-08-07 15:19:54 UTC (rev 17)
@@ -83,7 +83,7 @@
File javaBinDir = new File(_javaHome, "bin");
File javaExe = new File(javaBinDir, "java");
- NodeConfiguration nodeConfig = _productConfig.getNodeConfiguration(TestNode.getOSId());
+ NodeConfiguration nodeConfig = _productConfig.getNodeConfiguration(_nodeConfig.getOs()); // TestNode.getOSId()
StringPreprocessor pre = new StringPreprocessor();
pre.addReplacements(nodeConfig.getPreprocessedSets());
16 years, 4 months
DTF SVN: r16 - trunk/src/org/jboss/dtf/testframework/testnode.
by dtf-commits@lists.jboss.org
Author: mmusgrov
Date: 2008-08-04 06:37:32 -0400 (Mon, 04 Aug 2008)
New Revision: 16
Added:
trunk/src/org/jboss/dtf/testframework/testnode/AntTaskRunner.java
Modified:
trunk/src/org/jboss/dtf/testframework/testnode/JavaTaskRunner.java
trunk/src/org/jboss/dtf/testframework/testnode/TaskRunner.java
Log:
Updates unclude a new task runner for executing ant scripts.
Changes required for resolving JIRA JBTM-360
A testnode/AntTaskRunner.java
M testnode/TaskRunner.java
M testnode/JavaTaskRunner.java
Added: trunk/src/org/jboss/dtf/testframework/testnode/AntTaskRunner.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/testnode/AntTaskRunner.java (rev 0)
+++ trunk/src/org/jboss/dtf/testframework/testnode/AntTaskRunner.java 2008-08-04 10:37:32 UTC (rev 16)
@@ -0,0 +1,253 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ */
+
+// change this package
+package org.jboss.dtf.testframework.testnode ;
+
+import org.apache.tools.ant.BuildException ;
+import org.apache.tools.ant.Project ;
+import org.apache.tools.ant.ProjectHelper ;
+import org.apache.tools.ant.DefaultLogger ;
+import org.jboss.dtf.testframework.utils.logging.exception.LoggingServiceException;
+
+import java.io.File ;
+import java.util.Vector ;
+import java.util.Collection;
+import java.util.ArrayList;
+
+public class AntTaskRunner extends TaskRunner
+{
+ public final static String PRODUCT_DIR_PROP = "product.dir";
+
+ public void runTarget(String[] args)
+ {
+ String result = "Failed";
+
+ try {
+ // first find build file
+ File buildFile = null;
+ Vector<String> targets = new Vector<String> ();
+
+ setProductDir();
+
+ // get and set the user properties
+ for (String arg : args)
+ {
+ String[] kvp = arg.split("=");
+
+ if (kvp.length == 2)
+ {
+ String name = kvp[0].trim();
+ String value = kvp[1].trim();
+
+ if ("buildfile".equals(name))
+ {
+ buildFile = new File(getProductDir().getAbsolutePath() + '/' + value);
+ }
+ else if ("targets".equals(name))
+ {
+ for (String target : value.split(","))
+ targets.add(target.trim());
+ }
+ else if (name.startsWith("-D"))
+ {
+ System.err.println("Ignoring task parameter " + arg + " use jvm_param to set system parameters");
+ }
+ }
+ else
+ {
+ System.err.println("Ignoring invalid task parameter " + arg);
+ }
+ }
+
+ for (String prop : _jvmParameters)
+ {
+ if (prop.startsWith("-D"))
+ prop = prop.substring(2);
+
+ if (DebugEnabled)
+ System.out.println("setting jvm property: " + prop);
+
+ String[] kvp = prop.split("=");
+
+ if (kvp.length == 2)
+ {
+ String name = kvp[0].trim();
+ String value = kvp[1].trim();
+
+ if ("java.security.policy".equals(name))
+ {
+ File policyFile = new File(value);
+
+ if (!policyFile.exists())
+ policyFile = new File(getProductDir().getAbsolutePath() + '/' + value);
+
+ if (policyFile.exists())
+ System.setProperty(name, policyFile.getAbsolutePath());
+ else
+ System.err.println("Policy file not found: " + policyFile.getAbsolutePath());
+ }
+ else
+ System.setProperty(name, value);
+ }
+ else
+ {
+ System.err.println("Ignoring invalid jvm parameter " + prop);
+ }
+ }
+
+
+ if (buildFile == null)
+ buildFile = new File("build.xml");
+
+ // setup ant project
+ Project project = new Project() ;
+ project.init() ;
+ project.setCoreLoader(null) ;
+ project.setUserProperty("ant.version", org.apache.tools.ant.Main.getAntVersion()) ;
+ project.setUserProperty("ant.file", buildFile.getAbsolutePath()) ;
+
+ ProjectHelper.configureProject(project, buildFile) ;
+
+ //note: default property value was also set to "reports/html" instead of "."
+ String propVal = System.getProperty("org.jboss.dtf.testframework.testnode.UnitTestTaskRunner.resultsdirectory",".") ;
+ project.setProperty("dtf.report.dir", propVal) ;
+
+ if (DebugEnabled)
+ {
+ System.out.println("ant.version:" + org.apache.tools.ant.Main.getAntVersion()) ;
+ System.out.println("ant.file:" + buildFile.getAbsolutePath()) ;
+ System.out.println("setting property:" + "dtf.report.dir" + "=" + propVal) ;
+ System.out.println("executing ant script") ;
+ }
+
+ DefaultLogger logger = new DefaultLogger() ;
+
+ logger.setOutputPrintStream(System.out) ;
+ logger.setErrorPrintStream(System.err) ;
+ logger.setMessageOutputLevel(Project.MSG_INFO) ;
+
+ project.addBuildListener(logger) ;
+
+ // execute the ant script
+ if (buildFile.exists())
+ {
+ project.executeTargets(targets);
+ result = "Passed";
+ }
+ else
+ {
+ System.err.println("Cannot locate build file");
+ }
+
+ indicateTaskIsRunning();
+
+ readySignalled();
+ }
+ catch (BuildException e)
+ {
+ System.err.println("Build failed - build exception") ;
+ e.printStackTrace() ;
+ }
+ catch (Exception e)
+ {
+ System.err.println("Build failed - general exception") ;
+ e.printStackTrace() ;
+ }
+ catch (Error e)
+ {
+ System.err.println("Build failed - error") ;
+ e.printStackTrace() ;
+ }
+
+ // report the result of the test
+ try
+ {
+ System.out.println("Task " + _testId + ' ' + result);
+ getLoggingService().logResult(result, getTaskName(), _testId, _runId, _taskPermutationCode, _testPermutationCode);
+ _finished = true;
+ /*
+ * If there is a listener registered then
+ * inform the listener that the task has finished.
+ */
+ if (_listener!=null)
+ _listener.taskFinished( _taskId, _associatedTestNode, _testPermutationCode, true );
+ }
+ catch (LoggingServiceException e)
+ {
+ System.err.println("Unable to report task result: " + e.getMessage()) ;
+ e.printStackTrace();
+ }
+ catch (NoSuchTaskId noSuchTaskId)
+ {
+ System.out.println("Informed TestNode task has finished - task unknown: " + noSuchTaskId.getMessage());
+ }
+ catch (java.rmi.RemoteException e)
+ {
+ System.err.println("Unable to signal task complete: " + e.getMessage()) ;
+ }
+ }
+
+ private File getProductDir()
+ {
+ setProductDir();
+
+ return new File(System.getProperty(PRODUCT_DIR_PROP));
+ }
+
+ private void setProductDir()
+ {
+ String dirName = System.getProperty(PRODUCT_DIR_PROP);
+ File productDir;
+
+ if (dirName == null)
+ {
+ String home = System.getenv("DTF_HOME");
+ String productName = _productConfig.getName();
+
+ productDir = new File(home + '/' + productName);
+
+ if (!productDir.exists())
+ productDir = new File(home + '/' + productName.replaceAll("_", "-"));
+
+ System.setProperty(PRODUCT_DIR_PROP, productDir.getAbsolutePath());
+
+ if (DebugEnabled)
+ System.out.println("Product dir is " + System.getProperty(PRODUCT_DIR_PROP));
+ }
+ }
+
+ public void runTask() throws Exception
+ {
+ runTarget(_parameters);
+ }
+
+ public boolean terminate()
+ {
+ return true;
+ }
+
+ public void waitFor() throws InterruptedException
+ {
+
+ }
+
+}
Modified: trunk/src/org/jboss/dtf/testframework/testnode/JavaTaskRunner.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/testnode/JavaTaskRunner.java 2008-05-30 18:41:54 UTC (rev 15)
+++ trunk/src/org/jboss/dtf/testframework/testnode/JavaTaskRunner.java 2008-08-04 10:37:32 UTC (rev 16)
@@ -41,10 +41,7 @@
public class JavaTaskRunner extends TaskRunner
{
private final static String RESULTS_DIRECTORY_PROPERTY = "org.jboss.dtf.testframework.testnode.UnitTestTaskRunner.resultsdirectory";
- private final static String JAVA_TASK_RUNNER_DEBUG_PROPERTY = "com.arjuna.mw.testframework.javataskrunner.debug";
- protected static boolean DebugEnabled = Boolean.valueOf( System.getProperty(JAVA_TASK_RUNNER_DEBUG_PROPERTY, "false") ).booleanValue();
-
private final static String WAIT_FOR_PARAMETER = "wait_for_text";
private final static String PASS_INDICATOR_PARAMETER = "pass_indicator";
private final static String FAIL_INDICATOR_PARAMETER = "fail_indicator";
Modified: trunk/src/org/jboss/dtf/testframework/testnode/TaskRunner.java
===================================================================
--- trunk/src/org/jboss/dtf/testframework/testnode/TaskRunner.java 2008-05-30 18:41:54 UTC (rev 15)
+++ trunk/src/org/jboss/dtf/testframework/testnode/TaskRunner.java 2008-08-04 10:37:32 UTC (rev 16)
@@ -46,8 +46,10 @@
public abstract class TaskRunner implements Runnable
{
public final static String JAVA_HOME_DIRECTORY_PARAMETER = "java_home";
+ private final static String JAVA_TASK_RUNNER_DEBUG_PROPERTY = "com.arjuna.mw.testframework.javataskrunner.debug";
+ protected static boolean DebugEnabled = Boolean.valueOf( System.getProperty(JAVA_TASK_RUNNER_DEBUG_PROPERTY, "false") ).booleanValue();
- protected String _className;
+ protected String _className;
protected String[] _parameters;
protected String[] _jvmParameters;
protected int _testType = TestNodeInterface.WAIT_NONE,
16 years, 4 months