changeset 58836:2dbf459b5577

8213918: DumpReason JFR event is not covered by test Reviewed-by: mgronlun, mseledtsov
author egahlin
date Thu, 30 Jan 2020 17:23:22 +0100
parents 41f1e738b639
children 991acdf0e37f
files test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java test/jdk/jdk/jfr/event/runtime/TestDumpReason.java test/jdk/jdk/jfr/event/runtime/TestFlush.java test/lib/jdk/test/lib/jfr/EventNames.java
diffstat 4 files changed, 137 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java	Fri Jan 24 17:41:44 2020 +0800
+++ b/test/jdk/jdk/jfr/event/metadata/TestLookForUntestedEvents.java	Thu Jan 30 17:23:22 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -77,15 +77,11 @@
     // NOTE: if the event is not covered, a bug should be open, and bug number
     // noted in the comments for this set.
     private static final Set<String> knownNotCoveredEvents = new HashSet<>(
-        // DumpReason: JDK-8213918
-        Arrays.asList("DumpReason")
     );
 
     // Experimental events
     private static final Set<String> experimentalEvents = new HashSet<>(
-      Arrays.asList(
-                    "Flush", "FlushStorage", "FlushStacktrace",
-                    "FlushStringPool", "FlushMetadata", "FlushTypeSet")
+      Arrays.asList("Flush")
     );
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/event/runtime/TestDumpReason.java	Thu Jan 30 17:23:22 2020 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.event.runtime;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import jdk.internal.misc.Unsafe;
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.jfr.EventNames;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+/**
+ * @test
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc jdk.jfr
+ *
+ * @run main/othervm jdk.jfr.event.runtime.TestDumpReason
+ */
+public class TestDumpReason {
+    private final static int ATTEMPTS = 3;
+    private final static String EVENT_NAME = EventNames.DumpReason;
+
+    static class DumpCrash {
+        public static void main(String[] args) {
+            try (Recording r = new Recording()) {
+                r.enable(EVENT_NAME);
+                r.start();
+                Unsafe.getUnsafe().putInt(0L, 0);
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        test(DumpCrash.class, "Crash");
+    }
+
+    private static void test(Class<?> crasher, String reason) throws Exception {
+        // The JVM may be in a state it can't recover from, so try three times
+        // before concluding functionality is not working.
+        for (int attempt = 0; attempt < ATTEMPTS; attempt++) {
+            try {
+                verify(runProcess(crasher), reason);
+                return;
+            } catch (Exception e) {
+                System.out.println("Attempt " + attempt + ". Verification failed:");
+                System.out.println(e.getMessage());
+                System.out.println("Retrying...");
+                System.out.println();
+            } catch (OutOfMemoryError | StackOverflowError e) {
+                // Could happen if file is corrupt and parser loops or
+                // tries to allocate more memory than what is available
+                return;
+            }
+        }
+        throw new Exception(ATTEMPTS + " attempts with failure!");
+    }
+
+    private static long runProcess(Class<?> crasher) throws Exception {
+        System.out.println("Test case for " + crasher.getName());
+        Process p = ProcessTools.createJavaProcessBuilder(
+                true,
+                "-Xmx64m",
+                "-XX:-CreateCoredumpOnCrash",
+                "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED",
+                crasher.getName(),
+                ""
+                ).start();
+
+        OutputAnalyzer output = new OutputAnalyzer(p);
+        System.out.println("========== Crasher process output:");
+        System.out.println(output.getOutput());
+        System.out.println("==================================");
+
+        return p.pid();
+    }
+
+    private static void verify(long pid, String reason) throws Exception {
+        String fileName = "hs_err_pid" + pid + ".jfr";
+        Path file = Paths.get(fileName).toAbsolutePath().normalize();
+        try {
+            Asserts.assertTrue(Files.exists(file), "No emergency jfr recording file " + file + " exists");
+            Asserts.assertNotEquals(Files.size(file), 0L, "File length 0. Should at least be some bytes");
+            System.out.printf("File size=%d%n", Files.size(file));
+
+            List<RecordedEvent> events = RecordingFile.readAllEvents(file);
+            System.out.println(events);
+            Asserts.assertTrue(events.size() == 1, "Expected one event");
+            RecordedEvent e = events.get(0);
+            if (reason.equals(e.getString("reason"))) {
+                return;
+            }
+            throw new Exception("Could not find vaild DumpReason event");
+        } finally {
+            Files.delete(file);
+        }
+    }
+}
--- a/test/jdk/jdk/jfr/event/runtime/TestFlush.java	Fri Jan 24 17:41:44 2020 +0800
+++ b/test/jdk/jdk/jfr/event/runtime/TestFlush.java	Thu Jan 30 17:23:22 2020 +0100
@@ -74,22 +74,11 @@
 
         try (RecordingStream rs = new RecordingStream()) {
             rs.enable(EventNames.Flush);
-            rs.enable(EventNames.FlushStorage);
-            rs.enable(EventNames.FlushStacktrace);
-            rs.enable(EventNames.FlushStringPool);
-            rs.enable(EventNames.FlushMetadata);
-            rs.enable(EventNames.FlushTypeSet);
             rs.onEvent(e -> {
-                switch (e.getEventType().getName()) {
-                    case EventNames.Flush:
-                        flushEventAck = true;
-                    case EventNames.FlushStorage:
-                    case EventNames.FlushStacktrace:
-                    case EventNames.FlushStringPool:
-                    case EventNames.FlushMetadata:
-                    case EventNames.FlushTypeSet:
-                        validateFlushEvent(e);
-                        return;
+                if (e.getEventType().getName().equals(EventNames.Flush)) {
+                    flushEventAck = true;
+                    validateFlushEvent(e);
+                    return;
                 }
                 if (e.getEventType().getName().equals(CatEvent.class.getName())) {
                     System.out.println("Found cat!");
--- a/test/lib/jdk/test/lib/jfr/EventNames.java	Fri Jan 24 17:41:44 2020 +0800
+++ b/test/lib/jdk/test/lib/jfr/EventNames.java	Thu Jan 30 17:23:22 2020 +0100
@@ -191,11 +191,6 @@
     public final static String ActiveRecording = PREFIX + "ActiveRecording";
     public final static String ActiveSetting = PREFIX + "ActiveSetting";
     public static final String Flush = PREFIX + "Flush";
-    public static final String FlushStringPool = PREFIX + "FlushStringPool";
-    public static final String FlushStacktrace = PREFIX + "FlushStacktrace";
-    public static final String FlushStorage = PREFIX + "FlushStorage";
-    public static final String FlushMetadata = PREFIX + "FlushMetadata";
-    public static final String FlushTypeSet = PREFIX + "FlushTypeSet";
 
     // Diagnostics
     public static final String HeapDump = PREFIX + "HeapDump";