blob: eb2b020e7e7723a62932655f727c8d72d36339e9 [file] [log] [blame]
/*
* 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;
}
}
}