/* * Copyright (c) 2018, 2019, 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.testlibrary.Asserts; import jdk.testlibrary.jfr.CommonHelper; import jdk.testlibrary.jfr.EventNames; import jdk.testlibrary.jfr.Events; /* * @test * @summary Test getStartTime() and getEndTime(). Verify startTime <= endTime * @key jfr * @library /lib/testlibrary * @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; } } }