blob: 4f1c6fdd639fe9dc179f27fd0d8192a425455bf1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 Oracle.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php.
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
* Bob Nettleton (Oracle) - Initial Reference Implementation Unit Tests
******************************************************************************/
package org.eclipse.gemini.naming;
import java.lang.reflect.Field;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.naming.NamingException;
import javax.naming.spi.DirObjectFactory;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.NamingManager;
import javax.naming.spi.ObjectFactory;
import javax.naming.spi.ObjectFactoryBuilder;
import org.easymock.EasyMockSupport;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.jndi.JNDIConstants;
import org.osgi.service.jndi.JNDIContextManager;
import org.osgi.service.jndi.JNDIProviderAdmin;
import static org.easymock.EasyMock.*;
import junit.framework.TestCase;
public class ActivatorTestCase extends TestCase {
public void setUp() {
setNamingManagerStaticFieldToNull("initctx_factory_builder");
setNamingManagerStaticFieldToNull("object_factory_builder");
}
public void tearDown() {
setNamingManagerStaticFieldToNull("initctx_factory_builder");
setNamingManagerStaticFieldToNull("object_factory_builder");
}
/**
* Verify the basic startup of the Gemini Naming Activator.
*
* This test method verifies that all the expected services are
* registered using the correct interface, actual type, and service
* properties.
*/
public void testStart() throws Exception {
EasyMockSupport mockSupport = new EasyMockSupport();
BundleContext bundleContextMock =
mockSupport.createMock(BundleContext.class);
setupBundleContextMock(mockSupport, bundleContextMock);
// expect OSGi URLContextFactory
Hashtable<String, Object> serviceProperties = new Hashtable<String, Object>();
serviceProperties.put(JNDIConstants.JNDI_URLSCHEME, "osgi");
setServiceRegistrationExpectation(mockSupport, bundleContextMock,
ObjectFactory.class.getName(),
OSGiURLContextFactoryServiceFactory.class,
serviceProperties);
// expect the "default" InitialContextFactoryBuilder
setServiceRegistrationExpectation(mockSupport, bundleContextMock,
InitialContextFactoryBuilder.class.getName(),
DefaultRuntimeInitialContextFactoryBuilder.class,
null);
// expect the JNDIContextManager service registration
setServiceRegistrationExpectation(mockSupport, bundleContextMock,
JNDIContextManager.class.getName(),
ContextManagerServiceFactoryImpl.class,
null);
// expect the JNDIProviderAdmin service registration
setServiceRegistrationExpectation(mockSupport, bundleContextMock,
JNDIProviderAdmin.class.getName(),
SecurityAwareProviderAdminImpl.class,
null);
mockSupport.replayAll();
// begin test
Activator activator = new Activator();
activator.start(bundleContextMock);
// verify that the static singletons are set as expected
assertTrue("Activator did not set the InitialContextFactoryBuilder singleton correctly",
getPrivateStaticField(NamingManager.class, "initctx_factory_builder") instanceof TraditionalInitialContextFactoryBuilder);
assertTrue("Activator did not set the ObjectFactoryBuilder singleton correctly",
getPrivateStaticField(NamingManager.class, "object_factory_builder") instanceof TraditionalObjectFactoryBuilder);
// stop() should complete without any exceptions
activator.stop(bundleContextMock);
mockSupport.verifyAll();
}
public void testRegistrationOfContextBuilderError() throws Exception {
// setup test mocks
EasyMockSupport mockSupport = new EasyMockSupport();
InitialContextFactoryBuilder builderMock =
mockSupport.createMock(InitialContextFactoryBuilder.class);
if(!NamingManager.hasInitialContextFactoryBuilder()) {
NamingManager.setInitialContextFactoryBuilder(builderMock);
}
BundleContext bundleContextMock =
mockSupport.createMock(BundleContext.class);
mockSupport.replayAll();
// begin test
Activator activator = new Activator();
try {
activator.start(bundleContextMock);
fail("NamingException should have been thrown");
} catch (NamingException namingException) {
// expected exception
}
mockSupport.verifyAll();
}
public void testRegistrationOfObjectFactoryBuilderError() throws Exception {
// setup test mocks
EasyMockSupport mockSupport = new EasyMockSupport();
ObjectFactoryBuilder builderMock =
mockSupport.createMock(ObjectFactoryBuilder.class);
try {
// try to set builder, to guarantee
// that Activator's attempt to set this will fail
NamingManager.setObjectFactoryBuilder(builderMock);
} catch (Throwable throwable) {
// if already set, test can continue
}
BundleContext bundleContextMock =
mockSupport.createMock(BundleContext.class);
mockSupport.replayAll();
// begin test
Activator activator = new Activator();
try {
activator.start(bundleContextMock);
fail("NamingException should have been thrown");
} catch (NamingException namingException) {
// expected exception
}
mockSupport.verifyAll();
}
/* test utility methods/classes */
private static void setupBundleContextMock(EasyMockSupport mockSupport, BundleContext bundleContextMock) throws InvalidSyntaxException {
Filter filterMock =
mockSupport.createMock(Filter.class);
expect(bundleContextMock.createFilter("(objectClass=" + InitialContextFactory.class.getName() + ")")).andReturn(filterMock);
expect(bundleContextMock.createFilter("(objectClass=" + InitialContextFactoryBuilder.class.getName() + ")")).andReturn(filterMock);
expect(bundleContextMock.createFilter("(objectClass=" + ObjectFactory.class.getName() + ")")).andReturn(filterMock).anyTimes();
expect(bundleContextMock.createFilter("(objectClass=" + DirObjectFactory.class.getName() + ")")).andReturn(filterMock);
expect(bundleContextMock.createFilter("(objectClass=" + ObjectFactoryBuilder.class.getName() + ")")).andReturn(filterMock);
bundleContextMock.addServiceListener(isA(ServiceListener.class), isA(String.class));
expectLastCall().anyTimes();
bundleContextMock.removeServiceListener(isA(ServiceListener.class));
expectLastCall().anyTimes();
expect(bundleContextMock.getServiceReferences(isA(String.class), isA(String.class))).andReturn(new ServiceReference[0]).anyTimes();
expect(bundleContextMock.getServiceReferences(isA(String.class), (String)isNull())).andReturn(new ServiceReference[0]).anyTimes();
}
private static <T> void setServiceRegistrationExpectation(EasyMockSupport mockSupport, BundleContext bundleContextMock, String serviceName, Class<T> serviceType, Dictionary<String, Object> serviceProperties) {
ServiceRegistration serviceRegistrationMock =
mockSupport.createMock(ServiceRegistration.class);
// required for stop() method
serviceRegistrationMock.unregister();
if(serviceProperties != null) {
expect(bundleContextMock.registerService(eq(serviceName),
isA(serviceType), eq(serviceProperties))).andReturn(serviceRegistrationMock);
} else {
expect(bundleContextMock.registerService(eq(serviceName),
isA(serviceType), (Dictionary)isNull())).andReturn(serviceRegistrationMock);
}
}
/**
* This method should be used only for unit testing the Gemini Naming Activator.
*
* This method sets the static singleton fields on the NamingManger class to null. This facilitates
* simpler unit-testing of the Activator, which attempts to set these singletons. The NamingManager usually
* throws and Exception on the set() methods for these singletons after they've been set once.
*
* This utility method is meant to make unit testing simpler, but should not be used in production code.
*
* This utility method will probably not work properly if a security manager is enabled.
*
* @param fieldName the name of the static field to set to null.
*/
private static void setNamingManagerStaticFieldToNull(String fieldName) {
try {
final Field field = NamingManager.class.getDeclaredField(fieldName);
if(field != null) {
field.setAccessible(true);
// reset this static field to null
field.set(null, null);
}
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
/*
* Utility method used to access the private static singletons on the NamingManager class.
*
* This method should only be used for unit-testing the Gemini Naming code.
*
* This utility method will probably not work properly if a security manager is enabled.
*
* @param type the Class type that contains the field
* @param fieldName a String name that identifies the field
*/
private static Object getPrivateStaticField(Class type, String fieldName) throws Exception {
Field field = type.getDeclaredField(fieldName);
if(field != null) {
field.setAccessible(true);
return field.get(null);
}
return null;
}
}