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