Solve the issue that sleeping-based tests are not stable and optimize slow tests (#546)
This commit is contained in:
parent
226589f773
commit
5d3ccb0863
13
pom.xml
13
pom.xml
|
|
@ -47,6 +47,7 @@
|
||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.12</junit.version>
|
||||||
<mockito.version>2.21.0</mockito.version>
|
<mockito.version>2.21.0</mockito.version>
|
||||||
<awaitility.version>3.1.5</awaitility.version>
|
<awaitility.version>3.1.5</awaitility.version>
|
||||||
|
<powermock.version>2.0.0</powermock.version>
|
||||||
|
|
||||||
<!-- Build -->
|
<!-- Build -->
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|
@ -168,6 +169,18 @@
|
||||||
<version>2.0.0.0</version>
|
<version>2.0.0.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.powermock</groupId>
|
||||||
|
<artifactId>powermock-module-junit4</artifactId>
|
||||||
|
<version>${powermock.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.powermock</groupId>
|
||||||
|
<artifactId>powermock-api-mockito2</artifactId>
|
||||||
|
<version>${powermock.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,12 @@
|
||||||
<artifactId>zuul-core</artifactId>
|
<artifactId>zuul-core</artifactId>
|
||||||
<version>${zuul.version}</version>
|
<version>${zuul.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-all</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,14 @@
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
<artifactId>java-hamcrest</artifactId>
|
<artifactId>java-hamcrest</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.powermock</groupId>
|
||||||
|
<artifactId>powermock-module-junit4</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.powermock</groupId>
|
||||||
|
<artifactId>powermock-api-mockito2</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ public class AsyncEntryIntegrationTest {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
TimeUnit.SECONDS.sleep(2);
|
TimeUnit.MILLISECONDS.sleep(500);
|
||||||
anotherSyncInAsync();
|
anotherSyncInAsync();
|
||||||
System.out.println("Async result: 666");
|
System.out.println("Async result: 666");
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
|
@ -178,7 +178,7 @@ public class AsyncEntryIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we keep the original timeout of 15 seconds although the test should
|
// we keep the original timeout of 15 seconds although the test should
|
||||||
// complete in less than 6 seconds
|
// complete in less than 3 seconds
|
||||||
await().timeout(15, TimeUnit.SECONDS)
|
await().timeout(15, TimeUnit.SECONDS)
|
||||||
.until(new Callable<DefaultNode>() {
|
.until(new Callable<DefaultNode>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -249,7 +249,7 @@ public class AsyncEntryIntegrationTest {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
TimeUnit.SECONDS.sleep(3);
|
TimeUnit.MILLISECONDS.sleep(1000);
|
||||||
String resp = arg + ": " + System.currentTimeMillis();
|
String resp = arg + ": " + System.currentTimeMillis();
|
||||||
handler.accept(resp);
|
handler.accept(resp);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import com.alibaba.csp.sentinel.slots.statistic.data.MetricBucket;
|
||||||
import com.alibaba.csp.sentinel.util.TimeUtil;
|
import com.alibaba.csp.sentinel.util.TimeUtil;
|
||||||
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap;
|
import com.alibaba.csp.sentinel.slots.statistic.base.WindowWrap;
|
||||||
import com.alibaba.csp.sentinel.slots.statistic.metric.MetricsLeapArray;
|
import com.alibaba.csp.sentinel.slots.statistic.metric.MetricsLeapArray;
|
||||||
|
import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
@ -35,7 +36,7 @@ import static org.junit.Assert.*;
|
||||||
*
|
*
|
||||||
* @author Eric Zhao
|
* @author Eric Zhao
|
||||||
*/
|
*/
|
||||||
public class MetricsLeapArrayTest {
|
public class MetricsLeapArrayTest extends AbstractTimeBasedTest {
|
||||||
|
|
||||||
private final int windowLengthInMs = 1000;
|
private final int windowLengthInMs = 1000;
|
||||||
private final int intervalInSec = 2;
|
private final int intervalInSec = 2;
|
||||||
|
|
@ -149,6 +150,7 @@ public class MetricsLeapArrayTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetPreviousWindow() {
|
public void testGetPreviousWindow() {
|
||||||
|
setCurrentMillis(System.currentTimeMillis());
|
||||||
MetricsLeapArray leapArray = new MetricsLeapArray(sampleCount, intervalInMs);
|
MetricsLeapArray leapArray = new MetricsLeapArray(sampleCount, intervalInMs);
|
||||||
long time = TimeUtil.currentTimeMillis();
|
long time = TimeUtil.currentTimeMillis();
|
||||||
WindowWrap<MetricBucket> previousWindow = leapArray.currentWindow(time);
|
WindowWrap<MetricBucket> previousWindow = leapArray.currentWindow(time);
|
||||||
|
|
@ -166,7 +168,9 @@ public class MetricsLeapArrayTest {
|
||||||
final int windowLengthInMs = 100;
|
final int windowLengthInMs = 100;
|
||||||
final int intervalInMs = 1000;
|
final int intervalInMs = 1000;
|
||||||
final int sampleCount = intervalInMs / windowLengthInMs;
|
final int sampleCount = intervalInMs / windowLengthInMs;
|
||||||
|
|
||||||
|
setCurrentMillis(System.currentTimeMillis());
|
||||||
|
|
||||||
MetricsLeapArray leapArray = new MetricsLeapArray(sampleCount, intervalInMs);
|
MetricsLeapArray leapArray = new MetricsLeapArray(sampleCount, intervalInMs);
|
||||||
long time = TimeUtil.currentTimeMillis();
|
long time = TimeUtil.currentTimeMillis();
|
||||||
|
|
||||||
|
|
@ -180,7 +184,7 @@ public class MetricsLeapArrayTest {
|
||||||
assertTrue(windowWraps.contains(wrap));
|
assertTrue(windowWraps.contains(wrap));
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread.sleep(windowLengthInMs + intervalInMs);
|
sleep(windowLengthInMs + intervalInMs);
|
||||||
|
|
||||||
// This will replace the deprecated bucket, so all deprecated buckets will be reset.
|
// This will replace the deprecated bucket, so all deprecated buckets will be reset.
|
||||||
leapArray.currentWindow(time + windowLengthInMs + intervalInMs).value().addPass(1);
|
leapArray.currentWindow(time + windowLengthInMs + intervalInMs).value().addPass(1);
|
||||||
|
|
@ -194,7 +198,7 @@ public class MetricsLeapArrayTest {
|
||||||
final int intervalInSec = 1;
|
final int intervalInSec = 1;
|
||||||
final int intervalInMs = intervalInSec * 1000;
|
final int intervalInMs = intervalInSec * 1000;
|
||||||
final int sampleCount = intervalInMs / windowLengthInMs;
|
final int sampleCount = intervalInMs / windowLengthInMs;
|
||||||
|
|
||||||
MetricsLeapArray leapArray = new MetricsLeapArray(sampleCount, intervalInMs);
|
MetricsLeapArray leapArray = new MetricsLeapArray(sampleCount, intervalInMs);
|
||||||
long time = TimeUtil.currentTimeMillis();
|
long time = TimeUtil.currentTimeMillis();
|
||||||
|
|
||||||
|
|
@ -203,7 +207,7 @@ public class MetricsLeapArrayTest {
|
||||||
windowWraps.add(leapArray.currentWindow(time));
|
windowWraps.add(leapArray.currentWindow(time));
|
||||||
windowWraps.add(leapArray.currentWindow(time + windowLengthInMs));
|
windowWraps.add(leapArray.currentWindow(time + windowLengthInMs));
|
||||||
|
|
||||||
Thread.sleep(intervalInMs + windowLengthInMs * 3);
|
sleep(intervalInMs + windowLengthInMs * 3);
|
||||||
|
|
||||||
List<WindowWrap<MetricBucket>> list = leapArray.list();
|
List<WindowWrap<MetricBucket>> list = leapArray.list();
|
||||||
for (WindowWrap<MetricBucket> wrap : list) {
|
for (WindowWrap<MetricBucket> wrap : list) {
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ public class DegradeTest {
|
||||||
DegradeRule rule = new DegradeRule();
|
DegradeRule rule = new DegradeRule();
|
||||||
rule.setCount(1);
|
rule.setCount(1);
|
||||||
rule.setResource(key);
|
rule.setResource(key);
|
||||||
rule.setTimeWindow(5);
|
rule.setTimeWindow(2);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
assertTrue(rule.passCheck(context, node, 1));
|
assertTrue(rule.passCheck(context, node, 1));
|
||||||
|
|
@ -61,7 +61,7 @@ public class DegradeTest {
|
||||||
assertFalse(rule.passCheck(context, node, 1));
|
assertFalse(rule.passCheck(context, node, 1));
|
||||||
|
|
||||||
// Restore.
|
// Restore.
|
||||||
TimeUnit.SECONDS.sleep(6);
|
TimeUnit.MILLISECONDS.sleep(2200);
|
||||||
assertTrue(rule.passCheck(context, node, 1));
|
assertTrue(rule.passCheck(context, node, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,7 +81,7 @@ public class DegradeTest {
|
||||||
DegradeRule rule = new DegradeRule();
|
DegradeRule rule = new DegradeRule();
|
||||||
rule.setCount(0.15);
|
rule.setCount(0.15);
|
||||||
rule.setResource(key);
|
rule.setResource(key);
|
||||||
rule.setTimeWindow(5);
|
rule.setTimeWindow(2);
|
||||||
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
|
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
|
||||||
|
|
||||||
when(cn.successQps()).thenReturn(8L);
|
when(cn.successQps()).thenReturn(8L);
|
||||||
|
|
@ -90,7 +90,7 @@ public class DegradeTest {
|
||||||
assertFalse(rule.passCheck(context, node, 1));
|
assertFalse(rule.passCheck(context, node, 1));
|
||||||
|
|
||||||
// Restore from the degrade timeout.
|
// Restore from the degrade timeout.
|
||||||
TimeUnit.SECONDS.sleep(6);
|
TimeUnit.MILLISECONDS.sleep(2200);
|
||||||
|
|
||||||
when(cn.successQps()).thenReturn(20L);
|
when(cn.successQps()).thenReturn(20L);
|
||||||
// Will pass.
|
// Will pass.
|
||||||
|
|
@ -120,7 +120,7 @@ public class DegradeTest {
|
||||||
assertFalse(rule.passCheck(context, node, 1));
|
assertFalse(rule.passCheck(context, node, 1));
|
||||||
|
|
||||||
// Restore from the degrade timeout.
|
// Restore from the degrade timeout.
|
||||||
TimeUnit.SECONDS.sleep(3);
|
TimeUnit.MILLISECONDS.sleep(2200);
|
||||||
|
|
||||||
when(cn.totalException()).thenReturn(0L);
|
when(cn.totalException()).thenReturn(0L);
|
||||||
// Will pass.
|
// Will pass.
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,18 @@ import static org.mockito.Mockito.when;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.node.Node;
|
import com.alibaba.csp.sentinel.node.Node;
|
||||||
|
import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author jialiang.linjl
|
* @author jialiang.linjl
|
||||||
*/
|
*/
|
||||||
public class WarmUpControllerTest {
|
public class WarmUpControllerTest extends AbstractTimeBasedTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWarmUp() throws InterruptedException {
|
public void testWarmUp() throws InterruptedException {
|
||||||
WarmUpController warmupController = new WarmUpController(10, 10, 3);
|
WarmUpController warmupController = new WarmUpController(10, 10, 3);
|
||||||
|
|
||||||
|
setCurrentMillis(System.currentTimeMillis());
|
||||||
|
|
||||||
Node node = mock(Node.class);
|
Node node = mock(Node.class);
|
||||||
|
|
||||||
|
|
@ -48,7 +51,7 @@ public class WarmUpControllerTest {
|
||||||
when(node.previousPassQps()).thenReturn(10L);
|
when(node.previousPassQps()).thenReturn(10L);
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
Thread.sleep(100);
|
sleep(100);
|
||||||
warmupController.canPass(node, 1);
|
warmupController.canPass(node, 1);
|
||||||
}
|
}
|
||||||
when(node.passQps()).thenReturn(8L);
|
when(node.passQps()).thenReturn(8L);
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,15 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Eric Zhao
|
* @author Eric Zhao
|
||||||
*/
|
*/
|
||||||
public class LeapArrayTest {
|
public class LeapArrayTest extends AbstractTimeBasedTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetValidHead() {
|
public void testGetValidHead() {
|
||||||
int windowLengthInMs = 100;
|
int windowLengthInMs = 100;
|
||||||
|
|
@ -44,6 +46,7 @@ public class LeapArrayTest {
|
||||||
return windowWrap;
|
return windowWrap;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
WindowWrap<AtomicInteger> expected1 = leapArray.currentWindow();
|
WindowWrap<AtomicInteger> expected1 = leapArray.currentWindow();
|
||||||
expected1.value().addAndGet(1);
|
expected1.value().addAndGet(1);
|
||||||
sleep(windowLengthInMs);
|
sleep(windowLengthInMs);
|
||||||
|
|
@ -59,11 +62,4 @@ public class LeapArrayTest {
|
||||||
assertSame(expected2, leapArray.getValidHead());
|
assertSame(expected2, leapArray.getValidHead());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sleep(int t) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(t);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2018 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.test;
|
||||||
|
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.powermock.api.mockito.PowerMockito;
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.util.TimeUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock support for {@link TimeUtil}
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest({ TimeUtil.class })
|
||||||
|
public abstract class AbstractTimeBasedTest {
|
||||||
|
private long currentMillis = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
PowerMockito.mockStatic(TimeUtil.class);
|
||||||
|
PowerMockito.when(TimeUtil.currentTimeMillis()).thenReturn(currentMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void setCurrentMillis(long cur) {
|
||||||
|
currentMillis = cur;
|
||||||
|
PowerMockito.when(TimeUtil.currentTimeMillis()).thenReturn(currentMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void sleep(int t) {
|
||||||
|
currentMillis += t;
|
||||||
|
PowerMockito.when(TimeUtil.currentTimeMillis()).thenReturn(currentMillis);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue