1 package org.apache.maven.continuum.scm.queue;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.continuum.buildmanager.BuildsManager;
29 import org.apache.continuum.buildmanager.ParallelBuildsManager;
30 import org.apache.continuum.dao.ProjectScmRootDao;
31 import org.apache.continuum.model.project.ProjectScmRoot;
32 import org.apache.continuum.taskqueue.BuildProjectTask;
33 import org.apache.continuum.taskqueue.PrepareBuildProjectsTask;
34 import org.apache.maven.continuum.AbstractContinuumTest;
35 import org.apache.maven.continuum.configuration.ConfigurationService;
36 import org.apache.maven.continuum.core.action.AbstractContinuumAction;
37 import org.apache.maven.continuum.model.project.BuildDefinition;
38 import org.apache.maven.continuum.model.project.Project;
39 import org.apache.maven.continuum.model.project.ProjectGroup;
40 import org.apache.maven.continuum.project.ContinuumProjectState;
41 import org.apache.maven.continuum.project.builder.ContinuumProjectBuilder;
42 import org.apache.maven.continuum.project.builder.ContinuumProjectBuilderException;
43 import org.apache.maven.continuum.project.builder.ContinuumProjectBuildingResult;
44 import org.apache.maven.continuum.project.builder.maven.MavenTwoContinuumProjectBuilder;
45 import org.codehaus.plexus.action.ActionManager;
46 import org.codehaus.plexus.taskqueue.TaskQueue;
47 import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
48 import org.codehaus.plexus.util.StringUtils;
49
50 public class PrepareBuildProjectsTaskExecutorTest
51 extends AbstractContinuumTest
52 {
53 private ContinuumProjectBuilder projectBuilder;
54
55 private TaskQueue prepareBuildQueue;
56
57 private TaskQueueExecutor prepareBuildTaskQueueExecutor;
58
59 private ActionManager actionManager;
60
61 private ProjectScmRootDao projectScmRootDao;
62
63 private ConfigurationService configurationService;
64
65 private BuildsManager buildsManager;
66
67 @Override
68 protected void setUp()
69 throws Exception
70 {
71 super.setUp();
72
73 projectBuilder =
74 (ContinuumProjectBuilder) lookup( ContinuumProjectBuilder.ROLE, MavenTwoContinuumProjectBuilder.ID );
75
76 prepareBuildQueue = (TaskQueue) lookup( TaskQueue.ROLE, "prepare-build-project" );
77
78 prepareBuildTaskQueueExecutor = (TaskQueueExecutor) lookup( TaskQueueExecutor.ROLE, "prepare-build-project" );
79
80 projectScmRootDao = (ProjectScmRootDao) lookup( ProjectScmRootDao.class.getName() );
81
82 actionManager = (ActionManager) lookup( ActionManager.ROLE );
83
84 configurationService = (ConfigurationService ) lookup( "configurationService" );
85
86 buildsManager = (ParallelBuildsManager) lookup( BuildsManager.class, "parallel" );
87 }
88
89 public void testCheckoutPrepareBuildMultiModuleProject()
90 throws Exception
91 {
92 PrepareBuildProjectsTask task = createTask( "src/test-projects/multi-module/pom.xml", false, false );
93
94 this.prepareBuildQueue.put( task );
95
96 List<Project> projects = getProjectDao().getProjectsInGroup( task.getProjectGroupId() );
97
98 assertEquals( "failed to add all projects", 3, projects.size() );
99
100 Project rootProject = getProjectDao().getProjectByName( "multi-module-parent" );
101 Project moduleA = getProjectDao().getProjectByName( "module-A" );
102 Project moduleB = getProjectDao().getProjectByName( "module-B" );
103
104
105 while( !prepareBuildQueue.getQueueSnapshot().isEmpty() ||
106 prepareBuildTaskQueueExecutor.getCurrentTask() != null )
107 {
108 Thread.sleep( 10 );
109 }
110
111 ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( task.getProjectScmRootId() );
112 assertEquals( "Failed to update multi-module project", ContinuumProjectState.UPDATED, scmRoot.getState() );
113
114 File workingDir = configurationService.getWorkingDirectory();
115
116 assertTrue( "checkout directory of project 'multi-module-parent' does not exist.", new File( workingDir, Integer.toString( rootProject.getId() ) ).exists() );
117
118 assertTrue( "checkout directory of project 'module-A' does not exist.", new File( workingDir, Integer.toString( moduleA.getId() ) ).exists() );
119
120 assertTrue( "checkout directory of project 'module-B' does not exist.", new File( workingDir, Integer.toString( moduleB.getId() ) ).exists() );
121
122 while( !buildsManager.getCurrentBuilds().isEmpty() ||
123 isAnyProjectInBuildQueue() )
124 {
125 Thread.sleep( 10 );
126 }
127 }
128
129 public void testCheckoutPrepareBuildMultiModuleProjectFreshBuild()
130 throws Exception
131 {
132 PrepareBuildProjectsTask task = createTask( "src/test-projects/multi-module/pom.xml", false, true );
133
134 this.prepareBuildQueue.put( task );
135
136 List<Project> projects = getProjectDao().getProjectsInGroup( task.getProjectGroupId() );
137
138 assertEquals( "failed to add all projects", 3, projects.size() );
139
140 Project rootProject = getProjectDao().getProjectByName( "multi-module-parent" );
141 Project moduleA = getProjectDao().getProjectByName( "module-A" );
142 Project moduleB = getProjectDao().getProjectByName( "module-B" );
143
144
145 while( !prepareBuildQueue.getQueueSnapshot().isEmpty() ||
146 prepareBuildTaskQueueExecutor.getCurrentTask() != null )
147 {
148 Thread.sleep( 10 );
149 }
150
151 ProjectScmRoot scmRoot = projectScmRootDao.getProjectScmRoot( task.getProjectScmRootId() );
152 assertEquals( "Failed to update multi-module project", ContinuumProjectState.UPDATED, scmRoot.getState() );
153
154 File workingDir = configurationService.getWorkingDirectory();
155
156 assertTrue( "checkout directory of project 'multi-module-parent' does not exist.", new File( workingDir, Integer.toString( rootProject.getId() ) ).exists() );
157
158 assertTrue( "checkout directory of project 'module-A' does not exist.", new File( workingDir, Integer.toString( moduleA.getId() ) ).exists() );
159
160 assertTrue( "checkout directory of project 'module-B' does not exist.", new File( workingDir, Integer.toString( moduleB.getId() ) ).exists() );
161
162 while( !buildsManager.getCurrentBuilds().isEmpty() ||
163 isAnyProjectInBuildQueue() )
164 {
165 Thread.sleep( 10 );
166 }
167 }
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 private PrepareBuildProjectsTask createTask( String pomResource, boolean singleCheckout, boolean buildFresh )
302 throws Exception
303 {
304 ProjectGroup projectGroup = getProjectGroup( pomResource, singleCheckout );
305
306 BuildDefinition buildDefinition = new BuildDefinition();
307 buildDefinition.setId( 0 );
308 buildDefinition.setGoals( "clean" );
309 buildDefinition.setBuildFresh( buildFresh );
310
311 projectGroup.addBuildDefinition( buildDefinition );
312
313 Map<String, Object> pgContext = new HashMap<String, Object>();
314
315 AbstractContinuumAction.setWorkingDirectory( pgContext, configurationService.getWorkingDirectory().getAbsolutePath() );
316
317 AbstractContinuumAction.setUnvalidatedProjectGroup( pgContext, projectGroup );
318
319 actionManager.lookup( "validate-project-group" ).execute( pgContext );
320
321 actionManager.lookup( "store-project-group" ).execute( pgContext );
322
323 int projectGroupId = AbstractContinuumAction.getProjectGroupId( pgContext );
324
325 projectGroup = getProjectGroupDao().getProjectGroupWithBuildDetailsByProjectGroupId( projectGroupId );
326
327 String scmRootUrl = getScmRootUrl( projectGroup );
328
329 assertNotNull( scmRootUrl );
330
331 ProjectScmRoot scmRoot = getProjectScmRoot( projectGroup, scmRootUrl );
332
333 assertNotNull( scmRoot );
334
335 buildDefinition = (BuildDefinition) projectGroup.getBuildDefinitions().get( 0 );
336
337 Map<Integer, Integer> map = new HashMap<Integer, Integer>();
338
339 Project rootProject = null;
340
341 List<Project> projects = (List<Project>) projectGroup.getProjects();
342
343 for ( Project project : projects )
344 {
345 assertFalse( project.getId() == 0 );
346
347 map.put( project.getId(), buildDefinition.getId() );
348
349 if ( rootProject == null || rootProject.getId() > project.getId() )
350 {
351 rootProject = project;
352 }
353 }
354
355 assertEquals( 3, map.size() );
356 PrepareBuildProjectsTask task = new PrepareBuildProjectsTask( map, 1,
357 projectGroupId, projectGroup.getName(),
358 scmRoot.getScmRootAddress(), scmRoot.getId() );
359
360 return task;
361 }
362
363 private ProjectGroup getProjectGroup( String pomResource, boolean singleCheckout )
364 throws ContinuumProjectBuilderException, IOException
365 {
366 File pom = getTestFile( pomResource );
367
368 assertNotNull( "Can't find project " + pomResource, pom );
369
370
371 ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( pom.toURL(), null, null, true );
372
373
374
375
376 assertNotNull( "Project list not null", result.getProjects() );
377
378 assertEquals( "#Projectgroups", 1, result.getProjectGroups().size() );
379
380 ProjectGroup pg = result.getProjectGroups().get( 0 );
381
382 if ( !result.getProjects().isEmpty() )
383 {
384 for ( Project p : result.getProjects() )
385 {
386 pg.addProject( p );
387 }
388 }
389
390 return pg;
391 }
392
393 private ProjectScmRoot getProjectScmRoot ( ProjectGroup pg, String url )
394 throws Exception
395 {
396 if ( StringUtils.isEmpty( url ) )
397 {
398 return null;
399 }
400
401 ProjectScmRoot scmRoot =
402 projectScmRootDao.getProjectScmRootByProjectGroupAndScmRootAddress( pg.getId(), url );
403
404 if ( scmRoot != null )
405 {
406 return scmRoot;
407 }
408
409 ProjectScmRoot projectScmRoot = new ProjectScmRoot();
410
411 projectScmRoot.setProjectGroup( pg );
412
413 projectScmRoot.setScmRootAddress( url );
414
415 projectScmRoot.setState( ContinuumProjectState.ERROR );
416
417 return projectScmRootDao.addProjectScmRoot( projectScmRoot );
418 }
419
420 private String getScmRootUrl( ProjectGroup pg )
421 {
422 String scmRootUrl = null;
423
424 for ( Project project : (List<Project>) pg.getProjects() )
425 {
426 String scmUrl = project.getScmUrl();
427
428 scmRootUrl = getCommonPath( scmUrl, scmRootUrl );
429 }
430
431 return scmRootUrl;
432 }
433
434 private String getCommonPath( String path1, String path2 )
435 {
436 if ( path2 == null || path2.equals( "" ) )
437 {
438 return path1;
439 }
440 else
441 {
442 int indexDiff = StringUtils.differenceAt( path1, path2 );
443 return path1.substring( 0, indexDiff );
444 }
445 }
446
447 private boolean isAnyProjectInBuildQueue()
448 throws Exception
449 {
450 Map<String, List<BuildProjectTask>> buildTasks = buildsManager.getProjectsInBuildQueues();
451
452 for ( String queue : buildTasks.keySet() )
453 {
454 if ( !buildTasks.get( queue ).isEmpty() )
455 {
456 return true;
457 }
458 }
459
460 return false;
461 }
462 }