blob: 62a75e74b3ea30538ec924d0b4ce50f74464caac [file] [log] [blame]
package org.apache.maven.continuum.scm.queue;
/*
* 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 org.apache.continuum.buildmanager.BuildsManager;
import org.apache.continuum.buildmanager.ParallelBuildsManager;
import org.apache.continuum.dao.ProjectScmRootDao;
import org.apache.continuum.model.project.ProjectScmRoot;
import org.apache.continuum.taskqueue.BuildProjectTask;
import org.apache.continuum.taskqueue.PrepareBuildProjectsTask;
import org.apache.maven.continuum.AbstractContinuumTest;
import org.apache.maven.continuum.configuration.ConfigurationService;
import org.apache.maven.continuum.core.action.AbstractContinuumAction;
import org.apache.maven.continuum.model.project.BuildDefinition;
import org.apache.maven.continuum.model.project.Project;
import org.apache.maven.continuum.model.project.ProjectGroup;
import org.apache.maven.continuum.project.ContinuumProjectState;
import org.apache.maven.continuum.project.builder.ContinuumProjectBuilder;
import org.apache.maven.continuum.project.builder.ContinuumProjectBuilderException;
import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
import org.apache.maven.continuum.project.builder.maven.MavenTwoContinuumProjectBuilder;
import org.codehaus.plexus.action.ActionManager;
import org.codehaus.plexus.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PrepareBuildProjectsTaskExecutorTest
extends AbstractContinuumTest
{
private ContinuumProjectBuilder projectBuilder;
private ActionManager actionManager;
private ProjectScmRootDao projectScmRootDao;
private ConfigurationService configurationService;
private BuildsManager buildsManager;
@Override
protected void setUp()
throws Exception
{
super.setUp();
projectBuilder = (ContinuumProjectBuilder) lookup( ContinuumProjectBuilder.ROLE,
MavenTwoContinuumProjectBuilder.ID );
projectScmRootDao = (ProjectScmRootDao) lookup( ProjectScmRootDao.class.getName() );
actionManager = (ActionManager) lookup( ActionManager.ROLE );
configurationService = (ConfigurationService) lookup( "configurationService" );
buildsManager = (ParallelBuildsManager) lookup( BuildsManager.class, "parallel" );
}
public void testCheckoutPrepareBuildMultiModuleProject()
throws Exception
{
PrepareBuildProjectsTask task = createTask( "src/test-projects/multi-module/pom.xml", false, false );
List<Project> projects = getProjectDao().getProjectsInGroup( task.getProjectGroupId() );
assertEquals( "failed to add all projects", 4, projects.size() );
Project rootProject = getProjectDao().getProjectByName( "multi-module-parent" );
Project moduleA = getProjectDao().getProjectByName( "module-A" );
Project moduleB = getProjectDao().getProjectByName( "module-B" );
Project moduleD = getProjectDao().getProjectByName( "module-D" );
buildsManager.prepareBuildProjects( task.getProjectsBuildDefinitionsMap(), task.getBuildTrigger(),
task.getProjectGroupId(), task.getProjectGroupName(),
task.getScmRootAddress(), task.getProjectScmRootId() );
// wait while task finishes prepare build
waitForPrepareBuildToFinish( task.getProjectGroupId(), task.getProjectScmRootId() );
ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( task.getProjectScmRootId() );
assertEquals( "Failed to update multi-module project", ContinuumProjectState.UPDATED, scmRoot.getState() );
File workingDir = configurationService.getWorkingDirectory();
assertTrue( "checkout directory of project 'multi-module-parent' does not exist.", new File( workingDir,
Integer.toString(
rootProject.getId() ) ).exists() );
assertTrue( "checkout directory of project 'module-A' does not exist.", new File( workingDir, Integer.toString(
moduleA.getId() ) ).exists() );
assertTrue( "checkout directory of project 'module-B' does not exist.", new File( workingDir, Integer.toString(
moduleB.getId() ) ).exists() );
assertTrue( "checkout directory of project 'module-D' does not exist.", new File( workingDir, Integer.toString(
moduleD.getId() ) ).exists() );
assertTrue( "failed to checkout project 'multi-module-parent'", new File( workingDir, Integer.toString(
rootProject.getId() ) ).list().length > 0 );
assertTrue( "failed to checkout project 'module-A'", new File( workingDir, Integer.toString(
moduleA.getId() ) ).list().length > 0 );
assertTrue( "failed to checkout project 'module-B'", new File( workingDir, Integer.toString(
moduleB.getId() ) ).list().length > 0 );
assertTrue( "failed to checkout project 'module-D'", new File( workingDir, Integer.toString(
moduleD.getId() ) ).list().length > 0 );
// wait while task finished build
waitForBuildToFinish();
}
public void testCheckoutPrepareBuildMultiModuleProjectFreshBuild()
throws Exception
{
PrepareBuildProjectsTask task = createTask( "src/test-projects/multi-module/pom.xml", false, true );
List<Project> projects = getProjectDao().getProjectsInGroup( task.getProjectGroupId() );
assertEquals( "failed to add all projects", 4, projects.size() );
Project rootProject = getProjectDao().getProjectByName( "multi-module-parent" );
Project moduleA = getProjectDao().getProjectByName( "module-A" );
Project moduleB = getProjectDao().getProjectByName( "module-B" );
Project moduleD = getProjectDao().getProjectByName( "module-D" );
buildsManager.prepareBuildProjects( task.getProjectsBuildDefinitionsMap(), task.getBuildTrigger(),
task.getProjectGroupId(), task.getProjectGroupName(),
task.getScmRootAddress(), task.getProjectScmRootId() );
// wait while task finishes prepare build
waitForPrepareBuildToFinish( task.getProjectGroupId(), task.getProjectScmRootId() );
ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( task.getProjectScmRootId() );
assertEquals( "Failed to update multi-module project", ContinuumProjectState.UPDATED, scmRoot.getState() );
File workingDir = configurationService.getWorkingDirectory();
assertTrue( "checkout directory of project 'multi-module-parent' does not exist.", new File( workingDir,
Integer.toString(
rootProject.getId() ) ).exists() );
assertTrue( "checkout directory of project 'module-A' does not exist.", new File( workingDir, Integer.toString(
moduleA.getId() ) ).exists() );
assertTrue( "checkout directory of project 'module-B' does not exist.", new File( workingDir, Integer.toString(
moduleB.getId() ) ).exists() );
assertTrue( "checkout directory of project 'module-D' does not exist.", new File( workingDir, Integer.toString(
moduleD.getId() ) ).exists() );
assertTrue( "failed to checkout project 'multi-module-parent'", new File( workingDir, Integer.toString(
rootProject.getId() ) ).list().length > 0 );
assertTrue( "failed to checkout project 'module-A'", new File( workingDir, Integer.toString(
moduleA.getId() ) ).list().length > 0 );
assertTrue( "failed to checkout project 'module-B'", new File( workingDir, Integer.toString(
moduleB.getId() ) ).list().length > 0 );
assertTrue( "failed to checkout project 'module-D'", new File( workingDir, Integer.toString(
moduleD.getId() ) ).list().length > 0 );
// wait while task finished build
waitForBuildToFinish();
}
public void testCheckoutPrepareBuildSingleCheckedoutMultiModuleProject()
throws Exception
{
PrepareBuildProjectsTask task = createTask( "src/test-projects/multi-module/pom.xml", true, false );
List<Project> projects = getProjectDao().getProjectsInGroup( task.getProjectGroupId() );
assertEquals( "failed to add all projects", 4, projects.size() );
Project rootProject = getProjectDao().getProjectByName( "multi-module-parent" );
buildsManager.prepareBuildProjects( task.getProjectsBuildDefinitionsMap(), task.getBuildTrigger(),
task.getProjectGroupId(), task.getProjectGroupName(),
task.getScmRootAddress(), task.getProjectScmRootId() );
// wait while task finishes prepare build
waitForPrepareBuildToFinish( task.getProjectGroupId(), task.getProjectScmRootId() );
ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( task.getProjectScmRootId() );
assertEquals( "Failed to update multi-module project", ContinuumProjectState.UPDATED, scmRoot.getState() );
File checkedOutDir = new File( configurationService.getWorkingDirectory(), Integer.toString(
rootProject.getId() ) );
assertTrue( "checkout directory of project 'multi-module-parent' does not exist.", checkedOutDir.exists() );
assertTrue( "module-A was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-A" ).exists() );
assertTrue( "module-B was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-B" ).exists() );
assertTrue( "module-D was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-C/module-D" ).exists() );
assertTrue( "failed to checkout project 'multi-module-parent'", checkedOutDir.list().length > 0 );
assertTrue( "failed to checkout project 'module-A'", new File( checkedOutDir, "module-A" ).list().length > 0 );
assertTrue( "failed to checkout project 'module-B'", new File( checkedOutDir, "module-B" ).list().length > 0 );
assertTrue( "failed to checkout project 'module-D'", new File( checkedOutDir,
"module-C/module-D" ).list().length > 0 );
// wait while task finishes build
waitForBuildToFinish();
}
public void testCheckoutPrepareBuildSingleCheckedoutMultiModuleProjectFreshBuild()
throws Exception
{
PrepareBuildProjectsTask task = createTask( "src/test-projects/multi-module/pom.xml", true, true );
List<Project> projects = getProjectDao().getProjectsInGroup( task.getProjectGroupId() );
assertEquals( "failed to add all projects", 4, projects.size() );
Project rootProject = getProjectDao().getProjectByName( "multi-module-parent" );
buildsManager.prepareBuildProjects( task.getProjectsBuildDefinitionsMap(), task.getBuildTrigger(),
task.getProjectGroupId(), task.getProjectGroupName(),
task.getScmRootAddress(), task.getProjectScmRootId() );
// wait while task finishes prepare build
waitForPrepareBuildToFinish( task.getProjectGroupId(), task.getProjectScmRootId() );
ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( task.getProjectScmRootId() );
assertEquals( "Failed to update multi-module project", ContinuumProjectState.UPDATED, scmRoot.getState() );
File checkedOutDir = new File( configurationService.getWorkingDirectory(), Integer.toString(
rootProject.getId() ) );
assertTrue( "checkout directory of project 'multi-module-parent' does not exist.", checkedOutDir.exists() );
assertTrue( "module-A was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-A" ).exists() );
assertTrue( "module-B was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-B" ).exists() );
assertTrue( "module-D was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-C/module-D" ).exists() );
assertTrue( "failed to checkout project 'multi-module-parent'", checkedOutDir.list().length > 0 );
assertTrue( "failed to checkout project 'module-A'", new File( checkedOutDir, "module-A" ).list().length > 0 );
assertTrue( "failed to checkout project 'module-B'", new File( checkedOutDir, "module-B" ).list().length > 0 );
assertTrue( "failed to checkout project 'module-D'", new File( checkedOutDir,
"module-C/module-D" ).list().length > 0 );
// wait while task finishes build
waitForBuildToFinish();
}
public void testCheckoutPrepareBuildSingleCheckoutFlatMultiModuleProject()
throws Exception
{
PrepareBuildProjectsTask task = createTask( "src/test-projects/flat-multi-module/parent-project/pom.xml", true,
false );
List<Project> projects = getProjectDao().getProjectsInGroup( task.getProjectGroupId() );
assertEquals( "failed to add all projects", 4, projects.size() );
Project rootProject = getProjectDao().getProjectByName( "parent-project" );
buildsManager.prepareBuildProjects( task.getProjectsBuildDefinitionsMap(), task.getBuildTrigger(),
task.getProjectGroupId(), task.getProjectGroupName(),
task.getScmRootAddress(), task.getProjectScmRootId() );
// wait while task finishes prepare build
waitForPrepareBuildToFinish( task.getProjectGroupId(), task.getProjectScmRootId() );
ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( task.getProjectScmRootId() );
assertEquals( "Failed to update multi-module project", ContinuumProjectState.UPDATED, scmRoot.getState() );
File checkedOutDir = new File( configurationService.getWorkingDirectory(), Integer.toString(
rootProject.getId() ) );
assertTrue( "checkout directory of project 'parent-project' does not exist.", new File( checkedOutDir,
"parent-project" ).exists() );
assertTrue( "module-a was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-a" ).exists() );
assertTrue( "module-b was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-b" ).exists() );
assertTrue( "module-d was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-c/module-d" ).exists() );
assertTrue( "failed to checkout parent-project", new File( checkedOutDir, "parent-project" ).list().length >
0 );
assertTrue( "failed to checkout module-a", new File( checkedOutDir, "module-a" ).list().length > 0 );
assertTrue( "failed to checkout module-b", new File( checkedOutDir, "module-b" ).list().length > 0 );
assertTrue( "failed to checkout module-d", new File( checkedOutDir, "module-c/module-d" ).list().length > 0 );
// wait while task finishes build
waitForPrepareBuildToFinish( task.getProjectGroupId(), task.getProjectScmRootId() );
}
public void testCheckoutPrepareBuildSingleCheckoutFlatMultiModuleProjectBuildFresh()
throws Exception
{
PrepareBuildProjectsTask task = createTask( "src/test-projects/flat-multi-module/parent-project/pom.xml", true,
true );
List<Project> projects = getProjectDao().getProjectsInGroup( task.getProjectGroupId() );
assertEquals( "failed to add all projects", 4, projects.size() );
Project rootProject = getProjectDao().getProjectByName( "parent-project" );
buildsManager.prepareBuildProjects( task.getProjectsBuildDefinitionsMap(), task.getBuildTrigger(),
task.getProjectGroupId(), task.getProjectGroupName(),
task.getScmRootAddress(), task.getProjectScmRootId() );
// wait while task finishes prepare build
waitForPrepareBuildToFinish( task.getProjectGroupId(), task.getProjectScmRootId() );
ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( task.getProjectScmRootId() );
assertEquals( "Failed to update multi-module project", ContinuumProjectState.UPDATED, scmRoot.getState() );
File checkedOutDir = new File( configurationService.getWorkingDirectory(), Integer.toString(
rootProject.getId() ) );
assertTrue( "checkout directory of project 'parent-project' does not exist.", new File( checkedOutDir,
"parent-project" ).exists() );
assertTrue( "module-a was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-a" ).exists() );
assertTrue( "module-b was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-b" ).exists() );
assertTrue( "module-d was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-c/module-d" ).exists() );
assertTrue( "failed to checkout parent-project", new File( checkedOutDir, "parent-project" ).list().length >
0 );
assertTrue( "failed to checkout module-a", new File( checkedOutDir, "module-a" ).list().length > 0 );
assertTrue( "failed to checkout module-b", new File( checkedOutDir, "module-b" ).list().length > 0 );
assertTrue( "failed to checkout module-d", new File( checkedOutDir, "module-c/module-d" ).list().length > 0 );
// wait while task finishes build
waitForBuildToFinish();
}
public void testCheckoutPrepareBuildSingleCheckoutFlatMultiModuleProjectBuildFreshAfterRemovingWorkingCopy()
throws Exception
{
PrepareBuildProjectsTask task = createTask( "src/test-projects/flat-multi-module/parent-project/pom.xml", true,
true );
List<Project> projects = getProjectDao().getProjectsInGroup( task.getProjectGroupId() );
assertEquals( "failed to add all projects", 4, projects.size() );
Project rootProject = getProjectDao().getProjectByName( "parent-project" );
File rootProjectDir = new File( configurationService.getWorkingDirectory(), Integer.toString(
rootProject.getId() ) );
rootProjectDir = new File( rootProjectDir, "parent-project" );
rootProject.setWorkingDirectory( rootProjectDir.getAbsolutePath() );
getProjectDao().updateProject( rootProject );
buildsManager.prepareBuildProjects( task.getProjectsBuildDefinitionsMap(), task.getBuildTrigger(),
task.getProjectGroupId(), task.getProjectGroupName(),
task.getScmRootAddress(), task.getProjectScmRootId() );
// wait while task finishes prepare build
waitForPrepareBuildToFinish( task.getProjectGroupId(), task.getProjectScmRootId() );
ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( task.getProjectScmRootId() );
assertEquals( "Failed to update multi-module project", ContinuumProjectState.UPDATED, scmRoot.getState() );
File checkedOutDir = new File( configurationService.getWorkingDirectory(), Integer.toString(
rootProject.getId() ) );
assertTrue( "checkout directory of project 'parent-project' does not exist.", new File( checkedOutDir,
"parent-project" ).exists() );
assertTrue( "module-a was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-a" ).exists() );
assertTrue( "module-b was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-b" ).exists() );
assertTrue( "module-d was not checked out in the same directory as it's parent.", new File( checkedOutDir,
"module-c/module-d" ).exists() );
assertTrue( "failed to checkout parent-project", new File( checkedOutDir, "parent-project" ).list().length >
0 );
assertTrue( "failed to checkout module-a", new File( checkedOutDir, "module-a" ).list().length > 0 );
assertTrue( "failed to checkout module-b", new File( checkedOutDir, "module-b" ).list().length > 0 );
assertTrue( "failed to checkout module-d", new File( checkedOutDir, "module-c/module-d" ).list().length > 0 );
// wait while task finishes build
waitForBuildToFinish();
}
private PrepareBuildProjectsTask createTask( String pomResource, boolean singleCheckout, boolean buildFresh )
throws Exception
{
ProjectGroup projectGroup = getProjectGroup( pomResource, singleCheckout );
BuildDefinition buildDefinition = new BuildDefinition();
buildDefinition.setId( 0 );
buildDefinition.setGoals( "clean" );
buildDefinition.setBuildFresh( buildFresh );
projectGroup.addBuildDefinition( buildDefinition );
Map<String, Object> pgContext = new HashMap<String, Object>();
AbstractContinuumAction.setWorkingDirectory( pgContext,
configurationService.getWorkingDirectory().getAbsolutePath() );
AbstractContinuumAction.setUnvalidatedProjectGroup( pgContext, projectGroup );
actionManager.lookup( "validate-project-group" ).execute( pgContext );
actionManager.lookup( "store-project-group" ).execute( pgContext );
int projectGroupId = AbstractContinuumAction.getProjectGroupId( pgContext );
projectGroup = getProjectGroupDao().getProjectGroupWithBuildDetailsByProjectGroupId( projectGroupId );
String scmRootUrl = getScmRootUrl( projectGroup );
assertNotNull( scmRootUrl );
ProjectScmRoot scmRoot = getProjectScmRoot( projectGroup, scmRootUrl );
assertNotNull( scmRoot );
buildDefinition = (BuildDefinition) projectGroup.getBuildDefinitions().get( 0 );
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Project rootProject = null;
List<Project> projects = (List<Project>) projectGroup.getProjects();
for ( Project project : projects )
{
assertFalse( project.getId() == 0 );
map.put( project.getId(), buildDefinition.getId() );
if ( rootProject == null || rootProject.getId() > project.getId() )
{
rootProject = project;
}
}
assertEquals( 4, map.size() );
PrepareBuildProjectsTask task = new PrepareBuildProjectsTask( map,
new org.apache.continuum.utils.build.BuildTrigger(
1, "user" ), projectGroupId,
projectGroup.getName(),
scmRoot.getScmRootAddress(), scmRoot.getId() );
return task;
}
private ProjectGroup getProjectGroup( String pomResource, boolean singleCheckout )
throws ContinuumProjectBuilderException, IOException
{
File pom = getTestFile( pomResource );
assertNotNull( "Can't find project " + pomResource, pom );
//ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( pom.toURL(), null, null, true );
ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( pom.toURL(), null, null, true,
singleCheckout );
// some assertions to make sure our expectations match. This is NOT
// meant as a unit test for the projectbuilder!
assertNotNull( "Project list not null", result.getProjects() );
assertEquals( "#Projectgroups", 1, result.getProjectGroups().size() );
ProjectGroup pg = result.getProjectGroups().get( 0 );
if ( !result.getProjects().isEmpty() )
{
for ( Project p : result.getProjects() )
{
pg.addProject( p );
}
}
return pg;
}
private ProjectScmRoot getProjectScmRoot( ProjectGroup pg, String url )
throws Exception
{
if ( StringUtils.isEmpty( url ) )
{
return null;
}
ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRootByProjectGroupAndScmRootAddress( pg.getId(), url );
if ( scmRoot != null )
{
return scmRoot;
}
ProjectScmRoot projectScmRoot = new ProjectScmRoot();
projectScmRoot.setProjectGroup( pg );
projectScmRoot.setScmRootAddress( url );
//projectScmRoot.setState( ContinuumProjectState.ERROR );
return projectScmRootDao.addProjectScmRoot( projectScmRoot );
}
private String getScmRootUrl( ProjectGroup pg )
{
String scmRootUrl = null;
for ( Project project : (List<Project>) pg.getProjects() )
{
String scmUrl = project.getScmUrl();
scmRootUrl = getCommonPath( scmUrl, scmRootUrl );
}
return scmRootUrl;
}
private String getCommonPath( String path1, String path2 )
{
if ( path2 == null || path2.equals( "" ) )
{
return path1;
}
else
{
int indexDiff = StringUtils.differenceAt( path1, path2 );
return path1.substring( 0, indexDiff );
}
}
private void waitForPrepareBuildToFinish( int projectGroupId, int scmRootId )
throws Exception
{
while ( buildsManager.isInPrepareBuildQueue( projectGroupId, scmRootId ) ||
buildsManager.isProjectGroupCurrentlyPreparingBuild( projectGroupId, scmRootId ) )
{
Thread.sleep( 10 );
}
}
private void waitForBuildToFinish()
throws Exception
{
while ( buildsManager.isBuildInProgress() || isAnyProjectInBuildQueue() )
{
Thread.sleep( 10 );
}
}
private boolean isAnyProjectInBuildQueue()
throws Exception
{
Map<String, List<BuildProjectTask>> buildTasks = buildsManager.getProjectsInBuildQueues();
for ( String queue : buildTasks.keySet() )
{
if ( !buildTasks.get( queue ).isEmpty() )
{
return true;
}
}
return false;
}
}