1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * The contents of this file are subject to the terms of either the Universal Permissive License 7 * v 1.0 as shown at http://oss.oracle.com/licenses/upl 8 * 9 * or the following license: 10 * 11 * Redistribution and use in source and binary forms, with or without modification, are permitted 12 * provided that the following conditions are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions 15 * and the following disclaimer. 16 * 17 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 18 * conditions and the following disclaimer in the documentation and/or other materials provided with 19 * the distribution. 20 * 21 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to 22 * endorse or promote products derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 26 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 31 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 package org.openjdk.jmc.rjmx.test.internal; 34 35 import static org.junit.Assert.assertNotNull; 36 import static org.junit.Assert.assertTrue; 37 import static org.junit.Assert.fail; 38 39 import java.io.IOException; 40 import java.util.HashMap; 41 import java.util.HashSet; 42 import java.util.Iterator; 43 import java.util.Set; 44 45 import javax.management.MBeanAttributeInfo; 46 import javax.management.MBeanInfo; 47 import javax.management.MalformedObjectNameException; 48 import javax.management.Notification; 49 import javax.management.ObjectName; 50 51 import org.junit.After; 52 import org.junit.Before; 53 import org.junit.Test; 54 55 import org.openjdk.jmc.rjmx.internal.DefaultConnectionHandle; 56 import org.openjdk.jmc.rjmx.internal.JMXConnectionDescriptor; 57 import org.openjdk.jmc.rjmx.internal.RJMXConnection; 58 import org.openjdk.jmc.rjmx.internal.ServerDescriptor; 59 import org.openjdk.jmc.rjmx.subscription.MRI; 60 import org.openjdk.jmc.rjmx.subscription.MRI.Type; 61 import org.openjdk.jmc.rjmx.test.RjmxTestCase; 62 63 /** 64 * Testing the new RJMXConnection. 65 */ 66 @SuppressWarnings("nls") 67 public class RJMXConnectionTest extends RjmxTestCase { 68 // The MBEANS vital to console functionality. 69 public final static String[] MBEAN_NAMES = {"java.lang:type=OperatingSystem", "java.lang:type=ClassLoading", 70 "java.lang:type=Threading", "java.lang:type=Compilation", "java.lang:type=Memory", 71 "java.lang:type=Runtime", "java.lang:type=MemoryPool,*", "java.lang:type=GarbageCollector,*", 72 "java.lang:type=MemoryManager,*"}; 73 74 public final static String[] MBEAN_CLASS_NAMES = {"sun.management.RuntimeImpl"}; 75 76 public static final int MIN_CPUS = 1; 77 public static final int MAX_CPUS = 1024; 78 79 private MRI[] ATTRIBUTES_OS; 80 81 // Only use this one for testing! 82 private final static String[] ATTRIBUTE_SPEC_NAME = {"SpecName"}; 83 private RJMXConnection m_connection; 84 85 /** 86 * Override to avoid creating RJMXConnectorModels but still use the descriptor from superclass. 87 * 88 * @return null 89 */ 90 protected DefaultConnectionHandle createConnectorModel(JMXConnectionDescriptor descriptor) { 91 return null; 92 } 93 94 @Before 95 public void setUp() throws Exception { 96 m_connection = new RJMXConnection(m_connectionDescriptor, new ServerDescriptor(), null); 97 m_connection.connect(); 98 ATTRIBUTES_OS = getOSAttributes(); 99 } 100 101 public static MRI[] getOSAttributes() { 102 return new MRI[] {new MRI(Type.ATTRIBUTE, "java.lang:type=OperatingSystem", "SystemCpuLoad"), 103 new MRI(Type.ATTRIBUTE, "java.lang:type=OperatingSystem", "ProcessCpuLoad"), 104 new MRI(Type.ATTRIBUTE, "java.lang:type=OperatingSystem", "AvailableProcessors")}; 105 } 106 107 @After 108 public void tearDown() throws Exception { 109 m_connection.close(); 110 ATTRIBUTES_OS = null; 111 } 112 113 @Test 114 public void testConnect() { 115 assertTrue(m_connection.isConnected()); 116 } 117 118 @Test 119 public void testGetMBeanNames() throws Exception { 120 // <String, ObjectName> 121 HashMap<String, ObjectName> names = new HashMap<>(); 122 123 for (Object element : m_connection.getMBeanNames()) { 124 ObjectName o = (ObjectName) element; 125 names.put(o.toString(), o); 126 } 127 128 for (String element : MBEAN_NAMES) { 129 boolean found = false; 130 ObjectName mbeanName = new ObjectName(element); 131 for (ObjectName objectName : names.values()) { 132 if (mbeanName.apply(objectName)) { 133 found = true; 134 break; 135 } 136 } 137 assertTrue("MBean names did not contain: " + element, found); 138 } 139 } 140 141 @Test 142 public void testGetMBeanNamesAfterReconnect() throws Exception { 143 Set<String> names = getMBeanNameStrings(); 144 145 m_connection.close(); 146 m_connection.connect(); 147 148 Set<String> namesAfterReconnection = getMBeanNameStrings(); 149 150 if (!(names.containsAll(namesAfterReconnection) && namesAfterReconnection.containsAll(names))) { 151 fail("MBeans before (" + names.size() + ") and after (" + namesAfterReconnection.size() 152 + ") reconnect did not match. \nMBeans before: " + names.toString() + "\n MBeans after: " 153 + namesAfterReconnection.toString()); 154 } 155 } 156 157 /** 158 * Returns all available MBean name Strings. 159 * 160 * @throws IOException 161 * if not connected, or other exception occurred. 162 */ 163 private Set<String> getMBeanNameStrings() throws IOException { 164 HashSet<String> names = new HashSet<>(); 165 for (Object element : m_connection.getMBeanNames()) { 166 ObjectName o = (ObjectName) element; 167 names.add(o.toString()); 168 } 169 return names; 170 } 171 172 @Test 173 public void testGetMBeanInfos() throws Exception { 174 // <String, MBeanInfo> 175 HashMap<String, MBeanInfo> infos = new HashMap<>(); 176 177 @SuppressWarnings("rawtypes") 178 Iterator iter = m_connection.getMBeanInfos().values().iterator(); 179 while (iter.hasNext()) { 180 MBeanInfo info = (MBeanInfo) iter.next(); 181 infos.put(info.getClassName(), info); 182 } 183 // No longer check all the class names 184 for (String element : MBEAN_CLASS_NAMES) { 185 assertTrue("Returned infos did not contain MBean class name: " + element, infos 186 .containsKey(element)); 187 } 188 189 MBeanInfo loggingInfo = infos.get(MBEAN_CLASS_NAMES[0]); 190 assertNotNull("MBeanInfo was null for " + MBEAN_CLASS_NAMES[0], loggingInfo); 191 MBeanAttributeInfo[] attrInfo = loggingInfo.getAttributes(); 192 assertNotNull("MBeanAttributeInfo was null for " + MBEAN_CLASS_NAMES[0], attrInfo); 193 } 194 195 @Test 196 public void testGetAttributes() throws Exception { 197 for (MRI element : ATTRIBUTES_OS) { 198 Object value = m_connection.getAttributeValue(element); 199 if (element.equals(ATTRIBUTES_OS[0]) || element.equals(ATTRIBUTES_OS[1])) { 200 assertTrue(value != null); 201 } 202 if (element.equals(ATTRIBUTES_OS[2])) { 203 assertBetween(MIN_CPUS, MAX_CPUS, ((Number) value).intValue()); 204 } 205 } 206 } 207 208 @Test 209 public void testGetRuntimeMBeanAttribute() throws Exception { 210 Object attr = m_connection 211 .getAttributeValue(new MRI(Type.ATTRIBUTE, getObjectName(MBEAN_NAMES[5]), ATTRIBUTE_SPEC_NAME[0])); 212 assertNotNull(attr); 213 assertTrue(String.valueOf(attr).contains("Virtual Machine")); 214 } 215 216 public void handleRJMXException(Exception exception) { 217 fail(exception.getMessage()); 218 } 219 220 public void handleRJMXNotification(Notification n) { 221 // Ignore. Tested by the connection model. 222 } 223 224 public ObjectName getObjectName(String name) throws MalformedObjectNameException, NullPointerException { 225 ObjectName oname = new ObjectName(name); 226 return oname; 227 } 228 229 }