1 /* 2 * Copyright (c) 2016, 2019, 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.recording.misc; 26 27 import java.io.IOException; 28 import java.io.InputStream; 29 import java.nio.file.Files; 30 import java.nio.file.Path; 31 import java.nio.file.Paths; 32 import java.nio.file.StandardCopyOption; 33 import java.time.Duration; 34 import java.time.Instant; 35 import java.util.ArrayList; 36 import java.util.Arrays; 37 import java.util.List; 38 import java.util.stream.Collectors; 39 40 import jdk.jfr.Recording; 41 import jdk.jfr.consumer.RecordedEvent; 42 import jdk.jfr.consumer.RecordingFile; 43 import jdk.testlibrary.Asserts; 44 import jdk.testlibrary.jfr.SimpleEvent; 45 46 /* 47 * @test 48 * @summary A simple test for Recording.getStream() 49 * @key jfr 50 * @library /lib/testlibrary 51 * @run main/othervm jdk.jfr.api.recording.misc.TestGetStream 52 */ 53 public class TestGetStream { 54 55 private final static Instant offset = Instant.now(); 56 private static Instant previous; 57 58 public static void main(String[] args) throws Exception { 59 60 Recording recording = new Recording(); 61 Instant t0 = newTimestamp(); 62 recording.start(); 63 Instant t1 = newTimestamp(); 64 createChunkWithId(1); 65 Instant t2 = newTimestamp(); 66 createChunkWithId(2); 67 Instant t3 = newTimestamp(); 68 createChunkWithId(3); 69 Instant t4 = newTimestamp(); 70 recording.stop(); 71 Instant t5 = newTimestamp(); 72 printTimeStamp("t0", t0); 73 printTimeStamp("t1", t1); 74 printTimeStamp("t2", t2); 75 printTimeStamp("t3", t3); 76 printTimeStamp("t4", t4); 77 printTimeStamp("t5", t5); 78 79 assertContainsId(recording, "t1-t4", t1, t4, 1, 2, 3); 80 assertContainsId(recording, "t1-t3", t1, t3, 1, 2); 81 assertContainsId(recording, "t2-t4", t2, t4, 2, 3); 82 assertContainsId(recording, "t1-t2", t1, t2, 1); 83 assertContainsId(recording, "t2-t3", t2, t3, 2); 84 assertContainsId(recording, "t3-t4", t3, t4, 3); 85 assertContainsId(recording, "t0-t1", t0, t1); 86 assertContainsId(recording, "t4-t5", t4, t5); 87 88 assertEndBeforeBegin(); 89 } 90 91 private static void printTimeStamp(String name, Instant t) { 92 Duration s = Duration.between(offset, t); 93 System.out.println(name + ": " + (s.getSeconds() * 1_000_000_000L + s.getNano())); 94 } 95 96 private static void createChunkWithId(int id) throws InterruptedException { 97 newTimestamp(); // ensure every recording gets a unique start time 98 try (Recording r = new Recording()) { 99 r.start(); 100 SimpleEvent s = new SimpleEvent(); 101 s.id = id; 102 s.commit(); 103 r.stop(); 104 newTimestamp(); // ensure that start time is not equal to stop time 105 } 106 newTimestamp(); // ensure every recording gets a unique stop time 107 } 108 109 // Create a timestamp that is not same as the previous one 110 private static Instant newTimestamp() throws InterruptedException { 111 while (true) { 112 Instant now = Instant.now(); 113 if (!now.equals(previous)) { 114 previous = now; 115 return now; 116 } 117 Thread.sleep(1); 118 } 119 } 120 121 private static void assertContainsId(Recording r, String interval, Instant start, Instant end, Integer... ids) throws IOException { 122 List<Integer> idList = new ArrayList<>(Arrays.asList(ids)); 123 long time = System.currentTimeMillis(); 124 String fileName = idList.stream().map(x -> x.toString()).collect(Collectors.joining("_", "recording-get-stream_" + time + "_", ".jfr")); 125 Path file = Paths.get(fileName); 126 try (InputStream is = r.getStream(start, end)) { 127 Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING); 128 } 129 try (RecordingFile rf = new RecordingFile(file)) { 130 while (rf.hasMoreEvents()) { 131 RecordedEvent event = rf.readEvent(); 132 Integer id = event.getValue("id"); 133 Asserts.assertTrue(idList.contains(id), "Unexpected id " + id + " found in interval " + interval); 134 idList.remove(id); 135 } 136 Asserts.assertTrue(idList.isEmpty(), "Expected events with ids " + idList); 137 } 138 } 139 140 private static void assertEndBeforeBegin() throws IOException { 141 try (Recording recording = new Recording()) { 142 recording.start(); 143 recording.stop(); 144 Instant begin = Instant.now(); 145 Instant end = begin.minusNanos(1); 146 recording.getStream(begin, end); 147 Asserts.fail("Expected IllegalArgumentException has not been thrown"); 148 } catch (IllegalArgumentException x) { 149 // Caught the expected exception 150 } 151 } 152 153 }