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.event; 27 28 import java.time.Duration; 29 30 import jdk.jfr.Event; 31 import jdk.jfr.Recording; 32 import jdk.test.lib.Asserts; 33 34 /** 35 * @test 36 * @summary Test enable/disable event and verify recording has expected events. 37 * @key jfr 38 * 39 * @library /lib / 40 * @run main/othervm -XX:+LogJFR jdk.jfr.api.event.TestShouldCommit 41 */ 42 43 public class TestShouldCommit { 44 45 public static void main(String[] args) throws Exception { 46 Recording rA = new Recording(); 47 48 verifyShouldCommitFalse(); // No active recordings 49 50 rA.start(); 51 rA.enable(MyEvent.class).withoutThreshold(); // recA=all 52 verifyShouldCommitTrue(); 53 54 setThreshold(rA, 100); // recA=100 55 verifyThreshold(100); 56 57 setThreshold(rA, 200); // recA=200 58 verifyThreshold(200); 59 60 Recording rB = new Recording(); 61 verifyThreshold(200); // recA=200, recB=not started 62 63 rB.start(); 64 verifyThreshold(200); // recA=200, recB=not specified, settings from recA is used. 65 66 setThreshold(rB, 100); // recA=200, recB=100 67 verifyThreshold(100); 68 69 setThreshold(rB, 300); // recA=200, recB=300 70 verifyThreshold(200); 71 72 rA.disable(MyEvent.class); // recA=disabled, recB=300 73 74 verifyThreshold(300); 75 76 rB.disable(MyEvent.class); // recA=disabled, recB=disabled 77 verifyShouldCommitFalse(); 78 79 setThreshold(rA, 200); // recA=200, recB=disabled 80 verifyThreshold(200); 81 82 rB.enable(MyEvent.class).withoutThreshold(); // recA=200, recB=all 83 verifyShouldCommitTrue(); 84 85 setThreshold(rB, 100); // recA=200, recB=100 86 verifyThreshold(100); 87 88 rB.stop(); // recA=200, recB=stopped 89 verifyThreshold(200); 90 91 rA.stop(); // recA=stopped, recB=stopped 92 verifyShouldCommitFalse(); 93 94 rA.close(); 95 rB.close(); 96 97 verifyShouldCommitFalse(); 98 } 99 100 private static void setThreshold(Recording r, long millis) { 101 r.enable(MyEvent.class).withThreshold(Duration.ofMillis(millis)); 102 } 103 104 private static void verifyThreshold(long threshold) throws Exception { 105 // Create 2 events, with different sleep time between begin() and end() 106 // First event ends just before threshold, the other just after. 107 verifyThreshold(threshold-5, threshold); 108 verifyThreshold(threshold+5, threshold); 109 } 110 111 private static void verifyThreshold(long sleepMs, long thresholdMs) throws Exception { 112 MyEvent event = new MyEvent(); 113 114 long beforeStartNanos = System.nanoTime(); 115 event.begin(); 116 long afterStartNanos = System.nanoTime(); 117 118 Thread.sleep(sleepMs); 119 120 long beforeStopNanos = System.nanoTime(); 121 event.end(); 122 long afterStopNanos = System.nanoTime(); 123 124 boolean actualShouldCommit = event.shouldCommit(); 125 126 final long safetyMarginNanos = 2000000; // Allow an error of 2 ms. May have to be tuned. 127 128 //Duration of event has been at least minDurationMicros 129 long minDurationMicros = (beforeStopNanos - afterStartNanos - safetyMarginNanos) / 1000; 130 //Duration of event has been at most maxDurationMicros 131 long maxDurationMicros = (afterStopNanos - beforeStartNanos + safetyMarginNanos) / 1000; 132 Asserts.assertLessThanOrEqual(minDurationMicros, maxDurationMicros, "Wrong min/max duration. Test error."); 133 134 long thresholdMicros = thresholdMs * 1000; 135 Boolean shouldCommit = null; 136 if (minDurationMicros > thresholdMicros) { 137 shouldCommit = new Boolean(true); // shouldCommit() must be true 138 } else if (maxDurationMicros < thresholdMicros) { 139 shouldCommit = new Boolean(false); // shouldCommit() must be false 140 } else { 141 // Too close to call. No checks are done since we are not sure of expected shouldCommit(). 142 } 143 144 System.out.printf( 145 "threshold=%d, duration=[%d-%d], shouldCommit()=%b, expected=%s%n", 146 thresholdMicros, minDurationMicros, maxDurationMicros, actualShouldCommit, 147 (shouldCommit!=null ? shouldCommit : "too close to call")); 148 149 try { 150 if (shouldCommit != null) { 151 Asserts.assertEquals(shouldCommit.booleanValue(), actualShouldCommit, "Wrong shouldCommit()"); 152 } 153 } catch (Exception e) { 154 System.out.println("Unexpected value of shouldCommit(). Searching for active threshold..."); 155 searchThreshold(thresholdMs, 2000+thresholdMs); 156 throw e; 157 } 158 } 159 160 // Sleeps until shouldCommit() is true, or give up. Used for logging. 161 private static void searchThreshold(long expectedMs, long maxMs) throws Exception { 162 long start = System.nanoTime(); 163 long stop = start + maxMs * 1000000; 164 165 MyEvent event = new MyEvent(); 166 event.begin(); 167 event.end(); 168 169 while (!event.shouldCommit() && System.nanoTime() < stop) { 170 Thread.sleep(1); 171 event.end(); 172 } 173 long durationMicros = (System.nanoTime() - start) / 1000; 174 long expectedMicros = expectedMs * 1000; 175 System.out.printf("shouldCommit()=%b after %,d ms, expected %,d%n", event.shouldCommit(), durationMicros, expectedMicros); 176 } 177 178 private static void verifyShouldCommitFalse() { 179 MyEvent event = new MyEvent(); 180 event.begin(); 181 event.end(); 182 Asserts.assertFalse(event.shouldCommit(), "shouldCommit() expected false"); 183 } 184 185 private static void verifyShouldCommitTrue() { 186 MyEvent event = new MyEvent(); 187 event.begin(); 188 event.end(); 189 Asserts.assertTrue(event.shouldCommit(), "shouldCommit() expected true"); 190 } 191 192 private static class MyEvent extends Event { 193 } 194 195 }