1 package org.apache.maven.plugin.surefire;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.artifact.Artifact;
23 import org.apache.maven.artifact.DefaultArtifact;
24 import org.apache.maven.artifact.handler.ArtifactHandler;
25 import org.apache.maven.artifact.versioning.VersionRange;
26 import org.apache.maven.plugin.surefire.log.PluginConsoleLogger;
27 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
28 import org.apache.maven.surefire.booter.Classpath;
29 import org.apache.maven.surefire.booter.ModularClasspathConfiguration;
30 import org.apache.maven.surefire.booter.StartupConfiguration;
31 import org.apache.maven.surefire.suite.RunResult;
32 import org.apache.maven.surefire.util.DefaultScanResult;
33 import org.codehaus.plexus.languages.java.jpms.LocationManager;
34 import org.codehaus.plexus.languages.java.jpms.ResolvePathsRequest;
35 import org.codehaus.plexus.languages.java.jpms.ResolvePathsResult;
36 import org.codehaus.plexus.languages.java.jpms.ModuleNameSource;
37 import org.codehaus.plexus.logging.Logger;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.mockito.ArgumentCaptor;
41 import org.mockito.Mock;
42 import org.powermock.core.classloader.annotations.PrepareForTest;
43 import org.powermock.modules.junit4.PowerMockRunner;
44
45 import java.io.File;
46 import java.util.LinkedHashMap;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.Set;
50
51 import static java.util.Arrays.asList;
52 import static java.util.Collections.singleton;
53 import static java.util.Collections.singletonMap;
54 import static org.apache.maven.artifact.versioning.VersionRange.createFromVersion;
55 import static org.fest.assertions.Assertions.assertThat;
56 import static org.mockito.ArgumentMatchers.anyString;
57 import static org.mockito.ArgumentMatchers.eq;
58 import static org.mockito.Mockito.times;
59 import static org.mockito.Mockito.verify;
60 import static org.mockito.Mockito.when;
61 import static org.powermock.api.mockito.PowerMockito.doReturn;
62 import static org.powermock.api.mockito.PowerMockito.doNothing;
63 import static org.powermock.api.mockito.PowerMockito.mock;
64 import static org.powermock.api.mockito.PowerMockito.mockStatic;
65 import static org.powermock.api.mockito.PowerMockito.spy;
66 import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
67 import static org.powermock.api.mockito.PowerMockito.verifyStatic;
68 import static org.powermock.reflect.Whitebox.invokeMethod;
69
70
71
72
73 @RunWith( PowerMockRunner.class )
74 @PrepareForTest( { AbstractSurefireMojo.class, ResolvePathsRequest.class } )
75 public class AbstractSurefireMojoJava7PlusTest
76 {
77 @Mock
78 private ArtifactHandler handler;
79
80 @Mock
81 private LocationManager locationManager;
82
83 @Test
84 public void shouldHaveStartupConfigForModularClasspath()
85 throws Exception
86 {
87 AbstractSurefireMojo mojo = spy( new Mojo() );
88 doReturn( locationManager )
89 .when( mojo, "getLocationManager" );
90
91 when( handler.isAddedToClasspath() ).thenReturn( true );
92
93 VersionRange v1 = createFromVersion( "1" );
94 Artifact modular = new DefaultArtifact( "x", "modular", v1, "compile", "jar", "", handler );
95 modular.setFile( mockFile( "modular.jar" ) );
96
97 VersionRange v2 = createFromVersion( "1" );
98 Artifact nonModular = new DefaultArtifact( "x", "non-modular", v2, "test", "jar", "", handler );
99 nonModular.setFile( mockFile( "non-modular.jar" ) );
100
101 VersionRange v3 = createFromVersion( "4.12" );
102 Artifact junit = new DefaultArtifact( "junit", "junit", v3, "test", "jar", "", handler );
103 junit.setFile( mockFile( "junit.jar" ) );
104
105 VersionRange v4 = createFromVersion( "1.3.0" );
106 Artifact hamcrest = new DefaultArtifact( "org.hamcrest", "hamcrest-core", v4, "test", "jar", "", handler );
107 hamcrest.setFile( mockFile( "hamcrest.jar" ) );
108
109 File classesDir = mockFile( "classes" );
110 File testClassesDir = mockFile( "test-classes" );
111
112 TestClassPath testClasspath =
113 new TestClassPath( asList( modular, nonModular, junit, hamcrest ), classesDir, testClassesDir,
114 null, null );
115
116 doReturn( testClasspath ).when( mojo, "generateTestClasspath" );
117 doReturn( 1 ).when( mojo, "getEffectiveForkCount" );
118 doReturn( true ).when( mojo, "effectiveIsEnableAssertions" );
119 when( mojo.isChildDelegation() ).thenReturn( false );
120 when( mojo.getTestClassesDirectory() ).thenReturn( testClassesDir );
121
122 DefaultScanResult scanResult = mock( DefaultScanResult.class );
123 when( scanResult.getClasses() ).thenReturn( asList( "org.apache.A", "org.apache.B" ) );
124
125 ClassLoaderConfiguration classLoaderConfiguration = new ClassLoaderConfiguration( false, true );
126
127 VersionRange v5 = createFromVersion( "1" );
128 Artifact provider = new DefaultArtifact( "org.apache.maven.surefire", "surefire-provider", v5, "runtime",
129 "jar", "", handler );
130 provider.setFile( mockFile( "surefire-provider.jar" ) );
131 Set<Artifact> providerClasspath = singleton( provider );
132
133 File moduleInfo = mockFile( "classes/module-info.class" );
134
135 @SuppressWarnings( "unchecked" )
136 ResolvePathsRequest<String> req = mock( ResolvePathsRequest.class );
137 mockStatic( ResolvePathsRequest.class );
138 when( ResolvePathsRequest.ofStrings( eq( testClasspath.toClasspath().getClassPath() ) ) ).thenReturn( req );
139 when( req.setJdkHome( anyString() ) ).thenReturn( req );
140 when( req.setMainModuleDescriptor( eq( moduleInfo.getAbsolutePath() ) ) ).thenReturn( req );
141
142 @SuppressWarnings( "unchecked" )
143 ResolvePathsResult<String> res = mock( ResolvePathsResult.class );
144 when( res.getClasspathElements() ).thenReturn( asList( "non-modular.jar", "junit.jar", "hamcrest.jar" ) );
145 Map<String, ModuleNameSource> mod = new LinkedHashMap<>();
146 mod.put( "modular.jar", null );
147 mod.put( "classes", null );
148 when( res.getModulepathElements() ).thenReturn( mod );
149 when( res.getPathExceptions() ).thenReturn( singletonMap( "java 1.8", new Exception( "low version" ) ) );
150 when( locationManager.resolvePaths( eq( req ) ) ).thenReturn( res );
151
152 Logger logger = mock( Logger.class );
153 when( logger.isDebugEnabled() ).thenReturn( true );
154 doNothing().when( logger ).debug( anyString() );
155 when( mojo.getConsoleLogger() ).thenReturn( new PluginConsoleLogger( logger ) );
156
157 StartupConfiguration conf = invokeMethod( mojo, "newStartupConfigWithModularPath",
158 classLoaderConfiguration, providerClasspath, "org.asf.Provider", moduleInfo, scanResult,
159 "" );
160
161 verify( mojo, times( 1 ) ).effectiveIsEnableAssertions();
162 verify( mojo, times( 1 ) ).isChildDelegation();
163 verifyPrivate( mojo, times( 1 ) ).invoke( "generateTestClasspath" );
164 verify( mojo, times( 1 ) ).getEffectiveForkCount();
165 verify( mojo, times( 1 ) ).getTestClassesDirectory();
166 verify( scanResult, times( 1 ) ).getClasses();
167 verifyStatic( ResolvePathsRequest.class, times( 1 ) );
168 ResolvePathsRequest.ofStrings( eq( testClasspath.toClasspath().getClassPath() ) );
169 verify( req, times( 1 ) ).setMainModuleDescriptor( eq( moduleInfo.getAbsolutePath() ) );
170 verify( res, times( 1 ) ).getClasspathElements();
171 verify( res, times( 1 ) ).getModulepathElements();
172 verify( locationManager, times( 1 ) ).resolvePaths( eq( req ) );
173 ArgumentCaptor<String> argument1 = ArgumentCaptor.forClass( String.class );
174 ArgumentCaptor<Exception> argument2 = ArgumentCaptor.forClass( Exception.class );
175 verify( logger, times( 1 ) ).warn( argument1.capture(), argument2.capture() );
176 assertThat( argument1.getValue() )
177 .isEqualTo( "Exception for 'java 1.8'." );
178 assertThat( argument2.getValue().getMessage() )
179 .isEqualTo( "low version" );
180 ArgumentCaptor<String> argument = ArgumentCaptor.forClass( String.class );
181 verify( logger, times( 6 ) ).debug( argument.capture() );
182 assertThat( argument.getAllValues() )
183 .containsExactly( "test classpath: non-modular.jar junit.jar hamcrest.jar",
184 "test modulepath: modular.jar classes",
185 "provider classpath: surefire-provider.jar",
186 "test(compact) classpath: non-modular.jar junit.jar hamcrest.jar",
187 "test(compact) modulepath: modular.jar classes",
188 "provider(compact) classpath: surefire-provider.jar"
189 );
190
191 assertThat( conf ).isNotNull();
192 assertThat( conf.isShadefire() ).isFalse();
193 assertThat( conf.isProviderMainClass() ).isFalse();
194 assertThat( conf.isManifestOnlyJarRequestedAndUsable() ).isFalse();
195 assertThat( conf.getClassLoaderConfiguration() ).isSameAs( classLoaderConfiguration );
196 assertThat( conf.getProviderClassName() ).isEqualTo( "org.asf.Provider" );
197 assertThat( conf.getActualClassName() ).isEqualTo( "org.asf.Provider" );
198 assertThat( conf.getClasspathConfiguration() ).isNotNull();
199 assertThat( ( Object ) conf.getClasspathConfiguration().getTestClasspath() )
200 .isEqualTo( new Classpath( res.getClasspathElements() ) );
201 assertThat( ( Object ) conf.getClasspathConfiguration().getProviderClasspath() )
202 .isEqualTo( new Classpath( singleton( "surefire-provider.jar" ) ) );
203 assertThat( conf.getClasspathConfiguration() ).isInstanceOf( ModularClasspathConfiguration.class );
204 ModularClasspathConfiguration mcc = ( ModularClasspathConfiguration ) conf.getClasspathConfiguration();
205 assertThat( mcc.getModularClasspath().getModuleDescriptor() ).isEqualTo( moduleInfo );
206 assertThat( mcc.getModularClasspath().getPackages() ).containsOnly( "org.apache" );
207 assertThat( mcc.getModularClasspath().getPatchFile().getAbsolutePath() )
208 .isEqualTo( "test-classes" );
209 assertThat( mcc.getModularClasspath().getModulePath() )
210 .containsExactly( "modular.jar", "classes" );
211 assertThat( ( Object ) mcc.getTestClasspath() ).isEqualTo( new Classpath( res.getClasspathElements() ) );
212 }
213
214 private static File mockFile( String absolutePath )
215 {
216 File f = mock( File.class );
217 when( f.getAbsolutePath() ).thenReturn( absolutePath );
218 return f;
219 }
220
221 public static class Mojo
222 extends AbstractSurefireMojo
223 {
224
225 @Override
226 protected String getPluginName()
227 {
228 return null;
229 }
230
231 @Override
232 protected int getRerunFailingTestsCount()
233 {
234 return 0;
235 }
236
237 @Override
238 public boolean isSkipTests()
239 {
240 return false;
241 }
242
243 @Override
244 public void setSkipTests( boolean skipTests )
245 {
246
247 }
248
249 @Override
250 public boolean isSkipExec()
251 {
252 return false;
253 }
254
255 @Override
256 public void setSkipExec( boolean skipExec )
257 {
258
259 }
260
261 @Override
262 public boolean isSkip()
263 {
264 return false;
265 }
266
267 @Override
268 public void setSkip( boolean skip )
269 {
270
271 }
272
273 @Override
274 public File getBasedir()
275 {
276 return null;
277 }
278
279 @Override
280 public void setBasedir( File basedir )
281 {
282
283 }
284
285 @Override
286 public File getTestClassesDirectory()
287 {
288 return null;
289 }
290
291 @Override
292 public void setTestClassesDirectory( File testClassesDirectory )
293 {
294
295 }
296
297 @Override
298 public File getClassesDirectory()
299 {
300 return null;
301 }
302
303 @Override
304 public void setClassesDirectory( File classesDirectory )
305 {
306
307 }
308
309 @Override
310 public File getReportsDirectory()
311 {
312 return null;
313 }
314
315 @Override
316 public void setReportsDirectory( File reportsDirectory )
317 {
318
319 }
320
321 @Override
322 public String getTest()
323 {
324 return null;
325 }
326
327 @Override
328 public void setTest( String test )
329 {
330
331 }
332
333 @Override
334 public List<String> getIncludes()
335 {
336 return null;
337 }
338
339 @Override
340 public File getIncludesFile()
341 {
342 return null;
343 }
344
345 @Override
346 public void setIncludes( List<String> includes )
347 {
348
349 }
350
351 @Override
352 public boolean isPrintSummary()
353 {
354 return false;
355 }
356
357 @Override
358 public void setPrintSummary( boolean printSummary )
359 {
360
361 }
362
363 @Override
364 public String getReportFormat()
365 {
366 return null;
367 }
368
369 @Override
370 public void setReportFormat( String reportFormat )
371 {
372
373 }
374
375 @Override
376 public boolean isUseFile()
377 {
378 return false;
379 }
380
381 @Override
382 public void setUseFile( boolean useFile )
383 {
384
385 }
386
387 @Override
388 public String getDebugForkedProcess()
389 {
390 return null;
391 }
392
393 @Override
394 public void setDebugForkedProcess( String debugForkedProcess )
395 {
396
397 }
398
399 @Override
400 public int getForkedProcessTimeoutInSeconds()
401 {
402 return 0;
403 }
404
405 @Override
406 public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
407 {
408
409 }
410
411 @Override
412 public int getForkedProcessExitTimeoutInSeconds()
413 {
414 return 0;
415 }
416
417 @Override
418 public void setForkedProcessExitTimeoutInSeconds( int forkedProcessTerminationTimeoutInSeconds )
419 {
420
421 }
422
423 @Override
424 public double getParallelTestsTimeoutInSeconds()
425 {
426 return 0;
427 }
428
429 @Override
430 public void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds )
431 {
432
433 }
434
435 @Override
436 public double getParallelTestsTimeoutForcedInSeconds()
437 {
438 return 0;
439 }
440
441 @Override
442 public void setParallelTestsTimeoutForcedInSeconds( double parallelTestsTimeoutForcedInSeconds )
443 {
444
445 }
446
447 @Override
448 public boolean isUseSystemClassLoader()
449 {
450 return false;
451 }
452
453 @Override
454 public void setUseSystemClassLoader( boolean useSystemClassLoader )
455 {
456
457 }
458
459 @Override
460 public boolean isUseManifestOnlyJar()
461 {
462 return false;
463 }
464
465 @Override
466 public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
467 {
468
469 }
470
471 @Override
472 public String getEncoding()
473 {
474 return null;
475 }
476
477 @Override
478 public void setEncoding( String encoding )
479 {
480
481 }
482
483 @Override
484 public Boolean getFailIfNoSpecifiedTests()
485 {
486 return null;
487 }
488
489 @Override
490 public void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests )
491 {
492
493 }
494
495 @Override
496 public int getSkipAfterFailureCount()
497 {
498 return 0;
499 }
500
501 @Override
502 public String getShutdown()
503 {
504 return null;
505 }
506
507 @Override
508 public File getExcludesFile()
509 {
510 return null;
511 }
512
513 @Override
514 protected List<File> suiteXmlFiles()
515 {
516 return null;
517 }
518
519 @Override
520 protected boolean hasSuiteXmlFiles()
521 {
522 return false;
523 }
524
525 @Override
526 public File[] getSuiteXmlFiles()
527 {
528 return new File[0];
529 }
530
531 @Override
532 public void setSuiteXmlFiles( File[] suiteXmlFiles )
533 {
534
535 }
536
537 @Override
538 public String getRunOrder()
539 {
540 return null;
541 }
542
543 @Override
544 public void setRunOrder( String runOrder )
545 {
546
547 }
548
549 @Override
550 protected void handleSummary( RunResult summary, Exception firstForkException )
551 {
552
553 }
554
555 @Override
556 protected boolean isSkipExecution()
557 {
558 return false;
559 }
560
561 @Override
562 protected String[] getDefaultIncludes()
563 {
564 return new String[0];
565 }
566
567 @Override
568 protected String getReportSchemaLocation()
569 {
570 return null;
571 }
572
573 @Override
574 protected boolean useModulePath()
575 {
576 return false;
577 }
578
579 @Override
580 protected void setUseModulePath( boolean useModulePath )
581 {
582
583 }
584
585 @Override
586 protected Artifact getMojoArtifact()
587 {
588 return null;
589 }
590 }
591 }