View Javadoc

1   package org.apache.continuum.builder.distributed.manager;
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 org.apache.continuum.builder.distributed.executor.ThreadedDistributedBuildTaskQueueExecutor;
23  import org.apache.continuum.builder.distributed.stubs.DefaultDistributedBuildManagerStub;
24  import org.apache.continuum.configuration.BuildAgentConfiguration;
25  import org.apache.continuum.configuration.BuildAgentGroupConfiguration;
26  import org.apache.continuum.dao.BuildDefinitionDao;
27  import org.apache.continuum.dao.BuildResultDao;
28  import org.apache.continuum.dao.ProjectDao;
29  import org.apache.continuum.dao.ProjectScmRootDao;
30  import org.apache.continuum.model.project.ProjectRunSummary;
31  import org.apache.continuum.model.project.ProjectScmRoot;
32  import org.apache.continuum.taskqueue.BuildProjectTask;
33  import org.apache.continuum.taskqueue.OverallDistributedBuildQueue;
34  import org.apache.continuum.taskqueue.PrepareBuildProjectsTask;
35  import org.apache.continuum.utils.build.BuildTrigger;
36  import org.apache.maven.continuum.configuration.ConfigurationService;
37  import org.apache.maven.continuum.model.project.BuildDefinition;
38  import org.apache.maven.continuum.model.project.BuildResult;
39  import org.apache.maven.continuum.model.project.Project;
40  import org.apache.maven.continuum.model.project.ProjectGroup;
41  import org.apache.maven.continuum.model.system.Profile;
42  import org.apache.maven.continuum.project.ContinuumProjectState;
43  import org.codehaus.plexus.spring.PlexusInSpringTestCase;
44  import org.codehaus.plexus.taskqueue.Task;
45  import org.codehaus.plexus.taskqueue.TaskQueue;
46  import org.jmock.Expectations;
47  import org.jmock.Mockery;
48  import org.jmock.integration.junit3.JUnit3Mockery;
49  import org.jmock.lib.legacy.ClassImposteriser;
50  
51  import java.util.ArrayList;
52  import java.util.Collections;
53  import java.util.HashMap;
54  import java.util.LinkedHashMap;
55  import java.util.List;
56  import java.util.Map;
57  
58  public class DefaultDistributedBuildManagerTest
59      extends PlexusInSpringTestCase
60  {
61      private final String TEST_BUILD_AGENT1 = "http://sampleagent";
62  
63      private final String TEST_BUILD_AGENT2 = "http://testagent";
64  
65      private final String TEST_BUILD_AGENT_GROUP1 = "buildAgentGroup1";
66  
67      private DefaultDistributedBuildManager distributedBuildManager;
68  
69      private DefaultDistributedBuildManager distributedBuildManagerStub = new DefaultDistributedBuildManagerStub();
70  
71      private Mockery context;
72  
73      private OverallDistributedBuildQueue overallDistributedBuildQueue1;
74  
75      private OverallDistributedBuildQueue overallDistributedBuildQueue2;
76  
77      private BuildDefinitionDao buildDefinitionDao;
78  
79      private BuildResultDao buildResultDao;
80  
81      private ProjectDao projectDao;
82  
83      private ProjectScmRootDao projectScmRootDao;
84  
85      private ConfigurationService configurationService;
86  
87      private List<BuildAgentConfiguration> buildAgents;
88  
89      private BuildAgentConfiguration buildAgent1;
90  
91      private BuildAgentConfiguration buildAgent2;
92  
93      private ThreadedDistributedBuildTaskQueueExecutor distributedBuildTaskQueueExecutor;
94  
95      private TaskQueue distributedBuildQueue;
96  
97      private Project project;
98  
99      private Project project2;
100 
101     private ProjectGroup projectGroup;
102 
103     private BuildDefinition buildDefinition;
104 
105     private BuildAgentGroupConfiguration buildAgentGroup;
106 
107     @Override
108     public void setUp()
109         throws Exception
110     {
111         super.setUp();
112 
113         context = new JUnit3Mockery();
114         context.setImposteriser( ClassImposteriser.INSTANCE );
115 
116         distributedBuildManager = (DefaultDistributedBuildManager) lookup( DistributedBuildManager.class );
117 
118         buildDefinitionDao = context.mock( BuildDefinitionDao.class );
119         distributedBuildManager.setBuildDefinitionDao( buildDefinitionDao );
120         distributedBuildManagerStub.setBuildDefinitionDao( buildDefinitionDao );
121 
122         buildResultDao = context.mock( BuildResultDao.class );
123         distributedBuildManager.setBuildResultDao( buildResultDao );
124         distributedBuildManagerStub.setBuildResultDao( buildResultDao );
125 
126         projectDao = context.mock( ProjectDao.class );
127         distributedBuildManager.setProjectDao( projectDao );
128         distributedBuildManagerStub.setProjectDao( projectDao );
129 
130         projectScmRootDao = context.mock( ProjectScmRootDao.class );
131         distributedBuildManager.setProjectScmRootDao( projectScmRootDao );
132         distributedBuildManagerStub.setProjectScmRootDao( projectScmRootDao );
133 
134         distributedBuildManagerStub.setContainer( getContainer() );
135 
136         configurationService = context.mock( ConfigurationService.class );
137 
138         distributedBuildManager.setConfigurationService( configurationService );
139         distributedBuildManagerStub.setConfigurationService( configurationService );
140 
141         distributedBuildTaskQueueExecutor = (ThreadedDistributedBuildTaskQueueExecutor) context.mock(
142             ThreadedDistributedBuildTaskQueueExecutor.class, "distributed-build-project" );
143 
144         distributedBuildQueue = context.mock( TaskQueue.class, "distributed-build-queue" );
145 
146         overallDistributedBuildQueue1 = context.mock( OverallDistributedBuildQueue.class, TEST_BUILD_AGENT1 );
147         overallDistributedBuildQueue2 = context.mock( OverallDistributedBuildQueue.class, TEST_BUILD_AGENT2 );
148 
149         init();
150     }
151 
152     private void init()
153     {
154         buildAgent1 = new BuildAgentConfiguration();
155         buildAgent1.setEnabled( true );
156         buildAgent1.setUrl( TEST_BUILD_AGENT1 );
157 
158         buildAgent2 = new BuildAgentConfiguration();
159         buildAgent2.setEnabled( true );
160         buildAgent2.setUrl( TEST_BUILD_AGENT2 );
161 
162         List<BuildAgentConfiguration> buildAgents = new ArrayList<BuildAgentConfiguration>();
163         buildAgents.add( buildAgent1 );
164         buildAgents.add( buildAgent2 );
165 
166         setUpBuildAgentGroup( buildAgents );
167         setupBuildDefinition();
168 
169         projectGroup = new ProjectGroup();
170         projectGroup.setId( 1 );
171         projectGroup.setGroupId( "group" );
172 
173         project = new Project();
174         project.setId( 1 );
175         project.setGroupId( "groupId" );
176         project.setArtifactId( "artifactId" );
177         project.setVersion( "1.0" );
178         project.setProjectGroup( projectGroup );
179 
180         project2 = new Project();
181         project2.setId( 2 );
182         project2.setGroupId( "groupId" );
183         project2.setArtifactId( "artifactId" );
184         project2.setVersion( "1.0" );
185         project2.setProjectGroup( projectGroup );
186     }
187 
188     public void testViewQueuesAfterBuildAgentIsLost()
189         throws Exception
190     {
191         distributedBuildManager.setOverallDistributedBuildQueues( getMockOverallDistributedBuildQueues( 1 ) );
192 
193         recordViewQueuesAfterBuildAgentIsLost();
194 
195         Map<String, List<PrepareBuildProjectsTask>> prepareBuildQueues =
196             distributedBuildManager.getProjectsInPrepareBuildQueue();
197         Map<String, List<BuildProjectTask>> buildQueues = distributedBuildManager.getProjectsInBuildQueue();
198         Map<String, PrepareBuildProjectsTask> currentPrepareBuild =
199             distributedBuildManager.getProjectsCurrentlyPreparingBuild();
200         Map<String, BuildProjectTask> currentBuild = distributedBuildManager.getProjectsCurrentlyBuilding();
201 
202         assertEquals( prepareBuildQueues.size(), 0 );
203         assertEquals( buildQueues.size(), 0 );
204         assertEquals( currentPrepareBuild.size(), 0 );
205         assertEquals( currentBuild.size(), 0 );
206 
207         context.assertIsSatisfied();
208     }
209 
210     public void testDisableBuildAgentWhenUnavailableToPing()
211         throws Exception
212     {
213         distributedBuildManager.setOverallDistributedBuildQueues( getMockOverallDistributedBuildQueues( 1 ) );
214 
215         recordDisableOfBuildAgent();
216 
217         distributedBuildManager.isAgentAvailable( TEST_BUILD_AGENT1 );
218 
219         context.assertIsSatisfied();
220     }
221 
222     public void testViewQueuesWhen2BuildAgentsAreLost()
223         throws Exception
224     {
225         distributedBuildManager.setOverallDistributedBuildQueues( getMockOverallDistributedBuildQueues( 2 ) );
226 
227         recordViewQueuesAfter2BuildAgentsAreLost();
228 
229         Map<String, List<PrepareBuildProjectsTask>> prepareBuildQueues =
230             distributedBuildManager.getProjectsInPrepareBuildQueue();
231         Map<String, List<BuildProjectTask>> buildQueues = distributedBuildManager.getProjectsInBuildQueue();
232         Map<String, PrepareBuildProjectsTask> currentPrepareBuild =
233             distributedBuildManager.getProjectsCurrentlyPreparingBuild();
234         Map<String, BuildProjectTask> currentBuild = distributedBuildManager.getProjectsCurrentlyBuilding();
235 
236         assertEquals( prepareBuildQueues.size(), 0 );
237         assertEquals( buildQueues.size(), 0 );
238         assertEquals( currentPrepareBuild.size(), 0 );
239         assertEquals( currentBuild.size(), 0 );
240 
241         context.assertIsSatisfied();
242     }
243 
244     public void testBuildProjectWithBuildAgentGroupWithNoCurrentBuilds()
245         throws Exception
246     {
247         distributedBuildManagerStub.setOverallDistributedBuildQueues( getMockOverallDistributedBuildQueues( 2 ) );
248 
249         Map<Integer, Integer> projectsBuildDefinitionsMap = new HashMap<Integer, Integer>();
250         projectsBuildDefinitionsMap.put( 1, 1 );
251         projectsBuildDefinitionsMap.put( 2, 1 );
252 
253         BuildTrigger buildTrigger = new BuildTrigger( 1 );
254 
255         recordBuildOfProjectWithBuildAgentGroupWithNoCurrentBuilds();
256 
257         List<ProjectScmRoot> scmRoots = new ArrayList<ProjectScmRoot>();
258         ProjectScmRoot scmRoot = new ProjectScmRoot();
259         scmRoot.setId( 1 );
260         scmRoot.setProjectGroup( projectGroup );
261         scmRoot.setScmRootAddress( "scmRootAddress1" );
262         scmRoots.add( scmRoot );
263 
264         scmRoot = new ProjectScmRoot();
265         scmRoot.setId( 2 );
266         scmRoot.setProjectGroup( projectGroup );
267         scmRoot.setScmRootAddress( "scmRootAddress2" );
268         scmRoots.add( scmRoot );
269 
270         distributedBuildManagerStub.prepareBuildProjects( projectsBuildDefinitionsMap, buildTrigger, 1, "sample",
271                                                           "scmRootAddress1", 1, scmRoots );
272 
273         context.assertIsSatisfied();
274     }
275 
276     public void testBuildProjectWithBuildAgentGroupWithCurrentBuild()
277         throws Exception
278     {
279         distributedBuildManagerStub.setOverallDistributedBuildQueues( getMockOverallDistributedBuildQueues( 2 ) );
280 
281         Map<Integer, Integer> projectsBuildDefinitionsMap = new HashMap<Integer, Integer>();
282         projectsBuildDefinitionsMap.put( 1, 1 );
283 
284         BuildTrigger buildTrigger = new BuildTrigger( 1 );
285 
286         recordBuildOfProjectWithBuildAgentGroupWithCurrentBuild();
287 
288         List<ProjectScmRoot> scmRoots = new ArrayList<ProjectScmRoot>();
289         ProjectScmRoot scmRoot = new ProjectScmRoot();
290         scmRoot.setId( 2 );
291         scmRoot.setProjectGroup( projectGroup );
292         scmRoot.setScmRootAddress( "scmRootAddress2" );
293         scmRoots.add( scmRoot );
294 
295         scmRoot = new ProjectScmRoot();
296         scmRoot.setId( 1 );
297         scmRoot.setProjectGroup( projectGroup );
298         scmRoot.setScmRootAddress( "scmRootAddress1" );
299         scmRoots.add( scmRoot );
300 
301         distributedBuildManagerStub.prepareBuildProjects( projectsBuildDefinitionsMap, buildTrigger, 1, "sample",
302                                                           "scmRootAddress1", 1, scmRoots );
303 
304         context.assertIsSatisfied();
305     }
306 
307     // CONTINUUM-2494
308     public void testBuildProjectWithTheSecondBuildAgentAttachedToTheBuildAgentGroup()
309         throws Exception
310     {
311         distributedBuildManagerStub.setOverallDistributedBuildQueues( getMockOverallDistributedBuildQueues( 2 ) );
312 
313         List<BuildAgentConfiguration> buildAgents = new ArrayList<BuildAgentConfiguration>();
314         buildAgents.add( buildAgent2 );
315 
316         setUpBuildAgentGroup( buildAgents );
317         setupBuildDefinition();
318 
319         Map<Integer, Integer> projectsBuildDefinitionsMap = new HashMap<Integer, Integer>();
320         projectsBuildDefinitionsMap.put( 1, 1 );
321 
322         BuildTrigger buildTrigger = new BuildTrigger( 1 );
323 
324         recordBuildProjectWithTheSecondBuildAgentAttachedToTheBuildAgentGroup();
325 
326         List<ProjectScmRoot> scmRoots = new ArrayList<ProjectScmRoot>();
327         ProjectScmRoot scmRoot = new ProjectScmRoot();
328         scmRoot.setId( 1 );
329         scmRoot.setProjectGroup( projectGroup );
330         scmRoot.setScmRootAddress( "scmRootAddress1" );
331         scmRoots.add( scmRoot );
332 
333         distributedBuildManagerStub.prepareBuildProjects( projectsBuildDefinitionsMap, buildTrigger, 1, "sample",
334                                                           "scmRootAddress", 1, scmRoots );
335     }
336 
337     public void testGetBuildAgentPlatform()
338         throws Exception
339     {
340         distributedBuildManager.setOverallDistributedBuildQueues( getMockOverallDistributedBuildQueues( 1 ) );
341         context.checking( new Expectations()
342         {
343             {
344                 exactly( 2 ).of( configurationService ).getBuildAgents();
345                 will( returnValue( buildAgents ) );
346 
347                 one( configurationService ).getSharedSecretPassword();
348                 will( returnValue( null ) );
349 
350                 one( configurationService ).updateBuildAgent( buildAgent1 );
351                 one( configurationService ).store();
352 
353                 exactly( 2 ).of( overallDistributedBuildQueue1 ).getDistributedBuildTaskQueueExecutor();
354                 will( returnValue( distributedBuildTaskQueueExecutor ) );
355 
356                 one( distributedBuildTaskQueueExecutor ).getCurrentTask();
357                 will( returnValue( null ) );
358 
359                 one( overallDistributedBuildQueue1 ).getProjectsInQueue();
360                 will( returnValue( new ArrayList<PrepareBuildProjectsTask>() ) );
361 
362                 one( overallDistributedBuildQueue1 ).getDistributedBuildQueue();
363                 will( returnValue( distributedBuildQueue ) );
364 
365                 one( distributedBuildQueue ).removeAll( new ArrayList<PrepareBuildProjectsTask>() );
366 
367                 one( distributedBuildTaskQueueExecutor ).stop();
368             }
369         } );
370         assertEquals( distributedBuildManager.getBuildAgentPlatform( TEST_BUILD_AGENT1 ), "" );
371         context.assertIsSatisfied();
372     }
373 
374     public void testBuildAgentIsAvailable()
375         throws Exception
376     {
377         assertTrue( distributedBuildManagerStub.isAgentAvailable( TEST_BUILD_AGENT1 ) );
378         context.checking( new Expectations()
379         {
380             {
381                 never( configurationService ).getBuildAgents();
382                 never( configurationService ).updateBuildAgent( buildAgent1 );
383                 never( configurationService ).store();
384             }
385         } );
386         context.assertIsSatisfied();
387     }
388 
389     public void testCancelBuildStuckUpdate()
390         throws Exception
391     {
392         distributedBuildManagerStub.setCurrentRuns( getCurrentRuns() );
393 
394         recordOfStuckScm();
395 
396         distributedBuildManagerStub.cancelBuild( 1 );
397     }
398 
399     public void testCancelBuildStuckBuild()
400         throws Exception
401     {
402         distributedBuildManagerStub.setCurrentRuns( getCurrentRuns() );
403 
404         recordOfStuckBuild();
405 
406         distributedBuildManagerStub.cancelBuild( 1 );
407     }
408 
409     private void recordOfStuckBuild()
410         throws Exception
411     {
412         context.checking( new Expectations()
413         {
414             {
415                 exactly( 4 ).of( configurationService ).getBuildAgents();
416                 will( returnValue( buildAgents ) );
417 
418                 exactly( 2 ).of( projectScmRootDao ).getProjectScmRoot( 1 );
419                 will( returnValue( getScmRoot( ContinuumProjectState.OK ) ) );
420 
421                 Project proj1 = getProject( 1, ContinuumProjectState.BUILDING );
422                 one( projectDao ).getProject( 1 );
423                 will( returnValue( proj1 ) );
424 
425                 one( buildDefinitionDao ).getBuildDefinition( 1 );
426                 will( returnValue( new BuildDefinition() ) );
427 
428                 one( buildResultDao ).addBuildResult( with( any( Project.class ) ), with( any( BuildResult.class ) ) );
429                 one( projectDao ).updateProject( proj1 );
430 
431                 one( projectDao ).getProject( 2 );
432                 will( returnValue( getProject( 2, ContinuumProjectState.OK ) ) );
433             }
434         } );
435     }
436 
437     private void recordOfStuckScm()
438         throws Exception
439     {
440         context.checking( new Expectations()
441         {
442             {
443                 exactly( 4 ).of( configurationService ).getBuildAgents();
444                 will( returnValue( buildAgents ) );
445 
446                 ProjectScmRoot scmRootUpdating = getScmRoot( ContinuumProjectState.UPDATING );
447                 one( projectScmRootDao ).getProjectScmRoot( 1 );
448                 will( returnValue( scmRootUpdating ) );
449 
450                 one( projectScmRootDao ).updateProjectScmRoot( scmRootUpdating );
451 
452                 one( projectScmRootDao ).getProjectScmRoot( 1 );
453                 will( returnValue( getScmRoot( ContinuumProjectState.ERROR ) ) );
454             }
455         } );
456     }
457 
458     private List<ProjectRunSummary> getCurrentRuns()
459     {
460         List<ProjectRunSummary> runs = new ArrayList<ProjectRunSummary>();
461 
462         ProjectRunSummary run1 = new ProjectRunSummary();
463         run1.setProjectId( 1 );
464         run1.setBuildDefinitionId( 1 );
465         run1.setProjectGroupId( 1 );
466         run1.setProjectScmRootId( 1 );
467         run1.setTrigger( 1 );
468         run1.setTriggeredBy( "user" );
469         run1.setBuildAgentUrl( "http://localhost:8181/continuum-buildagent/xmlrpc" );
470         runs.add( run1 );
471 
472         ProjectRunSummary run2 = new ProjectRunSummary();
473         run2.setProjectId( 2 );
474         run2.setBuildDefinitionId( 2 );
475         run2.setProjectGroupId( 1 );
476         run2.setProjectScmRootId( 1 );
477         run2.setTrigger( 1 );
478         run2.setTriggeredBy( "user" );
479         run2.setBuildAgentUrl( "http://localhost:8181/continuum-buildagent/xmlrpc" );
480         runs.add( run2 );
481 
482         return runs;
483     }
484 
485     private ProjectScmRoot getScmRoot( int state )
486     {
487         ProjectScmRoot scmRoot = new ProjectScmRoot();
488         scmRoot.setState( state );
489         return scmRoot;
490     }
491 
492     private Project getProject( int projectId, int state )
493     {
494         Project project = new Project();
495         project.setId( projectId );
496         project.setState( state );
497         return project;
498     }
499 
500     private Map<String, OverallDistributedBuildQueue> getMockOverallDistributedBuildQueues( int size )
501     {
502         Map<String, OverallDistributedBuildQueue> overallDistributedBuildQueues = Collections.synchronizedMap(
503             new LinkedHashMap<String, OverallDistributedBuildQueue>() );
504 
505         buildAgents = new ArrayList<BuildAgentConfiguration>();
506         buildAgents.add( buildAgent1 );
507 
508         overallDistributedBuildQueues.put( TEST_BUILD_AGENT1, overallDistributedBuildQueue1 );
509 
510         if ( size == 2 )
511         {
512             buildAgents.add( buildAgent2 );
513             overallDistributedBuildQueues.put( TEST_BUILD_AGENT2, overallDistributedBuildQueue2 );
514         }
515 
516         return overallDistributedBuildQueues;
517     }
518 
519     private void setUpBuildAgentGroup( List<BuildAgentConfiguration> buildAgents )
520     {
521         buildAgentGroup = new BuildAgentGroupConfiguration();
522         buildAgentGroup.setName( TEST_BUILD_AGENT_GROUP1 );
523         buildAgentGroup.setBuildAgents( buildAgents );
524     }
525 
526     private void setupBuildDefinition()
527     {
528         Profile buildEnv1 = new Profile();
529         buildEnv1.setBuildAgentGroup( TEST_BUILD_AGENT_GROUP1 );
530 
531         buildDefinition = new BuildDefinition();
532         buildDefinition.setId( 1 );
533         buildDefinition.setProfile( buildEnv1 );
534     }
535 
536     private void recordDisableOfBuildAgent()
537         throws Exception
538     {
539         context.checking( new Expectations()
540         {
541             {
542                 one( configurationService ).getBuildAgents();
543                 will( returnValue( buildAgents ) );
544 
545                 one( configurationService ).getSharedSecretPassword();
546                 will( returnValue( null ) );
547 
548                 one( configurationService ).updateBuildAgent( buildAgent1 );
549                 one( configurationService ).store();
550             }
551         } );
552     }
553 
554     private void recordViewQueuesAfterBuildAgentIsLost()
555         throws Exception
556     {
557         context.checking( new Expectations()
558         {
559             {
560                 exactly( 5 ).of( configurationService ).getBuildAgents();
561                 will( returnValue( buildAgents ) );
562 
563                 one( configurationService ).getSharedSecretPassword();
564                 will( returnValue( null ) );
565 
566                 one( configurationService ).updateBuildAgent( buildAgent1 );
567                 one( configurationService ).store();
568 
569                 exactly( 2 ).of( overallDistributedBuildQueue1 ).getDistributedBuildTaskQueueExecutor();
570                 will( returnValue( distributedBuildTaskQueueExecutor ) );
571 
572                 one( distributedBuildTaskQueueExecutor ).getCurrentTask();
573                 will( returnValue( null ) );
574 
575                 one( overallDistributedBuildQueue1 ).getProjectsInQueue();
576                 will( returnValue( new ArrayList<PrepareBuildProjectsTask>() ) );
577 
578                 one( overallDistributedBuildQueue1 ).getDistributedBuildQueue();
579                 will( returnValue( distributedBuildQueue ) );
580 
581                 one( distributedBuildQueue ).removeAll( new ArrayList<PrepareBuildProjectsTask>() );
582 
583                 one( distributedBuildTaskQueueExecutor ).stop();
584             }
585         } );
586     }
587 
588     private void recordViewQueuesAfter2BuildAgentsAreLost()
589         throws Exception
590     {
591         context.checking( new Expectations()
592         {
593             {
594                 exactly( 6 ).of( configurationService ).getBuildAgents();
595                 will( returnValue( buildAgents ) );
596 
597                 exactly( 2 ).of( configurationService ).getSharedSecretPassword();
598                 will( returnValue( null ) );
599 
600                 one( configurationService ).updateBuildAgent( buildAgent1 );
601                 one( configurationService ).updateBuildAgent( buildAgent2 );
602                 exactly( 2 ).of( configurationService ).store();
603 
604                 exactly( 2 ).of( overallDistributedBuildQueue1 ).getDistributedBuildTaskQueueExecutor();
605                 will( returnValue( distributedBuildTaskQueueExecutor ) );
606 
607                 exactly( 2 ).of( overallDistributedBuildQueue2 ).getDistributedBuildTaskQueueExecutor();
608                 will( returnValue( distributedBuildTaskQueueExecutor ) );
609 
610                 exactly( 2 ).of( distributedBuildTaskQueueExecutor ).getCurrentTask();
611                 will( returnValue( null ) );
612 
613                 one( overallDistributedBuildQueue1 ).getProjectsInQueue();
614                 will( returnValue( new ArrayList<PrepareBuildProjectsTask>() ) );
615 
616                 one( overallDistributedBuildQueue2 ).getProjectsInQueue();
617                 will( returnValue( new ArrayList<PrepareBuildProjectsTask>() ) );
618 
619                 one( overallDistributedBuildQueue1 ).getDistributedBuildQueue();
620                 will( returnValue( distributedBuildQueue ) );
621 
622                 one( overallDistributedBuildQueue2 ).getDistributedBuildQueue();
623                 will( returnValue( distributedBuildQueue ) );
624 
625                 exactly( 2 ).of( distributedBuildQueue ).removeAll( new ArrayList<PrepareBuildProjectsTask>() );
626 
627                 exactly( 2 ).of( distributedBuildTaskQueueExecutor ).stop();
628             }
629         } );
630     }
631 
632     private void recordBuildOfProjectWithBuildAgentGroupWithNoCurrentBuilds()
633         throws Exception
634     {
635         context.checking( new Expectations()
636         {
637             {
638                 exactly( 3 ).of( projectDao ).getProjectWithDependencies( 1 );
639                 will( returnValue( project ) );
640 
641                 exactly( 3 ).of( projectDao ).getProjectWithDependencies( 2 );
642                 will( returnValue( project2 ) );
643 
644                 exactly( 3 ).of( buildDefinitionDao ).getBuildDefinition( 1 );
645                 will( returnValue( buildDefinition ) );
646 
647                 exactly( 3 ).of( configurationService ).getBuildAgentGroup( TEST_BUILD_AGENT_GROUP1 );
648                 will( returnValue( buildAgentGroup ) );
649 
650                 one( configurationService ).getBuildAgents();
651                 will( returnValue( buildAgents ) );
652 
653                 one( overallDistributedBuildQueue1 ).getBuildAgentUrl();
654 
655                 one( overallDistributedBuildQueue1 ).addToDistributedBuildQueue( with( any( Task.class ) ) );
656             }
657         } );
658     }
659 
660     private void recordBuildOfProjectWithBuildAgentGroupWithCurrentBuild()
661         throws Exception
662     {
663         context.checking( new Expectations()
664         {
665             {
666                 one( overallDistributedBuildQueue1 ).getProjectsInQueue();
667 
668                 one( overallDistributedBuildQueue1 ).getDistributedBuildTaskQueueExecutor();
669                 will( returnValue( distributedBuildTaskQueueExecutor ) );
670 
671                 one( distributedBuildTaskQueueExecutor ).getCurrentTask();
672                 will( returnValue( null ) );
673 
674                 one( projectDao ).getProjectsInGroup( 1 );
675                 will( returnValue( new ArrayList<Project>() ) );
676 
677                 one( configurationService ).getBuildAgents();
678                 will( returnValue( buildAgents ) );
679 
680                 one( overallDistributedBuildQueue1 ).getBuildAgentUrl();
681 
682                 one( overallDistributedBuildQueue1 ).addToDistributedBuildQueue( with( any( Task.class ) ) );
683             }
684         } );
685     }
686 
687     private void recordBuildProjectWithTheSecondBuildAgentAttachedToTheBuildAgentGroup()
688         throws Exception
689     {
690         context.checking( new Expectations()
691         {
692             {
693                 exactly( 3 ).of( projectDao ).getProjectWithDependencies( 1 );
694                 will( returnValue( project ) );
695 
696                 exactly( 3 ).of( buildDefinitionDao ).getBuildDefinition( 1 );
697                 will( returnValue( buildDefinition ) );
698 
699                 exactly( 3 ).of( configurationService ).getBuildAgentGroup( TEST_BUILD_AGENT_GROUP1 );
700                 will( returnValue( buildAgentGroup ) );
701 
702                 one( configurationService ).getBuildAgents();
703                 will( returnValue( buildAgents ) );
704 
705                 one( overallDistributedBuildQueue2 ).getBuildAgentUrl();
706 
707                 one( overallDistributedBuildQueue2 ).addToDistributedBuildQueue( with( any( Task.class ) ) );
708             }
709         } );
710     }
711 }