LocalManagementTest.java revision 9351:88724be4324e
1/*
2 * Copyright (c) 2013, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24import java.io.File;
25import java.io.IOException;
26import java.lang.reflect.Method;
27import java.lang.reflect.Modifier;
28import java.nio.file.FileSystem;
29import java.nio.file.FileSystems;
30import java.nio.file.Files;
31import java.nio.file.Path;
32import java.util.ArrayList;
33import java.util.List;
34import java.util.concurrent.TimeUnit;
35import java.util.concurrent.atomic.AtomicReference;
36
37/**
38 * @test
39 * @library /lib/testlibrary
40 * @bug 5016507 6173612 6319776 6342019 6484550 8004926
41 * @summary Start a managed VM and test that a management tool can connect
42 *          without connection or username/password details.
43 *          TestManager will attempt a connection to the address obtained from
44 *          both agent properties and jvmstat buffer.
45 * @build jdk.testlibrary.ProcessTools
46 * @build jdk.testlibrary.Utils
47 * @build TestManager TestApplication
48 * @run main/othervm/timeout=300 -XX:+UsePerfData LocalManagementTest
49 */
50
51import jdk.testlibrary.ProcessTools;
52import jdk.testlibrary.Utils;
53
54public class LocalManagementTest {
55    private static final String TEST_CLASSPATH = System.getProperty("test.class.path");
56    private static final String TEST_JDK = System.getProperty("test.jdk");
57    private static int MAX_GET_FREE_PORT_TRIES = 10;
58
59    public static void main(String[] args) throws Exception {
60        try {
61            MAX_GET_FREE_PORT_TRIES = Integer.parseInt(System.getProperty("test.getfreeport.max.tries", "10"));
62        } catch (NumberFormatException ex) {
63        }
64
65        int failures = 0;
66        for(Method m : LocalManagementTest.class.getDeclaredMethods()) {
67            if (Modifier.isStatic(m.getModifiers()) &&
68                m.getName().startsWith("test")) {
69                m.setAccessible(true);
70                try {
71                    System.out.println(m.getName());
72                    System.out.println("==========");
73                    Boolean rslt = (Boolean)m.invoke(null);
74                    if (!rslt) {
75                        System.err.println(m.getName() + " failed");
76                        failures++;
77                    }
78                } catch (Exception e) {
79                    e.printStackTrace();
80                    failures++;
81                }
82            }
83        }
84        if (failures > 0) {
85            throw new Error("Test failed");
86        }
87    }
88
89    private static boolean test1() throws Exception {
90        return doTest("1", "-Dcom.sun.management.jmxremote");
91    }
92
93    private static boolean test2() throws Exception {
94        Path agentPath = findAgent();
95        if (agentPath != null) {
96            String agent = agentPath.toString();
97            return doTest("2", "-javaagent:" + agent);
98        } else {
99            return false;
100        }
101    }
102
103    /**
104     * no args (blank) - manager should attach and start agent
105     */
106    private static boolean test3() throws Exception {
107        return doTest("3", null);
108    }
109
110    /**
111     * sanity check arguments to management-agent.jar
112     */
113    private static boolean test4() throws Exception {
114        Path agentPath = findAgent();
115        if (agentPath != null) {
116
117            for (int i = 0; i < MAX_GET_FREE_PORT_TRIES; ++i) {
118                ProcessBuilder builder = ProcessTools.createJavaProcessBuilder(
119                        "-javaagent:" + agentPath.toString() +
120                                "=com.sun.management.jmxremote.port=" + Utils.getFreePort() + "," +
121                                "com.sun.management.jmxremote.authenticate=false," +
122                                "com.sun.management.jmxremote.ssl=false",
123                        "-cp",
124                        TEST_CLASSPATH,
125                        "TestApplication",
126                        "-exit"
127                );
128
129                Process prc = null;
130                final AtomicReference<Boolean> isBindExceptionThrown = new AtomicReference<>();
131                isBindExceptionThrown.set(new Boolean(false));
132                try {
133                    prc = ProcessTools.startProcess(
134                            "TestApplication",
135                            builder,
136                            (String line) -> {
137                                if (line.contains("Exception thrown by the agent : " +
138                                        "java.rmi.server.ExportException: Port already in use")) {
139                                    isBindExceptionThrown.set(new Boolean(true));
140                                }
141                            });
142
143                    prc.waitFor();
144
145                    if (prc.exitValue() == 0) {
146                        return true;
147                    }
148
149                    if (isBindExceptionThrown.get().booleanValue()) {
150                        System.out.println("'Port already in use' error detected. Try again");
151                    } else {
152                        return false;
153                    }
154                } finally {
155                    if (prc != null) {
156                        prc.destroy();
157                        prc.waitFor();
158                    }
159                }
160            }
161        }
162        return false;
163    }
164
165    /**
166     * use DNS-only name service
167     */
168    private static boolean test5() throws Exception {
169        return doTest("5", "-Dsun.net.spi.namservice.provider.1=\"dns,sun\"");
170    }
171
172    private static Path findAgent() {
173        FileSystem FS = FileSystems.getDefault();
174        Path agentPath = FS.getPath(
175            TEST_JDK, "jre", "lib", "management-agent.jar"
176        );
177        if (!isFileOk(agentPath)) {
178            agentPath = FS.getPath(
179                TEST_JDK, "lib", "management-agent.jar"
180            );
181        }
182        if (!isFileOk(agentPath)) {
183            System.err.println("Can not locate management-agent.jar");
184            return null;
185        }
186        return agentPath;
187    }
188
189    private static boolean isFileOk(Path path) {
190        return Files.isRegularFile(path) && Files.isReadable(path);
191    }
192
193    private static boolean doTest(String testId, String arg) throws Exception {
194        List<String> args = new ArrayList<>();
195        args.add("-cp");
196        args.add(TEST_CLASSPATH);
197
198        if (arg != null) {
199            args.add(arg);
200        }
201        args.add("TestApplication");
202        ProcessBuilder server = ProcessTools.createJavaProcessBuilder(
203            args.toArray(new String[args.size()])
204        );
205
206        Process serverPrc = null, clientPrc = null;
207        try {
208            final AtomicReference<String> port = new AtomicReference<>();
209            final AtomicReference<String> pid = new AtomicReference<>();
210
211            serverPrc = ProcessTools.startProcess(
212                "TestApplication(" + testId + ")",
213                server,
214                (String line) -> {
215                    if (line.startsWith("port:")) {
216                         port.set(line.split("\\:")[1]);
217                     } else  if (line.startsWith("pid:")) {
218                         pid.set(line.split("\\:")[1]);
219                     } else if (line.startsWith("waiting")) {
220                         return true;
221                     }
222                     return false;
223                },
224                5,
225                TimeUnit.SECONDS
226            );
227
228            System.out.println("Attaching test manager:");
229            System.out.println("=========================");
230            System.out.println("  PID           : " + pid.get());
231            System.out.println("  shutdown port : " + port.get());
232
233            ProcessBuilder client = ProcessTools.createJavaProcessBuilder(
234                "-cp",
235                TEST_CLASSPATH +
236                    File.pathSeparator +
237                    TEST_JDK +
238                    File.separator +
239                    "lib" +
240                    File.separator +
241                    "tools.jar",
242                "TestManager",
243                pid.get(),
244                port.get(),
245                "true"
246            );
247
248            clientPrc = ProcessTools.startProcess(
249                "TestManager",
250                client,
251                (String line) -> line.startsWith("Starting TestManager for PID"),
252                10,
253                TimeUnit.SECONDS
254            );
255
256            int clientExitCode = clientPrc.waitFor();
257            int serverExitCode = serverPrc.waitFor();
258            return clientExitCode == 0 && serverExitCode == 0;
259        } finally {
260            if (clientPrc != null) {
261                System.out.println("Stopping process " + clientPrc);
262                clientPrc.destroy();
263                clientPrc.waitFor();
264            }
265            if (serverPrc != null) {
266                System.out.println("Stopping process " + serverPrc);
267                serverPrc.destroy();
268                serverPrc.waitFor();
269            }
270        }
271    }
272}