8241803: JFR TestThreadStartEndEvents.java failed due to "RuntimeException: Wrong thread id"

Reviewed-by: egahlin
This commit is contained in:
Markus Grönlund 2020-07-07 16:20:30 +02:00
parent 653af300cc
commit 1b3a127d06

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -48,16 +48,19 @@ import jdk.test.lib.jfr.Events;
*/ */
/** /**
* Starts and stops a number of threads in order. * Starts a number of threads in order and verifies
* Verifies that events are in the same order. * that Thread Start events are in that same order.
* The order of Thread End events is non-deterministic.
*/ */
public class TestThreadStartEndEvents { public class TestThreadStartEndEvents {
private final static String EVENT_NAME_THREAD_START = EventNames.ThreadStart; private final static String EVENT_NAME_THREAD_START = EventNames.ThreadStart;
private final static String EVENT_NAME_THREAD_END = EventNames.ThreadEnd; private final static String EVENT_NAME_THREAD_END = EventNames.ThreadEnd;
private static final String THREAD_NAME_PREFIX = "TestThread-"; private static final String THREAD_NAME_PREFIX = "TestThread-";
private static int currentThreadIndex = 0;
private static int numberOfThreadStartEvents = 0;
private static int numberOfThreadEndEvents = 0;
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
// Test Java Thread Start event
Recording recording = new Recording(); Recording recording = new Recording();
recording.enable(EVENT_NAME_THREAD_START).withThreshold(Duration.ofMillis(0)); recording.enable(EVENT_NAME_THREAD_START).withThreshold(Duration.ofMillis(0));
recording.enable(EVENT_NAME_THREAD_END).withThreshold(Duration.ofMillis(0)); recording.enable(EVENT_NAME_THREAD_END).withThreshold(Duration.ofMillis(0));
@ -65,8 +68,6 @@ public class TestThreadStartEndEvents {
LatchedThread[] threads = startThreads(); LatchedThread[] threads = startThreads();
stopThreads(threads); stopThreads(threads);
recording.stop(); recording.stop();
int currThreadIndex = 0;
List<RecordedEvent> events = Events.fromRecording(recording); List<RecordedEvent> events = Events.fromRecording(recording);
events.sort((e1, e2) -> e1.getStartTime().compareTo(e2.getStartTime())); events.sort((e1, e2) -> e1.getStartTime().compareTo(e2.getStartTime()));
Events.hasEvents(events); Events.hasEvents(events);
@ -75,22 +76,37 @@ public class TestThreadStartEndEvents {
continue; continue;
} }
System.out.println("Event:" + event); System.out.println("Event:" + event);
// Threads should be started and stopped in the correct order. String eventType = event.getEventType().getName();
Events.assertEventThread(event, threads[currThreadIndex % threads.length]); switch (eventType) {
String eventName = currThreadIndex < threads.length ? EVENT_NAME_THREAD_START : EVENT_NAME_THREAD_END; case EVENT_NAME_THREAD_START:
if (!eventName.equals(event.getEventType().getName())) { validateThreadStartEvent(event, threads);
throw new Exception("Expected event of type " + eventName + " but got " + event.getEventType().getName()); break;
case EVENT_NAME_THREAD_END:
validateThreadEndEvent(event);
break;
default:
throw new RuntimeException("Test encountered an invalid event: " + eventType);
} }
if (eventName == EVENT_NAME_THREAD_START) {
Events.assertEventThread(event, "parentThread", Thread.currentThread());
RecordedStackTrace stackTrace = event.getValue("stackTrace");
assertNotNull(stackTrace);
RecordedMethod topMethod = stackTrace.getFrames().get(0).getMethod();
assertEQ(topMethod.getName(), "startThread");
}
currThreadIndex++;
} }
assertEQ(numberOfThreadStartEvents, threads.length);
assertEQ(numberOfThreadEndEvents, threads.length);
}
// The order of Thread Start events should corresponding to their start order.
private static void validateThreadStartEvent(RecordedEvent event, LatchedThread[] threads) {
Events.assertEventThread(event, threads[currentThreadIndex++]);
Events.assertEventThread(event, "parentThread", Thread.currentThread());
RecordedStackTrace stackTrace = event.getValue("stackTrace");
assertNotNull(stackTrace);
RecordedMethod topMethod = stackTrace.getFrames().get(0).getMethod();
assertEQ(topMethod.getName(), "startThread");
numberOfThreadStartEvents++;
}
// The order of Thread End events is non-deterministic. This is because the event
// is committed as part of dismantling the JavaThread in the VM, post thread.isAlive().
private static void validateThreadEndEvent(RecordedEvent event) {
numberOfThreadEndEvents++;
} }
private static LatchedThread[] startThreads() { private static LatchedThread[] startThreads() {
@ -147,5 +163,4 @@ public class TestThreadStartEndEvents {
stop.countDown(); stop.countDown();
} }
} }
} }