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.jvm; 27 28 import java.io.IOException; 29 import java.time.Duration; 30 import java.util.ArrayList; 31 import java.util.Collections; 32 import java.util.HashMap; 33 import java.util.List; 34 import java.util.Map; 35 36 import jdk.jfr.Event; 37 import jdk.jfr.EventFactory; 38 import jdk.jfr.Recording; 39 import jdk.jfr.ValueDescriptor; 40 import jdk.jfr.consumer.RecordedEvent; 41 import jdk.test.lib.Asserts; 42 import jdk.test.lib.jfr.EventTypePrototype; 43 import jdk.test.lib.jfr.Events; 44 import jdk.test.lib.jfr.Stressor; 45 46 /** 47 * @test TestLargeJavaEvent512k 48 * @key jfr 49 * 50 * @library /lib / 51 * 52 * @run main/othervm jdk.jfr.jvm.TestLargeJavaEvent512k 53 */ 54 public class TestLargeJavaEvent512k { 55 static boolean error; 56 static void setError() { 57 error = true; 58 } 59 static boolean hasError() { 60 return error; 61 } 62 63 public static void main(String... args) throws Exception { 64 final String name = "MyLargeJavaEvent512k"; // name of synthetically generated event 65 final String fieldNamePrefix = "myfield"; 66 final int numberOfFields = 64; // 64*8k = 512k event size 67 final Map<String, Object> eventMap = new HashMap<>(); 68 final int numberOfThreads = 10; // 10 threads will run the test 69 final int numberOfEventsPerThread = 50; // each thread will generate 50 events 70 71 List<ValueDescriptor> fields = new ArrayList<>(); 72 for (int i = 0; i < numberOfFields; ++i) { 73 String fieldName = fieldNamePrefix + i; 74 eventMap.put(fieldName, largeString()); 75 fields.add(new ValueDescriptor(String.class, fieldName)); 76 } 77 78 EventTypePrototype prototype = new EventTypePrototype(name,Collections.emptyList(), fields); 79 80 EventFactory ef = EventFactory.create(prototype.getAnnotations(), prototype.getFields()); 81 82 Recording r = new Recording(); 83 r.enable(prototype.getName()).withThreshold(Duration.ofNanos(0)).withoutStackTrace(); 84 r.start(); 85 86 Thread.UncaughtExceptionHandler eh = (t, e) -> TestLargeJavaEvent512k.setError(); 87 88 Stressor.execute(numberOfThreads, eh, () -> { 89 for (int n = 0; n < numberOfEventsPerThread; ++n) { 90 try { 91 Event event = ef.newEvent(); 92 setEventValues(event, ef, prototype, eventMap); 93 event.commit(); 94 Thread.sleep(1); 95 } catch (Exception ex) { 96 throw new RuntimeException(ex); 97 } 98 } 99 }); 100 r.stop(); 101 try { 102 if (hasError()) { 103 throw new RuntimeException("One (or several) of the threads had an exception/error, test failed"); 104 } 105 verifyEvents(r, numberOfThreads, numberOfEventsPerThread, eventMap); 106 } finally { 107 r.close(); 108 } 109 } 110 111 private static void verifyEvents(Recording r, int numberOfThreads, int iterations, Map<String, Object> fields) throws IOException { 112 List<RecordedEvent> recordedEvents = Events.fromRecording(r); 113 Events.hasEvents(recordedEvents); 114 int eventCount = 0; 115 for (RecordedEvent re : recordedEvents) { 116 verify(re, fields); 117 eventCount++; 118 } 119 System.out.println("Number of expected events: " + numberOfThreads * iterations); 120 System.out.println("Number of events found: " + eventCount); 121 Asserts.assertEquals(numberOfThreads * iterations, eventCount, "Unexpected number of events"); 122 } 123 124 // each row is 64 chars for 128 rows == 8192 chars 125 private static String largeString() { 126 StringBuilder builder = new StringBuilder(); 127 for (int i = 0; i < 128; ++i) { 128 builder.append("cygwinapacygwinapacygwinapacygwinapacygwinapacygwinapacygwinapa "); 129 } 130 return builder.toString(); 131 } 132 133 private static void setEventValues(Event event, EventFactory f, EventTypePrototype prototype, Map<String, Object> fields) { 134 for (Map.Entry<String, Object> entry : fields.entrySet()) { 135 int index = prototype.getFieldIndex(entry.getKey()); 136 event.set(index, entry.getValue()); 137 } 138 } 139 140 private static void verify(RecordedEvent event, Map<String, Object> fields) { 141 for (Map.Entry<String, Object> entry : fields.entrySet()) { 142 String fieldName = entry.getKey(); 143 Object value = event.getValue(fieldName); 144 Object expected = fields.get(fieldName); 145 Asserts.assertEQ(value, expected); 146 } 147 } 148 }