8213918: DumpReason JFR event is not covered by test

Reviewed-by: mgronlun, mseledtsov
This commit is contained in:
Erik Gahlin 2020-01-30 17:23:22 +01:00
parent 987ba9f3a4
commit 9cfd632ef6
4 changed files with 137 additions and 26 deletions

View File

@ -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 @@ public class TestLookForUntestedEvents {
// 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")
);

View File

@ -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);
}
}
}

View File

@ -74,22 +74,11 @@ public class TestFlush {
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!");

View File

@ -191,11 +191,6 @@ public class EventNames {
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";