1 /*
   2  * Copyright (c) 2016, 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 package jdk.jfr.api.event;
  26 
  27 import java.time.Duration;
  28 import java.util.ArrayList;
  29 import java.util.List;
  30 
  31 import jdk.jfr.Recording;
  32 import jdk.jfr.consumer.RecordedEvent;
  33 import jdk.test.lib.Asserts;
  34 import jdk.test.lib.jfr.CommonHelper;
  35 import jdk.test.lib.jfr.EventNames;
  36 import jdk.test.lib.jfr.Events;
  37 import jdk.test.lib.jfr.SimpleEvent;
  38 
  39 /*
  40  * @test
  41  * @summary Test for RecordedEvent.getDuration()
  42  * @key jfr
  43  * @library /test/lib
  44  * @run main/othervm jdk.jfr.api.event.TestGetDuration
  45  */
  46 public class TestGetDuration {
  47 
  48     private static final int DURATIONAL_EVENT_ID = 1;
  49     private static final int INSTANT_EVENT_ID = 2;
  50 
  51     public static void main(String[] args) throws Exception {
  52         verifyCustomEvents();
  53         verifyNativeEvents();
  54     }
  55 
  56     private static void verifyCustomEvents() throws Exception {
  57         boolean fastTimeEnabled = CommonHelper.hasFastTimeEnabled();
  58         System.out.println("Fast time enabled: " + fastTimeEnabled);
  59         Recording r = new Recording();
  60         r.enable(SimpleEvent.class).withoutStackTrace();
  61         r.enable("com.oracle.jdk.CPUTimeStampCounter"); // for debugging purposes
  62         r.start();
  63 
  64         SimpleEvent durational = new SimpleEvent();
  65         durational.begin();
  66         durational.id = DURATIONAL_EVENT_ID;
  67         if (!fastTimeEnabled) {
  68             // if we have a low resolution clock sleep until time changes
  69             CommonHelper.waitForSystemCurrentMillisToChange();
  70         }
  71         durational.end();
  72         durational.commit();
  73 
  74         SimpleEvent instant = new SimpleEvent();
  75         instant.id = INSTANT_EVENT_ID;
  76         instant.commit();
  77 
  78         r.stop();
  79 
  80         List<RecordedEvent> recordedEvents = Events.fromRecording(r);
  81         List<RecordedEvent> testEvents = new ArrayList<>();
  82         for (RecordedEvent e : recordedEvents) {
  83             System.out.println(e); // for debugging time related issues
  84             if (!e.getEventType().getName().equals("com.oracle.jdk.CPUTimeStampCounter")) {
  85                 testEvents.add(e);
  86             }
  87         }
  88         Events.hasEvents(testEvents);
  89         for (RecordedEvent re : testEvents) {
  90             int id = re.getValue("id");
  91             Asserts.assertEquals(re.getDuration(), Duration.between(re.getStartTime(), re.getEndTime()));
  92             switch (id) {
  93                 case DURATIONAL_EVENT_ID:
  94                     Asserts.assertTrue(!re.getDuration().isNegative() && !re.getDuration().isZero());
  95                     break;
  96                 case INSTANT_EVENT_ID:
  97                     Asserts.assertTrue(re.getDuration().isZero());
  98                     break;
  99             }
 100         }
 101     }
 102 
 103     private static void verifyNativeEvents() throws Exception {
 104         Recording r = new Recording();
 105         r.enable(EventNames.JVMInformation);
 106         r.enable(EventNames.ThreadSleep);
 107         r.start();
 108         // Should trigger a sleep event even if we
 109         // have a low resolution clock
 110         Thread.sleep(200);
 111         r.stop();
 112         List<RecordedEvent> recordedEvents = Events.fromRecording(r);
 113         Events.hasEvents(recordedEvents);
 114         for (RecordedEvent re : recordedEvents) {
 115             Asserts.assertEquals(re.getDuration(), Duration.between(re.getStartTime(), re.getEndTime()));
 116             switch (re.getEventType().getName()) {
 117                 case EventNames.JVMInformation:
 118                     Asserts.assertTrue(re.getDuration().isZero());
 119                     break;
 120                 case EventNames.ThreadSleep:
 121                     Asserts.assertTrue(!re.getDuration().isNegative() && !re.getDuration().isZero());
 122                     break;
 123                 default:
 124                     Asserts.fail("Unexpected event: " + re);
 125                     break;
 126             }
 127         }
 128     }
 129 
 130 }