001package org.apache.maven.script.ant; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import static org.hamcrest.MatcherAssert.assertThat; 023import static org.junit.jupiter.api.Assertions.assertNotNull; 024import static org.junit.jupiter.api.Assertions.assertTrue; 025import static org.mockito.Mockito.atLeastOnce; 026import static org.mockito.Mockito.mock; 027import static org.mockito.Mockito.verify; 028import static org.mockito.Mockito.when; 029import static org.hamcrest.CoreMatchers.endsWith; 030import static org.hamcrest.CoreMatchers.startsWith; 031 032import java.io.ByteArrayOutputStream; 033import java.io.File; 034import java.io.IOException; 035import java.io.InputStreamReader; 036import java.io.PrintStream; 037import java.io.Reader; 038import java.net.URISyntaxException; 039import java.net.URL; 040import java.nio.file.Paths; 041import java.util.ArrayList; 042import java.util.Collections; 043import java.util.HashMap; 044import java.util.List; 045import java.util.Map; 046 047import org.apache.maven.artifact.Artifact; 048import org.apache.maven.execution.MavenSession; 049import org.apache.maven.model.Build; 050import org.apache.maven.model.Model; 051import org.apache.maven.plugin.MojoExecution; 052import org.apache.maven.plugin.MojoExecutionException; 053import org.apache.maven.plugin.descriptor.MojoDescriptor; 054import org.apache.maven.plugin.descriptor.PluginDescriptor; 055import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder; 056import org.apache.maven.project.MavenProject; 057import org.apache.maven.project.path.PathTranslator; 058import org.apache.tools.ant.BuildEvent; 059import org.apache.tools.ant.BuildListener; 060import org.codehaus.plexus.archiver.ArchiverException; 061import org.codehaus.plexus.archiver.jar.JarArchiver; 062import org.codehaus.plexus.component.configurator.ComponentConfigurationException; 063import org.codehaus.plexus.component.factory.ComponentInstantiationException; 064import org.codehaus.plexus.component.factory.ant.AntScriptInvoker; 065import org.codehaus.plexus.component.repository.ComponentRequirement; 066import org.codehaus.plexus.configuration.PlexusConfigurationException; 067import org.codehaus.plexus.logging.Logger; 068import org.codehaus.plexus.logging.console.ConsoleLogger; 069import org.junit.jupiter.api.BeforeEach; 070import org.junit.jupiter.api.Test; 071import org.mockito.ArgumentCaptor; 072 073// at least one test class must be public for test-javadoc report 074public class AntMojoWrapperTest 075{ 076 077 private BuildListener buildListener; 078 079 @BeforeEach 080 public void setUp() 081 { 082 buildListener = mock( BuildListener.class ); 083 } 084 085 @Test 086 void test2xStylePlugin() 087 throws PlexusConfigurationException, IOException, ComponentInstantiationException, MojoExecutionException, 088 ComponentConfigurationException, ArchiverException, URISyntaxException 089 { 090 String pluginXml = "META-INF/maven/plugin-2.1.xml"; 091 092 List<String> messages = run( pluginXml ); 093 094 assertPresence( messages, "Unpacked Ant build scripts (in Maven build directory)." ); 095 assertPresence( messages, "Maven parameter expression evaluator for Ant properties." ); 096 assertPresence( messages, "Maven standard project-based classpath references." ); 097 assertPresence( messages, "Maven standard plugin-based classpath references." ); 098 assertPresence( messages, "Maven project, session, mojo-execution, or path-translation parameter information is" ); 099 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}