Skip to content

Commit

Permalink
fix flaky tests and fix passDefaultLocalCheck (#3367)
Browse files Browse the repository at this point in the history
* fix test case SentinelDubboConsumerFilterTest#testDegradeSync

* When test is run slow, count bucket will count on next time span, causing failed test.

* dos2unix ParamFlowDefaultCheckerTest.java

* fix testParamFlowDefaultCheckSingleValueCheckQpsMultipleThreads by rule.setDurationInSec(2)

* set threshold as count in 2 seconds to prevent the failure of the unit test when the unit test runs longer than 1 second.

* fix quarkus test by set /txt sleep 300

* If /txt sleep 500 ms, in testSentinelJaxRsQuarkusAdapter, may cause 2 request intervals of more than 1 s, which cause rate limit policy is not effective.

* fix testDegradeAsync

* When test is run slow, count bucket will count on next time span, causing failed test.

* use testcontainers to fix testConsulDataSourceWhenInit

* Project embedded-consul has been deprecated in favour of org.testcontainers:consul
* use consul testcontainers to fix testConsulDataSourceWhenInit, which means docker is required to run tests.
```
Error:  com.alibaba.csp.sentinel.datasource.consul.ConsulDataSourceTest.testConsulDataSourceWhenInit -- Time elapsed: 34.47 s <<< ERROR!
  com.pszymczyk.consul.EmbeddedConsulException: Could not start Consul process in 30 seconds
  	at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
  	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
  	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
  	at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:72)
 ```

* introduce intermediate node to avoid ABA problem
  • Loading branch information
robberphex authored Apr 17, 2024
1 parent befdc56 commit cd02b1d
Show file tree
Hide file tree
Showing 18 changed files with 650 additions and 547 deletions.
2 changes: 1 addition & 1 deletion sentinel-adapter/sentinel-apache-dubbo-adapter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2024 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.
Expand All @@ -15,6 +15,7 @@
*/
package com.alibaba.csp.sentinel;

import com.alibaba.csp.sentinel.adapter.dubbo.AbstractTimeBasedTest;
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboAdapterGlobalConfig;
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DefaultDubboFallback;
import com.alibaba.csp.sentinel.config.SentinelConfig;
Expand All @@ -37,7 +38,7 @@
* @author cdfive
* @author lianglin
*/
public class BaseTest {
public class BaseTest extends AbstractTimeBasedTest {


/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 1999-2024 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.adapter.dubbo;

import com.alibaba.csp.sentinel.util.TimeUtil;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

public abstract class AbstractTimeBasedTest {

private long currentMillis = 0;

public MockedStatic<TimeUtil> mockTimeUtil() {
MockedStatic<TimeUtil> mocked = Mockito.mockStatic(TimeUtil.class);
mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
return mocked;
}

protected final void useActualTime(MockedStatic<TimeUtil> mocked) {
mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod();
}

protected final void setCurrentMillis(MockedStatic<TimeUtil> mocked, long cur) {
currentMillis = cur;
mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
}

protected final void sleep(MockedStatic<TimeUtil> mocked, long timeInMs) {
currentMillis += timeInMs;
mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
}

protected final void sleepSecond(MockedStatic<TimeUtil> mocked, long timeSec) {
sleep(mocked, timeSec * 1000);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2024 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.
Expand Down Expand Up @@ -36,11 +36,15 @@
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;

import com.alibaba.csp.sentinel.util.TimeUtil;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.support.RpcUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockedStatic;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.*;

Expand All @@ -53,6 +57,7 @@
* @author cdfive
* @author lianglin
*/
@RunWith(MockitoJUnitRunner.class)
public class SentinelDubboConsumerFilterTest extends BaseTest {

private final SentinelDubboConsumerFilter consumerFilter = new SentinelDubboConsumerFilter();
Expand Down Expand Up @@ -94,62 +99,68 @@ public void testInterfaceLevelFollowControlAsync() throws InterruptedException {

@Test
public void testDegradeAsync() throws InterruptedException {
try (MockedStatic<TimeUtil> mocked = super.mockTimeUtil()) {
setCurrentMillis(mocked, 1740000000000L);

Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
Invoker invoker = DubboTestUtil.getDefaultMockInvoker();

when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString());
initDegradeRule(DubboUtils.getInterfaceName(invoker));
Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
Invoker invoker = DubboTestUtil.getDefaultMockInvoker();

Result result = invokeDubboRpc(false, invoker, invocation);
verifyInvocationStructureForCallFinish(invoker, invocation);
assertEquals("normal", result.getValue());
when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString());
initDegradeRule(DubboUtils.getInterfaceName(invoker));

// inc the clusterNode's exception to trigger the fallback
for (int i = 0; i < 5; i++) {
invokeDubboRpc(true, invoker, invocation);
Result result = invokeDubboRpc(false, invoker, invocation);
verifyInvocationStructureForCallFinish(invoker, invocation);
}
assertEquals("normal", result.getValue());

Result result2 = invokeDubboRpc(false, invoker, invocation);
assertEquals("fallback", result2.getValue());
// inc the clusterNode's exception to trigger the fallback
for (int i = 0; i < 5; i++) {
invokeDubboRpc(true, invoker, invocation);
verifyInvocationStructureForCallFinish(invoker, invocation);
}

// sleeping 1000 ms to reset exception
Thread.sleep(1000);
Result result3 = invokeDubboRpc(false, invoker, invocation);
assertEquals("normal", result3.getValue());
Result result2 = invokeDubboRpc(false, invoker, invocation);
assertEquals("fallback", result2.getValue());

Context context = ContextUtil.getContext();
assertNull(context);
// sleeping 1000 ms to reset exception
sleep(mocked, 1000);
Result result3 = invokeDubboRpc(false, invoker, invocation);
assertEquals("normal", result3.getValue());

Context context = ContextUtil.getContext();
assertNull(context);
}
}

@Test
public void testDegradeSync() throws InterruptedException {
public void testDegradeSync() {
try (MockedStatic<TimeUtil> mocked = super.mockTimeUtil()) {
setCurrentMillis(mocked, 1740000000000L);

Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
Invoker invoker = DubboTestUtil.getDefaultMockInvoker();
initDegradeRule(DubboUtils.getInterfaceName(invoker));

Result result = invokeDubboRpc(false, invoker, invocation);
verifyInvocationStructureForCallFinish(invoker, invocation);
assertEquals("normal", result.getValue());
Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
Invoker invoker = DubboTestUtil.getDefaultMockInvoker();
initDegradeRule(DubboUtils.getInterfaceName(invoker));

// inc the clusterNode's exception to trigger the fallback
for (int i = 0; i < 5; i++) {
invokeDubboRpc(true, invoker, invocation);
Result result = invokeDubboRpc(false, invoker, invocation);
verifyInvocationStructureForCallFinish(invoker, invocation);
}
assertEquals("normal", result.getValue());

Result result2 = invokeDubboRpc(false, invoker, invocation);
assertEquals("fallback", result2.getValue());
// inc the clusterNode's exception to trigger the fallback
for (int i = 0; i < 5; i++) {
invokeDubboRpc(true, invoker, invocation);
verifyInvocationStructureForCallFinish(invoker, invocation);
}

// sleeping 1000 ms to reset exception
Thread.sleep(1000);
Result result3 = invokeDubboRpc(false, invoker, invocation);
assertEquals("normal", result3.getValue());
Result result2 = invokeDubboRpc(false, invoker, invocation);
assertEquals("fallback", result2.getValue());

Context context = ContextUtil.getContext();
assertNull(context);
// sleeping 1000 ms to reset exception
sleep(mocked, 1000);
Result result3 = invokeDubboRpc(false, invoker, invocation);
assertEquals("normal", result3.getValue());

Context context = ContextUtil.getContext();
assertNull(context);
}
}

@Test
Expand Down Expand Up @@ -183,7 +194,6 @@ public void testInvokeAsync() {

when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString());
final Result result = mock(Result.class);
when(result.hasException()).thenReturn(false);
when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> {
verifyInvocationStructureForAsyncCall(invoker, invocation);
return result;
Expand All @@ -203,7 +213,6 @@ public void testInvokeSync() {

final Result result = mock(Result.class);
when(result.hasException()).thenReturn(false);
when(result.getException()).thenReturn(new Exception());
when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> {
verifyInvocationStructure(invoker, invocation);
return result;
Expand Down
2 changes: 1 addition & 1 deletion sentinel-adapter/sentinel-apache-dubbo3-adapter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Copyright 1999-2024 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.
Expand All @@ -15,6 +15,7 @@
*/
package com.alibaba.csp.sentinel;

import com.alibaba.csp.sentinel.adapter.dubbo3.AbstractTimeBasedTest;
import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
import com.alibaba.csp.sentinel.adapter.dubbo3.fallback.DefaultDubboFallback;
import com.alibaba.csp.sentinel.config.SentinelConfig;
Expand All @@ -37,7 +38,7 @@
* @author cdfive
* @author lianglin
*/
public class BaseTest {
public class BaseTest extends AbstractTimeBasedTest {


/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 1999-2024 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.adapter.dubbo3;

import com.alibaba.csp.sentinel.util.TimeUtil;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

public abstract class AbstractTimeBasedTest {

private long currentMillis = 0;

public MockedStatic<TimeUtil> mockTimeUtil() {
MockedStatic<TimeUtil> mocked = Mockito.mockStatic(TimeUtil.class);
mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
return mocked;
}

protected final void useActualTime(MockedStatic<TimeUtil> mocked) {
mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod();
}

protected final void setCurrentMillis(MockedStatic<TimeUtil> mocked, long cur) {
currentMillis = cur;
mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
}

protected final void sleep(MockedStatic<TimeUtil> mocked, long timeInMs) {
currentMillis += timeInMs;
mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
}

protected final void sleepSecond(MockedStatic<TimeUtil> mocked, long timeSec) {
sleep(mocked, timeSec * 1000);
}
}
Loading

0 comments on commit cd02b1d

Please sign in to comment.