|
13 | 13 | import one.profiler.test.TestProcess; |
14 | 14 |
|
15 | 15 | import java.nio.file.Paths; |
16 | | -import java.util.HashMap; |
17 | | -import java.util.Map; |
| 16 | +import java.time.Instant; |
| 17 | +import java.time.temporal.ChronoUnit; |
| 18 | +import java.util.*; |
18 | 19 |
|
19 | 20 | public class JfrTests { |
20 | 21 |
|
@@ -76,4 +77,50 @@ public void parseMultiModeRecording(TestProcess p) throws Exception { |
76 | 77 | Assert.isGreater(eventsCount.get("jdk.JavaMonitorEnter"), 50); |
77 | 78 | Assert.isGreater(eventsCount.get("jdk.ObjectAllocationInNewTLAB"), 50); |
78 | 79 | } |
| 80 | + |
| 81 | + /** |
| 82 | + * Test to validate time to safepoint profiling |
| 83 | + * |
| 84 | + * @param p The test process to profile with. |
| 85 | + * @throws Exception Any exception thrown during profiling JFR output parsing. |
| 86 | + */ |
| 87 | + @Test(mainClass = Ttsp.class) |
| 88 | + public void ttsp(TestProcess p) throws Exception { |
| 89 | + p.profile("-d 3 -i 1ms --ttsp -f %f.jfr"); |
| 90 | + assert !containsSamplesOutsideWindow(p) : "Expected no samples outside of ttsp window"; |
| 91 | + } |
| 92 | + |
| 93 | + /** |
| 94 | + * Test to validate time to safepoint profiling (recording the windows only, profiling starts immediately) |
| 95 | + * |
| 96 | + * @param p The test process to profile with. |
| 97 | + * @throws Exception Any exception thrown during profiling JFR output parsing. |
| 98 | + */ |
| 99 | + @Test(mainClass = Ttsp.class) |
| 100 | + public void ttspNostop(TestProcess p) throws Exception { |
| 101 | + p.profile("-d 3 -i 1ms --ttsp --nostop -f %f.jfr"); |
| 102 | + assert containsSamplesOutsideWindow(p) : "Expected to find samples outside of ttsp window"; |
| 103 | + } |
| 104 | + |
| 105 | + private boolean containsSamplesOutsideWindow(TestProcess p) throws Exception { |
| 106 | + TreeMap<Instant, Instant> profilerWindows = new TreeMap<>(); |
| 107 | + List<RecordedEvent> samples = new ArrayList<>(); |
| 108 | + try (RecordingFile recordingFile = new RecordingFile(Paths.get(p.getFile("%f").getAbsolutePath()))) { |
| 109 | + while (recordingFile.hasMoreEvents()) { |
| 110 | + RecordedEvent event = recordingFile.readEvent(); |
| 111 | + if (event.getEventType().getName().equals("profiler.Window")) { |
| 112 | + profilerWindows.put(event.getStartTime(), event.getEndTime()); |
| 113 | + } else if (event.getEventType().getName().equals("jdk.ExecutionSample")) { |
| 114 | + samples.add(event); |
| 115 | + } |
| 116 | + } |
| 117 | + } |
| 118 | + |
| 119 | + return samples.stream().anyMatch(event -> { |
| 120 | + Map.Entry<Instant, Instant> entry = profilerWindows.floorEntry(event.getStartTime().plus(10, ChronoUnit.MILLIS)); |
| 121 | + Instant entryEnd = entry == null ? Instant.MIN : entry.getValue().plus(10, ChronoUnit.MILLIS); |
| 122 | + // check that the current sample takes place during a profiling window, allowing for a 10ms buffer at each end |
| 123 | + return entryEnd.isBefore(event.getStartTime()); |
| 124 | + }); |
| 125 | + } |
79 | 126 | } |
0 commit comments