/* * Copyright (c) 2010-2012 Grid Dynamics Consulting Services, Inc, All Rights Reserved * http://www.griddynamics.com * * This library is free software; you can redistribute it and/or modify it under the terms of * the Apache License; either * version 2.0 of the License, or any later version. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.griddynamics.jagger.engine.e1.scenario; import com.google.common.collect.ImmutableMap; import com.griddynamics.jagger.coordinator.NodeId; import com.griddynamics.jagger.util.JavaSystemClock; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.math.BigDecimal; import java.util.Map; import static com.griddynamics.jagger.util.DecimalUtil.areEqual; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class DefaultTpsRouterTest { private static final NodeId FIRST_NODE = NodeId.kernelNode("1"); private static final NodeId SECOND_NODE = NodeId.kernelNode("2"); private DefaultTpsRouter tpsRouter; private MaxTpsCalculator maxTpsCalculator; @BeforeMethod public void setUp() throws Exception { maxTpsCalculator = mock(MaxTpsCalculator.class); } @Test public void shouldRouteForOneNodeWithEmptyStats() throws Exception { tpsRouter = router(); assertThat(tpsRouter.getDesiredTps(), equalTo(BigDecimal.TEN)); Map<NodeId, NodeTpsStatistics> map = ImmutableMap.<NodeId, NodeTpsStatistics>builder().put(FIRST_NODE, emptyStats()).build(); Map<NodeId, BigDecimal> desiredTpsPerNode = tpsRouter.getDesiredTpsPerNode(map); assertThat(desiredTpsPerNode.size(), is(1)); assertThat(desiredTpsPerNode.containsKey(FIRST_NODE), is(true)); // todo create matcher! assertThat(areEqual(desiredTpsPerNode.get(FIRST_NODE), BigDecimal.TEN), is(true)); } private DefaultTpsRouter router() { return new DefaultTpsRouter(new ConstantTps(BigDecimal.TEN), maxTpsCalculator, new JavaSystemClock()); } @Test public void shouldRouteForTwoNodesWithEmptyStats() throws Exception { tpsRouter = router(); assertThat(tpsRouter.getDesiredTps(), equalTo(BigDecimal.TEN)); Map<NodeId, NodeTpsStatistics> statsPerNode = ImmutableMap.<NodeId, NodeTpsStatistics>builder() .put(FIRST_NODE, emptyStats()) .put(SECOND_NODE, emptyStats()) .build(); Map<NodeId, BigDecimal> desiredTpsPerNode = tpsRouter.getDesiredTpsPerNode(statsPerNode); assertThat(desiredTpsPerNode.size(), is(2)); assertThat(desiredTpsPerNode.containsKey(FIRST_NODE), is(true)); assertThat(desiredTpsPerNode.containsKey(SECOND_NODE), is(true)); assertThat(areEqual(desiredTpsPerNode.get(FIRST_NODE), new BigDecimal(5)), is(true)); assertThat(areEqual(desiredTpsPerNode.get(SECOND_NODE), new BigDecimal(5)), is(true)); } @Test public void shouldRouteForTwoFastNodes() throws Exception { tpsRouter = router(); assertThat(tpsRouter.getDesiredTps(), equalTo(BigDecimal.TEN)); NodeTpsStatistics fastStats = mock(NodeTpsStatistics.class); Map<NodeId, NodeTpsStatistics> statsPerNode = ImmutableMap.<NodeId, NodeTpsStatistics>builder() .put(FIRST_NODE, fastStats) .put(SECOND_NODE, fastStats) .build(); when(maxTpsCalculator.getMaxTps(fastStats)).thenReturn(new BigDecimal(11)); Map<NodeId, BigDecimal> desiredTpsPerNode = tpsRouter.getDesiredTpsPerNode(statsPerNode); assertThat(desiredTpsPerNode.size(), is(2)); assertThat(desiredTpsPerNode.containsKey(FIRST_NODE), is(true)); assertThat(desiredTpsPerNode.containsKey(SECOND_NODE), is(true)); assertThat(areEqual(desiredTpsPerNode.get(FIRST_NODE), new BigDecimal(5)), is(true)); assertThat(areEqual(desiredTpsPerNode.get(SECOND_NODE), new BigDecimal(5)), is(true)); } @Test public void shouldRouteForTwoSlowNodes() throws Exception { tpsRouter = router(); assertThat(tpsRouter.getDesiredTps(), equalTo(BigDecimal.TEN)); NodeTpsStatistics slowStats = mock(NodeTpsStatistics.class); Map<NodeId, NodeTpsStatistics> statsPerNode = ImmutableMap.<NodeId, NodeTpsStatistics>builder() .put(FIRST_NODE, slowStats) .put(SECOND_NODE, slowStats) .build(); when(maxTpsCalculator.getMaxTps(slowStats)).thenReturn(new BigDecimal(2)); Map<NodeId, BigDecimal> desiredTpsPerNode = tpsRouter.getDesiredTpsPerNode(statsPerNode); assertThat(desiredTpsPerNode.size(), is(2)); assertThat(desiredTpsPerNode.containsKey(FIRST_NODE), is(true)); assertThat(desiredTpsPerNode.containsKey(SECOND_NODE), is(true)); assertThat(areEqual(desiredTpsPerNode.get(FIRST_NODE), new BigDecimal(2)), is(true)); assertThat(areEqual(desiredTpsPerNode.get(SECOND_NODE), new BigDecimal(2)), is(true)); } @Test public void shouldBalanceWorkWhenOneNodeIsSlow() throws Exception { tpsRouter = router(); assertThat(tpsRouter.getDesiredTps(), equalTo(BigDecimal.TEN)); NodeTpsStatistics slowStats = mock(NodeTpsStatistics.class); NodeTpsStatistics fastStats = mock(NodeTpsStatistics.class); Map<NodeId, NodeTpsStatistics> statsPerNode = ImmutableMap.<NodeId, NodeTpsStatistics>builder() .put(FIRST_NODE, slowStats) .put(SECOND_NODE, fastStats) .build(); when(maxTpsCalculator.getMaxTps(slowStats)).thenReturn(new BigDecimal(2)); when(maxTpsCalculator.getMaxTps(fastStats)).thenReturn(new BigDecimal(10)); Map<NodeId, BigDecimal> desiredTpsPerNode = tpsRouter.getDesiredTpsPerNode(statsPerNode); assertThat(desiredTpsPerNode.size(), is(2)); assertThat(desiredTpsPerNode.containsKey(FIRST_NODE), is(true)); assertThat(desiredTpsPerNode.containsKey(SECOND_NODE), is(true)); assertThat(areEqual(desiredTpsPerNode.get(FIRST_NODE), new BigDecimal(2)), is(true)); assertThat(areEqual(desiredTpsPerNode.get(SECOND_NODE), new BigDecimal(8)), is(true)); } private NodeTpsRecorder emptyStats() { NodeTpsRecorder nodeTpsRecorder = new NodeTpsRecorder(100); nodeTpsRecorder.recordStatus(0, 0, 0, 1L); return nodeTpsRecorder; } }