Completed all testing and interface/functional changes for SGF-248 - Bootstrapping a Spring ApplicationContext with GemFire.

This commit is contained in:
John Blum
2014-01-27 18:45:53 -08:00
parent 5476837119
commit ba84061b48
9 changed files with 705 additions and 28 deletions

View File

@@ -0,0 +1,130 @@
/*
* Copyright 2010-2013 the original author or authors.
*
* Licensed 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.springframework.data.gemfire;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Properties;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.gemfire.repository.sample.User;
import org.springframework.data.gemfire.test.support.DataSourceAdapter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Assert;
/**
* The LazyWiringDeclarableSupportIntegrationTest class is a test suite of integration test cases testing
* a LazyWiringDeclarableSupport object/component's wiring configuration and initialization in
* a Spring container context.
* <p/>
* @author John Blum
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.springframework.test.context.ContextConfiguration
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
* @since 1.3.4
*/
@ContextConfiguration("lazy-wiring-declarable-support.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@SuppressWarnings("unused")
public class LazyWiringDeclarableSupportIntegrationTest {
@Autowired
private ApplicationContext applicationContext;
protected static Properties createParameters(final String parameter, final String value) {
Properties parameters = new Properties();
parameters.setProperty(parameter, value);
return parameters;
}
@Test
public void testWiring() {
TestDeclarable declarable = new TestDeclarable();
declarable.init(createParameters("testParam1", "testValue1"));
declarable.onApplicationEvent(new ContextRefreshedEvent(applicationContext));
declarable.assertInitialized();
assertNull(declarable.getDataSource());
assertNotNull(declarable.getUser());
assertEquals("supertool", declarable.getUser().getUsername());
}
@Test
public void testWiringWithBeanTemplate() {
TestDeclarable declarable = new TestDeclarable();
declarable.init(createParameters(LazyWiringDeclarableSupport.BEAN_NAME_PARAMETER, "declarableTemplateBean"));
declarable.onApplicationEvent(new ContextRefreshedEvent(applicationContext));
declarable.assertInitialized();
assertNotNull(declarable.getDataSource());
assertNotNull(declarable.getUser());
assertEquals("supertool", declarable.getUser().getUsername());
}
@Test(expected = IllegalArgumentException.class)
public void testWiringWithNonExistingBeanTemplate() {
TestDeclarable declarable = new TestDeclarable();
try {
declarable.init(createParameters(LazyWiringDeclarableSupport.BEAN_NAME_PARAMETER,
"nonExistingBeanTemplate"));
declarable.onApplicationEvent(new ContextRefreshedEvent(applicationContext));
}
catch (IllegalArgumentException expected) {
assertTrue(expected.getMessage().startsWith(
"No bean with name 'nonExistingBeanTemplate' was found in the Spring context"));
throw expected;
}
}
protected static final class TestDataSource extends DataSourceAdapter {
}
protected static final class TestDeclarable extends LazyWiringDeclarableSupport {
private DataSource dataSource;
@Autowired
private User user;
public final void setDataSource(final DataSource dataSource) {
this.dataSource = dataSource;
}
protected DataSource getDataSource() {
return dataSource;
}
protected User getUser() {
Assert.state(user != null, "A reference to the User was not properly configured!");
return user;
}
}
}

View File

@@ -0,0 +1,199 @@
/*
* Copyright 2010-2013 the original author or authors.
*
* Licensed 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.springframework.data.gemfire;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer;
/**
* The LazyWiringDeclarableSupportTest class is a test suite of test cases testing the contract and functionality
* of the LazyWiringDeclarableSupport class. This test class focuses on testing isolated units of functionality
* in the Declarable class directly, mocking any dependencies as appropriate, in order for the class to uphold
* it's contract.
* <p/>
* @author John Blum
* @see org.junit.Test
* @see org.mockito.Mockito
* @see org.springframework.data.gemfire.LazyWiringDeclarableSupport
* @since 1.3.4
*/
public class LazyWiringDeclarableSupportTest {
protected static Properties createParameters(final String parameter, final String value) {
Properties parameters = new Properties();
parameters.setProperty(parameter, value);
return parameters;
}
@Test
public void testAssertInitialized() {
LazyWiringDeclarableSupport declarable = new TestLazyWiringDeclarableSupport() {
@Override protected boolean isInitialized() {
return true;
}
};
try {
declarable.assertInitialized();
}
finally {
SpringContextBootstrappingInitializer.unregister(declarable);
}
}
@Test(expected = IllegalStateException.class)
public void testAssertInitializedWhenUninitialized() {
LazyWiringDeclarableSupport declarable = new TestLazyWiringDeclarableSupport();
try {
declarable.assertInitialized();
}
catch (IllegalStateException expected) {
assertEquals(String.format("This Declarable object (%1$s) has not ben properly configured and initialized!",
TestLazyWiringDeclarableSupport.class.getName()), expected.getMessage());
throw expected;
}
finally {
SpringContextBootstrappingInitializer.unregister(declarable);
}
}
@Test
public void testInit() {
new TestLazyWiringDeclarableSupport().init(createParameters("testParam1", "testValue1"));
}
@Test(expected = IllegalStateException.class)
public void testInitWhenInitialized() {
LazyWiringDeclarableSupport declarable = new TestLazyWiringDeclarableSupport();
try {
declarable.init(createParameters("testParam1", "testValue1"));
}
catch (IllegalStateException unexpected) {
fail("Calling init the first time should not throw an IllegalStateException!");
}
try {
declarable.init(createParameters("testParam2", "testValue1"));
}
catch (IllegalStateException expected) {
assertEquals(String.format("This Declarable (%1$s) has already been initialized.",
declarable.getClass().getName()), expected.getMessage());
throw expected;
}
}
@Test(expected = IllegalStateException.class)
public void testOnApplicationEventWithNoParameters() {
LazyWiringDeclarableSupport declarable = new TestLazyWiringDeclarableSupport();
try {
declarable.onApplicationEvent(new ContextRefreshedEvent(mock(ConfigurableApplicationContext.class,
"testOnApplicationEventWithNoParameters")));
}
catch (IllegalStateException expected) {
assertEquals(String.format("This Declarable object's (%1$s) init method has not been invoked!",
declarable.getClass().getName()), expected.getMessage());
throw expected;
}
}
@Test(expected = IllegalArgumentException.class)
public void testOnApplicationEventWithNonConfigurableApplicationContext() {
ApplicationContext mockApplicationContext = mock(ApplicationContext.class,
"testOnApplicationEventWithNonConfigurableApplicationContext");
LazyWiringDeclarableSupport declarable = new TestLazyWiringDeclarableSupport();
try {
declarable.init(createParameters("testParam1", "testValue1"));
declarable.onApplicationEvent(new ContextRefreshedEvent(mockApplicationContext));
}
catch (IllegalArgumentException expected) {
assertEquals(String.format("The Spring ApplicationContext (%1$s) must be an instance of ConfigurableApplicationContext.",
mockApplicationContext.getClass().getName()), expected.getMessage());
throw expected;
}
}
@Test
public void testOnApplicationEventAndDoPostInit() {
ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class,
"testOnApplicationEventAndDoPostInit.ApplicationContext");
ConfigurableListableBeanFactory mockBeanFactory = mock(ConfigurableListableBeanFactory.class,
"testOnApplicationEventAndDoPostInit.BeanFactory");
when(mockApplicationContext.getBeanFactory()).thenReturn(mockBeanFactory);
Properties testParameters = createParameters("testParam1", "testValue1");
final AtomicBoolean doPostInitCalled = new AtomicBoolean(false);
TestLazyWiringDeclarableSupport declarable = new TestLazyWiringDeclarableSupport() {
@Override protected void doPostInit(final Properties parameters) {
assertInitialized();
doPostInitCalled.set(true);
}
};
declarable.init(testParameters);
declarable.onApplicationEvent(new ContextRefreshedEvent(mockApplicationContext));
declarable.assertEquals(testParameters);
declarable.assertSame(mockBeanFactory);
assertTrue(doPostInitCalled.get());
}
protected static class TestLazyWiringDeclarableSupport extends LazyWiringDeclarableSupport {
private ConfigurableListableBeanFactory actualBeanFactory;
private Properties actualParameters;
protected void assertEquals(final Properties expectedParameters) {
Assert.assertEquals(expectedParameters, actualParameters);
}
protected void assertSame(final ConfigurableListableBeanFactory expectedBeanFactory) {
Assert.assertSame(expectedBeanFactory, actualBeanFactory);
}
@Override
void doInit(final ConfigurableListableBeanFactory beanFactory, final Properties parameters) {
this.actualBeanFactory = beanFactory;
this.actualParameters = parameters;
initialized = true;
doPostInit(parameters);
}
}
}

View File

@@ -87,6 +87,10 @@ public class User implements Comparable<User> {
return getUsername().compareTo(user.getUsername());
}
protected static boolean equalsIgnoreNull(final Object obj1, final Object obj2) {
return (obj1 == null ? obj2 == null : obj1.equals(obj2));
}
@Override
public boolean equals(final Object obj) {
if (obj == this) {
@@ -103,6 +107,10 @@ public class User implements Comparable<User> {
&& ObjectUtils.nullSafeEquals(this.getEmail(), that.getEmail());
}
protected static int hashCodeIgnoreNull(final Object obj) {
return (obj != null ? obj.hashCode() : 0);
}
@Override
public int hashCode() {
int hashValue = 17;

View File

@@ -48,8 +48,8 @@ import com.gemstone.gemfire.cache.LoaderHelper;
import com.gemstone.gemfire.cache.Region;
/**
* The SpringContextBootstrappingInitializerTest class is a test suite of test cases testing the functionality of the
* SpringContextBootstrappingInitializer class
* The SpringContextBootstrappingInitializerTest class is a test suite of test cases testing the integrated
* functionality of the SpringContextBootstrappingInitializer class.
* <p/>
* @author John Blum
* @see org.junit.Test
@@ -137,6 +137,7 @@ public class SpringContextBootstrappingInitializerIntegrationTest {
private DataSource userDataSource;
protected DataSource getDataSource() {
Assert.state(userDataSource != null, "A reference to the Users DataSource as not properly configured!");
return userDataSource;
}
}
@@ -151,6 +152,7 @@ public class SpringContextBootstrappingInitializerIntegrationTest {
private UserDao userDao;
protected UserDao getUserDao() {
Assert.state(userDao != null, "A reference to the UserDao was not properly configured!");
return userDao;
}
}
@@ -182,6 +184,10 @@ public class SpringContextBootstrappingInitializerIntegrationTest {
return createUser(username, String.format("%1$s@xcompay.com", username), active, Calendar.getInstance());
}
protected static User createUser(final String username, final Boolean active, final Calendar since) {
return createUser(username, String.format("%1$s@xcompay.com", username), active, since);
}
protected static User createUser(final String username, final String email, final Boolean active, final Calendar since) {
User user = new User(username);
user.setActive(active);

View File

@@ -0,0 +1,249 @@
/*
* Copyright 2010-2013 the original author or authors.
*
* Licensed 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.springframework.data.gemfire.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Properties;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.util.ObjectUtils;
/**
* The SpringContextBootstrappingInitializerTest class is a test suite of test cases testing the contract
* and functionality of the SpringContextBootstrappingInitializer class. This test class focuses on testing isolated
* units of functionality in the Initializer class directly, mocking any dependencies as appropriate, in order for the
* class to uphold it's contract.
* <p/>
* @author John Blum
* @see org.junit.Test
* @see org.mockito.Mockito
* @see org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer
* @see org.springframework.data.gemfire.support.SpringContextBootstrappingInitializerIntegrationTest
* @since 1.3.4
*/
public class SpringContextBootstrappingInitializerTest {
protected static Properties createParameters(final String parameter, final String value) {
Properties parameters = new Properties();
parameters.setProperty(parameter, value);
return parameters;
}
@After
public void tearDown() {
SpringContextBootstrappingInitializer.applicationContext = null;
}
@Test(expected = IllegalArgumentException.class)
public void testInitWithUnspecifiedContextConfigLocationsParameter() {
try {
new SpringContextBootstrappingInitializer().init(createParameters(
SpringContextBootstrappingInitializer.CONTEXT_CONFIG_LOCATIONS_PARAMETER, ""));
}
catch (IllegalArgumentException expected) {
assertEquals("The contextConfigLocations parameter is required.", expected.getMessage());
throw expected;
}
}
@Test(expected = IllegalStateException.class)
public void testInitWithExistingApplicationContext() {
try {
ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class,
"testInitWithExistingApplicationContext");
when(mockApplicationContext.getId()).thenReturn("testInitWithExistingApplicationContext");
SpringContextBootstrappingInitializer.applicationContext = mockApplicationContext;
new SpringContextBootstrappingInitializer().init(createParameters(
SpringContextBootstrappingInitializer.CONTEXT_CONFIG_LOCATIONS_PARAMETER,
"/path/to/spring/context/configuration/file.xml"));
}
catch (IllegalStateException expected) {
assertEquals("A Spring application context with ID (testInitWithExistingApplicationContext) has already been created.",
expected.getMessage());
throw expected;
}
}
@Test(expected = IllegalStateException.class)
public void testInitWithNonActiveApplicationConstruct() {
final ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class,
"testInitWithNonActiveApplicationConstruct");
when(mockApplicationContext.getId()).thenReturn("testInitWithNonActiveApplicationConstruct");
when(mockApplicationContext.isActive()).thenReturn(false);
SpringContextBootstrappingInitializer initializer = null;
try {
initializer = new SpringContextBootstrappingInitializer() {
@Override
protected ConfigurableApplicationContext createApplicationContext(final String[] configLocations, final boolean refresh) {
return mockApplicationContext;
}
};
initializer.init(createParameters(SpringContextBootstrappingInitializer.CONTEXT_CONFIG_LOCATIONS_PARAMETER,
"/path/to/spring/context/configuration/file.xml"));
}
catch (IllegalStateException expected) {
assertEquals("The Spring application context (testInitWithNonActiveApplicationConstruct) has failed to be properly initialized with the following config files ([/path/to/spring/context/configuration/file.xml])!",
expected.getMessage());
throw expected;
}
finally {
verify(mockApplicationContext, times(1)).addApplicationListener(eq(initializer));
verify(mockApplicationContext, times(1)).registerShutdownHook();
verify(mockApplicationContext, times(1)).refresh();
}
}
@Test
public void testInitFollowedByGetApplicationContext() {
final ConfigurableApplicationContext mockApplicationContext = mock(ConfigurableApplicationContext.class,
"testInitFollowedByGetApplicationContext");
when(mockApplicationContext.getId()).thenReturn("testInitFollowedByGetApplicationContext");
when(mockApplicationContext.isActive()).thenReturn(true);
SpringContextBootstrappingInitializer initializer = new SpringContextBootstrappingInitializer() {
@Override
protected ConfigurableApplicationContext createApplicationContext(final String[] configLocations, final boolean refresh) {
return mockApplicationContext;
}
};
initializer.init(createParameters(SpringContextBootstrappingInitializer.CONTEXT_CONFIG_LOCATIONS_PARAMETER,
"/path/to/spring/context/configuration/file.xml"));
verify(mockApplicationContext, times(1)).addApplicationListener(eq(initializer));
verify(mockApplicationContext, times(1)).registerShutdownHook();
verify(mockApplicationContext, times(1)).refresh();
assertSame(mockApplicationContext, SpringContextBootstrappingInitializer.getApplicationContext());
}
@Test(expected = IllegalStateException.class)
public void testGetApplicationContextUninitialized() {
try {
SpringContextBootstrappingInitializer.getApplicationContext();
}
catch (IllegalStateException expected) {
assertEquals("The Spring ApplicationContext has not been created!", expected.getMessage());
throw expected;
}
}
@Test
public void testNullSafeGetApplicationContextIdWithNullReference() {
assertNull(new SpringContextBootstrappingInitializer().nullSafeGetApplicationContextId(null));
}
@Test
public void testNullSafeGetApplicationContextWithNonNullReference() {
ApplicationContext mockApplicationContext = mock(ApplicationContext.class,
"testNullSafeGetApplicationContextWithNonNullReference");
when(mockApplicationContext.getId()).thenReturn("testNullSafeGetApplicationContextWithNonNullReference");
assertEquals("testNullSafeGetApplicationContextWithNonNullReference",
new SpringContextBootstrappingInitializer().nullSafeGetApplicationContextId(mockApplicationContext));
}
@Test
public void testRegisterAndOnApplicationEvent() {
TestApplicationListener testListener = SpringContextBootstrappingInitializer.register(
new TestApplicationListener());
try {
ContextRefreshedEvent testEvent = new ContextRefreshedEvent(mock(ApplicationContext.class,
"testRegisterAndOnApplicationEvent"));
new SpringContextBootstrappingInitializer().onApplicationEvent(testEvent);
testListener.assertCalled();
testListener.assertSame(testEvent);
}
finally {
SpringContextBootstrappingInitializer.unregister(testListener);
}
}
@Test
public void testRegisterUnregisterAndOnApplicationEvent() {
TestApplicationListener testListener = SpringContextBootstrappingInitializer.unregister(
SpringContextBootstrappingInitializer.register(new TestApplicationListener()));
try {
ContextRefreshedEvent testEvent = new ContextRefreshedEvent(mock(ApplicationContext.class,
"testUnregisterAndOnApplicationEvent"));
new SpringContextBootstrappingInitializer().onApplicationEvent(testEvent);
testListener.assertNotCalled();
}
finally {
SpringContextBootstrappingInitializer.unregister(testListener);
}
}
protected static class TestApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
private volatile boolean called = false;
private volatile ContextRefreshedEvent actualEvent;
public void assertCalled() {
assertTrue(String.format("Expected the (%1$s).onApplicationEvent(:ContextRefreshedEvent) method to be called!",
getClass().getName()), called);
}
public void assertNotCalled() {
assertFalse(String.format("Expected the (%1$s).onApplicationEvent(:ContextRefreshedEvent) method to not be called for ApplicationEvent (%2$s)!",
getClass().getName(), ObjectUtils.nullSafeClassName(actualEvent)), called);
}
public void assertSame(final ContextRefreshedEvent expectedEvent) {
Assert.assertSame(expectedEvent, actualEvent);
}
@Override
public void onApplicationEvent(final ContextRefreshedEvent event) {
this.actualEvent = event;
called = true;
}
}
}