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