View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.model.validation;
20  
21  import java.io.InputStream;
22  import java.util.List;
23  
24  import org.apache.maven.model.Model;
25  import org.apache.maven.model.building.DefaultModelBuildingRequest;
26  import org.apache.maven.model.building.ModelBuildingRequest;
27  import org.apache.maven.model.building.SimpleProblemCollector;
28  import org.apache.maven.model.interpolation.DefaultModelVersionProcessor;
29  import org.apache.maven.model.v4.MavenStaxReader;
30  import org.junit.jupiter.api.AfterEach;
31  import org.junit.jupiter.api.BeforeEach;
32  import org.junit.jupiter.api.Test;
33  
34  import static org.junit.jupiter.api.Assertions.assertEquals;
35  import static org.junit.jupiter.api.Assertions.assertNotNull;
36  import static org.junit.jupiter.api.Assertions.assertTrue;
37  
38  /**
39   */
40  class DefaultModelValidatorTest {
41  
42      private ModelValidator validator;
43  
44      private Model read(String pom) throws Exception {
45          String resource = "/poms/validation/" + pom;
46          try (InputStream is = getClass().getResourceAsStream(resource)) {
47              assertNotNull(is, "missing resource: " + resource);
48              return new Model(new MavenStaxReader().read(is));
49          }
50      }
51  
52      private SimpleProblemCollector validate(String pom) throws Exception {
53          return validateEffective(pom, ModelBuildingRequest.VALIDATION_LEVEL_STRICT);
54      }
55  
56      private SimpleProblemCollector validateRaw(String pom) throws Exception {
57          return validateRaw(pom, ModelBuildingRequest.VALIDATION_LEVEL_STRICT);
58      }
59  
60      private SimpleProblemCollector validateEffective(String pom, int level) throws Exception {
61          ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel(level);
62  
63          Model model = read(pom);
64  
65          SimpleProblemCollector problems = new SimpleProblemCollector(model);
66  
67          validator.validateEffectiveModel(model, request, problems);
68  
69          return problems;
70      }
71  
72      private SimpleProblemCollector validateRaw(String pom, int level) throws Exception {
73          ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel(level);
74  
75          Model model = read(pom);
76  
77          SimpleProblemCollector problems = new SimpleProblemCollector(model);
78  
79          validator.validateFileModel(model, request, problems);
80  
81          validator.validateRawModel(model, request, problems);
82  
83          return problems;
84      }
85  
86      private void assertContains(String msg, String substring) {
87          assertTrue(msg.contains(substring), "\"" + substring + "\" was not found in: " + msg);
88      }
89  
90      @BeforeEach
91      void setUp() throws Exception {
92          validator = new DefaultModelValidator(new DefaultModelVersionProcessor());
93      }
94  
95      @AfterEach
96      void tearDown() throws Exception {
97          this.validator = null;
98      }
99  
100     private void assertViolations(SimpleProblemCollector result, int fatals, int errors, int warnings) {
101         assertEquals(fatals, result.getFatals().size(), String.valueOf(result.getFatals()));
102         assertEquals(errors, result.getErrors().size(), String.valueOf(result.getErrors()));
103         assertEquals(warnings, result.getWarnings().size(), String.valueOf(result.getWarnings()));
104     }
105 
106     @Test
107     void testMissingModelVersion() throws Exception {
108         SimpleProblemCollector result = validate("missing-modelVersion-pom.xml");
109 
110         assertViolations(result, 0, 1, 0);
111 
112         assertEquals("'modelVersion' is missing.", result.getErrors().get(0));
113     }
114 
115     @Test
116     void testBadModelVersion() throws Exception {
117         SimpleProblemCollector result =
118                 validateRaw("bad-modelVersion.xml", ModelBuildingRequest.VALIDATION_LEVEL_STRICT);
119 
120         assertViolations(result, 1, 0, 0);
121 
122         assertTrue(result.getFatals().get(0).contains("modelVersion"));
123     }
124 
125     @Test
126     void testModelVersionMessage() throws Exception {
127         SimpleProblemCollector result =
128                 validateRaw("modelVersion-4_0.xml", ModelBuildingRequest.VALIDATION_LEVEL_STRICT);
129 
130         assertViolations(result, 0, 1, 0);
131 
132         assertTrue(result.getErrors().get(0).contains("'modelVersion' must be one of"));
133     }
134 
135     @Test
136     void testMissingArtifactId() throws Exception {
137         SimpleProblemCollector result = validate("missing-artifactId-pom.xml");
138 
139         assertViolations(result, 0, 1, 0);
140 
141         assertEquals("'artifactId' is missing.", result.getErrors().get(0));
142     }
143 
144     @Test
145     void testMissingGroupId() throws Exception {
146         SimpleProblemCollector result = validate("missing-groupId-pom.xml");
147 
148         assertViolations(result, 0, 1, 0);
149 
150         assertEquals("'groupId' is missing.", result.getErrors().get(0));
151     }
152 
153     @Test
154     void testInvalidCoordinateIds() throws Exception {
155         SimpleProblemCollector result = validate("invalid-coordinate-ids-pom.xml");
156 
157         assertViolations(result, 0, 2, 0);
158 
159         assertEquals(
160                 "'groupId' with value 'o/a/m' does not match a valid coordinate id pattern.",
161                 result.getErrors().get(0));
162 
163         assertEquals(
164                 "'artifactId' with value 'm$-do$' does not match a valid coordinate id pattern.",
165                 result.getErrors().get(1));
166     }
167 
168     @Test
169     void testMissingType() throws Exception {
170         SimpleProblemCollector result = validate("missing-type-pom.xml");
171 
172         assertViolations(result, 0, 1, 0);
173 
174         assertEquals("'packaging' is missing.", result.getErrors().get(0));
175     }
176 
177     @Test
178     void testMissingVersion() throws Exception {
179         SimpleProblemCollector result = validate("missing-version-pom.xml");
180 
181         assertViolations(result, 0, 1, 0);
182 
183         assertEquals("'version' is missing.", result.getErrors().get(0));
184     }
185 
186     @Test
187     void testInvalidAggregatorPackaging() throws Exception {
188         SimpleProblemCollector result = validate("invalid-aggregator-packaging-pom.xml");
189 
190         assertViolations(result, 0, 1, 0);
191 
192         assertTrue(result.getErrors().get(0).contains("Aggregator projects require 'pom' as packaging."));
193     }
194 
195     @Test
196     void testMissingDependencyArtifactId() throws Exception {
197         SimpleProblemCollector result = validate("missing-dependency-artifactId-pom.xml");
198 
199         assertViolations(result, 0, 1, 0);
200 
201         assertTrue(result.getErrors()
202                 .get(0)
203                 .contains("'dependencies.dependency.artifactId' for groupId:null:jar is missing"));
204     }
205 
206     @Test
207     void testMissingDependencyGroupId() throws Exception {
208         SimpleProblemCollector result = validate("missing-dependency-groupId-pom.xml");
209 
210         assertViolations(result, 0, 1, 0);
211 
212         assertTrue(result.getErrors()
213                 .get(0)
214                 .contains("'dependencies.dependency.groupId' for null:artifactId:jar is missing"));
215     }
216 
217     @Test
218     void testMissingDependencyVersion() throws Exception {
219         SimpleProblemCollector result = validate("missing-dependency-version-pom.xml");
220 
221         assertViolations(result, 0, 1, 0);
222 
223         assertTrue(result.getErrors()
224                 .get(0)
225                 .contains("'dependencies.dependency.version' for groupId:artifactId:jar is missing"));
226     }
227 
228     @Test
229     void testMissingDependencyManagementArtifactId() throws Exception {
230         SimpleProblemCollector result = validate("missing-dependency-mgmt-artifactId-pom.xml");
231 
232         assertViolations(result, 0, 1, 0);
233 
234         assertTrue(result.getErrors()
235                 .get(0)
236                 .contains("'dependencyManagement.dependencies.dependency.artifactId' for groupId:null:jar is missing"));
237     }
238 
239     @Test
240     void testMissingDependencyManagementGroupId() throws Exception {
241         SimpleProblemCollector result = validate("missing-dependency-mgmt-groupId-pom.xml");
242 
243         assertViolations(result, 0, 1, 0);
244 
245         assertTrue(result.getErrors()
246                 .get(0)
247                 .contains("'dependencyManagement.dependencies.dependency.groupId' for null:artifactId:jar is missing"));
248     }
249 
250     @Test
251     void testMissingAll() throws Exception {
252         SimpleProblemCollector result = validate("missing-1-pom.xml");
253 
254         assertViolations(result, 0, 4, 0);
255 
256         List<String> messages = result.getErrors();
257 
258         assertTrue(messages.contains("'modelVersion' is missing."));
259         assertTrue(messages.contains("'groupId' is missing."));
260         assertTrue(messages.contains("'artifactId' is missing."));
261         assertTrue(messages.contains("'version' is missing."));
262         // type is inherited from the super pom
263     }
264 
265     @Test
266     void testMissingPluginArtifactId() throws Exception {
267         SimpleProblemCollector result = validate("missing-plugin-artifactId-pom.xml");
268 
269         assertViolations(result, 0, 1, 0);
270 
271         assertEquals(
272                 "'build.plugins.plugin.artifactId' is missing.",
273                 result.getErrors().get(0));
274     }
275 
276     @Test
277     void testEmptyPluginVersion() throws Exception {
278         SimpleProblemCollector result = validate("empty-plugin-version.xml");
279 
280         assertViolations(result, 0, 1, 0);
281 
282         assertEquals(
283                 "'build.plugins.plugin.version' for org.apache.maven.plugins:maven-it-plugin"
284                         + " must be a valid version but is ''.",
285                 result.getErrors().get(0));
286     }
287 
288     @Test
289     void testMissingRepositoryId() throws Exception {
290         SimpleProblemCollector result =
291                 validateRaw("missing-repository-id-pom.xml", ModelBuildingRequest.VALIDATION_LEVEL_STRICT);
292 
293         assertViolations(result, 0, 4, 0);
294 
295         assertEquals(
296                 "'repositories.repository.id' is missing.", result.getErrors().get(0));
297 
298         assertEquals(
299                 "'repositories.repository.[null].url' is missing.",
300                 result.getErrors().get(1));
301 
302         assertEquals(
303                 "'pluginRepositories.pluginRepository.id' is missing.",
304                 result.getErrors().get(2));
305 
306         assertEquals(
307                 "'pluginRepositories.pluginRepository.[null].url' is missing.",
308                 result.getErrors().get(3));
309     }
310 
311     @Test
312     void testMissingResourceDirectory() throws Exception {
313         SimpleProblemCollector result = validate("missing-resource-directory-pom.xml");
314 
315         assertViolations(result, 0, 2, 0);
316 
317         assertEquals(
318                 "'build.resources.resource.directory' is missing.",
319                 result.getErrors().get(0));
320 
321         assertEquals(
322                 "'build.testResources.testResource.directory' is missing.",
323                 result.getErrors().get(1));
324     }
325 
326     @Test
327     void testBadPluginDependencyScope() throws Exception {
328         SimpleProblemCollector result = validate("bad-plugin-dependency-scope.xml");
329 
330         assertViolations(result, 0, 3, 0);
331 
332         assertTrue(result.getErrors().get(0).contains("test:d"));
333 
334         assertTrue(result.getErrors().get(1).contains("test:e"));
335 
336         assertTrue(result.getErrors().get(2).contains("test:f"));
337     }
338 
339     @Test
340     void testBadDependencyScope() throws Exception {
341         SimpleProblemCollector result = validate("bad-dependency-scope.xml");
342 
343         assertViolations(result, 0, 0, 2);
344 
345         assertTrue(result.getWarnings().get(0).contains("test:f"));
346 
347         assertTrue(result.getWarnings().get(1).contains("test:g"));
348     }
349 
350     @Test
351     void testBadDependencyManagementScope() throws Exception {
352         SimpleProblemCollector result = validate("bad-dependency-management-scope.xml");
353 
354         assertViolations(result, 0, 0, 1);
355 
356         assertContains(result.getWarnings().get(0), "test:g");
357     }
358 
359     @Test
360     void testBadDependencyVersion() throws Exception {
361         SimpleProblemCollector result = validate("bad-dependency-version.xml");
362 
363         assertViolations(result, 0, 2, 0);
364 
365         assertContains(
366                 result.getErrors().get(0), "'dependencies.dependency.version' for test:b:jar must be a valid version");
367         assertContains(
368                 result.getErrors().get(1),
369                 "'dependencies.dependency.version' for test:c:jar must not contain any of these characters");
370     }
371 
372     @Test
373     void testDuplicateModule() throws Exception {
374         SimpleProblemCollector result = validateRaw("duplicate-module.xml");
375 
376         assertViolations(result, 0, 1, 0);
377 
378         assertTrue(result.getErrors().get(0).contains("child"));
379     }
380 
381     @Test
382     void testInvalidProfileId() throws Exception {
383         SimpleProblemCollector result = validateRaw("invalid-profile-ids.xml");
384 
385         assertViolations(result, 0, 4, 0);
386 
387         assertTrue(result.getErrors().get(0).contains("+invalid-id"));
388         assertTrue(result.getErrors().get(1).contains("-invalid-id"));
389         assertTrue(result.getErrors().get(2).contains("!invalid-id"));
390         assertTrue(result.getErrors().get(3).contains("?invalid-id"));
391     }
392 
393     public void testDuplicateProfileId() throws Exception {
394         SimpleProblemCollector result = validateRaw("duplicate-profile-id.xml");
395 
396         assertViolations(result, 0, 1, 0);
397 
398         assertTrue(result.getErrors().get(0).contains("non-unique-id"));
399     }
400 
401     @Test
402     void testBadPluginVersion() throws Exception {
403         SimpleProblemCollector result = validate("bad-plugin-version.xml");
404 
405         assertViolations(result, 0, 4, 0);
406 
407         assertContains(
408                 result.getErrors().get(0), "'build.plugins.plugin.version' for test:mip must be a valid version");
409         assertContains(
410                 result.getErrors().get(1), "'build.plugins.plugin.version' for test:rmv must be a valid version");
411         assertContains(
412                 result.getErrors().get(2), "'build.plugins.plugin.version' for test:lmv must be a valid version");
413         assertContains(
414                 result.getErrors().get(3),
415                 "'build.plugins.plugin.version' for test:ifsc must not contain any of these characters");
416     }
417 
418     @Test
419     void testDistributionManagementStatus() throws Exception {
420         SimpleProblemCollector result = validate("distribution-management-status.xml");
421 
422         assertViolations(result, 0, 1, 0);
423 
424         assertTrue(result.getErrors().get(0).contains("distributionManagement.status"));
425     }
426 
427     @Test
428     void testIncompleteParent() throws Exception {
429         SimpleProblemCollector result = validateRaw("incomplete-parent.xml");
430 
431         assertViolations(result, 3, 0, 0);
432         assertTrue(result.getFatals().get(0).contains("parent.groupId"));
433         assertTrue(result.getFatals().get(1).contains("parent.artifactId"));
434         assertTrue(result.getFatals().get(2).contains("parent.version"));
435     }
436 
437     @Test
438     void testHardCodedSystemPath() throws Exception {
439         SimpleProblemCollector result = validateRaw("hard-coded-system-path.xml");
440 
441         assertViolations(result, 0, 0, 3);
442 
443         assertContains(
444                 result.getWarnings().get(0),
445                 "'dependencies.dependency.scope' for test:a:jar declares usage of deprecated 'system' scope");
446         assertContains(
447                 result.getWarnings().get(1),
448                 "'dependencies.dependency.systemPath' for test:a:jar should use a variable instead of a hard-coded path");
449         assertContains(
450                 result.getWarnings().get(2),
451                 "'dependencies.dependency.scope' for test:b:jar declares usage of deprecated 'system' scope");
452     }
453 
454     @Test
455     void testEmptyModule() throws Exception {
456         SimpleProblemCollector result = validate("empty-module.xml");
457 
458         assertViolations(result, 0, 1, 0);
459 
460         assertTrue(result.getErrors().get(0).contains("'modules.module[0]' has been specified without a path"));
461     }
462 
463     @Test
464     void testDuplicatePlugin() throws Exception {
465         SimpleProblemCollector result = validateRaw("duplicate-plugin.xml");
466 
467         assertViolations(result, 0, 4, 0);
468 
469         assertTrue(result.getErrors().get(0).contains("duplicate declaration of plugin test:duplicate"));
470         assertTrue(result.getErrors().get(1).contains("duplicate declaration of plugin test:managed-duplicate"));
471         assertTrue(result.getErrors().get(2).contains("duplicate declaration of plugin profile:duplicate"));
472         assertTrue(result.getErrors().get(3).contains("duplicate declaration of plugin profile:managed-duplicate"));
473     }
474 
475     @Test
476     void testDuplicatePluginExecution() throws Exception {
477         SimpleProblemCollector result = validateRaw("duplicate-plugin-execution.xml");
478 
479         assertViolations(result, 0, 4, 0);
480 
481         assertContains(result.getErrors().get(0), "duplicate execution with id a");
482         assertContains(result.getErrors().get(1), "duplicate execution with id default");
483         assertContains(result.getErrors().get(2), "duplicate execution with id c");
484         assertContains(result.getErrors().get(3), "duplicate execution with id b");
485     }
486 
487     @Test
488     void testReservedRepositoryId() throws Exception {
489         SimpleProblemCollector result = validate("reserved-repository-id.xml");
490 
491         assertViolations(result, 0, 4, 0);
492 
493         assertContains(result.getErrors().get(0), "'repositories.repository.id'" + " must not be 'local'");
494         assertContains(result.getErrors().get(1), "'pluginRepositories.pluginRepository.id' must not be 'local'");
495         assertContains(result.getErrors().get(2), "'distributionManagement.repository.id' must not be 'local'");
496         assertContains(result.getErrors().get(3), "'distributionManagement.snapshotRepository.id' must not be 'local'");
497     }
498 
499     @Test
500     void testMissingPluginDependencyGroupId() throws Exception {
501         SimpleProblemCollector result = validate("missing-plugin-dependency-groupId.xml");
502 
503         assertViolations(result, 0, 1, 0);
504 
505         assertTrue(result.getErrors().get(0).contains(":a:"));
506     }
507 
508     @Test
509     void testMissingPluginDependencyArtifactId() throws Exception {
510         SimpleProblemCollector result = validate("missing-plugin-dependency-artifactId.xml");
511 
512         assertViolations(result, 0, 1, 0);
513 
514         assertTrue(result.getErrors().get(0).contains("test:"));
515     }
516 
517     @Test
518     void testMissingPluginDependencyVersion() throws Exception {
519         SimpleProblemCollector result = validate("missing-plugin-dependency-version.xml");
520 
521         assertViolations(result, 0, 1, 0);
522 
523         assertTrue(result.getErrors().get(0).contains("test:a"));
524     }
525 
526     @Test
527     void testBadPluginDependencyVersion() throws Exception {
528         SimpleProblemCollector result = validate("bad-plugin-dependency-version.xml");
529 
530         assertViolations(result, 0, 1, 0);
531 
532         assertTrue(result.getErrors().get(0).contains("test:b"));
533     }
534 
535     @Test
536     void testBadVersion() throws Exception {
537         SimpleProblemCollector result = validate("bad-version.xml");
538 
539         assertViolations(result, 0, 1, 0);
540 
541         assertContains(result.getErrors().get(0), "'version' must not contain any of these characters");
542     }
543 
544     @Test
545     void testBadSnapshotVersion() throws Exception {
546         SimpleProblemCollector result = validate("bad-snapshot-version.xml");
547 
548         assertViolations(result, 0, 1, 0);
549 
550         assertContains(result.getErrors().get(0), "'version' uses an unsupported snapshot version format");
551     }
552 
553     @Test
554     void testBadRepositoryId() throws Exception {
555         SimpleProblemCollector result = validate("bad-repository-id.xml");
556 
557         assertViolations(result, 0, 4, 0);
558 
559         assertContains(
560                 result.getErrors().get(0), "'repositories.repository.id' must not contain any of these characters");
561         assertContains(
562                 result.getErrors().get(1),
563                 "'pluginRepositories.pluginRepository.id' must not contain any of these characters");
564         assertContains(
565                 result.getErrors().get(2),
566                 "'distributionManagement.repository.id' must not contain any of these characters");
567         assertContains(
568                 result.getErrors().get(3),
569                 "'distributionManagement.snapshotRepository.id' must not contain any of these characters");
570     }
571 
572     @Test
573     void testBadDependencyExclusionId() throws Exception {
574         SimpleProblemCollector result =
575                 validateEffective("bad-dependency-exclusion-id.xml", ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0);
576 
577         assertViolations(result, 0, 0, 2);
578 
579         assertContains(
580                 result.getWarnings().get(0), "'dependencies.dependency.exclusions.exclusion.groupId' for gid:aid:jar");
581         assertContains(
582                 result.getWarnings().get(1),
583                 "'dependencies.dependency.exclusions.exclusion.artifactId' for gid:aid:jar");
584 
585         // MNG-3832: Aether (part of M3+) supports wildcard expressions for exclusions
586 
587         SimpleProblemCollector result_30 = validate("bad-dependency-exclusion-id.xml");
588 
589         assertViolations(result_30, 0, 0, 0);
590     }
591 
592     @Test
593     void testMissingDependencyExclusionId() throws Exception {
594         SimpleProblemCollector result = validate("missing-dependency-exclusion-id.xml");
595 
596         assertViolations(result, 0, 0, 2);
597 
598         assertContains(
599                 result.getWarnings().get(0),
600                 "'dependencies.dependency.exclusions.exclusion.groupId' for gid:aid:jar is missing");
601         assertContains(
602                 result.getWarnings().get(1),
603                 "'dependencies.dependency.exclusions.exclusion.artifactId' for gid:aid:jar is missing");
604     }
605 
606     @Test
607     void testBadImportScopeType() throws Exception {
608         SimpleProblemCollector result = validateRaw("bad-import-scope-type.xml");
609 
610         assertViolations(result, 0, 0, 1);
611 
612         assertContains(
613                 result.getWarnings().get(0),
614                 "'dependencyManagement.dependencies.dependency.type' for test:a:jar must be 'pom'");
615     }
616 
617     @Test
618     void testBadImportScopeClassifier() throws Exception {
619         SimpleProblemCollector result = validateRaw("bad-import-scope-classifier.xml");
620 
621         assertViolations(result, 0, 1, 0);
622 
623         assertContains(
624                 result.getErrors().get(0),
625                 "'dependencyManagement.dependencies.dependency.classifier' for test:a:pom:cls must be empty");
626     }
627 
628     @Test
629     void testSystemPathRefersToProjectBasedir() throws Exception {
630         SimpleProblemCollector result = validateRaw("basedir-system-path.xml");
631 
632         assertViolations(result, 0, 0, 4);
633 
634         assertContains(
635                 result.getWarnings().get(0),
636                 "'dependencies.dependency.scope' for test:a:jar declares usage of deprecated 'system' scope");
637         assertContains(
638                 result.getWarnings().get(1),
639                 "'dependencies.dependency.systemPath' for test:a:jar should not point at files within the project directory");
640         assertContains(
641                 result.getWarnings().get(2),
642                 "'dependencies.dependency.scope' for test:b:jar declares usage of deprecated 'system' scope");
643         assertContains(
644                 result.getWarnings().get(3),
645                 "'dependencies.dependency.systemPath' for test:b:jar should not point at files within the project directory");
646     }
647 
648     @Test
649     void testInvalidVersionInPluginManagement() throws Exception {
650         SimpleProblemCollector result = validateRaw("raw-model/missing-plugin-version-pluginManagement.xml");
651 
652         assertViolations(result, 1, 0, 0);
653 
654         assertEquals(
655                 "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' version of a plugin must be defined. ",
656                 result.getFatals().get(0));
657     }
658 
659     @Test
660     void testInvalidGroupIdInPluginManagement() throws Exception {
661         SimpleProblemCollector result = validateRaw("raw-model/missing-groupId-pluginManagement.xml");
662 
663         assertViolations(result, 1, 0, 0);
664 
665         assertEquals(
666                 "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' groupId of a plugin must be defined. ",
667                 result.getFatals().get(0));
668     }
669 
670     @Test
671     void testInvalidArtifactIdInPluginManagement() throws Exception {
672         SimpleProblemCollector result = validateRaw("raw-model/missing-artifactId-pluginManagement.xml");
673 
674         assertViolations(result, 1, 0, 0);
675 
676         assertEquals(
677                 "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' artifactId of a plugin must be defined. ",
678                 result.getFatals().get(0));
679     }
680 
681     @Test
682     void testInvalidGroupAndArtifactIdInPluginManagement() throws Exception {
683         SimpleProblemCollector result = validateRaw("raw-model/missing-ga-pluginManagement.xml");
684 
685         assertViolations(result, 2, 0, 0);
686 
687         assertEquals(
688                 "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' groupId of a plugin must be defined. ",
689                 result.getFatals().get(0));
690 
691         assertEquals(
692                 "'build.pluginManagement.plugins.plugin.(groupId:artifactId)' artifactId of a plugin must be defined. ",
693                 result.getFatals().get(1));
694     }
695 
696     @Test
697     void testMissingReportPluginVersion() throws Exception {
698         SimpleProblemCollector result = validate("missing-report-version-pom.xml");
699 
700         assertViolations(result, 0, 0, 0);
701     }
702 
703     @Test
704     void testDeprecatedDependencyMetaversionsLatestAndRelease() throws Exception {
705         SimpleProblemCollector result = validateRaw("deprecated-dependency-metaversions-latest-and-release.xml");
706 
707         assertViolations(result, 0, 0, 2);
708 
709         assertContains(
710                 result.getWarnings().get(0),
711                 "'dependencies.dependency.version' for test:a:jar is either LATEST or RELEASE (both of them are being deprecated)");
712         assertContains(
713                 result.getWarnings().get(1),
714                 "'dependencies.dependency.version' for test:b:jar is either LATEST or RELEASE (both of them are being deprecated)");
715     }
716 
717     @Test
718     void testSelfReferencingDependencyInRawModel() throws Exception {
719         SimpleProblemCollector result = validateRaw("raw-model/self-referencing.xml");
720 
721         assertViolations(result, 1, 0, 0);
722 
723         assertEquals(
724                 "'dependencies.dependency[com.example.group:testinvalidpom:0.0.1-SNAPSHOT]' for com.example.group:testinvalidpom:0.0.1-SNAPSHOT is referencing itself.",
725                 result.getFatals().get(0));
726     }
727 
728     @Test
729     void testSelfReferencingDependencyWithClassifierInRawModel() throws Exception {
730         SimpleProblemCollector result = validateRaw("raw-model/self-referencing-classifier.xml");
731 
732         assertViolations(result, 0, 0, 0);
733     }
734 
735     @Test
736     void testCiFriendlySha1() throws Exception {
737         SimpleProblemCollector result = validateRaw("raw-model/ok-ci-friendly-sha1.xml");
738         assertViolations(result, 0, 0, 0);
739     }
740 
741     @Test
742     void testCiFriendlyRevision() throws Exception {
743         SimpleProblemCollector result = validateRaw("raw-model/ok-ci-friendly-revision.xml");
744         assertViolations(result, 0, 0, 0);
745     }
746 
747     @Test
748     void testCiFriendlyChangeList() throws Exception {
749         SimpleProblemCollector result = validateRaw("raw-model/ok-ci-friendly-changelist.xml");
750         assertViolations(result, 0, 0, 0);
751     }
752 
753     @Test
754     void testCiFriendlyAllExpressions() throws Exception {
755         SimpleProblemCollector result = validateRaw("raw-model/ok-ci-friendly-all-expressions.xml");
756         assertViolations(result, 0, 0, 0);
757     }
758 
759     @Test
760     void testCiFriendlyBad() throws Exception {
761         SimpleProblemCollector result = validateRaw("raw-model/bad-ci-friendly.xml");
762         assertViolations(result, 0, 0, 1);
763         assertEquals(
764                 "'version' contains an expression but should be a constant.",
765                 result.getWarnings().get(0));
766     }
767 
768     @Test
769     void testCiFriendlyBadSha1Plus() throws Exception {
770         SimpleProblemCollector result = validateRaw("raw-model/bad-ci-friendly-sha1plus.xml");
771         assertViolations(result, 0, 0, 1);
772         assertEquals(
773                 "'version' contains an expression but should be a constant.",
774                 result.getWarnings().get(0));
775     }
776 
777     @Test
778     void testCiFriendlyBadSha1Plus2() throws Exception {
779         SimpleProblemCollector result = validateRaw("raw-model/bad-ci-friendly-sha1plus2.xml");
780         assertViolations(result, 0, 0, 1);
781         assertEquals(
782                 "'version' contains an expression but should be a constant.",
783                 result.getWarnings().get(0));
784     }
785 
786     @Test
787     void testParentVersionLATEST() throws Exception {
788         SimpleProblemCollector result = validateRaw("raw-model/bad-parent-version-latest.xml");
789         assertViolations(result, 0, 0, 1);
790         assertEquals(
791                 "'parent.version' is either LATEST or RELEASE (both of them are being deprecated)",
792                 result.getWarnings().get(0));
793     }
794 
795     @Test
796     void testParentVersionRELEASE() throws Exception {
797         SimpleProblemCollector result = validateRaw("raw-model/bad-parent-version-release.xml");
798         assertViolations(result, 0, 0, 1);
799         assertEquals(
800                 "'parent.version' is either LATEST or RELEASE (both of them are being deprecated)",
801                 result.getWarnings().get(0));
802     }
803 
804     @Test
805     void repositoryWithExpression() throws Exception {
806         SimpleProblemCollector result = validateRaw("raw-model/repository-with-expression.xml");
807         assertViolations(result, 0, 1, 0);
808         assertEquals(
809                 "'repositories.repository.[repo].url' contains an expression but should be a constant.",
810                 result.getErrors().get(0));
811     }
812 
813     @Test
814     void repositoryWithBasedirExpression() throws Exception {
815         SimpleProblemCollector result = validateRaw("raw-model/repository-with-basedir-expression.xml");
816         assertViolations(result, 0, 0, 0);
817     }
818 
819     @Test
820     void profileActivationWithAllowedExpression() throws Exception {
821         SimpleProblemCollector result = validateRaw("raw-model/profile-activation-file-with-allowed-expressions.xml");
822         assertViolations(result, 0, 0, 0);
823     }
824 
825     @Test
826     void profileActivationWithProjectExpression() throws Exception {
827         SimpleProblemCollector result = validateRaw("raw-model/profile-activation-file-with-project-expressions.xml");
828         assertViolations(result, 0, 0, 2);
829 
830         assertEquals(
831                 "'profiles.profile[exists-project-version].activation.file.exists' "
832                         + "Failed to interpolate file location ${project.version}/test.txt: "
833                         + "${project.version} expressions are not supported during profile activation.",
834                 result.getWarnings().get(0));
835 
836         assertEquals(
837                 "'profiles.profile[missing-project-version].activation.file.missing' "
838                         + "Failed to interpolate file location ${project.version}/test.txt: "
839                         + "${project.version} expressions are not supported during profile activation.",
840                 result.getWarnings().get(1));
841     }
842 }