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