View Javadoc
1   package org.apache.maven.plugin.surefire;
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 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.project.MavenProject;
28  import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
29  import org.apache.maven.surefire.booter.Classpath;
30  import org.apache.maven.surefire.booter.StartupConfiguration;
31  import org.apache.maven.surefire.suite.RunResult;
32  import org.codehaus.plexus.logging.Logger;
33  import org.junit.Test;
34  import org.junit.runner.RunWith;
35  import org.mockito.ArgumentCaptor;
36  import org.mockito.Mock;
37  import org.powermock.core.classloader.annotations.PrepareForTest;
38  import org.powermock.modules.junit4.PowerMockRunner;
39  
40  import java.io.File;
41  import java.io.IOException;
42  import java.util.ArrayList;
43  import java.util.Collection;
44  import java.util.HashMap;
45  import java.util.HashSet;
46  import java.util.LinkedHashSet;
47  import java.util.List;
48  import java.util.Map;
49  import java.util.Set;
50  
51  import static java.io.File.separatorChar;
52  import static java.util.Arrays.asList;
53  import static java.util.Collections.singleton;
54  import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
55  import static org.apache.maven.artifact.versioning.VersionRange.createFromVersion;
56  import static org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec;
57  import static org.fest.assertions.Assertions.assertThat;
58  import static org.mockito.ArgumentMatchers.anyString;
59  import static org.mockito.Mockito.times;
60  import static org.mockito.Mockito.when;
61  import static org.mockito.Mockito.verify;
62  import static org.powermock.api.mockito.PowerMockito.doNothing;
63  import static org.powermock.api.mockito.PowerMockito.doReturn;
64  import static org.powermock.api.mockito.PowerMockito.mock;
65  import static org.powermock.api.mockito.PowerMockito.spy;
66  import static org.powermock.api.mockito.PowerMockito.verifyPrivate;
67  import static org.powermock.reflect.Whitebox.invokeMethod;
68  
69  /**
70   * Test for {@link AbstractSurefireMojo}.
71   */
72  @RunWith( PowerMockRunner.class )
73  @PrepareForTest( AbstractSurefireMojo.class )
74  public class AbstractSurefireMojoTest
75  {
76      @Mock
77      private ArtifactHandler handler;
78  
79      private final Mojo mojo = new Mojo();
80  
81      @Test
82      public void shouldRetainInPluginArtifacts() throws Exception
83      {
84          Artifact provider = new DefaultArtifact( "g", "a", createFromVersionSpec( "1" ), "compile", "jar", "", null );
85          Artifact common = new DefaultArtifact( "g", "c", createFromVersionSpec( "1" ), "compile", "jar", "", null );
86          Artifact api = new DefaultArtifact( "g", "a", createFromVersionSpec( "1" ), "compile", "jar", "", null );
87  
88          Set<Artifact> providerArtifacts = singleton( provider );
89          Artifact[] inPluginArtifacts = { common, api };
90          Set<Artifact> inPluginClasspath = invokeMethod( AbstractSurefireMojo.class,
91                  "retainInProcArtifactsUnique", providerArtifacts, inPluginArtifacts );
92  
93          assertThat( inPluginClasspath )
94                  .containsOnly( common );
95      }
96  
97      @Test
98      public void shouldRetainInProcArtifactsUnique() throws Exception
99      {
100         Artifact provider = new DefaultArtifact( "g", "p", createFromVersionSpec( "1" ), "compile", "jar", "", null );
101         Artifact common = new DefaultArtifact( "g", "c", createFromVersionSpec( "1" ), "compile", "jar", "", null );
102         Artifact api = new DefaultArtifact( "g", "a", createFromVersionSpec( "1" ), "compile", "jar", "", null );
103 
104         Set<Artifact> providerArtifacts = singleton( provider );
105         Artifact[] inPluginArtifacts = { common, api };
106         Set<Artifact> inPluginClasspath = invokeMethod( AbstractSurefireMojo.class,
107                 "retainInProcArtifactsUnique", providerArtifacts, inPluginArtifacts );
108 
109         assertThat( inPluginClasspath )
110                 .containsOnly( common, api );
111     }
112 
113     @Test
114     public void shouldCreateInProcClasspath() throws Exception
115     {
116         Artifact provider = new DefaultArtifact( "g", "p", createFromVersionSpec( "1" ), "compile", "jar", "", null );
117         provider.setFile( mockFile( "provider.jar" ) );
118 
119         Artifact common = new DefaultArtifact( "g", "c", createFromVersionSpec( "1" ), "compile", "jar", "", null );
120         common.setFile( mockFile( "maven-surefire-common.jar" ) );
121 
122         Artifact api = new DefaultArtifact( "g", "a", createFromVersionSpec( "1" ), "compile", "jar", "", null );
123         api.setFile( mockFile( "surefire-api.jar" ) );
124 
125         Set<Artifact> newArtifacts = new LinkedHashSet<Artifact>();
126         newArtifacts.add( common );
127         newArtifacts.add( api );
128 
129         Classpath providerClasspath = new Classpath( singleton( provider.getFile().getAbsolutePath() ) );
130 
131         Classpath inPluginClasspath = invokeMethod( AbstractSurefireMojo.class,
132                 "createInProcClasspath", providerClasspath, newArtifacts );
133 
134         Classpath expectedClasspath =
135                 new Classpath( asList( provider.getFile().getAbsolutePath(),
136                                        common.getFile().getAbsolutePath(),
137                                        api.getFile().getAbsolutePath() ) );
138 
139         assertThat( (Object ) inPluginClasspath )
140                 .isEqualTo( expectedClasspath );
141 
142     }
143 
144     @Test
145     public void shouldGenerateTestClasspath() throws Exception
146     {
147         AbstractSurefireMojo mojo = spy( this.mojo );
148 
149         when( mojo.getClassesDirectory() ).thenReturn( new File( "target" + separatorChar + "classes" ) );
150         when( mojo.getTestClassesDirectory() ).thenReturn( new File( "target" + separatorChar + "test-classes" ) );
151         when( mojo.getClasspathDependencyScopeExclude() ).thenReturn( "runtime" );
152         when( mojo.getClasspathDependencyExcludes() ).thenReturn( new String[]{ "g3:a3" } );
153         doReturn( mock( Artifact.class ) ).when( mojo, "getTestNgArtifact" );
154 
155         Set<Artifact> artifacts = new HashSet<Artifact>();
156 
157         Artifact a1 = mock( Artifact.class );
158         when( a1.getGroupId() ).thenReturn( "g1" );
159         when( a1.getArtifactId() ).thenReturn( "a1" );
160         when( a1.getVersion() ).thenReturn( "1" );
161         when( a1.getScope() ).thenReturn( "runtime" );
162         when( a1.getDependencyConflictId() ).thenReturn( "g1:a1:jar" );
163         when( a1.getId() ).thenReturn( "g1:a1:jar:1" );
164         artifacts.add( a1 );
165 
166         ArtifactHandler artifactHandler = mock( ArtifactHandler.class );
167         when( artifactHandler.isAddedToClasspath() ).thenReturn( true );
168 
169         Artifact a2 = mock( Artifact.class );
170         when( a2.getGroupId() ).thenReturn( "g2" );
171         when( a2.getArtifactId() ).thenReturn( "a2" );
172         when( a2.getVersion() ).thenReturn( "2" );
173         when( a2.getScope() ).thenReturn( "test" );
174         when( a2.getDependencyConflictId() ).thenReturn( "g2:a2:jar" );
175         when( a2.getId() ).thenReturn( "g2:a2:jar:2" );
176         when( a2.getFile() ).thenReturn( new File( "a2-2.jar" ) );
177         when( a2.getArtifactHandler() ).thenReturn( artifactHandler );
178         artifacts.add( a2 );
179 
180         Artifact a3 = mock( Artifact.class );
181         when( a3.getGroupId() ).thenReturn( "g3" );
182         when( a3.getArtifactId() ).thenReturn( "a3" );
183         when( a3.getVersion() ).thenReturn( "3" );
184         when( a3.getScope() ).thenReturn( "test" );
185         when( a3.getDependencyConflictId() ).thenReturn( "g3:a3:jar" );
186         when( a3.getId() ).thenReturn( "g3:a3:jar:3" );
187         when( a3.getFile() ).thenReturn( new File( "a3-3.jar" ) );
188         when( a3.getArtifactHandler() ).thenReturn( artifactHandler );
189         artifacts.add( a3 );
190 
191         MavenProject project = mock( MavenProject.class );
192         when( project.getArtifacts() ).thenReturn( artifacts );
193         when( mojo.getProject() ).thenReturn( project );
194 
195         TestClassPath cp = invokeMethod( mojo, "generateTestClasspath" );
196 
197         verifyPrivate( mojo, times( 1 ) ).invoke( "generateTestClasspath" );
198         verify( mojo, times( 1 ) ).getClassesDirectory();
199         verify( mojo, times( 1 ) ).getTestClassesDirectory();
200         verify( mojo, times( 3 ) ).getClasspathDependencyScopeExclude();
201         verify( mojo, times( 2 ) ).getClasspathDependencyExcludes();
202         verify( mojo, times( 1 ) ).getAdditionalClasspathElements();
203 
204         assertThat( cp.toClasspath().getClassPath() ).hasSize( 3 );
205         assertThat( cp.toClasspath().getClassPath().get( 0 ) ).endsWith( "test-classes" );
206         assertThat( cp.toClasspath().getClassPath().get( 1 ) ).endsWith( "classes" );
207         assertThat( cp.toClasspath().getClassPath().get( 2 ) ).endsWith( "a2-2.jar" );
208     }
209 
210     @Test
211     public void shouldHaveStartupConfigForNonModularClasspath()
212             throws Exception
213     {
214         AbstractSurefireMojo mojo = spy( this.mojo );
215 
216         Artifact common = new DefaultArtifact( "org.apache.maven.surefire", "maven-surefire-common",
217                 createFromVersion( "1" ), "runtime", "jar", "", handler );
218         common.setFile( mockFile( "maven-surefire-common.jar" ) );
219 
220         Artifact api = new DefaultArtifact( "org.apache.maven.surefire", "surefire-api",
221                 createFromVersion( "1" ), "runtime", "jar", "", handler );
222         api.setFile( mockFile( "surefire-api.jar" ) );
223 
224         Artifact loggerApi = new DefaultArtifact( "org.apache.maven.surefire", "surefire-logger-api",
225                 createFromVersion( "1" ), "runtime", "jar", "", handler );
226         loggerApi.setFile( mockFile( "surefire-logger-api.jar" ) );
227 
228         Map<String, Artifact> providerArtifactsMap = new HashMap<String, Artifact>();
229         providerArtifactsMap.put( "org.apache.maven.surefire:maven-surefire-common", common );
230         providerArtifactsMap.put( "org.apache.maven.surefire:surefire-api", api );
231         providerArtifactsMap.put( "org.apache.maven.surefire:surefire-logger-api", loggerApi );
232 
233         when( mojo.getPluginArtifactMap() )
234                 .thenReturn( providerArtifactsMap );
235 
236         when( handler.isAddedToClasspath() ).thenReturn( true );
237 
238         VersionRange v1 = createFromVersion( "4.12" );
239         Artifact junit = new DefaultArtifact( "junit", "junit", v1, "test", "jar", "", handler );
240         junit.setFile( mockFile( "junit.jar" ) );
241 
242         VersionRange v2 = createFromVersion( "1.3.0" );
243         Artifact hamcrest = new DefaultArtifact( "org.hamcrest", "hamcrest-core", v2, "test", "jar", "", handler );
244         hamcrest.setFile( mockFile( "hamcrest.jar" ) );
245 
246         File classesDir = mockFile( "classes" );
247         File testClassesDir = mockFile( "test-classes" );
248         TestClassPath testClasspath =
249                 new TestClassPath( asList( junit, hamcrest ), classesDir, testClassesDir, null, null );
250 
251         doReturn( testClasspath ).when( mojo, "generateTestClasspath" );
252         doReturn( 1 ).when( mojo, "getEffectiveForkCount" );
253         doReturn( true ).when( mojo, "effectiveIsEnableAssertions" );
254         when( mojo.isChildDelegation() ).thenReturn( false );
255 
256         ClassLoaderConfiguration classLoaderConfiguration = new ClassLoaderConfiguration( false, true );
257 
258         VersionRange v3 = createFromVersion( "1" );
259         Artifact provider = new DefaultArtifact( "x", "surefire-provider", v3, "runtime", "jar", "", handler );
260         provider.setFile( mockFile( "surefire-provider.jar" ) );
261         Set<Artifact> providerArtifacts = singleton( provider );
262 
263         Logger logger = mock( Logger.class );
264         when( logger.isDebugEnabled() ).thenReturn( true );
265         doNothing().when( logger ).debug( anyString() );
266         when( mojo.getConsoleLogger() ).thenReturn( new PluginConsoleLogger( logger ) );
267 
268         StartupConfiguration conf = invokeMethod( mojo, "newStartupConfigWithClasspath",
269                 classLoaderConfiguration, providerArtifacts, "org.asf.Provider" );
270 
271         verify( mojo, times( 1 ) ).effectiveIsEnableAssertions();
272         verify( mojo, times( 1 ) ).isChildDelegation();
273         verifyPrivate( mojo, times( 1 ) ).invoke( "generateTestClasspath" );
274         verify( mojo, times( 1 ) ).getEffectiveForkCount();
275         ArgumentCaptor<String> argument = ArgumentCaptor.forClass( String.class );
276         verify( logger, times( 6 ) ).debug( argument.capture() );
277         assertThat( argument.getAllValues() )
278                 .containsExactly( "test classpath:  test-classes  classes  junit.jar  hamcrest.jar",
279                 "provider classpath:  surefire-provider.jar",
280                 "test(compact) classpath:  test-classes  classes  junit.jar  hamcrest.jar",
281                 "provider(compact) classpath:  surefire-provider.jar",
282                 "in-process classpath:  surefire-provider.jar  maven-surefire-common.jar  surefire-api.jar  surefire-logger-api.jar",
283                 "in-process(compact) classpath:  surefire-provider.jar  maven-surefire-common.jar  surefire-api.jar  surefire-logger-api.jar"
284                 );
285 
286         assertThat( conf.getClassLoaderConfiguration() )
287                 .isSameAs( classLoaderConfiguration );
288 
289         assertThat( ( Object ) conf.getClasspathConfiguration().getTestClasspath() )
290                 .isEqualTo( testClasspath.toClasspath() );
291 
292         Collection<String> files = new ArrayList<String>();
293         for ( Artifact providerArtifact : providerArtifacts )
294         {
295             files.add( providerArtifact.getFile().getAbsolutePath() );
296         }
297         assertThat( ( Object ) conf.getClasspathConfiguration().getProviderClasspath() )
298                 .isEqualTo( new Classpath( files ) );
299 
300         assertThat( ( Object ) conf.getClasspathConfiguration().isClassPathConfig() )
301                 .isEqualTo( true );
302 
303         assertThat( ( Object ) conf.getClasspathConfiguration().isModularPathConfig() )
304                 .isEqualTo( false );
305 
306         assertThat( ( Object ) conf.getClasspathConfiguration().isEnableAssertions() )
307                 .isEqualTo( true );
308 
309         assertThat( conf.getProviderClassName() )
310                 .isEqualTo( "org.asf.Provider" );
311     }
312 
313     @Test
314     public void shouldExistTmpDirectory() throws IOException
315     {
316         String systemTmpDir = System.getProperty( "java.io.tmpdir" );
317         String usrDir = new File( System.getProperty( "user.dir" ) ).getCanonicalPath();
318 
319         String tmpDir = "surefireX" + System.currentTimeMillis();
320 
321         //noinspection ResultOfMethodCallIgnored
322         new File( systemTmpDir, tmpDir ).delete();
323 
324         File targetDir = new File( usrDir, "target" );
325         //noinspection ResultOfMethodCallIgnored
326         new File( targetDir, tmpDir ).delete();
327 
328         AbstractSurefireMojo mojo = mock( AbstractSurefireMojo.class );
329         when( mojo.getTempDir() ).thenReturn( tmpDir );
330         when( mojo.getProjectBuildDirectory() ).thenReturn( targetDir );
331         when( mojo.createSurefireBootDirectoryInTemp() ).thenCallRealMethod();
332         when( mojo.createSurefireBootDirectoryInBuild() ).thenCallRealMethod();
333         when( mojo.getSurefireTempDir() ).thenCallRealMethod();
334 
335         File bootDir = mojo.createSurefireBootDirectoryInTemp();
336         assertThat( bootDir ).isNotNull();
337         assertThat( bootDir ).isDirectory();
338 
339         assertThat( new File( systemTmpDir, bootDir.getName() ) ).isDirectory();
340         assertThat( bootDir.getName() )
341                 .startsWith( tmpDir );
342 
343         File buildTmp = mojo.createSurefireBootDirectoryInBuild();
344         assertThat( buildTmp ).isNotNull();
345         assertThat( buildTmp ).isDirectory();
346         assertThat( buildTmp.getParentFile().getCanonicalFile().getParent() ).isEqualTo( usrDir );
347         assertThat( buildTmp.getName() ).isEqualTo( tmpDir );
348 
349         File tmp = mojo.getSurefireTempDir();
350         assertThat( tmp ).isNotNull();
351         assertThat( tmp ).isDirectory();
352         assertThat( IS_OS_WINDOWS ? new File( systemTmpDir, bootDir.getName() ) : new File( targetDir, tmpDir ) )
353                 .isDirectory();
354     }
355 
356     public static class Mojo
357             extends AbstractSurefireMojo
358     {
359         @Override
360         protected String getPluginName()
361         {
362             return null;
363         }
364 
365         @Override
366         protected int getRerunFailingTestsCount()
367         {
368             return 0;
369         }
370 
371         @Override
372         public boolean isSkipTests()
373         {
374             return false;
375         }
376 
377         @Override
378         public void setSkipTests( boolean skipTests )
379         {
380 
381         }
382 
383         @Override
384         public boolean isSkipExec()
385         {
386             return false;
387         }
388 
389         @Override
390         public void setSkipExec( boolean skipExec )
391         {
392 
393         }
394 
395         @Override
396         public boolean isSkip()
397         {
398             return false;
399         }
400 
401         @Override
402         public void setSkip( boolean skip )
403         {
404 
405         }
406 
407         @Override
408         public File getBasedir()
409         {
410             return null;
411         }
412 
413         @Override
414         public void setBasedir( File basedir )
415         {
416 
417         }
418 
419         @Override
420         public File getTestClassesDirectory()
421         {
422             return null;
423         }
424 
425         @Override
426         public void setTestClassesDirectory( File testClassesDirectory )
427         {
428 
429         }
430 
431         @Override
432         public File getClassesDirectory()
433         {
434             return null;
435         }
436 
437         @Override
438         public void setClassesDirectory( File classesDirectory )
439         {
440 
441         }
442 
443         @Override
444         public File getReportsDirectory()
445         {
446             return null;
447         }
448 
449         @Override
450         public void setReportsDirectory( File reportsDirectory )
451         {
452 
453         }
454 
455         @Override
456         public String getTest()
457         {
458             return null;
459         }
460 
461         @Override
462         public void setTest( String test )
463         {
464 
465         }
466 
467         @Override
468         public List<String> getIncludes()
469         {
470             return null;
471         }
472 
473         @Override
474         public File getIncludesFile()
475         {
476             return null;
477         }
478 
479         @Override
480         public void setIncludes( List<String> includes )
481         {
482 
483         }
484 
485         @Override
486         public boolean isPrintSummary()
487         {
488             return false;
489         }
490 
491         @Override
492         public void setPrintSummary( boolean printSummary )
493         {
494 
495         }
496 
497         @Override
498         public String getReportFormat()
499         {
500             return null;
501         }
502 
503         @Override
504         public void setReportFormat( String reportFormat )
505         {
506 
507         }
508 
509         @Override
510         public boolean isUseFile()
511         {
512             return false;
513         }
514 
515         @Override
516         public void setUseFile( boolean useFile )
517         {
518 
519         }
520 
521         @Override
522         public String getDebugForkedProcess()
523         {
524             return null;
525         }
526 
527         @Override
528         public void setDebugForkedProcess( String debugForkedProcess )
529         {
530 
531         }
532 
533         @Override
534         public int getForkedProcessTimeoutInSeconds()
535         {
536             return 0;
537         }
538 
539         @Override
540         public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
541         {
542 
543         }
544 
545         @Override
546         public int getForkedProcessExitTimeoutInSeconds()
547         {
548             return 0;
549         }
550 
551         @Override
552         public void setForkedProcessExitTimeoutInSeconds( int forkedProcessTerminationTimeoutInSeconds )
553         {
554 
555         }
556 
557         @Override
558         public double getParallelTestsTimeoutInSeconds()
559         {
560             return 0;
561         }
562 
563         @Override
564         public void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds )
565         {
566 
567         }
568 
569         @Override
570         public double getParallelTestsTimeoutForcedInSeconds()
571         {
572             return 0;
573         }
574 
575         @Override
576         public void setParallelTestsTimeoutForcedInSeconds( double parallelTestsTimeoutForcedInSeconds )
577         {
578 
579         }
580 
581         @Override
582         public boolean isUseSystemClassLoader()
583         {
584             return false;
585         }
586 
587         @Override
588         public void setUseSystemClassLoader( boolean useSystemClassLoader )
589         {
590 
591         }
592 
593         @Override
594         public boolean isUseManifestOnlyJar()
595         {
596             return false;
597         }
598 
599         @Override
600         public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
601         {
602 
603         }
604 
605         @Override
606         public String getEncoding()
607         {
608             return null;
609         }
610 
611         @Override
612         public void setEncoding( String encoding )
613         {
614 
615         }
616 
617         @Override
618         public Boolean getFailIfNoSpecifiedTests()
619         {
620             return null;
621         }
622 
623         @Override
624         public void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests )
625         {
626 
627         }
628 
629         @Override
630         public int getSkipAfterFailureCount()
631         {
632             return 0;
633         }
634 
635         @Override
636         public String getShutdown()
637         {
638             return null;
639         }
640 
641         @Override
642         public File getExcludesFile()
643         {
644             return null;
645         }
646 
647         @Override
648         protected List<File> suiteXmlFiles()
649         {
650             return null;
651         }
652 
653         @Override
654         protected boolean hasSuiteXmlFiles()
655         {
656             return false;
657         }
658 
659         @Override
660         public File[] getSuiteXmlFiles()
661         {
662             return new File[0];
663         }
664 
665         @Override
666         public void setSuiteXmlFiles( File[] suiteXmlFiles )
667         {
668 
669         }
670 
671         @Override
672         public String getRunOrder()
673         {
674             return null;
675         }
676 
677         @Override
678         public void setRunOrder( String runOrder )
679         {
680 
681         }
682 
683         @Override
684         protected void handleSummary( RunResult summary, Exception firstForkException )
685         {
686 
687         }
688 
689         @Override
690         protected boolean isSkipExecution()
691         {
692             return false;
693         }
694 
695         @Override
696         protected String[] getDefaultIncludes()
697         {
698             return new String[0];
699         }
700 
701         @Override
702         protected String getReportSchemaLocation()
703         {
704             return null;
705         }
706 
707         @Override
708         protected Artifact getMojoArtifact()
709         {
710             return null;
711         }
712     }
713 
714     private static File mockFile( String absolutePath )
715     {
716         File f = mock( File.class );
717         when( f.getAbsolutePath() ).thenReturn( absolutePath );
718         return f;
719     }
720 }