Index: .cvsignore =================================================================== RCS file: /cvsroot/cruisecontrol/cruisecontrol/.cvsignore,v retrieving revision 1.6 diff -u -r1.6 .cvsignore --- .cvsignore 26 Aug 2004 12:38:06 -0000 1.6 +++ .cvsignore 27 Dec 2004 00:44:57 -0000 @@ -14,3 +14,4 @@ intellij-out +target Index: main/src/net/sourceforge/cruisecontrol/CruiseControlController.java =================================================================== RCS file: /cvsroot/cruisecontrol/cruisecontrol/main/src/net/sourceforge/cruisecontrol/CruiseControlController.java,v retrieving revision 1.12 diff -u -r1.12 CruiseControlController.java --- main/src/net/sourceforge/cruisecontrol/CruiseControlController.java 17 Dec 2004 16:59:33 -0000 1.12 +++ main/src/net/sourceforge/cruisecontrol/CruiseControlController.java 27 Dec 2004 00:44:58 -0000 @@ -44,6 +44,7 @@ import java.io.FileInputStream; import java.io.ObjectInputStream; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.EventListener; import java.util.Iterator; @@ -59,13 +60,13 @@ private File configFile; private List projects = new ArrayList(); private BuildQueue buildQueue = new BuildQueue(); - + private List listeners = new ArrayList(); - + public File getConfigFile() { return configFile; } - + public void setConfigFile(File configFile) throws CruiseControlException { this.configFile = configFile; if (configFile == null) { @@ -76,7 +77,7 @@ } parseConfigFile(); } - + private void parseConfigFile() throws CruiseControlException { Element configRoot = Util.loadConfigFile(configFile); addPluginsToRootRegistry(configRoot); @@ -86,7 +87,7 @@ addProject(project); } } - + private void addPluginsToRootRegistry(Element configRoot) { for (Iterator pluginIter = configRoot.getChildren("plugin").iterator(); pluginIter.hasNext(); ) { Element pluginElement = (Element) pluginIter.next(); @@ -102,7 +103,7 @@ } } } - + private void addProject(Project project) { projects.add(project); for (Iterator listenIter = listeners.iterator(); listenIter.hasNext();) { @@ -111,7 +112,7 @@ listener.projectAdded(project); } } - + public void resume() { buildQueue.start(); for (Iterator iterator = projects.iterator(); iterator.hasNext();) { @@ -120,7 +121,7 @@ currentProject.start(); } } - + public void pause() { buildQueue.stop(); for (Iterator iterator = projects.iterator(); iterator.hasNext();) { @@ -128,12 +129,12 @@ currentProject.stop(); } } - + public void halt() { pause(); System.exit(0); } - + public String getBuildQueueStatus() { if (buildQueue.isAlive()) { if (buildQueue.isWaiting()) { @@ -145,31 +146,35 @@ return "dead"; } } - + public List getProjects() { return Collections.unmodifiableList(projects); } - + private List getAllProjects(Element configRoot) throws CruiseControlException { - String[] projectNames = getProjectNames(configRoot); - ArrayList allProjects = new ArrayList(projectNames.length); - for (int i = 0; i < projectNames.length; i++) { - String projectName = projectNames[i]; - LOG.info("projectName = [" + projectName + "]"); - Project project = configureProject(projectName); + ServerXMLHelper helper = new ServerXMLHelper(configRoot, configFile); + Collection projectNames = helper.getProjectList(); + ArrayList allProjects = new ArrayList(projectNames.size()); + for (Iterator projectIterator = projectNames.iterator(); projectIterator.hasNext();) { + ProjectDescriptor projectKeyValue = (ProjectDescriptor) projectIterator.next(); + String projectName = (String) projectKeyValue.getProjectName(); + File projectConfigFile = (File) projectKeyValue.getConfigurationFile(); + LOG.info("projectName = [" + projectName + "] and projectConfigFile = [" + projectConfigFile + "]"); + Project project = configureProject(projectName, projectConfigFile); allProjects.add(project); } + return allProjects; } - - protected Project configureProject(String projectName) throws CruiseControlException { + + protected Project configureProject(String projectName, File projectConfigFile) throws CruiseControlException { Project project = readProject(projectName); project.setName(projectName); - project.setConfigFile(configFile); + project.setConfigFile(projectConfigFile); project.init(); return project; } - + /** * Reads project configuration from a previously serialized Project. The * name of the serialized project file is equivalent to the name of the @@ -183,7 +188,7 @@ //look for fileName.ser first File serializedProjectFile = new File(fileName + ".ser"); LOG.debug("Reading serialized project from: " + serializedProjectFile.getAbsolutePath()); - + if (!serializedProjectFile.exists() || !serializedProjectFile.canRead()) { //filename.ser doesn't exist, try finding fileName serializedProjectFile = new File(fileName); @@ -197,7 +202,7 @@ return newProject; } } - + try { ObjectInputStream s = new ObjectInputStream(new FileInputStream(serializedProjectFile)); Project project = (Project) s.readObject(); @@ -207,7 +212,7 @@ return new Project(); } } - + private String[] getProjectNames(Element rootElement) { ArrayList projectNames = new ArrayList(); Iterator projectIterator = rootElement.getChildren("project").iterator(); @@ -223,12 +228,12 @@ } return (String[]) projectNames.toArray(new String[]{}); } - + public void addListener(Listener listener) { LOG.debug("Listener added"); listeners.add(listener); } - + public static interface Listener extends EventListener { void projectAdded(Project project); } Index: main/src/net/sourceforge/cruisecontrol/ServerXMLHelper.java =================================================================== RCS file: /cvsroot/cruisecontrol/cruisecontrol/main/src/net/sourceforge/cruisecontrol/ServerXMLHelper.java,v retrieving revision 1.1 diff -u -r1.1 ServerXMLHelper.java --- main/src/net/sourceforge/cruisecontrol/ServerXMLHelper.java 3 Jul 2004 05:54:34 -0000 1.1 +++ main/src/net/sourceforge/cruisecontrol/ServerXMLHelper.java 27 Dec 2004 00:44:58 -0000 @@ -38,17 +38,21 @@ import net.sourceforge.cruisecontrol.util.Util; import org.apache.log4j.Logger; +import org.apache.tools.ant.DirectoryScanner; import org.jdom.Attribute; import org.jdom.DataConversionException; import org.jdom.Element; import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; /** - * @author Jared Richardson jared.richardson@sas.com - *

- * this routine encapsulates the config file for the application. - * it fetches a value from the config file and handles errors. + * @author Jared Richardson jared.richardson@sas.com

this routine + * encapsulates the config file for the application. it fetches a value + * from the config file and handles errors. */ public class ServerXMLHelper { @@ -56,44 +60,204 @@ private int numThreads = 1; - public ServerXMLHelper(File configFile) { - try { - Element configLogElement = Util.loadConfigFile(configFile); - Element systemElement = configLogElement.getChild("system"); - if (systemElement == null) { - LOG.debug("no system element found in config.xml"); - return; - } - Element configurationElement = systemElement.getChild("configuration"); - if (configurationElement == null) { - LOG.debug("no configuraiton element found in config.xml"); - return; - } - Element threadElement = configurationElement.getChild("threads"); - if (threadElement == null) { - LOG.debug("no threads element found in config.xml"); - return; + private List projectConfigFiles = new ArrayList(); + + private File configFile = null; + + private Element configLogElement = null; + + /** + * Convenience Constructor for testing. + * + */ + ServerXMLHelper() { + + } + + void processConfigElement() { + Element systemElement = configLogElement.getChild("system"); + if (systemElement == null) { + LOG.debug("no system element found in config.xml"); + return; + } + Element configurationElement = systemElement.getChild("configuration"); + if (configurationElement == null) { + LOG.debug("no configuration element found in config.xml"); + return; + } + + processThreadElement(configurationElement); + + processProjectFilesElement(configurationElement); + } + + /** + * @param configurationElement + */ + private void processProjectFilesElement(Element configurationElement) { + // Check if there are any children to load. + Element configFiles = configurationElement.getChild("projectfiles"); + if (configFiles != null) { + // Check for files that were added using ant's format + String baseDir = configFiles.getAttributeValue("basedir"); + + if (baseDir == null || "".equals(baseDir)) { + baseDir = "."; + } + + String[] includes = getDirectoryScannerConfigs(configFiles, "include"); + String[] excludes = getDirectoryScannerConfigs(configFiles, "exclude"); + + if (excludes.length != 0 || includes.length != 0) { + DirectoryScanner ds = new DirectoryScanner(); + ds.setBasedir(baseDir); + ds.setIncludes(includes); + ds.setExcludes(excludes); + ds.scan(); + + String[] includedFiles = ds.getIncludedFiles(); + for (int i = 0; i < includedFiles.length; i++) { + File f = new File(includedFiles[i]); + projectConfigFiles.add(f); + } } + + List fileElements = configFiles.getChildren("project"); + for (Iterator iter = fileElements.iterator(); iter.hasNext();) { + Element fileE = (Element) iter.next(); + Attribute fileNameAttr = fileE.getAttribute("filename"); + LOG.debug("fileName attribute on files is " + fileNameAttr); + if (fileNameAttr != null) { + String fileName = fileNameAttr.getValue(); + File projectConfigFile = new File(fileName); + if (projectConfigFile.exists()) { + projectConfigFiles.add(projectConfigFile); + } + } + } + } + } + + /** + * @param configFiles + * @param nodeType + * @return + */ + private String[] getDirectoryScannerConfigs(Element configFiles, String nodeType) { + List patterns = configFiles.getChildren(nodeType); + String[] rv = new String[patterns.size()]; + int i = 0; + for (Iterator iter = patterns.iterator(); iter.hasNext();) { + Element element = (Element) iter.next(); + rv[i] = element + .getAttributeValue("name"); + i++; + } + return rv; + } + + /** + * @param configurationElement + */ + private void processThreadElement(Element configurationElement) { + Element threadElement = configurationElement.getChild("threads"); + if (threadElement != null) { Attribute threadCount = threadElement.getAttribute("count"); - LOG.debug("count attribute on threads is " + threadCount.toString()); + LOG + .debug("count attribute on threads is " + + threadCount.toString()); try { numThreads = threadCount.getIntValue(); } catch (DataConversionException dce) { - LOG.error("Expected a numeric value for system-configuration-threads-count in config.xml but found " - + threadCount.toString(), dce); + LOG + .error( + "Expected a numeric value for system-configuration-threads-count in config.xml but found " + + threadCount.toString(), dce); numThreads = 1; } - } catch (Exception e) { - LOG.warn("error parsing thread count from config file; defaulting to 1 thread.", e); + } else { + LOG + .debug("no threads element found in config.xml, using 1 thread."); + } + } + + public ServerXMLHelper(Element configLogElement, File configFile) { + if (configLogElement != null) { + this.configFile = configFile; + this.configLogElement = configLogElement; + processConfigElement(); + } + } + + public ServerXMLHelper(File configFile) { + + //Element configLogElement = null; + try { + configLogElement = Util.loadConfigFile(configFile); + } catch (CruiseControlException e) { + LOG + .warn( + "error parsing thread count from config file; defaulting to 1 thread.", + e); numThreads = 1; + return; } + + processConfigElement(); } /** - * @return int the number of threads that CruiseControl should allow to run at the same time - * to process pending build requests + * @return int the number of threads that CruiseControl should allow to run + * at the same time to process pending build requests */ public int getNumThreads() { return numThreads; } -} + + public List getProjectConfigFiles() { + return projectConfigFiles; + } + + public Collection getProjectList() { + ArrayList projectList = new ArrayList(); + + // Check the default file for projects + projectList.addAll(processProjectNodes(configLogElement)); + + // Now check the other configFiles + for (Iterator projectFilesIterator = projectConfigFiles.iterator(); projectFilesIterator + .hasNext();) { + File projectFile = (File) projectFilesIterator.next(); + try { + Element rootElement = Util.loadConfigFile(projectFile); + projectList.addAll(processProjectNodes(rootElement)); + } catch (CruiseControlException e) { + LOG.error("Error trying to process file " + projectFile, e); + } + } + return projectList; + } + + private Collection processProjectNodes(Element rootElement) { + ArrayList projectList = new ArrayList(); + + // Check the default file for projects + Iterator projectIterator = rootElement.getChildren("project") + .iterator(); + while (projectIterator.hasNext()) { + Element projectElement = (Element) projectIterator.next(); + String projectName = projectElement.getAttributeValue("name"); + if (projectName == null) { + // TODO: will be ignored? + LOG + .warn("configuration file contains project element with no name"); + } else { + ProjectDescriptor projectData = new ProjectDescriptor(); + projectData.setProjectName(projectName); + projectData.setConfigurationFile(configFile); + projectList.add(projectData); + } + } + return projectList; + } +} \ No newline at end of file Index: main/test/net/sourceforge/cruisecontrol/CruiseControlControllerTest.java =================================================================== RCS file: /cvsroot/cruisecontrol/cruisecontrol/main/test/net/sourceforge/cruisecontrol/CruiseControlControllerTest.java,v retrieving revision 1.9 diff -u -r1.9 CruiseControlControllerTest.java --- main/test/net/sourceforge/cruisecontrol/CruiseControlControllerTest.java 22 Aug 2004 09:30:20 -0000 1.9 +++ main/test/net/sourceforge/cruisecontrol/CruiseControlControllerTest.java 27 Dec 2004 00:44:58 -0000 @@ -47,21 +47,21 @@ * @author Robert Watkins */ public class CruiseControlControllerTest extends TestCase { - + private File configFile = new File("_tempConfigFile"); private CruiseControlController test; - + protected void setUp() throws Exception { test = new CruiseControlController(); } - + public void tearDown() { if (configFile.exists()) { configFile.delete(); } test = null; } - + public void testSetNoFile() { try { test.setConfigFile(null); @@ -76,40 +76,93 @@ assertEquals("Config file not found: " + configFile, expected.getMessage()); } } - + public void testLoadEmptyProjects() throws IOException, CruiseControlException { FileWriter configOut = new FileWriter(configFile); - configOut.write("\n"); - configOut.write("\n"); - configOut.write("\n"); + writeConfigHeader(configOut); + writeConfigFooter(configOut); configOut.close(); - + test.setConfigFile(configFile); assertEquals(configFile, test.getConfigFile()); assertTrue(test.getProjects().isEmpty()); } - + public void testLoadSomeProjects() throws IOException, CruiseControlException { - test = new CruiseControlController() { - protected Project configureProject(String projectName) { - final Project project = new Project(); - project.setName(projectName); - return project; - } - }; + setupMockControlller(); FileWriter configOut = new FileWriter(configFile); - configOut.write("\n"); - configOut.write("\n"); + writeConfigHeader(configOut); writeProjectDetails(configOut, "testProject1"); writeProjectDetails(configOut, "testProject2"); + writeConfigFooter(configOut); + configOut.close(); + + test.setConfigFile(configFile); + assertEquals(configFile, test.getConfigFile()); + assertEquals(2, test.getProjects().size()); + } + + /** + * @param configOut + * @throws IOException + */ + private void writeConfigFooter(FileWriter configOut) throws IOException { configOut.write("\n"); + } + + /** + * @param configOut + * @throws IOException + */ + private void writeConfigHeader(FileWriter configOut) throws IOException { + configOut.write("\n"); + configOut.write("\n"); + } + + public void testLoadSomeExternalProjects() throws IOException, CruiseControlException { + setupMockControlller(); + + // Create an external configFile + File externalConfigFile = new File("_extConfigfile"); + FileWriter extConfigOut = new FileWriter(externalConfigFile); + writeConfigHeader(extConfigOut); + writeProjectDetails(extConfigOut, "testProject1"); + writeProjectDetails(extConfigOut, "testProject2"); + writeConfigFooter(extConfigOut); + extConfigOut.close(); + + + FileWriter configOut = new FileWriter(configFile); + writeConfigHeader(configOut); + configOut.write("\n"); + configOut.write("\n"); + configOut.write("\n"); + configOut.write(""); + configOut.write("\n"); + configOut.write("\n"); + configOut.write("\n"); + writeConfigFooter(configOut); configOut.close(); - + test.setConfigFile(configFile); assertEquals(configFile, test.getConfigFile()); assertEquals(2, test.getProjects().size()); } - + + /** + * + */ + private void setupMockControlller() { + test = new CruiseControlController() { + protected Project configureProject(String projectName, File configFile) { + final Project project = new Project(); + project.setName(projectName); + project.setConfigFile(configFile); + return project; + } + }; + } + public void testReadProject() throws IOException { File tempFile = File.createTempFile("foo", ".tmp"); String tempDir = tempFile.getParent(); @@ -118,24 +171,24 @@ assertNotNull(project); assertTrue(project.getBuildForced()); } - + public void testRegisterPlugins() throws Exception { FileWriter configOut = new FileWriter(configFile); configOut.write("\n"); configOut.write("\n"); configOut.write(" \n"); + + "classname=\"net.sourceforge.cruisecontrol.CruiseControllerTest\"/>\n"); configOut.write(" \n"); configOut.write("\n"); configOut.close(); - + test.setConfigFile(configFile); PluginRegistry newRegistry = PluginRegistry.createRegistry(); assertTrue(newRegistry.isPluginRegistered("testname")); assertFalse(newRegistry.isPluginRegistered("unknown_plugin")); assertEquals(newRegistry.getPluginClassname("labelincrementer"), "my.global.Incrementer"); } - + private void writeProjectDetails(FileWriter configOut, final String projectName) throws IOException { configOut.write("\n"); } Index: main/src/net/sourceforge/cruisecontrol/ProjectDescriptor.java =================================================================== RCS file: main/src/net/sourceforge/cruisecontrol/ProjectDescriptor.java diff -N main/src/net/sourceforge/cruisecontrol/ProjectDescriptor.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ main/src/net/sourceforge/cruisecontrol/ProjectDescriptor.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,45 @@ +/* + * Created on Dec 24, 2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package net.sourceforge.cruisecontrol; + +import java.io.File; + +/** + * @author mbotelho + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class ProjectDescriptor { + private String projectName; + private File configurationFile; + + /** + * @return Returns the project name. + */ + public String getProjectName() { + return projectName; + } + /** + * @param projectName The project name to set. + */ + public void setProjectName(String projectName) { + this.projectName = projectName; + } + /** + * @return Returns the configuration file associated to the project. + */ + public File getConfigurationFile() { + return configurationFile; + } + /** + * @param configurationFile The configuration file to set. + */ + public void setConfigurationFile(File configurationFile) { + this.configurationFile = configurationFile; + } +} Index: main/test/net/sourceforge/cruisecontrol/ServerXMLHelperTest.java =================================================================== RCS file: main/test/net/sourceforge/cruisecontrol/ServerXMLHelperTest.java diff -N main/test/net/sourceforge/cruisecontrol/ServerXMLHelperTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ main/test/net/sourceforge/cruisecontrol/ServerXMLHelperTest.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,163 @@ +/******************************************************************************** + * CruiseControl, a Continuous Integration Toolkit + * Copyright (c) 2001, ThoughtWorks, Inc. + * 651 W Washington Ave. Suite 600 + * Chicago, IL 60661 USA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * + Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * + Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************************/ +package net.sourceforge.cruisecontrol; + +import java.io.File; + +import junit.framework.TestCase; + +import org.jdom.Element; + +public class ServerXMLHelperTest extends TestCase { + + private File configFile; + private File tempDirectory; + + private static final int ONE_SECOND = 1000; + private Element cruisecontrol; + private Element system; + private Element configuration; + + public void testGetThreadsInvalid() throws Exception { + File junk = new File("junk"); + ServerXMLHelper sxh = new ServerXMLHelper(cruisecontrol, junk); + + sxh.processConfigElement(); + assertEquals(1, sxh.getNumThreads()); + } + + public void testGetThreadsValid() throws Exception { + File junk = new File("junk"); + ServerXMLHelper sxh = new ServerXMLHelper(cruisecontrol, junk); + + // Check for a valid number + Element threads = new Element("threads"); + threads.setAttribute("count", "2"); + configuration.addContent(threads); + sxh.processConfigElement(); + assertEquals(2, sxh.getNumThreads()); + } + + public void testInvalidConfig() throws Exception { + File junk = new File("junk.xml"); + ServerXMLHelper sxh = new ServerXMLHelper(junk); + assertEquals(1, sxh.getNumThreads()); + } + + public void testEmptyProjectFilesElement() throws Exception { + File junk = new File("junk"); + ServerXMLHelper sxh = new ServerXMLHelper(cruisecontrol, junk); + + Element projectFiles = new Element ("projectfiles"); + Element tmp = configuration.addContent(projectFiles); + + sxh.processConfigElement(); + + assertEquals(0, sxh.getProjectConfigFiles().size()); + } + + public void testProjectFiles() throws Exception { + File junk = new File("junk"); + ServerXMLHelper sxh = new ServerXMLHelper(cruisecontrol, junk); + Element projectFiles = new Element ("projectfiles"); + Element tmp = configuration.addContent(projectFiles); + + // Create 2 empty files + File file1 = File.createTempFile("project1", "xml"); + File file2 = File.createTempFile("project2", "xml"); + + Element proj1 = new Element("project"); + proj1.setAttribute("filename", file1.getAbsolutePath()); + projectFiles.addContent(proj1); + + Element proj2 = new Element("project"); + proj2.setAttribute("filename", file2.getAbsolutePath()); + projectFiles.addContent(proj2); + + Element proj3 = new Element("project"); + projectFiles.addContent(proj3); + + sxh.processConfigElement(); + + assertEquals(2, sxh.getProjectConfigFiles().size()); + file1.delete(); + file2.delete(); + } + + public void testProjectFilesWithIncludes() throws Exception { + File junk = new File("junk"); + ServerXMLHelper sxh = new ServerXMLHelper(cruisecontrol, junk); + Element projectFiles = new Element ("projectfiles"); + Element tmp = configuration.addContent(projectFiles); + + // Create 2 empty files + File file1 = File.createTempFile("project1", "xml"); + File file2 = File.createTempFile("project2", "xml"); + + projectFiles.setAttribute("basedir", file1.getParentFile().getAbsolutePath()); + + Element proj1 = new Element("include"); + proj1.setAttribute("name", "project1*xml"); + projectFiles.addContent(proj1); + + Element proj2 = new Element("exclude"); + proj2.setAttribute("name", "project2*xml"); + projectFiles.addContent(proj2); + + Element proj3 = new Element("project"); + projectFiles.addContent(proj3); + + sxh.processConfigElement(); + + assertEquals(1, sxh.getProjectConfigFiles().size()); + file1.delete(); + file2.delete(); + } + + protected void setUp() throws Exception { + cruisecontrol = new Element("cruisecontrol"); + system = new Element("system"); + configuration = new Element("configuration"); + cruisecontrol.addContent(system); + system.addContent(configuration); + } + + protected void tearDown() throws Exception { + cruisecontrol = null; + } + +}