1 /* 2 * Copyright (c) 2015, 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.io.IOException; 25 import java.net.BindException; 26 import java.util.Properties; 27 import java.util.function.Predicate; 28 import static org.testng.Assert.*; 29 import org.testng.annotations.AfterMethod; 30 import org.testng.annotations.BeforeClass; 31 import org.testng.annotations.BeforeMethod; 32 import org.testng.annotations.BeforeTest; 33 import org.testng.annotations.Test; 34 35 import jdk.testlibrary.ProcessTools; 36 37 38 /** 39 * @test 40 * @bug 8075926 41 * @summary Makes sure that the current management agent status is reflected 42 * in the related performance counters. 43 * @key intermittent 44 * @library /lib/testlibrary 45 * @modules jdk.management.agent/jdk.internal.agent 46 * @build jdk.testlibrary.* PortAllocator TestApp ManagementAgentJcmd 47 * @run testng/othervm -XX:+UsePerfData JMXStatusPerfCountersTest 48 */ 49 public class JMXStatusPerfCountersTest { 50 private final static String TEST_APP_NAME = "TestApp"; 51 52 private final static String REMOTE_STATUS_KEY = "sun.management.JMXConnectorServer.remote.enabled"; 53 54 private static ProcessBuilder testAppPb; 55 private Process testApp; 56 57 private ManagementAgentJcmd jcmd; 58 59 @BeforeClass 60 public static void setupClass() throws Exception { 61 testAppPb = ProcessTools.createJavaProcessBuilder( 62 "-XX:+UsePerfData", 63 "-cp", System.getProperty("test.class.path"), 64 TEST_APP_NAME 65 ); 66 } 67 68 @BeforeTest 69 public void setup() { 70 jcmd = new ManagementAgentJcmd(TEST_APP_NAME, false); 71 } 72 73 @BeforeMethod 74 public void startTestApp() throws Exception { 75 testApp = ProcessTools.startProcess( 76 TEST_APP_NAME, testAppPb, 77 (Predicate<String>)l->l.trim().equals("main enter") 78 ); 79 } 80 81 @AfterMethod 82 public void stopTestApp() throws Exception { 83 testApp.getOutputStream().write(1); 84 testApp.getOutputStream().flush(); 85 testApp.waitFor(); 86 testApp = null; 87 } 88 89 /** 90 * The 'sun.management.JMXConnectorServer.remote.enabled' counter must not be 91 * exported if the remote agent is not enabled. 92 * @throws Exception 93 */ 94 @Test 95 public void testNotInitializedRemote() throws Exception { 96 assertFalse( 97 getCounters().containsKey(REMOTE_STATUS_KEY), 98 "Unexpected occurrence of " + REMOTE_STATUS_KEY + " in perf counters" 99 ); 100 } 101 102 /** 103 * After enabling the remote agent the 'sun.management.JMXConnectorServer.remote.enabled' 104 * counter will be exported with value of '0' - corresponding to the actual 105 * version of the associated remote connector perf counters. 106 * @throws Exception 107 */ 108 @Test 109 public void testRemoteEnabled() throws Exception { 110 while (true) { 111 try { 112 int[] ports = PortAllocator.allocatePorts(1); 113 jcmd.start( 114 "jmxremote.port=" + ports[0], 115 "jmxremote.authenticate=false", 116 "jmxremote.ssl=false" 117 ); 118 String v = getCounters().getProperty(REMOTE_STATUS_KEY); 119 assertNotNull(v); 120 assertEquals("0", v); 121 return; 122 } catch (BindException e) { 123 System.out.println("Failed to allocate ports. Retrying ..."); 124 } 125 } 126 } 127 128 /** 129 * After disabling the remote agent the value of 'sun.management.JMXConnectorServer.remote.enabled' 130 * counter will become '-1'. 131 * @throws Exception 132 */ 133 @Test 134 public void testRemoteDisabled() throws Exception { 135 while (true) { 136 try { 137 int[] ports = PortAllocator.allocatePorts(1); 138 jcmd.start( 139 "jmxremote.port=" + ports[0], 140 "jmxremote.authenticate=false", 141 "jmxremote.ssl=false" 142 ); 143 jcmd.stop(); 144 String v = getCounters().getProperty(REMOTE_STATUS_KEY); 145 assertNotNull(v); 146 assertEquals("-1", v); 147 return; 148 } catch (BindException e) { 149 System.out.println("Failed to allocate ports. Retrying ..."); 150 } 151 } 152 } 153 154 /** 155 * Each subsequent re-enablement of the remote agent must keep the value of 156 * 'sun.management.JMXConnectorServer.remote.enabled' counter in sync with 157 * the actual version of the associated remote connector perf counters. 158 * @throws Exception 159 */ 160 @Test 161 public void testRemoteReEnabled() throws Exception { 162 while (true) { 163 try { 164 int[] ports = PortAllocator.allocatePorts(1); 165 jcmd.start( 166 "jmxremote.port=" + ports[0], 167 "jmxremote.authenticate=false", 168 "jmxremote.ssl=false" 169 ); 170 jcmd.stop(); 171 jcmd.start( 172 "jmxremote.port=" + ports[0], 173 "jmxremote.authenticate=false", 174 "jmxremote.ssl=false" 175 ); 176 177 String v = getCounters().getProperty(REMOTE_STATUS_KEY); 178 assertNotNull(v); 179 assertEquals("1", v); 180 return; 181 } catch (BindException e) { 182 System.out.println("Failed to allocate ports. Retrying ..."); 183 } 184 } 185 } 186 187 private Properties getCounters() throws IOException, InterruptedException { 188 return jcmd.perfCounters("sun\\.management\\.JMXConnectorServer\\..*"); 189 } 190 }