blob: ea10c643fa9a7b16d668713b34f7461cedb81203 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.aries.jndi;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.NoInitialContextException;
import javax.naming.ldap.Control;
import javax.naming.ldap.ExtendedRequest;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.ObjectFactory;
import junit.framework.Assert;
import org.apache.aries.jndi.startup.Activator;
import org.apache.aries.mocks.BundleContextMock;
import org.apache.aries.unittest.mocks.MethodCall;
import org.apache.aries.unittest.mocks.Skeleton;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.osgi.framework.BundleContext;
import org.osgi.service.jndi.JNDIConstants;
public class InitialContextTest
{
private Activator activator;
private BundleContext bc;
private InitialContext ic;
/**
* This method does the setup .
* @throws NoSuchFieldException
* @throws SecurityException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@Before
public void setup() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
{
bc = Skeleton.newMock(new BundleContextMock(), BundleContext.class);
activator = new Activator();
activator.start(bc);
}
/**
* Make sure we clear the caches out before the next test.
*/
@After
public void teardown()
{
activator.stop(bc);
BundleContextMock.clear();
}
@Test
public void testLookupWithICF() throws NamingException
{
InitialContextFactory icf = Skeleton.newMock(InitialContextFactory.class);
bc.registerService(new String[] {InitialContextFactory.class.getName(), icf.getClass().getName()}, icf, (Dictionary) new Properties());
Skeleton.getSkeleton(icf).setReturnValue(new MethodCall(Context.class, "lookup", "/"), Skeleton.newMock(Context.class));
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, icf.getClass().getName());
props.put(JNDIConstants.BUNDLE_CONTEXT, bc);
InitialContext ctx = new InitialContext(props);
Context namingCtx = (Context) ctx.lookup("/");
assertTrue("Context returned isn't the raw naming context: " + namingCtx, Skeleton.isSkeleton(namingCtx));
}
@Test(expected=NoInitialContextException.class)
public void testLookupWithoutICF() throws NamingException
{
Properties props = new Properties();
props.put(JNDIConstants.BUNDLE_CONTEXT, bc);
InitialContext ctx = new InitialContext(props);
ctx.lookup("/");
}
@Test
public void testLookupWithoutICFButWithURLLookup() throws NamingException
{
ObjectFactory factory = Skeleton.newMock(ObjectFactory.class);
Context ctx = Skeleton.newMock(Context.class);
Skeleton.getSkeleton(factory).setReturnValue(new MethodCall(ObjectFactory.class, "getObjectInstance", Object.class, Name.class, Context.class, Hashtable.class),
ctx);
Skeleton.getSkeleton(ctx).setReturnValue(new MethodCall(Context.class, "lookup", String.class), "someText");
Properties props = new Properties();
props.put(JNDIConstants.JNDI_URLSCHEME, "testURL");
bc.registerService(ObjectFactory.class.getName(), factory, (Dictionary) props);
props = new Properties();
props.put(JNDIConstants.BUNDLE_CONTEXT, bc);
InitialContext initialCtx = new InitialContext(props);
Object someObject = initialCtx.lookup("testURL:somedata");
assertEquals("Expected to be given a string, but got something else.", "someText", someObject);
}
@Test
public void testLookFromLdapICF() throws Exception
{
InitialContextFactoryBuilder icf = Skeleton.newMock(InitialContextFactoryBuilder.class);
bc.registerService(new String[] {InitialContextFactoryBuilder.class.getName(), icf.getClass().getName()}, icf, (Dictionary) new Properties());
LdapContext backCtx = Skeleton.newMock(LdapContext.class);
InitialContextFactory fac = Skeleton.newMock(InitialContextFactory.class);
Skeleton.getSkeleton(fac).setReturnValue(
new MethodCall(InitialContextFactory.class, "getInitialContext", Hashtable.class),
backCtx);
Skeleton.getSkeleton(icf).setReturnValue(
new MethodCall(InitialContextFactoryBuilder.class, "createInitialContextFactory", Hashtable.class),
fac);
Properties props = new Properties();
props.put(JNDIConstants.BUNDLE_CONTEXT, bc);
props.put(Context.INITIAL_CONTEXT_FACTORY, "dummy.factory");
InitialLdapContext ilc = new InitialLdapContext(props, new Control[0]);
ExtendedRequest req = Skeleton.newMock(ExtendedRequest.class);
ilc.extendedOperation(req);
Skeleton.getSkeleton(backCtx).assertCalled(new MethodCall(LdapContext.class, "extendedOperation", req));
}
@Test
public void testURLLookup() throws Exception {
ObjectFactory of = new ObjectFactory() {
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
return dummyContext("result");
}
};
registerURLObjectFactory(of, "test");
ic = initialContext();
assertEquals("result", ic.lookup("test:something"));
}
@Test
public void testNoURLContextCaching() throws Exception {
final AtomicBoolean second = new AtomicBoolean(false);
final Context ctx = dummyContext("one");
final Context ctx2 = dummyContext("two");
ObjectFactory of = new ObjectFactory() {
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
if (second.get()) return ctx2;
else {
second.set(true);
return ctx;
}
}
};
registerURLObjectFactory(of, "test");
ic = initialContext();
assertEquals("one", ic.lookup("test:something"));
assertEquals("two", ic.lookup("test:something"));
}
@Test
public void testURLContextErrorPropagation() throws Exception {
ObjectFactory of = new ObjectFactory() {
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable<?, ?> environment) throws Exception {
throw new Exception("doh");
}
};
registerURLObjectFactory(of, "test");
ic = initialContext();
try {
ic.lookup("test:something");
Assert.fail("Expected NamingException");
} catch (NamingException ne) {
assertNotNull(ne.getCause());
assertEquals("doh", ne.getCause().getMessage());
}
}
/**
* Create a minimal initial context with just the bundle context in the environment
* @return
* @throws Exception
*/
private InitialContext initialContext() throws Exception {
Properties props = new Properties();
props.put(JNDIConstants.BUNDLE_CONTEXT, bc);
InitialContext ic = new InitialContext(props);
return ic;
}
/**
* Registers an ObjectFactory to be used for creating URLContexts for the given scheme
* @param of
* @param scheme
*/
private void registerURLObjectFactory(ObjectFactory of, String scheme) {
Properties props = new Properties();
props.setProperty(JNDIConstants.JNDI_URLSCHEME, "test");
bc.registerService(ObjectFactory.class.getName(), of, (Dictionary) props);
}
/**
* Creates a context that always returns the given object
* @param toReturn
* @return
*/
private Context dummyContext(Object toReturn) {
Context ctx = Skeleton.newMock(Context.class);
Skeleton.getSkeleton(ctx).setReturnValue(new MethodCall(Context.class, "lookup", String.class), toReturn);
Skeleton.getSkeleton(ctx).setReturnValue(new MethodCall(Context.class, "lookup", Name.class), toReturn);
return ctx;
}
}