/* * 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.stress.javaagent; import com.sun.tools.attach.VirtualMachine; import java.nio.file.Path; import java.nio.file.Paths; import java.util.jar.Attributes; import java.util.jar.Manifest; import jdk.jfr.consumer.RecordingFile; import jdk.test.lib.Asserts; import jdk.test.lib.Utils; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.JarUtils; /** * @test * @key jfr * @summary Test event generation from within java agent * @requires vm.hasJFR * * @library /test/lib /test/jdk * @modules java.instrument * * @build JavaAgent SimpleLoop * @run driver jdk.jfr.stress.javaagent.TestEventsFromJavaAgent prepareAgent * @run main/othervm -javaagent:StressEventsAgent.jar jdk.jfr.stress.javaagent.TestEventsFromJavaAgent test */ public class TestEventsFromJavaAgent { public static void main(String... args) throws Exception { if(args[0].equals("prepareAgent")) { prepareAgent(); return; } System.out.println("Hello from TestEventsFromJavaAgent"); // Test Case 01: the test runs in premain() in this process. // The recording file can get fairly large; delete it upon exit. JavaAgent.RECORDING_FILE_PREMAIN.toFile().deleteOnExit(); validateRecording(JavaAgent.RECORDING_FILE_PREMAIN); // Test Case 02: the test runs in agentmain() in a child process. testWithDynamicallyLoadedAgent(); JavaAgent.RECORDING_FILE_AGENTMAIN.toFile().deleteOnExit(); validateRecording(JavaAgent.RECORDING_FILE_AGENTMAIN); } // Run simple loop in a child process, // attach and dynamically load the agent to record events. private static void testWithDynamicallyLoadedAgent() throws Exception { ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("jdk.jfr.stress.javaagent.SimpleLoop", "20"); Process p = pb.start(); VirtualMachine vm = VirtualMachine.attach("" + p.pid()); vm.loadAgent("StressEventsAgent.jar"); vm.detach(); p.waitFor(); OutputAnalyzer out = new OutputAnalyzer(p); System.out.println("========= child process output:"); System.out.println(out.getOutput()); System.out.println("========= "); out.shouldHaveExitValue(0) .shouldContain("agentmain(): done") .shouldNotContain("agentmain(): exception"); } private static void prepareAgent() throws Exception { Manifest mf = new Manifest(); Attributes attrs = mf.getMainAttributes(); attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0"); attrs.putValue("Premain-Class", "jdk.jfr.stress.javaagent.JavaAgent"); attrs.putValue("Agent-Class", "jdk.jfr.stress.javaagent.JavaAgent"); JarUtils.createJarFile(Paths.get(".", "StressEventsAgent.jar"), mf, Paths.get(Utils.TEST_CLASSES), Paths.get(Utils.TEST_CLASSES, "jdk", "jfr", "stress", "javaagent", "JavaAgent.class")); } private static void validateRecording(Path recordingFile) throws Exception { String eventName = "jdk.jfr.stress.javaagent.TestEvent"; long testEventCount = RecordingFile.readAllEvents(recordingFile).stream() .filter(e -> e.getEventType().getName().equals(eventName)) .count(); long expectedEventCount = JavaAgent.NUMBER_OF_EVENT_GENERATOR_THREADS * JavaAgent.NUMBER_OF_EVENTS_PER_THREAD; Asserts.assertTrue(testEventCount == expectedEventCount, "Mismatch in TestEvent count"); } }