Solve the issue that sleeping-based tests are not stable and optimize slow tests (#546)

This commit is contained in:
Jason Joo 2019-03-06 16:49:59 +08:00 committed by Eric Zhao
parent 226589f773
commit 5d3ccb0863
9 changed files with 104 additions and 24 deletions

13
pom.xml
View File

@ -47,6 +47,7 @@
<junit.version>4.12</junit.version>
<mockito.version>2.21.0</mockito.version>
<awaitility.version>3.1.5</awaitility.version>
<powermock.version>2.0.0</powermock.version>
<!-- Build -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -168,6 +169,18 @@
<version>2.0.0.0</version>
<scope>test</scope>
</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>
</dependencyManagement>

View File

@ -32,6 +32,12 @@
<artifactId>zuul-core</artifactId>
<version>${zuul.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>

View File

@ -39,6 +39,14 @@
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -59,7 +59,7 @@ public class AsyncEntryIntegrationTest {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
TimeUnit.MILLISECONDS.sleep(500);
anotherSyncInAsync();
System.out.println("Async result: 666");
} catch (InterruptedException e) {
@ -178,7 +178,7 @@ public class AsyncEntryIntegrationTest {
}
// 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)
.until(new Callable<DefaultNode>() {
@Override
@ -249,7 +249,7 @@ public class AsyncEntryIntegrationTest {
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(3);
TimeUnit.MILLISECONDS.sleep(1000);
String resp = arg + ": " + System.currentTimeMillis();
handler.accept(resp);

View File

@ -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.slots.statistic.base.WindowWrap;
import com.alibaba.csp.sentinel.slots.statistic.metric.MetricsLeapArray;
import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest;
import org.junit.Test;
@ -35,7 +36,7 @@ import static org.junit.Assert.*;
*
* @author Eric Zhao
*/
public class MetricsLeapArrayTest {
public class MetricsLeapArrayTest extends AbstractTimeBasedTest {
private final int windowLengthInMs = 1000;
private final int intervalInSec = 2;
@ -149,6 +150,7 @@ public class MetricsLeapArrayTest {
@Test
public void testGetPreviousWindow() {
setCurrentMillis(System.currentTimeMillis());
MetricsLeapArray leapArray = new MetricsLeapArray(sampleCount, intervalInMs);
long time = TimeUtil.currentTimeMillis();
WindowWrap<MetricBucket> previousWindow = leapArray.currentWindow(time);
@ -166,7 +168,9 @@ public class MetricsLeapArrayTest {
final int windowLengthInMs = 100;
final int intervalInMs = 1000;
final int sampleCount = intervalInMs / windowLengthInMs;
setCurrentMillis(System.currentTimeMillis());
MetricsLeapArray leapArray = new MetricsLeapArray(sampleCount, intervalInMs);
long time = TimeUtil.currentTimeMillis();
@ -180,7 +184,7 @@ public class MetricsLeapArrayTest {
assertTrue(windowWraps.contains(wrap));
}
Thread.sleep(windowLengthInMs + intervalInMs);
sleep(windowLengthInMs + intervalInMs);
// This will replace the deprecated bucket, so all deprecated buckets will be reset.
leapArray.currentWindow(time + windowLengthInMs + intervalInMs).value().addPass(1);
@ -194,7 +198,7 @@ public class MetricsLeapArrayTest {
final int intervalInSec = 1;
final int intervalInMs = intervalInSec * 1000;
final int sampleCount = intervalInMs / windowLengthInMs;
MetricsLeapArray leapArray = new MetricsLeapArray(sampleCount, intervalInMs);
long time = TimeUtil.currentTimeMillis();
@ -203,7 +207,7 @@ public class MetricsLeapArrayTest {
windowWraps.add(leapArray.currentWindow(time));
windowWraps.add(leapArray.currentWindow(time + windowLengthInMs));
Thread.sleep(intervalInMs + windowLengthInMs * 3);
sleep(intervalInMs + windowLengthInMs * 3);
List<WindowWrap<MetricBucket>> list = leapArray.list();
for (WindowWrap<MetricBucket> wrap : list) {

View File

@ -50,7 +50,7 @@ public class DegradeTest {
DegradeRule rule = new DegradeRule();
rule.setCount(1);
rule.setResource(key);
rule.setTimeWindow(5);
rule.setTimeWindow(2);
for (int i = 0; i < 4; i++) {
assertTrue(rule.passCheck(context, node, 1));
@ -61,7 +61,7 @@ public class DegradeTest {
assertFalse(rule.passCheck(context, node, 1));
// Restore.
TimeUnit.SECONDS.sleep(6);
TimeUnit.MILLISECONDS.sleep(2200);
assertTrue(rule.passCheck(context, node, 1));
}
@ -81,7 +81,7 @@ public class DegradeTest {
DegradeRule rule = new DegradeRule();
rule.setCount(0.15);
rule.setResource(key);
rule.setTimeWindow(5);
rule.setTimeWindow(2);
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
when(cn.successQps()).thenReturn(8L);
@ -90,7 +90,7 @@ public class DegradeTest {
assertFalse(rule.passCheck(context, node, 1));
// Restore from the degrade timeout.
TimeUnit.SECONDS.sleep(6);
TimeUnit.MILLISECONDS.sleep(2200);
when(cn.successQps()).thenReturn(20L);
// Will pass.
@ -120,7 +120,7 @@ public class DegradeTest {
assertFalse(rule.passCheck(context, node, 1));
// Restore from the degrade timeout.
TimeUnit.SECONDS.sleep(3);
TimeUnit.MILLISECONDS.sleep(2200);
when(cn.totalException()).thenReturn(0L);
// Will pass.

View File

@ -23,15 +23,18 @@ import static org.mockito.Mockito.when;
import org.junit.Test;
import com.alibaba.csp.sentinel.node.Node;
import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest;
/**
* @author jialiang.linjl
*/
public class WarmUpControllerTest {
public class WarmUpControllerTest extends AbstractTimeBasedTest {
@Test
public void testWarmUp() throws InterruptedException {
WarmUpController warmupController = new WarmUpController(10, 10, 3);
setCurrentMillis(System.currentTimeMillis());
Node node = mock(Node.class);
@ -48,7 +51,7 @@ public class WarmUpControllerTest {
when(node.previousPassQps()).thenReturn(10L);
for (int i = 0; i < 100; i++) {
Thread.sleep(100);
sleep(100);
warmupController.canPass(node, 1);
}
when(node.passQps()).thenReturn(8L);

View File

@ -19,13 +19,15 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest;
import static org.junit.Assert.*;
/**
* @author Eric Zhao
*/
public class LeapArrayTest {
public class LeapArrayTest extends AbstractTimeBasedTest {
@Test
public void testGetValidHead() {
int windowLengthInMs = 100;
@ -44,6 +46,7 @@ public class LeapArrayTest {
return windowWrap;
}
};
WindowWrap<AtomicInteger> expected1 = leapArray.currentWindow();
expected1.value().addAndGet(1);
sleep(windowLengthInMs);
@ -59,11 +62,4 @@ public class LeapArrayTest {
assertSame(expected2, leapArray.getValidHead());
}
private void sleep(int t) {
try {
Thread.sleep(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -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);
}
}