1 /* 2 * Copyright (c) 2013, 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 24 /* 25 * @test 26 * @bug 8023524 27 * @summary tests logging generated classes for lambda 28 * @library /java/nio/file 29 * @modules jdk.compiler 30 * @run testng LogGeneratedClassesTest 31 */ 32 import java.io.File; 33 import java.io.IOException; 34 import java.util.ArrayList; 35 import java.util.List; 36 import java.util.function.Predicate; 37 import java.nio.file.Files; 38 import java.nio.file.Path; 39 import java.nio.file.Paths; 40 import java.nio.file.attribute.PosixFileAttributeView; 41 42 import org.testng.annotations.AfterClass; 43 import org.testng.annotations.BeforeClass; 44 import org.testng.annotations.Test; 45 import org.testng.SkipException; 46 47 import static java.nio.file.attribute.PosixFilePermissions.*; 48 import static org.testng.Assert.assertEquals; 49 import static org.testng.Assert.assertFalse; 50 import static org.testng.Assert.assertTrue; 51 52 public class LogGeneratedClassesTest extends LUtils { 53 String longFQCN; 54 55 @BeforeClass 56 public void setup() throws IOException { 57 final List<String> scratch = new ArrayList<>(); 58 scratch.clear(); 59 scratch.add("package com.example;"); 60 scratch.add("public class TestLambda {"); 61 scratch.add(" interface I {"); 62 scratch.add(" int foo();"); 63 scratch.add(" }"); 64 scratch.add(" public static void main(String[] args) {"); 65 scratch.add(" I lam = () -> 10;"); 66 scratch.add(" Runnable r = () -> {"); 67 scratch.add(" System.out.println(\"Runnable\");"); 68 scratch.add(" };"); 69 scratch.add(" r.run();"); 70 scratch.add(" System.out.println(\"Finish\");"); 71 scratch.add(" }"); 72 scratch.add("}"); 73 74 File test = new File("TestLambda.java"); 75 createFile(test, scratch); 76 compile("-d", ".", test.getName()); 77 78 scratch.remove(0); 79 scratch.remove(0); 80 scratch.add(0, "public class LongPackageName {"); 81 StringBuilder sb = new StringBuilder("com.example."); 82 // longer than 255 which exceed max length of most filesystems 83 for (int i = 0; i < 30; i++) { 84 sb.append("nonsense."); 85 } 86 sb.append("enough"); 87 longFQCN = sb.toString() + ".LongPackageName"; 88 sb.append(";"); 89 sb.insert(0, "package "); 90 scratch.add(0, sb.toString()); 91 test = new File("LongPackageName.java"); 92 createFile(test, scratch); 93 compile("-d", ".", test.getName()); 94 95 // create target 96 Files.createDirectory(Paths.get("dump")); 97 Files.createDirectories(Paths.get("dumpLong/com/example/nonsense")); 98 Files.createFile(Paths.get("dumpLong/com/example/nonsense/nonsense")); 99 Files.createFile(Paths.get("file")); 100 } 101 102 @AfterClass 103 public void cleanup() throws IOException { 104 Files.delete(Paths.get("TestLambda.java")); 105 Files.delete(Paths.get("LongPackageName.java")); 106 Files.delete(Paths.get("file")); 107 TestUtil.removeAll(Paths.get("com")); 108 TestUtil.removeAll(Paths.get("dump")); 109 TestUtil.removeAll(Paths.get("dumpLong")); 110 } 111 112 @Test 113 public void testNotLogging() { 114 TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), 115 "-cp", ".", 116 "-Djava.security.manager", 117 "com.example.TestLambda"); 118 tr.assertZero("Should still return 0"); 119 } 120 121 @Test 122 public void testLogging() throws IOException { 123 assertTrue(Files.exists(Paths.get("dump"))); 124 TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), 125 "-cp", ".", 126 "-Djdk.internal.lambda.dumpProxyClasses=dump", 127 "-Djava.security.manager", 128 "com.example.TestLambda"); 129 // dump/com/example + 2 class files 130 assertEquals(Files.walk(Paths.get("dump")).count(), 5, "Two lambda captured"); 131 tr.assertZero("Should still return 0"); 132 } 133 134 @Test 135 public void testDumpDirNotExist() throws IOException { 136 assertFalse(Files.exists(Paths.get("notExist"))); 137 TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), 138 "-cp", ".", 139 "-Djdk.internal.lambda.dumpProxyClasses=notExist", 140 "-Djava.security.manager", 141 "com.example.TestLambda"); 142 assertEquals(tr.testOutput.stream() 143 .filter(s -> s.startsWith("WARNING")) 144 .peek(s -> assertTrue(s.contains("does not exist"))) 145 .count(), 146 1, "only show error once"); 147 tr.assertZero("Should still return 0"); 148 } 149 150 @Test 151 public void testDumpDirIsFile() throws IOException { 152 assertTrue(Files.isRegularFile(Paths.get("file"))); 153 TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), 154 "-cp", ".", 155 "-Djdk.internal.lambda.dumpProxyClasses=file", 156 "-Djava.security.manager", 157 "com.example.TestLambda"); 158 assertEquals(tr.testOutput.stream() 159 .filter(s -> s.startsWith("WARNING")) 160 .peek(s -> assertTrue(s.contains("not a directory"))) 161 .count(), 162 1, "only show error once"); 163 tr.assertZero("Should still return 0"); 164 } 165 166 private static boolean isWriteableDirectory(Path p) { 167 if (!Files.isDirectory(p)) { 168 return false; 169 } 170 Path test = p.resolve(Paths.get("test")); 171 try { 172 Files.createFile(test); 173 assertTrue(Files.exists(test)); 174 return true; 175 } catch (IOException e) { 176 assertFalse(Files.exists(test)); 177 return false; 178 } finally { 179 if (Files.exists(test)) { 180 try { 181 Files.delete(test); 182 } catch (IOException e) { 183 throw new Error(e); 184 } 185 } 186 } 187 } 188 189 @Test 190 public void testDumpDirNotWritable() throws IOException { 191 if (!Files.getFileStore(Paths.get(".")) 192 .supportsFileAttributeView(PosixFileAttributeView.class)) { 193 // No easy way to setup readonly directory without POSIX 194 // We would like to skip the test with a cause with 195 // throw new SkipException("Posix not supported"); 196 // but jtreg will report failure so we just pass the test 197 // which we can look at if jtreg changed its behavior 198 System.out.println("WARNING: POSIX is not supported. Skipping testDumpDirNotWritable test."); 199 return; 200 } 201 202 Files.createDirectory(Paths.get("readOnly"), 203 asFileAttribute(fromString("r-xr-xr-x"))); 204 try { 205 if (isWriteableDirectory(Paths.get("readOnly"))) { 206 // Skipping the test: it's allowed to write into read-only directory 207 // (e.g. current user is super user). 208 System.out.println("WARNING: readOnly directory is writeable. Skipping testDumpDirNotWritable test."); 209 return; 210 } 211 212 TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), 213 "-cp", ".", 214 "-Djdk.internal.lambda.dumpProxyClasses=readOnly", 215 "-Djava.security.manager", 216 "com.example.TestLambda"); 217 assertEquals(tr.testOutput.stream() 218 .filter(s -> s.startsWith("WARNING")) 219 .peek(s -> assertTrue(s.contains("not writable"))) 220 .count(), 221 1, "only show error once"); 222 tr.assertZero("Should still return 0"); 223 } finally { 224 TestUtil.removeAll(Paths.get("readOnly")); 225 } 226 } 227 228 @Test 229 public void testLoggingException() throws IOException { 230 assertTrue(Files.exists(Paths.get("dumpLong"))); 231 TestResult tr = doExec(JAVA_CMD.getAbsolutePath(), 232 "-cp", ".", 233 "-Djdk.internal.lambda.dumpProxyClasses=dumpLong", 234 "-Djava.security.manager", 235 longFQCN); 236 assertEquals(tr.testOutput.stream() 237 .filter(s -> s.startsWith("WARNING: Exception")) 238 .count(), 239 2, "show error each capture"); 240 // dumpLong/com/example/nonsense/nonsense 241 Path dumpPath = Paths.get("dumpLong/com/example/nonsense"); 242 Predicate<Path> filter = p -> p.getParent() == null || dumpPath.startsWith(p) || p.startsWith(dumpPath); 243 boolean debug = true; 244 if (debug) { 245 Files.walk(Paths.get("dumpLong")) 246 .forEachOrdered(p -> { 247 if (filter.test(p)) { 248 System.out.println("accepted: " + p.toString()); 249 } else { 250 System.out.println("filetered out: " + p.toString()); 251 } 252 }); 253 } 254 assertEquals(Files.walk(Paths.get("dumpLong")) 255 .filter(filter) 256 .count(), 5, "Two lambda captured failed to log"); 257 tr.assertZero("Should still return 0"); 258 } 259 }