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.plugin.eclipse;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.lang.reflect.Field;
24  import java.net.URL;
25  import java.util.Collections;
26  
27  import junit.framework.Assert;
28  import junit.framework.TestCase;
29  
30  import org.apache.maven.artifact.Artifact;
31  import org.apache.maven.artifact.DefaultArtifact;
32  import org.apache.maven.artifact.repository.ArtifactRepository;
33  import org.apache.maven.artifact.versioning.VersionRange;
34  import org.apache.maven.model.Model;
35  import org.apache.maven.plugin.MojoExecutionException;
36  import org.apache.maven.plugin.MojoFailureException;
37  import org.apache.maven.plugin.logging.Log;
38  import org.apache.maven.plugin.logging.SystemStreamLog;
39  import org.apache.maven.project.MavenProject;
40  import org.apache.maven.project.MavenProjectBuilder;
41  import org.apache.maven.project.ProjectBuildingException;
42  import org.apache.maven.shared.osgi.DefaultMaven2OsgiConverter;
43  import org.apache.maven.shared.osgi.Maven2OsgiConverter;
44  import org.apache.maven.shared.tools.easymock.MockManager;
45  import org.apache.maven.shared.tools.easymock.TestFileManager;
46  import org.codehaus.plexus.archiver.manager.ArchiverManager;
47  import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
48  import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
49  import org.codehaus.plexus.components.interactivity.InputHandler;
50  import org.codehaus.plexus.logging.console.ConsoleLogger;
51  import org.easymock.MockControl;
52  
53  public class InstallPluginsMojoTest
54      extends TestCase
55  {
56      private static final String TEST_M2_REPO = "m2repo/eclipseinstall/";
57  
58      private static Artifact ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME;
59  
60      private TestFileManager fileManager;
61  
62      private MockManager mm = new MockManager();
63  
64      private File eclipseDir;
65  
66      private File pluginsDir;
67  
68      private Maven2OsgiConverter maven2OsgiConverter = new DefaultMaven2OsgiConverter();
69  
70      /**
71       * Has both Bundle-Name and Bundle-SymbolicName and should be installed.
72       * 
73       * @throws MojoExecutionException
74       * @throws MojoFailureException
75       */
76      public void testJira_MECLIPSE_418_correct_bundle_headers()
77          throws MojoExecutionException, MojoFailureException
78      {
79          Artifact artifact = createArtifact( "jira.meclipse_418", "correct_bundle_headers", "1" );
80  
81          performTestInstall( null, false, artifact, "eclipse-plugin" );
82  
83          assertInstalledFileExists( artifact );
84          assertInstalledDirDoesNotExist( artifact );
85  
86          mm.verifyAll();
87      }
88  
89      /**
90       * Has Bundle-SymbolicName but no Bundle-Name and should be installed.
91       * 
92       * @throws MojoExecutionException
93       * @throws MojoFailureException
94       */
95      public void testJira_MECLIPSE_418_no_bundle_name()
96          throws MojoExecutionException, MojoFailureException
97      {
98          Artifact artifact = createArtifact( "jira.meclipse_418", "no_bundle_name", "1" );
99  
100         performTestInstall( null, false, artifact, "eclipse-plugin" );
101 
102         assertInstalledFileExists( artifact );
103         assertInstalledDirDoesNotExist( artifact );
104 
105         mm.verifyAll();
106     }
107 
108     /**
109      * Has Bundle-Name but no Bundle-SymbolicName and should be installed.
110      * 
111      * @throws MojoExecutionException
112      * @throws MojoFailureException
113      */
114     public void testJira_MECLIPSE_418_no_bundle_symbolicname()
115         throws MojoExecutionException, MojoFailureException
116     {
117         Artifact artifact = createArtifact( "jira.meclipse_418", "no_bundle_symbolicname", "1" );
118 
119         performTestInstall( null, false, artifact, "eclipse-plugin" );
120 
121         assertInstalledFileExists( artifact );
122         assertInstalledDirDoesNotExist( artifact );
123 
124         mm.verifyAll();
125     }
126 
127     /**
128      * Has neither Bundle-Name or Bundle-SymbolicName and should NOT be installed.
129      * 
130      * @throws MojoExecutionException
131      * @throws MojoFailureException
132      */
133     public void testJira_MECLIPSE_418_no_manifest_headers()
134         throws MojoExecutionException, MojoFailureException
135     {
136         Artifact artifact = createArtifact( "jira.meclipse_418", "no_manifest_headers", "1" );
137 
138         performTestInstall( null, false, artifact, "eclipse-plugin" );
139 
140         assertInstalledFileDoesNotExist( artifact );
141         assertInstalledDirDoesNotExist( artifact );
142 
143         mm.verifyAll();
144     }
145 
146     /**
147      * if a jar has no manifest, do not install plugin.
148      * 
149      * @throws MojoExecutionException
150      * @throws MojoFailureException
151      */
152     public void testJira_MECLIPSE_488()
153         throws MojoExecutionException, MojoFailureException
154     {
155         Artifact jira488_missingManifest = createArtifact( "jira", "meclipse_488", "1" );
156 
157         performTestInstall( null, false, jira488_missingManifest, "eclipse-plugin" );
158 
159         assertInstalledFileDoesNotExist( jira488_missingManifest );
160         assertInstalledDirDoesNotExist( jira488_missingManifest );
161 
162         mm.verifyAll();
163     }
164 
165     public void testShouldInstallAsJarWhenPropertyNotSpecified()
166         throws MojoExecutionException, MojoFailureException
167     {
168         performTestInstall( null, false, ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME, "eclipse-plugin" );
169 
170         assertInstalledFileExists( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
171         assertInstalledDirDoesNotExist( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
172 
173         mm.verifyAll();
174     }
175 
176     public void testShouldInstallAsJarWhenPropertyIsTrue()
177         throws MojoExecutionException, MojoFailureException
178     {
179         performTestInstall( Boolean.TRUE, false, ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME, "eclipse-plugin" );
180 
181         assertInstalledFileExists( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
182         assertInstalledDirDoesNotExist( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
183 
184         mm.verifyAll();
185     }
186 
187     public void testShouldInstallAsDirWhenPropertyIsFalse()
188         throws MojoExecutionException, MojoFailureException
189     {
190         performTestInstall( Boolean.FALSE, false, ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME, "eclipse-plugin" );
191 
192         assertInstalledFileDoesNotExist( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
193         assertInstalledDirExists( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
194 
195         mm.verifyAll();
196     }
197 
198     public void testShouldInstallWhenTypeContainedInPluginTypesListWithMultipleValues()
199         throws MojoExecutionException, MojoFailureException
200     {
201         performTestInstall( null, false, ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME, "osgi-bundle,eclipse-plugin" );
202 
203         assertInstalledFileExists( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
204         assertInstalledDirDoesNotExist( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
205 
206         mm.verifyAll();
207     }
208 
209     public void testShouldNotInstallWhenTypeNotContainedInPluginTypesList()
210         throws MojoExecutionException, MojoFailureException
211     {
212         performTestInstall( null, false, ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME, "type-not-in-this-list" );
213 
214         assertInstalledFileDoesNotExist( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
215         assertInstalledDirDoesNotExist( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
216 
217         mm.verifyAll();
218     }
219 
220     public void testShouldRemoveOldDirectoryBeforeInstallingNewJarWhenOverwriteIsFalse()
221         throws MojoExecutionException, MojoFailureException
222     {
223         createPluginsDir();
224 
225         File installedDir = locateInstalledDir( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
226         installedDir.mkdir();
227         assertInstalledDirExists( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
228 
229         performTestInstall( Boolean.FALSE, true, ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME, "eclipse-plugin" );
230 
231         assertInstalledFileDoesNotExist( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
232         assertInstalledDirExists( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
233 
234         mm.verifyAll();
235     }
236 
237     public void testShouldRemoveOldDirectoryBeforeInstallingNewJarWhenOverwriteIsTrue()
238         throws MojoExecutionException, MojoFailureException
239     {
240         createPluginsDir();
241 
242         File installedDir = locateInstalledDir( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
243         installedDir.mkdir();
244         assertInstalledDirExists( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
245 
246         performTestInstall( null, true, ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME, "eclipse-plugin" );
247 
248         assertInstalledFileExists( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
249         assertInstalledDirDoesNotExist( ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME );
250 
251         mm.verifyAll();
252     }
253 
254     private void assertInstalledFileDoesNotExist( Artifact artifact )
255     {
256         File installedFile = locateInstalledFile( artifact );
257 
258         assertFalse( installedFile + " should not exist.", installedFile.exists() );
259     }
260 
261     private void assertInstalledFileExists( Artifact artifact )
262     {
263         File installedFile = locateInstalledFile( artifact );
264 
265         assertTrue( installedFile + " should exist.", installedFile.exists() );
266     }
267 
268     private void assertInstalledDirDoesNotExist( Artifact artifact )
269     {
270         File installedFile = locateInstalledDir( artifact );
271 
272         assertFalse( installedFile + " should not exist.", installedFile.exists() );
273     }
274 
275     private void assertInstalledDirExists( Artifact artifact )
276     {
277         File installedFile = locateInstalledDir( artifact );
278 
279         assertTrue( installedFile + " should exist.", installedFile.exists() );
280     }
281 
282     public void setUp()
283     {
284         fileManager = new TestFileManager( "InstallPluginsMojo.test.", "" );
285 
286         ARTIFACT_ORG_ECLIPSE_CORE_RUNTIME = createArtifact( "org.eclipse.core", "runtime", "3.2.0-v20060603" );
287     }
288 
289     private File locateArtifact( Artifact artifact )
290     {
291         URL resource;
292 
293         String sourcepath =
294             artifact.getGroupId().replace( '.', '/' ) + "/" + artifact.getArtifactId() + "/" + artifact.getVersion()
295                 + "/" + artifact.getArtifactId() + "-" + artifact.getVersion() + ".jar";
296 
297         resource = Thread.currentThread().getContextClassLoader().getResource( TEST_M2_REPO + sourcepath );
298 
299         if ( resource == null )
300         {
301             throw new IllegalStateException( "Cannot find test source jar: " + TEST_M2_REPO + sourcepath
302                 + " in context classloader!" );
303         }
304         return new File( resource.getPath() );
305     }
306 
307     public void tearDown()
308         throws IOException
309     {
310         fileManager.cleanUp();
311     }
312 
313     private void performTestInstall( Boolean installAsJar, boolean overwrite, Artifact artifact, String typeList )
314         throws MojoExecutionException, MojoFailureException
315     {
316         createPluginsDir();
317 
318         String type = artifact.getType();
319 
320         ArtifactRepository localRepo = createLocalRepository();
321         MavenProjectBuilder projectBuilder = createProjectBuilder(typeList.contains(type), installAsJar );
322         ArchiverManager archiverManager = createArchiverManager(typeList.contains(type), installAsJar );
323         InputHandler inputHandler = createInputHandler();
324 
325         Log log = new SystemStreamLog();
326 
327         mm.replayAll();
328 
329         InstallPluginsMojo mojo =
330             new InstallPluginsMojo( eclipseDir, overwrite, Collections.singletonList( artifact ), typeList, localRepo,
331                                     projectBuilder, archiverManager, inputHandler, log );
332         try
333         {
334             Field field = InstallPluginsMojo.class.getDeclaredField( "maven2OsgiConverter" );
335             field.setAccessible( true );
336             field.set( mojo, new DefaultMaven2OsgiConverter() );
337         }
338         catch ( Exception e )
339         {
340             throw new MojoExecutionException( "Unable to configure maven2OsgiConverter", e );
341         }
342 
343         mojo.execute();
344     }
345 
346     private File createPluginsDir()
347     {
348         if ( eclipseDir == null )
349         {
350             eclipseDir = fileManager.createTempDir();
351         }
352 
353         if ( pluginsDir == null )
354         {
355             pluginsDir = new File( eclipseDir, "plugins" );
356 
357             pluginsDir.mkdir();
358         }
359 
360         return pluginsDir;
361     }
362 
363     private InputHandler createInputHandler()
364     {
365         MockControl control = MockControl.createControl( InputHandler.class );
366 
367         mm.add( control );
368 
369         InputHandler handler = (InputHandler) control.getMock();
370 
371         return handler;
372     }
373 
374     private ArchiverManager createArchiverManager( boolean isReachable, Boolean installAsJar )
375     {
376         MockControl control = MockControl.createControl( ArchiverManager.class );
377 
378         mm.add( control );
379 
380         ArchiverManager manager = (ArchiverManager) control.getMock();
381 
382         if ( isReachable && installAsJar == Boolean.FALSE )
383         {
384             try
385             {
386                 manager.getUnArchiver( (File) null );
387                 control.setMatcher( MockControl.ALWAYS_MATCHER );
388                 ZipUnArchiver zipUnArchiver = new ZipUnArchiver();
389                 zipUnArchiver.enableLogging( new ConsoleLogger( org.codehaus.plexus.logging.Logger.LEVEL_INFO,
390                                                                 "console" ) );
391                 control.setReturnValue( zipUnArchiver, MockControl.ONE_OR_MORE );
392             }
393             catch ( NoSuchArchiverException e )
394             {
395                 Assert.fail( "Should never happen." );
396             }
397         }
398 
399         return manager;
400     }
401 
402     private MavenProjectBuilder createProjectBuilder( boolean expectBuildFromRepository, Boolean installAsJar )
403     {
404         MockControl control = MockControl.createControl( MavenProjectBuilder.class );
405 
406         mm.add( control );
407 
408         MavenProjectBuilder projectBuilder = (MavenProjectBuilder) control.getMock();
409 
410         if ( expectBuildFromRepository )
411         {
412             try
413             {
414                 Model model = new Model();
415 
416                 if ( installAsJar != null )
417                 {
418                     model.addProperty( InstallPluginsMojo.PROP_UNPACK_PLUGIN, "" + ( !installAsJar) );
419                 }
420 
421                 MavenProject project = new MavenProject( model );
422 
423                 projectBuilder.buildFromRepository( null, null, null, true );
424                 control.setMatcher( MockControl.ALWAYS_MATCHER );
425                 control.setReturnValue( project, MockControl.ONE_OR_MORE );
426             }
427             catch ( ProjectBuildingException e )
428             {
429                 Assert.fail( "should never happen." );
430             }
431         }
432 
433         return projectBuilder;
434     }
435 
436     private ArtifactRepository createLocalRepository()
437     {
438         MockControl control = MockControl.createControl( ArtifactRepository.class );
439 
440         mm.add( control );
441 
442         ArtifactRepository repo = (ArtifactRepository) control.getMock();
443 
444         return repo;
445     }
446 
447     /**
448      * @param groupId
449      * @param artifactId
450      * @param version
451      * @return an artifact with the specified values and configured for testing to the local m2repo
452      */
453     private Artifact createArtifact( String groupId, String artifactId, String version )
454     {
455         Artifact artifact =
456             new DefaultArtifact( groupId, artifactId, VersionRange.createFromVersion( version ), "scope-unused",
457                                  "eclipse-plugin", "classifier-unused", null );
458         artifact.setFile( locateArtifact( artifact ) );
459 
460         return artifact;
461     }
462 
463     /**
464      * Copied from {@link InstallPluginsMojo#formatEclipsePluginName}
465      */
466     private String formatEclipsePluginName( Artifact artifact )
467     {
468         return maven2OsgiConverter.getBundleSymbolicName( artifact ) + "_"
469             + maven2OsgiConverter.getVersion( artifact.getVersion() );
470     }
471 
472     /**
473      * @param artifact
474      * @return the installed directory for the plugin (because it is an unpacked bundle)
475      */
476     private File locateInstalledDir( Artifact artifact )
477     {
478         return new File( pluginsDir, formatEclipsePluginName( artifact ) );
479     }
480 
481     /**
482      * @param artifact
483      * @return the installed file for the plugin bundle
484      */
485     private File locateInstalledFile( Artifact artifact )
486     {
487         return new File( pluginsDir, formatEclipsePluginName( artifact ) + ".jar" );
488     }
489 }