/**
* Helios, OpenSource Monitoring
* Brought to you by the Helios Development Group
*
* Copyright 2007, Helios Development Group and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*
*/
package org.helios.gmx;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.util.Random;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.helios.gmx.util.ClosureCompiler;
import org.helios.gmx.util.JMXHelper;
import org.helios.gmx.util.jvmcontrol.JVMLauncher;
import org.helios.gmx.util.jvmcontrol.LaunchedJVMProcess;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
/**
* <p>Title: GmxSameHostRemoteVMTestCase</p>
* <p>Description: Gmx tests for same host but remote VM connections.</p>
* <p>Company: Helios Development Group LLC</p>
* @author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.gmx.GmxSameHostRemoteVMTestCase</code></p>
*/
public class GmxSameHostRemoteVMTestCase {
/** Tracks the test name */
@Rule
public TestName testName= new TestName();
public static final Random random = new Random(System.nanoTime());
/** Instance logger */
protected final Logger LOG = Logger.getLogger(getClass());
/** This JVM's PID */
public static final String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
@BeforeClass
public static void classSetup() {
BasicConfigurator.configure();
// LoggingConfig.set(ReverseClassLoader.class, true);
// LoggingConfig.set(ByteCodeRepository.class, true);
}
/**
* {@inheritDoc}
* @see junit.framework.TestCase#setUp()
*/
@Before
public void setUp() {
String methodName = testName.getMethodName();
LOG.debug("\n\t******\n\t Test [" + getClass().getSimpleName() + "." + methodName + "]\n\t******");
}
/**
* Creates a JMXServiceURL string for the passed port
* @param port The listening port
* @return a JMXServiceURL string
*/
private String jmxUrl(int port) {
return "service:jmx:rmi:///jndi/rmi://localhost:" + port + "/jmxrmi";
}
/**
* Validates that the Runtime name of a launched JVM is the same as the launcher says it is.
*/
@Test(timeout=20000)
public void testSimpleJVMProcess() throws Exception {
int port = 18900;
Gmx gmx = null;
LaunchedJVMProcess jvmProcess = null;
try {
jvmProcess = JVMLauncher.newJVMLauncher().timeout(5000).basicPortJmx(port).start();
//jvmProcess = JVMLauncher.newJVMLauncher().timeout(50000).basicPortJmx(port).debug(1889, true, true).start();
String remotePid = jvmProcess.getProcessId();
gmx = Gmx.remote(jmxUrl(port));
String remoteRuntimeName = (String)gmx.mbean(ManagementFactory.RUNTIME_MXBEAN_NAME).getProperty("Name");
String remoteRuntimePid = remoteRuntimeName.split("@")[0];
Assert.assertEquals("The remote runtime pid", remotePid, remoteRuntimePid);
Assert.assertEquals("The remote runtime name", gmx.getJvmName(), remoteRuntimeName);
if(gmx!=null) try { gmx.close(); gmx = null; } catch (Exception e) {}
int exitCode = jvmProcess.stop();
jvmProcess = null;
Assert.assertEquals("The JVM process exit code", 0, exitCode);
} finally {
if(gmx!=null) try { gmx.close(); } catch (Exception e) {}
if(jvmProcess!=null) try { jvmProcess.destroy(); } catch (Exception e) {}
}
}
/**
* Validates simple remote closure execution against a foreign JVM by comparing MBean count and Domains.
*/
@Test(timeout=20000)
public void testRemoteClosureForMBeanCountAndDomains() throws Exception {
int port = 18900;
Gmx gmx = null;
LaunchedJVMProcess jvmProcess = null;
try {
jvmProcess = JVMLauncher.newJVMLauncher().timeout(0).basicPortJmx(port).start();
gmx = Gmx.remote(jmxUrl(port));
String[] remoteDomains = (String[])gmx.exec(ClosureCompiler.compile("return it.getDomains();"));
String[] domains = gmx.getDomains();
Assert.assertArrayEquals("The remote Domain names" , domains, remoteDomains);
Integer remoteMBeanCount = (Integer)gmx.exec(ClosureCompiler.compile("return it.getMBeanCount();"));
Integer mbeanCount = gmx.getMBeanCount();
Assert.assertEquals("The Remote MBeanCount", mbeanCount, remoteMBeanCount);
remoteMBeanCount = (Integer)gmx.exec(ClosureCompiler.compile("return it.queryNames(null, null).size();"));
Assert.assertEquals("The Remote MBeanCount", mbeanCount, remoteMBeanCount);
remoteMBeanCount = (Integer)gmx.exec(ClosureCompiler.compile("it, name, query -> return it.queryNames(name, query).size();"), null, null);
Assert.assertEquals("The Remote MBeanCount", mbeanCount, remoteMBeanCount);
ObjectName gcWildcard = JMXHelper.objectName("java.lang:type=GarbageCollector,*");
Integer gcMbeanCount = gmx.queryNames(gcWildcard, null).size();
Integer gcRemoteMbeanCount = (Integer)gmx.exec(ClosureCompiler.compile("it, name, query -> return it.queryNames(name, query).size();"), gcWildcard, null);
Assert.assertEquals("The GC MBeanCount", gcMbeanCount, gcRemoteMbeanCount);
} finally {
if(gmx!=null) try { gmx.close(); } catch (Exception e) {}
if(jvmProcess!=null) try { jvmProcess.destroy(); } catch (Exception e) {}
}
}
@Test
public void testNewMBeanOpInvoker() throws Exception {
Gmx gmx = null;
try {
gmx = Gmx.newInstance();
MetaMBean mbean = gmx.mbean(ManagementFactory.THREAD_MXBEAN_NAME);
ThreadInfo directThreadInfo = ((ThreadInfo[])ManagementFactory.getThreadMXBean().getThreadInfo(new long[]{Thread.currentThread().getId()}))[0];
CompositeData[] gmxCompDatas = (CompositeData[]) mbean.invokeMethod("getThreadInfo", new long[]{Thread.currentThread().getId()});
ThreadInfo gmxThreadInfo = ThreadInfo.from(gmxCompDatas[0]);
Assert.assertEquals("The Thread Name", directThreadInfo.getThreadName(), gmxThreadInfo.getThreadName());
Assert.assertEquals("The Thread ID", directThreadInfo.getThreadId(), gmxThreadInfo.getThreadId());
Assert.assertEquals("The Thread toString", directThreadInfo.toString(), gmxThreadInfo.toString());
} finally {
}
}
}