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