View Javadoc
1   package org.apache.maven.script.ant;
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 static org.hamcrest.MatcherAssert.assertThat;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  import static org.mockito.Mockito.atLeastOnce;
26  import static org.mockito.Mockito.mock;
27  import static org.mockito.Mockito.verify;
28  import static org.mockito.Mockito.when;
29  import static org.hamcrest.CoreMatchers.endsWith;
30  import static org.hamcrest.CoreMatchers.startsWith;
31  
32  import java.io.ByteArrayOutputStream;
33  import java.io.File;
34  import java.io.IOException;
35  import java.io.InputStreamReader;
36  import java.io.PrintStream;
37  import java.io.Reader;
38  import java.net.URISyntaxException;
39  import java.net.URL;
40  import java.nio.file.Paths;
41  import java.util.ArrayList;
42  import java.util.Collections;
43  import java.util.HashMap;
44  import java.util.List;
45  import java.util.Map;
46  
47  import org.apache.maven.artifact.Artifact;
48  import org.apache.maven.execution.MavenSession;
49  import org.apache.maven.model.Build;
50  import org.apache.maven.model.Model;
51  import org.apache.maven.plugin.MojoExecution;
52  import org.apache.maven.plugin.MojoExecutionException;
53  import org.apache.maven.plugin.descriptor.MojoDescriptor;
54  import org.apache.maven.plugin.descriptor.PluginDescriptor;
55  import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
56  import org.apache.maven.project.MavenProject;
57  import org.apache.maven.project.path.PathTranslator;
58  import org.apache.tools.ant.BuildEvent;
59  import org.apache.tools.ant.BuildListener;
60  import org.codehaus.plexus.archiver.ArchiverException;
61  import org.codehaus.plexus.archiver.jar.JarArchiver;
62  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
63  import org.codehaus.plexus.component.factory.ComponentInstantiationException;
64  import org.codehaus.plexus.component.factory.ant.AntScriptInvoker;
65  import org.codehaus.plexus.component.repository.ComponentRequirement;
66  import org.codehaus.plexus.configuration.PlexusConfigurationException;
67  import org.codehaus.plexus.logging.Logger;
68  import org.codehaus.plexus.logging.console.ConsoleLogger;
69  import org.junit.jupiter.api.BeforeEach;
70  import org.junit.jupiter.api.Test;
71  import org.mockito.ArgumentCaptor;
72  
73  // at least one test class must be public for test-javadoc report
74  public class AntMojoWrapperTest
75  {
76      
77      private BuildListener buildListener;
78  
79      @BeforeEach
80      public void setUp() 
81      {
82          buildListener = mock( BuildListener.class );
83      }
84      
85      @Test
86      void test2xStylePlugin()
87          throws PlexusConfigurationException, IOException, ComponentInstantiationException, MojoExecutionException,
88          ComponentConfigurationException, ArchiverException, URISyntaxException
89      {
90          String pluginXml = "META-INF/maven/plugin-2.1.xml";
91  
92          List<String> messages = run( pluginXml );
93  
94          assertPresence( messages, "Unpacked Ant build scripts (in Maven build directory)." );
95          assertPresence( messages, "Maven parameter expression evaluator for Ant properties." );
96          assertPresence( messages, "Maven standard project-based classpath references." );
97          assertPresence( messages, "Maven standard plugin-based classpath references." );
98          assertPresence( messages, "Maven project, session, mojo-execution, or path-translation parameter information is" );
99          assertPresence( messages, "maven-script-ant < 2.1.0, or used maven-plugin-tools-ant < 2.2 during release" );
100 
101         ArgumentCaptor<BuildEvent> buildEvent = ArgumentCaptor.forClass(BuildEvent.class);
102         verify( buildListener, atLeastOnce() ).messageLogged( buildEvent.capture() );
103 
104         // last message
105         assertThat( buildEvent.getValue().getMessage(), startsWith( "plugin classpath is: " ) );
106         assertThat( buildEvent.getValue().getMessage(), endsWith( ".test.jar" ) );
107     }
108 
109     private void assertPresence( List<String> messages, String test )
110     {
111         assertTrue( messages.stream().noneMatch( s -> s.contains( test ) ),
112                 "Test string: '" + test + "' was found in output, but SHOULD NOT BE THERE." );
113     }
114 
115     private List<String> run( String pluginXml )
116         throws PlexusConfigurationException, IOException, ComponentInstantiationException, MojoExecutionException,
117         ComponentConfigurationException, ArchiverException, URISyntaxException
118     {
119         StackTraceElement stack = new Throwable().getStackTrace()[1];
120         System.out.println( "\n\nRunning: " + stack.getMethodName() + "\n\n" );
121 
122         URL resource = Thread.currentThread().getContextClassLoader().getResource( pluginXml );
123 
124         assertNotNull( resource, "plugin descriptor not found: '" + pluginXml + "'." );
125 
126         PluginDescriptor pd;
127         try ( Reader reader = new InputStreamReader( resource.openStream() ) )
128         {
129             pd = new PluginDescriptorBuilder().build( reader, pluginXml );
130         }
131 
132         Map<String, Object> config = new HashMap<>();
133         config.put( "basedir", new File( "." ).getAbsoluteFile() );
134         config.put( "messageLevel", "info" );
135 
136         MojoDescriptor md = pd.getMojo( "test" );
137 
138         AntMojoWrapper wrapper =
139             new AntMojoWrapper( new AntScriptInvoker( md, Thread.currentThread().getContextClassLoader() ) );
140 
141         wrapper.enableLogging( new ConsoleLogger( Logger.LEVEL_DEBUG, "test" ) );
142 
143         Artifact artifact = mock( Artifact.class );
144         PathTranslator pt = mock( PathTranslator.class );
145 
146         File pluginXmlFile = Paths.get( resource.toURI() ).toFile();
147 
148         File jarFile = File.createTempFile( "AntMojoWrapperTest.", ".test.jar" );
149         jarFile.deleteOnExit();
150 
151         JarArchiver archiver = new JarArchiver();
152         archiver.setDestFile( jarFile );
153         archiver.addFile( pluginXmlFile, pluginXml );
154         archiver.createArchive();
155 
156         when( artifact.getFile() ).thenReturn( jarFile );
157 
158         Model model = new Model();
159 
160         Build build = new Build();
161         build.setDirectory( "target" );
162 
163         model.setBuild( build );
164 
165         MavenProject project = new MavenProject( model );
166         project.setFile( new File( "pom.xml" ).getAbsoluteFile() );
167 
168         pd.setPluginArtifact( artifact );
169         pd.setArtifacts( Collections.singletonList( artifact ) );
170 
171         config.put( "project", project );
172         config.put( "session", new MavenSession( null, null, null, null, null, null, null, null, null, null ) );
173         config.put( "mojoExecution", new MojoExecution( md ) );
174 
175         ComponentRequirement cr = new ComponentRequirement();
176         cr.setRole( PathTranslator.class.getName() );
177 
178         wrapper.addComponentRequirement( cr, pt );
179 
180         wrapper.setComponentConfiguration( config );
181 
182         TestBuildListener tbl = new TestBuildListener();
183         
184         wrapper.getAntProject().addBuildListener( buildListener );
185         
186         PrintStream oldOut = System.out;
187         
188         ByteArrayOutputStream baos = new ByteArrayOutputStream();
189         try
190         {
191             System.setOut( new PrintStream( baos ) );
192 
193             wrapper.execute();
194         }
195         finally
196         {
197             System.setOut( oldOut );
198         }
199 
200         System.out.println( "\n\n" + stack.getMethodName() + " executed; verifying...\n\n" );
201 
202         List<String> messages = new ArrayList<>();
203         if ( !tbl.messages.isEmpty() )
204         {
205             messages.addAll( tbl.messages );
206         }
207         
208         messages.add( baos.toString() );
209         
210         return messages;
211     }
212 
213     private static final class TestBuildListener
214         implements BuildListener
215     {
216         private final List<String> messages = new ArrayList<>();
217 
218         public void buildFinished( BuildEvent arg0 )
219         {
220         }
221 
222         public void buildStarted( BuildEvent arg0 )
223         {
224         }
225 
226         public void messageLogged( BuildEvent event )
227         {
228             messages.add( event.getMessage() );
229         }
230 
231         public void targetFinished( BuildEvent arg0 )
232         {
233         }
234 
235         public void targetStarted( BuildEvent arg0 )
236         {
237         }
238 
239         public void taskFinished( BuildEvent arg0 )
240         {
241         }
242 
243         public void taskStarted( BuildEvent arg0 )
244         {
245         }
246     }
247 }