1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jfr.api.recording.event; 27 28 import java.time.Instant; 29 import java.util.ArrayList; 30 import java.util.Collections; 31 import java.util.List; 32 33 import jdk.jfr.Event; 34 import jdk.jfr.Recording; 35 import jdk.jfr.consumer.RecordedEvent; 36 import jdk.test.lib.Asserts; 37 import jdk.test.lib.jfr.CommonHelper; 38 import jdk.test.lib.jfr.EventNames; 39 import jdk.test.lib.jfr.Events; 40 41 /** 42 * @test 43 * @summary Test getStartTime() and getEndTime(). Verify startTime <= endTime 44 * @key jfr 45 * 46 * @library /lib / 47 * @run main/othervm jdk.jfr.api.recording.event.TestEventTime 48 */ 49 public class TestEventTime { 50 51 static List<TimeEvent> actualOrder = new ArrayList<>(); 52 53 public static void main(String[] args) throws Throwable { 54 Recording r = new Recording(); 55 r.enable(MyEvent.class).withoutStackTrace(); 56 // for debugging time related issues 57 r.enable(EventNames.CPUTimeStampCounter); 58 r.start(); 59 MyEvent event1 = beginEvent(1); 60 MyEvent event2 = beginEvent(2); 61 endEvent(event1); 62 MyEvent event3 = beginEvent(3); 63 endEvent(event2); 64 endEvent(event3); 65 66 r.stop(); 67 68 List<RecordedEvent> events = Events.fromRecording(r); 69 70 RecordedEvent recEvent1 = findEvent(1, events); 71 RecordedEvent recEvent2 = findEvent(2, events); 72 RecordedEvent recEvent3 = findEvent(3, events); 73 74 List<TimeEvent> recordedOrder = new ArrayList<>(); 75 recordedOrder.add(new TimeEvent(1, true, recEvent1.getStartTime())); 76 recordedOrder.add(new TimeEvent(1, false, recEvent1.getEndTime())); 77 recordedOrder.add(new TimeEvent(2, true, recEvent2.getStartTime())); 78 recordedOrder.add(new TimeEvent(2, false, recEvent2.getEndTime())); 79 recordedOrder.add(new TimeEvent(3, true, recEvent3.getStartTime())); 80 recordedOrder.add(new TimeEvent(3, false, recEvent3.getEndTime())); 81 Collections.sort(recordedOrder); 82 83 printTimedEvents("Actual order", actualOrder); 84 printTimedEvents("Recorded order", recordedOrder); 85 86 for (int i = 0; i < 6; i++) { 87 if (!actualOrder.get(i).equals(recordedOrder.get(i))) { 88 throw new Exception("Event times not in expected order. Was " + recordedOrder.get(1) + " but expected " + actualOrder.get(1)); 89 } 90 } 91 } 92 93 private static void printTimedEvents(String heading, List<TimeEvent> recordedOrder) { 94 System.out.println(); 95 System.out.println(heading); 96 System.out.println("======================"); 97 for (TimeEvent t : recordedOrder) { 98 System.out.println(t.toString()); 99 } 100 } 101 102 private static MyEvent beginEvent(int id) throws Exception { 103 MyEvent event = new MyEvent(id); 104 event.begin(); 105 if (!CommonHelper.hasFastTimeEnabled()) { 106 CommonHelper.waitForSystemCurrentMillisToChange();; 107 } 108 actualOrder.add(new TimeEvent(id, true)); 109 return event; 110 } 111 112 private static void endEvent(MyEvent event) throws Exception { 113 event.end(); 114 if (!CommonHelper.hasFastTimeEnabled()) { 115 CommonHelper.waitForSystemCurrentMillisToChange();; 116 } 117 event.commit(); 118 actualOrder.add(new TimeEvent(event.id, false)); 119 } 120 121 private final static class TimeEvent implements Comparable<TimeEvent> { 122 long id; 123 private boolean begin; 124 private Instant time; 125 126 public TimeEvent(int id, boolean begin) { 127 this.id = id; 128 this.begin = begin; 129 } 130 131 public TimeEvent(int id, boolean begin, Instant time) { 132 this(id, begin); 133 this.time = time; 134 } 135 136 @Override 137 public int compareTo(TimeEvent that) { 138 return this.time.compareTo(that.time); 139 } 140 141 public String toString() { 142 StringBuilder sb = new StringBuilder(); 143 if (begin) { 144 sb.append("begin"); 145 } else { 146 sb.append("end"); 147 } 148 sb.append("Event"); 149 sb.append("("); 150 sb.append(id); 151 sb.append(")"); 152 return sb.toString(); 153 } 154 155 public boolean equals(Object thatObject) { 156 if (thatObject instanceof TimeEvent) { 157 TimeEvent that = (TimeEvent) thatObject; 158 return that.id == this.id && that.begin == this.begin; 159 } 160 return false; 161 } 162 } 163 164 private static RecordedEvent findEvent(int id, List<RecordedEvent> events) { 165 for (RecordedEvent event : events) { 166 if (!event.getEventType().getName().equals(EventNames.CPUTimeStampCounter)) { 167 int eventId = Events.assertField(event, "id").getValue(); 168 if (eventId == id) { 169 return event; 170 } 171 } 172 } 173 Asserts.fail("No event with id " + id); 174 return null; 175 } 176 177 private static class MyEvent extends Event { 178 int id; 179 180 public MyEvent(int id) { 181 this.id = id; 182 } 183 } 184 }