You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@continuum.apache.org by oc...@apache.org on 2008/12/11 12:02:40 UTC
svn commit: r725657 - in /continuum/branches/continuum-parallel-builds:
continuum-api/src/main/java/org/apache/continuum/buildmanager/
continuum-api/src/main/java/org/apache/continuum/taskqueue/
continuum-core/src/main/java/org/apache/continuum/buildma...
Author: oching
Date: Thu Dec 11 03:02:39 2008
New Revision: 725657
URL: http://svn.apache.org/viewvc?rev=725657&view=rev
Log:
- updated implementation of parallel builds manager
- added tests
- changed instantiation-strategy of task queues to per-lookup
Added:
continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/buildmanager/BuildsManager.java
continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/buildmanager/ParallelBuildsManager.java
continuum/branches/continuum-parallel-builds/continuum-core/src/test/java/org/apache/continuum/buildmanager/ParallelBuildsManagerTest.java
Removed:
continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/buildmanager/BuildManager.java
continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/buildmanager/DefaultBuildManager.java
continuum/branches/continuum-parallel-builds/continuum-core/src/test/java/org/apache/continuum/buildmanager/DefaultBuildManagerTest.java
Modified:
continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/taskqueue/OverallBuildQueue.java
continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/taskqueue/DefaultOverallBuildQueue.java
continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java
continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AddProjectToCheckOutQueueAction.java
continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateBuildProjectTaskAction.java
continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/PrepareBuildProjectsTaskExecutor.java
continuum/branches/continuum-parallel-builds/continuum-core/src/main/resources/META-INF/plexus/components.xml
continuum/branches/continuum-parallel-builds/continuum-model/pom.xml
continuum/branches/continuum-parallel-builds/continuum-model/src/main/mdo/continuum.xml
Added: continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/buildmanager/BuildsManager.java
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/buildmanager/BuildsManager.java?rev=725657&view=auto
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/buildmanager/BuildsManager.java (added)
+++ continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/buildmanager/BuildsManager.java Thu Dec 11 03:02:39 2008
@@ -0,0 +1,82 @@
+package org.apache.continuum.buildmanager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.continuum.taskqueue.OverallBuildQueue;
+import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.model.project.Project;
+
+/**
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ *
+ */
+public interface BuildsManager
+{
+ // NOTE: deng parallel builds
+ // I think we can move out the prepare build queue from the build manager?
+ // only builds and checkouts should be executed in parallel? :D
+
+ public void buildProjects( List<Project> projects, Map<Integer, BuildDefinition> projectsBuildDefinitionsMap, int trigger ) throws BuildManagerException;
+
+ public void buildProject( int projectId, BuildDefinition buildDefinition, String projectName, int trigger ) throws BuildManagerException;
+
+ //public void prepareBuildProjects( Collection<Map<Integer, Integer>> projectsBuildDefinitions, int trigger, int scheduleId );
+
+ //public void prepareBuildProject( int projectId, BuildDefinition buildDefinition, String projectName, int trigger, int scheduleId );
+
+ // project checkout doesn't require dependency checking
+ public void checkoutProject( int projectId, String projectName, File workingDirectory, String scmUsername, String scmPassword, BuildDefinition defaultBuildDefinition ) throws BuildManagerException;
+
+ public boolean cancelBuild( int projectId ) throws BuildManagerException;
+
+ public boolean cancelAllBuilds() throws BuildManagerException;
+
+ public boolean cancelBuildInQueue( int buildQueueId ) throws BuildManagerException;
+
+ public boolean cancelCheckout(int projectId) throws BuildManagerException;
+
+ public boolean cancelAllCheckouts() throws BuildManagerException;
+
+ //public boolean cancelPrepareBuild(int projectId) throws BuildManagerException;
+
+ //public boolean cancelAllPrepareBuilds() throws BuildManagerException;
+
+ public void removeProjectFromBuildQueue( int projectId ) throws BuildManagerException;
+
+ public void removeProjectsFromBuildQueue( int[] projectIds );
+
+ public void removeProjectFromCheckoutQueue( int projectId ) throws BuildManagerException;
+
+ public void removeProjectsFromCheckoutQueue( int[] projectIds );
+
+ //public void removeProjectFromPrepareBuildQueue( int projectId );
+
+ // public void removeProjectsFromPrepareBuildQueue( int[] projectIds );
+
+ public void addOverallBuildQueue( OverallBuildQueue overallBuildQueue );
+
+ public void removeOverallBuildQueue( int overallBuildQueueId ) throws BuildManagerException;
+
+}
Modified: continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/taskqueue/OverallBuildQueue.java
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/taskqueue/OverallBuildQueue.java?rev=725657&r1=725656&r2=725657&view=diff
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/taskqueue/OverallBuildQueue.java (original)
+++ continuum/branches/continuum-parallel-builds/continuum-api/src/main/java/org/apache/continuum/taskqueue/OverallBuildQueue.java Thu Dec 11 03:02:39 2008
@@ -39,6 +39,14 @@
void setId( int id );
+ /**
+ * Returns the name of the "overall" build queue
+ * @return
+ */
+ String getName();
+
+ void setName( String name );
+
/* Checkout Queue */
/**
Added: continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/buildmanager/ParallelBuildsManager.java
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/buildmanager/ParallelBuildsManager.java?rev=725657&view=auto
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/buildmanager/ParallelBuildsManager.java (added)
+++ continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/buildmanager/ParallelBuildsManager.java Thu Dec 11 03:02:39 2008
@@ -0,0 +1,674 @@
+package org.apache.continuum.buildmanager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.continuum.dao.BuildDefinitionDao;
+import org.apache.continuum.taskqueue.OverallBuildQueue;
+import org.apache.maven.continuum.buildqueue.BuildProjectTask;
+import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.model.project.BuildQueue;
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.scm.queue.CheckOutTask;
+import org.apache.maven.continuum.store.ContinuumStoreException;
+import org.codehaus.plexus.taskqueue.Task;
+import org.codehaus.plexus.taskqueue.TaskQueue;
+import org.codehaus.plexus.taskqueue.TaskQueueException;
+import org.codehaus.plexus.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Parallel builds manager.
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ * @plexus.component role="org.apache.continuum.buildmanager.BuildsManager" role-hint="parallel"
+ */
+public class ParallelBuildsManager
+ implements BuildsManager
+{
+ private Logger log = LoggerFactory.getLogger( ParallelBuildsManager.class );
+
+ // map must be synchronized
+ private Map<Integer, OverallBuildQueue> overallBuildQueues =
+ Collections.synchronizedMap( new HashMap<Integer, OverallBuildQueue>() );
+
+ private static final int BUILD_QUEUE = 1;
+
+ private static final int CHECKOUT_QUEUE = 2;
+
+ private static final int PREPARE_BUILD_QUEUE = 3;
+
+ /**
+ * @plexus.requirement
+ */
+ private BuildDefinitionDao buildDefinitionDao;
+
+ // REQUIREMENTS:
+ // UI:
+ // - add a new page for adding a build queue. It should have a build queue name that
+ // will be used to associate it with a schedule. The number of build queues that can
+ // be added should respect the "Number of Allowed Builds in Parallel" set in the
+ // General Configuration.
+ // - in the add/edit schedule page, add a list box that contains the build queues which
+ // would allow the user to select which build queue(s) to associate with the schedule.
+ //
+ // Back-end:
+ // 1. when a build is triggered:
+ // * check for available build queue(s) associated with the schedule. Get the first available
+ // build queue.
+ // * add the project to the associated build queue's checkout queue or build queue depending
+ // whether the project is configured to always "build fresh"
+ // * once the build finishes, remove the project build instance from the associated build queue
+ // * build the next project in the queue
+ //2. for releases:
+ // * projects to be released will be built in sequence in a queue of their own. As long as
+ // they don't modify the build state or working copy it is ok to build the original
+ // project simultaneously. If the working copy changes are made in place for bumping
+ // versions, suggest blocking it and being built elsewhere.
+
+ public void buildProject( int projectId, BuildDefinition buildDefinition, String projectName, int trigger ) throws BuildManagerException
+ {
+ try
+ {
+ if( isInQueue( projectId, BUILD_QUEUE ) )
+ {
+ log.warn( "Project already queued." );
+ return;
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while checking if the project is already in queue: " + e.getMessage() );
+ }
+
+ OverallBuildQueue overallBuildQueue =
+ getOverallBuildQueue( projectId, BUILD_QUEUE, buildDefinition.getSchedule().getBuildQueues() );
+
+ String buildDefinitionLabel = buildDefinition.getDescription();
+ if ( StringUtils.isEmpty( buildDefinitionLabel ) )
+ {
+ buildDefinitionLabel = buildDefinition.getGoals();
+ }
+
+ Task buildTask = new BuildProjectTask( projectId, buildDefinition.getId(), trigger, projectName,
+ buildDefinitionLabel);
+ try
+ {
+ overallBuildQueue.addToBuildQueue( buildTask );
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while adding project to build queue: " + e.getMessage() );
+ }
+ }
+
+ public void buildProjects( List<Project> projects,
+ Map<Integer, BuildDefinition> projectsBuildDefinitionsMap, int trigger ) throws BuildManagerException
+ {
+ int firstProjectId = 0;
+ // get id of the first project in the list that is not yet in the build queue
+ for( Project project : projects )
+ {
+ try
+ {
+ if( !isInQueue( project.getId(), BUILD_QUEUE ) )
+ {
+ firstProjectId = project.getId();
+ break;
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ log.warn( "Error occurred while verifying if project is already queued." );
+ continue;
+ }
+ }
+
+ if( firstProjectId != 0 )
+ {
+ BuildDefinition buildDef = projectsBuildDefinitionsMap.get( firstProjectId );
+ OverallBuildQueue overallBuildQueue =
+ getOverallBuildQueue( firstProjectId, BUILD_QUEUE, buildDef.getSchedule().getBuildQueues() );;
+
+ if( overallBuildQueue != null )
+ {
+ for( Project project : projects )
+ {
+ try
+ {
+ if( isInQueue( project.getId(), BUILD_QUEUE ) )
+ {
+ continue;
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ log.warn( "Error occurred while verifying if project is already queued." );
+ continue;
+ }
+
+ BuildDefinition buildDefinition = projectsBuildDefinitionsMap.get( project.getId() );
+ String buildDefinitionLabel = buildDefinition.getDescription();
+ if ( StringUtils.isEmpty( buildDefinitionLabel ) )
+ {
+ buildDefinitionLabel = buildDefinition.getGoals();
+ }
+
+ Task buildTask = new BuildProjectTask( project.getId(), buildDefinition.getId(), trigger, project.getName(),
+ buildDefinitionLabel);
+ try
+ {
+ overallBuildQueue.addToBuildQueue( buildTask );
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while adding project to build queue: " + e.getMessage() );
+ }
+ }
+ }
+ }
+ else
+ {
+ log.error( "Projects are already in build queue." );
+ throw new BuildManagerException( "Projects are already in build queue." );
+ }
+ }
+
+ public boolean cancelBuildInQueue( int buildQueueId ) throws BuildManagerException
+ {
+ synchronized( overallBuildQueues )
+ {
+ OverallBuildQueue overallBuildQueue = null;
+ try
+ {
+ overallBuildQueue = overallBuildQueues.get( buildQueueId );
+ if( overallBuildQueue != null )
+ {
+ overallBuildQueue.cancelCurrentBuild();
+ }
+ else
+ {
+ log.warn( "Project not found in any of the build queues." );
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ log.error( "Cannot cancel build on build queue '" + overallBuildQueue.getName() + "'." );
+ throw new BuildManagerException( "Cannot cancel build on build queue '" + overallBuildQueue.getName() +
+ "': " + e.getMessage() );
+ }
+ return true;
+ }
+ }
+
+ public boolean cancelAllBuilds() throws BuildManagerException
+ {
+ synchronized( overallBuildQueues )
+ {
+ Set<Integer> keySet = overallBuildQueues.keySet();
+ OverallBuildQueue overallBuildQueue = null;
+
+ try
+ {
+ for( Integer key : keySet )
+ {
+ overallBuildQueue = overallBuildQueues.get( key );
+ overallBuildQueue.cancelCurrentBuild();
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ log.error( "Cannot cancel build on build queue '" + overallBuildQueue.getName() + "'." );
+ throw new BuildManagerException( "Cannot cancel build on build queue '" + overallBuildQueue.getName() +
+ "': " + e.getMessage() );
+ }
+ return true;
+ }
+ }
+
+ public boolean cancelAllCheckouts() throws BuildManagerException
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /*public boolean cancelAllPrepareBuilds() throws BuildManagerException
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }*/
+
+ public boolean cancelBuild(int projectId) throws BuildManagerException
+ {
+ try
+ {
+ OverallBuildQueue overallBuildQueue = getOverallBuildQueue( projectId, BUILD_QUEUE );
+ if( overallBuildQueue != null )
+ {
+ overallBuildQueue.cancelBuildTask( projectId );
+ }
+ else
+ {
+ throw new BuildManagerException( "Project not found in any of the build queues." );
+ }
+ }
+ catch( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while cancelling build: " +
+ e.getMessage() );
+ }
+
+ return true;
+ }
+
+ // TODO: should this be permitted? (might need to execute svn cleanup?)
+ public boolean cancelCheckout(int projectId) throws BuildManagerException
+ {
+ try
+ {
+ OverallBuildQueue overallBuildQueue = getOverallBuildQueue( projectId, CHECKOUT_QUEUE );
+ if( overallBuildQueue != null )
+ {
+ //overallBuildQueue.getCheckoutQueue()
+ }
+ else
+ {
+ throw new BuildManagerException( "Project not found in any of the checkout queues." );
+ }
+ }
+ catch( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while cancelling build: " +
+ e.getMessage() );
+ }
+
+ return true;
+ }
+
+ /*public boolean cancelPrepareBuild(int projectId) throws BuildManagerException
+ {
+ // TODO Auto-generated method stub
+ return false;
+ }*/
+
+ public void checkoutProject( int projectId, String projectName, File workingDirectory, String scmUsername, String scmPassword, BuildDefinition defaultBuildDefinition ) throws BuildManagerException
+ {
+ try
+ {
+ if( isInQueue( projectId, CHECKOUT_QUEUE ) )
+ {
+ log.warn( "Project already in checkout queue." );
+ return;
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while checking if the project is already in queue: " + e.getMessage() );
+ }
+
+ OverallBuildQueue overallBuildQueue =
+ getOverallBuildQueue( projectId, CHECKOUT_QUEUE, defaultBuildDefinition.getSchedule().getBuildQueues() );
+
+ CheckOutTask checkoutTask =
+ new CheckOutTask( projectId, workingDirectory, projectName, scmUsername, scmPassword );
+ try
+ {
+ overallBuildQueue.addToCheckoutQueue( checkoutTask );
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while adding project to checkout queue: " + e.getMessage() );
+ }
+ }
+
+ /*public void prepareBuildProject( int projectId, BuildDefinition buildDefinition, String projectName, int trigger, int scheduleId )
+ {
+ // TODO Auto-generated method stub
+
+ }*/
+
+ /*public void prepareBuildProjects( Collection<Map<Integer, Integer>> projectsBuildDefinitions, int trigger, int scheduleId )
+ {
+ // TODO Auto-generated method stub
+
+ }*/
+
+ public void removeProjectFromBuildQueue( int projectId ) throws BuildManagerException
+ {
+ try
+ {
+ OverallBuildQueue overallBuildQueue = getOverallBuildQueue( projectId, BUILD_QUEUE );
+ if( overallBuildQueue != null )
+ {
+ overallBuildQueue.removeProjectFromBuildQueue( projectId );
+ }
+ else
+ {
+ throw new BuildManagerException( "Project not found in any of the build queues." );
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while removing project from build queue: " +
+ e.getMessage() );
+ }
+ }
+
+ public void removeProjectFromCheckoutQueue( int projectId ) throws BuildManagerException
+ {
+ try
+ {
+ OverallBuildQueue overallBuildQueue = getOverallBuildQueue( projectId, CHECKOUT_QUEUE );
+ if( overallBuildQueue != null )
+ {
+ overallBuildQueue.removeProjectFromCheckoutQueue( projectId );
+ }
+ else
+ {
+ throw new BuildManagerException( "Project not found in any of the checkout queues." );
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while removing project from checkout queue: " +
+ e.getMessage() );
+ }
+ }
+
+ /*public void removeProjectFromPrepareBuildQueue( int projectId )
+ {
+ // TODO Auto-generated method stub
+
+ }*/
+
+ public void removeProjectsFromBuildQueue( int[] projectIds )
+ {
+ for( int i = 0; i < projectIds.length; i++ )
+ {
+ try
+ {
+ OverallBuildQueue overallBuildQueue = getOverallBuildQueue( projectIds[i], BUILD_QUEUE );
+ if( overallBuildQueue != null )
+ {
+ overallBuildQueue.removeProjectFromBuildQueue( projectIds[i] );
+ }
+ else
+ {
+ log.error( "Project '" + projectIds[i] + "' not found in any of the build queues." );
+ continue;
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ log.error( "Error occurred while removing project '" + projectIds[i] + "' from build queue." );
+ continue;
+ }
+ }
+ }
+
+ public void removeProjectsFromCheckoutQueue( int[] projectIds )
+ {
+ for( int i = 0; i < projectIds.length; i++ )
+ {
+ try
+ {
+ OverallBuildQueue overallBuildQueue = getOverallBuildQueue( projectIds[i], CHECKOUT_QUEUE );
+ if( overallBuildQueue != null )
+ {
+ overallBuildQueue.removeProjectFromCheckoutQueue( projectIds[i] );
+ }
+ else
+ {
+ log.error( "Project '" + projectIds[i] + "' not found in any of the checkout queues." );
+ continue;
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ log.error( "Error occurred while removing project '" + projectIds[i] + "' from checkout queue." );
+ continue;
+ }
+ }
+ }
+
+ public void removeProjectsFromPrepareBuildQueue( int[] projectIds )
+ {
+ // TODO Auto-generated method stub
+ }
+
+ public void addOverallBuildQueue( OverallBuildQueue overallBuildQueue )
+ {
+ synchronized( overallBuildQueues )
+ {
+ this.overallBuildQueues.put( overallBuildQueue.getId(), overallBuildQueue );
+ }
+ }
+
+ public void removeOverallBuildQueue( int overallBuildQueueId ) throws BuildManagerException
+ {
+ List<BuildProjectTask> tasks = null;
+ List<CheckOutTask> checkoutTasks = null;
+
+ synchronized( overallBuildQueues )
+ {
+ OverallBuildQueue overallBuildQueue = overallBuildQueues.get( overallBuildQueueId );
+ try
+ {
+ tasks = overallBuildQueue.getProjectsInBuildQueue();
+ checkoutTasks = overallBuildQueue.getCheckOutTasksInQueue();
+
+ overallBuildQueue.getBuildQueue().removeAll( tasks );
+ overallBuildQueue.getCheckoutQueue().removeAll( checkoutTasks );
+
+ overallBuildQueue = null;
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new BuildManagerException(
+ "Cannot remove build queue. An error occurred while retrieving queued tasks." );
+ }
+
+ this.overallBuildQueues.remove( overallBuildQueueId );
+ }
+
+ try
+ {
+ for( BuildProjectTask task : tasks )
+ {
+ BuildDefinition buildDefinition = buildDefinitionDao.getBuildDefinition( task.getBuildDefinitionId() );
+ buildProject( task.getProjectId(), buildDefinition, task.getProjectName(), task.getTrigger() );
+ }
+
+ for( CheckOutTask task : checkoutTasks )
+ {
+ BuildDefinition buildDefinition = buildDefinitionDao.getDefaultBuildDefinition( task.getProjectId() );
+ checkoutProject( task.getProjectId(), task.getProjectName(), task.getWorkingDirectory(),
+ task.getScmUserName(), task.getScmPassword(), buildDefinition );
+ }
+ }
+ catch ( ContinuumStoreException e )
+ {
+ throw new BuildManagerException(
+ "Cannot remove build queue: " + e.getMessage() );
+ }
+ }
+
+ public Map<Integer, OverallBuildQueue> getOverallBuildQueues()
+ {
+ return overallBuildQueues;
+ }
+
+ private boolean isInQueue( int projectId, int typeOfQueue )
+ throws TaskQueueException
+ {
+ synchronized( overallBuildQueues )
+ {
+ Set<Integer> keySet = overallBuildQueues.keySet();
+ for( Integer key : keySet )
+ {
+ OverallBuildQueue overallBuildQueue = overallBuildQueues.get( key );
+ if( typeOfQueue == BUILD_QUEUE )
+ {
+ if( overallBuildQueue.isInBuildQueue( projectId ) )
+ {
+ return true;
+ }
+ }
+ else if( typeOfQueue == CHECKOUT_QUEUE )
+ {
+ if( overallBuildQueue.isInCheckoutQueue( projectId ) )
+ {
+ return true;
+ }
+ }
+ /*else if( typeOfQueue == PREPARE_BUILD_QUEUE )
+ {
+ if( overallBuildQueue.isInPrepareBuildQueue( projectId ) )
+ {
+ return true;
+ }
+ }*/
+ }
+
+ return false;
+ }
+ }
+
+ private OverallBuildQueue getOverallBuildQueue( int projectId, int typeOfQueue )
+ throws TaskQueueException
+ {
+ synchronized( overallBuildQueues )
+ {
+ OverallBuildQueue whereQueued = null;
+ Set<Integer> keySet = overallBuildQueues.keySet();
+
+ for( Integer key : keySet )
+ {
+ OverallBuildQueue overallBuildQueue = overallBuildQueues.get( key );
+ if( typeOfQueue == BUILD_QUEUE )
+ {
+ if( overallBuildQueue.isInBuildQueue( projectId ) )
+ {
+ whereQueued = overallBuildQueue;
+ break;
+ }
+ }
+ else if( typeOfQueue == CHECKOUT_QUEUE )
+ {
+ if( overallBuildQueue.isInCheckoutQueue( projectId ) )
+ {
+ whereQueued = overallBuildQueue;
+ break;
+ }
+ }
+ /*else if( typeOfQueue == PREPARE_BUILD_QUEUE )
+ {
+ if( overallBuildQueue.isInPrepareBuildQueue( projectId ) )
+ {
+ whereQueued = overallBuildQueue;
+ break;
+ }
+ }*/
+ }
+
+ return whereQueued;
+ }
+ }
+
+ private OverallBuildQueue getOverallBuildQueue( int projectId, int typeOfQueue, List<BuildQueue> buildQueues )
+ throws BuildManagerException
+ {
+ OverallBuildQueue whereToBeQueued = null;
+ synchronized( overallBuildQueues )
+ {
+ if( overallBuildQueues == null || overallBuildQueues.isEmpty() )
+ {
+ throw new BuildManagerException( "No build queues configured." );
+ }
+
+ int size = 0;
+ int idx = 0;
+ try
+ {
+ for( BuildQueue buildQueue : buildQueues )
+ {
+ OverallBuildQueue overallBuildQueue = overallBuildQueues.get( buildQueue.getId() );
+ if( overallBuildQueue != null )
+ {
+ TaskQueue taskQueue = null;
+ if( typeOfQueue == BUILD_QUEUE )
+ {
+ taskQueue = overallBuildQueue.getBuildQueue();
+ }
+ else if( typeOfQueue == CHECKOUT_QUEUE )
+ {
+ taskQueue = overallBuildQueue.getCheckoutQueue();
+ }
+ /*else if( typeOfQueue == PREPARE_BUILD_QUEUE )
+ {
+ taskQueue = overallBuildQueue.getPrepareBuildQueue();
+ }*/
+
+ if( idx == 0 )
+ {
+ size = taskQueue.getQueueSnapshot().size();
+ whereToBeQueued = overallBuildQueue;
+ }
+
+ if( taskQueue.getQueueSnapshot().size() < size )
+ {
+ whereToBeQueued = overallBuildQueue;
+ size = taskQueue.getQueueSnapshot().size();
+ }
+
+ idx++;
+ }
+ else
+ {
+ log.error( "Build queue not found." );
+ }
+ }
+ }
+ catch ( TaskQueueException e )
+ {
+ throw new BuildManagerException( "Error occurred while retrieving task quueue: " + e.getMessage() );
+ }
+ }
+
+ if( whereToBeQueued == null )
+ {
+ throw new BuildManagerException( "No build queue found." );
+ }
+
+ return whereToBeQueued;
+ }
+
+ public void setBuildDefinitionDao( BuildDefinitionDao buildDefinitionDao )
+ {
+ this.buildDefinitionDao = buildDefinitionDao;
+ }
+}
Modified: continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/taskqueue/DefaultOverallBuildQueue.java
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/taskqueue/DefaultOverallBuildQueue.java?rev=725657&r1=725656&r2=725657&view=diff
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/taskqueue/DefaultOverallBuildQueue.java (original)
+++ continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/continuum/taskqueue/DefaultOverallBuildQueue.java Thu Dec 11 03:02:39 2008
@@ -56,6 +56,10 @@
extends AbstractLogEnabled
implements OverallBuildQueue, Contextualizable
{
+ // TODO: deng parallel builds
+ // - might need to set a task queue executor for each task queue!
+ // change getXXXXTaskQueueExecutor() methods
+
// TODO:
// - need to specify each task queue to be instantiated each time it is looked up!!!
@@ -83,6 +87,8 @@
private int id;
+ private String name;
+
public int getId()
{
return id;
@@ -92,6 +98,16 @@
{
this.id = id;
}
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
/* Checkout Queue */
@@ -291,7 +307,7 @@
public TaskQueueExecutor getBuildTaskQueueExecutor()
throws ComponentLookupException
{
- return (TaskQueueExecutor) container.lookup( TaskQueueExecutor.class, "build-project" );
+ return ( TaskQueueExecutor ) container.lookup( TaskQueueExecutor.class, "build-project" );
}
public void addToBuildQueue( Task buildTask )
Modified: continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java?rev=725657&r1=725656&r2=725657&view=diff
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java (original)
+++ continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/DefaultContinuum.java Thu Dec 11 03:02:39 2008
@@ -664,6 +664,8 @@
context.put( AbstractContinuumAction.KEY_PROJECT_ID, new Integer( projectId ) );
+ // TODO: deng parallel builds
+ // - add default build definition of project (schedule is attached to the build def) to context!
executeAction( "add-project-to-checkout-queue", context );
}
Modified: continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AddProjectToCheckOutQueueAction.java
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AddProjectToCheckOutQueueAction.java?rev=725657&r1=725656&r2=725657&view=diff
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AddProjectToCheckOutQueueAction.java (original)
+++ continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/AddProjectToCheckOutQueueAction.java Thu Dec 11 03:02:39 2008
@@ -56,6 +56,9 @@
throws Exception
{
+ //TODO: deng parallel builds
+ // - get the default build definition from context and pass to parallel builds manager!
+
Project project = (Project) getObject( context, KEY_PROJECT, null );
if ( project == null )
{
Modified: continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateBuildProjectTaskAction.java
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateBuildProjectTaskAction.java?rev=725657&r1=725656&r2=725657&view=diff
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateBuildProjectTaskAction.java (original)
+++ continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateBuildProjectTaskAction.java Thu Dec 11 03:02:39 2008
@@ -65,6 +65,11 @@
public synchronized void execute( Map context )
throws Exception
{
+ // TODO: deng parallel builds
+ // - context now contains a "list" of projects and a "map" of projectId, build definition ket-value pair
+ // - update the list of projects
+ // - pass this updated list + map of build definitions to builds manager
+
Project project = AbstractContinuumAction.getProject( context );
int buildDefinitionId = AbstractContinuumAction.getBuildDefinitionId( context );
int trigger = AbstractContinuumAction.getTrigger( context );
Modified: continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/PrepareBuildProjectsTaskExecutor.java
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/PrepareBuildProjectsTaskExecutor.java?rev=725657&r1=725656&r2=725657&view=diff
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/PrepareBuildProjectsTaskExecutor.java (original)
+++ continuum/branches/continuum-parallel-builds/continuum-core/src/main/java/org/apache/maven/continuum/scm/queue/PrepareBuildProjectsTaskExecutor.java Thu Dec 11 03:02:39 2008
@@ -464,6 +464,11 @@
shouldBuild = true;
}
+ // TODO: deng parallel builds..
+ // - add those projects which should be built into a list
+ // and also add the build definition into a map of <projectId,build definition>
+ // - set these in the context map
+ //
if ( shouldBuild )
{
try
Modified: continuum/branches/continuum-parallel-builds/continuum-core/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-core/src/main/resources/META-INF/plexus/components.xml?rev=725657&r1=725656&r2=725657&view=diff
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-core/src/main/resources/META-INF/plexus/components.xml (original)
+++ continuum/branches/continuum-parallel-builds/continuum-core/src/main/resources/META-INF/plexus/components.xml Thu Dec 11 03:02:39 2008
@@ -57,6 +57,7 @@
<component>
<role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
<role-hint>build-project</role-hint>
+ <instantiation-strategy>per-lookup</instantiation-strategy>
<implementation>org.apache.maven.continuum.buildcontroller.BuildProjectTaskExecutor</implementation>
<requirements>
<requirement>
@@ -71,8 +72,8 @@
<component>
<role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
<role-hint>build-project</role-hint>
- <implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
- <instantiation-strategy>singleton</instantiation-strategy>
+ <instantiation-strategy>per-lookup</instantiation-strategy>
+ <implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
<requirements>
<requirement>
<role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
@@ -99,6 +100,7 @@
<role-hint>check-out-project</role-hint>
<implementation>org.codehaus.plexus.taskqueue.DefaultTaskQueue</implementation>
<lifecycle-handler>plexus-configurable</lifecycle-handler>
+ <instantiation-strategy>per-lookup</instantiation-strategy>
</component>
@@ -106,7 +108,7 @@
<role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
<role-hint>check-out-project</role-hint>
<implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
- <instantiation-strategy>singleton</instantiation-strategy>
+ <instantiation-strategy>per-lookup</instantiation-strategy>
<requirements>
<requirement>
<role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
@@ -134,13 +136,14 @@
<role-hint>prepare-build-project</role-hint>
<implementation>org.codehaus.plexus.taskqueue.DefaultTaskQueue</implementation>
<lifecycle-handler>plexus-configurable</lifecycle-handler>
+ <instantiation-strategy>per-lookup</instantiation-strategy>
</component>
<component>
<role>org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor</role>
<role-hint>prepare-build-project</role-hint>
<implementation>org.codehaus.plexus.taskqueue.execution.ThreadedTaskQueueExecutor</implementation>
- <instantiation-strategy>singleton</instantiation-strategy>
+ <instantiation-strategy>per-lookup</instantiation-strategy>
<requirements>
<requirement>
<role>org.codehaus.plexus.taskqueue.execution.TaskExecutor</role>
Added: continuum/branches/continuum-parallel-builds/continuum-core/src/test/java/org/apache/continuum/buildmanager/ParallelBuildsManagerTest.java
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-core/src/test/java/org/apache/continuum/buildmanager/ParallelBuildsManagerTest.java?rev=725657&view=auto
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-core/src/test/java/org/apache/continuum/buildmanager/ParallelBuildsManagerTest.java (added)
+++ continuum/branches/continuum-parallel-builds/continuum-core/src/test/java/org/apache/continuum/buildmanager/ParallelBuildsManagerTest.java Thu Dec 11 03:02:39 2008
@@ -0,0 +1,687 @@
+package org.apache.continuum.buildmanager;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.continuum.dao.BuildDefinitionDao;
+import org.apache.continuum.taskqueue.OverallBuildQueue;
+import org.apache.maven.continuum.model.project.BuildDefinition;
+import org.apache.maven.continuum.model.project.BuildQueue;
+import org.apache.maven.continuum.model.project.Project;
+import org.apache.maven.continuum.model.project.Schedule;
+import org.codehaus.plexus.spring.PlexusInSpringTestCase;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit3.JUnit3Mockery;
+
+/**
+ *
+ * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
+ */
+public class ParallelBuildsManagerTest
+ extends PlexusInSpringTestCase
+{
+ private ParallelBuildsManager buildsManager;
+
+ Mockery context;
+
+ private BuildDefinitionDao buildDefinitionDao;
+
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+
+ buildsManager = ( ParallelBuildsManager ) lookup( BuildsManager.class, "parallel" );
+
+ context = new JUnit3Mockery();
+
+ buildDefinitionDao = context.mock( BuildDefinitionDao.class );
+
+ buildsManager.setBuildDefinitionDao( buildDefinitionDao );
+ }
+
+ public void tearDown()
+ throws Exception
+ {
+ super.tearDown();
+
+ buildsManager = null;
+ }
+
+ private List<BuildQueue> getBuildQueues( int start, int end )
+ {
+ List<BuildQueue> buildQueues = new ArrayList<BuildQueue>();
+ for( int i = start; i <= end; i++ )
+ {
+ BuildQueue buildQueue = new BuildQueue();
+ buildQueue.setId( i );
+ buildQueue.setName( "BUILD_QUEUE_" + String.valueOf( i ) );
+ buildQueues.add( buildQueue );
+ }
+
+ return buildQueues;
+ }
+
+ private Schedule getSchedule( int id, int start, int end )
+ {
+ Schedule schedule = new Schedule();
+ schedule.setId( id );
+ schedule.setName( "DEFAULT_SCHEDULE" );
+ schedule.setCronExpression( "0 0 * * * ?" );
+ schedule.setDelay( 100 );
+ schedule.setMaxJobExecutionTime( 10000 );
+ schedule.setBuildQueues( getBuildQueues( start, end ) );
+
+ return schedule;
+ }
+
+ private void setupOverallBuildQueues()
+ {
+ for( int i = 1; i <= 5; i++ )
+ {
+ OverallBuildQueue overallBuildQueue = ( OverallBuildQueue ) lookup( OverallBuildQueue.class );
+ overallBuildQueue.setId( i );
+ overallBuildQueue.setName( "BUILD_QUEUE_" + String.valueOf( i ) );
+
+ buildsManager.addOverallBuildQueue( overallBuildQueue );
+ }
+
+ assertEquals( 5, buildsManager.getOverallBuildQueues().size() );
+ }
+
+// start of tests...
+
+ public void testBuildProjectNoProjectQueuedInAnyOverallBuildQueues()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 2 ) );
+
+ buildsManager.buildProject( 1, buildDef, "continuum-project-test-1", 1 );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+ OverallBuildQueue whereBuildIsQueued = overallBuildQueues.get( 1 );
+
+ assertNotNull( whereBuildIsQueued );
+ assertEquals( 1, whereBuildIsQueued.getId() );
+ assertEquals( "BUILD_QUEUE_1", whereBuildIsQueued.getName() );
+
+ // verify that other build queues are not used
+ assertFalse( overallBuildQueues.get( 2 ).isInBuildQueue( 1 ) );
+ assertFalse( overallBuildQueues.get( 3 ).isInBuildQueue( 1 ) );
+ assertFalse( overallBuildQueues.get( 4 ).isInBuildQueue( 1 ) );
+ assertFalse( overallBuildQueues.get( 5 ).isInBuildQueue( 1 ) );
+ }
+
+ public void testBuildProjectProjectsAreAlreadyQueuedInOverallBuildQueues()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 2 ) );
+
+ buildsManager.buildProject( 1, buildDef, "continuum-project-test-1", 1 );
+ buildsManager.buildProject( 2, buildDef, "continuum-project-test-2", 1 );
+ buildsManager.buildProject( 3, buildDef, "continuum-project-test-3", 1 );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+
+ assertNotNull( overallBuildQueues.get( 1 ) );
+ assertNotNull( overallBuildQueues.get( 2 ) );
+
+ assertTrue( overallBuildQueues.get( new Integer( 1 ) ).isInBuildQueue( 1, buildDef.getId() ) );
+ assertTrue( overallBuildQueues.get( new Integer( 1 ) ).isInBuildQueue( 3, buildDef.getId() ) );
+ assertTrue( overallBuildQueues.get( new Integer( 2 ) ).isInBuildQueue( 2, buildDef.getId() ) );
+ }
+
+ /*public void testBuildProjectProjectAlreadyInQueue()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 2 ) );
+
+ buildManager.buildProject( 1, buildDef, "continuum-project-test-1", 1 );
+ buildManager.buildProject( 2, buildDef, "continuum-project-test-2", 1 );
+ buildManager.buildProject( 1, buildDef, "continuum-project-test-1", 1 );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildManager.getOverallBuildQueues();
+
+ assertNotNull( overallBuildQueues.get( new Integer( 1 ) ) );
+ assertNotNull( overallBuildQueues.get( new Integer( 2 ) ) );
+
+ assertTrue( overallBuildQueues.get( new Integer( 1 ) ).isInBuildQueue( 1, buildDef.getId() ) );
+ assertTrue( overallBuildQueues.get( new Integer( 2 ) ).isInBuildQueue( 2, buildDef.getId() ) );
+ }*/
+
+ public void testBuildProjects()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 2 ) );
+
+ List<Project> projects = new ArrayList<Project>();
+ Project project = new Project();
+ project.setId( 4 );
+ project.setGroupId( "org.apache.continuum" );
+ project.setArtifactId( "continuum-test-1" );
+ project.addBuildDefinition( buildDef );
+ projects.add( project );
+
+ project = new Project();
+ project.setId( 5 );
+ project.setGroupId( "org.apache.continuum" );
+ project.setArtifactId( "continuum-test-2" );
+ project.addBuildDefinition( buildDef );
+ projects.add( project );
+
+ project = new Project();
+ project.setId( 6 );
+ project.setGroupId( "org.apache.continuum" );
+ project.setArtifactId( "continuum-test-3" );
+ project.addBuildDefinition( buildDef );
+ projects.add( project );
+
+ Map<Integer, BuildDefinition> projectsBuildDefinitionsMap = new HashMap<Integer, BuildDefinition>();
+ projectsBuildDefinitionsMap.put( 4, buildDef );
+ projectsBuildDefinitionsMap.put( 5, buildDef );
+ projectsBuildDefinitionsMap.put( 6, buildDef );
+
+ // populate build queue
+ buildsManager.buildProject( 1, buildDef, "continuum-project-test-1", 1 );
+ buildsManager.buildProject( 2, buildDef, "continuum-project-test-2", 1 );
+ buildsManager.buildProject( 3, buildDef, "continuum-project-test-3", 1 );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+
+ assertTrue( overallBuildQueues.get( 1 ).isInBuildQueue( 1, buildDef.getId() ) );
+ assertTrue( overallBuildQueues.get( 1 ).isInBuildQueue( 3, buildDef.getId() ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 2, buildDef.getId() ) );
+
+ // build a set of projects
+ buildsManager.buildProjects( projects, projectsBuildDefinitionsMap, 1 );
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+
+ assertFalse( overallBuildQueues.get( 1 ).isInBuildQueue( 4 ) );
+ assertFalse( overallBuildQueues.get( 1 ).isInBuildQueue( 5 ) );
+ assertFalse( overallBuildQueues.get( 1 ).isInBuildQueue( 6 ) );
+
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 4 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 5 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 6 ) );
+ }
+
+ /*public void testCancelCurrentBuild()
+ throws Exception
+ {
+
+ }
+
+ public void testCancelAllBuilds()
+ throws Exception
+ {
+ }*/
+
+ public void testRemoveProjectFromBuildQueue()
+ throws Exception
+ {
+ // - if project is built from a group, should the whole group be cancelled?
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 2 ) );
+
+ // populate build queue
+ buildsManager.buildProject( 1, buildDef, "continuum-project-test-1", 1 );
+ buildsManager.buildProject( 2, buildDef, "continuum-project-test-2", 1 );
+ buildsManager.buildProject( 3, buildDef, "continuum-project-test-3", 1 );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+
+ assertTrue( overallBuildQueues.get( 1 ).isInBuildQueue( 1, buildDef.getId() ) );
+ assertTrue( overallBuildQueues.get( 1 ).isInBuildQueue( 3, buildDef.getId() ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 2, buildDef.getId() ) );
+
+ // remove project 1
+ buildsManager.removeProjectFromBuildQueue( 1 );
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertFalse( overallBuildQueues.get( 1 ).isInBuildQueue( 1, buildDef.getId() ) );
+
+ // remove project 2
+ buildsManager.removeProjectFromBuildQueue( 2 );
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertFalse( overallBuildQueues.get( 2 ).isInBuildQueue( 2, buildDef.getId() ) );
+
+ // remove project 3
+ buildsManager.removeProjectFromBuildQueue( 3 );
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertFalse( overallBuildQueues.get( 1 ).isInBuildQueue( 3, buildDef.getId() ) );
+ }
+
+ public void testRemoveProjectFromBuildQueueProjectNotInAnyBuildQueue()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ try
+ {
+ buildsManager.removeProjectFromBuildQueue( 1 );
+ fail( "An exception should have been thrown." );
+ }
+ catch( BuildManagerException e )
+ {
+ assertEquals( "Project not found in any of the build queues.", e.getMessage() );
+ }
+ }
+
+ public void testRemoveProjectsFromBuildQueue()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 2 ) );
+
+ int[] projectIds = new int[]{ 1, 2, 3 };
+
+ // populate build queue
+ buildsManager.buildProject( 1, buildDef, "continuum-project-test-1", 1 );
+ buildsManager.buildProject( 2, buildDef, "continuum-project-test-2", 1 );
+ buildsManager.buildProject( 3, buildDef, "continuum-project-test-3", 1 );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+
+ assertTrue( overallBuildQueues.get( 1 ).isInBuildQueue( 1, buildDef.getId() ) );
+ assertTrue( overallBuildQueues.get( 1 ).isInBuildQueue( 3, buildDef.getId() ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 2, buildDef.getId() ) );
+
+ // remove all projects
+ buildsManager.removeProjectsFromBuildQueue( projectIds );
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertFalse( overallBuildQueues.get( 1 ).isInBuildQueue( 1, buildDef.getId() ) );
+ assertFalse( overallBuildQueues.get( 2 ).isInBuildQueue( 2, buildDef.getId() ) );
+ assertFalse( overallBuildQueues.get( 1 ).isInBuildQueue( 3, buildDef.getId() ) );
+ }
+
+ public void testCheckoutProjectSingle()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 2 ) );
+
+ buildsManager.checkoutProject( 1, "continuum-test-1", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 1 ) );
+
+ // verify that other build queues are not used
+ assertFalse( overallBuildQueues.get( 2 ).isInCheckoutQueue( 1 ) );
+ assertFalse( overallBuildQueues.get( 3 ).isInCheckoutQueue( 1 ) );
+ assertFalse( overallBuildQueues.get( 4 ).isInCheckoutQueue( 1 ) );
+ assertFalse( overallBuildQueues.get( 5 ).isInCheckoutQueue( 1 ) );
+ }
+
+ public void testCheckoutProjectMultiple()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 2 ) );
+
+ buildsManager.checkoutProject( 1, "continuum-test-1", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 2, "continuum-test-2", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 3, "continuum-test-3", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 4, "continuum-test-4", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 5, "continuum-test-5", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 1 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInCheckoutQueue( 2 ) );
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 3 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInCheckoutQueue( 4 ) );
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 5 ) );
+ }
+
+ /*public void testPrepareBuildProject()
+ throws Exception
+ {
+
+ }
+
+ public void testPrepareBuildProjectProjectAlreadyInQueue()
+ throws Exception
+ {
+
+ }*/
+
+ /*public void testPrepareBuildProjects()
+ throws Exception
+ {
+ //buildManager.prepareBuildProjects( projectsBuildDefinitions, trigger, scheduleId )
+ }*/
+
+
+ /*public void testCancelCheckoutOfProject()
+ throws Exception
+ {
+
+ }
+
+ public void testCancelAllCheckouts()
+ throws Exception
+ {
+
+ }
+
+ public void testCancelCheckoutInBuildQueue()
+ throws Exception
+ {
+
+ }*/
+
+ /*public void testCancelCurrentPrepareBuild()
+ throws Exception
+ {
+
+ }
+*/
+
+ public void testRemoveProjectFromCheckoutQueue()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 2 ) );
+
+ buildsManager.checkoutProject( 1, "continuum-test-1", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 2, "continuum-test-2", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 3, "continuum-test-3", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 1 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInCheckoutQueue( 2 ) );
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 3 ) );
+
+ buildsManager.removeProjectFromCheckoutQueue( 1 );
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertFalse( overallBuildQueues.get( 1 ).isInCheckoutQueue( 1 ) );
+
+ buildsManager.removeProjectFromCheckoutQueue( 2 );
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertFalse( overallBuildQueues.get( 2 ).isInCheckoutQueue( 2 ) );
+
+ buildsManager.removeProjectFromCheckoutQueue( 3 );
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertFalse( overallBuildQueues.get( 1 ).isInCheckoutQueue( 3 ) );
+ }
+
+ public void testRemoveProjectFromCheckoutQueueProjectNotInAnyCheckoutQueue()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ try
+ {
+ buildsManager.removeProjectFromCheckoutQueue( 1 );
+ fail( "An exception should have been thrown." );
+ }
+ catch ( BuildManagerException e )
+ {
+ assertEquals( "Project not found in any of the checkout queues.", e.getMessage() );
+ }
+ }
+
+ public void testRemoveProjectsFromCheckoutQueue()
+ throws Exception
+ {
+ setupOverallBuildQueues();
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 2 ) );
+
+ buildsManager.checkoutProject( 1, "continuum-test-1", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 2, "continuum-test-2", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 3, "continuum-test-3", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 1 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInCheckoutQueue( 2 ) );
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 3 ) );
+
+ int[] projectIds = new int[]{ 1, 2 , 3 };
+ buildsManager.removeProjectsFromCheckoutQueue( projectIds );
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertFalse( overallBuildQueues.get( 1 ).isInCheckoutQueue( 1 ) );
+ assertFalse( overallBuildQueues.get( 2 ).isInCheckoutQueue( 2 ) );
+ assertFalse( overallBuildQueues.get( 1 ).isInCheckoutQueue( 3 ) );
+ }
+
+ /*public void testRemoveProjectFromPrepareBuildQueue()
+ throws Exception
+ {
+
+ }*/
+
+ public void testRemoveOverallBuildQueue()
+ throws Exception
+ {
+ // queued tasks (both checkout & build tasks) must be transferred to the other queues!
+ setupOverallBuildQueues();
+ assertEquals( 5, buildsManager.getOverallBuildQueues().size() );
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 1, 3 ) );
+
+ // populate build queue
+ buildsManager.buildProject( 1, buildDef, "continuum-build-test-1", 1 );
+ buildsManager.buildProject( 2, buildDef, "continuum-build-test-2", 1 );
+ buildsManager.buildProject( 3, buildDef, "continuum-build-test-3", 1 );
+ buildsManager.buildProject( 4, buildDef, "continuum-build-test-4", 1 );
+ buildsManager.buildProject( 5, buildDef, "continuum-build-test-5", 1 );
+
+ Map<Integer, OverallBuildQueue> overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertTrue( overallBuildQueues.get( 1 ).isInBuildQueue( 1 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 2 ) );
+ assertTrue( overallBuildQueues.get( 3 ).isInBuildQueue( 3 ) );
+ assertTrue( overallBuildQueues.get( 1 ).isInBuildQueue( 4 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 5 ) );
+
+ // populate checkout queue
+ buildsManager.checkoutProject( 6, "continuum-checkout-test-6",
+ new File( getBasedir(), "/target/test-working-dir/1" ),"dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 7, "continuum-checkout-test-7",
+ new File( getBasedir(), "/target/test-working-dir/1" ),"dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 8, "continuum-checkout-test-8",
+ new File( getBasedir(), "/target/test-working-dir/1" ),"dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 9, "continuum-checkout-test-9",
+ new File( getBasedir(), "/target/test-working-dir/1" ),"dummy", "dummypass", buildDef );
+ buildsManager.checkoutProject( 10, "continuum-checkout-test-10",
+ new File( getBasedir(), "/target/test-working-dir/1" ),"dummy", "dummypass", buildDef );
+
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 6 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInCheckoutQueue( 7 ) );
+ assertTrue( overallBuildQueues.get( 3 ).isInCheckoutQueue( 8 ) );
+ assertTrue( overallBuildQueues.get( 1 ).isInCheckoutQueue( 9 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInCheckoutQueue( 10 ) );
+
+ final BuildDefinition buildDefinition = new BuildDefinition();
+ buildDefinition.setId( 1 );
+ buildDefinition.setSchedule( getSchedule( 1, 2, 3 ) );
+
+ // set expectations
+ context.checking( new Expectations()
+ {
+ {
+ exactly( 2 ).of( buildDefinitionDao ).getBuildDefinition( 1 );
+ will( returnValue( buildDefinition ) );
+ }
+ } );
+
+ context.checking( new Expectations()
+ {
+ {
+ one( buildDefinitionDao ).getDefaultBuildDefinition( 6 );
+ will( returnValue( buildDefinition ) );
+
+ one( buildDefinitionDao ).getDefaultBuildDefinition( 9 );
+ will( returnValue( buildDefinition ) );
+ }
+ } );
+
+ buildsManager.removeOverallBuildQueue( 1 );
+
+ // verify
+ context.assertIsSatisfied();
+
+ overallBuildQueues = buildsManager.getOverallBuildQueues();
+ assertEquals( 4, overallBuildQueues.size() );
+
+ // checkout queues
+ assertNull( overallBuildQueues.get( 1 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInCheckoutQueue( 7 ) );
+ assertTrue( overallBuildQueues.get( 3 ).isInCheckoutQueue( 8 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInCheckoutQueue( 10 ) );
+ assertTrue( overallBuildQueues.get( 3 ).isInCheckoutQueue( 6 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInCheckoutQueue( 9 ) );
+
+ // build queues
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 2 ) );
+ assertTrue( overallBuildQueues.get( 3 ).isInBuildQueue( 3 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 5 ) );
+ assertTrue( overallBuildQueues.get( 3 ).isInBuildQueue( 1 ) );
+ assertTrue( overallBuildQueues.get( 2 ).isInBuildQueue( 4 ) );
+ }
+
+ public void testNoBuildQueuesConfigured()
+ throws Exception
+ {
+ OverallBuildQueue overallBuildQueue = ( OverallBuildQueue ) lookup( OverallBuildQueue.class );
+ overallBuildQueue.setId( 1 );
+ overallBuildQueue.setName( "BUILD_QUEUE_1" );
+
+ buildsManager.addOverallBuildQueue( overallBuildQueue );
+
+ BuildDefinition buildDef = new BuildDefinition();
+ buildDef.setId( 1 );
+ buildDef.setSchedule( getSchedule( 1, 2, 3 ) );
+
+ // test if buildProject(...) is invoked
+ try
+ {
+ buildsManager.buildProject( 1, buildDef, "continuum-project-test-1", 1 );
+ fail( "An exception should have been thrown." );
+ }
+ catch ( BuildManagerException e )
+ {
+ assertEquals( "No build queue found.", e.getMessage() );
+ }
+
+ // test if buildProjects(...) is invoked
+ List<Project> projects = new ArrayList<Project>();
+ Project project = new Project();
+ project.setId( 4 );
+ project.setGroupId( "org.apache.continuum" );
+ project.setArtifactId( "continuum-test-4" );
+ project.addBuildDefinition( buildDef );
+ projects.add( project );
+
+ project = new Project();
+ project.setId( 5 );
+ project.setGroupId( "org.apache.continuum" );
+ project.setArtifactId( "continuum-test-5" );
+ project.addBuildDefinition( buildDef );
+ projects.add( project );
+
+ Map<Integer, BuildDefinition> projectsBuildDefinitionsMap = new HashMap<Integer, BuildDefinition>();
+ projectsBuildDefinitionsMap.put( 4, buildDef );
+ projectsBuildDefinitionsMap.put( 5, buildDef );
+
+ try
+ {
+ buildsManager.buildProjects( projects, projectsBuildDefinitionsMap, 1 );
+ fail( "An exception should have been thrown." );
+ }
+ catch ( BuildManagerException e )
+ {
+ assertEquals( "No build queue found.", e.getMessage() );
+ }
+
+ // test if checkoutProject(..) is invoked
+ try
+ {
+ buildsManager.checkoutProject( 6, "continuum-checkout-test-1", new File( getBasedir(), "/target/test-working-dir/1" ),
+ "dummy", "dummypass", buildDef );
+ fail( "An exception should have been thrown." );
+ }
+ catch ( BuildManagerException e )
+ {
+ assertEquals( "No build queue found.", e.getMessage() );
+ }
+ }
+}
Modified: continuum/branches/continuum-parallel-builds/continuum-model/pom.xml
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-model/pom.xml?rev=725657&r1=725656&r2=725657&view=diff
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-model/pom.xml (original)
+++ continuum/branches/continuum-parallel-builds/continuum-model/pom.xml Thu Dec 11 03:02:39 2008
@@ -63,7 +63,7 @@
</execution>
</executions>
<configuration>
- <version>1.1.3</version>
+ <version>1.1.4</version>
<packageWithVersion>false</packageWithVersion>
<model>src/main/mdo/continuum.xml</model>
</configuration>
Modified: continuum/branches/continuum-parallel-builds/continuum-model/src/main/mdo/continuum.xml
URL: http://svn.apache.org/viewvc/continuum/branches/continuum-parallel-builds/continuum-model/src/main/mdo/continuum.xml?rev=725657&r1=725656&r2=725657&view=diff
==============================================================================
--- continuum/branches/continuum-parallel-builds/continuum-model/src/main/mdo/continuum.xml (original)
+++ continuum/branches/continuum-parallel-builds/continuum-model/src/main/mdo/continuum.xml Thu Dec 11 03:02:39 2008
@@ -1030,6 +1030,27 @@
</fields>
</class>
<class>
+ <name>BuildQueue</name>
+ <version>1.1.4+</version>
+ <description><![CDATA[
+ Build queue.
+ ]]></description>
+ <fields>
+ <field>
+ <name>id</name>
+ <version>1.1.4+</version>
+ <identifier>true</identifier>
+ <type>int</type>
+ </field>
+ <field>
+ <name>name</name>
+ <version>1.1.4+</version>
+ <type>String</type>
+ <required>true</required>
+ </field>
+ </fields>
+ </class>
+ <class>
<name>Schedule</name>
<version>1.0.9+</version>
<description><![CDATA[
@@ -1088,6 +1109,14 @@
<version>1.0.9+</version>
<type>String</type>
</field>
+ <field jpox.fetch-groups="schedule-build-queues">
+ <name>buildQueues</name>
+ <version>1.1.4+</version>
+ <association xml.reference="true" stash.part="true" jpox.dependent="false">
+ <type>BuildQueue</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
</fields>
</class>
@@ -1593,7 +1622,6 @@
<required>true</required>
</field>
</fields>
- </class>
-
+ </class>
</classes>
</model>