/* * JBoss, Home of Professional Open Source * Copyright 2006, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt 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.naming.test; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.Properties; import java.util.Hashtable; import java.io.Serializable; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NameAlreadyBoundException; import javax.naming.NameClassPair; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.Name; import javax.naming.RefAddr; import javax.naming.Reference; import javax.naming.StringRefAddr; import javax.naming.spi.StateFactory; import javax.naming.spi.ObjectFactory; import junit.framework.TestCase; import junit.framework.Test; import junit.framework.TestSuite; import junit.textui.TestRunner; import org.jboss.logging.Logger; import org.jboss.naming.ENCFactory; /** Simple unit tests for the jndi implementation. * * @author Scott.Stark@jboss.org * @version $Revision: 77587 $ */ public class ImplUnitTestCase extends TestCase { static final Logger log = Logger.getLogger(ImplUnitTestCase.class); /** * Constructor for the SimpleUnitTestCase object * * @param name Test name */ public ImplUnitTestCase(String name) { super(name); } /** * Tests that the second time you create a subcontext you get an exception. * * @exception Exception Description of Exception */ public void testCreateSubcontext() throws Exception { log.debug("+++ testCreateSubcontext"); InitialContext ctx = getInitialContext(); ctx.createSubcontext("foo"); try { ctx.createSubcontext("foo"); fail("Second createSubcontext(foo) did NOT fail"); } catch (NameAlreadyBoundException e) { log.debug("Second createSubcontext(foo) failed as expected"); } ctx.createSubcontext("foo/bar"); ctx.unbind("foo/bar"); ctx.unbind("foo"); } /** Lookup a name to test basic connectivity and lookup of a known name * * @throws Exception */ public void testLookup() throws Exception { log.debug("+++ testLookup"); InitialContext ctx = getInitialContext(); Object obj = ctx.lookup(""); log.debug("lookup('') = "+obj); } /** * Validate that bind("x", null) works * */ public void testBindNull() throws Exception { log.debug("+++ testBindNull"); InitialContext ctx = getInitialContext(); ctx.bind("testBindNull", null); Object x = ctx.lookup("testBindNull"); assertNull("testBindNull", x); NamingEnumeration<NameClassPair> ncps = ctx.list(""); NameClassPair testBindNullNCP = null; while( ncps.hasMore() ) { NameClassPair ncp = ncps.next(); if( ncp.getName().equals("testBindNull") ) { testBindNullNCP = ncp; break; } } assertTrue("testBindNull NameClassPair != null", testBindNullNCP != null); } /** * Validate that rebind("x", null) works * */ public void testRebindNull() throws Exception { log.debug("+++ testRebindNull"); InitialContext ctx = getInitialContext(); ctx.bind("testRebindNull", null); Object x = ctx.lookup("testRebindNull"); assertNull("testRebindNull", x); NamingEnumeration<NameClassPair> ncps = ctx.list(""); NameClassPair testBindNullNCP = null; while( ncps.hasMore() ) { NameClassPair ncp = ncps.next(); if( ncp.getName().equals("testRebindNull") ) { testBindNullNCP = ncp; break; } } assertTrue("testRebindNull NameClassPair != null", testBindNullNCP != null); } public void testEncPerf() throws Exception { int count = Integer.getInteger("jbosstest.threadcount", 10).intValue(); int iterations = Integer.getInteger("jbosstest.iterationcount", 1000).intValue(); log.info("Creating "+count+"threads doing "+iterations+" iterations"); InitialContext ctx = getInitialContext(); URL[] empty = {}; Thread[] testThreads = new Thread[count]; for(int t = 0; t < count; t ++) { ClassLoader encLoader = URLClassLoader.newInstance(empty); Thread.currentThread().setContextClassLoader(encLoader); Runnable test = new ENCTester(ctx, iterations); Thread thr = new Thread(test, "Tester#"+t); thr.setContextClassLoader(encLoader); thr.start(); testThreads[t] = thr; } for(int t = 0; t < count; t ++) { Thread thr = testThreads[t]; thr.join(); } } /** * * @throws NamingException */ public void testFactorySupport() throws NamingException { log.info("+++ testFactorySupport"); NotSerializableObject nso = new NotSerializableObject( "nsc" ); Context ctx = getInitialContext(); try { ctx.bind("test", nso); fail(); } catch( NamingException ex ) { log.debug("bind failed as expected", ex); } Properties env = new Properties(); env.setProperty(Context.STATE_FACTORIES, TestFactory.class.getName()); env.setProperty(Context.OBJECT_FACTORIES, TestFactory.class.getName()); ctx = new InitialContext(env); log.debug("Retest with TestFactory enabled"); ctx.bind("test", nso); Object boundObject = ctx.lookup( "test" ); assertNotNull( boundObject ); // make sure it's of type NotSerializableObject NotSerializableObject nso2 = (NotSerializableObject) boundObject; assertEquals( nso.getId(), nso2.getId() ); } public void testCloneableReference() throws Exception { log.info("+++ testFactorySupport"); NotSerializableObject nso = new NotSerializableObject( "nsc" ); CloneObjectFactory.setInstance(nso); Context ctx = getInitialContext(); RefAddr refAddr = new StringRefAddr("NotSerializableObject", "Clone"); Reference ref = new Reference(NotSerializableObject.class.getName(), refAddr, CloneObjectFactory.class.getName(), null); ctx.bind("NotSerializableObject", ref); // Validate each lookup produces a unique but equal instance NotSerializableObject nso1 = (NotSerializableObject) ctx.lookup("NotSerializableObject"); NotSerializableObject nso2 = (NotSerializableObject) ctx.lookup("NotSerializableObject"); assertTrue(nso != nso1); assertTrue(nso != nso2); assertTrue(nso1 != nso2); } static InitialContext getInitialContext() throws NamingException { InitialContext ctx = new InitialContext(); return ctx; } private static class ENCTester implements Runnable { Context enc; int iterations; ENCTester(InitialContext ctx, int iterations) throws Exception { log.info("CL: "+Thread.currentThread().getContextClassLoader()); this.iterations = iterations; enc = (Context) ctx.lookup("java:comp"); enc = enc.createSubcontext("env"); enc.bind("int", new Integer(1)); enc.bind("double", new Double(1.234)); enc.bind("string", "str"); enc.bind("url", new URL("http://www.jboss.org")); } public void run() { try { InitialContext ctx = new InitialContext(); for(int i = 0; i < iterations; i ++) { Integer i1 = (Integer) enc.lookup("int"); log.debug("int: "+i1); i1 = (Integer) ctx.lookup("java:comp/env/int"); log.debug("java:comp/env/int: "+i1); Double d = (Double) enc.lookup("double"); log.debug("double: "+d); d = (Double) ctx.lookup("java:comp/env/double"); log.debug("java:comp/env/double: "+d); String s = (String) enc.lookup("string"); log.debug("string: "+s); s = (String) ctx.lookup("java:comp/env/string"); log.debug("java:comp/env/string: "+s); URL u = (URL) enc.lookup("url"); log.debug("url: "+u); u = (URL) ctx.lookup("java:comp/env/url"); log.debug("java:comp/env/url: "+u); } } catch(Exception e) { e.printStackTrace(); } } } private static class NotSerializableObject implements Cloneable { protected String id; public NotSerializableObject() {} public NotSerializableObject( String id ) { this.id = id; } public String getId() { return id; } public String toString() { return "NotSerializableObject<" + getId() + ">"; } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public boolean equals(Object obj) { boolean equals = false; if(obj instanceof NotSerializableObject) { NotSerializableObject nso = (NotSerializableObject) obj; equals = id.equals(nso.id); } return equals; } @Override public int hashCode() { return id.hashCode(); } } private static class SerializableObject extends NotSerializableObject implements Serializable { private static long serialVersionUID = 1; public SerializableObject () {} public SerializableObject (String id) { super( id ); } public String toString() { return "SerializableObject<" + getId() + ">"; } private void writeObject(ObjectOutputStream out) throws IOException { out.writeObject(getId()); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { id = (String) in.readObject(); } } public static class CloneObjectFactory implements ObjectFactory { private static Object instance; private static Method clone; public static void setInstance(Object instance) throws Exception { CloneObjectFactory.instance = instance; Class<?> empty[] = {}; if(instance != null) clone = instance.getClass().getDeclaredMethod("clone", empty); } public Object getObjectInstance (Object obj, Name name, Context nameCtx, Hashtable env) throws Exception { log.debug("CloneObjectFactory.getObjectInstance, obj:" + obj + ", name: " + name + ", nameCtx: " + nameCtx +", env: "+env); return clone.invoke(instance, null); } } public static class TestFactory implements StateFactory, ObjectFactory { public Object getStateToBind (Object obj, Name name, Context nameCtx, Hashtable environment) throws NamingException { if( obj instanceof NotSerializableObject ) { String id = ((NotSerializableObject) obj).getId(); return new SerializableObject( id ); } return null; } public Object getObjectInstance (Object obj, Name name, Context nameCtx, Hashtable env) throws Exception { log.debug("TestFactory.getObjectInstance, obj:" + obj + ", name: " + name + ", nameCtx: " + nameCtx +", env: "+env); if( obj instanceof SerializableObject ) { String id = ((SerializableObject) obj).getId(); return new NotSerializableObject( id ); } return null; } } public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new TestSuite(ImplUnitTestCase.class)); // Create an initializer for the test suite NamingServerSetup wrapper = new NamingServerSetup(suite); return wrapper; } /** Used to run the testcase from the command line * * @param args The command line arguments */ public static void main(String[] args) { TestRunner.run(ImplUnitTestCase.suite()); } }