--- /dev/null 2017-11-09 09:38:01.297999907 +0100 +++ new/test/jdk/jdk/jfr/api/recording/event/TestEventTime.java 2018-04-09 17:14:27.252337322 +0200 @@ -0,0 +1,183 @@ +/* + * 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 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 events = Events.fromRecording(r); + + RecordedEvent recEvent1 = findEvent(1, events); + RecordedEvent recEvent2 = findEvent(2, events); + RecordedEvent recEvent3 = findEvent(3, events); + + List 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 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 { + 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 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; + } + } +}