1 package org.apache.maven.plugin.surefire.booterclient;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.net.URI;
24 import java.net.URISyntaxException;
25 import java.net.URLDecoder;
26 import java.nio.charset.Charset;
27 import java.nio.file.Path;
28
29 import org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.ClasspathElementUri;
30 import org.apache.maven.plugin.surefire.booterclient.output.InPluginProcessDumpSingleton;
31
32 import static java.nio.charset.StandardCharsets.UTF_8;
33 import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.relativize;
34 import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.toAbsoluteUri;
35 import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.toClasspathElementUri;
36 import static org.apache.maven.plugin.surefire.booterclient.JarManifestForkConfiguration.escapeUri;
37 import static org.fest.assertions.Assertions.assertThat;
38
39 import org.junit.AfterClass;
40 import org.junit.BeforeClass;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43
44 import static org.fest.util.Files.delete;
45 import static org.fest.util.Files.newTemporaryFolder;
46 import static org.mockito.ArgumentMatchers.any;
47 import static org.mockito.ArgumentMatchers.anyBoolean;
48 import static org.mockito.ArgumentMatchers.anyString;
49 import static org.mockito.ArgumentMatchers.same;
50 import static org.powermock.api.mockito.PowerMockito.mock;
51 import static org.powermock.api.mockito.PowerMockito.mockStatic;
52 import static org.powermock.api.mockito.PowerMockito.when;
53
54 import org.mockito.invocation.InvocationOnMock;
55 import org.mockito.stubbing.Answer;
56 import org.powermock.core.classloader.annotations.PowerMockIgnore;
57 import org.powermock.core.classloader.annotations.PrepareForTest;
58 import org.powermock.modules.junit4.PowerMockRunner;
59
60
61
62
63 @RunWith( PowerMockRunner.class )
64 @PrepareForTest( { JarManifestForkConfiguration.class, InPluginProcessDumpSingleton.class } )
65 @PowerMockIgnore( { "org.jacoco.agent.rt.*", "com.vladium.emma.rt.*" } )
66 public class JarManifestForkConfigurationTest
67 {
68 private static final File TMP = newTemporaryFolder();
69
70 private static File dumpDirectory;
71
72 @BeforeClass
73 public static void createSystemTemporaryDir()
74 {
75 dumpDirectory = new File( TMP, "dump" );
76 assertThat( dumpDirectory.mkdir() )
77 .isTrue();
78 }
79
80 @AfterClass
81 public static void deleteSystemTemporaryDir()
82 {
83 delete( TMP );
84 }
85
86 @Test
87 public void relativeClasspathUnixSimple()
88 throws Exception
89 {
90 mockStatic( JarManifestForkConfiguration.class );
91 Path parent = mock( Path.class );
92 when( parent.toString() ).thenReturn( "/home/me/prj/target/surefire" );
93 Path classPathElement = mock( Path.class );
94 when( classPathElement.toString() ).thenReturn( "/home/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
95 when( relativize( parent, classPathElement ) )
96 .thenReturn( "../../../.m2/repository/grp/art/1.0/art-1.0.jar" );
97 when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
98 .thenCallRealMethod();
99 when( escapeUri( anyString(), any( Charset.class ) ) )
100 .thenCallRealMethod();
101 assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
102 .isEqualTo( "../../../.m2/repository/grp/art/1.0/art-1.0.jar" );
103 }
104
105 @Test
106 public void relativeClasspathUnixTricky()
107 throws Exception
108 {
109 mockStatic( JarManifestForkConfiguration.class );
110 Path parent = mock( Path.class );
111 when( parent.toString() ).thenReturn( "/home/me/prj/target/surefire" );
112 Path classPathElement = mock( Path.class );
113 when( classPathElement.toString() ).thenReturn( "/the Maven repo/grp/art/1.0/art-1.0.jar" );
114 when( relativize( parent, classPathElement ) )
115 .thenReturn( "../../../../../the Maven repo/grp/art/1.0/art-1.0.jar" );
116 when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
117 .thenCallRealMethod();
118 when( escapeUri( anyString(), any( Charset.class ) ) )
119 .thenCallRealMethod();
120 assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
121 .isEqualTo( "../../../../../the%20Maven%20repo/grp/art/1.0/art-1.0.jar" );
122 }
123
124 @Test
125 public void relativeClasspathWindowsSimple()
126 throws Exception
127 {
128 mockStatic( JarManifestForkConfiguration.class );
129 Path parent = mock( Path.class );
130 when( parent.toString() ).thenReturn( "C:\\Windows\\Temp\\surefire" );
131 Path classPathElement = mock( Path.class );
132 when( classPathElement.toString() ).thenReturn( "C:\\Users\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar" );
133 when( relativize( parent, classPathElement ) )
134 .thenReturn( "..\\..\\..\\Users\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar" );
135 when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
136 .thenCallRealMethod();
137 when( escapeUri( anyString(), any( Charset.class ) ) )
138 .thenCallRealMethod();
139 assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
140 .isEqualTo( "../../../Users/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
141 }
142
143 @Test
144 public void relativeClasspathWindowsTricky()
145 throws Exception
146 {
147 mockStatic( JarManifestForkConfiguration.class );
148 Path parent = mock( Path.class );
149 when( parent.toString() ).thenReturn( "C:\\Windows\\Temp\\surefire" );
150 Path classPathElement = mock( Path.class );
151 when( classPathElement.toString() )
152 .thenReturn( "C:\\Test User\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar" );
153 when( relativize( parent, classPathElement ) )
154 .thenReturn( "..\\..\\..\\Test User\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar" );
155 when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
156 .thenCallRealMethod();
157 when( escapeUri( anyString(), any( Charset.class ) ) )
158 .thenCallRealMethod();
159 assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
160 .isEqualTo( "../../../Test%20User/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
161 }
162
163 @Test
164 public void crossDriveWindows()
165 throws Exception
166 {
167 mockStatic( JarManifestForkConfiguration.class );
168 mockStatic( InPluginProcessDumpSingleton.class );
169 when( InPluginProcessDumpSingleton.getSingleton() ).thenReturn( mock( InPluginProcessDumpSingleton.class ) );
170 Path parent = mock( Path.class );
171 when( parent.toString() ).thenReturn( "C:\\Windows\\Temp\\surefire" );
172 Path classPathElement = mock( Path.class );
173 when( classPathElement.toString() ).thenReturn( "X:\\Users\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar" );
174 when( classPathElement.toUri() )
175 .thenAnswer( new Answer<URI>()
176 {
177 @Override
178 public URI answer( InvocationOnMock invocation ) throws URISyntaxException
179 {
180 String path = invocation.getMock().toString();
181 return new URI( "file", "", "/" + path.replace( '\\', '/' ), null );
182 }
183 } );
184 when( relativize( same( parent ), same( classPathElement ) ) )
185 .thenThrow( new IllegalArgumentException() );
186 when( toClasspathElementUri( same( parent ), same( classPathElement ), same( dumpDirectory ), anyBoolean() ) )
187 .thenCallRealMethod();
188 when( escapeUri( anyString(), any( Charset.class ) ) )
189 .thenCallRealMethod();
190 when( toAbsoluteUri( same( classPathElement ) ) )
191 .thenCallRealMethod();
192 assertThat( toClasspathElementUri( parent, classPathElement, dumpDirectory, true ).uri )
193 .isEqualTo( "file:///X:/Users/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
194 }
195
196 @Test
197 @SuppressWarnings( "checkstyle:magicnumber" )
198 public void shouldEscapeUri()
199 throws Exception
200 {
201 assertThat( escapeUri( "a", UTF_8 ) ).isEqualTo( "a" );
202 assertThat( escapeUri( " ", UTF_8 ) ).isEqualTo( "%20" );
203 assertThat( escapeUri( "%", UTF_8 ) ).isEqualTo( "%25" );
204 assertThat( escapeUri( "+", UTF_8 ) ).isEqualTo( "%2B" );
205 assertThat( escapeUri( ",", UTF_8 ) ).isEqualTo( "%2C" );
206 assertThat( escapeUri( "/", UTF_8 ) ).isEqualTo( "/" );
207 assertThat( escapeUri( "7", UTF_8 ) ).isEqualTo( "7" );
208 assertThat( escapeUri( ":", UTF_8 ) ).isEqualTo( "%3A" );
209 assertThat( escapeUri( "@", UTF_8 ) ).isEqualTo( "%40" );
210 assertThat( escapeUri( "A", UTF_8 ) ).isEqualTo( "A" );
211 assertThat( escapeUri( "[", UTF_8 ) ).isEqualTo( "%5B" );
212 assertThat( escapeUri( "\\", UTF_8 ) ).isEqualTo( "/" );
213 assertThat( escapeUri( "]", UTF_8 ) ).isEqualTo( "%5D" );
214 assertThat( escapeUri( "`", UTF_8 ) ).isEqualTo( "%60" );
215 assertThat( escapeUri( "a", UTF_8 ) ).isEqualTo( "a" );
216 assertThat( escapeUri( "{", UTF_8 ) ).isEqualTo( "%7B" );
217 assertThat( escapeUri( "" + (char) 0xFF, UTF_8 ) ).isEqualTo( "%C3%BF" );
218
219 assertThat( escapeUri( "..\\..\\..\\Test : User\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar",
220 UTF_8 ) )
221 .isEqualTo( "../../../Test%20%3A%20User/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
222
223 assertThat( escapeUri( "..\\..\\..\\Test : User\\me\\.m2\\repository\\grp\\art\\1.0\\art-1.0.jar",
224 Charset.defaultCharset() ) )
225 .isEqualTo( "../../../Test%20%3A%20User/me/.m2/repository/grp/art/1.0/art-1.0.jar" );
226
227 assertThat( escapeUri( "../../surefire-its/target/junit-pathWithÜmlaut_1/target/surefire", UTF_8 ) )
228 .isEqualTo( "../../surefire-its/target/junit-pathWith%C3%9Cmlaut_1/target/surefire" );
229
230 String source = "../../surefire-its/target/junit-pathWithÜmlaut_1/target/surefire";
231 String encoded = escapeUri( "../../surefire-its/target/junit-pathWithÜmlaut_1/target/surefire", UTF_8 );
232 String decoded = URLDecoder.decode( encoded, UTF_8.name() );
233 assertThat( decoded )
234 .isEqualTo( source );
235 }
236
237 @Test
238 public void shouldRelativizeOnRealPlatform()
239 {
240 Path parentDir = new File( TMP, "test-parent-1" )
241 .toPath();
242
243 Path testDir = new File( TMP, "@1 test with white spaces" )
244 .toPath();
245
246 String relativeTestDir = relativize( parentDir, testDir );
247
248 assertThat( relativeTestDir )
249 .isEqualTo( ".." + File.separator + "@1 test with white spaces" );
250 }
251
252 @Test
253 public void shouldMakeAbsoluteUriOnRealPlatform()
254 throws Exception
255 {
256 Path testDir = new File( TMP, "@2 test with white spaces" )
257 .toPath();
258
259 URI testDirUri = new URI( toAbsoluteUri( testDir ) );
260
261 assertThat( testDirUri.getScheme() )
262 .isEqualTo( "file" );
263
264 assertThat( testDirUri.getRawPath() )
265 .isEqualTo( testDir.toUri().getRawPath() );
266 }
267
268 @Test
269 public void shouldMakeRelativeUriOnRealPlatform()
270 throws Exception
271 {
272 Path parentDir = new File( TMP, "test-parent-2" )
273 .toPath();
274
275 Path testDir = new File( TMP, "@3 test with white spaces" )
276 .toPath();
277
278 ClasspathElementUri testDirUriPath = toClasspathElementUri( parentDir, testDir, dumpDirectory, true );
279
280 assertThat( testDirUriPath.uri )
281 .isEqualTo( "../%403%20test%20with%20white%20spaces" );
282 }
283 }