View Javadoc

1   package org.apache.maven.plugin.jar;
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 junit.framework.TestCase;
23  import org.apache.maven.model.Model;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.project.MavenProject;
26  import org.codehaus.plexus.util.cli.CommandLineException;
27  import org.codehaus.plexus.util.cli.Commandline;
28  import org.codehaus.plexus.util.cli.StreamConsumer;
29  
30  import java.io.File;
31  import java.io.IOException;
32  import java.io.InputStream;
33  import java.util.ArrayList;
34  import java.util.HashMap;
35  import java.util.List;
36  import java.util.Map;
37  
38  /**
39   * These unit tests only check whether the generated command lines are correct.
40   * Really running the command would mean checking the results, which is too painful and not really a unit test.
41   * It would probably require to 'jarsigner -verify' the resulting signed jar and I believe it would make the code
42   * too complex with very few benefits.
43   *
44   * @author Jerome Lacoste <jerome@coffeebreaks.org>
45   * @version $Id: JarSignMojoTest.java 728546 2008-12-21 22:56:51Z bentmann $
46   */
47  public class JarSignMojoTest
48      extends TestCase
49  {
50      private MockJarSignMojo mojo;
51  
52      static class MockJarSignMojo
53          extends JarSignMojo
54      {
55          public int executeResult;
56  
57          public List commandLines = new ArrayList();
58  
59          public String failureMsg;
60  
61          public Map systemProperties = new HashMap();
62  
63          public JarSignVerifyMojo verifyMojo = new JarSignVerifyMojo();
64  
65          protected int executeCommandLine( Commandline commandLine, InputStream inputStream, StreamConsumer stream1,
66                                            StreamConsumer stream2 )
67              throws CommandLineException
68          {
69              commandLines.add( commandLine );
70              if ( failureMsg != null )
71              {
72                  throw new CommandLineException( failureMsg );
73              }
74              return executeResult;
75          }
76  
77          protected JarSignVerifyMojo createJarSignVerifyMojo()
78          {
79              return verifyMojo;
80          }
81  
82          protected String getSystemProperty( String key )
83          {
84              return (String) systemProperties.get( key );
85          }
86      }
87  
88      public void setUp()
89          throws IOException
90      {
91          mojo = new MockJarSignMojo();
92          mojo.executeResult = 0;
93          // it doesn't really matter if the paths are not cross-platform, we don't execute the command lines anyway
94          File basedir = new File( System.getProperty( "java.io.tmpdir" ) );
95          mojo.setBasedir( basedir );
96          mojo.setWorkingDir( basedir );
97          mojo.setSignedJar( new File( getDummySignedJarPath() ) );
98          mojo.setAlias( "alias" );
99          mojo.setKeystore( "/tmp/keystore" );
100         mojo.setKeypass( "secretpassword" );
101         MavenProject project = new MavenProject( new Model() );
102         MockArtifact mockArtifact = new MockArtifact();
103         mockArtifact.setGroupId( "test" );
104         mockArtifact.setArtifactId( "test" );
105         mockArtifact.setVersion( "1.0" );
106         mockArtifact.setType( "jar" );
107         project.setArtifact( mockArtifact );
108         mojo.setProject( project );
109 
110         new File( getDummyNonSignedJarPath() ).delete();
111     }
112 
113     public void tearDown()
114     {
115         mojo = null;
116     }
117 
118     /**
119      */
120     public void testRunOK()
121         throws MojoExecutionException
122     {
123         JarSignVerifyMojoTest.MockJarSignVerifyMojo mockJarSignVerifyMojo =
124             new JarSignVerifyMojoTest.MockJarSignVerifyMojo();
125         mojo.verifyMojo = mockJarSignVerifyMojo;
126 
127         mojo.execute();
128 
129         String[] expectedArguments = {"-keystore", "/tmp/keystore", "-keypass", "secretpassword", "-signedjar",
130             getDummySignedJarPath(), getDummyNonSignedJarPath(), "alias"};
131 
132         checkMojo( expectedArguments );
133 
134         assertEquals( "sign operation wasn't verified", 0, mockJarSignVerifyMojo.commandLines.size() );
135     }
136 
137     /**
138      */
139     public void testVerifyJarGeneratedBySignOperation()
140         throws MojoExecutionException
141     {
142         JarSignVerifyMojoTest.MockJarSignVerifyMojo mockJarSignVerifyMojo =
143             new JarSignVerifyMojoTest.MockJarSignVerifyMojo();
144         mojo.verifyMojo = mockJarSignVerifyMojo;
145         mojo.setVerify( true );
146         mockJarSignVerifyMojo.lastOutLine = "jar verified.";
147 
148         mojo.execute();
149 
150         String[] expectedArguments = {"-keystore", "/tmp/keystore", "-keypass", "secretpassword", "-signedjar",
151             getDummySignedJarPath(), getDummyNonSignedJarPath(), "alias"};
152 
153         checkMojo( expectedArguments );
154 
155         String[] expectedVerifyArguments = {"-verify", getDummySignedJarPath()};
156 
157         JarSignVerifyMojoTest.checkMojo( mockJarSignVerifyMojo, expectedVerifyArguments );
158     }
159 
160     /**
161      */
162     public void testVerifyInPlaceSignedJar()
163         throws MojoExecutionException
164     {
165         JarSignVerifyMojoTest.MockJarSignVerifyMojo mockJarSignVerifyMojo =
166             new JarSignVerifyMojoTest.MockJarSignVerifyMojo();
167         mojo.verifyMojo = mockJarSignVerifyMojo;
168         mojo.setSignedJar( null );
169         mojo.setVerify( true );
170         mockJarSignVerifyMojo.lastOutLine = "jar verified.";
171 
172         mojo.execute();
173 
174         String[] expectedArguments =
175             {"-keystore", "/tmp/keystore", "-keypass", "secretpassword", getDummyNonSignedJarPath(), "alias"};
176 
177         checkMojo( expectedArguments );
178 
179         String[] expectedVerifyArguments = {"-verify", getDummyNonSignedJarPath()};
180 
181         JarSignVerifyMojoTest.checkMojo( mockJarSignVerifyMojo, expectedVerifyArguments );
182     }
183 
184     /**
185      * We shouldn't sign the jar twice.
186      * On the second run, we simulated a created and signed jar.
187      */
188     public void testRunTwice()
189         throws MojoExecutionException, IOException
190     {
191         mojo.execute();
192 
193         class MyJarSignVerifyMojo
194             extends JarSignVerifyMojo
195         {
196             int nbExecutions;
197 
198             public void execute()
199                 throws MojoExecutionException
200             {
201                 nbExecutions++;
202             }
203 
204             public boolean isSigned()
205             {
206                 return true;
207             }
208         }
209 
210         mojo.verifyMojo = new MyJarSignVerifyMojo();
211 
212         new File( getDummyNonSignedJarPath() ).createNewFile();
213 
214         mojo.execute();
215 
216         String[] expectedArguments = {"-keystore", "/tmp/keystore", "-keypass", "secretpassword", "-signedjar",
217             getDummySignedJarPath(), getDummyNonSignedJarPath(), "alias"};
218 
219         checkMojo( expectedArguments );
220     }
221 
222     /**
223      */
224     public void testRunFailure()
225     {
226         JarSignVerifyMojoTest.MockJarSignVerifyMojo mockJarSignVerifyMojo =
227             new JarSignVerifyMojoTest.MockJarSignVerifyMojo();
228         mojo.verifyMojo = mockJarSignVerifyMojo;
229 
230         mojo.executeResult = 1;
231 
232         // any missing argument should produce this. Let's simulate a missing alias
233         mojo.setAlias( null );
234 
235         try
236         {
237             mojo.execute();
238             fail( "expected failure" );
239         }
240         catch ( MojoExecutionException e )
241         {
242             assertTrue( e.getMessage().startsWith( "Result of " ) );
243         }
244 
245         String[] expectedArguments = {"-keystore", "/tmp/keystore", "-keypass", "secretpassword", "-signedjar",
246             getDummySignedJarPath(), getDummyNonSignedJarPath()};
247 
248         checkMojo( expectedArguments );
249 
250         assertEquals( "sign operation wasn't verified", 0, mockJarSignVerifyMojo.commandLines.size() );
251     }
252 
253     private String getDummySignedJarPath()
254     {
255         return new File(System.getProperty( "java.io.tmpdir" ), "signed.jar").getAbsolutePath();
256     }
257 
258     private String getDummyNonSignedJarPath()
259     {
260         return new File(System.getProperty( "java.io.tmpdir" ), "null.jar").getAbsolutePath();
261     }
262 
263     /**
264      */
265     public void testRunError()
266     {
267         mojo.failureMsg = "simulated failure";
268 
269         try
270         {
271             mojo.execute();
272             fail( "expected failure" );
273         }
274         catch ( MojoExecutionException e )
275         {
276             assertEquals( "command execution failed", e.getMessage() );
277         }
278 
279         String[] expectedArguments = {"-keystore", "/tmp/keystore", "-keypass", "secretpassword", "-signedjar",
280             getDummySignedJarPath(), getDummyNonSignedJarPath(), "alias"};
281 
282         checkMojo( expectedArguments );
283     }
284 
285     private void checkMojo( String[] expectedCommandLineArguments )
286     {
287         assertEquals( 1, mojo.commandLines.size() );
288         Commandline commandline = (Commandline) mojo.commandLines.get( 0 );
289         String[] arguments = commandline.getArguments();
290 
291         assertEquals( "Differing number of arguments", expectedCommandLineArguments.length, arguments.length );
292         for ( int i = 0; i < arguments.length; i++ )
293         {
294             assertEquals( expectedCommandLineArguments[i].replace( '\\', '/' ), arguments[i].replace( '\\', '/' ) );
295         }
296     }
297 }