1 package org.apache.maven.model.validation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.InputStream;
23 import java.util.List;
24
25 import org.apache.maven.model.Model;
26 import org.apache.maven.model.building.DefaultModelBuildingRequest;
27 import org.apache.maven.model.building.ModelBuildingRequest;
28 import org.apache.maven.model.building.SimpleProblemCollector;
29 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
30 import org.codehaus.plexus.PlexusTestCase;
31
32
33
34
35
36 public class DefaultModelValidatorTest
37 extends PlexusTestCase
38 {
39
40 private DefaultModelValidator validator;
41
42 private Model read( String pom )
43 throws Exception
44 {
45 String resource = "/poms/validation/" + pom;
46 InputStream is = getClass().getResourceAsStream( resource );
47 assertNotNull( "missing resource: " + resource, is );
48 return new MavenXpp3Reader().read( is );
49 }
50
51 private SimpleProblemCollector validate( String pom )
52 throws Exception
53 {
54 return validateEffective( pom, ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
55 }
56
57 private SimpleProblemCollector validateRaw( String pom )
58 throws Exception
59 {
60 return validateRaw( pom, ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
61 }
62
63 private SimpleProblemCollector validateEffective( String pom, int level )
64 throws Exception
65 {
66 ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel( level );
67
68 SimpleProblemCollector problems = new SimpleProblemCollector();
69
70 validator.validateEffectiveModel( read( pom ), request, problems );
71
72 return problems;
73 }
74
75 private SimpleProblemCollector validateRaw( String pom, int level )
76 throws Exception
77 {
78 ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel( level );
79
80 SimpleProblemCollector problems = new SimpleProblemCollector();
81
82 validator.validateRawModel( read( pom ), request, problems );
83
84 return problems;
85 }
86
87 private void assertContains( String msg, String substring )
88 {
89 assertTrue( "\"" + substring + "\" was not found in: " + msg, msg.contains( substring ) );
90 }
91
92 @Override
93 protected void setUp()
94 throws Exception
95 {
96 super.setUp();
97
98 validator = (DefaultModelValidator) lookup( ModelValidator.class );
99 }
100
101 @Override
102 protected void tearDown()
103 throws Exception
104 {
105 this.validator = null;
106
107 super.tearDown();
108 }
109
110 private void assertViolations( SimpleProblemCollector result, int fatals, int errors, int warnings )
111 {
112 assertEquals( String.valueOf( result.getFatals() ), fatals, result.getFatals().size() );
113 assertEquals( String.valueOf( result.getErrors() ), errors, result.getErrors().size() );
114 assertEquals( String.valueOf( result.getWarnings() ), warnings, result.getWarnings().size() );
115 }
116
117 public void testMissingModelVersion()
118 throws Exception
119 {
120 SimpleProblemCollector result = validate( "missing-modelVersion-pom.xml" );
121
122 assertViolations( result, 0, 1, 0 );
123
124 assertEquals( "'modelVersion' is missing.", result.getErrors().get( 0 ) );
125 }
126
127 public void testBadModelVersion()
128 throws Exception
129 {
130 SimpleProblemCollector result =
131 validateRaw( "bad-modelVersion.xml", ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
132
133 assertViolations( result, 0, 1, 0 );
134
135 assertTrue( result.getErrors().get( 0 ).indexOf( "modelVersion" ) > -1 );
136 }
137
138 public void testMissingArtifactId()
139 throws Exception
140 {
141 SimpleProblemCollector result = validate( "missing-artifactId-pom.xml" );
142
143 assertViolations( result, 0, 1, 0 );
144
145 assertEquals( "'artifactId' is missing.", result.getErrors().get( 0 ) );
146 }
147
148 public void testMissingGroupId()
149 throws Exception
150 {
151 SimpleProblemCollector result = validate( "missing-groupId-pom.xml" );
152
153 assertViolations( result, 0, 1, 0 );
154
155 assertEquals( "'groupId' is missing.", result.getErrors().get( 0 ) );
156 }
157
158 public void testInvalidIds()
159 throws Exception
160 {
161 SimpleProblemCollector result = validate( "invalid-ids-pom.xml" );
162
163 assertViolations( result, 0, 2, 0 );
164
165 assertEquals( "'groupId' with value 'o/a/m' does not match a valid id pattern.", result.getErrors().get( 0 ) );
166
167 assertEquals( "'artifactId' with value 'm$-do$' does not match a valid id pattern.", result.getErrors().get( 1 ) );
168 }
169
170 public void testMissingType()
171 throws Exception
172 {
173 SimpleProblemCollector result = validate( "missing-type-pom.xml" );
174
175 assertViolations( result, 0, 1, 0 );
176
177 assertEquals( "'packaging' is missing.", result.getErrors().get( 0 ) );
178 }
179
180 public void testMissingVersion()
181 throws Exception
182 {
183 SimpleProblemCollector result = validate( "missing-version-pom.xml" );
184
185 assertViolations( result, 0, 1, 0 );
186
187 assertEquals( "'version' is missing.", result.getErrors().get( 0 ) );
188 }
189
190 public void testInvalidAggregatorPackaging()
191 throws Exception
192 {
193 SimpleProblemCollector result = validate( "invalid-aggregator-packaging-pom.xml" );
194
195 assertViolations( result, 0, 1, 0 );
196
197 assertTrue( result.getErrors().get( 0 ).indexOf( "Aggregator projects require 'pom' as packaging." ) > -1 );
198 }
199
200 public void testMissingDependencyArtifactId()
201 throws Exception
202 {
203 SimpleProblemCollector result = validate( "missing-dependency-artifactId-pom.xml" );
204
205 assertViolations( result, 0, 1, 0 );
206
207 assertTrue( result.getErrors().get( 0 ).indexOf(
208 "'dependencies.dependency.artifactId' for groupId:null:jar is missing" ) > -1 );
209 }
210
211 public void testMissingDependencyGroupId()
212 throws Exception
213 {
214 SimpleProblemCollector result = validate( "missing-dependency-groupId-pom.xml" );
215
216 assertViolations( result, 0, 1, 0 );
217
218 assertTrue( result.getErrors().get( 0 ).indexOf(
219 "'dependencies.dependency.groupId' for null:artifactId:jar is missing" ) > -1 );
220 }
221
222 public void testMissingDependencyVersion()
223 throws Exception
224 {
225 SimpleProblemCollector result = validate( "missing-dependency-version-pom.xml" );
226
227 assertViolations( result, 0, 1, 0 );
228
229 assertTrue( result.getErrors().get( 0 ).indexOf(
230 "'dependencies.dependency.version' for groupId:artifactId:jar is missing" ) > -1 );
231 }
232
233 public void testMissingDependencyManagementArtifactId()
234 throws Exception
235 {
236 SimpleProblemCollector result = validate( "missing-dependency-mgmt-artifactId-pom.xml" );
237
238 assertViolations( result, 0, 1, 0 );
239
240 assertTrue( result.getErrors().get( 0 ).indexOf(
241 "'dependencyManagement.dependencies.dependency.artifactId' for groupId:null:jar is missing" ) > -1 );
242 }
243
244 public void testMissingDependencyManagementGroupId()
245 throws Exception
246 {
247 SimpleProblemCollector result = validate( "missing-dependency-mgmt-groupId-pom.xml" );
248
249 assertViolations( result, 0, 1, 0 );
250
251 assertTrue( result.getErrors().get( 0 ).indexOf(
252 "'dependencyManagement.dependencies.dependency.groupId' for null:artifactId:jar is missing" ) > -1 );
253 }
254
255 public void testMissingAll()
256 throws Exception
257 {
258 SimpleProblemCollector result = validate( "missing-1-pom.xml" );
259
260 assertViolations( result, 0, 4, 0 );
261
262 List<String> messages = result.getErrors();
263
264 assertTrue( messages.contains( "\'modelVersion\' is missing." ) );
265 assertTrue( messages.contains( "\'groupId\' is missing." ) );
266 assertTrue( messages.contains( "\'artifactId\' is missing." ) );
267 assertTrue( messages.contains( "\'version\' is missing." ) );
268
269 }
270
271 public void testMissingPluginArtifactId()
272 throws Exception
273 {
274 SimpleProblemCollector result = validate( "missing-plugin-artifactId-pom.xml" );
275
276 assertViolations( result, 0, 1, 0 );
277
278 assertEquals( "'build.plugins.plugin.artifactId' is missing.", result.getErrors().get( 0 ) );
279 }
280
281 public void testEmptyPluginVersion()
282 throws Exception
283 {
284 SimpleProblemCollector result = validate( "empty-plugin-version.xml" );
285
286 assertViolations( result, 0, 1, 0 );
287
288 assertEquals( "'build.plugins.plugin.version' for org.apache.maven.plugins:maven-it-plugin"
289 + " must be a valid version but is ''.", result.getErrors().get( 0 ) );
290 }
291
292 public void testMissingRepositoryId()
293 throws Exception
294 {
295 SimpleProblemCollector result =
296 validateRaw( "missing-repository-id-pom.xml", ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
297
298 assertViolations( result, 0, 4, 0 );
299
300 assertEquals( "'repositories.repository.id' is missing.", result.getErrors().get( 0 ) );
301
302 assertEquals( "'repositories.repository[null].url' is missing.", result.getErrors().get( 1 ) );
303
304 assertEquals( "'pluginRepositories.pluginRepository.id' is missing.", result.getErrors().get( 2 ) );
305
306 assertEquals( "'pluginRepositories.pluginRepository[null].url' is missing.", result.getErrors().get( 3 ) );
307 }
308
309 public void testMissingResourceDirectory()
310 throws Exception
311 {
312 SimpleProblemCollector result = validate( "missing-resource-directory-pom.xml" );
313
314 assertViolations( result, 0, 2, 0 );
315
316 assertEquals( "'build.resources.resource.directory' is missing.", result.getErrors().get( 0 ) );
317
318 assertEquals( "'build.testResources.testResource.directory' is missing.", result.getErrors().get( 1 ) );
319 }
320
321 public void testBadPluginDependencyScope()
322 throws Exception
323 {
324 SimpleProblemCollector result = validate( "bad-plugin-dependency-scope.xml" );
325
326 assertViolations( result, 0, 3, 0 );
327
328 assertTrue( result.getErrors().get( 0 ).contains( "test:d" ) );
329
330 assertTrue( result.getErrors().get( 1 ).contains( "test:e" ) );
331
332 assertTrue( result.getErrors().get( 2 ).contains( "test:f" ) );
333 }
334
335 public void testBadDependencyScope()
336 throws Exception
337 {
338 SimpleProblemCollector result = validate( "bad-dependency-scope.xml" );
339
340 assertViolations( result, 0, 0, 2 );
341
342 assertTrue( result.getWarnings().get( 0 ).contains( "test:f" ) );
343
344 assertTrue( result.getWarnings().get( 1 ).contains( "test:g" ) );
345 }
346
347 public void testBadDependencyVersion()
348 throws Exception
349 {
350 SimpleProblemCollector result = validate( "bad-dependency-version.xml" );
351
352 assertViolations( result, 0, 2, 0 );
353
354 assertContains( result.getErrors().get( 0 ),
355 "'dependencies.dependency.version' for test:b:jar must be a valid version" );
356 assertContains( result.getErrors().get( 1 ),
357 "'dependencies.dependency.version' for test:c:jar must not contain any of these characters" );
358 }
359
360 public void testDuplicateModule()
361 throws Exception
362 {
363 SimpleProblemCollector result = validate( "duplicate-module.xml" );
364
365 assertViolations( result, 0, 1, 0 );
366
367 assertTrue( result.getErrors().get( 0 ).contains( "child" ) );
368 }
369
370 public void testDuplicateProfileId()
371 throws Exception
372 {
373 SimpleProblemCollector result = validateRaw( "duplicate-profile-id.xml" );
374
375 assertViolations( result, 0, 1, 0 );
376
377 assertTrue( result.getErrors().get( 0 ).contains( "non-unique-id" ) );
378 }
379
380 public void testBadPluginVersion()
381 throws Exception
382 {
383 SimpleProblemCollector result = validate( "bad-plugin-version.xml" );
384
385 assertViolations( result, 0, 4, 0 );
386
387 assertContains( result.getErrors().get( 0 ),
388 "'build.plugins.plugin.version' for test:mip must be a valid version" );
389 assertContains( result.getErrors().get( 1 ),
390 "'build.plugins.plugin.version' for test:rmv must be a valid version" );
391 assertContains( result.getErrors().get( 2 ),
392 "'build.plugins.plugin.version' for test:lmv must be a valid version" );
393 assertContains( result.getErrors().get( 3 ),
394 "'build.plugins.plugin.version' for test:ifsc must not contain any of these characters" );
395 }
396
397 public void testDistributionManagementStatus()
398 throws Exception
399 {
400 SimpleProblemCollector result = validate( "distribution-management-status.xml" );
401
402 assertViolations( result, 0, 1, 0 );
403
404 assertTrue( result.getErrors().get( 0 ).contains( "distributionManagement.status" ) );
405 }
406
407 public void testIncompleteParent()
408 throws Exception
409 {
410 SimpleProblemCollector result = validateRaw( "incomplete-parent.xml" );
411
412 assertViolations( result, 3, 0, 0 );
413
414 assertTrue( result.getFatals().get( 0 ).contains( "parent.groupId" ) );
415 assertTrue( result.getFatals().get( 1 ).contains( "parent.artifactId" ) );
416 assertTrue( result.getFatals().get( 2 ).contains( "parent.version" ) );
417 }
418
419 public void testHardCodedSystemPath()
420 throws Exception
421 {
422 SimpleProblemCollector result = validateRaw( "hard-coded-system-path.xml" );
423
424 assertViolations( result, 0, 0, 1 );
425
426 assertTrue( result.getWarnings().get( 0 ).contains( "test:a:jar" ) );
427 }
428
429 public void testEmptyModule()
430 throws Exception
431 {
432 SimpleProblemCollector result = validate( "empty-module.xml" );
433
434 assertViolations( result, 0, 0, 1 );
435
436 assertTrue( result.getWarnings().get( 0 ).contains( "'modules.module[0]' has been specified without a path" ) );
437 }
438
439 public void testDuplicatePlugin()
440 throws Exception
441 {
442 SimpleProblemCollector result = validateRaw( "duplicate-plugin.xml" );
443
444 assertViolations( result, 0, 0, 4 );
445
446 assertTrue( result.getWarnings().get( 0 ).contains( "duplicate declaration of plugin test:duplicate" ) );
447 assertTrue( result.getWarnings().get( 1 ).contains( "duplicate declaration of plugin test:managed-duplicate" ) );
448 assertTrue( result.getWarnings().get( 2 ).contains( "duplicate declaration of plugin profile:duplicate" ) );
449 assertTrue( result.getWarnings().get( 3 ).contains( "duplicate declaration of plugin profile:managed-duplicate" ) );
450 }
451
452 public void testDuplicatePluginExecution()
453 throws Exception
454 {
455 SimpleProblemCollector result = validateRaw( "duplicate-plugin-execution.xml" );
456
457 assertViolations( result, 0, 4, 0 );
458
459 assertContains( result.getErrors().get( 0 ), "duplicate execution with id a" );
460 assertContains( result.getErrors().get( 1 ), "duplicate execution with id default" );
461 assertContains( result.getErrors().get( 2 ), "duplicate execution with id c" );
462 assertContains( result.getErrors().get( 3 ), "duplicate execution with id b" );
463 }
464
465 public void testReservedRepositoryId()
466 throws Exception
467 {
468 SimpleProblemCollector result = validate( "reserved-repository-id.xml" );
469
470 assertViolations( result, 0, 0, 4 );
471
472 assertContains( result.getWarnings().get( 0 ), "'repositories.repository.id'" + " must not be 'local'" );
473 assertContains( result.getWarnings().get( 1 ), "'pluginRepositories.pluginRepository.id' must not be 'local'" );
474 assertContains( result.getWarnings().get( 2 ), "'distributionManagement.repository.id' must not be 'local'" );
475 assertContains( result.getWarnings().get( 3 ),
476 "'distributionManagement.snapshotRepository.id' must not be 'local'" );
477 }
478
479 public void testMissingPluginDependencyGroupId()
480 throws Exception
481 {
482 SimpleProblemCollector result = validate( "missing-plugin-dependency-groupId.xml" );
483
484 assertViolations( result, 0, 1, 0 );
485
486 assertTrue( result.getErrors().get( 0 ).contains( ":a:" ) );
487 }
488
489 public void testMissingPluginDependencyArtifactId()
490 throws Exception
491 {
492 SimpleProblemCollector result = validate( "missing-plugin-dependency-artifactId.xml" );
493
494 assertViolations( result, 0, 1, 0 );
495
496 assertTrue( result.getErrors().get( 0 ).contains( "test:" ) );
497 }
498
499 public void testMissingPluginDependencyVersion()
500 throws Exception
501 {
502 SimpleProblemCollector result = validate( "missing-plugin-dependency-version.xml" );
503
504 assertViolations( result, 0, 1, 0 );
505
506 assertTrue( result.getErrors().get( 0 ).contains( "test:a" ) );
507 }
508
509 public void testBadPluginDependencyVersion()
510 throws Exception
511 {
512 SimpleProblemCollector result = validate( "bad-plugin-dependency-version.xml" );
513
514 assertViolations( result, 0, 1, 0 );
515
516 assertTrue( result.getErrors().get( 0 ).contains( "test:b" ) );
517 }
518
519 public void testBadVersion()
520 throws Exception
521 {
522 SimpleProblemCollector result = validate( "bad-version.xml" );
523
524 assertViolations( result, 0, 0, 1 );
525
526 assertContains( result.getWarnings().get( 0 ), "'version' must not contain any of these characters" );
527 }
528
529 public void testBadSnapshotVersion()
530 throws Exception
531 {
532 SimpleProblemCollector result = validate( "bad-snapshot-version.xml" );
533
534 assertViolations( result, 0, 0, 1 );
535
536 assertContains( result.getWarnings().get( 0 ), "'version' uses an unsupported snapshot version format" );
537 }
538
539 public void testBadRepositoryId()
540 throws Exception
541 {
542 SimpleProblemCollector result = validate( "bad-repository-id.xml" );
543
544 assertViolations( result, 0, 0, 4 );
545
546 assertContains( result.getWarnings().get( 0 ),
547 "'repositories.repository.id' must not contain any of these characters" );
548 assertContains( result.getWarnings().get( 1 ),
549 "'pluginRepositories.pluginRepository.id' must not contain any of these characters" );
550 assertContains( result.getWarnings().get( 2 ),
551 "'distributionManagement.repository.id' must not contain any of these characters" );
552 assertContains( result.getWarnings().get( 3 ),
553 "'distributionManagement.snapshotRepository.id' must not contain any of these characters" );
554 }
555
556 public void testBadDependencyExclusionId()
557 throws Exception
558 {
559 SimpleProblemCollector result = validate( "bad-dependency-exclusion-id.xml" );
560
561 assertViolations( result, 0, 0, 2 );
562
563 assertContains( result.getWarnings().get( 0 ),
564 "'dependencies.dependency.exclusions.exclusion.groupId' for gid:aid:jar" );
565 assertContains( result.getWarnings().get( 1 ),
566 "'dependencies.dependency.exclusions.exclusion.artifactId' for gid:aid:jar" );
567 }
568
569 public void testMissingDependencyExclusionId()
570 throws Exception
571 {
572 SimpleProblemCollector result = validate( "missing-dependency-exclusion-id.xml" );
573
574 assertViolations( result, 0, 0, 2 );
575
576 assertContains( result.getWarnings().get( 0 ),
577 "'dependencies.dependency.exclusions.exclusion.groupId' for gid:aid:jar is missing" );
578 assertContains( result.getWarnings().get( 1 ),
579 "'dependencies.dependency.exclusions.exclusion.artifactId' for gid:aid:jar is missing" );
580 }
581
582 public void testBadImportScopeType()
583 throws Exception
584 {
585 SimpleProblemCollector result = validateRaw( "bad-import-scope-type.xml" );
586
587 assertViolations( result, 0, 0, 1 );
588
589 assertContains( result.getWarnings().get( 0 ),
590 "'dependencyManagement.dependencies.dependency.type' for test:a:jar must be 'pom'" );
591 }
592
593 public void testBadImportScopeClassifier()
594 throws Exception
595 {
596 SimpleProblemCollector result = validateRaw( "bad-import-scope-classifier.xml" );
597
598 assertViolations( result, 0, 1, 0 );
599
600 assertContains( result.getErrors().get( 0 ),
601 "'dependencyManagement.dependencies.dependency.classifier' for test:a:pom:cls must be empty" );
602 }
603
604 public void testSystemPathRefersToProjectBasedir()
605 throws Exception
606 {
607 SimpleProblemCollector result = validateRaw( "basedir-system-path.xml" );
608
609 assertViolations( result, 0, 0, 2 );
610
611 assertContains( result.getWarnings().get( 0 ), "'dependencies.dependency.systemPath' for test:a:jar "
612 + "should not point at files within the project directory" );
613 assertContains( result.getWarnings().get( 1 ), "'dependencies.dependency.systemPath' for test:b:jar "
614 + "should not point at files within the project directory" );
615 }
616
617 }