Refactor Node interface: change return type of `xxxQps` method from long to double (#564)
- Update test cases (use assertEquals(e, a, delta) instead) - Also add `totalPass` method in Node interface Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
63d7c9d207
commit
4b1ccd93e2
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue