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