1/* 2 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24import java.io.IOException; 25import java.io.OutputStream; 26import java.io.UncheckedIOException; 27import java.lang.annotation.Annotation; 28import java.lang.annotation.Retention; 29import java.lang.annotation.RetentionPolicy; 30import java.lang.reflect.InvocationTargetException; 31import java.lang.reflect.Method; 32import java.nio.file.FileSystem; 33import java.nio.file.FileSystems; 34import java.nio.file.Files; 35import java.nio.file.Path; 36import java.nio.file.Paths; 37import java.util.ArrayList; 38import java.util.Arrays; 39import java.util.List; 40import java.util.stream.Collectors; 41import java.util.zip.ZipEntry; 42import java.util.zip.ZipOutputStream; 43 44import javax.tools.JavaCompiler; 45import javax.tools.StandardJavaFileManager; 46import javax.tools.ToolProvider; 47 48/** 49 * Base class for unit tests for StandardJavaFileManager. 50 */ 51class SJFM_TestBase { 52 53 /** Shared compiler instance. */ 54 JavaCompiler comp; 55 56 /** A list of items to be closed when the test is complete. */ 57 List<AutoCloseable> closeables; 58 59 /** 60 * Runs a test. This is the primary entry point and should generally be 61 * called from each test's main method. 62 * It calls all methods annotated with {@code @Test} with the instances 63 * of StandardJavaFileManager to be tested. 64 * 65 * @throws Exception if the test fails. 66 */ 67 void run() throws Exception { 68 comp = ToolProvider.getSystemJavaCompiler(); 69 closeables = new ArrayList<>(); 70 71 try (StandardJavaFileManager systemFileManager = comp.getStandardFileManager(null, null, null); 72 StandardJavaFileManager customFileManager = new MyStandardJavaFileManager(systemFileManager)) { 73 test(systemFileManager); 74 test(customFileManager); 75 } finally { 76 for (AutoCloseable c: closeables) { 77 try { 78 c.close(); 79 } catch (IOException e) { 80 error("Exception closing " + c + ": " + e); 81 } 82 } 83 } 84 85 if (errors > 0) 86 throw new Exception(errors + " errors occurred"); 87 } 88 89 /** 90 * Get the file managers to be tested. 91 * 92 * Currently, two are provided: 93 * <ol> 94 * <li>the system-provided file manager 95 * <li>a custom file manager, which relies on the default methods provided in the 96 * StandardJavaFileManager interface 97 * </li> 98 * 99 * @return the file managers to be tested 100 */ 101 List<StandardJavaFileManager> getTestFileManagers() { 102 StandardJavaFileManager systemFileManager = comp.getStandardFileManager(null, null, null); 103 StandardJavaFileManager customFileManager = new MyStandardJavaFileManager(systemFileManager); 104 return Arrays.asList(systemFileManager, customFileManager); 105 } 106 107 /** 108 * Tests a specific file manager, by calling all methods annotated 109 * with {@code @Test} passing this file manager as an argument. 110 * 111 * @param fm the file manager to be tested 112 * @throws Exception if the test fails 113 */ 114 void test(StandardJavaFileManager fm) throws Exception { 115 System.err.println("Testing " + fm); 116 for (Method m: getClass().getDeclaredMethods()) { 117 Annotation a = m.getAnnotation(Test.class); 118 if (a != null) { 119 try { 120 System.err.println("Test " + m.getName()); 121 m.invoke(this, new Object[] { fm }); 122 } catch (InvocationTargetException e) { 123 Throwable cause = e.getCause(); 124 throw (cause instanceof Exception) ? ((Exception) cause) : e; 125 } 126 System.err.println(); 127 } 128 } 129 } 130 131 /** Marker annotation for test cases. */ 132 @Retention(RetentionPolicy.RUNTIME) 133 @interface Test { } 134 135 /** 136 * Returns a series of paths for artifacts in the default file system. 137 * The paths are for the .java files in the test.src directory. 138 * 139 * @return a list of paths 140 * @throws IOException 141 */ 142 List<Path> getTestFilePaths() throws IOException { 143 String testSrc = System.getProperty("test.src"); 144 return Files.list(Paths.get(testSrc)) 145 .filter(p -> p.getFileName().toString().endsWith(".java")) 146 .collect(Collectors.toList()); 147 } 148 149 private FileSystem zipfs; 150 private List<Path> zipPaths; 151 152 /** 153 * Returns a series of paths for artifacts in a non-default file system. 154 * A zip file is created containing copies of the .java files in the 155 * test.src directory. The paths that are returned refer to these files. 156 * 157 * @return a list of paths 158 * @throws IOException 159 */ 160 List<Path> getTestZipPaths() throws IOException { 161 if (zipfs == null) { 162 Path testZip = createSourceZip(); 163 zipfs = FileSystems.newFileSystem(testZip, null); 164 closeables.add(zipfs); 165 zipPaths = Files.list(zipfs.getRootDirectories().iterator().next()) 166 .filter(p -> p.getFileName().toString().endsWith(".java")) 167 .collect(Collectors.toList()); 168 } 169 return zipPaths; 170 } 171 172 /** 173 * Create a zip file containing the contents of the test.src directory. 174 * 175 * @return a path for the zip file. 176 * @throws IOException if there is a problem creating the file 177 */ 178 private Path createSourceZip() throws IOException { 179 Path testSrc = Paths.get(System.getProperty("test.src")); 180 Path testZip = Paths.get("test.zip"); 181 try (OutputStream os = Files.newOutputStream(testZip)) { 182 try (ZipOutputStream zos = new ZipOutputStream(os)) { 183 Files.list(testSrc) 184 .filter(p -> p.getFileName().toString().endsWith(".java")) 185 .forEach(p -> { 186 try { 187 zos.putNextEntry(new ZipEntry(p.getFileName().toString())); 188 zos.write(Files.readAllBytes(p)); 189 zos.closeEntry(); 190 } catch (IOException ex) { 191 throw new UncheckedIOException(ex); 192 } 193 }); 194 } 195 } 196 return testZip; 197 } 198 199 /** 200 * Tests whether it is expected that a file manager will be able 201 * to create a series of file objects from a series of paths. 202 * 203 * MyStandardJavaFileManager does not support paths referring to 204 * non-default file systems. 205 * 206 * @param fm the file manager to be tested 207 * @param paths the paths to be tested 208 * @return 209 */ 210 boolean isGetFileObjectsSupported(StandardJavaFileManager fm, List<Path> paths) { 211 return !(fm instanceof MyStandardJavaFileManager 212 && (paths.get(0).getFileSystem() != FileSystems.getDefault())); 213 } 214 215 /** 216 * Report an error. 217 */ 218 void error(String msg) { 219 System.err.println("Error: " + msg); 220 errors++; 221 } 222 223 /** Count of errors reported. */ 224 int errors; 225 226} 227