View Javadoc
1   package org.apache.maven.model.inheritance;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.model.Model;
23  import org.apache.maven.model.building.SimpleProblemCollector;
24  import org.apache.maven.model.io.ModelParseException;
25  import org.apache.maven.model.io.ModelReader;
26  import org.apache.maven.model.io.ModelWriter;
27  import org.codehaus.plexus.PlexusTestCase;
28  import org.custommonkey.xmlunit.XMLAssert;
29  import org.custommonkey.xmlunit.XMLUnit;
30  
31  import junit.framework.AssertionFailedError;
32  
33  import java.io.File;
34  import java.io.FileInputStream;
35  import java.io.IOException;
36  import java.io.InputStreamReader;
37  import java.io.Reader;
38  import java.nio.charset.StandardCharsets;
39  
40  /**
41   * @author Hervé Boutemy
42   */
43  public class DefaultInheritanceAssemblerTest
44      extends PlexusTestCase
45  {
46      private ModelReader reader;
47  
48      private ModelWriter writer;
49  
50      private InheritanceAssembler assembler;
51  
52      @Override
53      protected void setUp()
54          throws Exception
55      {
56          super.setUp();
57  
58          reader = lookup( ModelReader.class );
59          writer = lookup( ModelWriter.class );
60          assembler = lookup( InheritanceAssembler.class );
61      }
62  
63      private File getPom( String name )
64      {
65          return getTestFile( "src/test/resources/poms/inheritance/" + name + ".xml" );
66      }
67  
68      private Model getModel( String name )
69          throws ModelParseException, IOException
70      {
71          return reader.read( getPom( name ), null );
72      }
73  
74      public void testPluginConfiguration()
75          throws Exception
76      {
77          testInheritance( "plugin-configuration" );
78      }
79  
80      /**
81       * Check most classical urls inheritance: directory structure where parent POM in parent directory
82       * and child directory == artifactId
83       * @throws Exception
84       */
85      public void testUrls()
86          throws Exception
87      {
88          testInheritance( "urls" );
89      }
90  
91      /**
92       * Flat directory structure: parent & child POMs in sibling directories, child directory == artifactId.
93       * @throws Exception
94       */
95      public void testFlatUrls()
96          throws Exception
97      {
98          testInheritance( "flat-urls" );
99      }
100 
101     /**
102      * Tricky case: flat directory structure, but child directory != artifactId.
103      * Model interpolation does not give same result when calculated from build or from repo...
104      * This is why MNG-5000 fix in code is marked as bad practice (uses file names)
105      * @throws Exception
106      */
107     public void testFlatTrickyUrls()
108         throws Exception
109     {
110         // parent references child with artifactId (which is not directory name)
111         // then relative path calculation will fail during build from disk but success when calculated from repo
112         try
113         {
114             // build from disk expected to fail
115             testInheritance( "tricky-flat-artifactId-urls", false );
116             //fail( "should have failed since module reference == artifactId != directory name" );
117         }
118         catch ( AssertionFailedError afe )
119         {
120             // expected failure: wrong relative path calculation
121             assertTrue( afe.getMessage(),
122                         afe.getMessage().contains( "http://www.apache.org/path/to/parent/child-artifact-id/" ) );
123         }
124         // but ok from repo: local disk is ignored
125         testInheritance( "tricky-flat-artifactId-urls", true );
126 
127         // parent references child with directory name (which is not artifact id)
128         // then relative path calculation will success during build from disk but failwhen calculated from repo
129         testInheritance( "tricky-flat-directory-urls", false );
130         try
131         {
132             testInheritance( "tricky-flat-directory-urls", true );
133             fail( "should have failed since module reference == directory name != artifactId" );
134         }
135         catch ( AssertionFailedError afe )
136         {
137             // expected failure
138             assertTrue( afe.getMessage(),
139                         afe.getMessage().contains( "http://www.apache.org/path/to/parent/child-artifact-id/" ) );
140         }
141     }
142 
143     public void testWithEmptyUrl() 
144         throws Exception
145     {
146         	testInheritance( "empty-urls", false );
147     }
148     
149     public void testInheritance( String baseName )
150         throws Exception
151     {
152         testInheritance( baseName, false );
153         testInheritance( baseName, true );
154     }
155 
156     public void testInheritance( String baseName, boolean fromRepo )
157         throws Exception
158     {
159         Model parent = getModel( baseName + "-parent" );
160 
161         Model child = getModel( baseName + "-child" );
162 
163         if ( fromRepo )
164         {
165             // when model is read from repo, a stream is used, then pomFile == null
166             // (has consequences in inheritance algorithm since getProjectDirectory() returns null)
167             parent.setPomFile( null );
168             child.setPomFile( null );
169         }
170 
171         SimpleProblemCollector problems = new SimpleProblemCollector();
172 
173         assembler.assembleModelInheritance( child, parent, null, problems );
174 
175         // write baseName + "-actual"
176         File actual = getTestFile( "target/test-classes/poms/inheritance/" + baseName
177             + ( fromRepo ? "-build" : "-repo" ) + "-actual.xml" );
178         writer.write( actual, null, child );
179 
180         // check with getPom( baseName + "-expected" )
181         File expected = getPom( baseName + "-expected" );
182         try ( Reader control = new InputStreamReader( new FileInputStream( expected ), StandardCharsets.UTF_8 );
183               Reader test = new InputStreamReader( new FileInputStream( actual ), StandardCharsets.UTF_8 ) )
184         {
185             XMLUnit.setIgnoreComments( true );
186             XMLUnit.setIgnoreWhitespace( true );
187             XMLAssert.assertXMLEqual( control, test );
188         }
189     }    
190 
191     public void testModulePathNotArtifactId()
192         throws Exception
193     {
194         Model parent = getModel( "module-path-not-artifactId-parent" );
195 
196         Model child = getModel( "module-path-not-artifactId-child" );
197 
198         SimpleProblemCollector problems = new SimpleProblemCollector();
199 
200         assembler.assembleModelInheritance( child, parent, null, problems );
201 
202         File actual = getTestFile( "target/test-classes/poms/inheritance/module-path-not-artifactId-actual.xml" );
203 
204         writer.write( actual, null, child );
205 
206         // check with getPom( "module-path-not-artifactId-effective" )
207         File expected = getPom( "module-path-not-artifactId-expected" );
208         try ( Reader control = new InputStreamReader( new FileInputStream( expected ), StandardCharsets.UTF_8 );
209                         Reader test = new InputStreamReader( new FileInputStream( actual ), StandardCharsets.UTF_8 ) )
210         {
211             XMLUnit.setIgnoreComments( true );
212             XMLUnit.setIgnoreWhitespace( true );
213             XMLAssert.assertXMLEqual( control, test );
214         }
215     }
216 }