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