| /* |
| * Copyright (c) 2018, 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.api.recording.event; |
| |
| import java.time.Instant; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import jdk.jfr.Event; |
| import jdk.jfr.Recording; |
| import jdk.jfr.consumer.RecordedEvent; |
| import jdk.test.lib.Asserts; |
| import jdk.test.lib.jfr.CommonHelper; |
| import jdk.test.lib.jfr.EventNames; |
| import jdk.test.lib.jfr.Events; |
| |
| /* |
| * @test |
| * @summary Test getStartTime() and getEndTime(). Verify startTime <= endTime |
| * @key jfr |
| * @library /test/lib |
| * @run main/othervm jdk.jfr.api.recording.event.TestEventTime |
| */ |
| public class TestEventTime { |
| |
| static List<TimeEvent> actualOrder = new ArrayList<>(); |
| |
| public static void main(String[] args) throws Throwable { |
| Recording r = new Recording(); |
| r.enable(MyEvent.class).withoutStackTrace(); |
| // for debugging time related issues |
| r.enable(EventNames.CPUTimeStampCounter); |
| r.start(); |
| MyEvent event1 = beginEvent(1); |
| MyEvent event2 = beginEvent(2); |
| endEvent(event1); |
| MyEvent event3 = beginEvent(3); |
| endEvent(event2); |
| endEvent(event3); |
| |
| r.stop(); |
| |
| List<RecordedEvent> events = Events.fromRecording(r); |
| |
| RecordedEvent recEvent1 = findEvent(1, events); |
| RecordedEvent recEvent2 = findEvent(2, events); |
| RecordedEvent recEvent3 = findEvent(3, events); |
| |
| List<TimeEvent> recordedOrder = new ArrayList<>(); |
| recordedOrder.add(new TimeEvent(1, true, recEvent1.getStartTime())); |
| recordedOrder.add(new TimeEvent(1, false, recEvent1.getEndTime())); |
| recordedOrder.add(new TimeEvent(2, true, recEvent2.getStartTime())); |
| recordedOrder.add(new TimeEvent(2, false, recEvent2.getEndTime())); |
| recordedOrder.add(new TimeEvent(3, true, recEvent3.getStartTime())); |
| recordedOrder.add(new TimeEvent(3, false, recEvent3.getEndTime())); |
| Collections.sort(recordedOrder); |
| |
| printTimedEvents("Actual order", actualOrder); |
| printTimedEvents("Recorded order", recordedOrder); |
| |
| for (int i = 0; i < 6; i++) { |
| if (!actualOrder.get(i).equals(recordedOrder.get(i))) { |
| throw new Exception("Event times not in expected order. Was " + recordedOrder.get(1) + " but expected " + actualOrder.get(1)); |
| } |
| } |
| } |
| |
| private static void printTimedEvents(String heading, List<TimeEvent> recordedOrder) { |
| System.out.println(); |
| System.out.println(heading); |
| System.out.println("======================"); |
| for (TimeEvent t : recordedOrder) { |
| System.out.println(t.toString()); |
| } |
| } |
| |
| private static MyEvent beginEvent(int id) throws Exception { |
| MyEvent event = new MyEvent(id); |
| event.begin(); |
| if (!CommonHelper.hasFastTimeEnabled()) { |
| CommonHelper.waitForSystemCurrentMillisToChange();; |
| } |
| actualOrder.add(new TimeEvent(id, true)); |
| return event; |
| } |
| |
| private static void endEvent(MyEvent event) throws Exception { |
| event.end(); |
| if (!CommonHelper.hasFastTimeEnabled()) { |
| CommonHelper.waitForSystemCurrentMillisToChange();; |
| } |
| event.commit(); |
| actualOrder.add(new TimeEvent(event.id, false)); |
| } |
| |
| private final static class TimeEvent implements Comparable<TimeEvent> { |
| long id; |
| private boolean begin; |
| private Instant time; |
| |
| public TimeEvent(int id, boolean begin) { |
| this.id = id; |
| this.begin = begin; |
| } |
| |
| public TimeEvent(int id, boolean begin, Instant time) { |
| this(id, begin); |
| this.time = time; |
| } |
| |
| @Override |
| public int compareTo(TimeEvent that) { |
| return this.time.compareTo(that.time); |
| } |
| |
| public String toString() { |
| StringBuilder sb = new StringBuilder(); |
| if (begin) { |
| sb.append("begin"); |
| } else { |
| sb.append("end"); |
| } |
| sb.append("Event"); |
| sb.append("("); |
| sb.append(id); |
| sb.append(")"); |
| return sb.toString(); |
| } |
| |
| public boolean equals(Object thatObject) { |
| if (thatObject instanceof TimeEvent) { |
| TimeEvent that = (TimeEvent) thatObject; |
| return that.id == this.id && that.begin == this.begin; |
| } |
| return false; |
| } |
| } |
| |
| private static RecordedEvent findEvent(int id, List<RecordedEvent> events) { |
| for (RecordedEvent event : events) { |
| if (!event.getEventType().getName().equals(EventNames.CPUTimeStampCounter)) { |
| int eventId = Events.assertField(event, "id").getValue(); |
| if (eventId == id) { |
| return event; |
| } |
| } |
| } |
| Asserts.fail("No event with id " + id); |
| return null; |
| } |
| |
| private static class MyEvent extends Event { |
| int id; |
| |
| public MyEvent(int id) { |
| this.id = id; |
| } |
| } |
| } |