View Javadoc

1   package org.apache.maven.continuum;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.Collection;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  
29  import org.apache.continuum.buildmanager.BuildsManager;
30  import org.apache.continuum.dao.BuildResultDao;
31  import org.apache.continuum.dao.ProjectDao;
32  import org.apache.continuum.model.release.ContinuumReleaseResult;
33  import org.apache.continuum.model.repository.LocalRepository;
34  import org.apache.continuum.repository.RepositoryService;
35  import org.apache.continuum.taskqueue.manager.TaskQueueManager;
36  import org.apache.maven.continuum.builddefinition.BuildDefinitionService;
37  import org.apache.maven.continuum.configuration.ConfigurationService;
38  import org.apache.maven.continuum.execution.ContinuumBuildExecutorConstants;
39  import org.apache.maven.continuum.initialization.ContinuumInitializer;
40  import org.apache.maven.continuum.model.project.BuildDefinition;
41  import org.apache.maven.continuum.model.project.BuildResult;
42  import org.apache.maven.continuum.model.project.Project;
43  import org.apache.maven.continuum.model.project.ProjectGroup;
44  import org.apache.maven.continuum.model.project.ProjectNotifier;
45  import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
46  import org.jmock.Expectations;
47  import org.jmock.Mockery;
48  import org.jmock.integration.junit3.JUnit3Mockery;
49  import org.slf4j.Logger;
50  import org.slf4j.LoggerFactory;
51  
52  /**
53   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
54   * @version $Id: DefaultContinuumTest.java 822551 2009-10-07 02:17:10Z ctan $
55   */
56  public class DefaultContinuumTest
57      extends AbstractContinuumTest
58  {
59      private static final Logger log = LoggerFactory.getLogger( DefaultContinuumTest.class );
60  
61      private Mockery context;
62  
63      private TaskQueueManager taskQueueManager;
64  
65      private ProjectDao projectDao;
66  
67      private BuildResultDao buildResultDao;
68  
69      @Override
70      protected void setUp()
71          throws Exception
72      {
73          super.setUp();
74  
75          context = new JUnit3Mockery();
76  
77          taskQueueManager = context.mock( TaskQueueManager.class );
78  
79          projectDao = context.mock( ProjectDao.class );
80      }
81  
82      public void testContinuumConfiguration()
83          throws Exception
84      {
85          lookup( Continuum.ROLE );
86      }
87  
88      public void testAddMavenTwoProjectSet()
89          throws Exception
90      {
91          Continuum continuum = (Continuum) lookup( Continuum.ROLE );
92  
93          int projectCount = getProjectDao().getAllProjectsByName().size();
94  
95          int projectGroupCount = getProjectGroupDao().getAllProjectGroupsWithProjects().size();
96  
97          File rootPom = getTestFile( "src/test/resources/projects/continuum/continuum-notifiers/pom.xml" );
98  
99          assertTrue( rootPom.exists() );
100 
101         ContinuumProjectBuildingResult result =
102             continuum.addMavenTwoProject( rootPom.toURI().toURL().toExternalForm(), -1, true, false, true, -1 );
103 
104         assertNotNull( result );
105 
106         assertEquals( "result.warnings.size" + result.getErrors(), 0, result.getErrors().size() );
107 
108         assertEquals( "result.projects.size", 3, result.getProjects().size() );
109 
110         assertEquals( "result.projectGroups.size", 1, result.getProjectGroups().size() );
111 
112         log.info( "number of projects: " + getProjectDao().getAllProjectsByName().size() );
113 
114         log.info( "number of project groups: " + getProjectGroupDao().getAllProjectGroupsWithProjects().size() );
115 
116         assertEquals( "Total project count", projectCount + 3, getProjectDao().getAllProjectsByName().size() );
117 
118         assertEquals( "Total project group count.", projectGroupCount + 1,
119                       getProjectGroupDao().getAllProjectGroupsWithProjects().size() );
120 
121         Map<String, Project> projects = new HashMap<String, Project>();
122 
123         for ( Project project : getProjectDao().getAllProjectsByName() )
124         {
125             projects.put( project.getName(), project );
126 
127             // validate project in project group
128             assertTrue( "project not in project group",
129                         getProjectGroupDao().getProjectGroupByProjectId( project.getId() ) != null );
130         }
131 
132         assertTrue( "no irc notifier", projects.containsKey( "Continuum IRC Notifier" ) );
133 
134         assertTrue( "no jabber notifier", projects.containsKey( "Continuum Jabber Notifier" ) );
135 
136 
137     }
138 
139     public void testUpdateMavenTwoProject()
140         throws Exception
141     {
142         Continuum continuum = (Continuum) lookup( Continuum.ROLE );
143 
144         // ----------------------------------------------------------------------
145         // Test projects with duplicate names
146         // ----------------------------------------------------------------------
147 
148         String url = getTestFile( "src/test-projects/project1/pom.xml" ).toURL().toExternalForm();
149 
150         ContinuumProjectBuildingResult result = continuum.addMavenTwoProject( url );
151 
152         assertNotNull( result );
153 
154         List<Project> projects = result.getProjects();
155 
156         assertEquals( 1, projects.size() );
157 
158         assertEquals( Project.class, projects.get( 0 ).getClass() );
159 
160         Project project = projects.get( 0 );
161 
162         // reattach
163         project = continuum.getProject( project.getId() );
164 
165         project.setName( project.getName() + " 2" );
166 
167         continuum.updateProject( project );
168 
169         project = continuum.getProject( project.getId() );
170     }
171 
172     public void testRemoveMavenTwoProject()
173         throws Exception
174     {
175         Continuum continuum = (Continuum) lookup( Continuum.ROLE );
176 
177         Project project = makeStubProject( "test-project" );
178 
179         ProjectGroup defaultGroup = getDefaultProjectGroup();
180 
181         defaultGroup.addProject( project );
182 
183         getProjectGroupDao().updateProjectGroup( defaultGroup );
184 
185         project = getProjectDao().getProjectByName( "test-project" );
186 
187         assertNotNull ( project );
188 
189         BuildResult buildResult = new BuildResult();
190 
191         getBuildResultDao().addBuildResult( project, buildResult );
192 
193         Collection<BuildResult> brs = continuum.getBuildResultsForProject( project.getId() );
194 
195         assertEquals( "Build result of project was not added", 1, brs.size() );
196 
197         // delete project
198         continuum.removeProject( project.getId() );
199 
200         try
201         {
202             continuum.getProject( project.getId() );
203 
204             fail( "Project was not removed" );
205         }
206         catch ( ContinuumException expected )
207         {
208             brs = continuum.getBuildResultsForProject( project.getId() );
209 
210             assertEquals( "Build result of project was not removed", 0, brs.size() );
211         }
212     }
213 
214     public void testBuildDefinitions()
215         throws Exception
216     {
217         Continuum continuum = (Continuum) lookup( Continuum.ROLE );
218 
219         String url = getTestFile( "src/test-projects/project1/pom.xml" ).toURL().toExternalForm();
220 
221         ContinuumProjectBuildingResult result = continuum.addMavenTwoProject( url );
222 
223         assertNotNull( result );
224 
225         List<Project> projects = result.getProjects();
226 
227         assertEquals( 1, projects.size() );
228 
229         assertEquals( Project.class, projects.get( 0 ).getClass() );
230 
231         Project project = projects.get( 0 );
232 
233         // reattach
234         project = continuum.getProject( project.getId() );
235 
236         ProjectGroup projectGroup = getProjectGroupDao().getProjectGroupByProjectId( project.getId() );
237 
238         projectGroup = getProjectGroupDao().getProjectGroupWithBuildDetailsByProjectGroupId( projectGroup.getId() );
239 
240         List<BuildDefinition> buildDefs = projectGroup.getBuildDefinitions();
241 
242         assertTrue( "missing project group build definition", !buildDefs.isEmpty() );
243 
244         assertTrue( "more then one project group build definition on add project", buildDefs.size() == 1 );
245 
246         BuildDefinition pgbd = buildDefs.get( 0 );
247 
248         pgbd.setGoals( "foo" );
249 
250         continuum.updateBuildDefinitionForProjectGroup( projectGroup.getId(), pgbd );
251 
252         pgbd = continuum.getBuildDefinition( pgbd.getId() );
253 
254         assertTrue( "update failed for project group build definition", "foo".equals( pgbd.getGoals() ) );
255 
256         assertTrue( "project group build definition is not default", pgbd.isDefaultForProject() );
257 
258         assertTrue( "project group build definition not default for project",
259                     continuum.getDefaultBuildDefinition( project.getId() ).getId() == pgbd.getId() );
260 
261         BuildDefinition nbd = new BuildDefinition();
262         nbd.setGoals( "clean" );
263         nbd.setArguments( "" );
264         nbd.setDefaultForProject( true );
265         nbd.setSchedule( getScheduleDao().getScheduleByName( ConfigurationService.DEFAULT_SCHEDULE_NAME ) );
266 
267         continuum.addBuildDefinitionToProject( project.getId(), nbd );
268 
269         assertTrue( "project lvl build definition not default for project",
270                     continuum.getDefaultBuildDefinition( project.getId() ).getId() == nbd.getId() );
271 
272         continuum.removeBuildDefinitionFromProject( project.getId(), nbd.getId() );
273 
274         assertTrue( "default build definition didn't toggle back to project group level",
275                     continuum.getDefaultBuildDefinition( project.getId() ).getId() == pgbd.getId() );
276 
277         try
278         {
279             continuum.removeBuildDefinitionFromProjectGroup( projectGroup.getId(), pgbd.getId() );
280             fail( "we were able to remove the default build definition, and that is bad" );
281         }
282         catch ( ContinuumException expected )
283         {
284 
285         }
286     }
287 
288     /**
289      * todo add another project group to test
290      */
291     public void testProjectGroups()
292         throws Exception
293     {
294         Continuum continuum = (Continuum) lookup( Continuum.ROLE );
295 
296         Collection projectGroupList = continuum.getAllProjectGroups();
297 
298         int projectGroupsBefore = projectGroupList.size();
299 
300         assertEquals( 1, projectGroupsBefore );
301 
302         String url = getTestFile( "src/test-projects/project1/pom.xml" ).toURL().toExternalForm();
303 
304         ContinuumProjectBuildingResult result = continuum.addMavenTwoProject( url );
305 
306         assertNotNull( result );
307 
308         assertEquals( 1, result.getProjectGroups().size() );
309 
310         ProjectGroup projectGroup = result.getProjectGroups().get( 0 );
311 
312         assertEquals( "plexus", projectGroup.getGroupId() );
313 
314         projectGroupList = continuum.getAllProjectGroups();
315 
316         assertEquals( "Project group missing, should have " + ( projectGroupsBefore + 1 ) + " project groups",
317                       projectGroupsBefore + 1, projectGroupList.size() );
318 
319         projectGroup = (ProjectGroup) projectGroupList.iterator().next();
320 
321         assertNotNull( projectGroup );
322 
323         BuildsManager buildsManager = continuum.getBuildsManager();
324 
325         List<Project> projects = continuum.getProjectGroupWithProjects( projectGroup.getId() ).getProjects();
326         int[] projectIds = new int[projects.size()];
327 
328         int idx = 0;
329         for ( Project project : projects )
330         {
331             projectIds[idx] = project.getId();
332             idx++;
333         }
334 
335         while ( buildsManager.isAnyProjectCurrentlyBeingCheckedOut( projectIds ) )
336         {
337         }
338 
339         continuum.removeProjectGroup( projectGroup.getId() );
340 
341         projectGroupList = continuum.getAllProjectGroups();
342 
343         assertEquals( "Remove project group failed", projectGroupsBefore, projectGroupList.size() );
344     }
345 
346     /**
347      * test the logic for notifiers
348      */
349     public void testProjectAndGroupNotifiers()
350         throws Exception
351     {
352         Continuum continuum = (Continuum) lookup( Continuum.ROLE );
353 
354         Collection projectGroupList = continuum.getAllProjectGroups();
355 
356         int projectGroupsBefore = projectGroupList.size();
357 
358         assertEquals( 1, projectGroupsBefore );
359 
360         String url = getTestFile( "src/test-projects/project1/pom.xml" ).toURL().toExternalForm();
361 
362         ContinuumProjectBuildingResult result = continuum.addMavenTwoProject( url );
363 
364         assertNotNull( result );
365 
366         assertEquals( 1, result.getProjectGroups().size() );
367 
368         ProjectGroup projectGroup = result.getProjectGroups().get( 0 );
369 
370         continuum.addGroupNotifier( projectGroup.getId(), new ProjectNotifier() );
371 
372         for ( Project p : (List<Project>) projectGroup.getProjects() )
373         {
374             continuum.addNotifier( p.getId(), new ProjectNotifier() );
375         }
376 
377         projectGroup = continuum.getProjectGroupWithBuildDetails( projectGroup.getId() );
378 
379         assertEquals( 1, projectGroup.getNotifiers().size() );
380 
381         for ( Project p : (List<Project>) projectGroup.getProjects() )
382         {
383             assertEquals( 2, p.getNotifiers().size() );
384         }
385     }
386 
387     public void testExecuteAction()
388         throws Exception
389     {
390         DefaultContinuum continuum = (DefaultContinuum) lookup( Continuum.ROLE );
391 
392         String exceptionName = ContinuumException.class.getName();
393         try
394         {
395             continuum.executeAction( "testAction", new HashMap() );
396         }
397         catch ( ContinuumException e )
398         {
399             //expected, check for twice wrapped exception
400             if ( e.getCause() != null )
401             {
402                 assertFalse( exceptionName + " is wrapped in " + exceptionName,
403                              e.getCause().getClass().equals( ContinuumException.class ) );
404             }
405         }
406     }
407 
408     public void testRemoveProjectFromCheckoutQueue()
409         throws Exception
410     {
411         Continuum continuum = (Continuum) lookup( Continuum.ROLE );
412 
413         BuildsManager parallelBuildsManager = continuum.getBuildsManager();
414 
415         String url = getTestFile( "src/test-projects/project1/pom.xml" ).toURL().toExternalForm();
416 
417         ContinuumProjectBuildingResult result = continuum.addMavenTwoProject( url );
418 
419         assertNotNull( result );
420 
421         List<Project> projects = result.getProjects();
422 
423         assertEquals( 1, projects.size() );
424 
425         assertEquals( Project.class, projects.get( 0 ).getClass() );
426 
427         Project project = projects.get( 0 );
428 
429         parallelBuildsManager.removeProjectFromCheckoutQueue( project.getId() );
430 
431         assertFalse( "project still exist on the checkout queue",
432                      parallelBuildsManager.isInAnyCheckoutQueue( project.getId() ) );
433     }
434 
435     public void testAddAntProjectWithdefaultBuildDef()
436         throws Exception
437     {
438         Continuum continuum = getContinuum();
439 
440         Project project = new Project();
441         project.setScmUrl( "scmUrl" );
442         ProjectGroup defaultProjectGroup =
443             continuum.getProjectGroupByGroupId( ContinuumInitializer.DEFAULT_PROJECT_GROUP_GROUP_ID );
444         int projectId = continuum.addProject( project, ContinuumBuildExecutorConstants.ANT_BUILD_EXECUTOR,
445                                               defaultProjectGroup.getId() );
446         assertEquals( 1, continuum.getProjectGroupWithProjects( defaultProjectGroup.getId() ).getProjects().size() );
447         project = continuum.getProjectWithAllDetails( projectId );
448         assertNotNull( project );
449 
450         BuildDefinitionService service = (BuildDefinitionService) lookup( BuildDefinitionService.class );
451         assertEquals( 4, service.getAllBuildDefinitionTemplate().size() );
452         assertEquals( 5, service.getAllBuildDefinitions().size() );
453 
454         BuildDefinition buildDef =
455             (BuildDefinition) service.getDefaultAntBuildDefinitionTemplate().getBuildDefinitions().get( 0 );
456         buildDef = service.cloneBuildDefinition( buildDef );
457         buildDef.setTemplate( false );
458         continuum.addBuildDefinitionToProject( project.getId(), buildDef );
459         project = continuum.getProjectWithAllDetails( project.getId() );
460         assertEquals( 2, project.getBuildDefinitions().size() );
461         assertEquals( 4, service.getAllBuildDefinitionTemplate().size() );
462         assertEquals( 6, service.getAllBuildDefinitions().size() );
463     }
464 
465     public void testRemoveProjectGroupWithRepository()
466         throws Exception
467     {
468         Continuum continuum = getContinuum();
469         RepositoryService service = (RepositoryService) lookup( RepositoryService.ROLE );
470 
471         LocalRepository repository = new LocalRepository();
472         repository.setName( "defaultRepo" );
473         repository.setLocation( getTestFile( "target/default-repository" ).getAbsolutePath() );
474         repository = service.addLocalRepository( repository );
475 
476         ProjectGroup group = new ProjectGroup();
477         group.setGroupId( "testGroup" );
478         group.setName( "testGroup" );
479         group.setLocalRepository( repository );
480         continuum.addProjectGroup( group );
481 
482         ProjectGroup retrievedDefaultProjectGroup = continuum.getProjectGroupByGroupId( "testGroup" );
483         assertNotNull( retrievedDefaultProjectGroup.getLocalRepository() );
484 
485         continuum.removeProjectGroup( retrievedDefaultProjectGroup.getId() );
486 
487         try
488         {
489             continuum.getProjectGroupByGroupId( "testGroup" );
490             fail( "project group was not deleted" );
491         }
492         catch ( Exception e )
493         {
494             // should fail. do nothing.
495         }
496 
497         LocalRepository retrievedRepository = service.getLocalRepository( repository.getId() );
498         assertNotNull( retrievedRepository );
499         assertEquals( repository, retrievedRepository );
500     }
501 
502     public void testContinuumReleaseResult()
503         throws Exception
504     {
505         Continuum continuum = getContinuum();
506 
507         ProjectGroup defaultProjectGroup =
508             continuum.getProjectGroupByGroupId( ContinuumInitializer.DEFAULT_PROJECT_GROUP_GROUP_ID );
509 
510         assertEquals( 0, continuum.getAllContinuumReleaseResults().size() );
511 
512         ContinuumReleaseResult releaseResult = new ContinuumReleaseResult();
513         releaseResult.setStartTime( System.currentTimeMillis() );
514 
515         File logFile = continuum.getConfiguration().getReleaseOutputFile( defaultProjectGroup.getId(),
516                                                                           "releases-" + releaseResult.getStartTime() );
517         logFile.mkdirs();
518 
519         assertTrue( logFile.exists() );
520 
521         releaseResult.setResultCode( 0 );
522         releaseResult.setEndTime( System.currentTimeMillis() );
523         releaseResult.setProjectGroup( defaultProjectGroup );
524 
525         releaseResult = continuum.addContinuumReleaseResult( releaseResult );
526 
527         List<ContinuumReleaseResult> releaseResults =
528             continuum.getContinuumReleaseResultsByProjectGroup( defaultProjectGroup.getId() );
529         assertEquals( 1, releaseResults.size() );
530         assertEquals( releaseResult, releaseResults.get( 0 ) );
531 
532         continuum.removeContinuumReleaseResult( releaseResult.getId() );
533         assertEquals( 0, continuum.getAllContinuumReleaseResults().size() );
534         assertFalse( logFile.exists() );
535         assertEquals( defaultProjectGroup,
536                       continuum.getProjectGroupByGroupId( ContinuumInitializer.DEFAULT_PROJECT_GROUP_GROUP_ID ) );
537 
538     }
539 
540     public void testBuildProjectWhileProjectIsInReleaseStage()
541         throws Exception
542     {
543         DefaultContinuum continuum = (DefaultContinuum) getContinuum();
544 
545         continuum.setTaskQueueManager( taskQueueManager );
546 
547         continuum.setProjectDao( projectDao );
548 
549         final Project project = new Project();
550         project.setId( 1 );
551         project.setName( "Continuum Core" );
552         project.setGroupId( "org.apache.continuum" );
553         project.setArtifactId( "continuum-core" );
554 
555         context.checking( new Expectations()
556         {
557             {
558                 one( projectDao ).getProject( 1 );
559                 will( returnValue( project ) );
560 
561                 one( taskQueueManager ).isProjectInReleaseStage( "org.apache.continuum:continuum-core" );
562                 will( returnValue( true ) );
563             }} );
564 
565         try
566         {
567             continuum.buildProject( 1 );
568             fail( "An exception should have been thrown." );
569         }
570         catch ( ContinuumException e )
571         {
572             assertEquals( "Project (id=1) is currently in release stage.", e.getMessage() );
573         }
574     }
575 
576     public void testBuildProjectGroupWhileAtLeastOneProjectIsInReleaseStage()
577         throws Exception
578     {
579         DefaultContinuum continuum = (DefaultContinuum) getContinuum();
580 
581         continuum.setTaskQueueManager( taskQueueManager );
582 
583         continuum.setProjectDao( projectDao );
584 
585         final List<Project> projects = new ArrayList<Project>();
586 
587         Project project = new Project();
588         project.setId( 1 );
589         project.setName( "Continuum Core" );
590         project.setGroupId( "org.apache.continuum" );
591         project.setArtifactId( "continuum-core" );
592         projects.add( project );
593 
594         project = new Project();
595         project.setId( 2 );
596         project.setName( "Continuum API" );
597         project.setGroupId( "org.apache.continuum" );
598         project.setArtifactId( "continuum-api" );
599         projects.add( project );
600 
601         context.checking( new Expectations()
602         {
603             {
604                 one( projectDao ).getProjectsInGroup( 1 );
605                 will( returnValue( projects ) );
606 
607                 one( taskQueueManager ).isProjectInReleaseStage( "org.apache.continuum:continuum-core" );
608                 will( returnValue( true ) );
609             }} );
610 
611         try
612         {
613             continuum.buildProjectGroup( 1 );
614             fail( "An exception should have been thrown." );
615         }
616         catch ( ContinuumException e )
617         {
618             assertEquals( "Cannot build project group. Project (id=1) in group is currently in release stage.",
619                           e.getMessage() );
620         }
621     }
622 
623     private Continuum getContinuum()
624         throws Exception
625     {
626         return (Continuum) lookup( Continuum.ROLE );
627     }
628 
629     private BuildResultDao getBuildResultDao()
630     {
631         return (BuildResultDao) lookup( BuildResultDao.class.getName() );
632     }
633 }