1 /*
   2  * Copyright (c) 2013, 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  * @run testng LogGeneratedClassesTest
  30  */
  31 import java.io.File;
  32 import java.io.IOException;
  33 import java.util.ArrayList;
  34 import java.util.List;
  35 import java.nio.file.Files;
  36 import java.nio.file.LinkOption;
  37 import java.nio.file.Path;
  38 import java.nio.file.Paths;
  39 import java.nio.file.attribute.PosixFileAttributeView;
  40 import java.util.stream.Stream;
  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     @Test
 167     public void testDumpDirNotWritable() throws IOException {
 168         if (! Files.getFileStore(Paths.get("."))
 169                    .supportsFileAttributeView(PosixFileAttributeView.class)) {
 170             // No easy way to setup readonly directory without POSIX
 171             // We would like to skip the test with a cause with
 172             //     throw new SkipException("Posix not supported");
 173             // but jtreg will report failure so we just pass the test
 174             // which we can look at if jtreg changed its behavior
 175             return;
 176         }
 177 
 178         if ("root".equals(System.getProperty("user.name"))) {
 179             // Super user can create files in read-only directories (at least on Linux & Solaris).
 180             // The test is not applicable in that case.
 181             return;
 182         }
 183 
 184         Files.createDirectory(Paths.get("readOnly"),
 185                               asFileAttribute(fromString("r-xr-xr-x")));
 186 
 187         TestResult tr = doExec(JAVA_CMD.getAbsolutePath(),
 188                                "-cp", ".",
 189                                "-Djdk.internal.lambda.dumpProxyClasses=readOnly",
 190                                "-Djava.security.manager",
 191                                "com.example.TestLambda");
 192         assertEquals(tr.testOutput.stream()
 193                                   .filter(s -> s.startsWith("WARNING"))
 194                                   .peek(s -> assertTrue(s.contains("not writable")))
 195                                   .count(),
 196                      1, "only show error once");
 197         tr.assertZero("Should still return 0");
 198 
 199         TestUtil.removeAll(Paths.get("readOnly"));
 200     }
 201 
 202     @Test
 203     public void testLoggingException() throws IOException {
 204         assertTrue(Files.exists(Paths.get("dumpLong")));
 205         TestResult tr = doExec(JAVA_CMD.getAbsolutePath(),
 206                                "-cp", ".",
 207                                "-Djdk.internal.lambda.dumpProxyClasses=dumpLong",
 208                                "-Djava.security.manager",
 209                                longFQCN);
 210         assertEquals(tr.testOutput.stream()
 211                                   .filter(s -> s.startsWith("WARNING: Exception"))
 212                                   .count(),
 213                      2, "show error each capture");
 214         // dumpLong/com/example/nosense/nosense
 215         assertEquals(Files.walk(Paths.get("dumpLong")).count(), 5, "Two lambda captured failed to log");
 216         tr.assertZero("Should still return 0");
 217     }
 218 }