From: <pau...@us...> - 2006-04-30 15:45:28
|
Revision: 2521 Author: pauljulius Date: 2006-04-30 08:41:09 -0700 (Sun, 30 Apr 2006) ViewCVS: http://svn.sourceforge.net/cruisecontrol/?rev=2521&view=rev Log Message: ----------- Brought up to date with CVS. Tarball from SourceForge appeared to be about a month out of date. Modified Paths: -------------- trunk/cruisecontrol/RELEASENOTES.txt trunk/cruisecontrol/binaryrelease/cruisecontrol.bat trunk/cruisecontrol/binaryrelease/cruisecontrol.sh trunk/cruisecontrol/build.properties trunk/cruisecontrol/contrib/distributed/README.html trunk/cruisecontrol/contrib/distributed/cruisecontrol.bat trunk/cruisecontrol/contrib/distributed/cruisecontrol.sh trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/builders/DistributedMasterBuilder.java trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/distributed/BuildAgentService.java trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/distributed/BuildAgentServiceImpl.java trunk/cruisecontrol/contrib/distributed/test/net/sourceforge/cruisecontrol/distributed/BuildAgentServiceImplTest.java trunk/cruisecontrol/docs/contributions.html trunk/cruisecontrol/docs/download.html trunk/cruisecontrol/docs/gettingstartedsourcedist.html trunk/cruisecontrol/docs/index.html trunk/cruisecontrol/release.bat trunk/cruisecontrol/reporting/jsp/build.bat trunk/cruisecontrol/reporting/jsp/build.xml trunk/cruisecontrol/reporting/jsp/project.xml trunk/cruisecontrol/reporting/jsp/src/net/sourceforge/cruisecontrol/servlet/FileServlet.java trunk/cruisecontrol/reporting/jsp/src/net/sourceforge/cruisecontrol/taglib/NavigationCountTag.java trunk/cruisecontrol/reporting/jsp/test/net/sourceforge/cruisecontrol/servlet/FileServletTest.java Added Paths: ----------- trunk/cruisecontrol/lib/xercesImpl-2.8.0.jar trunk/cruisecontrol/lib/xml-apis-2.8.0.jar trunk/cruisecontrol/reporting/jsp/lib/serializer-2.7.0.jar trunk/cruisecontrol/reporting/jsp/lib/xalan-2.7.0.jar trunk/cruisecontrol/reporting/jsp/lib/xercesImpl-2.8.0.jar trunk/cruisecontrol/reporting/jsp/lib/xml-apis-2.8.0.jar Removed Paths: ------------- trunk/cruisecontrol/lib/xercesImpl-2.7.0.jar trunk/cruisecontrol/lib/xml-apis-2.7.0.jar trunk/cruisecontrol/reporting/jsp/lib/xalan-2.6.0.jar trunk/cruisecontrol/reporting/jsp/lib/xercesImpl-2.7.0.jar trunk/cruisecontrol/reporting/jsp/lib/xml-apis-2.7.0.jar Modified: trunk/cruisecontrol/RELEASENOTES.txt =================================================================== --- trunk/cruisecontrol/RELEASENOTES.txt 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/RELEASENOTES.txt 2006-04-30 15:41:09 UTC (rev 2521) @@ -2,20 +2,22 @@ Changes listed by release, then alphabetically. -CruiseControl Release Notes - Current +CruiseControl Release Notes - 2.5 general ====================== * Included build.xml target to create executable windows installer, from contrib definition (CC-314). Submitted by Julian Simpson. Should make CruiseControl-VER.exe available as a distribution. -* Some general code cleanup and formatting changes. +* Updated Xerces (2.8) and Xalan (2.7) jars to fix memory leak (CC-426) contrib ====================== * WindowsInstaller definition using nsis (CC-314). Submitted by Julian Simpson. +* Update DistributedBuildMaster to support instance reuse (CC-434). Submitted by Dan Rollo build loop ====================== * Cleaned up incorrect usages of static SimpleDateFormats (CC-422). Proposed by Scott Coplin. +* Fixed recently introduced bug where project would keep on building with its overriden target when invoked once from the JMX interface using buildWithTarget. Builder ---------------------- @@ -25,26 +27,67 @@ ---------------------- * New publisher for use with ClearCase UCM (CC-414). Submitted by Kevin Lee. +CruiseControlConfig: +---------------------- +* On first load attempt to run projects in the same order they appear in config file. Patch by Olek + CruiseControlControllerAgent: ---------------------- * Look for an existing MBeanServer before creating a new one. This will make it possible to manage CC through Java 5's JConsole (CC-417). Patch by Gavin Kinghall Were. +ExecutePublisher: +---------------------- +* No longer asynchronous (CC-280). Patch by Michael Kloss + LDAPMapper: ---------------------- -* Email mapper that uses an LDAP lookup to determine user email addresses (CC-413). Submitted by Esa Laine.Email mapper that uses an LDAP lookup to determine user email addresses (CC-413). Submitted by Esa Laine. +* Email mapper that uses an LDAP lookup to determine user email addresses (CC-413). Submitted by Esa Laine. +Maven2Builder: +---------------------- +* Fix problem where Maven2 reports were not showing build details (CC-429). Contributions by Jean-Laurent de Morlhon and Roger Butenuth. Final patch from Dan Rollo. + +Maven2SnapshotDependency: +---------------------- +* New sourcecontrol (CC-438). Contributed by Dan Rollo with fixes by Jerome Lacoste. + +PauseBuilder: +---------------------- +* PauseBuilder is no longer a Builder. + +ProjectConfig: +---------------------- +* buildAfterFailed should default to true. + ProjectWrapper: ---------------------- * Fix problem where forcing a build while build is running will effectively kill the worker thread leading to all projects queued but not building (CC-431). Patch by John Lewis. +PVCS: +---------------------- +* Handle archive file names that don't end in "-arc". Added property archiveFileSuffix. (CC-425) + Schedule: ---------------------- -* Fixed recently introduced bug where project would keep on building with its overriden target when invoked once from the JMX interface using buildWithTarget. +* Removed deprecated methods addBuilder and addPauseBuilder. +SCPPublisher: +---------------------- +* Fixed bug where publisher always published the same log file. +* No longer asynchronous (CC-280). Patch by Michael Kloss + SourceControl (Plugin API): ---------------------- * getProperties() now returns a Map instead of a Hashtable +SfeeFrsPublisher: +---------------------- +* remove setFile(File file) to avoid couldn't invoke setter problem (CC-433). + +SVN: +---------------------- +* Fix NPE when client has no read permissions to the changed file. Patch by Britt Piehler + UCM: ---------------------- * Add property attribute that gets set if modifications are found (CC-421). Patch by Scott Coplin. Modified: trunk/cruisecontrol/binaryrelease/cruisecontrol.bat =================================================================== --- trunk/cruisecontrol/binaryrelease/cruisecontrol.bat 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/binaryrelease/cruisecontrol.bat 2006-04-30 15:41:09 UTC (rev 2521) @@ -71,10 +71,11 @@ set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\ant-launcher.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\jasper-compiler.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\jasper-runtime.jar -set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\xercesImpl-2.7.0.jar -set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\xml-apis-2.7.0.jar +set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\xercesImpl-2.8.0.jar +set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\xml-apis-2.8.0.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\xmlrpc-2.0.1.jar -set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\xalan-2.6.0.jar +set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\xalan-2.7.0.jar +set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\serializer-2.7.0.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\jakarta-oro-2.0.3.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\mail.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\junit.jar @@ -88,6 +89,7 @@ set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\comm.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\x10.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\fast-md5.jar +set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\maven-embedder-2.0.3-dep.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\javax.servlet.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\org.mortbay.jetty.jar set CRUISE_PATH=%CRUISE_PATH%;%LIBDIR%\commons-logging.jar Modified: trunk/cruisecontrol/binaryrelease/cruisecontrol.sh =================================================================== --- trunk/cruisecontrol/binaryrelease/cruisecontrol.sh 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/binaryrelease/cruisecontrol.sh 2006-04-30 15:41:09 UTC (rev 2521) @@ -51,7 +51,7 @@ JAVA_HOME=`cygpath --path --unix "$JAVA_HOME"` fi -CRUISE_PATH=$JAVA_HOME/lib/tools.jar:$LIBDIR/cruisecontrol.jar:$LIBDIR/log4j.jar:$LIBDIR/jdom.jar:$LIBDIR/ant.jar:$LIBDIR/ant-launcher.jar:$LIBDIR/jasper-compiler.jar:$LIBDIR/jasper-runtime.jar:$LIBDIR/xercesImpl-2.7.0.jar:$LIBDIR/xml-apis-2.7.0.jar:$LIBDIR/xmlrpc-2.0.1.jar:$LIBDIR/xalan-2.6.0.jar:$LIBDIR/jakarta-oro-2.0.3.jar:$LIBDIR/mail.jar:$LIBDIR/junit.jar:$LIBDIR/activation.jar:$LIBDIR/commons-net-1.1.0.jar:$LIBDIR/starteam-sdk.jar:$LIBDIR/mx4j.jar:$LIBDIR/mx4j-tools.jar:$LIBDIR/mx4j-remote.jar:$LIBDIR/smack.jar:$LIBDIR/comm.jar:$LIBDIR/x10.jar:$LIBDIR/fast-md5.jar:$LIBDIR/javax.servlet.jar:$LIBDIR/org.mortbay.jetty.jar:$LIBDIR/commons-logging.jar:$LIBDIR/commons-el.jar:. +CRUISE_PATH=$JAVA_HOME/lib/tools.jar:$LIBDIR/cruisecontrol.jar:$LIBDIR/log4j.jar:$LIBDIR/jdom.jar:$LIBDIR/ant.jar:$LIBDIR/ant-launcher.jar:$LIBDIR/jasper-compiler.jar:$LIBDIR/jasper-runtime.jar:$LIBDIR/xercesImpl-2.8.0.jar:$LIBDIR/xml-apis-2.8.0.jar:$LIBDIR/xmlrpc-2.0.1.jar:$LIBDIR/xalan-2.7.0.jar:$LIBDIR/serializer-2.7.0.jar:$LIBDIR/jakarta-oro-2.0.3.jar:$LIBDIR/mail.jar:$LIBDIR/junit.jar:$LIBDIR/activation.jar:$LIBDIR/commons-net-1.1.0.jar:$LIBDIR/starteam-sdk.jar:$LIBDIR/mx4j.jar:$LIBDIR/mx4j-tools.jar:$LIBDIR/mx4j-remote.jar:$LIBDIR/smack.jar:$LIBDIR/comm.jar:$LIBDIR/x10.jar:$LIBDIR/fast-md5.jar:$LIBDIR/maven-embedder-2.0.3-dep.jar:$LIBDIR/javax.servlet.jar:$LIBDIR/org.mortbay.jetty.jar:$LIBDIR/commons-logging.jar:$LIBDIR/commons-el.jar:. # convert the existing path to unix if [ `uname | grep -n CYGWIN` ]; then Modified: trunk/cruisecontrol/build.properties =================================================================== --- trunk/cruisecontrol/build.properties 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/build.properties 2006-04-30 15:41:09 UTC (rev 2521) @@ -1,3 +1,3 @@ -cc.version=2.4.2-dev +cc.version=2.5 apache.ant=apache-ant-1.6.5 apache.ant.zip=binaryrelease/${apache.ant}-bin.zip Modified: trunk/cruisecontrol/contrib/distributed/README.html =================================================================== --- trunk/cruisecontrol/contrib/distributed/README.html 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/contrib/distributed/README.html 2006-04-30 15:41:09 UTC (rev 2521) @@ -95,7 +95,8 @@ agentoutputdir="agent/output" masteroutputdir="master/log"> ... </distributed></pre> - After a remote build, any files on the agent machine in dir "agent/log" will be copied back to the master machine into dir "master/log". The "logs" and "output" dirs will be deleted on the Agent after the build finishes.</li> + After a remote build, any files on the agent machine in dir "agent/log" will be copied back to the master machine into dir "master/log". The "logs" and "output" dirs will be deleted on the Agent after the build finishes. + <p/>NOTE: You may have problems when running a BuildAgent on the same machine as the main CC server due to the removal of the log/output dirs by the BuildAgent (if the main CC server needs the deleted directories). In such cases, you should override the cannonical artifact dirs using these tags.</li> <li>Java Web Start deployment of build agents: <code>ant war-agent</code> will use the file <code>build-sign.properties</code> to sign agent jars and bundle them into a deployable <code>.war</code> file (<code>dist/cc-agnet.war</code>). Be sure you update the <code>build-sign.properties</code> appropriately to use your signing information/certificate.</li> Modified: trunk/cruisecontrol/contrib/distributed/cruisecontrol.bat =================================================================== --- trunk/cruisecontrol/contrib/distributed/cruisecontrol.bat 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/contrib/distributed/cruisecontrol.bat 2006-04-30 15:41:09 UTC (rev 2521) @@ -73,7 +73,7 @@ set DISTRIBDIR=%CCDIR%\..\contrib\distributed set LIBS_JINI=%DISTRIBDIR%\lib\jini-core.jar;%DISTRIBDIR%\lib\jini-ext.jar;%DISTRIBDIR%\lib\jsk-platform.jar;%DISTRIBDIR%\lib\reggie.jar;%DISTRIBDIR%\lib\reggie-dl.jar;%DISTRIBDIR%\lib\start.jar;%DISTRIBDIR%\lib\tools.jar;%DISTRIBDIR%\conf -set CRUISE_PATH=%CRUISE_PATH%;%DISTDIR%\cruisecontrol.jar;%LIBDIR%\log4j.jar;%LIBDIR%\jdom.jar;%LIBDIR%\ant\ant.jar;%LIBDIR%\ant\ant-launcher.jar;%LIBDIR%\xml-apis-2.7.0.jar;%LIBDIR%\xercesImpl-2.7.0.jar;%LIBDIR%\xalan-2.6.0.jar;%LIBDIR%\jakarta-oro-2.0.3.jar;%LIBDIR%\mail.jar;%LIBDIR%\junit.jar;%LIBDIR%\activation.jar;%LIBDIR%\commons-net-1.1.0.jar;%LIBDIR%\mx4j.jar;%LIBDIR%\mx4j-tools.jar;%LIBDIR%\mx4j-remote.jar;%LIBDIR%\fast-md5.jar;%DISTRIBDIR%\dist\agent\lib\cc-agent.jar;%LIBS_JINI%;. +set CRUISE_PATH=%CRUISE_PATH%;%DISTDIR%\cruisecontrol.jar;%LIBDIR%\log4j.jar;%LIBDIR%\jdom.jar;%LIBDIR%\ant\ant.jar;%LIBDIR%\ant\ant-launcher.jar;%LIBDIR%\xml-apis-2.8.0.jar;%LIBDIR%\xercesImpl-2.8.0.jar;%LIBDIR%\xalan-2.7.0.jar;%LIBDIR%\serializer-2.7.0.jar;%LIBDIR%\jakarta-oro-2.0.3.jar;%LIBDIR%\mail.jar;%LIBDIR%\junit.jar;%LIBDIR%\activation.jar;%LIBDIR%\commons-net-1.1.0.jar;%LIBDIR%\mx4j.jar;%LIBDIR%\mx4j-tools.jar;%LIBDIR%\mx4j-remote.jar;%LIBDIR%\fast-md5.jar;%LIBDIR%\maven-embedder-2.0.3-dep.jar;%DISTRIBDIR%\dist\agent\lib\cc-agent.jar;%LIBS_JINI%;. set EXEC="%JAVA_HOME%\bin\java" %CC_OPTS% -cp "%CRUISE_PATH%" -Djavax.management.builder.initial=mx4j.server.MX4JMBeanServerBuilder -Djava.security.policy=%DISTRIBDIR%\conf\insecure.policy CruiseControl -debug %* echo %EXEC% Modified: trunk/cruisecontrol/contrib/distributed/cruisecontrol.sh =================================================================== --- trunk/cruisecontrol/contrib/distributed/cruisecontrol.sh 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/contrib/distributed/cruisecontrol.sh 2006-04-30 15:41:09 UTC (rev 2521) @@ -74,7 +74,7 @@ DISTRIBDIR=$CCDIR/../contrib/distributed LIBS_JINI=$DISTRIBDIR/lib/jini-core.jar:$DISTRIBDIR/lib/jini-ext.jar:$DISTRIBDIR/lib/jsk-platform.jar:$DISTRIBDIR/lib/reggie.jar:$DISTRIBDIR/lib/reggie-dl.jar:$DISTRIBDIR/lib/start.jar:$DISTRIBDIR/lib/tools.jar:$DISTRIBDIR/conf -CRUISE_PATH=$JAVA_HOME/lib/tools.jar:$DISTDIR/cruisecontrol.jar:$LIBDIR/log4j.jar:$LIBDIR/jdom.jar:$LIBDIR/ant/ant.jar:$LIBDIR/ant/ant-launcher.jar:$LIBDIR/xml-apis-2.7.0.jar:$LIBDIR/xercesImpl-2.7.0.jar:$LIBDIR/xalan-2.6.0.jar:$LIBDIR/jakarta-oro-2.0.3.jar:$LIBDIR/mail.jar:$LIBDIR/junit.jar:$LIBDIR/activation.jar:$LIBDIR/commons-net-1.1.0.jar:$LIBDIR/starteam-sdk.jar:$LIBDIR/mx4j.jar:$LIBDIR/mx4j-tools.jar:$LIBDIR/mx4j-remote.jar:$LIBDIR/smack.jar:$LIBDIR/fast-md5.jar:$DISTRIBDIR/dist/agent/lib/cc-agent.jar:$LIBS_JINI:. +CRUISE_PATH=$JAVA_HOME/lib/tools.jar:$DISTDIR/cruisecontrol.jar:$LIBDIR/log4j.jar:$LIBDIR/jdom.jar:$LIBDIR/ant/ant.jar:$LIBDIR/ant/ant-launcher.jar:$LIBDIR/xml-apis-2.8.0.jar:$LIBDIR/xercesImpl-2.8.0.jar:$LIBDIR/xalan-2.7.0.jar:$LIBDIR/serializer-2.7.0.jar:$LIBDIR/jakarta-oro-2.0.3.jar:$LIBDIR/mail.jar:$LIBDIR/junit.jar:$LIBDIR/activation.jar:$LIBDIR/commons-net-1.1.0.jar:$LIBDIR/starteam-sdk.jar:$LIBDIR/mx4j.jar:$LIBDIR/mx4j-tools.jar:$LIBDIR/mx4j-remote.jar:$LIBDIR/smack.jar:$LIBDIR/fast-md5.jar:$LIBDIR/maven-embedder-2.0.3-dep.jar:$DISTRIBDIR/dist/agent/lib/cc-agent.jar:$LIBS_JINI:. # convert the existing path to unix if [ `uname | grep -n CYGWIN` ]; then Modified: trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/builders/DistributedMasterBuilder.java =================================================================== --- trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/builders/DistributedMasterBuilder.java 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/builders/DistributedMasterBuilder.java 2006-04-30 15:41:09 UTC (rev 2521) @@ -91,12 +91,12 @@ private Element thisElement; private Element childBuilderElement; - private String overrideTarget = ""; + private String overrideTarget; private MulticastDiscovery discovery; private Properties cruiseProperties; private File rootDir; - protected void overrideTarget(String target) { + protected void overrideTarget(final String target) { overrideTarget = target; } @@ -106,7 +106,7 @@ /** If true, available agent lookup will not block until an agent is found, * but will return null immediately. */ - public synchronized void setFailFast(boolean isFailFast) { + public synchronized void setFailFast(final boolean isFailFast) { this.isFailFast = isFailFast; } private synchronized boolean isFailFast() { @@ -114,7 +114,7 @@ } /** Intended only for use by unit tests. **/ - void setDiscovery(MulticastDiscovery multicastDiscovery) { + void setDiscovery(final MulticastDiscovery multicastDiscovery) { discovery = multicastDiscovery; } MulticastDiscovery getDiscovery() { @@ -131,16 +131,16 @@ * @param element * @throws net.sourceforge.cruisecontrol.CruiseControlException */ - public void configure(Element element) throws CruiseControlException { + public void configure(final Element element) throws CruiseControlException { thisElement = element; - List children = element.getChildren(); + final List children = element.getChildren(); if (children.size() > 1) { - String message = "DistributedMasterBuilder can only have one nested builder"; + final String message = "DistributedMasterBuilder can only have one nested builder"; LOG.error(message); throw new CruiseControlException(message); } else if (children.size() == 0) { // @todo Clarify when configure() can be called... - String message = "Nested Builder required by DistributedMasterBuilder, " + final String message = "Nested Builder required by DistributedMasterBuilder, " + "ignoring and assuming this call is during plugin-preconfig"; LOG.warn(message); return; @@ -170,16 +170,16 @@ // optional attributes tempAttribute = thisElement.getAttribute("agentlogdir"); - setAgentLogDir(tempAttribute != null ? tempAttribute.getValue() : ""); + setAgentLogDir(tempAttribute != null ? tempAttribute.getValue() : null); tempAttribute = thisElement.getAttribute("agentoutputdir"); - setAgentOutputDir(tempAttribute != null ? tempAttribute.getValue() : ""); + setAgentOutputDir(tempAttribute != null ? tempAttribute.getValue() : null); tempAttribute = thisElement.getAttribute("masterlogdir"); - setMasterLogDir(tempAttribute != null ? tempAttribute.getValue() : ""); + setMasterLogDir(tempAttribute != null ? tempAttribute.getValue() : null); tempAttribute = thisElement.getAttribute("masteroutputdir"); - setMasterOutputDir(tempAttribute != null ? tempAttribute.getValue() : ""); + setMasterOutputDir(tempAttribute != null ? tempAttribute.getValue() : null); try { cruiseProperties = (Properties) PropertiesHelper.loadRequiredProperties(CRUISE_PROPERTIES); @@ -195,7 +195,7 @@ && (getAgentLogDir() == null && getMasterLogDir() == null) && (getAgentOutputDir() == null && getMasterOutputDir() == null) ) { - String message = "Could not get property " + CRUISE_RUN_DIR + " from " + CRUISE_PROPERTIES + final String message = "Could not get property " + CRUISE_RUN_DIR + " from " + CRUISE_PROPERTIES + ", or run dir does not exist: " + rootDir; LOG.error(message); System.err.println(message); @@ -215,7 +215,7 @@ private static void applyPluginDefaults(final Map pluginDefaults, final Element elementToAlter) { final String pluginName = elementToAlter.getName(); // to preserve precedence, only add default attribute if it is not also defined in the tag directly - Set defaultAttribMapKeys = pluginDefaults.keySet(); + final Set defaultAttribMapKeys = pluginDefaults.keySet(); for (Iterator itrKeys = defaultAttribMapKeys.iterator(); itrKeys.hasNext();) { final String attribName = (String) itrKeys.next(); final String attribValueExisting = elementToAlter.getAttributeValue(attribName); @@ -305,7 +305,7 @@ super.validate(); final Element elmChildBuilder = getChildBuilderElement(); if (elmChildBuilder == null) { - String message = "A nested Builder is required for DistributedMasterBuilder"; + final String message = "A nested Builder is required for DistributedMasterBuilder"; LOG.warn(message); throw new CruiseControlException(message); } @@ -325,7 +325,7 @@ //*/ if (module == null) { - String message = "The 'module' attribute is required for DistributedMasterBuilder"; + final String message = "The 'module' attribute is required for DistributedMasterBuilder"; LOG.warn(message); throw new CruiseControlException(message); } @@ -373,21 +373,41 @@ return retVal; } + public Element buildWithTarget(Map properties, String target) throws CruiseControlException { + String oldOverideTarget = overrideTarget; + overrideTarget(target); + try { + return build(properties); + } finally { + overrideTarget(oldOverideTarget); + } + } - public Element build(Map projectProperties) throws CruiseControlException { + public Element build(final Map projectProperties) throws CruiseControlException { try { final BuildAgentService agent = pickAgent(); // agent is now marked as claimed + String agentMachine = "unknown"; + try { + agentMachine = agent.getMachineName(); + } catch (RemoteException e1) { + ; // ignored + } + final Element buildResults; try { - projectProperties.put(PropertiesHelper.DISTRIBUTED_OVERRIDE_TARGET, overrideTarget); - projectProperties.put(PropertiesHelper.DISTRIBUTED_MODULE, module); - projectProperties.put(PropertiesHelper.DISTRIBUTED_AGENT_LOGDIR, getAgentLogDir()); - projectProperties.put(PropertiesHelper.DISTRIBUTED_AGENT_OUTPUTDIR, getAgentOutputDir()); - + final Map distributedAgentProps = new HashMap(); + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_OVERRIDE_TARGET, overrideTarget); + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_MODULE, module); + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_AGENT_LOGDIR, getAgentLogDir()); + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_AGENT_OUTPUTDIR, getAgentOutputDir()); + LOG.debug("Distributed Agent Props: " + distributedAgentProps.toString()); + + LOG.debug("Project Props: " + projectProperties.toString()); + LOG.info("Starting remote build on agent: " + agent.getMachineName() + " of module: " + module); - buildResults = agent.doBuild(getChildBuilderElement(), projectProperties); + buildResults = agent.doBuild(getChildBuilderElement(), projectProperties, distributedAgentProps); final String rootDirPath; try { @@ -395,7 +415,7 @@ LOG.debug("rootDir: " + rootDir + "; rootDir.cp: " + rootDir.getCanonicalPath()); rootDirPath = rootDir.getCanonicalPath(); } catch (IOException e) { - String message = "Error getting canonical path for: " + rootDir; + final String message = "Error getting canonical path for: " + rootDir; LOG.error(message); System.err.println(message); throw new CruiseControlException(message, e); @@ -420,13 +440,7 @@ agent.clearOutputFiles(); } catch (RemoteException e) { - String agentMachine = "unknown"; - try { - agentMachine = agent.getMachineName(); - } catch (RemoteException e1) { - ; // ignored - } - String message = "RemoteException from" + final String message = "RemoteException from" + "\nagent on: " + agentMachine + "\nwhile building module: " + module; LOG.error(message, e); @@ -441,7 +455,7 @@ } return buildResults; } catch (RuntimeException e) { - String message = "Distributed build runtime exception"; + final String message = "Distributed build runtime exception"; LOG.error(message, e); System.err.println(message + " - " + e.getMessage()); throw new CruiseControlException(message, e); @@ -453,7 +467,7 @@ throws RemoteException { if (agent.resultsExist(resultsType)) { - String zipFilePath = FileUtil.bytesToFile(agent.retrieveResultsAsZip(resultsType), rootDirPath, + final String zipFilePath = FileUtil.bytesToFile(agent.retrieveResultsAsZip(resultsType), rootDirPath, resultsType + ".zip"); try { LOG.info("unzip " + resultsType + " (" + zipFilePath + ") to: " + masterDir); @@ -464,7 +478,7 @@ LOG.debug("Ignored retrieve " + resultsType + " results error:", e); } } else { - String message = "No results returned for " + resultsType; + final String message = "No results returned for " + resultsType; LOG.info(message); } } @@ -508,7 +522,7 @@ return agentLogDir; } - public void setAgentLogDir(String agentLogDir) { + public void setAgentLogDir(final String agentLogDir) { this.agentLogDir = agentLogDir; } @@ -516,7 +530,7 @@ return agentOutputDir; } - public void setAgentOutputDir(String agentOutputDir) { + public void setAgentOutputDir(final String agentOutputDir) { this.agentOutputDir = agentOutputDir; } @@ -524,7 +538,7 @@ return masterLogDir; } - public void setMasterLogDir(String masterLogDir) { + public void setMasterLogDir(final String masterLogDir) { this.masterLogDir = masterLogDir; } @@ -532,7 +546,7 @@ return masterOutputDir; } - public void setMasterOutputDir(String masterOutputDir) { + public void setMasterOutputDir(final String masterOutputDir) { this.masterOutputDir = masterOutputDir; } } Modified: trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/distributed/BuildAgentService.java =================================================================== --- trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/distributed/BuildAgentService.java 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/distributed/BuildAgentService.java 2006-04-30 15:41:09 UTC (rev 2521) @@ -46,10 +46,12 @@ public interface BuildAgentService extends Remote { - public Element doBuild(Element nestedBuilderElement, Map projectProperties) throws RemoteException; + public Element doBuild(Element nestedBuilderElement, Map projectProperties, + Map distributedAgentProperties) throws RemoteException; public String getMachineName() throws RemoteException; + /** @return the date this Build Agent started running (not when a specific build started). */ public Date getDateStarted() throws RemoteException; public void claim() throws RemoteException; @@ -58,6 +60,7 @@ public boolean isBusy() throws RemoteException; + /** @return the module being built now, or null if no module is being built. */ public String getModule() throws RemoteException; public boolean resultsExist(String resultsType) throws RemoteException; Modified: trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/distributed/BuildAgentServiceImpl.java =================================================================== --- trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/distributed/BuildAgentServiceImpl.java 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/contrib/distributed/src/net/sourceforge/cruisecontrol/distributed/BuildAgentServiceImpl.java 2006-04-30 15:41:09 UTC (rev 2521) @@ -50,6 +50,7 @@ import java.util.Date; import java.util.List; import java.util.ArrayList; +import java.util.HashMap; import net.sourceforge.cruisecontrol.Builder; import net.sourceforge.cruisecontrol.CruiseControlException; @@ -67,6 +68,9 @@ import javax.jnlp.BasicService; import javax.jnlp.UnavailableServiceException; +/** + * Build Agent implementation. + */ public class BuildAgentServiceImpl implements BuildAgentService, Serializable { private static final Logger LOG = Logger.getLogger(BuildAgentServiceImpl.class); @@ -78,6 +82,9 @@ static final String DEFAULT_USER_DEFINED_PROPERTIES_FILE = "user-defined.properties"; + /** Cache host name. */ + private final String machineName; + private final Date dateStarted; private boolean isBusy; private Date dateClaimed; @@ -86,9 +93,9 @@ private boolean isPendingRestart; private Date pendingRestartSince; - private Properties configProperties; - private Properties projectProperties = new Properties(); - private String logDir = ""; + private Properties configProperties; + private final Map distributedAgentProps = new HashMap(); + private String logDir; private String outputDir; private String buildRootDir; private String logsFilePath; @@ -96,16 +103,68 @@ private final List agentStatusListeners = new ArrayList(); + private final String logMsgPrefix; + /** + * Prepends Agent machine name to error message. This is especially + * useful when combined with an "email logger" config for Log4j using a modified + * log4j.properties on build agents. For example: + * <pre> + * log4j.rootCategory=INFO,A1,FILE,Mail + * + * ... + * + * # Mail is set to be a SMTPAppender + * log4j.appender.Mail=org.apache.log4j.net.SMTPAppender + * log4j.appender.Mail.BufferSize=100 + * log4j.appender.Mail.From=cc...@yo... + * log4j.appender.Mail.SMTPHost=yoursmtp.mailhost.com + * log4j.appender.Mail.Subject=CC has had an error!!! + * log4j.appender.Mail.To=you...@yo... + * log4j.appender.Mail.layout=org.apache.log4j.PatternLayout + * log4j.appender.Mail.layout.ConversionPattern=%d{dd.MM.yyyy HH:mm:ss} %-5p [%x] [%c{3}] %m%n + * + * </pre> + * + * @param message the message to log (will be prefixed with machineName). + */ + private final void logPrefixDebug(final Object message) { + LOG.debug(logMsgPrefix + message); + } + private final void logPrefixInfo(final Object message) { + LOG.info(logMsgPrefix + message); + } + private final void logPrefixError(final Object message) { + LOG.error(logMsgPrefix + message); + } + private final void logPrefixError(final Object message, final Throwable throwable) { + LOG.error(logMsgPrefix + message, throwable); + } + + + /** Constructor. */ public BuildAgentServiceImpl() { dateStarted = new Date(); + + try { + machineName = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + final String message = "Failed to get hostname"; + // Don't call Log helper method here since hostname is not yet set + LOG.error(message, e); + System.err.println(message + " - " + e.getMessage()); + throw new RuntimeException(message, e); + } + logMsgPrefix = "Agent Host: " + machineName + "; "; } + /** @return the date this Build Agent started running (not when a specific build started). */ public Date getDateStarted() { return dateStarted; } + /** @return the module being built now, or null if no module is being built. */ public synchronized String getModule() { - return projectProperties.getProperty(PropertiesHelper.DISTRIBUTED_MODULE); + return (String) distributedAgentProps.get(PropertiesHelper.DISTRIBUTED_MODULE); } void setAgentPropertiesFilename(final String filename) { @@ -126,9 +185,9 @@ doKill(); } - // clear out projectProperties from last build - projectProperties.clear(); - + // clear out distributed build agent props + distributedAgentProps.clear(); + dateClaimed = null; } else { dateClaimed = new Date(); @@ -140,25 +199,32 @@ fireAgentStatusChanged(); - LOG.info("agent busy status changed to: " + newIsBusy); + logPrefixInfo("agent busy status changed to: " + newIsBusy); } - public Element doBuild(Element nestedBuilderElement, Map projectPropertiesMap) throws RemoteException { + public Element doBuild(final Element nestedBuilderElement, final Map projectPropertiesMap, + final Map distributedAgentProperties) throws RemoteException { synchronized (busyLock) { if (!isBusy()) { // only reclaim if needed, since it resets the dateClaimed. - setBusy(true); // we could remove this, since claim() is called during lookup... + setBusy(true); // we could remove this, since claim() is called during lookup... } } try { - projectProperties.putAll(projectPropertiesMap); - String infoMessage = "Building module: " + getModule() - + "\n\tAgentLogDir: " + projectProperties.getProperty(PropertiesHelper.DISTRIBUTED_AGENT_LOGDIR) - + "\n\tAgentOutputDir: " + projectProperties.getProperty( + logPrefixDebug("Build Agent Props: " + distributedAgentProperties.toString()); + distributedAgentProps.putAll(distributedAgentProperties); + + final String infoMessage = "Building module: " + getModule() + + "\n\tAgentLogDir: " + distributedAgentProps.get( + PropertiesHelper.DISTRIBUTED_AGENT_LOGDIR) + + "\n\tAgentOutputDir: " + distributedAgentProps.get( PropertiesHelper.DISTRIBUTED_AGENT_OUTPUTDIR); System.out.println(); System.out.println(infoMessage); - LOG.info(infoMessage); + logPrefixInfo(infoMessage); + + logPrefixDebug("Build Agent Project Props: " + projectPropertiesMap.toString()); + // this is done only to update agent UI info regarding Module - which isn't available // until projectPropertiesMap has been set. fireAgentStatusChanged(); @@ -169,8 +235,8 @@ nestedBuilder = createBuilder(nestedBuilderElement); nestedBuilder.validate(); } catch (CruiseControlException e) { - String message = "Failed to configure nested Builder on agent"; - LOG.error(message, e); + final String message = "Failed to configure nested Builder on agent"; + logPrefixError(message, e); System.err.println(message + " - " + e.getMessage()); throw new RemoteException(message, e); } @@ -178,45 +244,46 @@ try { buildResults = nestedBuilder.build(projectPropertiesMap); } catch (CruiseControlException e) { - String message = "Failed to complete build on agent"; - LOG.error(message, e); + final String message = "Failed to complete build on agent"; + logPrefixError(message, e); System.err.println(message + " - " + e.getMessage()); throw new RemoteException(message, e); } prepareLogsAndArtifacts(); return buildResults; } catch (RemoteException e) { - LOG.error("doBuild threw exception, setting busy to false."); + logPrefixError("doBuild threw exception, setting busy to false."); setBusy(false); throw e; // rethrow original exception } } - private Builder createBuilder(Element builderElement) throws CruiseControlException { + private Builder createBuilder(final Element builderElement) throws CruiseControlException { configProperties = (Properties) PropertiesHelper.loadRequiredProperties( getAgentPropertiesFilename()); - final String overrideTarget = projectProperties.getProperty(PropertiesHelper.DISTRIBUTED_OVERRIDE_TARGET); - PluginXMLHelper pluginXMLHelper = PropertiesHelper.createPluginXMLHelper(overrideTarget); + final String overrideTarget + = (String) distributedAgentProps.get(PropertiesHelper.DISTRIBUTED_OVERRIDE_TARGET); + final PluginXMLHelper pluginXMLHelper = PropertiesHelper.createPluginXMLHelper(overrideTarget); - PluginRegistry plugins = PluginRegistry.createRegistry(); - Class pluginClass = plugins.getPluginClass(builderElement.getName()); + final PluginRegistry plugins = PluginRegistry.createRegistry(); + final Class pluginClass = plugins.getPluginClass(builderElement.getName()); final Builder builder = (Builder) pluginXMLHelper.configure(builderElement, pluginClass, false); return builder; } /** - * + * Zip any build artifacts found in the logDir and/or outputDir. */ private void prepareLogsAndArtifacts() { - String buildDirProperty = configProperties.getProperty(CRUISE_BUILD_DIR); + final String buildDirProperty = configProperties.getProperty(CRUISE_BUILD_DIR); try { buildRootDir = new File(buildDirProperty).getCanonicalPath(); } catch (IOException e) { - String message = "Couldn't create " + buildDirProperty; - LOG.error(message, e); + final String message = "Couldn't create " + buildDirProperty; + logPrefixError(message, e); System.err.println(message + " - " + e.getMessage()); throw new RuntimeException(message); } @@ -236,8 +303,8 @@ private String getAgentResultDir(final String resultType, final String resultProperty) { String resultDir; - resultDir = projectProperties.getProperty(resultProperty); - LOG.debug("Result: " + resultType + "Prop value: " + resultDir); + resultDir = (String) distributedAgentProps.get(resultProperty); + logPrefixDebug("Result: " + resultType + "Prop value: " + resultDir); if (resultDir == null || "".equals(resultDir)) { // use canonical behavior if attribute is not set @@ -248,14 +315,7 @@ } public String getMachineName() { - try { - return InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - String message = "Failed to get hostname"; - LOG.error(message, e); - System.err.println(message + " - " + e.getMessage()); - throw new RuntimeException(message, e); - } + return machineName; } public void claim() { @@ -263,9 +323,7 @@ // when multiple master threads find the same agent, before any build thread has started. synchronized (busyLock) { if (isBusy()) { - String machineName = "unknown"; - machineName = getMachineName(); - throw new IllegalStateException("Cannot claim agent on " + machineName + throw new IllegalStateException("Cannot claim agent on " + getMachineName() + " that is busy building module: " + getModule()); } @@ -275,7 +333,7 @@ public boolean isBusy() { synchronized (busyLock) { - LOG.debug("Is busy called. value: " + isBusy); + logPrefixDebug("Is busy called. value: " + isBusy); return isBusy; } } @@ -316,7 +374,7 @@ } - public boolean resultsExist(String resultsType) throws RemoteException { + public boolean resultsExist(final String resultsType) throws RemoteException { if (resultsType.equals(PropertiesHelper.RESULT_TYPE_LOGS)) { return !(new File(logDir).list().length == 0); } else if (resultsType.equals(PropertiesHelper.RESULT_TYPE_OUTPUT)) { @@ -326,7 +384,7 @@ } } - public byte[] retrieveResultsAsZip(String resultsType) throws RemoteException { + public byte[] retrieveResultsAsZip(final String resultsType) throws RemoteException { final String zipFilePath = buildRootDir + File.separator + resultsType + ".zip"; @@ -334,8 +392,8 @@ try { response = FileUtil.getFileAsBytes(new File(zipFilePath)); } catch (IOException e) { - String message = "Unable to get file " + zipFilePath; - LOG.error(message, e); + final String message = "Unable to get file " + zipFilePath; + logPrefixError(message, e); System.err.println(message + " - " + e.getMessage()); throw new RuntimeException(message, e); } @@ -344,33 +402,43 @@ public void clearOutputFiles() { try { - LOG.debug("Deleting contents of " + logDir); - Util.deleteFile(new File(logDir)); + if (logDir != null) { + logPrefixDebug("Deleting contents of " + logDir); + Util.deleteFile(new File(logDir)); + } else { + logPrefixDebug("Skip delete agent logDir: " + logDir); + } if (logsFilePath != null) { - LOG.debug("Deleting log zip " + logsFilePath); + logPrefixDebug("Deleting log zip " + logsFilePath); Util.deleteFile(new File(logsFilePath)); } else { - LOG.error("Skipping delete of log zip, file path is null."); + logPrefixError("Skipping delete of log zip, file path is null."); } - LOG.debug("Deleting contents of " + outputDir); - Util.deleteFile(new File(outputDir)); + if (outputDir != null) { + logPrefixDebug("Deleting contents of " + outputDir); + Util.deleteFile(new File(outputDir)); + } else { + logPrefixDebug("Skip delete agent outputDir: " + outputDir); + } if (outputFilePath != null) { - LOG.debug("Deleting output zip " + outputFilePath); + logPrefixDebug("Deleting output zip " + outputFilePath); Util.deleteFile(new File(outputFilePath)); } else { - LOG.error("Skipping delete of output zip, file path is null."); + logPrefixError("Skipping delete of output zip, file path is null."); } + setBusy(false); + } catch (RuntimeException e) { - LOG.error("Error cleaning agent build files.", e); + logPrefixError("Error cleaning agent build files.", e); throw e; } } private void doRestart() { - LOG.info("Attempting agent restart."); + logPrefixInfo("Attempting agent restart."); synchronized (busyLock) { if (!isBusy()) { @@ -384,11 +452,11 @@ basicService = (BasicService) ServiceManager.lookup(BasicService.class.getName()); } catch (UnavailableServiceException e) { final String errMsg = "Couldn't find webstart Basic Service. Is Agent running outside of webstart?"; - LOG.error(errMsg, e); + logPrefixError(errMsg, e); throw new RuntimeException(errMsg, e); } final URL codeBaseURL = basicService.getCodeBase(); - LOG.info("basicService.getCodeBase()=" + codeBaseURL.toString()); + logPrefixInfo("basicService.getCodeBase()=" + codeBaseURL.toString()); // relaunch via new browser session // @todo How to close the browser after jnlp is relaunched? @@ -397,21 +465,21 @@ relaunchURL = new URL(codeBaseURL, "agent.jnlp"); } catch (MalformedURLException e) { final String errMsg = "Error building webstart relaunch URL from " + codeBaseURL.toString(); - LOG.error(errMsg, e); + logPrefixError(errMsg, e); throw new RuntimeException(errMsg, e); } if (basicService.showDocument(relaunchURL)) { - LOG.info("Relaunched agent via URL: " + relaunchURL.toString() + ". Will kill current agent now."); + logPrefixInfo("Relaunched agent via URL: " + relaunchURL.toString() + ". Will kill current agent now."); doKill(); // don't wait for build finish, since we've already relaunched at this point. } else { final String errMsg = "Failed to relaunch agent via URL: " + relaunchURL.toString(); - LOG.error(errMsg); + logPrefixError(errMsg); throw new RuntimeException(errMsg); } } private void doKill() { - LOG.info("Attempting agent kill."); + logPrefixInfo("Attempting agent kill."); synchronized (busyLock) { if (!isBusy()) { // claim agent so no new build can start Modified: trunk/cruisecontrol/contrib/distributed/test/net/sourceforge/cruisecontrol/distributed/BuildAgentServiceImplTest.java =================================================================== --- trunk/cruisecontrol/contrib/distributed/test/net/sourceforge/cruisecontrol/distributed/BuildAgentServiceImplTest.java 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/contrib/distributed/test/net/sourceforge/cruisecontrol/distributed/BuildAgentServiceImplTest.java 2006-04-30 15:41:09 UTC (rev 2521) @@ -2,9 +2,10 @@ import junit.framework.TestCase; -import java.util.Properties; import java.util.Arrays; import java.util.Date; +import java.util.Map; +import java.util.HashMap; import java.io.File; import java.rmi.RemoteException; @@ -52,6 +53,82 @@ } + private static class MyAgentStatusListener implements BuildAgent.AgentStatusListener + { + private int agentStatusChangeCount; + + public void statusChanged(BuildAgentService buildAgentServiceImpl) { + agentStatusChangeCount++; + } + + int getAgentStatusChangeCount() { + return agentStatusChangeCount; + } + + void setAgentStatusChangeCount(int agentStatusChangeCount) { + this.agentStatusChangeCount = agentStatusChangeCount; + } + } + + /** + * Re-use of builder caused problems with null value in overrideTarget. + * This test verifies null values in the Map are allowed. + */ + public void testGetPropertiesMap() throws Exception { + final BuildAgentServiceImpl agentImpl = new BuildAgentServiceImpl(); + agentImpl.setAgentPropertiesFilename(TEST_AGENT_PROPERTIES_FILE); + + MyAgentStatusListener agentListener = new MyAgentStatusListener(); + agentImpl.addAgentStatusListener(agentListener); + + String agentAsString = agentImpl.asString(); + assertTrue("Wrong value: " + agentAsString, + agentAsString.startsWith("Machine Name: ")); + assertTrue("Wrong value: " + agentAsString, + agentAsString.endsWith("Busy: false;\tSince: null;\tModule: null\n\t" + + "Pending Restart: false;\tPending Restart Since: null\n\t" + + "Pending Kill: false;\tPending Kill Since: null")); + + + final Map distributedAgentProps = new HashMap(); + final String testModuleName = "testModuleName"; + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_MODULE, testModuleName); + + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_OVERRIDE_TARGET, null); + try { + // fails at old props.putAll() and now at projectPropertiesMap.toString(), + // doesn't fire 2nd agent status event + agentImpl.doBuild(null, null, distributedAgentProps); + fail("should fail w/ NPE"); + } catch (NullPointerException e) { + assertEquals(null, e.getMessage()); + } + assertEquals("Wrong agent status", 1, agentListener.getAgentStatusChangeCount()); + + + distributedAgentProps.remove(PropertiesHelper.DISTRIBUTED_OVERRIDE_TARGET); + agentImpl.setBusy(false); + agentListener.setAgentStatusChangeCount(0); + try { + // gets far enough to fire 2nd agent status change + agentImpl.doBuild(null, new HashMap(), distributedAgentProps); + fail("should fail w/ NPE"); + } catch (NullPointerException e) { + assertEquals(null, e.getMessage()); + } + assertEquals("Wrong agent status", 2, agentListener.getAgentStatusChangeCount()); + + agentAsString = agentImpl.asString(); + assertTrue("Wrong value: " + agentAsString, + agentAsString.startsWith("Machine Name: ")); + assertTrue("Wrong value: " + agentAsString, + agentAsString.indexOf("Busy: true;\tSince: ") > -1); + assertTrue("Wrong value: " + agentAsString, + agentAsString.endsWith(";\tModule: " + testModuleName + + "\n\tPending Restart: false;\tPending Restart Since: null\n\t" + + "Pending Kill: false;\tPending Kill Since: null")); + } + public void testAsString() throws Exception { final BuildAgentServiceImpl agentImpl = new BuildAgentServiceImpl(); agentImpl.setAgentPropertiesFilename(TEST_AGENT_PROPERTIES_FILE); @@ -64,12 +141,14 @@ + "Pending Restart: false;\tPending Restart Since: null\n\t" + "Pending Kill: false;\tPending Kill Since: null")); + final Map projectProps = null; + + final Map distributedAgentProps = new HashMap(); final String testModuleName = "testModuleName"; - final Properties projectProps = new Properties(); - projectProps.put(PropertiesHelper.DISTRIBUTED_MODULE, testModuleName); + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_MODULE, testModuleName); try { - agentImpl.doBuild(null, projectProps); // gets far enough to set Module name... + agentImpl.doBuild(null, projectProps, distributedAgentProps); // gets far enough to set Module name... fail("should fail w/ NPE"); } catch (NullPointerException e) { assertEquals(null, e.getMessage()); @@ -110,12 +189,14 @@ assertNull(agentImpl.getModule()); + final Map projectProps = null; + + final Map distributedAgentProps = new HashMap(); final String testModuleName = "testModuleName"; - final Properties projectProps = new Properties(); - projectProps.put(PropertiesHelper.DISTRIBUTED_MODULE, testModuleName); + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_MODULE, testModuleName); try { - agentImpl.doBuild(null, projectProps); // gets far enough to set Module name... + agentImpl.doBuild(null, projectProps, distributedAgentProps); // gets far enough to set Module name... fail("should fail w/ NPE"); } catch (NullPointerException e) { assertEquals(null, e.getMessage()); @@ -237,8 +318,43 @@ } } + public void testRetrieveResultsWithAgentLogDir() throws Exception { + final File testLogDir = new File(DIR_LOGS, "myTestLogDir"); + testLogDir.deleteOnExit(); + testLogDir.mkdirs(); + final File testLog = new File(testLogDir, "myTestLog"); + testLog.createNewFile(); + testLog.deleteOnExit(); + + final Map distributedAgentProps = new HashMap(); + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_AGENT_LOGDIR, + testLogDir.getAbsolutePath()); + + final BuildAgentServiceImpl agentImpl = createTestAgent(false, distributedAgentProps); + + // clear out default log dir + final File tmSuccessDir = new File(DIR_LOGS, "testmodule-success"); + new File(tmSuccessDir, "TEST-bogustestclassSuccess.xml").delete(); + deleteDirConfirm(tmSuccessDir); + + try { + // make sure agent looks in myTestLog dir for files + assertTrue(agentImpl.resultsExist(PropertiesHelper.RESULT_TYPE_LOGS)); + + assertTrue(agentImpl.resultsExist(PropertiesHelper.RESULT_TYPE_OUTPUT)); + assertTrue("Agent should be busy until build results are retrived and cleared.", + agentImpl.isBusy()); + } finally { + // cleanup left over files + agentImpl.clearOutputFiles(); + testLog.delete(); + testLogDir.delete(); + } + assertFalse(agentImpl.isBusy()); + } + public void testRetrieveResultsAsZipBuildSuccess() throws Exception { - final BuildAgentServiceImpl agentImpl = createTestAgent(false); + final BuildAgentServiceImpl agentImpl = createTestAgent(false, new HashMap()); try { assertTrue(agentImpl.resultsExist(PropertiesHelper.RESULT_TYPE_LOGS)); assertTrue(agentImpl.resultsExist(PropertiesHelper.RESULT_TYPE_OUTPUT)); @@ -252,7 +368,7 @@ } public void testRetrieveResultsAsZipBuildFail() throws Exception { - final BuildAgentServiceImpl agentImpl = createTestAgent(true); + final BuildAgentServiceImpl agentImpl = createTestAgent(true, new HashMap()); try { assertTrue(agentImpl.resultsExist(PropertiesHelper.RESULT_TYPE_LOGS)); assertFalse(agentImpl.resultsExist(PropertiesHelper.RESULT_TYPE_OUTPUT)); @@ -265,21 +381,34 @@ assertFalse(agentImpl.isBusy()); } - private static BuildAgentServiceImpl createTestAgent(boolean isBuildFailure) + private static BuildAgentServiceImpl createTestAgent(boolean isBuildFailure, + final Map distributedAgentProps) throws CruiseControlException, RemoteException { final BuildAgentServiceImpl agentImpl = new BuildAgentServiceImpl(); agentImpl.setAgentPropertiesFilename(TEST_AGENT_PROPERTIES_FILE); // @todo Fix issues where AntBuilder fails if java is not on os path - callTestDoBuild(isBuildFailure, agentImpl); + callTestDoBuild(isBuildFailure, agentImpl, distributedAgentProps); return agentImpl; } + /** Call doBuild() on the given agent using test settings */ public static Element callTestDoBuild(boolean isBuildFailure, - final BuildAgentService agent) throws CruiseControlException, RemoteException { + final BuildAgentService agent) + throws CruiseControlException, RemoteException { + + return callTestDoBuild(isBuildFailure, agent, new HashMap()); + } + + /** Call doBuild() on the given agent using test settings */ + public static Element callTestDoBuild(boolean isBuildFailure, + final BuildAgentService agent, + final Map distributedAgentProps) + throws CruiseControlException, RemoteException { + final Element rootElement = Util.loadConfigFile(TEST_CONFIG_FILE); final Element project = (Element) rootElement.getChildren("project").get(0); @@ -303,8 +432,11 @@ } final String moduleName = distributed.getAttributeValue("module"); assertEquals(expectedModuleName, moduleName); - final Properties projectProps = new Properties(); - projectProps.put(PropertiesHelper.DISTRIBUTED_MODULE, moduleName); + + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_MODULE, moduleName); + + // handle re-use case of DMB when overrideTarget is null + distributedAgentProps.put(PropertiesHelper.DISTRIBUTED_OVERRIDE_TARGET, null); final Element antBuilderElement = (Element) distributed.getChildren().get(0); DistributedMasterBuilderTest.addMissingPluginDefaults(antBuilderElement); @@ -317,7 +449,9 @@ LOG.warn("Unit Test couldn't find ANT_HOME env var. Might work if java/bin is in the path. Here goes..."); } - final Element buildResult = agent.doBuild(antBuilderElement, projectProps); + final Map projectProps = new HashMap(); + + final Element buildResult = agent.doBuild(antBuilderElement, projectProps, distributedAgentProps); return buildResult; } @@ -349,7 +483,7 @@ // @todo should agent expose a release() method to clear busy flag? try { - agentImpl.doBuild(null, null); + agentImpl.doBuild(null, null, null); fail("Should have failed to build"); } catch (NullPointerException e) { assertEquals("Unexpected build error: " + e.getMessage(), null, e.getMessage()); @@ -360,16 +494,9 @@ } assertEquals(firstClaimDate, agentImpl.getDateClaimed()); - try { - agentImpl.clearOutputFiles(); - fail("Expected agent cleanup to fail"); - } catch (NullPointerException e) { - assertEquals("Unexpected build error: " + e.getMessage(), null, e.getMessage()); - } - assertTrue("Expected agent busy flag to be true after cleanup failed.", agentImpl.isBusy()); - assertEquals(firstClaimDate, agentImpl.getDateClaimed()); - - agentImpl.setBusy(false); + // we now avoid NPE error during cleanup since logDir and outputDir can be null + agentImpl.clearOutputFiles(); + assertFalse("Expected agent busy flag to be false after cleanup call.", agentImpl.isBusy()); assertNull(agentImpl.getDateClaimed()); } } Modified: trunk/cruisecontrol/docs/contributions.html =================================================================== --- trunk/cruisecontrol/docs/contributions.html 2006-04-30 14:58:22 UTC (rev 2520) +++ trunk/cruisecontrol/docs/contributions.html 2006-04-30 15:41:09 UTC (rev 2521) @@ -52,12 +52,11 @@ <h2>Making Contributions</h2> - <p>Contributions should be mailed to the Developer <a href="contact.html"> - mailing list</a>. (Here is a discussion of why the SourceForge provided - <a href="sffeatures.html">tracking features are not used</a>.) The - contribution may be a patch or an entire file as an attachment. A - Committer will include the contribution in the repository. Not every - contribution will be committed to the repository.</p> + <p>Contributions should be submitted to the <a href="http://jira.public.thoughtworks.org/browse/CC">JIRA + issue tracking site</a>. Simple contributions may alternatively be ma... [truncated message content] |