/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, 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.jboss.test.jmx.test;
import java.io.File;
import java.net.URL;
import java.util.Collection;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import org.jboss.deployers.spi.DeploymentException;
import org.jboss.test.JBossTestCase;
import org.jboss.test.JBossTestServices;
/**
* @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
* @author Scott.Stark@jboss.org
* @author <a href="mailto:ales.justin@jboss.org">Ales Justin</a>
* @version $Revision: 82261 $
*/
public class DeployServiceUnitTestCase
extends JBossTestCase
{
// Constants -----------------------------------------------------
protected final static int INSTALLED = 0;
protected final static int CONFIGURED = 1;
protected final static int CREATED = 2;
protected final static int RUNNING = 3;
protected final static int FAILED = 4;
protected final static int STOPPED = 5;
protected final static int DESTROYED = 6;
protected final static int NOTYETINSTALLED = 7;
// Attributes ----------------------------------------------------
ObjectName serviceControllerName;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
/**
* Constructor for the DeployServiceUnitTestCase object
*
* @param name Test case name
*/
public DeployServiceUnitTestCase(String name)
{
super(name);
try
{
serviceControllerName = new ObjectName("jboss.system:service=ServiceController");
}
catch (Exception e)
{
} // end of try-catch
}
// Public --------------------------------------------------------
/**
* Test deployment and undeployment of *-service.xml files. Make sure mbeans
* are removed on undeployment
*
* @exception Exception Description of Exception
*/
public void testDeployXML() throws Exception
{
// The class loader used to locate the configuration file
ClassLoader loader = Thread.currentThread().getContextClassLoader();
assertTrue("ContextClassloader missing", loader != null);
//Get URL for deployable *service.xml file in resources
URL url = loader.getResource("jmx/test-service.xml");
if (url == null)
{
//if we're running from the jmxtest.jar, it should be here instead
url = loader.getResource("test-service.xml");
}
assertTrue("resource test-service.xml not found", url != null);
String testUrl = url.toString();
//the mbeans we are trying to deploy/undeploy
ObjectName testObjectName = new ObjectName("jboss.test:service=TestService,test=jmx");
//check they aren't there already
//Well, lets try to kill it.
if (getServer().isRegistered(testObjectName))
{
getServer().unregisterMBean(testObjectName);
} // end of if ()
assertTrue("test mbean already registered before deploy", !getServer().isRegistered(testObjectName));
try
{
//deploy the test xml doc.
deploy(testUrl);
//check deployment registered expected mbeans
assertTrue("test mbean not registered after deploy", checkState(testObjectName, RUNNING));
//deploy the test xml doc again, should undeploy and redeploy.
undeploy(testUrl);
deploy(testUrl);
//check deployment registered expected mbeans
assertTrue("test mbean not registered after redeploy", checkState(testObjectName, RUNNING));
}
finally
{
//undeploy test xml doc.
undeploy(testUrl);
}
//check they aren't there any more
assertTrue("test mbean still registered after undeploy", !getServer().isRegistered(testObjectName));
}
/** Test that a spaces in the classpath element archives attribute do not
* affect the classpath seen.
* @throws Exception
*/
public void testSpaceInClasspath() throws Exception
{
getLog().debug("+++ testSpaceInClasspath");
String testUrl = "archivestest-service.xml";
try{
//deploy the test xml doc.
deploy(testUrl);
ObjectName testObjectName = new ObjectName("test:name=TestSpaceInClasspath");
//check deployment registered expected mbeans
assertTrue(testObjectName+" registered", checkState(testObjectName, RUNNING));
}
finally
{
undeploy("archivestest-service.xml");
}
}
/**
* Test deployment and undeployment of a service archive (sar). Test that
* after undeployment classes from the sar are not available.
*
* @exception Exception Description of Exception
*/
public void testDeploySAR() throws Exception
{
//Find the testdeploy.sar file in lib directory with other jars.
String testUrl = "testdeploy.sar";
getLog().debug("testUrl is : " + testUrl);
//the mbeans we are trying to deploy/undeploy
ObjectName testObjectName = new ObjectName("test:name=TestDeployer");
ObjectName testObjectName2 = new ObjectName("test:name=TestDeployer2");
ObjectName testObjectName3 = new ObjectName("test:name=TestDeployer3");
//check they aren't there already
assertTrue("test mbean already registered before deploy", !getServer().isRegistered(testObjectName));
try
{
//deploy the test xml doc.
deploy(testUrl);
//check deployment registered expected mbeans
assertTrue("test mbean not registered after deploy", checkState(testObjectName, RUNNING));
//make sure we can create an mbean based on the class we just deployed.
try
{
getServer().createMBean("org.jboss.test.jmx.mbean.TestDeployer", testObjectName2);
}
catch (Exception e)
{
fail("could not create mbean after class loaded in jsr" + e);
}
//now remove it again
try
{
getServer().unregisterMBean(testObjectName2);
}
catch (Exception e)
{
fail("could not remove mbean after class loaded in jsr" + e);
}
//deploy the test xml doc again, should undeploy and redeploy.
undeploy(testUrl);
deploy(testUrl);
//check deployment registered expected mbeans
assertTrue("test mbean not registered after redeploy", checkState(testObjectName, RUNNING));
//undeploy test xml doc.
undeploy(testUrl);
//check they aren't there any more
assertTrue("test mbean still registered after undeploy", !getServer().isRegistered(testObjectName));
//check the class is not available
try
{
ObjectInstance oe = getServer().createMBean("org.jboss.test.jmx.mbean.TestDeployer", testObjectName3);
fail("created mbean when class should not be present: object instance: " + oe);
}
catch (ReflectionException re)
{
Exception e = re.getTargetException();
if (!(e instanceof ClassNotFoundException))
{
fail("Wrong exception thrown when trying to create mbean" + e);
}
}
//deploy the test xml doc a second time.
deploy(testUrl);
//check deployment registered expected mbeans
assertTrue("test mbean not registered after deploy", checkState(testObjectName, RUNNING));
}
finally
{
//undeploy test xml doc.
undeploy(testUrl);
}
//check they aren't there any more
assertTrue("test mbean still registered after undeploy", !getServer().isRegistered(testObjectName));
}
/**
* Test deployment and undeployment of a service archive (sar). Test that
* after undeployment classes from the sar are not available.
*
* @exception Exception Description of Exception
*/
public void testDeploySARWithJar() throws Exception
{
String testUrl = "testdeploye.sar";
getLog().debug("testUrl is : " + testUrl);
ObjectName testObjectName = new ObjectName("test:name=TestDeployerE");
deploy(testUrl);
// See that deployment registered expected mbeans
assertTrue("test:name=TestDeployerE is registered after deploy",
checkState(testObjectName, RUNNING));
// Invoke the accessUtilClass operation
Object[] args = {};
String[] sig = {};
getServer().invoke(testObjectName, "accessUtilClass", args, sig);
//make sure we can create an mbean based on the class we just deployed.
ObjectName testObjectName2 = new ObjectName("test:name=TestDeployerE#2");
getServer().createMBean("org.jboss.test.jmx.mbeane.TestDeployerE", testObjectName2);
// Remove the instance
getServer().unregisterMBean(testObjectName2);
undeploy(testUrl);
}
/**
* Test some deployment/undeployment dependencies for sars. C depends on A
* and B. Make sure undeploying A undeploys C, and redeploying A redeploys C.
*
* @exception Exception Description of Exception
*/
public void testDependsElement() throws Exception
{
//C depends on A and B
//Find the testdeploy[ABC].sar files in lib directory with other jars.
String testUrlA = "testdeploya.sar";
String testUrlB = "testdeployb.sar";
String testUrlC = "testdeployc.sar";
getLog().debug("testUrlA is : " + testUrlA);
//the mbeans we are trying to deploy/undeploy
ObjectName testObjectNameA = new ObjectName("test:name=TestDeployerA");
ObjectName testObjectNameB = new ObjectName("test:name=TestDeployerB");
ObjectName testObjectNameC = new ObjectName("test:name=TestDeployerC");
try
{
//check they aren't there already
assertTrue("test mbean already registered before deploy", !getServer().isRegistered(testObjectNameA));
assertTrue("test mbean already registered before deploy", !getServer().isRegistered(testObjectNameB));
assertTrue("test mbean already registered before deploy", !getServer().isRegistered(testObjectNameC));
//deploy the test jsrs.
deploy(testUrlA);
deploy(testUrlB);
deploy(testUrlC);
//check deployment registered expected mbeans
assertTrue("test mbean A not running after deploy", checkState(testObjectNameA, RUNNING));
assertTrue("test mbean B not running after deploy", checkState(testObjectNameB, RUNNING));
assertTrue("test mbean C not running after deploy", checkState(testObjectNameC, RUNNING));
//we'll believe from testDeployJSR that the classes are available.
//undeploy test xml doc.
undeploy(testUrlA);
//check they aren't there any more or they have stopped.
assertTrue("test mbean A still registered after undeploy of A", !getServer().isRegistered(testObjectNameA));
assertTrue("test mbean C not stopped after undeploy of A", !checkState(testObjectNameC, RUNNING));
assertTrue("test mbean B stopped after undeploy of A", checkState(testObjectNameB, RUNNING));
//Now undeploy B, should prevent redeploy of C when A is redeployed.
// not working, skip for now
undeploy(testUrlB);
assertTrue("test mbean B is registered after undeploy of B", !getServer().isRegistered(testObjectNameB));
//deploy the test jsr A doc a second time.
deploy(testUrlA);
// check deployment registered expected mbeans
assertTrue("test mbean A not registered after deploy of A", checkState(testObjectNameA, RUNNING));
assertTrue("test mbean B is registered after deploy of A", !getServer().isRegistered(testObjectNameB));
assertTrue("test mbean C started after deploy of A, with B unregistered", !checkState(testObjectNameC, RUNNING));
//now redeploy B, should also redeploy C
deploy(testUrlB);
//check deployment registered expected mbeans- all three should be registered
assertTrue("test mbean A not running after deploy of B", checkState(testObjectNameA, RUNNING));
assertTrue("test mbean B not running after deploy of B", checkState(testObjectNameB, RUNNING));
assertTrue("test mbean C not running after deploy of B", checkState(testObjectNameC, RUNNING));
//undeploy test xml doc.
undeploy(testUrlC);
undeploy(testUrlA);
undeploy(testUrlB);
//check they aren't there any more
assertTrue("test mbean still registered after undeploy", !getServer().isRegistered(testObjectNameA));
assertTrue("test mbean still registered after undeploy", !getServer().isRegistered(testObjectNameB));
assertTrue("test mbean still registered after undeploy", !getServer().isRegistered(testObjectNameC));
}
finally
{
undeploy(testUrlC);
undeploy(testUrlA);
undeploy(testUrlB);
}
}
/**
* Test depends tag D depends on mbeans in A and C.
* Deploying D should wait for A and C; undeploying A and/or C should
* undeploy D's mbean. Redeploying both should resuscitate D's mbean.
*
* @exception Exception Description of Exception
*/
public void testDependsListElement() throws Exception
{
//C depends on A and B via anonymous depends element.
//D depends on A and C via anonymous dependsList.
//Find the testdeploy[ABC].sar files in lib directory with other jars.
String testUrlA = "testdeploya.sar";
String testUrlB = "testdeployb.sar";
String testUrlC = "testdeployc.sar";
String testUrlD = "testdeployd.sar";
getLog().debug("testUrlA is : " + testUrlA);
//the mbeans we are trying to deploy/undeploy
ObjectName testObjectNameA = new ObjectName("test:name=TestDeployerA");
ObjectName testObjectNameB = new ObjectName("test:name=TestDeployerB");
ObjectName testObjectNameC = new ObjectName("test:name=TestDeployerC");
ObjectName testObjectNameD = new ObjectName("test:name=TestDeployerD");
try
{
//check they aren't there already
assertTrue("test mbean a already registered before deploy", !getServer().isRegistered(testObjectNameA));
assertTrue("test mbean b already registered before deploy", !getServer().isRegistered(testObjectNameB));
assertTrue("test mbean c already registered before deploy", !getServer().isRegistered(testObjectNameC));
assertTrue("test mbean d already registered before deploy", !getServer().isRegistered(testObjectNameD));
//deploy the test jsrs.
try
{
deploy(testUrlD);
// FIXME
// deploy does not throw an deploymentException, but it does not really
// affect the test itself - as the package stays deployed for now
// fail("D deployed without dependencies");
}
catch (DeploymentException e)
{
//expected
} // end of try-catch
assertTrue("test mbean D started with A, B, and C unregistered", !checkState(testObjectNameD, RUNNING));
//deploy A.
deploy(testUrlA);
//A should be started, not anything else
assertTrue("test mbean A not started", checkState(testObjectNameA, RUNNING));
assertTrue("test mbean D started with A, B, and C unregistered", !checkState(testObjectNameD, RUNNING));
//Deploy C, should not start since B is not deployed
try
{
deploy(testUrlC);
// FIXME
// fail("C deployed completely, D should still be waiting");
}
catch (DeploymentException e)
{
//expected
} // end of try-catch
assertTrue("test mbean C started with B unregistered", !checkState(testObjectNameC, RUNNING));
//deploy the test bean B. C and D should start too.
deploy(testUrlB);
assertTrue("test mbean A not started", checkState(testObjectNameA, RUNNING));
assertTrue("test mbean B not started", checkState(testObjectNameB, RUNNING));
assertTrue("test mbean C not started", checkState(testObjectNameC, RUNNING));
assertTrue("test mbean D not started", checkState(testObjectNameD, RUNNING));
//undeploy test xml doc.
undeploy(testUrlA);
assertTrue("test mbean A present after undeploy", !getServer().isRegistered(testObjectNameA));
assertTrue("test mbean B not started after undeploy of A", checkState(testObjectNameB, RUNNING));
assertTrue("test mbean C started after undeploy of A", !checkState(testObjectNameC, RUNNING));
assertTrue("test mbean D started after undeploy of A", !checkState(testObjectNameD, RUNNING));
undeploy(testUrlC);
undeploy(testUrlB);
undeploy(testUrlD);
//check they aren't there any more
Collection ds = (Collection)getServer().invoke(serviceControllerName,
"listDeployedNames",
new Object[] {},
new String[] {});
assertTrue("test mbean A still registered after undeploy", !ds.contains(testObjectNameA));
assertTrue("test mbean B still registered after undeploy", !ds.contains(testObjectNameB));
assertTrue("test mbean C still registered after undeploy", !ds.contains(testObjectNameC));
assertTrue("test mbean D still registered after undeploy", !ds.contains(testObjectNameD));
}
finally
{
try
{
undeploy(testUrlD);
}
catch (Exception e)
{
}
try
{
undeploy(testUrlC);
}
catch (Exception e)
{
}
try
{
undeploy(testUrlA);
}
catch (Exception e)
{
}
try
{
undeploy(testUrlB);
}
catch (Exception e)
{
}
}
}
/**
* The <code>testCopyLocalDir</code> method tests the local-directory element
* in jboss-system.xml.
*
* @exception Exception if an error occurs
*/
/*Needs a package not recognized as possibly deployable
public void testCopyLocalDir() throws Exception
{
String testUrl = "testcopylocaldir.sar";
getLog().debug("testUrl is : " + testUrl);
//the mbeans we are trying to deploy/undeploy
ObjectName testObjectName = new ObjectName("test:name=TestCopyLocalDir");
try
{
//check they aren't there already
assertTrue("test mbean already registered before deploy", !getServer().isRegistered(testObjectName));
//deploy C
deploy(testUrl);
String base = (String)getServer().getAttribute(testObjectName, "BaseDir");
File f = new File(base + File.separator + "db" + File.separator + "local-directory");
//local dir should still be there after undeploy.
undeploy(testUrl);
assertTrue("local-directory not found!", f.exists());
File[] subs = f.listFiles();
assertTrue("Subdir missing!", subs.length != 0);
//delete it, redeploy, check again - it might have been there before we deployed.
recursiveDelete(f);
deploy(testUrl);
assertTrue("local-directory not found!", f.exists());
subs = f.listFiles();
assertTrue("Subdir missing!", subs.length != 0);
recursiveDelete(f);
}
finally
{
undeploy(testUrl);
} // end of finally
}
*/
public void testConfigureError() throws Exception
{
String testUrl = "testdeploy.sar";
getLog().debug("testUrl is : " + testUrl);
//deploy sar
deploy(testUrl);
try
{
//deploy service.xml with a nonexistent attribute to cause
//a configuration error
String errorUrl = "testConfigError-service.xml";
String fixedUrl = "testConfigFixed-service.xml";
ObjectName errorObjectName = new ObjectName("test:name=TestConfigError");
try
{
deploy(errorUrl);
} catch (Exception e)
{
//??
getLog().info("deploying errorUrl gave exception: ", e);
} // end of try-catch
if (getServer().isRegistered(errorObjectName))
{
System.out.println("Erroneous mbean state: " + (Integer)getServer().getAttribute(errorObjectName, "State"));
//assertTrue("Erroneous mbean is not failed!", checkState(errorObjectName, FAILED));
} // end of if ()
//the mbeans we are trying to deploy/undeploy
try
{
undeploy(errorUrl);
} catch (Exception e)
{
} // end of try-catch
try
{
deploy(fixedUrl);
assertTrue("Corrected mbean is not registered!", checkState(errorObjectName, RUNNING));
} finally
{
undeploy(fixedUrl);
} // end of try-catch
} finally
{
undeploy(testUrl);
} // end of try-catch
}
// This test does not seem to make sense any more
/*
public void testCrashInStart() throws Exception
//Thanks to David Budworth for this test.
{
String testUrl = "testcrashinstart.sar";
getLog().debug("testUrl is : " + testUrl);
ObjectName dontCrashName = new ObjectName("CrashTest:name=DontCrash");
ObjectName crashName = new ObjectName("CrashTest:name=Crash");
//deploy sar
try
{
deploy(testUrl);
fail("expected IncompleteDeploymentException");
}
catch (DeploymentException e)
{
//expected
} // end of try-catch
try
{
assertTrue("dontcrash mbean is missing!", getServer().isRegistered(dontCrashName));
assertTrue("crash mbean is missing!", getServer().isRegistered(crashName));
assertTrue("dontcrash mbean is started!", !getServer().getAttribute(dontCrashName, "StateString").equals("Started"));
assertTrue("crash mbean is started!", !getServer().getAttribute(crashName, "StateString").equals("Started"));
undeploy(testUrl);
assertTrue("dontcrash mbean is registered!", !getServer().isRegistered(dontCrashName));
assertTrue("crash mbean is registered!", !getServer().isRegistered(crashName));
} finally
{
undeploy(testUrl);
} // end of try-catch
}
*/
public void testNullInfoInDynamicMBean() throws Exception
//Thanks to David Budworth for this test.
//Tries to deploy a DynamicMBean that returns null from getMBeanInfo.
//The Sun RI jmx registers this invalid mbean!!
{
String testUrl = "testnullinfo.sar";
getLog().debug("testUrl is : " + testUrl);
ObjectName nullInfoName = new ObjectName("NullInfoTest:name=NullInfo");
//deploy sar
try
{
deploy(testUrl);
fail("Was able to deploy invalid sar");
}
catch(Exception e)
{
getLog().debug("Deployment failed as expected", e);
boolean isRegistered = getServer().isRegistered(nullInfoName);
assertTrue("NullInfoTest:name=NullInfo is NOT registered", !isRegistered);
}
finally
{
try
{
undeploy(testUrl);
}
catch (Exception e)
{
}
try
{
getServer().unregisterMBean(nullInfoName);
}
catch (Exception e)
{
}
} // end of try-catch
}
/** Test that a sar deployment descriptor that
*/
public void testDDEntityRefs() throws Exception
{
String testUrl = "entityref.sar";
getLog().debug("testUrl is : " + testUrl);
try
{
//deploy sar
deploy(testUrl);
//check deployment registered expected mbeans
ObjectName name = new ObjectName("test:name=EntityRefTest");
assertTrue("test:name=EntityRefTest is registered after deploy", checkState(name, RUNNING));
}
finally
{
undeploy(testUrl);
}
}
/** Test that a sar deployment that has its service class in the default
* package
*/
public void testDefaultPkgService() throws Exception
{
String testUrl = "defaultpkg.sar";
getLog().debug("testUrl is : " + testUrl);
try
{
//deploy sar
deploy(testUrl);
//check deployment registered expected mbeans
ObjectName name = new ObjectName("test:name=DefaultPkgService");
assertTrue("test:name=DefaultPkgService is registered after deploy", checkState(name, RUNNING));
}
finally
{
undeploy(testUrl);
}
}
public void testExplicitStandardInterfaceService() throws Exception
{
String testUrl = "explicit-standard-interface.sar";
getLog().debug("testUrl is : " + testUrl);
try
{
//deploy sar
deploy(testUrl);
//check deployment registered expected mbeans
ObjectName name = new ObjectName("test:name=TestStandardService");
assertTrue("test:name=TestStandardService is registered after deploy", checkState(name, RUNNING));
}
finally
{
undeploy(testUrl);
}
}
public void testMultipleServiceFiles() throws Exception
{
String testUrl = "multiple-service-files.sar";
getLog().debug("testUrl is : " + testUrl);
try
{
//deploy sar
deploy(testUrl);
//check deployment registered expected mbeans
ObjectName name1 = new ObjectName("test:name=TestStandardService1");
assertTrue("test:name=TestStandardService1 is registered after deploy", checkState(name1, RUNNING));
ObjectName name2 = new ObjectName("test:name=TestStandardService2");
assertTrue("test:name=TestStandardService2 is registered after deploy", checkState(name2, RUNNING));
}
finally
{
undeploy(testUrl);
}
}
protected boolean recursiveDelete(File f)
{
if (f.isDirectory())
{
File[] files = f.listFiles();
for (int i = 0; i < files.length; ++i)
{
if (!recursiveDelete(files[i]))
{
return false;
}
}
}
return f.delete();
}
protected boolean checkState(ObjectName mbean, int state) throws Exception
{
Integer mbeanState = (Integer)getServer().getAttribute(mbean, "State");
return state == mbeanState.intValue();
}
}