diff options
Diffstat (limited to 'java/broker-core/src/test/java/org/apache/qpid/server')
14 files changed, 830 insertions, 200 deletions
diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java index 6cfcf430b2..14ff640c57 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/StoreConfigurationChangeListenerTest.java @@ -27,10 +27,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import java.util.Collections; import java.util.UUID; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Model; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostNode; @@ -69,6 +71,9 @@ public class StoreConfigurationChangeListenerTest extends QpidTestCase when(broker.getCategoryClass()).thenReturn(Broker.class); VirtualHost child = mock(VirtualHost.class); when(child.getCategoryClass()).thenReturn(VirtualHost.class); + Model model = mock(Model.class); + when(model.getChildTypes(any(Class.class))).thenReturn(Collections.<Class<? extends ConfiguredObject>>emptyList()); + when(child.getModel()).thenReturn(model); _listener.childAdded(broker, child); verify(_store).update(eq(true), any(ConfiguredObjectRecord.class)); } 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 a1a363d5fe..54a059e067 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 @@ -24,16 +24,15 @@ import java.util.Collections; import java.util.HashMap; 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; +import org.apache.qpid.test.utils.QpidTestCase; -public class AbstractConfiguredObjectTest extends TestCase +public class AbstractConfiguredObjectTest extends QpidTestCase { private final Model _model = TestModel.getInstance(); @@ -169,6 +168,27 @@ public class AbstractConfiguredObjectTest extends TestCase System.clearProperty(sysPropertyName); } + + public void testDefaultContextIsInContextKeys() + { + final String objectName = "myName"; + + Map<String, Object> attributes = new HashMap<>(); + attributes.put(ConfiguredObject.NAME, objectName); + + + TestRootCategory object = _model.getObjectFactory().create(TestRootCategory.class, + attributes); + + + assertTrue("context default not in contextKeys", object.getContextKeys(true).contains(TestRootCategory.TEST_CONTEXT_DEFAULT)); + assertEquals(object.getContextValue(String.class, TestRootCategory.TEST_CONTEXT_DEFAULT), "default"); + + setTestSystemProperty(TestRootCategory.TEST_CONTEXT_DEFAULT, "notdefault"); + assertTrue("context default not in contextKeys", object.getContextKeys(true).contains(TestRootCategory.TEST_CONTEXT_DEFAULT)); + assertEquals(object.getContextValue(String.class, TestRootCategory.TEST_CONTEXT_DEFAULT), "notdefault"); + } + public void testStringAttributeValueFromContextVariableProvidedObjectsContext() { String contextToken = "${myReplacement}"; diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategory.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategory.java index d3fe14b7d8..de4b1ae1c2 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategory.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestChildCategory.java @@ -24,12 +24,12 @@ import java.util.Set; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.ManagedAttribute; +import org.apache.qpid.server.model.ManagedContextDefault; import org.apache.qpid.server.model.ManagedObject; @ManagedObject public interface TestChildCategory<X extends TestChildCategory<X>> extends ConfiguredObject<X> { - String NON_INTERPOLATED_VALID_VALUE = "${file.separator}"; @ManagedAttribute(validValues = { NON_INTERPOLATED_VALID_VALUE }, defaultValue = "") diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategory.java b/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategory.java index 7f804006b2..2359a93b43 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategory.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestRootCategory.java @@ -24,6 +24,7 @@ import java.util.Map; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.ManagedAttribute; +import org.apache.qpid.server.model.ManagedContextDefault; import org.apache.qpid.server.model.ManagedObject; @ManagedObject( defaultType = "test" ) @@ -35,6 +36,13 @@ public interface TestRootCategory<X extends TestRootCategory<X>> extends Configu String STRING_VALUE = "stringValue"; String MAP_VALUE = "mapValue"; + + String TEST_CONTEXT_DEFAULT = "TEST_CONTEXT_DEFAULT"; + + @ManagedContextDefault(name = TEST_CONTEXT_DEFAULT) + String testGlobalDefault = "default"; + + @ManagedAttribute String getAutomatedPersistedValue(); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java index 5366e6d8bf..8e814745b6 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java @@ -44,10 +44,10 @@ public class SubjectCreatorTest extends TestCase private static final String USERNAME = "username"; private static final String PASSWORD = "password"; - private AuthenticationProvider _authenticationProvider = mock(AuthenticationProvider.class); + private AuthenticationProvider<?> _authenticationProvider = mock(AuthenticationProvider.class); - private GroupProvider _groupManager1 = mock(GroupProvider.class); - private GroupProvider _groupManager2 = mock(GroupProvider.class); + private GroupProvider<?> _groupManager1 = mock(GroupProvider.class); + private GroupProvider<?> _groupManager2 = mock(GroupProvider.class); private Principal _userPrincipal = mock(Principal.class); private Principal _group1 = mock(Principal.class); @@ -64,7 +64,7 @@ public class SubjectCreatorTest extends TestCase when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group1)); when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group2)); - _subjectCreator = new SubjectCreator(_authenticationProvider, new HashSet<GroupProvider>(Arrays.asList(_groupManager1, _groupManager2)), + _subjectCreator = new SubjectCreator(_authenticationProvider, new HashSet<GroupProvider<?>>(Arrays.asList(_groupManager1, _groupManager2)), false); _authenticationResult = new AuthenticationResult(_userPrincipal); when(_authenticationProvider.authenticate(USERNAME, PASSWORD)).thenReturn(_authenticationResult); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/MD5AuthenticationManagerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/MD5AuthenticationManagerTest.java new file mode 100644 index 0000000000..aecd318937 --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/MD5AuthenticationManagerTest.java @@ -0,0 +1,53 @@ +/* + * + * 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 java.util.Map; + +public class MD5AuthenticationManagerTest extends ManagedAuthenticationManagerTestBase +{ + @Override + public void setUp() throws Exception + { + super.setUp(); + } + + @Override + protected ConfigModelPasswordManagingAuthenticationProvider<?> createAuthManager(final Map<String, Object> attributesMap) + { + return new MD5AuthenticationProvider(attributesMap, getBroker()); + } + + @Override + protected boolean isPlain() + { + return false; + } + + @Override + public void tearDown() throws Exception + { + super.tearDown(); + } + + + +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ManagedAuthenticationManagerTestBase.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ManagedAuthenticationManagerTestBase.java new file mode 100644 index 0000000000..dd92d3ebca --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ManagedAuthenticationManagerTestBase.java @@ -0,0 +1,252 @@ +/* + * + * 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 static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import javax.security.auth.login.AccountNotFoundException; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + +import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.User; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SubjectCreator; +import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.test.utils.QpidTestCase; + +abstract class ManagedAuthenticationManagerTestBase extends QpidTestCase +{ + private ConfigModelPasswordManagingAuthenticationProvider<?> _authManager; + + + private Broker _broker; + private SecurityManager _securityManager; + private TaskExecutor _executor; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _executor = new CurrentThreadTaskExecutor(); + _executor.start(); + _broker = BrokerTestHelper.createBrokerMock(); + _securityManager = mock(SecurityManager.class); + when(_broker.getTaskExecutor()).thenReturn(_executor); + when(_broker.getSecurityManager()).thenReturn(_securityManager); + final Map<String, Object> attributesMap = new HashMap<String, Object>(); + attributesMap.put(AuthenticationProvider.NAME, getTestName()); + attributesMap.put(AuthenticationProvider.ID, UUID.randomUUID()); + _authManager = createAuthManager(attributesMap); + _authManager.open(); + } + + + @Override + public void tearDown() throws Exception + { + _executor.stop(); + super.tearDown(); + } + + protected abstract ConfigModelPasswordManagingAuthenticationProvider createAuthManager(final Map<String, Object> attributesMap); + + public Broker getBroker() + { + return _broker; + } + + public ConfigModelPasswordManagingAuthenticationProvider<?> getAuthManager() + { + return _authManager; + } + + + public void testMechanisms() + { + SubjectCreator insecureCreator = _authManager.getSubjectCreator(false); + assertFalse("PLAIN authentication should not be available on an insecure connection", insecureCreator.getMechanisms().contains("PLAIN")); + SubjectCreator secureCreator = _authManager.getSubjectCreator(true); + assertTrue("PLAIN authentication should be available on a secure connection", secureCreator.getMechanisms().contains("PLAIN")); + + try + { + SaslServer saslServer = secureCreator.createSaslServer("PLAIN", "127.0.0.1", null); + assertNotNull(saslServer); + } + catch (SaslException e) + { + fail("Unable to create a SaslServer for PLAIN authentication on a secure connection" + e.getMessage()); + } + + try + { + SaslServer saslServer = insecureCreator.createSaslServer("PLAIN", "127.0.0.1", null); + fail("Erroneously created a SaslServer for PLAIN authentication on an insecure connection"); + } + catch (SaslException e) + { + // Pass + } + + } + + public void testAddChildAndThenDelete() + { + // No children should be present before the test starts + assertEquals("No users should be present before the test starts", 0, _authManager.getChildren(User.class).size()); + assertEquals("No users should be present before the test starts", 0, _authManager.getUsers().size()); + + final Map<String, Object> childAttrs = new HashMap<String, Object>(); + + childAttrs.put(User.NAME, getTestName()); + childAttrs.put(User.PASSWORD, "password"); + User user = _authManager.addChild(User.class, childAttrs); + assertNotNull("User should be created but addChild returned null", user); + assertEquals(getTestName(), user.getName()); + if(!isPlain()) + { + // password shouldn't actually be the given string, but instead hashed value + assertFalse("Password shouldn't actually be the given string, but instead hashed value", + "password".equals(user.getPassword())); + } + + AuthenticationResult authResult = + _authManager.authenticate(getTestName(), "password"); + + assertEquals("User should authenticate with given password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); + + assertEquals("Manager should have exactly one user child",1, _authManager.getChildren(User.class).size()); + assertEquals("Manager should have exactly one user child",1, _authManager.getUsers().size()); + + + user.delete(); + + assertEquals("No users should be present after child deletion", 0, _authManager.getChildren(User.class).size()); + + + authResult = _authManager.authenticate(getTestName(), "password"); + assertEquals("User should no longer authenticate with given password", AuthenticationResult.AuthenticationStatus.ERROR, authResult.getStatus()); + + } + + public void testCreateUser() + { + assertEquals("No users should be present before the test starts", 0, _authManager.getChildren(User.class).size()); + assertTrue(_authManager.createUser(getTestName(), "password", Collections.<String, String>emptyMap())); + assertEquals("Manager should have exactly one user child",1, _authManager.getChildren(User.class).size()); + User user = _authManager.getChildren(User.class).iterator().next(); + assertEquals(getTestName(), user.getName()); + if(!isPlain()) + { + // password shouldn't actually be the given string, but instead salt and the hashed value + assertFalse("Password shouldn't actually be the given string, but instead salt and the hashed value", + "password".equals(user.getPassword())); + } + final Map<String, Object> childAttrs = new HashMap<String, Object>(); + + childAttrs.put(User.NAME, getTestName()); + childAttrs.put(User.PASSWORD, "password"); + try + { + user = _authManager.addChild(User.class, childAttrs); + fail("Should not be able to create a second user with the same name"); + } + catch(IllegalArgumentException e) + { + // pass + } + try + { + _authManager.deleteUser(getTestName()); + } + catch (AccountNotFoundException e) + { + fail("AccountNotFoundException thrown when none was expected: " + e.getMessage()); + } + try + { + _authManager.deleteUser(getTestName()); + fail("AccountNotFoundException not thrown when was expected"); + } + catch (AccountNotFoundException e) + { + // pass + } + } + + protected abstract boolean isPlain(); + + public void testUpdateUser() + { + assertTrue(_authManager.createUser(getTestName(), "password", Collections.<String, String>emptyMap())); + assertTrue(_authManager.createUser(getTestName()+"_2", "password", Collections.<String, String>emptyMap())); + assertEquals("Manager should have exactly two user children",2, _authManager.getChildren(User.class).size()); + + AuthenticationResult authResult = _authManager.authenticate(getTestName(), "password"); + + assertEquals("User should authenticate with given password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); + authResult = _authManager.authenticate(getTestName()+"_2", "password"); + assertEquals("User should authenticate with given password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); + + for(User user : _authManager.getChildren(User.class)) + { + if(user.getName().equals(getTestName())) + { + user.setAttributes(Collections.singletonMap(User.PASSWORD, "newpassword")); + } + } + + authResult = _authManager.authenticate(getTestName(), "newpassword"); + assertEquals("User should authenticate with updated password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); + authResult = _authManager.authenticate(getTestName()+"_2", "password"); + assertEquals("User should authenticate with original password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); + + authResult = _authManager.authenticate(getTestName(), "password"); + assertEquals("User not authenticate with original password", AuthenticationResult.AuthenticationStatus.ERROR, authResult.getStatus()); + + for(User user : _authManager.getChildren(User.class)) + { + if(user.getName().equals(getTestName())) + { + user.setPassword("newerpassword"); + } + } + + authResult = _authManager.authenticate(getTestName(), "newerpassword"); + assertEquals("User should authenticate with updated password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); + + + + } + + +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PlainAuthenticationManagerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PlainAuthenticationManagerTest.java new file mode 100644 index 0000000000..f7f60227db --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PlainAuthenticationManagerTest.java @@ -0,0 +1,51 @@ +/* + * + * 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 java.util.Map; + +public class PlainAuthenticationManagerTest extends ManagedAuthenticationManagerTestBase +{ + @Override + public void setUp() throws Exception + { + super.setUp(); + } + + @Override + protected ConfigModelPasswordManagingAuthenticationProvider<?> createAuthManager(final Map<String, Object> attributesMap) + { + return new PlainAuthenticationProvider(attributesMap, getBroker()); + } + + @Override + protected boolean isPlain() + { + return true; + } + + @Override + public void tearDown() throws Exception + { + super.tearDown(); + } + +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManagerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManagerTest.java index 455b5b5ec2..9a7e59abe0 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManagerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManagerTest.java @@ -20,213 +20,43 @@ */ package org.apache.qpid.server.security.auth.manager; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import java.util.Collections; -import java.util.HashMap; import java.util.Map; -import java.util.UUID; - -import javax.security.auth.login.AccountNotFoundException; -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; - -import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; -import org.apache.qpid.server.configuration.updater.TaskExecutor; -import org.apache.qpid.server.model.AuthenticationProvider; -import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.User; -import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.SubjectCreator; -import org.apache.qpid.server.security.auth.AuthenticationResult; -import org.apache.qpid.server.util.BrokerTestHelper; -import org.apache.qpid.test.utils.QpidTestCase; -public class ScramSHA1AuthenticationManagerTest extends QpidTestCase +public class ScramSHA1AuthenticationManagerTest extends ManagedAuthenticationManagerTestBase { - private ScramSHA1AuthenticationManager _authManager; - private Broker _broker; - private SecurityManager _securityManager; - private TaskExecutor _executor; - @Override public void setUp() throws Exception { super.setUp(); - _executor = new CurrentThreadTaskExecutor(); - _executor.start(); - _broker = BrokerTestHelper.createBrokerMock(); - _securityManager = mock(SecurityManager.class); - when(_broker.getTaskExecutor()).thenReturn(_executor); - when(_broker.getSecurityManager()).thenReturn(_securityManager); - final Map<String, Object> attributesMap = new HashMap<String, Object>(); - attributesMap.put(AuthenticationProvider.NAME, getTestName()); - attributesMap.put(AuthenticationProvider.ID, UUID.randomUUID()); - _authManager = new ScramSHA1AuthenticationManager(attributesMap, _broker); - _authManager.open(); } @Override - public void tearDown() throws Exception - { - _executor.stop(); - super.tearDown(); - } - - public void testMechanisms() + protected ConfigModelPasswordManagingAuthenticationProvider<?> createAuthManager(final Map<String, Object> attributesMap) { - SubjectCreator insecureCreator = _authManager.getSubjectCreator(false); - assertFalse("PLAIN authentication should not be available on an insecure connection", insecureCreator.getMechanisms().contains("PLAIN")); - SubjectCreator secureCreator = _authManager.getSubjectCreator(true); - assertTrue("PLAIN authentication should be available on a secure connection", secureCreator.getMechanisms().contains("PLAIN")); - - try - { - SaslServer saslServer = secureCreator.createSaslServer("PLAIN", "127.0.0.1", null); - assertNotNull(saslServer); - } - catch (SaslException e) - { - fail("Unable to create a SaslServer for PLAIN authentication on a secure connection" + e.getMessage()); - } - - try - { - SaslServer saslServer = insecureCreator.createSaslServer("PLAIN", "127.0.0.1", null); - fail("Erroneously created a SaslServer for PLAIN authentication on an insecure connection"); - } - catch (SaslException e) - { - // Pass - } - + return new ScramSHA1AuthenticationManager(attributesMap, getBroker()); } - public void testAddChildAndThenDelete() + @Override + protected boolean isPlain() { - // No children should be present before the test starts - assertEquals("No users should be present before the test starts", 0, _authManager.getChildren(User.class).size()); - assertEquals("No users should be present before the test starts", 0, _authManager.getUsers().size()); - - final Map<String, Object> childAttrs = new HashMap<String, Object>(); - - childAttrs.put(User.NAME, getTestName()); - childAttrs.put(User.PASSWORD, "password"); - User user = _authManager.addChild(User.class, childAttrs); - assertNotNull("User should be created but addChild returned null", user); - assertEquals(getTestName(), user.getName()); - // password shouldn't actually be the given string, but instead salt and the hashed value - assertFalse("Password shouldn't actually be the given string, but instead salt and the hashed value", "password".equals(user.getPassword())); - - AuthenticationResult authResult = - _authManager.authenticate(getTestName(), "password"); - - assertEquals("User should authenticate with given password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); - - assertEquals("Manager should have exactly one user child",1, _authManager.getChildren(User.class).size()); - assertEquals("Manager should have exactly one user child",1, _authManager.getUsers().size()); - - - user.delete(); - - assertEquals("No users should be present after child deletion", 0, _authManager.getChildren(User.class).size()); - - - authResult = _authManager.authenticate(getTestName(), "password"); - assertEquals("User should no longer authenticate with given password", AuthenticationResult.AuthenticationStatus.ERROR, authResult.getStatus()); - + return false; } - public void testCreateUser() + @Override + public void tearDown() throws Exception { - assertEquals("No users should be present before the test starts", 0, _authManager.getChildren(User.class).size()); - assertTrue(_authManager.createUser(getTestName(), "password", Collections.<String, String>emptyMap())); - assertEquals("Manager should have exactly one user child",1, _authManager.getChildren(User.class).size()); - User user = _authManager.getChildren(User.class).iterator().next(); - assertEquals(getTestName(), user.getName()); - // password shouldn't actually be the given string, but instead salt and the hashed value - assertFalse("Password shouldn't actually be the given string, but instead salt and the hashed value", "password".equals(user.getPassword())); - final Map<String, Object> childAttrs = new HashMap<String, Object>(); - - childAttrs.put(User.NAME, getTestName()); - childAttrs.put(User.PASSWORD, "password"); - try - { - user = _authManager.addChild(User.class, childAttrs); - fail("Should not be able to create a second user with the same name"); - } - catch(IllegalArgumentException e) - { - // pass - } - try - { - _authManager.deleteUser(getTestName()); - } - catch (AccountNotFoundException e) - { - fail("AccountNotFoundException thrown when none was expected: " + e.getMessage()); - } - try - { - _authManager.deleteUser(getTestName()); - fail("AccountNotFoundException not thrown when was expected"); - } - catch (AccountNotFoundException e) - { - // pass - } + super.tearDown(); } - public void testUpdateUser() - { - assertTrue(_authManager.createUser(getTestName(), "password", Collections.<String, String>emptyMap())); - assertTrue(_authManager.createUser(getTestName()+"_2", "password", Collections.<String, String>emptyMap())); - assertEquals("Manager should have exactly two user children",2, _authManager.getChildren(User.class).size()); - - AuthenticationResult authResult = _authManager.authenticate(getTestName(), "password"); - - assertEquals("User should authenticate with given password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); - authResult = _authManager.authenticate(getTestName()+"_2", "password"); - assertEquals("User should authenticate with given password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); - - for(User user : _authManager.getChildren(User.class)) - { - if(user.getName().equals(getTestName())) - { - user.setAttributes(Collections.singletonMap(User.PASSWORD, "newpassword")); - } - } - - authResult = _authManager.authenticate(getTestName(), "newpassword"); - assertEquals("User should authenticate with updated password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); - authResult = _authManager.authenticate(getTestName()+"_2", "password"); - assertEquals("User should authenticate with original password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); - - authResult = _authManager.authenticate(getTestName(), "password"); - assertEquals("User not authenticate with original password", AuthenticationResult.AuthenticationStatus.ERROR, authResult.getStatus()); - - for(User user : _authManager.getChildren(User.class)) - { - if(user.getName().equals(getTestName())) - { - user.setPassword("newerpassword"); - } - } - - authResult = _authManager.authenticate(getTestName(), "newerpassword"); - assertEquals("User should authenticate with updated password", AuthenticationResult.AuthenticationStatus.SUCCESS, authResult.getStatus()); - - - - } public void testNonASCIIUser() { try { - _authManager.createUser(getTestName()+Character.toString((char)0xa3), "password", Collections.<String, String>emptyMap()); + getAuthManager().createUser(getTestName() + Character.toString((char) 0xa3), + "password", + Collections.<String, String>emptyMap()); fail("Expected exception when attempting to create a user with a non ascii name"); } catch(IllegalArgumentException e) diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexInitialiserTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexInitialiserTest.java index 3079222b1c..52bf6a39d7 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexInitialiserTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/CRAMMD5HexInitialiserTest.java @@ -28,6 +28,7 @@ import java.security.NoSuchAlgorithmException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; +import javax.xml.bind.DatatypeConverter; import junit.framework.TestCase; @@ -35,7 +36,6 @@ import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrinci import org.apache.qpid.server.security.auth.database.PrincipalDatabase; import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexInitialiser; import org.apache.qpid.test.utils.TestFileUtils; -import org.apache.qpid.tools.security.Passwd; /** * These tests ensure that the Hex wrapping that the initialiser performs does actually operate when the handle method is called. @@ -73,7 +73,13 @@ public class CRAMMD5HexInitialiserTest extends TestCase public void setUp() throws Exception { super.setUp(); - _file = TestFileUtils.createTempFile(this, "password-file", new Passwd().getOutput(TEST_USER , TEST_PASSWORD)); + + MessageDigest md = MessageDigest.getInstance("MD5"); + + md.update(TEST_PASSWORD.getBytes("utf-8")); + + _file = TestFileUtils.createTempFile(this, "password-file", + TEST_USER + ":" + DatatypeConverter.printBase64Binary(md.digest())); } public void tearDown() throws Exception 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 c220876a23..f4802481cb 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 @@ -34,7 +34,6 @@ import java.util.UUID; import junit.framework.TestCase; import org.apache.qpid.server.BrokerOptions; -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; @@ -261,7 +260,7 @@ public class BrokerRecovererTest extends TestCase resolveObjects(_brokerEntry); Broker<?> broker = _systemConfig.getBroker(); broker.open(); - verify(_brokerShutdownProvider).shutdown(); + verify(_brokerShutdownProvider).shutdown(1); } } @@ -280,7 +279,7 @@ public class BrokerRecovererTest extends TestCase Broker<?> broker = (Broker<?>) recover.resolve(); broker.open(); - verify(_brokerShutdownProvider).shutdown(); + verify(_brokerShutdownProvider).shutdown(1); } public void testIncorrectModelVersion() throws Exception @@ -298,7 +297,7 @@ public class BrokerRecovererTest extends TestCase _systemConfig.getObjectFactory().recover(_brokerEntry, _systemConfig); Broker<?> broker = (Broker<?>) recover.resolve(); broker.open(); - verify(_brokerShutdownProvider).shutdown(); + verify(_brokerShutdownProvider).shutdown(1); reset(_brokerShutdownProvider); } } diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/transport/TCPandSSLTransportTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/transport/TCPandSSLTransportTest.java new file mode 100644 index 0000000000..d8471e5384 --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/transport/TCPandSSLTransportTest.java @@ -0,0 +1,180 @@ +/* + * + * 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.transport; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.ByteArrayInputStream; +import java.net.InetAddress; +import java.security.KeyStore; +import java.util.Arrays; +import java.util.HashSet; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLHandshakeException; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManagerFactory; +import javax.xml.bind.DatatypeConverter; + +import org.apache.qpid.server.model.Protocol; +import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.model.port.AmqpPort; +import org.apache.qpid.test.utils.QpidTestCase; + +public class TCPandSSLTransportTest extends QpidTestCase +{ + + public void testNoSSLv3SupportOnSSLOnlyPort() throws Exception + { + try + { + checkSSLExcluded("SSLv3", Transport.SSL); + fail("Should not be able to connect using SSLv3"); + } + catch(SSLHandshakeException e) + { + // pass + } + } + + + public void testNoSSLv3SupportOnSharedPort() throws Exception + { + try + { + checkSSLExcluded("SSLv3", Transport.TCP, Transport.SSL); + fail("Should not be able to connect using SSLv3"); + } + catch(SSLHandshakeException e) + { + // pass + } + } + + + public void testTLSSupportOnSharedPort() throws Exception + { + try + { + checkSSLExcluded("TLSv1.1", Transport.TCP, Transport.SSL); + } + catch(SSLHandshakeException e) + { + // pass + fail("Should be able to connect using TLSv1.1"); + + } + } + + + + private void checkSSLExcluded(String clientProtocol, final Transport... transports) throws Exception + { + KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(new ByteArrayInputStream(DatatypeConverter.parseBase64Binary(keystoreString)), "password".toCharArray()); + + + final SSLContext sslContext = SSLContext.getInstance("TLS"); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, "password".toCharArray()); + + sslContext.init(kmf.getKeyManagers(), null, null); + + + + final AmqpPort<?> port = mock(AmqpPort.class); + when(port.getPort()).thenReturn(0); + when(port.getSendBufferSize()).thenReturn(64*1024); + when(port.getReceiveBufferSize()).thenReturn(64*1024); + + TCPandSSLTransport transport = new TCPandSSLTransport(new HashSet<>(Arrays.asList(transports)), + sslContext, + port, + new HashSet<>(Arrays.asList(Protocol.AMQP_0_8, + Protocol.AMQP_0_9, + Protocol.AMQP_0_9_1, + Protocol.AMQP_0_10, + Protocol.AMQP_1_0)), + Protocol.AMQP_0_9_1); + + transport.start(); + + SSLContext clientContext = SSLContext.getInstance("TLS"); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); + + clientContext.init(null, tmf.getTrustManagers(), null); + + + SSLSocket sslSocket = + (SSLSocket) clientContext.getSocketFactory().createSocket(InetAddress.getLoopbackAddress(), + transport.getAcceptingPort()); + + sslSocket.setEnabledProtocols(new String[] {clientProtocol}); + + sslSocket.startHandshake(); + transport.close(); + } + + // self signed cert keystore valid until Oct 2024 + private static String keystoreString = "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" + + "9WC+xnZta0IoYC/vO29IVsok"; +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java b/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java index 8573ae3a42..0bee92a2e9 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java @@ -28,6 +28,8 @@ import static org.mockito.Mockito.when; import java.net.SocketAddress; import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -110,17 +112,28 @@ public class BrokerTestHelper } public static VirtualHostImpl<?,?,?> createVirtualHost(Map<String, Object> attributes) - throws Exception { Broker<?> broker = createBrokerMock(); + return createVirtualHost(attributes, broker); + } + + public static VirtualHostImpl<?, ?, ?> createVirtualHost(final Map<String, Object> attributes, + final Broker<?> broker) + { ConfiguredObjectFactory objectFactory = broker.getObjectFactory(); VirtualHostNode virtualHostNode = mock(VirtualHostNode.class); + when(virtualHostNode.getName()).thenReturn((String) attributes.get(VirtualHostNode.NAME)); when(virtualHostNode.getTaskExecutor()).thenReturn(TASK_EXECUTOR); when(virtualHostNode.getParent(eq(Broker.class))).thenReturn(broker); + Collection<VirtualHostNode<?>> nodes = broker.getVirtualHostNodes(); + nodes = new ArrayList<>(nodes != null ? nodes : Collections.<VirtualHostNode<?>>emptyList()); + nodes.add(virtualHostNode); + when(broker.getVirtualHostNodes()).thenReturn(nodes); + DurableConfigurationStore dcs = mock(DurableConfigurationStore.class); when(virtualHostNode.getConfigurationStore()).thenReturn(dcs); when(virtualHostNode.getParent(eq(VirtualHostNode.class))).thenReturn(virtualHostNode); @@ -128,19 +141,26 @@ public class BrokerTestHelper when(virtualHostNode.getObjectFactory()).thenReturn(objectFactory); when(virtualHostNode.getCategoryClass()).thenReturn(VirtualHostNode.class); when(virtualHostNode.getTaskExecutor()).thenReturn(TASK_EXECUTOR); - AbstractVirtualHost host = (AbstractVirtualHost) objectFactory.create(VirtualHost.class, attributes, virtualHostNode ); + AbstractVirtualHost + host = (AbstractVirtualHost) objectFactory.create(VirtualHost.class, attributes, virtualHostNode ); host.start(); - + when(virtualHostNode.getVirtualHost()).thenReturn(host); return host; } + public static VirtualHostImpl<?,?,?> createVirtualHost(String name) throws Exception { + return createVirtualHost(name, createBrokerMock()); + } + + public static VirtualHostImpl<?,?,?> createVirtualHost(String name, Broker<?> broker) throws Exception + { Map<String,Object> attributes = new HashMap<String, Object>(); attributes.put(org.apache.qpid.server.model.VirtualHost.TYPE, TestMemoryVirtualHost.VIRTUAL_HOST_TYPE); attributes.put(org.apache.qpid.server.model.VirtualHost.NAME, name); - return createVirtualHost(attributes); + return createVirtualHost(attributes, broker); } public static AMQSessionModel<?,?> createSession(int channelId, AMQConnectionModel<?,?> connection) diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostalias/VirtualHostAliasTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostalias/VirtualHostAliasTest.java new file mode 100644 index 0000000000..1a7e2cdc0d --- /dev/null +++ b/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostalias/VirtualHostAliasTest.java @@ -0,0 +1,206 @@ +/* + * + * 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.virtualhostalias; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.ConfiguredObjectFactory; +import org.apache.qpid.server.model.PatternMatchingAlias; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostAlias; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.model.port.AmqpPort; +import org.apache.qpid.server.util.BrokerTestHelper; +import org.apache.qpid.server.virtualhost.VirtualHostImpl; +import org.apache.qpid.test.utils.QpidTestCase; + +public class VirtualHostAliasTest extends QpidTestCase +{ + private Broker<?> _broker; + private Map<String, VirtualHost<?,?,?>> _vhosts; + private AmqpPort _port; + + @Override + public void setUp() throws Exception + { + super.setUp(); + _broker = BrokerTestHelper.createBrokerMock(); + + AuthenticationProvider dummyAuthProvider = mock(AuthenticationProvider.class); + when(dummyAuthProvider.getName()).thenReturn("dummy"); + when(dummyAuthProvider.getId()).thenReturn(UUID.randomUUID()); + when(_broker.getChildren(eq(AuthenticationProvider.class))).thenReturn(Collections.singleton(dummyAuthProvider)); + _vhosts = new HashMap<>(); + for(String name : new String[] { "red", "blue", "purple", "black" }) + { + _vhosts.put(name, BrokerTestHelper.createVirtualHost(name, _broker)); + } + ConfiguredObjectFactory objectFactory = _broker.getObjectFactory(); + when(_broker.getDefaultVirtualHost()).thenReturn("black"); + + final Map<String, Object> attributes = new HashMap<>(); + attributes.put(Port.NAME, getTestName()); + attributes.put(Port.PORT, findFreePort()); + attributes.put(Port.AUTHENTICATION_PROVIDER, "dummy"); + attributes.put(Port.TYPE, "AMQP"); + _port = (AmqpPort) objectFactory.create(Port.class, attributes, _broker ); + + } + + public void testDefaultAliases() + { + VirtualHostImpl vhost = _port.getVirtualHost("red"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("red"), vhost); + + vhost = _port.getVirtualHost("blue"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("blue"), vhost); + + vhost = _port.getVirtualHost("orange!"); + + assertNull(vhost); + + // test the default vhost resolution + vhost = _port.getVirtualHost(""); + + assertNotNull(vhost); + assertEquals(_vhosts.get("black"), vhost); + + + // 127.0.0.1 should always resolve and thus return the default vhost + vhost = _port.getVirtualHost("127.0.0.1"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("black"), vhost); + + } + + public void testPatternMatching() + { + final Map<String, Object> attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, "matcher"); + attributes.put(VirtualHostAlias.TYPE, PatternMatchingAlias.TYPE_NAME); + attributes.put(PatternMatchingAlias.PATTERN, "orange|pink.*"); + attributes.put(PatternMatchingAlias.VIRTUAL_HOST_NODE, _vhosts.get("purple").getParent(VirtualHostNode.class)); + _port.createVirtualHostAlias(attributes); + + VirtualHostImpl vhost = _port.getVirtualHost("orange"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + vhost = _port.getVirtualHost("pink"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + + vhost = _port.getVirtualHost("pinker"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + + + vhost = _port.getVirtualHost("o.*"); + + assertNull(vhost); + + } + + public void testPriority() + { + + VirtualHostImpl vhost = _port.getVirtualHost("blue"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("blue"), vhost); + + vhost = _port.getVirtualHost("black"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("black"), vhost); + + + + Map<String, Object> attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, "matcher10"); + attributes.put(VirtualHostAlias.TYPE, PatternMatchingAlias.TYPE_NAME); + attributes.put(VirtualHostAlias.PRIORITY, 10); + attributes.put(PatternMatchingAlias.PATTERN, "bl.*"); + attributes.put(PatternMatchingAlias.VIRTUAL_HOST_NODE, _vhosts.get("purple").getParent(VirtualHostNode.class)); + _port.createVirtualHostAlias(attributes); + + vhost = _port.getVirtualHost("blue"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + vhost = _port.getVirtualHost("black"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + + attributes = new HashMap<>(); + attributes.put(VirtualHostAlias.NAME, "matcher5"); + attributes.put(VirtualHostAlias.TYPE, PatternMatchingAlias.TYPE_NAME); + attributes.put(VirtualHostAlias.PRIORITY, 5); + attributes.put(PatternMatchingAlias.PATTERN, ".*u.*"); + attributes.put(PatternMatchingAlias.VIRTUAL_HOST_NODE, _vhosts.get("red").getParent(VirtualHostNode.class)); + _port.createVirtualHostAlias(attributes); + + + + vhost = _port.getVirtualHost("blue"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("red"), vhost); + + vhost = _port.getVirtualHost("black"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("purple"), vhost); + + + + vhost = _port.getVirtualHost("purple"); + + assertNotNull(vhost); + assertEquals(_vhosts.get("red"), vhost); + + + + } +} |