# HG changeset patch # User mseledtsov # Date 1566495331 25200 # Node ID d6a422987d86a21c8e135be52031af7d456986a4 # Parent abf6ee4c477c2b586ef956511c5b15fb8360410c 8226779: [TESTBUG] Test JFR API from Java agent Summary: Created new tests for JFR plus Java Agent Reviewed-by: egahlin diff -r abf6ee4c477c -r d6a422987d86 test/jdk/jdk/jfr/javaagent/EventEmitterAgent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/jdk/jfr/javaagent/EventEmitterAgent.java Thu Aug 22 10:35:31 2019 -0700 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.javaagent; + +import java.lang.instrument.Instrumentation; +import java.nio.file.Path; +import java.nio.file.Paths; + +import jdk.jfr.Configuration; +import jdk.jfr.Event; +import jdk.jfr.Name; +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordingFile; +import jdk.test.lib.Asserts; +import jdk.test.lib.jfr.EventNames; + +// Java agent that emits in multiple threads +public class EventEmitterAgent { + + private static final int THREADS = 5; + private static final int EVENTS_PER_THREAD = 150_000; + private static final int EXPECTED_COUNT = THREADS * EVENTS_PER_THREAD; + private static final Path DUMP_PATH = Paths.get("dump.jfr").toAbsolutePath(); + + // Called when agent is loaded from command line + public static void agentmain(String agentArgs, Instrumentation inst) throws Exception { + agentWork(); + } + + // Called when agent is dynamically loaded + public static void premain(String agentArgs, Instrumentation inst) throws Exception { + agentWork(); + } + + private static void agentWork() throws Exception { + try (Recording r = new Recording(Configuration.getConfiguration("default"))) { + r.enable(EventNames.JavaExceptionThrow); + r.setDestination(DUMP_PATH); + r.start(); + Thread[] threads = new Thread[THREADS]; + for (int i = 0; i < THREADS; i++) { + threads[i] = new Thread(EventEmitterAgent::emitEvents); + threads[i].start(); + } + for (int i = 0; i < THREADS; i++) { + threads[i].join(); + } + r.stop(); + } + } + + public static void emitEvents() { + for (int i = 0; i < EVENTS_PER_THREAD; i++) { + TestEvent e = new TestEvent(); + e.msg = "Long message that puts pressure on the string pool " + i % 100; + e.count = i; + e.thread = Thread.currentThread(); + e.clazz = String.class; + e.commit(); + if (i % 10000 == 0) { + try { + Thread.sleep(1); + } catch (InterruptedException ie) { + // ignore + } + } + } + } + + @Name("Test") + static class TestEvent extends Event { + String msg; + int count; + Thread thread; + Class clazz; + } + + public static void validateRecording() throws Exception { + long testEventCount = RecordingFile.readAllEvents(DUMP_PATH) + .stream() + .filter(e -> e.getEventType().getName().equals("Test")) + .count(); + Asserts.assertTrue(testEventCount == EXPECTED_COUNT, "Mismatch in TestEvent count"); + } +} diff -r abf6ee4c477c -r d6a422987d86 test/jdk/jdk/jfr/javaagent/JavaAgentBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/jdk/jfr/javaagent/JavaAgentBuilder.java Thu Aug 22 10:35:31 2019 -0700 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.test.lib.util; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import jdk.test.lib.Utils; +import jdk.test.lib.util.JarUtils; + +/** + * A builder for a common Java agent. + * Can be used directly from the jtreg test header to + * build a java agent before the test is executed. + * + * E.g.: + * @run driver jdk.test.lib.util.JavaAgentBuilder + * jdk.jfr.javaagent.EventEmitterAgent EventEmitterAgent.jar + * + */ +public class JavaAgentBuilder { + + /** + * Build a java agent jar file with a given agent class. + * + * @param args[0] fully qualified name of an agent class + * @param args[1] file name of the agent jar to be created + * @throws IOException + */ + public static void main(String... args) throws IOException { + String agentClass = args[0]; + String agentJar = args[1]; + System.out.println("Building " + agentJar + " with agent class " + agentClass); + build(agentClass, agentJar); + } + + /** + * Build a java agent jar file with a given agent class. + * The agent class will be added as both premain class and agent class. + * + * @param agentClass fully qualified name of an agent class + * @param agentJar file name of the agent jar to be created + * the file will be placed in a current work directory + * @throws IOException + */ + public static void build(String agentClass, String agentJar) throws IOException { + Manifest mf = new Manifest(); + Attributes attrs = mf.getMainAttributes(); + attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); + attrs.putValue("Premain-Class", agentClass); + attrs.putValue("Agent-Class", agentClass); + + Path jarFile = Paths.get(".", agentJar); + String testClasses = Utils.TEST_CLASSES; + String agentPath = agentClass.replace(".", File.separator) + ".class"; + Path agentFile = Paths.get(testClasses, agentPath); + Path dir = Paths.get(testClasses); + JarUtils.createJarFile(jarFile, mf, dir, agentFile); + System.out.println("Agent built:" + jarFile.toAbsolutePath()); + } +} diff -r abf6ee4c477c -r d6a422987d86 test/jdk/jdk/jfr/javaagent/TestLoadedAgent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/jdk/jfr/javaagent/TestLoadedAgent.java Thu Aug 22 10:35:31 2019 -0700 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @key jfr + * @summary Tests emitting events in a dynamically loaded Java agent + * @requires vm.hasJFR + * + * @library /test/lib /test/jdk + * @modules java.instrument + * + * @build jdk.jfr.javaagent.EventEmitterAgent + * + * @run driver jdk.test.lib.util.JavaAgentBuilder + * jdk.jfr.javaagent.EventEmitterAgent EventEmitterAgent.jar + * + * @run main/othervm -Djdk.attach.allowAttachSelf=true jdk.jfr.javaagent.TestLoadedAgent + */ + +package jdk.jfr.javaagent; + +import com.sun.tools.attach.VirtualMachine; +import jdk.jfr.FlightRecorder; +import jdk.jfr.FlightRecorderListener; +import jdk.jfr.Recording; +import jdk.jfr.RecordingState; + + +public class TestLoadedAgent { + public static void main(String... arg) throws Exception { + long pid = ProcessHandle.current().pid(); + VirtualMachine vm = VirtualMachine.attach(Long.toString(pid)); + vm.loadAgent("EventEmitterAgent.jar"); + vm.detach(); + EventEmitterAgent.validateRecording(); + } +} diff -r abf6ee4c477c -r d6a422987d86 test/jdk/jdk/jfr/javaagent/TestPremainAgent.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/jdk/jfr/javaagent/TestPremainAgent.java Thu Aug 22 10:35:31 2019 -0700 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @key jfr + * @summary Tests emitting event before main using a Java agent + * @requires vm.hasJFR + * + * @library /test/lib + * @modules java.instrument + * + * @build jdk.jfr.javaagent.EventEmitterAgent + * + * @run driver jdk.test.lib.util.JavaAgentBuilder + * jdk.jfr.javaagent.EventEmitterAgent EventEmitterAgent.jar + * + * @run main/othervm -javaagent:EventEmitterAgent.jar jdk.jfr.javaagent.TestPremainAgent + */ + +package jdk.jfr.javaagent; + + +public class TestPremainAgent { + public static void main(String... arg) throws Exception { + EventEmitterAgent.validateRecording(); + } +}