/* * Copyright 2009 Martin Grotzke * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package de.javakaffee.web.msm; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.testng.Assert; import org.testng.annotations.Test; import de.javakaffee.web.msm.NodeAvailabilityCache.CacheLoader; /** * Tests the {@link NodeIdService}. * * @author <a href="mailto:martin.grotzke@javakaffee.de">Martin Grotzke</a> */ public class NodeIdServiceTest { @Test public void testSetNodeAvailability() { final String nodeId1 = "n1"; final CacheLoader<String> cacheLoader = new CacheLoader<String>() { @Override public boolean isNodeAvailable( final String key ) { return true; } }; final NodeIdService cut = new NodeIdService( new NodeAvailabilityCache<String>( 10, 100, cacheLoader ), NodeIdList.create( nodeId1 ), Collections.<String> emptyList() ); Assert.assertTrue( cut.isNodeAvailable( nodeId1 ) ); cut.setNodeAvailable( nodeId1, false ); Assert.assertFalse( cut.isNodeAvailable( nodeId1 ) ); cut.setNodeAvailable( nodeId1, true ); Assert.assertTrue( cut.isNodeAvailable( nodeId1 ) ); } @Test public final void testGetNextNodeId_SingleNode() { final CacheLoader<String> cacheLoader = new DummyCacheLoader( null ); final NodeIdService cut = new NodeIdService( new NodeAvailabilityCache<String>( 10, 100, cacheLoader ), NodeIdList.create( "n1" ), null ); final String actual = cut.getAvailableNodeId( "n1" ); assertNull( actual, "For a sole existing node we cannot get a next node" ); } /** * Test two memcached nodes: * - node n1 is the currently used node, which failed * - node n2 must be the next node * * Also test that if the current node is n2, then n1 must be chosen. */ @Test public final void testGetNextNodeId_TwoNodes() { final String nodeId1 = "n1"; final String nodeId2 = "n2"; final CacheLoader<String> cacheLoader = new DummyCacheLoader( null ); final NodeIdService cut = new NodeIdService( new NodeAvailabilityCache<String>( 10, 100, cacheLoader ), NodeIdList.create( nodeId1, nodeId2 ), null ); String actual = cut.getAvailableNodeId( nodeId1 ); assertEquals( nodeId2, actual ); /* let's switch nodes, so that the session is bound to node 2 */ actual = cut.getAvailableNodeId( nodeId2 ); assertEquals( nodeId1, actual ); } /** * Test two memcached nodes: * - node n2 is the currently used node, which failed * - node n1 is also unavailable * - the result must be null */ @Test public final void testGetNextNodeId_TwoNodes_NoNodeLeft() { final String nodeId1 = "n1"; final String nodeId2 = "n2"; final CacheLoader<String> cacheLoader = new DummyCacheLoader( Arrays.asList( nodeId1 ) ); final NodeIdService cut = new NodeIdService( new NodeAvailabilityCache<String>( 10, 100, cacheLoader ), NodeIdList.create( nodeId1, nodeId2 ), null ); final String actual = cut.getAvailableNodeId( nodeId2 ); assertNull( actual ); } /** * Test two memcached nodes with no regular nodes left, so that a failover * node is chosen */ @Test public final void testGetNextNodeId_RegularNode_NoRegularNodeLeft() { final String nodeId1 = "n1"; final String nodeId2 = "n2"; final NodeIdService cut = new NodeIdService( createNodeAvailabilityCache(), NodeIdList.create( nodeId1 ), Arrays.asList( nodeId2 ) ); final String actual = cut.getAvailableNodeId( nodeId1 ); assertEquals( nodeId2, actual, "The failover node is not chosen" ); } /** * Test two memcached nodes: * - with the current node beeing a failover node * - regular nodes present * * A regular node shall be chosen */ @Test public final void testGetNextNodeId_FailoverNode_RegularNodeLeft() { final String nodeId1 = "n1"; final String nodeId2 = "n2"; final NodeIdService cut = new NodeIdService( createNodeAvailabilityCache(), NodeIdList.create( nodeId1 ), Arrays.asList( nodeId2 ) ); final String actual = cut.getAvailableNodeId( nodeId2 ); assertEquals( nodeId1, actual, "The regular node is not chosen" ); } /** * Test two memcached nodes: * - with the current node beeing a failover node * - no regular nodes left * * no node can be chosen */ @Test public final void testGetNextNodeId_FailoverNode_NoRegularNodeLeft() { final String nodeId1 = "n1"; final String nodeId2 = "n2"; final NodeIdService cut = new NodeIdService( createNodeAvailabilityCache( nodeId1 ), NodeIdList.create( nodeId1 ), Arrays.asList( nodeId2 ) ); final String actual = cut.getAvailableNodeId( nodeId2 ); assertNull( actual ); } /** * Test three memcached nodes: * - with the current node beeing the first failover node * - no regular nodes left * - another failover node left * * the second failover node must be chosen */ @Test public final void testGetNextNodeId_FailoverNode_NoRegularNodeButAnotherFailoverNodeLeft() { final String nodeId1 = "n1"; final String nodeId2 = "n2"; final String nodeId3 = "n3"; final NodeIdService cut = new NodeIdService( createNodeAvailabilityCache( nodeId1 ), NodeIdList.create( nodeId1 ), Arrays.asList( nodeId2, nodeId3 ) ); final String actual = cut.getAvailableNodeId( nodeId2 ); assertEquals( nodeId3, actual, "The second failover node is not chosen" ); } private NodeAvailabilityCache<String> createNodeAvailabilityCache( final String ... unavailableNodes ) { final List<String> unavailable = unavailableNodes != null ? Arrays.asList( unavailableNodes ) : null; return new NodeAvailabilityCache<String>( 10, 100, new DummyCacheLoader( unavailable ) ); } private static final class DummyCacheLoader implements CacheLoader<String> { private final List<String> _unavailable; private DummyCacheLoader( final List<String> unavailable ) { _unavailable = unavailable; } @Override public boolean isNodeAvailable( final String key ) { return _unavailable == null || !_unavailable.contains( key ); } } }