1 /*
2  * Copyright (c) 2015, 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.
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 
24 import java.net.BindException;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.function.Predicate;
28 import java.util.regex.Pattern;
29 import org.testng.annotations.*;
30 import static org.testng.Assert.*;
31 
32 import jdk.test.lib.process.ProcessTools;
33 
34 /**
35  * @test
36  * @bug 8023093 8138748 8142398
37  * @summary Performs a sanity test for the ManagementAgent.status diagnostic command.
38  *          Management agent may be disabled, started (only local connections) and started.
39  *          The test asserts that the expected text is being printed.
40  *
41  * @library /test/lib
42  *
43  * @build PortAllocator TestApp ManagementAgentJcmd
44  *        JMXStatusTest JMXStatus1Test JMXStatus2Test
45  * @run testng/othervm -XX:+UsePerfData JMXStatus1Test
46  * @run testng/othervm -XX:+UsePerfData JMXStatus2Test
47  */
48 abstract public class JMXStatusTest {
49     private final static String TEST_APP_NAME = "TestApp";
50 
51     protected final static Pattern DISABLED_AGENT_STATUS = Pattern.compile(
52         "Agent\\s*\\: disabled$"
53     );
54 
55     protected final static Pattern LOCAL_AGENT_STATUS = Pattern.compile(
56         "Agent\\s*\\:\\s*enabled\\n+" +
57         "Connection Type\\s*\\:\\s*local\\n+" +
58         "Protocol\\s*\\:\\s*[a-z]+\\n+" +
59         "Host\\s*\\:\\s*.+\\n+" +
60         "URL\\s*\\:\\s*service\\:jmx\\:.+\\n+" +
61         "Properties\\s*\\:\\n+(\\s*\\S+\\s*=\\s*\\S+(\\s+\\[default\\])?\\n*)+",
62         Pattern.MULTILINE
63     );
64 
65     protected final static Pattern REMOTE_AGENT_STATUS = Pattern.compile(
66         "Agent\\s*\\: enabled\\n+" +
67         ".*" +
68         "Connection Type\\s*\\: remote\\n+" +
69         "Protocol\\s*\\: [a-z]+\\n+" +
70         "Host\\s*\\: .+\\n+" +
71         "URL\\s*\\: service\\:jmx\\:.+\\n+" +
72         "Properties\\s*\\:\\n+(\\s*\\S+\\s*=\\s*\\S+(\\s+\\[default\\])?\\n*)+",
73         Pattern.MULTILINE | Pattern.DOTALL
74     );
75 
76     private static ProcessBuilder testAppPb;
77     private Process testApp;
78 
79     private ManagementAgentJcmd jcmd;
80 
getCustomVmArgs()81     abstract protected List<String> getCustomVmArgs();
getDefaultPattern()82     abstract protected Pattern getDefaultPattern();
83 
84     @BeforeTest
setup()85     public final void setup() throws Exception {
86         List<String> args = new ArrayList<>();
87         args.add("-cp");
88         args.add(System.getProperty("test.class.path"));
89         args.add("-XX:+UsePerfData");
90         args.addAll(getCustomVmArgs());
91         args.add(TEST_APP_NAME);
92         testAppPb = ProcessTools.createJavaProcessBuilder(args.toArray(new String[args.size()]));
93 
94         jcmd = new ManagementAgentJcmd(TEST_APP_NAME, false);
95     }
96 
97     @BeforeMethod
startTestApp()98     public final void startTestApp() throws Exception {
99         testApp = ProcessTools.startProcess(
100             TEST_APP_NAME, testAppPb,
101             (Predicate<String>)l->l.trim().equals("main enter")
102         );
103     }
104 
105     @AfterMethod
stopTestApp()106     public final void stopTestApp() throws Exception {
107         testApp.getOutputStream().write(1);
108         testApp.getOutputStream().flush();
109         testApp.waitFor();
110         testApp = null;
111     }
112 
113     @Test
testAgentLocal()114     public final void testAgentLocal() throws Exception {
115         jcmd.startLocal();
116         String status = jcmd.status();
117 
118         assertStatusMatches(LOCAL_AGENT_STATUS, status);
119     }
120 
121     @Test
testAgentRemote()122     public final void testAgentRemote() throws Exception {
123         while (true) {
124             try {
125                 int[] ports = PortAllocator.allocatePorts(1);
126                 jcmd.start(
127                     "jmxremote.port=" + ports[0],
128                     "jmxremote.authenticate=false",
129                     "jmxremote.ssl=false"
130                 );
131                 String status = jcmd.status();
132 
133                 assertStatusMatches(REMOTE_AGENT_STATUS, status);
134                 return;
135             } catch (BindException e) {
136                 System.out.println("Failed to allocate ports. Retrying ...");
137             }
138         }
139     }
140 
141     @Test
testAgentDefault()142     public final void testAgentDefault() throws Exception {
143         String status = jcmd.status();
144         assertStatusMatches(getDefaultPattern(), status);
145     }
146 
assertStatusMatches(Pattern expected, String value)147     protected void assertStatusMatches(Pattern expected, String value) {
148         assertStatusMatches(expected, value, "");
149     }
150 
assertStatusMatches(Pattern expected, String value, String msg)151     protected void assertStatusMatches(Pattern expected, String value, String msg) {
152         int idx = value.indexOf('\n');
153         if (idx > -1) {
154             value = value.substring(idx + 1).trim();
155             assertTrue(expected.matcher(value).find(), msg);
156         } else {
157             fail("The management agent status must contain more then one line of text");
158         }
159     }
160 }
161