View Javadoc
1   package org.apache.maven.plugin.testing.resources;
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 java.io.File;
23  import java.io.IOException;
24  import java.util.Collection;
25  import java.util.Set;
26  import java.util.TreeSet;
27  
28  import org.codehaus.plexus.util.DirectoryScanner;
29  import org.codehaus.plexus.util.FileUtils;
30  import org.junit.Assert;
31  import org.junit.Rule;
32  import org.junit.rules.TestWatcher;
33  import org.junit.runner.Description;
34  
35  /**
36   * Junit4 test {@link Rule} to extract and assert test resources.
37   * 
38   * @since 3.1.0
39   */
40  public class TestResources
41      extends TestWatcher
42  {
43  
44      private final String projectsDir;
45  
46      private final String workDir;
47  
48      public TestResources()
49      {
50          this( "src/test/projects", "target/test-projects" );
51      }
52  
53      public TestResources( String projectsDir, String workDir )
54      {
55          this.projectsDir = projectsDir;
56          this.workDir = workDir;
57      }
58  
59      private String name;
60  
61      @Override
62      protected void starting( Description d )
63      {
64          String methodName = d.getMethodName();
65          if ( methodName != null )
66          {
67              methodName = methodName.replace( '/', '_' ).replace( '\\', '_' );
68          }
69          name = d.getTestClass().getSimpleName() + "_" + methodName;
70      }
71  
72      /**
73       * Creates new clean copy of test project directory structure. The copy is named after both the test being executed
74       * and test project name, which allows the same test project can be used by multiple tests and by different
75       * instances of the same parametrized tests.<br/>
76       * TODO Provide alternative working directory naming for Windows, which still limits path names to ~250 charecters
77       */
78      public File getBasedir( String project )
79          throws IOException
80      {
81          if ( name == null )
82          {
83              throw new IllegalStateException( getClass().getSimpleName()
84                  + " must be a test class field annotated with org.junit.Rule" );
85          }
86          File src = new File( projectsDir, project ).getCanonicalFile();
87          Assert.assertTrue( "Test project directory does not exist: " + src.getPath(), src.isDirectory() );
88          File basedir = new File( workDir, name + "_" + project ).getCanonicalFile();
89          FileUtils.deleteDirectory( basedir );
90          Assert.assertTrue( "Test project working directory created", basedir.mkdirs() );
91          FileUtils.copyDirectoryStructure( src, basedir );
92          return basedir;
93      }
94  
95      // static helpers
96  
97      public static void cp( File basedir, String from, String to )
98          throws IOException
99      {
100         // TODO ensure destination lastModified timestamp changes
101         FileUtils.copyFile( new File( basedir, from ), new File( basedir, to ) );
102     }
103 
104     public static void assertFileContents( File basedir, String expectedPath, String actualPath )
105         throws IOException
106     {
107         String expected = FileUtils.fileRead( new File( basedir, expectedPath ) );
108         String actual = FileUtils.fileRead( new File( basedir, actualPath ) );
109         Assert.assertEquals( expected, actual );
110     }
111 
112     public static void assertDirectoryContents( File dir, String... expectedPaths )
113     {
114         DirectoryScanner scanner = new DirectoryScanner();
115         scanner.setBasedir( dir );
116         scanner.addDefaultExcludes();
117         scanner.scan();
118 
119         Set<String> actual = new TreeSet<String>();
120         for ( String path : scanner.getIncludedFiles() )
121         {
122             actual.add( path );
123         }
124         for ( String path : scanner.getIncludedDirectories() )
125         {
126             if ( path.length() > 0 )
127             {
128                 actual.add( path + "/" );
129             }
130         }
131 
132         Set<String> expected = new TreeSet<String>();
133         if ( expectedPaths != null )
134         {
135             for ( String path : expectedPaths )
136             {
137                 expected.add( path );
138             }
139         }
140 
141         // compare textual representation to make diff easier to understand
142         Assert.assertEquals( toString( expected ), toString( actual ) );
143     }
144 
145     private static String toString( Collection<String> strings )
146     {
147         StringBuilder sb = new StringBuilder();
148         for ( String string : strings )
149         {
150             sb.append( string ).append( '\n' );
151         }
152         return sb.toString();
153     }
154 
155     public static void touch( File basedir, String path )
156         throws InterruptedException
157     {
158         touch( new File( basedir, path ) );
159     }
160 
161     public static void touch( File file )
162         throws InterruptedException
163     {
164         if ( !file.isFile() )
165         {
166             throw new IllegalArgumentException( "Not a file " + file );
167         }
168         long lastModified = file.lastModified();
169         file.setLastModified( System.currentTimeMillis() );
170 
171         // TODO do modern filesystems still have this silly lastModified resolution?
172         if ( lastModified == file.lastModified() )
173         {
174             Thread.sleep( 1000L );
175             file.setLastModified( System.currentTimeMillis() );
176         }
177     }
178 
179     public static void rm( File basedir, String path )
180     {
181         Assert.assertTrue( "delete " + path, new File( basedir, path ).delete() );
182     }
183 
184     /**
185      * @since 3.2.0
186      */
187     public static void create( File basedir, String... paths )
188         throws IOException
189     {
190         if ( paths == null || paths.length == 0 )
191         {
192             throw new IllegalArgumentException();
193         }
194         for ( String path : paths )
195         {
196             File file = new File( basedir, path );
197             Assert.assertTrue( file.getParentFile().mkdirs() );
198             file.createNewFile();
199             Assert.assertTrue( file.isFile() && file.canRead() );
200         }
201     }
202 
203 }