diff options
Diffstat (limited to 'java/broker-core/src/test/java/org/apache')
18 files changed, 1450 insertions, 130 deletions
diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/binding/BindingImplTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/binding/BindingImplTest.java new file mode 100644 index 0000000000..93fa9114fb --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/binding/BindingImplTest.java @@ -0,0 +1,76 @@ +/* + * + * 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.qpid.server.binding; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.common.AMQPFilterTypes; +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.exchange.ExchangeImpl; +import org.apache.qpid.server.model.Binding; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.test.utils.QpidTestCase; + +public class BindingImplTest extends QpidTestCase +{ + private TaskExecutor _taskExecutor; + private Model _model; + + public void setUp() throws Exception + { + super.setUp(); + _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance(); + _model = BrokerModel.getInstance(); + } + + public void testBindingValidationOnCreateWithInvalidSelector() + { + Map<String, String> arguments = new HashMap<>(); + arguments.put(AMQPFilterTypes.JMS_SELECTOR.toString(), "test in ("); + Map<String,Object> attributes = new HashMap<>(); + attributes.put(Binding.ARGUMENTS, arguments); + attributes.put(Binding.NAME, getTestName()); + AMQQueue queue = mock(AMQQueue.class); + when(queue.getTaskExecutor()).thenReturn(_taskExecutor); + when(queue.getModel()).thenReturn(_model); + ExchangeImpl exchange = mock(ExchangeImpl.class); + when(exchange.getTaskExecutor()).thenReturn(_taskExecutor); + when(exchange.getModel()).thenReturn(_model); + BindingImpl binding = new BindingImpl(attributes, queue, exchange); + try + { + binding.create(); + fail("Exception is expected on validation with invalid selector"); + } + catch (IllegalConfigurationException e) + { + assertTrue("Unexpected exception message " + e.getMessage(), e.getMessage().startsWith("Cannot parse JMS selector")); + } + } +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java index 4b4891d838..b4f92990eb 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java @@ -63,7 +63,7 @@ public class FileKeyStoreCreationTest extends TestCase Map<String, Object> attributesCopy = new HashMap<String, Object>(attributes); Broker broker = mock(Broker.class); - TaskExecutor executor = new CurrentThreadTaskExecutor(); + TaskExecutor executor = CurrentThreadTaskExecutor.newStartedInstance(); when(broker.getObjectFactory()).thenReturn(_factory); when(broker.getModel()).thenReturn(_factory.getModel()); when(broker.getTaskExecutor()).thenReturn(executor); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java index 36353f0dba..fbb08cdd2a 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java @@ -34,6 +34,7 @@ import java.util.HashSet; import java.util.Map; import java.util.UUID; +import org.apache.qpid.server.model.BrokerShutdownProvider; import org.mockito.ArgumentCaptor; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -78,7 +79,8 @@ public class ManagementModeStoreHandlerTest extends QpidTestCase _taskExecutor.start(); _systemConfig = new JsonSystemConfigImpl(_taskExecutor, mock(EventLogger.class), - mock(LogRecorder.class), new BrokerOptions()); + mock(LogRecorder.class), new BrokerOptions(), + mock(BrokerShutdownProvider.class)); ConfiguredObjectRecord systemContextRecord = _systemConfig.asObjectRecord(); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java index e5c5a89c10..a1a363d5fe 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java @@ -26,7 +26,9 @@ import java.util.Map; import junit.framework.TestCase; +import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.model.testmodel.TestChildCategory; +import org.apache.qpid.server.model.testmodel.TestConfiguredObject; import org.apache.qpid.server.model.testmodel.TestModel; import org.apache.qpid.server.model.testmodel.TestRootCategory; import org.apache.qpid.server.store.ConfiguredObjectRecord; @@ -257,4 +259,189 @@ public class AbstractConfiguredObjectTest extends TestCase parent.getChildren(TestChildCategory.class).isEmpty()); } + public void testOpeningResultsInErroredStateWhenResolutionFails() throws Exception + { + TestConfiguredObject object = new TestConfiguredObject(getName()); + object.setThrowExceptionOnPostResolve(true); + object.open(); + assertFalse("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.ERRORED, object.getState()); + + object.setThrowExceptionOnPostResolve(false); + object.setAttributes(Collections.<String, Object>singletonMap(Port.DESIRED_STATE, State.ACTIVE)); + assertTrue("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.ACTIVE, object.getState()); + } + + public void testOpeningInERROREDStateAfterFailedOpenOnDesiredStateChangeToActive() throws Exception + { + TestConfiguredObject object = new TestConfiguredObject(getName()); + object.setThrowExceptionOnOpen(true); + object.open(); + assertFalse("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.ERRORED, object.getState()); + + object.setThrowExceptionOnOpen(false); + object.setAttributes(Collections.<String, Object>singletonMap(Port.DESIRED_STATE, State.ACTIVE)); + assertTrue("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.ACTIVE, object.getState()); + } + + public void testOpeningInERROREDStateAfterFailedOpenOnStart() throws Exception + { + TestConfiguredObject object = new TestConfiguredObject(getName()); + object.setThrowExceptionOnOpen(true); + object.open(); + assertFalse("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.ERRORED, object.getState()); + + object.setThrowExceptionOnOpen(false); + object.start(); + assertTrue("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.ACTIVE, object.getState()); + } + + public void testDeletionERROREDStateAfterFailedOpenOnDelete() throws Exception + { + TestConfiguredObject object = new TestConfiguredObject(getName()); + object.setThrowExceptionOnOpen(true); + object.open(); + assertFalse("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.ERRORED, object.getState()); + + object.delete(); + assertFalse("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.DELETED, object.getState()); + } + + public void testDeletionInERROREDStateAfterFailedOpenOnDesiredStateChangeToDelete() throws Exception + { + TestConfiguredObject object = new TestConfiguredObject(getName()); + object.setThrowExceptionOnOpen(true); + object.open(); + assertFalse("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.ERRORED, object.getState()); + + object.setAttributes(Collections.<String, Object>singletonMap(Port.DESIRED_STATE, State.DELETED)); + assertFalse("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.DELETED, object.getState()); + } + + + public void testCreationWithExceptionThrownFromValidationOnCreate() throws Exception + { + TestConfiguredObject object = new TestConfiguredObject(getName()); + object.setThrowExceptionOnValidationOnCreate(true); + try + { + object.create(); + fail("IllegalConfigurationException is expected to be thrown"); + } + catch(IllegalConfigurationException e) + { + //pass + } + assertFalse("Unexpected opened", object.isOpened()); + } + + public void testCreationWithoutExceptionThrownFromValidationOnCreate() throws Exception + { + TestConfiguredObject object = new TestConfiguredObject(getName()); + object.setThrowExceptionOnValidationOnCreate(false); + object.create(); + assertTrue("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.ACTIVE, object.getState()); + } + + public void testCreationWithExceptionThrownFromOnOpen() throws Exception + { + TestConfiguredObject object = new TestConfiguredObject(getName()); + object.setThrowExceptionOnOpen(true); + try + { + object.create(); + fail("Exception should have been re-thrown"); + } + catch (RuntimeException re) + { + // pass + } + + assertFalse("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.DELETED, object.getState()); + } + + public void testCreationWithExceptionThrownFromOnCreate() throws Exception + { + TestConfiguredObject object = new TestConfiguredObject(getName()); + object.setThrowExceptionOnCreate(true); + try + { + object.create(); + fail("Exception should have been re-thrown"); + } + catch (RuntimeException re) + { + // pass + } + + assertFalse("Unexpected opened", object.isOpened()); + assertEquals("Unexpected state", State.DELETED, object.getState()); + } + + public void testUnresolvedChildInERROREDStateIsNotValidatedOrOpenedOrAttainedDesiredStateOnParentOpen() throws Exception + { + TestConfiguredObject parent = new TestConfiguredObject("parent"); + TestConfiguredObject child1 = new TestConfiguredObject("child1", parent, parent.getTaskExecutor()); + child1.registerWithParents(); + TestConfiguredObject child2 = new TestConfiguredObject("child2", parent, parent.getTaskExecutor()); + child2.registerWithParents(); + + child1.setThrowExceptionOnPostResolve(true); + + parent.open(); + + assertTrue("Parent should be resolved", parent.isResolved()); + assertTrue("Parent should be validated", parent.isValidated()); + assertTrue("Parent should be opened", parent.isOpened()); + assertEquals("Unexpected parent state", State.ACTIVE, parent.getState()); + + assertTrue("Child2 should be resolved", child2.isResolved()); + assertTrue("Child2 should be validated", child2.isValidated()); + assertTrue("Child2 should be opened", child2.isOpened()); + assertEquals("Unexpected child2 state", State.ACTIVE, child2.getState()); + + assertFalse("Child2 should not be resolved", child1.isResolved()); + assertFalse("Child1 should not be validated", child1.isValidated()); + assertFalse("Child1 should not be opened", child1.isOpened()); + assertEquals("Unexpected child1 state", State.ERRORED, child1.getState()); + } + + public void testUnvalidatedChildInERROREDStateIsNotOpenedOrAttainedDesiredStateOnParentOpen() throws Exception + { + TestConfiguredObject parent = new TestConfiguredObject("parent"); + TestConfiguredObject child1 = new TestConfiguredObject("child1", parent, parent.getTaskExecutor()); + child1.registerWithParents(); + TestConfiguredObject child2 = new TestConfiguredObject("child2", parent, parent.getTaskExecutor()); + child2.registerWithParents(); + + child1.setThrowExceptionOnValidate(true); + + parent.open(); + + assertTrue("Parent should be resolved", parent.isResolved()); + assertTrue("Parent should be validated", parent.isValidated()); + assertTrue("Parent should be opened", parent.isOpened()); + assertEquals("Unexpected parent state", State.ACTIVE, parent.getState()); + + assertTrue("Child2 should be resolved", child2.isResolved()); + assertTrue("Child2 should be validated", child2.isValidated()); + assertTrue("Child2 should be opened", child2.isOpened()); + assertEquals("Unexpected child2 state", State.ACTIVE, child2.getState()); + + assertTrue("Child1 should be resolved", child1.isResolved()); + assertFalse("Child1 should not be validated", child1.isValidated()); + assertFalse("Child1 should not be opened", child1.isOpened()); + assertEquals("Unexpected child1 state", State.ERRORED, child1.getState()); + } } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java index db5cf1a7ba..ba6b0d95f3 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java @@ -65,6 +65,7 @@ public class VirtualHostTest extends QpidTestCase private TaskExecutor _taskExecutor; private VirtualHostNode<?> _virtualHostNode; private DurableConfigurationStore _configStore; + private VirtualHost<?, ?, ?> _virtualHost; @Override protected void setUp() throws Exception @@ -94,7 +95,17 @@ public class VirtualHostTest extends QpidTestCase { try { - _taskExecutor.stopImmediately(); + try + { + _taskExecutor.stopImmediately(); + } + finally + { + if (_virtualHost != null) + { + _virtualHost.close(); + } + } } finally { @@ -386,6 +397,7 @@ public class VirtualHostTest extends QpidTestCase TestMemoryVirtualHost host = new TestMemoryVirtualHost(attributes, _virtualHostNode); host.create(); + _virtualHost = host; return host; } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java new file mode 100644 index 0000000000..50a4e5a86e --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java @@ -0,0 +1,117 @@ +/* + * + * 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.qpid.server.model.adapter; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.test.utils.TestFileUtils; + +public class FileBasedGroupProviderImplTest extends QpidTestCase +{ + private TaskExecutor _taskExecutor; + private Broker _broker; + private File _groupFile; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance(); + + _broker = mock(Broker.class); + when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); + when(_broker.getModel()).thenReturn(BrokerModel.getInstance()); + when(_broker.getId()).thenReturn(UUID.randomUUID()); + when(_broker.getSecurityManager()).thenReturn(new SecurityManager(_broker, false)); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_groupFile.exists()) + { + _groupFile.delete(); + } + _taskExecutor.stop(); + } + finally + { + super.tearDown(); + } + } + + public void testValidationOnCreateWithInvalidPath() + { + Map<String,Object> attributes = new HashMap<>(); + _groupFile = TestFileUtils.createTempFile(this, "groups"); + + String groupsFile = _groupFile.getAbsolutePath() + File.separator + "groups"; + assertFalse("File should not exist", new File(groupsFile).exists()); + attributes.put(FileBasedGroupProvider.PATH, groupsFile); + attributes.put(FileBasedGroupProvider.NAME, getTestName()); + + FileBasedGroupProviderImpl groupsProvider = new FileBasedGroupProviderImpl(attributes, _broker); + try + { + groupsProvider.create(); + fail("Exception is expected on validation of groups provider with invalid path"); + } catch (IllegalConfigurationException e) + { + assertEquals("Unexpected exception message:" + e.getMessage(), String.format("Cannot create groups file at '%s'", groupsFile), e.getMessage()); + } + } + + public void testValidationOnCreateWithInvalidGroups() + { + _groupFile = TestFileUtils.createTempFile(this, "groups", "=blah"); + Map<String, Object> attributes = new HashMap<>(); + String groupsFile = _groupFile.getAbsolutePath(); + attributes.put(FileBasedGroupProvider.PATH, groupsFile); + attributes.put(FileBasedGroupProvider.NAME, getTestName()); + + FileBasedGroupProviderImpl groupsProvider = new FileBasedGroupProviderImpl(attributes, _broker); + try + { + groupsProvider.create(); + fail("Exception is expected on validation of groups provider with invalid group file"); + } + catch (IllegalConfigurationException e) + { + assertEquals("Unexpected exception message:" + e.getMessage(), String.format("Cannot load groups from '%s'", groupsFile), e.getMessage()); + } + } + +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java index 9bb004e4c2..f532a9325b 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.model.AuthenticationProvider; @@ -109,7 +110,7 @@ public class FileSystemPreferencesProviderTest extends QpidTestCase attributes.put(ConfiguredObject.ID, UUID.randomUUID()); attributes.put(ConfiguredObject.NAME, getTestName()); _preferencesProvider = new FileSystemPreferencesProviderImpl(attributes, _authenticationProvider); - _preferencesProvider.open(); + _preferencesProvider.create(); assertEquals(State.ACTIVE, _preferencesProvider.getState()); assertTrue("Preferences file was not created", nonExistingFile.exists()); @@ -120,6 +121,57 @@ public class FileSystemPreferencesProviderTest extends QpidTestCase } } + public void testValidationOnCreateForInvalidPath() throws Exception + { + File file = new File(TMP_FOLDER + File.separator + getTestName() + System.nanoTime() ); + file.createNewFile(); + String path = file.getAbsolutePath() + File.separator + "users"; + + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(FileSystemPreferencesProvider.PATH, path); + attributes.put(ConfiguredObject.ID, UUID.randomUUID()); + attributes.put(ConfiguredObject.NAME, getTestName()); + _preferencesProvider = new FileSystemPreferencesProviderImpl(attributes, _authenticationProvider); + + try + { + + _preferencesProvider.create(); + + fail("Creation of preferences provider with invalid path should have failed"); + } + catch(IllegalConfigurationException e) + { + assertEquals("Unexpected exception message:" + e.getMessage(), String.format("Cannot create preferences store file at '%s'", path), e.getMessage()); + } + } + + public void testValidationOnCreateWithInvalidPreferences() + { + File tmp = TestFileUtils.createTempFile(this, "preferences", "{blah:=boo}"); + try + { + Map<String, Object> attributes = new HashMap<String, Object>(); + attributes.put(FileSystemPreferencesProvider.PATH, tmp.getAbsolutePath()); + attributes.put(ConfiguredObject.ID, UUID.randomUUID()); + attributes.put(ConfiguredObject.NAME, getTestName()); + _preferencesProvider = new FileSystemPreferencesProviderImpl(attributes, _authenticationProvider); + try + { + _preferencesProvider.create(); + fail("Exception is expected on validation of groups provider with invalid preferences format"); + } + catch (IllegalConfigurationException e) + { + assertEquals("Unexpected exception message:" + e.getMessage(), "Cannot parse preferences json in " + tmp.getName(), e.getMessage()); + } + } + finally + { + tmp.delete(); + } + } + public void testConstructionWithEmptyFile() throws Exception { File emptyPrefsFile = new File(TMP_FOLDER, "preferences-" + getTestName() + ".json"); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java index 523203c756..642ea06ede 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java @@ -54,7 +54,7 @@ import org.apache.qpid.test.utils.QpidTestCase; public class PortFactoryTest extends QpidTestCase { private UUID _portId = UUID.randomUUID(); - private int _portNumber = 123; + private int _portNumber; private Set<String> _tcpStringSet = Collections.singleton(Transport.TCP.name()); private Set<Transport> _tcpTransports = Collections.singleton(Transport.TCP); private Set<String> _sslStringSet = Collections.singleton(Transport.SSL.name()); @@ -68,11 +68,13 @@ public class PortFactoryTest extends QpidTestCase private String _authProviderName = "authProvider"; private AuthenticationProvider _authProvider = mock(AuthenticationProvider.class); private ConfiguredObjectFactoryImpl _factory; + private Port<?> _port; @Override protected void setUp() throws Exception { + _portNumber = findFreePort(); TaskExecutor executor = CurrentThreadTaskExecutor.newStartedInstance(); when(_authProvider.getName()).thenReturn(_authProviderName); when(_broker.getChildren(eq(AuthenticationProvider.class))).thenReturn(Collections.singleton(_authProvider)); @@ -109,30 +111,45 @@ public class PortFactoryTest extends QpidTestCase _attributes.put(Port.BINDING_ADDRESS, "127.0.0.1"); } + public void tearDown() throws Exception + { + try + { + if (_port != null) + { + _port.close(); + } + } + finally + { + super.tearDown(); + } + } + public void testCreatePortWithMinimumAttributes() { Map<String, Object> attributes = new HashMap<String, Object>(); - attributes.put(Port.PORT, 1); + attributes.put(Port.PORT, _portNumber); attributes.put(Port.NAME, getName()); attributes.put(Port.AUTHENTICATION_PROVIDER, _authProviderName); attributes.put(Port.DESIRED_STATE, State.QUIESCED); - Port<?> port = _factory.create(Port.class, attributes, _broker); + _port = _factory.create(Port.class, attributes, _broker); - assertNotNull(port); - assertTrue(port instanceof AmqpPort); - assertEquals("Unexpected port", 1, port.getPort()); - assertEquals("Unexpected transports", Collections.singleton(PortFactory.DEFAULT_TRANSPORT), port.getTransports()); + assertNotNull(_port); + assertTrue(_port instanceof AmqpPort); + assertEquals("Unexpected _port", _portNumber, _port.getPort()); + assertEquals("Unexpected transports", Collections.singleton(PortFactory.DEFAULT_TRANSPORT), _port.getTransports()); assertEquals("Unexpected send buffer size", PortFactory.DEFAULT_AMQP_SEND_BUFFER_SIZE, - port.getAttribute(AmqpPort.SEND_BUFFER_SIZE)); + _port.getAttribute(AmqpPort.SEND_BUFFER_SIZE)); assertEquals("Unexpected receive buffer size", PortFactory.DEFAULT_AMQP_RECEIVE_BUFFER_SIZE, - port.getAttribute(AmqpPort.RECEIVE_BUFFER_SIZE)); + _port.getAttribute(AmqpPort.RECEIVE_BUFFER_SIZE)); assertEquals("Unexpected need client auth", PortFactory.DEFAULT_AMQP_NEED_CLIENT_AUTH, - port.getAttribute(Port.NEED_CLIENT_AUTH)); + _port.getAttribute(Port.NEED_CLIENT_AUTH)); assertEquals("Unexpected want client auth", PortFactory.DEFAULT_AMQP_WANT_CLIENT_AUTH, - port.getAttribute(Port.WANT_CLIENT_AUTH)); - assertEquals("Unexpected tcp no delay", PortFactory.DEFAULT_AMQP_TCP_NO_DELAY, port.getAttribute(Port.TCP_NO_DELAY)); - assertEquals("Unexpected binding", PortFactory.DEFAULT_AMQP_BINDING, port.getAttribute(Port.BINDING_ADDRESS)); + _port.getAttribute(Port.WANT_CLIENT_AUTH)); + assertEquals("Unexpected tcp no delay", PortFactory.DEFAULT_AMQP_TCP_NO_DELAY, _port.getAttribute(Port.TCP_NO_DELAY)); + assertEquals("Unexpected binding", PortFactory.DEFAULT_AMQP_BINDING, _port.getAttribute(Port.BINDING_ADDRESS)); } public void testCreateAmqpPort() @@ -256,27 +273,27 @@ public class PortFactoryTest extends QpidTestCase _attributes.put(Port.DESIRED_STATE, State.QUIESCED); - Port<?> port = _factory.create(Port.class, _attributes, _broker); + _port = _factory.create(Port.class, _attributes, _broker); - assertNotNull(port); - assertTrue(port instanceof AmqpPort); - assertEquals(_portId, port.getId()); - assertEquals(_portNumber, port.getPort()); + assertNotNull(_port); + assertTrue(_port instanceof AmqpPort); + assertEquals(_portId, _port.getId()); + assertEquals(_portNumber, _port.getPort()); if(useSslTransport) { - assertEquals(_sslTransports, port.getTransports()); + assertEquals(_sslTransports, _port.getTransports()); } else { - assertEquals(_tcpTransports, port.getTransports()); + assertEquals(_tcpTransports, _port.getTransports()); } - assertEquals(amqp010ProtocolSet, port.getProtocols()); - assertEquals("Unexpected send buffer size", 2, port.getAttribute(AmqpPort.SEND_BUFFER_SIZE)); - assertEquals("Unexpected receive buffer size", 1, port.getAttribute(AmqpPort.RECEIVE_BUFFER_SIZE)); - assertEquals("Unexpected need client auth", needClientAuth, port.getAttribute(Port.NEED_CLIENT_AUTH)); - assertEquals("Unexpected want client auth", wantClientAuth, port.getAttribute(Port.WANT_CLIENT_AUTH)); - assertEquals("Unexpected tcp no delay", true, port.getAttribute(Port.TCP_NO_DELAY)); - assertEquals("Unexpected binding", "127.0.0.1", port.getAttribute(Port.BINDING_ADDRESS)); + assertEquals(amqp010ProtocolSet, _port.getProtocols()); + assertEquals("Unexpected send buffer size", 2, _port.getAttribute(AmqpPort.SEND_BUFFER_SIZE)); + assertEquals("Unexpected receive buffer size", 1, _port.getAttribute(AmqpPort.RECEIVE_BUFFER_SIZE)); + assertEquals("Unexpected need client auth", needClientAuth, _port.getAttribute(Port.NEED_CLIENT_AUTH)); + assertEquals("Unexpected want client auth", wantClientAuth, _port.getAttribute(Port.WANT_CLIENT_AUTH)); + assertEquals("Unexpected tcp no delay", true, _port.getAttribute(Port.TCP_NO_DELAY)); + assertEquals("Unexpected binding", "127.0.0.1", _port.getAttribute(Port.BINDING_ADDRESS)); } public void testCreateNonAmqpPort() @@ -291,14 +308,14 @@ public class PortFactoryTest extends QpidTestCase _attributes.put(Port.NAME, getName()); _attributes.put(Port.ID, _portId); - Port<?> port = _factory.create(Port.class, _attributes, _broker); + _port = _factory.create(Port.class, _attributes, _broker); - assertNotNull(port); - assertFalse("Port should not be an AMQP-specific subclass", port instanceof AmqpPort); - assertEquals(_portId, port.getId()); - assertEquals(_portNumber, port.getPort()); - assertEquals(_tcpTransports, port.getTransports()); - assertEquals(nonAmqpProtocolSet, port.getProtocols()); + assertNotNull(_port); + assertFalse("Port should not be an AMQP-specific subclass", _port instanceof AmqpPort); + assertEquals(_portId, _port.getId()); + assertEquals(_portNumber, _port.getPort()); + assertEquals(_tcpTransports, _port.getTransports()); + assertEquals(nonAmqpProtocolSet, _port.getProtocols()); } public void testCreateNonAmqpPortWithPartiallySetAttributes() @@ -312,14 +329,14 @@ public class PortFactoryTest extends QpidTestCase _attributes.put(Port.NAME, getName()); _attributes.put(Port.ID, _portId); - Port<?> port = _factory.create(Port.class, _attributes, _broker); + _port = _factory.create(Port.class, _attributes, _broker); - assertNotNull(port); - assertFalse("Port not be an AMQP-specific port subclass", port instanceof AmqpPort); - assertEquals(_portId, port.getId()); - assertEquals(_portNumber, port.getPort()); - assertEquals(Collections.singleton(PortFactory.DEFAULT_TRANSPORT), port.getTransports()); - assertEquals(nonAmqpProtocolSet, port.getProtocols()); + assertNotNull(_port); + assertFalse("Port not be an AMQP-specific _port subclass", _port instanceof AmqpPort); + assertEquals(_portId, _port.getId()); + assertEquals(_portNumber, _port.getPort()); + assertEquals(Collections.singleton(PortFactory.DEFAULT_TRANSPORT), _port.getTransports()); + assertEquals(nonAmqpProtocolSet, _port.getProtocols()); } @@ -330,7 +347,7 @@ public class PortFactoryTest extends QpidTestCase try { - Port<?> port = _factory.create(Port.class, _attributes, _broker); + _port = _factory.create(Port.class, _attributes, _broker); fail("Exception not thrown"); } catch (IllegalConfigurationException e) @@ -353,7 +370,7 @@ public class PortFactoryTest extends QpidTestCase try { - Port<?> port = _factory.create(Port.class, attributes, _broker); + _port = _factory.create(Port.class, attributes, _broker); fail("RMI port creation should fail as another one already exist"); } catch(IllegalConfigurationException e) @@ -377,7 +394,7 @@ public class PortFactoryTest extends QpidTestCase try { - Port<?> port = _factory.create(Port.class, attributes, _broker); + _port = _factory.create(Port.class, attributes, _broker); fail("RMI port creation should fail due to requesting SSL"); } catch(IllegalConfigurationException e) diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/port/AmqpPortImplTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/port/AmqpPortImplTest.java new file mode 100644 index 0000000000..1a993f8967 --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/port/AmqpPortImplTest.java @@ -0,0 +1,123 @@ +/* + * 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.qpid.server.model.port; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.logging.EventLogger; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.test.utils.QpidTestCase; + +public class AmqpPortImplTest extends QpidTestCase +{ + private static final String AUTHENTICATION_PROVIDER_NAME = "test"; + private TaskExecutor _taskExecutor; + private Broker _broker; + private ServerSocket _socket; + private AmqpPortImpl _port; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance(); + Model model = BrokerModel.getInstance(); + + _broker = mock(Broker.class); + when(_broker.getTaskExecutor()).thenReturn(_taskExecutor); + when(_broker.getModel()).thenReturn(model); + when(_broker.getId()).thenReturn(UUID.randomUUID()); + when(_broker.getSecurityManager()).thenReturn(new SecurityManager(_broker, false)); + when(_broker.getCategoryClass()).thenReturn(Broker.class); + when(_broker.getEventLogger()).thenReturn(new EventLogger()); + AuthenticationProvider<?> provider = mock(AuthenticationProvider.class); + when(provider.getName()).thenReturn(AUTHENTICATION_PROVIDER_NAME); + when(provider.getParent(Broker.class)).thenReturn(_broker); + when(_broker.getChildren(AuthenticationProvider.class)).thenReturn(Collections.<AuthenticationProvider>singleton(provider)); + when(_broker.getChildByName(AuthenticationProvider.class, AUTHENTICATION_PROVIDER_NAME)).thenReturn(provider); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_socket != null) + { + _socket.close(); + } + _taskExecutor.stop(); + } + finally + { + if (_port != null) + { + _port.close(); + } + super.tearDown(); + } + } + + public void testValidateOnCreate() throws Exception + { + _socket = openSocket(); + + Map<String, Object> attributes = new HashMap<>(); + attributes.put(AmqpPort.PORT, _socket.getLocalPort()); + attributes.put(AmqpPort.NAME, getTestName()); + attributes.put(AmqpPort.AUTHENTICATION_PROVIDER, AUTHENTICATION_PROVIDER_NAME); + _port = new AmqpPortImpl(attributes, _broker); + try + { + _port.create(); + fail("Creation should fail due to validation check"); + } + catch (IllegalConfigurationException e) + { + assertEquals("Unexpected exception message", + String.format("Cannot bind to port %d and binding address '%s'. Port is already is use.", + _socket.getLocalPort(), "*"), e.getMessage()); + } + } + + private ServerSocket openSocket() throws IOException + { + ServerSocket serverSocket = new ServerSocket(); + serverSocket.setReuseAddress(true); + serverSocket.bind(new InetSocketAddress(findFreePort())); + return serverSocket; + } +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java new file mode 100644 index 0000000000..5c04db0cd6 --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java @@ -0,0 +1,256 @@ +/* + * 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.qpid.server.model.testmodel; + +import static org.mockito.Mockito.mock; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.AbstractConfiguredObject; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.ConfiguredObjectFactory; +import org.apache.qpid.server.model.ConfiguredObjectFactoryImpl; +import org.apache.qpid.server.model.ConfiguredObjectTypeRegistry; +import org.apache.qpid.server.model.ManagedObject; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.StateTransition; +import org.apache.qpid.server.plugin.ConfiguredObjectRegistration; + +@ManagedObject +public class TestConfiguredObject extends AbstractConfiguredObject +{ + private boolean _opened; + private boolean _validated; + private boolean _resolved; + private boolean _throwExceptionOnOpen; + private boolean _throwExceptionOnValidationOnCreate; + private boolean _throwExceptionOnPostResolve; + private boolean _throwExceptionOnCreate; + private boolean _throwExceptionOnValidate; + + public final static Map<Class<? extends ConfiguredObject>, ConfiguredObject<?>> createParents(ConfiguredObject<?> parent) + { + return Collections.<Class<? extends ConfiguredObject>, ConfiguredObject<?>>singletonMap(parent.getCategoryClass(), parent); + } + + public TestConfiguredObject(String name) + { + this(name, mock(ConfiguredObject.class), CurrentThreadTaskExecutor.newStartedInstance()); + } + + public TestConfiguredObject(String name, ConfiguredObject<?> parent, TaskExecutor taskExecutor) + { + this(createParents(parent), Collections.<String, Object>singletonMap(ConfiguredObject.NAME, name), taskExecutor, TestConfiguredObjectModel.INSTANCE); + } + + public TestConfiguredObject(Map parents, Map<String, Object> attributes, TaskExecutor taskExecutor, Model model) + { + super(parents, attributes, taskExecutor, model); + _opened = false; + } + + @Override + protected void postResolve() + { + if (_throwExceptionOnPostResolve) + { + throw new IllegalConfigurationException("Cannot resolve"); + } + _resolved = true; + } + + @Override + protected void onCreate() + { + if (_throwExceptionOnCreate) + { + throw new IllegalConfigurationException("Cannot create"); + } + } + + @Override + protected void onOpen() + { + if (_throwExceptionOnOpen) + { + throw new IllegalConfigurationException("Cannot open"); + } + _opened = true; + } + + @Override + protected void validateOnCreate() + { + if (_throwExceptionOnValidationOnCreate) + { + throw new IllegalConfigurationException("Cannot validate on create"); + } + } + + @Override + public void onValidate() + { + if (_throwExceptionOnValidate) + { + throw new IllegalConfigurationException("Cannot validate"); + } + _validated = true; + } + + @StateTransition( currentState = {State.ERRORED, State.UNINITIALIZED}, desiredState = State.ACTIVE ) + protected void activate() + { + setState(State.ACTIVE); + } + + @StateTransition( currentState = {State.ERRORED, State.UNINITIALIZED}, desiredState = State.DELETED ) + protected void doDelete() + { + setState(State.DELETED); + } + + public boolean isOpened() + { + return _opened; + } + + public void setThrowExceptionOnOpen(boolean throwException) + { + _throwExceptionOnOpen = throwException; + } + + public void setThrowExceptionOnValidationOnCreate(boolean throwException) + { + _throwExceptionOnValidationOnCreate = throwException; + } + + public void setThrowExceptionOnPostResolve(boolean throwException) + { + _throwExceptionOnPostResolve = throwException; + } + + public void setThrowExceptionOnCreate(boolean throwExceptionOnCreate) + { + _throwExceptionOnCreate = throwExceptionOnCreate; + } + + public void setThrowExceptionOnValidate(boolean throwException) + { + _throwExceptionOnValidate= throwException; + } + + public boolean isValidated() + { + return _validated; + } + + public boolean isResolved() + { + return _resolved; + } + + public static class TestConfiguredObjectModel extends Model + { + + private Collection<Class<? extends ConfiguredObject>> CATEGORIES = Collections.<Class<? extends ConfiguredObject>>singleton(TestConfiguredObject.class); + private ConfiguredObjectFactoryImpl _configuredObjectFactory; + + private static TestConfiguredObjectModel INSTANCE = new TestConfiguredObjectModel(); + private ConfiguredObjectTypeRegistry _configuredObjectTypeRegistry; + + private TestConfiguredObjectModel() + { + _configuredObjectFactory = new ConfiguredObjectFactoryImpl(this); + ConfiguredObjectRegistration configuredObjectRegistration = new ConfiguredObjectRegistration() + { + @Override + public Collection<Class<? extends ConfiguredObject>> getConfiguredObjectClasses() + { + return CATEGORIES; + } + + @Override + public String getType() + { + return TestConfiguredObjectModel.class.getSimpleName(); + } + }; + _configuredObjectTypeRegistry = new ConfiguredObjectTypeRegistry(Arrays.asList(configuredObjectRegistration), CATEGORIES); + } + + @Override + public Collection<Class<? extends ConfiguredObject>> getSupportedCategories() + { + return CATEGORIES; + } + + @Override + public Collection<Class<? extends ConfiguredObject>> getChildTypes(Class<? extends ConfiguredObject> parent) + { + return TestConfiguredObject.class.isAssignableFrom(parent) + ? CATEGORIES + : Collections.<Class<? extends ConfiguredObject>>emptySet(); + } + + @Override + public Class<? extends ConfiguredObject> getRootCategory() + { + return TestConfiguredObject.class; + } + + @Override + public Collection<Class<? extends ConfiguredObject>> getParentTypes(final Class<? extends ConfiguredObject> child) + { + return TestConfiguredObject.class.isAssignableFrom(child) + ? CATEGORIES + : Collections.<Class<? extends ConfiguredObject>>emptySet(); + } + + @Override + public int getMajorVersion() + { + return 99; + } + + @Override + public int getMinorVersion() + { + return 99; + } + + @Override + public ConfiguredObjectFactory getObjectFactory() + { + return _configuredObjectFactory; + } + + @Override + public ConfiguredObjectTypeRegistry getTypeRegistry() + { + return _configuredObjectTypeRegistry; + } + } +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java index 703a8d43c9..84ba7a3822 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java @@ -90,31 +90,28 @@ public class PrincipalDatabaseAuthenticationManagerTest extends QpidTestCase private void setupMocks() throws Exception { - _principalDatabase = mock(PrincipalDatabase.class); - - when(_principalDatabase.getMechanisms()).thenReturn(Collections.singletonList(MOCK_MECH_NAME)); - when(_principalDatabase.createSaslServer(MOCK_MECH_NAME, LOCALHOST, null)).thenReturn(new MySaslServer(false, true)); + setUpPrincipalDatabase(); setupManager(false); _manager.initialise(); } + private void setUpPrincipalDatabase() throws SaslException + { + _principalDatabase = mock(PrincipalDatabase.class); + + when(_principalDatabase.getMechanisms()).thenReturn(Collections.singletonList(MOCK_MECH_NAME)); + when(_principalDatabase.createSaslServer(MOCK_MECH_NAME, LOCALHOST, null)).thenReturn(new MySaslServer(false, true)); + } + private void setupManager(final boolean recovering) { Map<String,Object> attrs = new HashMap<String, Object>(); attrs.put(ConfiguredObject.ID, UUID.randomUUID()); attrs.put(ConfiguredObject.NAME, getTestName()); attrs.put("path", _passwordFileLocation); - _manager = new PrincipalDatabaseAuthenticationManager(attrs, BrokerTestHelper.createBrokerMock()) - { - @Override - protected PrincipalDatabase createDatabase() - { - return _principalDatabase; - } - - }; + _manager = getPrincipalDatabaseAuthenticationManager(attrs); if(recovering) { _manager.open(); @@ -273,6 +270,41 @@ public class PrincipalDatabaseAuthenticationManagerTest extends QpidTestCase assertFalse("Password file was not deleted", new File(_passwordFileLocation).exists()); } + public void testCreateForInvalidPath() throws Exception + { + setUpPrincipalDatabase(); + + Map<String,Object> attrs = new HashMap<>(); + attrs.put(ConfiguredObject.ID, UUID.randomUUID()); + attrs.put(ConfiguredObject.NAME, getTestName()); + String path = TMP_FOLDER + File.separator + getTestName() + System.nanoTime() + File.separator + "users"; + attrs.put("path", path); + + _manager = getPrincipalDatabaseAuthenticationManager(attrs); + try + { + _manager.create(); + fail("Creation with invalid path should have failed"); + } + catch(IllegalConfigurationException e) + { + assertEquals("Unexpected exception message:" + e.getMessage(), String.format("Cannot create password file at '%s'", path), e.getMessage()); + } + } + + PrincipalDatabaseAuthenticationManager getPrincipalDatabaseAuthenticationManager(final Map<String, Object> attrs) + { + return new PrincipalDatabaseAuthenticationManager(attrs, BrokerTestHelper.createBrokerMock()) + { + @Override + protected PrincipalDatabase createDatabase() + { + return _principalDatabase; + } + + }; + } + private void deletePasswordFileIfExists() { File passwordFile = new File(_passwordFileLocation); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java index 6001ed1750..9e580d3157 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java @@ -57,40 +57,15 @@ public class SimpleLDAPAuthenticationManagerFactoryTest extends TestCase _configuration.put(AuthenticationProvider.NAME, getName()); } - public void testLdapInstanceCreated() throws Exception + public void testLdapCreated() throws Exception { _configuration.put(AuthenticationProvider.TYPE, SimpleLDAPAuthenticationManager.PROVIDER_TYPE); - _configuration.put("providerUrl", "ldap://example.com:389/"); - _configuration.put("searchContext", "dc=example"); - - AuthenticationProvider manager = _factory.create(AuthenticationProvider.class, _configuration, _broker); - assertNotNull(manager); - - } - - public void testLdapsInstanceCreated() throws Exception - { - _configuration.put(AuthenticationProvider.TYPE, SimpleLDAPAuthenticationManager.PROVIDER_TYPE); - _configuration.put("providerUrl", "ldaps://example.com:636/"); - _configuration.put("searchContext", "dc=example"); - - AuthenticationProvider manager = _factory.create(AuthenticationProvider.class, _configuration, _broker); - assertNotNull(manager); - - } - - public void testLdapsWithTrustStoreInstanceCreated() throws Exception - { - when(_broker.getChildren(eq(TrustStore.class))).thenReturn(Collections.singletonList(_trustStore)); - - - _configuration.put(AuthenticationProvider.TYPE, SimpleLDAPAuthenticationManager.PROVIDER_TYPE); _configuration.put("providerUrl", "ldaps://example.com:636/"); _configuration.put("searchContext", "dc=example"); - _configuration.put("trustStore", "mytruststore"); + _configuration.put("searchFilter", "(uid={0})"); + _configuration.put("ldapContextFactory", TestLdapDirectoryContext.class.getName()); - AuthenticationProvider manager = _factory.create(AuthenticationProvider.class, _configuration, _broker); - assertNotNull(manager); + _factory.create(AuthenticationProvider.class, _configuration, _broker); } public void testLdapsWhenTrustStoreNotFound() throws Exception @@ -100,6 +75,7 @@ public class SimpleLDAPAuthenticationManagerFactoryTest extends TestCase _configuration.put(AuthenticationProvider.TYPE, SimpleLDAPAuthenticationManager.PROVIDER_TYPE); _configuration.put("providerUrl", "ldaps://example.com:636/"); _configuration.put("searchContext", "dc=example"); + _configuration.put("searchFilter", "(uid={0})"); _configuration.put("trustStore", "notfound"); try @@ -110,7 +86,7 @@ public class SimpleLDAPAuthenticationManagerFactoryTest extends TestCase catch(IllegalArgumentException e) { // PASS - assertTrue("Message does not include underlying issue", e.getMessage().contains("name 'notfound'")); + assertTrue("Message does not include underlying issue ", e.getMessage().contains("name 'notfound'")); assertTrue("Message does not include the attribute name", e.getMessage().contains("trustStore")); assertTrue("Message does not include the expected type", e.getMessage().contains("TrustStore")); } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/TestLdapDirectoryContext.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/TestLdapDirectoryContext.java new file mode 100644 index 0000000000..87b73c8373 --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/TestLdapDirectoryContext.java @@ -0,0 +1,38 @@ +/* + * 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.qpid.server.security.auth.manager; + +import static org.mockito.Mockito.mock; + +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; + +public class TestLdapDirectoryContext implements javax.naming.spi.InitialContextFactory +{ + @Override + public Context getInitialContext(final Hashtable<?, ?> environment) throws NamingException + { + return (DirContext)mock(DirContext.class); + } + +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java index 52f70e7fd6..c220876a23 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java @@ -21,7 +21,9 @@ package org.apache.qpid.server.store; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; import java.util.Arrays; import java.util.Collections; @@ -40,6 +42,7 @@ import org.apache.qpid.server.logging.LogRecorder; import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.BrokerShutdownProvider; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.GroupProvider; import org.apache.qpid.server.model.JsonSystemConfigImpl; @@ -55,6 +58,7 @@ public class BrokerRecovererTest extends TestCase private UUID _authenticationProvider1Id = UUID.randomUUID(); private SystemConfig<?> _systemConfig; private TaskExecutor _taskExecutor; + private BrokerShutdownProvider _brokerShutdownProvider; @Override protected void setUp() throws Exception @@ -63,8 +67,11 @@ public class BrokerRecovererTest extends TestCase _taskExecutor = new CurrentThreadTaskExecutor(); _taskExecutor.start(); + _brokerShutdownProvider = mock(BrokerShutdownProvider.class); _systemConfig = new JsonSystemConfigImpl(_taskExecutor, - mock(EventLogger.class), mock(LogRecorder.class), new BrokerOptions()); + mock(EventLogger.class), mock(LogRecorder.class), + new BrokerOptions(), + _brokerShutdownProvider); when(_brokerEntry.getId()).thenReturn(_brokerId); when(_brokerEntry.getType()).thenReturn(Broker.class.getSimpleName()); @@ -251,18 +258,10 @@ public class BrokerRecovererTest extends TestCase brokerAttributes.put(Broker.NAME, getName()); when(_brokerEntry.getAttributes()).thenReturn(brokerAttributes); - try - { - resolveObjects(_brokerEntry); - Broker<?> broker = _systemConfig.getBroker(); - broker.open(); - fail("The broker creation should fail due to unsupported model version"); - } - catch (IllegalConfigurationException e) - { - assertEquals("The model version '" + incompatibleVersion - + "' in configuration is incompatible with the broker model version '" + BrokerModel.MODEL_VERSION + "'", e.getMessage()); - } + resolveObjects(_brokerEntry); + Broker<?> broker = _systemConfig.getBroker(); + broker.open(); + verify(_brokerShutdownProvider).shutdown(); } } @@ -276,20 +275,12 @@ public class BrokerRecovererTest extends TestCase when(_brokerEntry.getAttributes()).thenReturn(brokerAttributes); - try - { - UnresolvedConfiguredObject<? extends ConfiguredObject> recover = - _systemConfig.getObjectFactory().recover(_brokerEntry, _systemConfig); + UnresolvedConfiguredObject<? extends ConfiguredObject> recover = + _systemConfig.getObjectFactory().recover(_brokerEntry, _systemConfig); - Broker<?> broker = (Broker<?>) recover.resolve(); - broker.open(); - fail("The broker creation should fail due to unsupported model version"); - } - catch (IllegalConfigurationException e) - { - assertEquals("The model version '" + incompatibleVersion - + "' in configuration is incompatible with the broker model version '" + BrokerModel.MODEL_VERSION + "'", e.getMessage()); - } + Broker<?> broker = (Broker<?>) recover.resolve(); + broker.open(); + verify(_brokerShutdownProvider).shutdown(); } public void testIncorrectModelVersion() throws Exception @@ -303,18 +294,12 @@ public class BrokerRecovererTest extends TestCase brokerAttributes.put(Broker.MODEL_VERSION, modelVersion); when(_brokerEntry.getAttributes()).thenReturn(brokerAttributes); - try - { - UnresolvedConfiguredObject<? extends ConfiguredObject> recover = - _systemConfig.getObjectFactory().recover(_brokerEntry, _systemConfig); - Broker<?> broker = (Broker<?>) recover.resolve(); - broker.open(); - fail("The broker creation should fail due to unsupported model version"); - } - catch (IllegalConfigurationException e) - { - // pass - } + UnresolvedConfiguredObject<? extends ConfiguredObject> recover = + _systemConfig.getObjectFactory().recover(_brokerEntry, _systemConfig); + Broker<?> broker = (Broker<?>) recover.resolve(); + broker.open(); + verify(_brokerShutdownProvider).shutdown(); + reset(_brokerShutdownProvider); } } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java index c94a0ef9c4..45b595b62e 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java @@ -32,6 +32,7 @@ import org.apache.qpid.server.BrokerOptions; import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.logging.LogRecorder; +import org.apache.qpid.server.model.BrokerShutdownProvider; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.JsonSystemConfigImpl; import org.apache.qpid.server.model.SystemConfig; @@ -60,7 +61,8 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase _systemConfig = new JsonSystemConfigImpl(_taskExecutor, mock(EventLogger.class), mock(LogRecorder.class), - new BrokerOptions()); + new BrokerOptions(), + mock(BrokerShutdownProvider.class)); } public void testUpgradeVirtualHostWithJDBCStoreAndBoneCPPool() diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java new file mode 100644 index 0000000000..889097f850 --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java @@ -0,0 +1,247 @@ +/* + * + * 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.qpid.server.virtualhost; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.doThrow; + +import java.io.File; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutorImpl; +import org.apache.qpid.server.logging.EventLogger; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.SystemConfig; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.store.DurableConfigurationStore; +import org.apache.qpid.server.store.MessageStore; +import org.apache.qpid.test.utils.QpidTestCase; +import org.mockito.verification.VerificationMode; + +public class AbstractVirtualHostTest extends QpidTestCase +{ + private TaskExecutor _taskExecutor; + private VirtualHostNode<?> _node; + private MessageStore _failingStore; + + @Override + public void setUp() throws Exception + { + super.setUp(); + + SystemConfig systemConfig = mock(SystemConfig.class); + when(systemConfig.getEventLogger()).thenReturn(mock(EventLogger.class)); + Broker<?> broker = mock(Broker.class); + when(broker.getParent(SystemConfig.class)).thenReturn(systemConfig); + when(broker.getSecurityManager()).thenReturn(new SecurityManager(broker, false)); + + _taskExecutor = new TaskExecutorImpl(); + _taskExecutor.start(); + when(broker.getTaskExecutor()).thenReturn(_taskExecutor); + + _node = mock(VirtualHostNode.class); + when(_node.getParent(Broker.class)).thenReturn(broker); + when(_node.getModel()).thenReturn(BrokerModel.getInstance()); + when(_node.getTaskExecutor()).thenReturn(_taskExecutor); + when(_node.getConfigurationStore()).thenReturn(mock(DurableConfigurationStore.class)); + + _failingStore = mock(MessageStore.class); + doThrow(new RuntimeException("Cannot open store")).when(_failingStore).openMessageStore(any(ConfiguredObject.class)); + } + + @Override + public void tearDown() throws Exception + { + try + { + if (_taskExecutor != null) + { + _taskExecutor.stopImmediately(); + } + } + finally + { + super.tearDown(); + } + } + + public void testValidateOnCreateFails() + { + Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName()); + + AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node) + { + @Override + protected MessageStore createMessageStore() + { + return _failingStore; + } + }; + + try + { + host.validateOnCreate(); + fail("Validation on creation should fail"); + } + catch(IllegalConfigurationException e) + { + assertTrue("Unexpected exception " + e.getMessage(), e.getMessage().startsWith("Cannot open virtual host message store")); + } + } + + public void testValidateOnCreateSucceeds() + { + Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName()); + final MessageStore store = mock(MessageStore.class); + AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node) + { + @Override + protected MessageStore createMessageStore() + { + return store; + } + }; + + host.validateOnCreate(); + verify(store).openMessageStore(host); + verify(store).closeMessageStore(); + } + + public void testOpenFails() + { + Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName()); + + AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node) + { + @Override + protected MessageStore createMessageStore() + { + return _failingStore; + } + }; + + host.open(); + assertEquals("Unexpected host state", State.ERRORED, host.getState()); + } + + public void testOpenSucceeds() + { + Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName()); + final MessageStore store = mock(MessageStore.class); + AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node) + { + @Override + protected MessageStore createMessageStore() + { + return store; + } + }; + + host.open(); + assertEquals("Unexpected host state", State.ACTIVE, host.getState()); + verify(store).openMessageStore(host); + + // make sure that method AbstractVirtualHost.onExceptionInOpen was not called + verify(store, times(0)).closeMessageStore(); + } + + public void testDeleteInErrorStateAfterOpen() + { + Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName()); + AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node) + { + @Override + protected MessageStore createMessageStore() + { + return _failingStore; + } + }; + + host.open(); + + assertEquals("Unexpected state", State.ERRORED, host.getState()); + + host.delete(); + assertEquals("Unexpected state", State.DELETED, host.getState()); + } + + public void testActivateInErrorStateAfterOpen() throws Exception + { + Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName()); + final MessageStore store = mock(MessageStore.class); + doThrow(new RuntimeException("Cannot open store")).when(store).openMessageStore(any(ConfiguredObject.class)); + AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node) + { + @Override + protected MessageStore createMessageStore() + { + return store; + } + }; + + host.open(); + assertEquals("Unexpected state", State.ERRORED, host.getState()); + + doNothing().when(store).openMessageStore(any(ConfiguredObject.class)); + + host.setAttributes(Collections.<String, Object>singletonMap(VirtualHost.DESIRED_STATE, State.ACTIVE)); + assertEquals("Unexpected state", State.ACTIVE, host.getState()); + } + + public void testStartInErrorStateAfterOpen() throws Exception + { + Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName()); + final MessageStore store = mock(MessageStore.class); + doThrow(new RuntimeException("Cannot open store")).when(store).openMessageStore(any(ConfiguredObject.class)); + AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node) + { + @Override + protected MessageStore createMessageStore() + { + return store; + } + }; + + host.open(); + assertEquals("Unexpected state", State.ERRORED, host.getState()); + + doNothing().when(store).openMessageStore(any(ConfiguredObject.class)); + + host.start(); + assertEquals("Unexpected state", State.ACTIVE, host.getState()); + } +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java index 971c96b2ff..b17f383217 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java @@ -20,22 +20,30 @@ */ package org.apache.qpid.server.virtualhostnode; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.security.AccessControlException; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; +import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; import org.apache.qpid.server.configuration.updater.TaskExecutor; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.BrokerModel; +import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.ConfiguredObjectFactoryImpl; import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.RemoteReplicationNode; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.SystemConfig; import org.apache.qpid.server.model.VirtualHost; @@ -348,6 +356,132 @@ public class AbstractStandardVirtualHostNodeTest extends QpidTestCase assertEquals("Virtual host node state changed unexpectedly", State.ACTIVE, node.getState()); } + public void testValidateOnCreateFails() throws Exception + { + String nodeName = getTestName(); + Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName); + + final DurableConfigurationStore store = mock(DurableConfigurationStore.class); + doThrow(new RuntimeException("Cannot open store")).when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class)); + AbstractStandardVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store); + + try + { + node.validateOnCreate(); + fail("Cannot create node"); + } + catch (IllegalConfigurationException e) + { + assertTrue("Unexpected exception " + e.getMessage(), e.getMessage().startsWith("Cannot open node configuration store")); + } + } + + public void testValidateOnCreateSucceeds() throws Exception + { + String nodeName = getTestName(); + Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName); + + final DurableConfigurationStore store = mock(DurableConfigurationStore.class); + AbstractStandardVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store); + + node.validateOnCreate(); + verify(store).openConfigurationStore(node, false); + verify(store).closeConfigurationStore(); + } + + public void testOpenFails() throws Exception + { + String nodeName = getTestName(); + Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName); + + DurableConfigurationStore store = mock(DurableConfigurationStore.class); + AbstractVirtualHostNode node = new TestAbstractVirtualHostNode( _broker, attributes, store); + node.open(); + assertEquals("Unexpected node state", State.ERRORED, node.getState()); + } + + public void testOpenSucceeds() throws Exception + { + String nodeName = getTestName(); + Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName); + + final AtomicBoolean onFailureFlag = new AtomicBoolean(); + DurableConfigurationStore store = mock(DurableConfigurationStore.class); + AbstractVirtualHostNode node = new TestAbstractVirtualHostNode( _broker, attributes, store) + { + @Override + public void onValidate() + { + // no op + } + + @Override + protected void onExceptionInOpen(RuntimeException e) + { + try + { + super.onExceptionInOpen(e); + } + finally + { + onFailureFlag.set(true); + } + } + }; + + node.open(); + assertEquals("Unexpected node state", State.ACTIVE, node.getState()); + assertFalse("onExceptionInOpen was called", onFailureFlag.get()); + } + + + public void testDeleteInErrorStateAfterOpen() + { + String nodeName = getTestName(); + Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName); + + final DurableConfigurationStore store = mock(DurableConfigurationStore.class); + doThrow(new RuntimeException("Cannot open store")).when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class)); + AbstractStandardVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store); + node.open(); + assertEquals("Unexpected node state", State.ERRORED, node.getState()); + + node.delete(); + assertEquals("Unexpected state", State.DELETED, node.getState()); + } + + public void testActivateInErrorStateAfterOpen() throws Exception + { + String nodeName = getTestName(); + Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName); + + DurableConfigurationStore store = mock(DurableConfigurationStore.class); + doThrow(new RuntimeException("Cannot open store")).when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class)); + AbstractVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store); + node.open(); + assertEquals("Unexpected node state", State.ERRORED, node.getState()); + doNothing().when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class)); + + node.setAttributes(Collections.<String, Object>singletonMap(VirtualHostNode.DESIRED_STATE, State.ACTIVE)); + assertEquals("Unexpected state", State.ACTIVE, node.getState()); + } + + public void testStartInErrorStateAfterOpen() throws Exception + { + String nodeName = getTestName(); + Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName); + + DurableConfigurationStore store = mock(DurableConfigurationStore.class); + doThrow(new RuntimeException("Cannot open store")).when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class)); + AbstractVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store); + node.open(); + assertEquals("Unexpected node state", State.ERRORED, node.getState()); + doNothing().when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class)); + + node.start(); + assertEquals("Unexpected state", State.ACTIVE, node.getState()); + } + private ConfiguredObjectRecord createVirtualHostConfiguredObjectRecord(UUID virtualHostId) { Map<String, Object> virtualHostAttributes = new HashMap<>(); @@ -384,4 +518,62 @@ public class AbstractStandardVirtualHostNodeTest extends QpidTestCase return configStoreThatProduces(null); } + + private AbstractStandardVirtualHostNode createAbstractStandardVirtualHostNode(final Map<String, Object> attributes, final DurableConfigurationStore store) + { + return new AbstractStandardVirtualHostNode(attributes, _broker){ + + @Override + protected void writeLocationEventLog() + { + + } + + @Override + protected DurableConfigurationStore createConfigurationStore() + { + return store; + } + }; + } + + private class TestAbstractVirtualHostNode extends AbstractVirtualHostNode + { + private DurableConfigurationStore _store; + + public TestAbstractVirtualHostNode(Broker parent, Map attributes, DurableConfigurationStore store) + { + super(parent, attributes); + _store = store; + } + + @Override + public void onValidate() + { + throw new RuntimeException("Cannot validate"); + } + + @Override + protected DurableConfigurationStore createConfigurationStore() + { + return _store; + } + + @Override + protected void activate() + { + } + + @Override + protected ConfiguredObjectRecord enrichInitialVirtualHostRootRecord(ConfiguredObjectRecord vhostRecord) + { + return null; + } + + @Override + public Collection<? extends RemoteReplicationNode> getRemoteReplicationNodes() + { + return null; + } + } } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java index 277ef8b400..4fe8136624 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java @@ -53,6 +53,12 @@ public class TestVirtualHostNode extends AbstractStandardVirtualHostNode<TestVir } @Override + public DurableConfigurationStore getConfigurationStore() + { + return _store; + } + + @Override protected void writeLocationEventLog() { } |