- Update test cases (use assertEquals(e, a, delta) instead) - Also add `totalPass` method in Node interface Signed-off-by: Eric Zhao <sczyh16@gmail.com>master
@@ -45,7 +45,7 @@ public class FluxSentinelOperatorTestIntegrationTest { | |||
ClusterNode cn = ClusterBuilderSlot.getClusterNode(resourceName); | |||
assertNotNull(cn); | |||
assertEquals(1, cn.passQps()); | |||
assertEquals(1, cn.passQps(), 0.01); | |||
assertEquals(1, cn.totalException()); | |||
} | |||
@@ -68,7 +68,7 @@ public class SentinelWebFluxIntegrationTest { | |||
ClusterNode cn = ClusterBuilderSlot.getClusterNode(url); | |||
assertNotNull(cn); | |||
assertEquals(1, cn.passQps()); | |||
assertEquals(1, cn.passQps(), 0.01); | |||
} | |||
@Test | |||
@@ -94,7 +94,7 @@ public class SentinelWebFluxIntegrationTest { | |||
.expectBody(String.class).isEqualTo("Hello 2"); | |||
ClusterNode cn = ClusterBuilderSlot.getClusterNode(fooPrefix + "*"); | |||
assertEquals(2, cn.passQps()); | |||
assertEquals(2, cn.passQps(), 0.01); | |||
assertNull(ClusterBuilderSlot.getClusterNode(url1)); | |||
assertNull(ClusterBuilderSlot.getClusterNode(url2)); | |||
@@ -83,7 +83,7 @@ public class CommonFilterTest { | |||
ClusterNode cn = ClusterBuilderSlot.getClusterNode(url); | |||
assertNotNull(cn); | |||
assertEquals(1, cn.passQps()); | |||
assertEquals(1, cn.passQps(), 0.01); | |||
testCommonBlockAndRedirectBlockPage(url, cn); | |||
@@ -99,7 +99,7 @@ public class CommonFilterTest { | |||
this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN)) | |||
.andExpect(status().isOk()) | |||
.andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG)); | |||
assertEquals(1, cn.blockQps()); | |||
assertEquals(1, cn.blockQps(), 0.01); | |||
// Test for redirect. | |||
String redirectUrl = "http://some-location.com"; | |||
@@ -132,7 +132,7 @@ public class CommonFilterTest { | |||
.andExpect(status().isOk()) | |||
.andExpect(content().string("Hello 2")); | |||
ClusterNode cn = ClusterBuilderSlot.getClusterNode(fooPrefix + "*"); | |||
assertEquals(2, cn.passQps()); | |||
assertEquals(2, cn.passQps(), 0.01); | |||
assertNull(ClusterBuilderSlot.getClusterNode(url1)); | |||
assertNull(ClusterBuilderSlot.getClusterNode(url2)); | |||
@@ -86,7 +86,7 @@ public class CommonFilterMethodTest { | |||
ClusterNode cnGet = ClusterBuilderSlot.getClusterNode(GET + COLON + url); | |||
assertNotNull(cnGet); | |||
assertEquals(1, cnGet.passQps()); | |||
assertEquals(1, cnGet.passQps(), 0.01); | |||
ClusterNode cnPost = ClusterBuilderSlot.getClusterNode(POST + COLON + url); | |||
@@ -98,10 +98,9 @@ public class CommonFilterMethodTest { | |||
cnPost = ClusterBuilderSlot.getClusterNode(POST + COLON + url); | |||
assertNotNull(cnPost); | |||
assertEquals(1, cnPost.passQps()); | |||
assertEquals(1, cnPost.passQps(), 0.01); | |||
testCommonBlockAndRedirectBlockPage(url, cnGet, cnPost); | |||
} | |||
private void testCommonBlockAndRedirectBlockPage(String url, ClusterNode cnGet, ClusterNode cnPost) throws Exception { | |||
@@ -110,21 +109,20 @@ public class CommonFilterMethodTest { | |||
this.mvc.perform(get(url).accept(MediaType.TEXT_PLAIN)) | |||
.andExpect(status().isOk()) | |||
.andExpect(content().string(FilterUtil.DEFAULT_BLOCK_MSG)); | |||
assertEquals(1, cnGet.blockQps()); | |||
assertEquals(1, cnGet.blockQps(), 0.01); | |||
// Test for post pass | |||
this.mvc.perform(post(url)) | |||
.andExpect(status().isOk()) | |||
.andExpect(content().string(HELLO_POST_STR)); | |||
assertEquals(2, cnPost.passQps()); | |||
assertEquals(2, cnPost.passQps(), 0.01); | |||
FlowRuleManager.loadRules(null); | |||
WebServletConfig.setBlockPage(""); | |||
} | |||
@After | |||
public void cleanUp() { | |||
FlowRuleManager.loadRules(null); | |||
@@ -48,7 +48,7 @@ public class DefaultNode extends StatisticNode { | |||
/** | |||
* The list of all child nodes. | |||
*/ | |||
private volatile Set<Node> childList = new HashSet<Node>(); | |||
private volatile Set<Node> childList = new HashSet<>(); | |||
/** | |||
* Associated cluster node. | |||
@@ -85,7 +85,7 @@ public class DefaultNode extends StatisticNode { | |||
if (!childList.contains(node)) { | |||
synchronized (this) { | |||
if (!childList.contains(node)) { | |||
Set<Node> newSet = new HashSet<Node>(childList.size() + 1); | |||
Set<Node> newSet = new HashSet<>(childList.size() + 1); | |||
newSet.addAll(childList); | |||
newSet.add(node); | |||
childList = newSet; | |||
@@ -99,7 +99,7 @@ public class DefaultNode extends StatisticNode { | |||
* Reset the child node list. | |||
*/ | |||
public void removeChildList() { | |||
this.childList = new HashSet<Node>(); | |||
this.childList = new HashSet<>(); | |||
} | |||
public Set<Node> getChildList() { | |||
@@ -43,9 +43,9 @@ public class EntranceNode extends DefaultNode { | |||
} | |||
@Override | |||
public long avgRt() { | |||
long total = 0; | |||
long totalQps = 0; | |||
public double avgRt() { | |||
double total = 0; | |||
double totalQps = 0; | |||
for (Node node : getChildList()) { | |||
total += node.avgRt() * node.passQps(); | |||
totalQps += node.passQps(); | |||
@@ -54,8 +54,8 @@ public class EntranceNode extends DefaultNode { | |||
} | |||
@Override | |||
public long blockQps() { | |||
long blockQps = 0; | |||
public double blockQps() { | |||
double blockQps = 0; | |||
for (Node node : getChildList()) { | |||
blockQps += node.blockQps(); | |||
} | |||
@@ -81,8 +81,8 @@ public class EntranceNode extends DefaultNode { | |||
} | |||
@Override | |||
public long totalQps() { | |||
long r = 0; | |||
public double totalQps() { | |||
double r = 0; | |||
for (Node node : getChildList()) { | |||
r += node.totalQps(); | |||
} | |||
@@ -90,8 +90,8 @@ public class EntranceNode extends DefaultNode { | |||
} | |||
@Override | |||
public long successQps() { | |||
long r = 0; | |||
public double successQps() { | |||
double r = 0; | |||
for (Node node : getChildList()) { | |||
r += node.successQps(); | |||
} | |||
@@ -99,8 +99,8 @@ public class EntranceNode extends DefaultNode { | |||
} | |||
@Override | |||
public long passQps() { | |||
long r = 0; | |||
public double passQps() { | |||
double r = 0; | |||
for (Node node : getChildList()) { | |||
r += node.passQps(); | |||
} | |||
@@ -116,4 +116,12 @@ public class EntranceNode extends DefaultNode { | |||
return r; | |||
} | |||
@Override | |||
public long totalPass() { | |||
long r = 0; | |||
for (Node node : getChildList()) { | |||
r += node.totalPass(); | |||
} | |||
return r; | |||
} | |||
} |
@@ -19,98 +19,125 @@ import java.util.Map; | |||
import com.alibaba.csp.sentinel.Entry; | |||
import com.alibaba.csp.sentinel.node.metric.MetricNode; | |||
import com.alibaba.csp.sentinel.slots.statistic.metric.DebugSupport; | |||
/** | |||
* This class holds real-time statistics for a resource. | |||
* Holds real-time statistics for resources. | |||
* | |||
* @author qinan.qn | |||
* @author leyou | |||
* @author Eric Zhao | |||
*/ | |||
public interface Node { | |||
public interface Node extends DebugSupport { | |||
/** | |||
* Get incoming request per minute. {@code pass + block} | |||
* Get incoming request per minute ({@code pass + block}). | |||
* | |||
* @return total request count per minute | |||
*/ | |||
long totalRequest(); | |||
/** | |||
* Get pass count per minute. | |||
* | |||
* @return total passed request count per minute | |||
* @since 1.5.0 | |||
*/ | |||
long totalPass(); | |||
/** | |||
* Get {@link Entry#exit()} count per minute. | |||
* | |||
* @return Outgoing request per minute. | |||
* @return total completed request count per minute | |||
*/ | |||
long totalSuccess(); | |||
/** | |||
* Get block request count per minute. | |||
* Get blocked request count per minute (totalBlockRequest). | |||
* | |||
* @return total blocked request count per minute | |||
*/ | |||
long blockRequest(); | |||
/** | |||
* Get exception count per minute. | |||
* | |||
* @return total business exception count per minute | |||
*/ | |||
long totalException(); | |||
/** | |||
* Get pass request per second. | |||
* | |||
* @return QPS of passed requests | |||
*/ | |||
long passQps(); | |||
double passQps(); | |||
/** | |||
* Get block request per second. | |||
* | |||
* @return QPS of blocked requests | |||
*/ | |||
long blockQps(); | |||
double blockQps(); | |||
/** | |||
* Get {@link #passQps()} + {@link #blockQps()} request per second. | |||
* | |||
* @return QPS of passed and blocked requests | |||
*/ | |||
long totalQps(); | |||
double totalQps(); | |||
/** | |||
* Get {@link Entry#exit()} request per second. | |||
* | |||
* @return QPS of completed requests | |||
*/ | |||
long successQps(); | |||
double successQps(); | |||
/** | |||
* Get estimated max success QPS till now. | |||
* | |||
* @return max success QPS | |||
* @return max completed QPS | |||
*/ | |||
long maxSuccessQps(); | |||
double maxSuccessQps(); | |||
/** | |||
* Get exception count per second. | |||
* | |||
* @return QPS of exception occurs | |||
*/ | |||
long exceptionQps(); | |||
double exceptionQps(); | |||
/** | |||
* Get average rt per second. | |||
* | |||
* @return average response time per second | |||
*/ | |||
long avgRt(); | |||
double avgRt(); | |||
/** | |||
* Get minimal response time. | |||
* | |||
* @return recorded minimal response time | |||
*/ | |||
long minRt(); | |||
double minRt(); | |||
/** | |||
* Get current active thread count. | |||
* | |||
* @return current active thread count | |||
*/ | |||
int curThreadNum(); | |||
/** | |||
* Get last second block QPS. | |||
*/ | |||
long previousBlockQps(); | |||
double previousBlockQps(); | |||
/** | |||
* Last window QPS. | |||
*/ | |||
long previousPassQps(); | |||
double previousPassQps(); | |||
/** | |||
* Fetch all valid metric nodes of resources. | |||
@@ -129,18 +156,22 @@ public interface Node { | |||
/** | |||
* Add rt and success count. | |||
* | |||
* @param rt response time | |||
* @param rt response time | |||
* @param success success count to add | |||
*/ | |||
void addRtAndSuccess(long rt, int success); | |||
/** | |||
* Increase the block count. | |||
* | |||
* @param count count to add | |||
*/ | |||
void increaseBlockQps(int count); | |||
/** | |||
* Increase the biz exception count. | |||
* Add the biz exception count. | |||
* | |||
* @param count count to add | |||
*/ | |||
void increaseExceptionQps(int count); | |||
@@ -159,9 +190,4 @@ public interface Node { | |||
* {@link SampleCountProperty#SAMPLE_COUNT} is changed. | |||
*/ | |||
void reset(); | |||
/** | |||
* Debug only. | |||
*/ | |||
void debug(); | |||
} |
@@ -151,28 +151,33 @@ public class StatisticNode implements Node { | |||
return totalRequest; | |||
} | |||
@Override | |||
public long totalPass() { | |||
return rollingCounterInMinute.pass(); | |||
} | |||
@Override | |||
public long blockRequest() { | |||
return rollingCounterInMinute.block(); | |||
} | |||
@Override | |||
public long blockQps() { | |||
return rollingCounterInSecond.block() / (long) rollingCounterInSecond.getWindowIntervalInSec(); | |||
public double blockQps() { | |||
return rollingCounterInSecond.block() / rollingCounterInSecond.getWindowIntervalInSec(); | |||
} | |||
@Override | |||
public long previousBlockQps() { | |||
public double previousBlockQps() { | |||
return this.rollingCounterInMinute.previousWindowBlock(); | |||
} | |||
@Override | |||
public long previousPassQps() { | |||
public double previousPassQps() { | |||
return this.rollingCounterInMinute.previousWindowPass(); | |||
} | |||
@Override | |||
public long totalQps() { | |||
public double totalQps() { | |||
return passQps() + blockQps(); | |||
} | |||
@@ -182,8 +187,8 @@ public class StatisticNode implements Node { | |||
} | |||
@Override | |||
public long exceptionQps() { | |||
return rollingCounterInSecond.exception() / (long) rollingCounterInSecond.getWindowIntervalInSec(); | |||
public double exceptionQps() { | |||
return rollingCounterInSecond.exception() / rollingCounterInSecond.getWindowIntervalInSec(); | |||
} | |||
@Override | |||
@@ -192,32 +197,32 @@ public class StatisticNode implements Node { | |||
} | |||
@Override | |||
public long passQps() { | |||
return rollingCounterInSecond.pass() / (long) rollingCounterInSecond.getWindowIntervalInSec(); | |||
public double passQps() { | |||
return rollingCounterInSecond.pass() / rollingCounterInSecond.getWindowIntervalInSec(); | |||
} | |||
@Override | |||
public long successQps() { | |||
return rollingCounterInSecond.success() / (long) rollingCounterInSecond.getWindowIntervalInSec(); | |||
public double successQps() { | |||
return rollingCounterInSecond.success() / rollingCounterInSecond.getWindowIntervalInSec(); | |||
} | |||
@Override | |||
public long maxSuccessQps() { | |||
public double maxSuccessQps() { | |||
return rollingCounterInSecond.maxSuccess() * rollingCounterInSecond.getSampleCount(); | |||
} | |||
@Override | |||
public long avgRt() { | |||
public double avgRt() { | |||
long successCount = rollingCounterInSecond.success(); | |||
if (successCount == 0) { | |||
return 0; | |||
} | |||
return rollingCounterInSecond.rt() / successCount; | |||
return rollingCounterInSecond.rt() * 1.0 / successCount; | |||
} | |||
@Override | |||
public long minRt() { | |||
public double minRt() { | |||
return rollingCounterInSecond.minRt(); | |||
} | |||
@@ -184,7 +184,7 @@ public class DegradeRule extends AbstractRule { | |||
} else if (grade == RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) { | |||
double exception = clusterNode.exceptionQps(); | |||
double success = clusterNode.successQps(); | |||
long total = clusterNode.totalQps(); | |||
double total = clusterNode.totalQps(); | |||
// if total qps less than RT_MAX_EXCEED_N, pass. | |||
if (total < RT_MAX_EXCEED_N) { | |||
return true; | |||
@@ -112,9 +112,9 @@ public class WarmUpController implements TrafficShapingController { | |||
@Override | |||
public boolean canPass(Node node, int acquireCount, boolean prioritized) { | |||
long passQps = node.passQps(); | |||
long passQps = (long) node.passQps(); | |||
long previousQps = node.previousPassQps(); | |||
long previousQps = (long) node.previousPassQps(); | |||
syncToken(previousQps); | |||
// 开始计算它的斜率 | |||
@@ -22,19 +22,16 @@ import com.alibaba.csp.sentinel.util.TimeUtil; | |||
/** | |||
* @author jialiang.linjl | |||
* @since 1.4.0 | |||
*/ | |||
public class WarmUpRateLimiterController extends WarmUpController { | |||
final int timeOutInMs; | |||
final AtomicLong latestPassedTime = new AtomicLong(-1); | |||
private final int timeoutInMs; | |||
private final AtomicLong latestPassedTime = new AtomicLong(-1); | |||
/** | |||
* @param count | |||
* @param warmUpPeriodSec | |||
*/ | |||
public WarmUpRateLimiterController(double count, int warmUpPeriodSec, int timeOutMs, int coldFactor) { | |||
super(count, warmUpPeriodSec, coldFactor); | |||
this.timeOutInMs = timeOutMs; | |||
this.timeoutInMs = timeOutMs; | |||
} | |||
@Override | |||
@@ -44,7 +41,7 @@ public class WarmUpRateLimiterController extends WarmUpController { | |||
@Override | |||
public boolean canPass(Node node, int acquireCount, boolean prioritized) { | |||
long previousQps = node.previousPassQps(); | |||
long previousQps = (long) node.previousPassQps(); | |||
syncToken(previousQps); | |||
long currentTime = TimeUtil.currentTimeMillis(); | |||
@@ -68,13 +65,13 @@ public class WarmUpRateLimiterController extends WarmUpController { | |||
return true; | |||
} else { | |||
long waitTime = costTime + latestPassedTime.get() - currentTime; | |||
if (waitTime > timeOutInMs) { | |||
if (waitTime > timeoutInMs) { | |||
return false; | |||
} else { | |||
long oldTime = latestPassedTime.addAndGet(costTime); | |||
try { | |||
waitTime = oldTime - TimeUtil.currentTimeMillis(); | |||
if (waitTime > timeOutInMs) { | |||
if (waitTime > timeoutInMs) { | |||
latestPassedTime.addAndGet(-costTime); | |||
return false; | |||
} | |||
@@ -89,4 +86,3 @@ public class WarmUpRateLimiterController extends WarmUpController { | |||
return false; | |||
} | |||
} | |||
@@ -0,0 +1,28 @@ | |||
/* | |||
* Copyright 1999-2019 Alibaba Group Holding Ltd. | |||
* | |||
* 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 com.alibaba.csp.sentinel.slots.statistic.metric; | |||
/** | |||
* @author Eric Zhao | |||
* @since 1.5.0 | |||
*/ | |||
public interface DebugSupport { | |||
/** | |||
* For debug; | |||
*/ | |||
void debug(); | |||
} |
@@ -139,18 +139,18 @@ public class ClusterNodeTest { | |||
// test count<=0, no exceptionQps added | |||
clusterNode.trace(exception, 0); | |||
clusterNode.trace(exception, -1); | |||
assertEquals(0, clusterNode.exceptionQps()); | |||
assertEquals(0, clusterNode.exceptionQps(), 0.01); | |||
assertEquals(0, clusterNode.totalException()); | |||
// test count=1, not BlockException, 1 exceptionQps added | |||
clusterNode.trace(exception, 1); | |||
assertEquals(1, clusterNode.exceptionQps()); | |||
assertEquals(1, clusterNode.exceptionQps(), 0.01); | |||
assertEquals(1, clusterNode.totalException()); | |||
// test count=1, BlockException, no exceptionQps added | |||
FlowException flowException = new FlowException("flow"); | |||
clusterNode.trace(flowException, 1); | |||
assertEquals(1, clusterNode.exceptionQps()); | |||
assertEquals(1, clusterNode.exceptionQps(), 0.01); | |||
assertEquals(1, clusterNode.totalException()); | |||
} | |||
} |
@@ -92,9 +92,9 @@ public class StatisticNodeTest { | |||
tickEs.shutdown(); | |||
// now no biz method execute, so there is no curThreadNum,passQps,successQps | |||
assertEquals(0, node.curThreadNum()); | |||
assertEquals(0, node.passQps()); | |||
assertEquals(0, node.successQps()); | |||
assertEquals(0, node.curThreadNum(), 0.01); | |||
assertEquals(0, node.passQps(), 0.01); | |||
assertEquals(0, node.successQps(), 0.01); | |||
// note: total time cost should be controlled within 1 minute, | |||
// as the node.totalRequest() holding statistics of recent 60 seconds | |||
@@ -105,7 +105,7 @@ public class StatisticNodeTest { | |||
assertEquals(totalRequest, node.totalSuccess()); | |||
// now there are no data in time span, so the minRT should be equals to TIME_DROP_VALVE | |||
assertEquals(node.minRt(), Constants.TIME_DROP_VALVE); | |||
assertEquals(node.minRt(), Constants.TIME_DROP_VALVE, 0.01); | |||
log("===================================================="); | |||
log("testStatisticThreadNumAndQps done, cost " + (TimeUtil.currentTimeMillis() - testStartTime) + "ms"); | |||
@@ -45,7 +45,7 @@ public class DegradeTest { | |||
Context context = mock(Context.class); | |||
DefaultNode node = mock(DefaultNode.class); | |||
when(node.getClusterNode()).thenReturn(cn); | |||
when(cn.avgRt()).thenReturn(2L); | |||
when(cn.avgRt()).thenReturn(2d); | |||
DegradeRule rule = new DegradeRule(); | |||
rule.setCount(1); | |||
@@ -69,9 +69,9 @@ public class DegradeTest { | |||
public void testExceptionRatioModeDegrade() throws Throwable { | |||
String key = "test_degrade_exception_ratio"; | |||
ClusterNode cn = mock(ClusterNode.class); | |||
when(cn.exceptionQps()).thenReturn(2L); | |||
when(cn.exceptionQps()).thenReturn(2d); | |||
// Indicates that there are QPS more than min threshold. | |||
when(cn.totalQps()).thenReturn(12L); | |||
when(cn.totalQps()).thenReturn(12d); | |||
ClusterBuilderSlot.getClusterNodeMap().put(new StringResourceWrapper(key, EntryType.IN), cn); | |||
Context context = mock(Context.class); | |||
@@ -84,7 +84,7 @@ public class DegradeTest { | |||
rule.setTimeWindow(2); | |||
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO); | |||
when(cn.successQps()).thenReturn(8L); | |||
when(cn.successQps()).thenReturn(8d); | |||
// Will fail. | |||
assertFalse(rule.passCheck(context, node, 1)); | |||
@@ -92,7 +92,7 @@ public class DegradeTest { | |||
// Restore from the degrade timeout. | |||
TimeUnit.MILLISECONDS.sleep(2200); | |||
when(cn.successQps()).thenReturn(20L); | |||
when(cn.successQps()).thenReturn(20d); | |||
// Will pass. | |||
assertTrue(rule.passCheck(context, node, 1)); | |||
} | |||
@@ -18,9 +18,12 @@ package com.alibaba.csp.sentinel.slots.block.flow; | |||
import static org.junit.Assert.assertTrue; | |||
import static org.junit.Assert.fail; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import com.alibaba.csp.sentinel.Entry; | |||
@@ -34,6 +37,16 @@ import com.alibaba.csp.sentinel.slots.block.RuleConstant; | |||
*/ | |||
public class FlowPartialIntegrationTest { | |||
@Before | |||
public void setUp() throws Exception { | |||
FlowRuleManager.loadRules(new ArrayList<FlowRule>()); | |||
} | |||
@After | |||
public void tearDown() throws Exception { | |||
FlowRuleManager.loadRules(new ArrayList<FlowRule>()); | |||
} | |||
@Test | |||
public void testQPSGrade() { | |||
FlowRule flowRule = new FlowRule(); | |||
@@ -15,7 +15,7 @@ | |||
*/ | |||
package com.alibaba.csp.sentinel.slots.block.flow; | |||
import static org.junit.Assert.assertTrue; | |||
import static org.junit.Assert.*; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
@@ -52,15 +52,15 @@ public class FlowRuleTest { | |||
when(context.getOrigin()).thenReturn(""); | |||
when(node.getClusterNode()).thenReturn(cn); | |||
when(cn.passQps()).thenReturn(1l); | |||
when(cn.passQps()).thenReturn(1d); | |||
assertTrue(flowRule.passCheck(context, node, 1, new Object[0]) == false); | |||
assertFalse(flowRule.passCheck(context, node, 1)); | |||
flowRule.setGrade(RuleConstant.FLOW_GRADE_THREAD); | |||
defaultController = new DefaultController(1, flowRule.getGrade()); | |||
flowRule.setRater(defaultController); | |||
when(cn.curThreadNum()).thenReturn(1); | |||
assertTrue(flowRule.passCheck(context, node, 1, new Object[0]) == false); | |||
assertTrue(!flowRule.passCheck(context, node, 1)); | |||
} | |||
@Test | |||
@@ -79,17 +79,16 @@ public class FlowRuleTest { | |||
DefaultNode dn = mock(DefaultNode.class); | |||
when(context.getName()).thenReturn("entry1"); | |||
when(dn.passQps()).thenReturn(1l); | |||
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0]) == false); | |||
when(dn.passQps()).thenReturn(1d); | |||
assertFalse(flowRule.passCheck(context, dn, 1)); | |||
when(context.getName()).thenReturn("entry2"); | |||
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0])); | |||
assertTrue(flowRule.passCheck(context, dn, 1)); | |||
// Strategy == relate | |||
flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN); | |||
ClusterNode cn = mock(ClusterNode.class); | |||
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0]) == true); | |||
assertTrue(flowRule.passCheck(context, dn, 1)); | |||
} | |||
@Test | |||
@@ -106,7 +105,7 @@ public class FlowRuleTest { | |||
Context context = mock(Context.class); | |||
DefaultNode dn = mock(DefaultNode.class); | |||
when(context.getOrigin()).thenReturn("origin1"); | |||
when(dn.passQps()).thenReturn(1l); | |||
when(dn.passQps()).thenReturn(1d); | |||
when(context.getOriginNode()).thenReturn(dn); | |||
/* | |||
@@ -115,9 +114,9 @@ public class FlowRuleTest { | |||
*/ | |||
ClusterNode cn = mock(ClusterNode.class); | |||
when(dn.getClusterNode()).thenReturn(cn); | |||
when(cn.passQps()).thenReturn(1l); | |||
when(cn.passQps()).thenReturn(1d); | |||
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0]) == false); | |||
when(cn.passQps()).thenReturn(0l); | |||
when(cn.passQps()).thenReturn(0d); | |||
assertTrue(flowRule.passCheck(context, dn, 1, new Object[0])); | |||
flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN); | |||
@@ -16,7 +16,7 @@ public class DefaultControllerTest { | |||
@Test | |||
public void testCanPassForQps() { | |||
long threshold = 10; | |||
double threshold = 10; | |||
TrafficShapingController controller = new DefaultController(threshold, RuleConstant.FLOW_GRADE_QPS); | |||
Node node = mock(Node.class); | |||
when(node.passQps()).thenReturn(threshold - 1) | |||
@@ -38,26 +38,26 @@ public class WarmUpControllerTest extends AbstractTimeBasedTest { | |||
Node node = mock(Node.class); | |||
when(node.passQps()).thenReturn(8L); | |||
when(node.previousPassQps()).thenReturn(1L); | |||
when(node.passQps()).thenReturn(8d); | |||
when(node.previousPassQps()).thenReturn(1d); | |||
assertFalse(warmupController.canPass(node, 1)); | |||
when(node.passQps()).thenReturn(1L); | |||
when(node.previousPassQps()).thenReturn(1L); | |||
when(node.passQps()).thenReturn(1d); | |||
when(node.previousPassQps()).thenReturn(1d); | |||
assertTrue(warmupController.canPass(node, 1)); | |||
when(node.previousPassQps()).thenReturn(10L); | |||
when(node.previousPassQps()).thenReturn(10d); | |||
for (int i = 0; i < 100; i++) { | |||
sleep(100); | |||
warmupController.canPass(node, 1); | |||
} | |||
when(node.passQps()).thenReturn(8L); | |||
when(node.passQps()).thenReturn(8d); | |||
assertTrue(warmupController.canPass(node, 1)); | |||
when(node.passQps()).thenReturn(10L); | |||
when(node.passQps()).thenReturn(10d); | |||
assertFalse(warmupController.canPass(node, 1)); | |||
} | |||
} |
@@ -22,15 +22,15 @@ public class WarmUpRateLimiterControllerTest { | |||
Node node = mock(Node.class); | |||
when(node.passQps()).thenReturn(100L); | |||
when(node.previousPassQps()).thenReturn(100L); | |||
when(node.passQps()).thenReturn(100d); | |||
when(node.previousPassQps()).thenReturn(100d); | |||
assertTrue(controller.canPass(node, 1)); | |||
long start = System.currentTimeMillis(); | |||
assertTrue(controller.canPass(node, 1)); | |||
long cost = System.currentTimeMillis() - start; | |||
assertTrue(cost >= 100 && cost <= 110); | |||
assertTrue(cost >= 100 && cost <= 120); | |||
} | |||
@Test | |||
@@ -39,8 +39,8 @@ public class WarmUpRateLimiterControllerTest { | |||
Node node = mock(Node.class); | |||
when(node.passQps()).thenReturn(100L); | |||
when(node.previousPassQps()).thenReturn(100L); | |||
when(node.passQps()).thenReturn(100d); | |||
when(node.previousPassQps()).thenReturn(100d); | |||
assertTrue(controller.canPass(node, 1)); | |||
@@ -63,12 +63,12 @@ public class NodeVo { | |||
vo.parentId = parentId; | |||
vo.resource = node.getId().getShowName(); | |||
vo.threadNum = node.curThreadNum(); | |||
vo.passQps = node.passQps(); | |||
vo.blockQps = node.blockQps(); | |||
vo.totalQps = node.totalQps(); | |||
vo.averageRt = node.avgRt(); | |||
vo.successQps = node.successQps(); | |||
vo.exceptionQps = node.exceptionQps(); | |||
vo.passQps = (long) node.passQps(); | |||
vo.blockQps = (long) node.blockQps(); | |||
vo.totalQps = (long) node.totalQps(); | |||
vo.averageRt = (long) node.avgRt(); | |||
vo.successQps = (long) node.successQps(); | |||
vo.exceptionQps = (long) node.exceptionQps(); | |||
vo.oneMinuteException = node.totalException(); | |||
vo.oneMinutePass = node.totalRequest() - node.blockRequest(); | |||
vo.oneMinuteBlock = node.blockRequest(); | |||
@@ -102,12 +102,12 @@ public class NodeVo { | |||
NodeVo vo = new NodeVo(); | |||
vo.resource = name; | |||
vo.threadNum = node.curThreadNum(); | |||
vo.passQps = node.passQps(); | |||
vo.blockQps = node.blockQps(); | |||
vo.totalQps = node.totalQps(); | |||
vo.averageRt = node.avgRt(); | |||
vo.successQps = node.successQps(); | |||
vo.exceptionQps = node.exceptionQps(); | |||
vo.passQps = (long) node.passQps(); | |||
vo.blockQps = (long) node.blockQps(); | |||
vo.totalQps = (long) node.totalQps(); | |||
vo.averageRt = (long) node.avgRt(); | |||
vo.successQps = (long) node.successQps(); | |||
vo.exceptionQps = (long) node.exceptionQps(); | |||
vo.oneMinuteException = node.totalException(); | |||
vo.oneMinutePass = node.totalRequest() - node.blockRequest(); | |||
vo.oneMinuteBlock = node.blockRequest(); | |||