continuum-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From c...@apache.org
Subject svn commit: r1161980 - in /continuum/trunk: ./ continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/ continuum-api/src/main/java/org/apache/continuum/builder/distributed/work/ continuum-buildagent/continuum-buildagent-core/src/m...
Date Fri, 26 Aug 2011 03:45:05 GMT
Author: ctan
Date: Fri Aug 26 03:45:05 2011
New Revision: 1161980

URL: http://svn.apache.org/viewvc?rev=1161980&view=rev
Log:
[CONTINUUM-2656] added a worker that will check every minute if the builds are still active
and stop them if they aren't

Added:
    continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/work/
    continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/work/ContinuumWorker.java
  (with props)
    continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/work/
    continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorker.java
  (with props)
    continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/work/
    continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorkerTest.java
  (with props)
Modified:
    continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java
    continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java
    continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/DefaultDistributedBuildService.java
    continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java
    continuum/trunk/continuum-core/src/main/resources/META-INF/spring-context.xml
    continuum/trunk/continuum-webapp/pom.xml
    continuum/trunk/continuum-webapp/src/main/webapp/WEB-INF/applicationContext.xml
    continuum/trunk/pom.xml

Modified: continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java?rev=1161980&r1=1161979&r2=1161980&view=diff
==============================================================================
--- continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java
(original)
+++ continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/manager/DistributedBuildManager.java
Fri Aug 26 03:45:05 2011
@@ -25,6 +25,7 @@ import java.util.Map;
 import org.apache.continuum.buildagent.NoBuildAgentException;
 import org.apache.continuum.buildagent.NoBuildAgentInGroupException;
 import org.apache.continuum.configuration.BuildAgentConfiguration;
+import org.apache.continuum.model.project.ProjectRunSummary;
 import org.apache.continuum.model.project.ProjectScmRoot;
 import org.apache.continuum.taskqueue.BuildProjectTask;
 import org.apache.continuum.taskqueue.PrepareBuildProjectsTask;
@@ -113,4 +114,8 @@ public interface DistributedBuildManager
         
     String getBuildAgentUrl( int projectId, int buildDefinitionId )
         throws ContinuumException;
+
+    List<ProjectRunSummary> getCurrentRuns();
+
+    void removeCurrentRun( int projectId, int buildDefinitionId );
 }

Added: continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/work/ContinuumWorker.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/work/ContinuumWorker.java?rev=1161980&view=auto
==============================================================================
--- continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/work/ContinuumWorker.java
(added)
+++ continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/work/ContinuumWorker.java
Fri Aug 26 03:45:05 2011
@@ -0,0 +1,6 @@
+package org.apache.continuum.builder.distributed.work;
+
+public interface ContinuumWorker
+{
+    void work();
+}

Propchange: continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/work/ContinuumWorker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/trunk/continuum-api/src/main/java/org/apache/continuum/builder/distributed/work/ContinuumWorker.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java?rev=1161980&r1=1161979&r2=1161980&view=diff
==============================================================================
--- continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java
(original)
+++ continuum/trunk/continuum-buildagent/continuum-buildagent-core/src/main/java/org/apache/continuum/buildagent/ContinuumBuildAgentServiceImpl.java
Fri Aug 26 03:45:05 2011
@@ -33,7 +33,6 @@ import org.apache.commons.lang.ArrayUtil
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.continuum.buildagent.buildcontext.BuildContext;
 import org.apache.continuum.buildagent.buildcontext.manager.BuildContextManager;
-import org.apache.continuum.buildagent.configuration.BuildAgentConfigurationException;
 import org.apache.continuum.buildagent.configuration.BuildAgentConfigurationService;
 import org.apache.continuum.buildagent.manager.BuildAgentManager;
 import org.apache.continuum.buildagent.manager.BuildAgentReleaseManager;

Modified: continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/DefaultDistributedBuildService.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/DefaultDistributedBuildService.java?rev=1161980&r1=1161979&r2=1161980&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/DefaultDistributedBuildService.java
(original)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/DefaultDistributedBuildService.java
Fri Aug 26 03:45:05 2011
@@ -11,6 +11,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.continuum.builder.distributed.manager.DistributedBuildManager;
 import org.apache.continuum.builder.distributed.util.DistributedBuildUtil;
 import org.apache.continuum.builder.utils.ContinuumBuildConstant;
 import org.apache.continuum.dao.BuildDefinitionDao;
@@ -88,6 +89,11 @@ public class DefaultDistributedBuildServ
      */
     private DistributedBuildUtil distributedBuildUtil;
 
+    /**
+     * @plexus.requirement
+     */
+    private DistributedBuildManager distributedBuildManager;
+
     public void updateBuildResult( Map<String, Object> context )
         throws ContinuumException
     {
@@ -167,6 +173,8 @@ public class DefaultDistributedBuildServ
             {
                 notifierDispatcher.buildComplete( project, buildDefinition, buildResult );
             }
+
+            distributedBuildManager.removeCurrentRun( projectId, buildDefinitionId );
         }
         catch ( ContinuumStoreException e )
         {

Modified: continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java?rev=1161980&r1=1161979&r2=1161980&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java
(original)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/manager/DefaultDistributedBuildManager.java
Fri Aug 26 03:45:05 2011
@@ -39,6 +39,7 @@ import org.apache.continuum.dao.BuildRes
 import org.apache.continuum.dao.ProjectDao;
 import org.apache.continuum.distributed.transport.slave.SlaveBuildAgentTransportClient;
 import org.apache.continuum.distributed.transport.slave.SlaveBuildAgentTransportService;
+import org.apache.continuum.model.project.ProjectRunSummary;
 import org.apache.continuum.model.project.ProjectScmRoot;
 import org.apache.continuum.taskqueue.BuildProjectTask;
 import org.apache.continuum.taskqueue.OverallDistributedBuildQueue;
@@ -83,6 +84,8 @@ public class DefaultDistributedBuildMana
     private Map<String, OverallDistributedBuildQueue> overallDistributedBuildQueues
=
         Collections.synchronizedMap( new HashMap<String, OverallDistributedBuildQueue>()
);
 
+    private List<ProjectRunSummary> currentRuns = Collections.synchronizedList( new
ArrayList<ProjectRunSummary>() );
+
     /**
      * @plexus.requirement
      */
@@ -415,8 +418,10 @@ public class DefaultDistributedBuildMana
         {
             try
             {
-                log.info( "Building project in the least busy agent {}", overallDistributedBuildQueue.getBuildAgentUrl()
);
+                String agentUrl = overallDistributedBuildQueue.getBuildAgentUrl();
+                log.info( "Building project in the least busy agent {}", agentUrl );
                 overallDistributedBuildQueue.addToDistributedBuildQueue( task );
+                createProjectRunSummaries( task, agentUrl );
             }
             catch ( TaskQueueException e )
             {
@@ -1758,6 +1763,79 @@ public class DefaultDistributedBuildMana
         return false;
     }
 
+    public List<ProjectRunSummary> getCurrentRuns()
+    {
+        return currentRuns;
+    }
+
+    public void removeCurrentRun( int projectId, int buildDefinitionId )
+    {
+        synchronized( currentRuns )
+        {
+            boolean found = false;
+            ProjectRunSummary runToDelete = null;
+
+            for ( ProjectRunSummary currentRun : currentRuns )
+            {
+                if ( currentRun.getProjectId() == projectId && currentRun.getBuildDefinitionId()
== buildDefinitionId )
+                {
+                    found = true;
+                    runToDelete = currentRun;
+                    break;
+                }
+            }
+
+            if ( found )
+            {
+                currentRuns.remove( runToDelete );
+            }
+        }
+    }
+
+    private void createProjectRunSummaries( PrepareBuildProjectsTask task, String buildAgentUrl
)
+    {
+        synchronized( currentRuns )
+        {
+            int projectGroupId = task.getProjectGroupId();
+            int projectScmRootId = task.getProjectScmRootId();
+            Map<Integer, Integer> map = task.getProjectsBuildDefinitionsMap();
+    
+            for ( int projectId : map.keySet() )
+            {
+                int buildDefinitionId = map.get( projectId );
+
+                ProjectRunSummary runToDelete = null;
+
+                // check if there is an existing current run with that project id and build
definition id
+                for ( ProjectRunSummary currentRun : currentRuns )
+                {
+                    if ( currentRun.getProjectId() == projectId && currentRun.getBuildDefinitionId()
== buildDefinitionId )
+                    {
+                        runToDelete = currentRun;
+                        break;
+                    }
+                }
+
+                if ( runToDelete != null )
+                {
+                    // previous run already finished, but was not removed from the list
+                    // removed it
+                    currentRuns.remove( runToDelete );
+                }
+
+                ProjectRunSummary run = new ProjectRunSummary();
+                run.setProjectGroupId( projectGroupId );
+                run.setProjectScmRootId( projectScmRootId );
+                run.setProjectId( projectId );
+                run.setBuildDefinitionId( buildDefinitionId );
+                run.setTriggeredBy( task.getBuildTrigger().getTriggeredBy() );
+                run.setTrigger( task.getBuildTrigger().getTrigger() );
+                run.setBuildAgentUrl( buildAgentUrl );
+                currentRuns.add( run );
+            }
+        }
+    }
+
     private void disableBuildAgent( String buildAgentUrl )
         throws ContinuumException
     {

Added: continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorker.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorker.java?rev=1161980&view=auto
==============================================================================
--- continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorker.java
(added)
+++ continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorker.java
Fri Aug 26 03:45:05 2011
@@ -0,0 +1,188 @@
+package org.apache.continuum.builder.distributed.work;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.continuum.builder.distributed.manager.DistributedBuildManager;
+import org.apache.continuum.dao.BuildDefinitionDao;
+import org.apache.continuum.dao.BuildResultDao;
+import org.apache.continuum.dao.ProjectDao;
+import org.apache.continuum.dao.ProjectScmRootDao;
+import org.apache.continuum.model.project.ProjectRunSummary;
+import org.apache.continuum.model.project.ProjectScmRoot;
+import org.apache.maven.continuum.configuration.ConfigurationService;
+import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.model.project.BuildResult;
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.project.ContinuumProjectState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @plexus.component role="org.apache.continuum.builder.distributed.work.ContinuumWorker"
+ */
+public class DefaultContinuumWorker
+    implements ContinuumWorker
+{
+    private static final Logger log = LoggerFactory.getLogger( DefaultContinuumWorker.class
);
+
+    /**
+     * @plexus.requirement
+     */
+    private ProjectDao projectDao;
+
+    /**
+     * @plexus.requirement
+     */
+    private ProjectScmRootDao projectScmRootDao;
+
+    /**
+     * @plexus.requirement
+     */
+    private BuildDefinitionDao buildDefinitionDao;
+
+    /**
+     * @plexus.requirement
+     */
+    private BuildResultDao buildResultDao;
+
+    /**
+     * @plexus.requirement
+     */
+    private DistributedBuildManager distributedBuildManager;
+
+    /**
+     * @plexus.requirement
+     */
+    private ConfigurationService configurationService;
+
+    public synchronized void work()
+    {
+        if ( !configurationService.isDistributedBuildEnabled() )
+        {
+            return;
+        }
+
+        log.debug( "Start continuum worker..." );
+
+        List<ProjectRunSummary> currentRuns = new ArrayList<ProjectRunSummary>(
distributedBuildManager.getCurrentRuns() );
+        List<ProjectRunSummary> runsToDelete = new ArrayList<ProjectRunSummary>();
+
+        synchronized ( currentRuns )
+        {
+            for ( ProjectRunSummary currentRun : currentRuns )
+            {
+                try
+                {
+                    // check for scm update
+                    ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( currentRun.getProjectScmRootId()
);
+    
+                    if ( scmRoot != null && scmRoot.getState() == ContinuumProjectState.UPDATING
)
+                    {
+                        // check if it's still updating
+                        if ( !distributedBuildManager.isProjectCurrentlyPreparingBuild( currentRun.getProjectId(),
currentRun.getBuildDefinitionId() ) )
+                        {
+                            // no longer updating, but state was not updated.
+                            scmRoot.setState( ContinuumProjectState.ERROR );
+                            scmRoot.setError( "Problem encountered while returning scm update
result to master by build agent '" + currentRun.getBuildAgentUrl() + "'. \n" +
+                                              "Make sure build agent is configured properly.
Check the logs for more information." );
+                            projectScmRootDao.updateProjectScmRoot( scmRoot );
+    
+                            log.debug( "projectId={}, buildDefinitionId={} is not updating
anymore. Problem encountered while return scm update result by build agent {}. Stopping the
build.",
+                                       new Object[] { currentRun.getProjectId(), currentRun.getBuildDefinitionId(),
currentRun.getBuildAgentUrl() } );
+                            runsToDelete.add( currentRun );
+                        }
+                    }
+                    else if ( scmRoot != null && scmRoot.getState() == ContinuumProjectState.ERROR
)
+                    {
+                        log.debug( "projectId={}, buildDefinitionId={} is not updating anymore.
Problem encountered while return scm update result by build agent {}. Stopping the build.",
+                                   new Object[] { currentRun.getProjectId(), currentRun.getBuildDefinitionId(),
currentRun.getBuildAgentUrl() } );
+                        runsToDelete.add( currentRun );
+                    }
+                    else
+                    {
+                        Project project = projectDao.getProject( currentRun.getProjectId()
);
+    
+                        if ( project != null && project.getState() == ContinuumProjectState.BUILDING
)
+                        {
+                            // check if it's still building
+                            if ( !distributedBuildManager.isProjectCurrentlyBuilding( currentRun.getProjectId(),
currentRun.getBuildDefinitionId() ) )
+                            {
+                                BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition(
currentRun.getBuildDefinitionId() );
+
+                                // no longer building, but state was not updated
+                                BuildResult buildResult = new BuildResult();
+                                buildResult.setBuildDefinition( buildDefinition );
+                                buildResult.setBuildUrl( currentRun.getBuildAgentUrl() );
+                                buildResult.setTrigger( currentRun.getTrigger() );
+                                buildResult.setUsername( currentRun.getTriggeredBy() );
+                                buildResult.setState( ContinuumProjectState.ERROR );
+                                buildResult.setSuccess( false );
+                                buildResult.setStartTime( new Date().getTime() );
+                                buildResult.setEndTime( new Date().getTime() );
+                                buildResult.setExitCode( 1 );
+                                buildResult.setError( "Problem encountered while returning
build result to master by build agent '" + currentRun.getBuildAgentUrl() + "'. \n" +
+                                                      "Make sure build agent is configured
properly. Check the logs for more information." );
+                                buildResultDao.addBuildResult( project, buildResult );
+    
+                                project.setState( ContinuumProjectState.ERROR );
+                                project.setLatestBuildId( buildResult.getId() );
+                                projectDao.updateProject( project );
+    
+                                log.debug( "projectId={}, buildDefinitionId={} is not building
anymore. Problem encountered while return build result by build agent {}. Stopping the build.",
+                                           new Object[] { currentRun.getProjectId(), currentRun.getBuildDefinitionId(),
currentRun.getBuildAgentUrl() } );
+
+                                // create a build result
+                                runsToDelete.add( currentRun );
+                            }
+                        }
+                    }
+                }
+                catch ( Exception e )
+                {
+                    log.error( "Unable to check if projectId={}, buildDefinitionId={} is
still updating or building: {}",
+                               new Object[] { currentRun.getProjectId(), currentRun.getBuildDefinitionId(),
e.getMessage() } );
+                }
+            }
+
+            if ( runsToDelete.size() > 0 )
+            {
+                distributedBuildManager.getCurrentRuns().removeAll( runsToDelete );
+            }
+        }
+
+        log.debug( "End continuum worker..." );
+    }
+
+    // for testing
+    public void setProjectDao( ProjectDao projectDao )
+    {
+        this.projectDao = projectDao;
+    }
+
+    public void setProjectScmRootDao( ProjectScmRootDao projectScmRootDao )
+    {
+        this.projectScmRootDao = projectScmRootDao;
+    }
+
+    public void setBuildDefinitionDao( BuildDefinitionDao buildDefinitionDao )
+    {
+        this.buildDefinitionDao = buildDefinitionDao;
+    }
+
+    public void setBuildResultDao( BuildResultDao buildResultDao )
+    {
+        this.buildResultDao = buildResultDao;
+    }
+
+    public void setConfigurationService( ConfigurationService configurationService )
+    {
+        this.configurationService = configurationService;
+    }
+
+    public void setDistributedBuildManager( DistributedBuildManager distributedBuildManager
)
+    {
+        this.distributedBuildManager = distributedBuildManager;
+    }
+}

Propchange: continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/trunk/continuum-core/src/main/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorker.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: continuum/trunk/continuum-core/src/main/resources/META-INF/spring-context.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/main/resources/META-INF/spring-context.xml?rev=1161980&r1=1161979&r2=1161980&view=diff
==============================================================================
--- continuum/trunk/continuum-core/src/main/resources/META-INF/spring-context.xml (original)
+++ continuum/trunk/continuum-core/src/main/resources/META-INF/spring-context.xml Fri Aug
26 03:45:05 2011
@@ -42,4 +42,11 @@
      <property name="checkoutTaskQueueExecutor" ref="taskQueueExecutor#check-out-project"/>
      <property name="prepareBuildTaskQueueExecutor" ref="taskQueueExecutor#prepare-build-project"/>
   </bean>
+  
+  <!-- jobs -->
+  <bean name="continuumBuildJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
+    <property name="targetObject" ref="continuumWorker" />
+    <property name="targetMethod" value="work" />
+    <property name="concurrent" value="false" />
+  </bean>
 </beans>

Added: continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorkerTest.java
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorkerTest.java?rev=1161980&view=auto
==============================================================================
--- continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorkerTest.java
(added)
+++ continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorkerTest.java
Fri Aug 26 03:45:05 2011
@@ -0,0 +1,189 @@
+package org.apache.continuum.builder.distributed.work;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.continuum.builder.distributed.manager.DistributedBuildManager;
+import org.apache.continuum.dao.BuildDefinitionDao;
+import org.apache.continuum.dao.BuildResultDao;
+import org.apache.continuum.dao.ProjectDao;
+import org.apache.continuum.dao.ProjectScmRootDao;
+import org.apache.continuum.model.project.ProjectRunSummary;
+import org.apache.continuum.model.project.ProjectScmRoot;
+import org.apache.maven.continuum.configuration.ConfigurationService;
+import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.model.project.BuildResult;
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.project.ContinuumProjectState;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit3.JUnit3Mockery;
+import org.jmock.lib.legacy.ClassImposteriser;
+
+public class DefaultContinuumWorkerTest
+    extends PlexusInSpringTestCase
+{
+    private Mockery context;
+
+    private ProjectDao projectDao;
+
+    private ProjectScmRootDao projectScmRootDao;
+
+    private BuildDefinitionDao buildDefinitionDao;
+
+    private BuildResultDao buildResultDao;
+
+    private DistributedBuildManager distributedBuildManager;
+
+    private ConfigurationService configurationService;
+
+    private DefaultContinuumWorker worker;
+
+    @Override
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+        context = new JUnit3Mockery();
+        context.setImposteriser( ClassImposteriser.INSTANCE );
+
+        projectDao = context.mock( ProjectDao.class );
+        projectScmRootDao = context.mock( ProjectScmRootDao.class );
+        buildDefinitionDao = context.mock( BuildDefinitionDao.class );
+        buildResultDao = context.mock( BuildResultDao.class );
+        configurationService = context.mock( ConfigurationService.class );
+        distributedBuildManager = context.mock( DistributedBuildManager.class );
+
+        worker = (DefaultContinuumWorker) lookup( ContinuumWorker.class );
+        worker.setBuildDefinitionDao( buildDefinitionDao );
+        worker.setBuildResultDao( buildResultDao );
+        worker.setProjectDao( projectDao );
+        worker.setProjectScmRootDao( projectScmRootDao );
+        worker.setConfigurationService( configurationService );
+        worker.setDistributedBuildManager( distributedBuildManager );
+    }
+
+    public void testWorkerWithStuckBuild()
+        throws Exception
+    {
+        recordOfStuckBuild();
+
+        worker.work();
+
+        context.assertIsSatisfied();
+    }
+
+    public void testWorkerWithStuckScm()
+        throws Exception
+    {
+        recordOfStuckScm();
+
+        worker.work();
+
+        context.assertIsSatisfied();
+    }
+
+    private void recordOfStuckBuild()
+        throws Exception
+    {
+        context.checking( new Expectations()
+        {
+            {
+                one( configurationService ).isDistributedBuildEnabled();
+                will( returnValue( true ) );
+
+                exactly( 2 ).of( distributedBuildManager ).getCurrentRuns();
+                will( returnValue( getCurrentRuns() ) );
+
+                exactly( 2 ).of( projectScmRootDao ).getProjectScmRoot( 1 );
+                will( returnValue( getScmRoot( ContinuumProjectState.OK ) ) );
+
+                Project proj1 = getProject( 1, ContinuumProjectState.BUILDING );
+                one( projectDao ).getProject( 1 );
+                will( returnValue( proj1 ) );
+
+                one( distributedBuildManager ).isProjectCurrentlyBuilding( 1, 1 );
+                will( returnValue( false ) );
+
+                one( buildDefinitionDao ).getBuildDefinition( 1 );
+                will( returnValue( new BuildDefinition() ) );
+
+                one( buildResultDao ).addBuildResult( with( any( Project.class ) ), with(
any( BuildResult.class ) ) );
+                one( projectDao ).updateProject( proj1 );
+
+                one( projectDao ).getProject( 2 );
+                will( returnValue( getProject( 2, ContinuumProjectState.OK ) ) );
+            }
+        });
+    }
+
+    private void recordOfStuckScm()
+        throws Exception
+    {
+        context.checking( new Expectations()
+        {
+            {
+                one( configurationService ).isDistributedBuildEnabled();
+                will( returnValue( true ) );
+
+                exactly( 2 ).of( distributedBuildManager ).getCurrentRuns();
+                will( returnValue( getCurrentRuns() ) );
+
+                ProjectScmRoot scmRootUpdating = getScmRoot( ContinuumProjectState.UPDATING
);
+                one( projectScmRootDao ).getProjectScmRoot( 1 );
+                will( returnValue( scmRootUpdating ) );
+
+                one( distributedBuildManager ).isProjectCurrentlyPreparingBuild( 1, 1 );
+                will( returnValue( false ) );
+
+                one( projectScmRootDao ).updateProjectScmRoot( scmRootUpdating );
+
+                one( projectScmRootDao ).getProjectScmRoot( 1 );
+                will( returnValue( getScmRoot( ContinuumProjectState.ERROR ) ) );
+            }
+        });
+    }
+
+    private List<ProjectRunSummary> getCurrentRuns()
+    {
+        List<ProjectRunSummary> runs = new ArrayList<ProjectRunSummary>();
+
+        ProjectRunSummary run1 = new ProjectRunSummary();
+        run1.setProjectId( 1 );
+        run1.setBuildDefinitionId( 1 );
+        run1.setProjectGroupId( 1 );
+        run1.setProjectScmRootId( 1 );
+        run1.setTrigger( 1 );
+        run1.setTriggeredBy( "user" );
+        run1.setBuildAgentUrl( "http://localhost:8181/continuum-buildagent/xmlrpc" );
+        runs.add( run1 );
+
+        ProjectRunSummary run2 = new ProjectRunSummary();
+        run2.setProjectId( 2 );
+        run2.setBuildDefinitionId( 2 );
+        run2.setProjectGroupId( 1 );
+        run2.setProjectScmRootId( 1 );
+        run2.setTrigger( 1 );
+        run2.setTriggeredBy( "user" );
+        run2.setBuildAgentUrl( "http://localhost:8181/continuum-buildagent/xmlrpc" );
+        runs.add( run2 );
+
+        return runs;
+    }
+
+    private ProjectScmRoot getScmRoot( int state )
+    {
+        ProjectScmRoot scmRoot = new ProjectScmRoot();
+        scmRoot.setState( state );
+        return scmRoot;
+    }
+
+    private Project getProject( int projectId, int state )
+    {
+        Project project = new Project();
+        project.setId( projectId );
+        project.setState( state );
+        return project;
+    }
+}

Propchange: continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorkerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: continuum/trunk/continuum-core/src/test/java/org/apache/continuum/builder/distributed/work/DefaultContinuumWorkerTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: continuum/trunk/continuum-webapp/pom.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/pom.xml?rev=1161980&r1=1161979&r2=1161980&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/pom.xml (original)
+++ continuum/trunk/continuum-webapp/pom.xml Fri Aug 26 03:45:05 2011
@@ -656,6 +656,10 @@ under the License.
       <artifactId>spring-context</artifactId>
     </dependency>    
     <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-tx</artifactId>
+    </dependency>
+    <dependency>
       <groupId>jmock</groupId>
       <artifactId>jmock</artifactId>
       <scope>test</scope>

Modified: continuum/trunk/continuum-webapp/src/main/webapp/WEB-INF/applicationContext.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/continuum-webapp/src/main/webapp/WEB-INF/applicationContext.xml?rev=1161980&r1=1161979&r2=1161980&view=diff
==============================================================================
--- continuum/trunk/continuum-webapp/src/main/webapp/WEB-INF/applicationContext.xml (original)
+++ continuum/trunk/continuum-webapp/src/main/webapp/WEB-INF/applicationContext.xml Fri Aug
26 03:45:05 2011
@@ -120,4 +120,29 @@
     <constructor-arg ref="securitySystem"/>
   </bean>
   
+  <!-- triggers -->
+  <bean id="continuumBuildTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
+    <property name="jobDetail" ref="continuumBuildJob" />
+    <property name="cronExpression" value="0 * * * * ?" />
+  </bean>
+  
+   <!-- scheduler -->
+  <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
+    <property name="triggers">
+      <list>
+        <ref bean="continuumBuildTrigger" />
+      </list>
+    </property>
+    <property name="schedulerName" value="Continuum Scheduler" />
+    <property name="waitForJobsToCompleteOnShutdown" value="true" />
+    <property name="quartzProperties">
+      <props>
+        <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
+        <prop key="org.quartz.plugin.shutdownhook.class">org.quartz.plugins.management.ShutdownHookPlugin
+        </prop>
+        <prop key="org.quartz.plugin.shutdownhook.cleanShutdown">true</prop>
+      </props>
+    </property>
+  </bean>
+
 </beans>

Modified: continuum/trunk/pom.xml
URL: http://svn.apache.org/viewvc/continuum/trunk/pom.xml?rev=1161980&r1=1161979&r2=1161980&view=diff
==============================================================================
--- continuum/trunk/pom.xml (original)
+++ continuum/trunk/pom.xml Fri Aug 26 03:45:05 2011
@@ -1386,6 +1386,17 @@ under the License.
         </exclusions>
       </dependency>
       <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-tx</artifactId>
+        <version>${spring.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
         <groupId>javax.annotation</groupId>
         <artifactId>jsr250-api</artifactId>
         <version>1.0</version>



Mime
View raw message