From 8fef1b5eeed72f9bbab1906bcb6b513a61e06495 Mon Sep 17 00:00:00 2001 From: Robert Lu Date: Tue, 20 Feb 2024 04:58:52 -0600 Subject: [PATCH] Support jdk17 (#3339) Adjust the test logic, use jdk17 to build, 8, 11, 17 to run --- .circleci/config.yml | 12 - .github/workflows/ci.yml | 22 +- .github/workflows/codeql-analysis.yml | 7 +- pom.xml | 74 ++- .../sentinel-jax-rs-adapter/pom.xml | 4 +- sentinel-adapter/sentinel-web-servlet/pom.xml | 5 +- .../sentinel-cluster-server-default/pom.xml | 12 +- .../cluster/AbstractTimeBasedTest.java | 57 ++ .../ConcurrentClusterFlowCheckerTest.java | 90 +-- .../concurrent/TokenCacheNodeManagerTest.java | 46 +- .../limit/GlobalRequestLimiterTest.java | 34 +- .../statistic/limit/RequestLimiterTest.java | 36 +- .../statistic/metric/ClusterMetricTest.java | 42 +- .../metric/ClusterParamMetricTest.java | 46 +- .../cluster/server/AbstractTimeBasedTest.java | 55 ++ .../cluster/test/AbstractTimeBasedTest.java | 55 -- .../sentinel/test/AbstractTimeBasedTest.java | 57 -- sentinel-core/pom.xml | 12 +- .../callback/MetricExitCallbackTest.java | 105 ++-- .../CircuitBreakingIntegrationTest.java | 412 +++++++------- .../ExceptionCircuitBreakerTest.java | 70 +-- .../ResponseTimeCircuitBreakerTest.java | 48 +- .../flow/controller/WarmUpControllerTest.java | 42 +- .../flow/tokenbucket/TokenBucketTest.java | 116 ++-- .../slots/statistic/base/LeapArrayTest.java | 58 +- .../metric/OccupiableBucketLeapArrayTest.java | 170 +++--- .../sentinel/test/AbstractTimeBasedTest.java | 50 +- ...lAnnotationInterceptorIntegrationTest.java | 1 + .../sentinel-datasource-eureka/pom.xml | 11 +- .../pom.xml | 7 +- .../sentinel-parameter-flow-control/pom.xml | 12 +- .../flow/param/AbstractTimeBasedTest.java | 58 ++ .../param/ParamFlowDefaultCheckerTest.java | 517 +++++++++--------- .../sentinel/test/AbstractTimeBasedTest.java | 58 -- 34 files changed, 1248 insertions(+), 1153 deletions(-) create mode 100644 sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/AbstractTimeBasedTest.java create mode 100644 sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/server/AbstractTimeBasedTest.java delete mode 100644 sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/test/AbstractTimeBasedTest.java delete mode 100644 sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java create mode 100644 sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/block/flow/param/AbstractTimeBasedTest.java delete mode 100644 sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java diff --git a/.circleci/config.yml b/.circleci/config.yml index 1f0edcc144..6b3dccf5ee 100755 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,16 +1,5 @@ version: 2 jobs: - integration-test: - docker: - - image: cimg/openjdk:8.0 - working_directory: ~/sentinel - environment: - MAVEN_OPTS: -Xmx3200m - steps: - - checkout - # Run tests - - run: mvn integration-test - document-lint: docker: # this image is build from Dockerfile @@ -49,5 +38,4 @@ workflows: version: 2 ci: jobs: - - integration-test - document-lint diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e6363fec6..71fafc0019 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,9 +3,7 @@ name: Sentinel CI on: push: branches: - - master - - "1.8" - - "2.0" + - '*' pull_request: branches: - master @@ -17,20 +15,26 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [8, 11] + java: [8, 11, 17] steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - - name: Setup Java - uses: actions/setup-java@v3 + - name: Setup Java for test + uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} distribution: 'temurin' - architecture: x64 + cache: 'maven' + + - name: Setup Java for mvn + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: 'temurin' - name: Test with Maven - run: mvn --batch-mode test + run: mvn --batch-mode test -Dsurefire.jdk-toolchain-version=${{ matrix.java }} - name: Build with Maven run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -DminimumPriority=1 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 8cd76731ae..cb5cc7b1f6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL @@ -48,6 +48,11 @@ jobs: # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality + - name: Setup Java + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: 'temurin' # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) diff --git a/pom.xml b/pom.xml index 95bc66e78c..23596e56e4 100755 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ 4.12 - 2.28.2 + 3.12.4 3.12.1 3.1.5 2.0.0 @@ -56,14 +56,14 @@ 1.8 1.8 UTF-8 - 3.8.0 - 2.22.1 + 3.12.0 + 3.2.5 3.0.1 3.0.1 2.8.2 1.6 0.8.3 - 3.1.0 + 3.3.0 3.8 @@ -189,6 +189,12 @@ ${mockito.version} test + + org.mockito + mockito-inline + ${mockito.version} + test + org.assertj assertj-core @@ -207,18 +213,6 @@ 2.0.0.0 test - - org.powermock - powermock-module-junit4 - ${powermock.version} - test - - - org.powermock - powermock-api-mockito2 - ${powermock.version} - test - @@ -271,15 +265,33 @@ org.apache.maven.plugins maven-compiler-plugin ${maven.compiler.version} + + + default-compile + + 17 + + + + base-compile + + compile + + + + module-info.java + + + + - ${java.source.version} - ${java.target.version} - ${java.encoding} + 8 org.apache.maven.plugins maven-surefire-plugin + ${maven.surefire.version} @{argLine} -Xms1024m -Xmx2048m @@ -394,6 +406,30 @@ + + custom-test-runtime-version + + + surefire.jdk-toolchain-version + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven.surefire.version} + + + ${surefire.jdk-toolchain-version} + + + + + + + diff --git a/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml b/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml index e48d676f8b..2f53809961 100755 --- a/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml +++ b/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml @@ -43,7 +43,7 @@ org.springframework.boot spring-boot-starter-test - 2.2.6.RELEASE + 2.4.13 test @@ -66,7 +66,7 @@ org.apache.maven.plugins maven-surefire-plugin - always + false diff --git a/sentinel-adapter/sentinel-web-servlet/pom.xml b/sentinel-adapter/sentinel-web-servlet/pom.xml index 23186bf7b5..c8df08012d 100755 --- a/sentinel-adapter/sentinel-web-servlet/pom.xml +++ b/sentinel-adapter/sentinel-web-servlet/pom.xml @@ -14,6 +14,7 @@ 3.1.0 + 2.4.13 @@ -37,13 +38,13 @@ org.springframework.boot spring-boot-starter-web - 1.5.17.RELEASE + ${spring.boot.version} test org.springframework.boot spring-boot-starter-test - 1.5.17.RELEASE + ${spring.boot.version} test diff --git a/sentinel-cluster/sentinel-cluster-server-default/pom.xml b/sentinel-cluster/sentinel-cluster-server-default/pom.xml index 12450b7640..33928db4d7 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/pom.xml +++ b/sentinel-cluster/sentinel-cluster-server-default/pom.xml @@ -41,16 +41,6 @@ sentinel-datasource-nacos test - - org.powermock - powermock-module-junit4 - test - - - org.powermock - powermock-api-mockito2 - test - junit junit @@ -58,7 +48,7 @@ org.mockito - mockito-core + mockito-inline test diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/AbstractTimeBasedTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/AbstractTimeBasedTest.java new file mode 100644 index 0000000000..2b06e151b4 --- /dev/null +++ b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/AbstractTimeBasedTest.java @@ -0,0 +1,57 @@ +/* + * 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.cluster; + +import com.alibaba.csp.sentinel.util.TimeUtil; +import org.junit.runner.RunWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** + * Mock support for {@link TimeUtil} + * + * @author jason + */ +@RunWith(MockitoJUnitRunner.class) +public abstract class AbstractTimeBasedTest { + + private long currentMillis = 0; + + public MockedStatic mockTimeUtil() { + MockedStatic mocked = Mockito.mockStatic(TimeUtil.class); + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + return mocked; + } + + protected final void useActualTime(MockedStatic mocked) { + mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod(); + } + + protected final void setCurrentMillis(MockedStatic mocked, long cur) { + currentMillis = cur; + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + } + + protected final void sleep(MockedStatic mocked, long t) { + currentMillis += t; + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + } + + protected final void sleepSecond(MockedStatic mocked, long timeSec) { + sleep(mocked, timeSec * 1000); + } +} diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/ConcurrentClusterFlowCheckerTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/ConcurrentClusterFlowCheckerTest.java index 3a7e2e9618..c9761cc12a 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/ConcurrentClusterFlowCheckerTest.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/ConcurrentClusterFlowCheckerTest.java @@ -21,14 +21,16 @@ import com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.CurrentConcurrencyManager; import com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNodeManager; import com.alibaba.csp.sentinel.cluster.server.connection.ConnectionManager; +import com.alibaba.csp.sentinel.cluster.server.AbstractTimeBasedTest; import com.alibaba.csp.sentinel.slots.block.ClusterRuleConstant; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; -import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.MockedStatic; import java.util.ArrayList; import java.util.concurrent.CountDownLatch; @@ -60,56 +62,60 @@ public void setUp() { @Test public void testEasyAcquireAndRelease() throws InterruptedException { - setCurrentMillis(System.currentTimeMillis()); - FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(111L); - ArrayList list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - TokenResult result = ConcurrentClusterFlowChecker.acquireConcurrentToken("127.0.0.1", rule, 1); - Assert.assertTrue("fail to acquire token", - result.getStatus() == TokenResultStatus.OK && result.getTokenId() != 0); - list.add(result.getTokenId()); - } - for (int i = 0; i < 10; i++) { - TokenResult result = ConcurrentClusterFlowChecker.acquireConcurrentToken("127.0.0.1", rule, 1); - Assert.assertTrue("fail to acquire block token", - result.getStatus() == TokenResultStatus.BLOCKED); - } - for (int i = 0; i < 10; i++) { - TokenResult result = ConcurrentClusterFlowChecker.releaseConcurrentToken(list.get(i)); + try (MockedStatic mocked = super.mockTimeUtil()) { + setCurrentMillis(mocked, System.currentTimeMillis()); + FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(111L); + ArrayList list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + TokenResult result = ConcurrentClusterFlowChecker.acquireConcurrentToken("127.0.0.1", rule, 1); + Assert.assertTrue("fail to acquire token", + result.getStatus() == TokenResultStatus.OK && result.getTokenId() != 0); + list.add(result.getTokenId()); + } + for (int i = 0; i < 10; i++) { + TokenResult result = ConcurrentClusterFlowChecker.acquireConcurrentToken("127.0.0.1", rule, 1); + Assert.assertTrue("fail to acquire block token", + result.getStatus() == TokenResultStatus.BLOCKED); + } + for (int i = 0; i < 10; i++) { + TokenResult result = ConcurrentClusterFlowChecker.releaseConcurrentToken(list.get(i)); + Assert.assertTrue("fail to release token", + result.getStatus() == TokenResultStatus.RELEASE_OK); + } Assert.assertTrue("fail to release token", - result.getStatus() == TokenResultStatus.RELEASE_OK); + CurrentConcurrencyManager.get(111L).get() == 0 && TokenCacheNodeManager.getSize() == 0); } - Assert.assertTrue("fail to release token", - CurrentConcurrencyManager.get(111L).get() == 0 && TokenCacheNodeManager.getSize() == 0); } @Test public void testConcurrentAcquireAndRelease() throws InterruptedException { - setCurrentMillis(System.currentTimeMillis()); - final FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(111L); - final CountDownLatch countDownLatch = new CountDownLatch(1000); - ExecutorService pool = Executors.newFixedThreadPool(100); + try (MockedStatic mocked = super.mockTimeUtil()) { + setCurrentMillis(mocked, System.currentTimeMillis()); + final FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(111L); + final CountDownLatch countDownLatch = new CountDownLatch(1000); + ExecutorService pool = Executors.newFixedThreadPool(100); - for (long i = 0; i < 1000; i++) { - Runnable task = new Runnable() { - @Override - public void run() { - assert rule != null; - TokenResult result = ConcurrentClusterFlowChecker.acquireConcurrentToken("127.0.0.1", rule, 1); - Assert.assertTrue("concurrent control fail", CurrentConcurrencyManager.get(111L).get() <= rule.getCount()); - if (result.getStatus() == TokenResultStatus.OK) { - ConcurrentClusterFlowChecker.releaseConcurrentToken(result.getTokenId()); + for (long i = 0; i < 1000; i++) { + Runnable task = new Runnable() { + @Override + public void run() { + assert rule != null; + TokenResult result = ConcurrentClusterFlowChecker.acquireConcurrentToken("127.0.0.1", rule, 1); + Assert.assertTrue("concurrent control fail", CurrentConcurrencyManager.get(111L).get() <= rule.getCount()); + if (result.getStatus() == TokenResultStatus.OK) { + ConcurrentClusterFlowChecker.releaseConcurrentToken(result.getTokenId()); + } + countDownLatch.countDown(); } - countDownLatch.countDown(); - } - }; - pool.execute(task); + }; + pool.execute(task); + } + countDownLatch.await(); + pool.shutdown(); + assert rule != null; + Assert.assertTrue("fail to acquire and release token", + CurrentConcurrencyManager.get(rule.getClusterConfig().getFlowId()).get() == 0 && TokenCacheNodeManager.getSize() == 0); } - countDownLatch.await(); - pool.shutdown(); - assert rule != null; - Assert.assertTrue("fail to acquire and release token", - CurrentConcurrencyManager.get(rule.getClusterConfig().getFlowId()).get() == 0 && TokenCacheNodeManager.getSize() == 0); } @Test diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManagerTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManagerTest.java index 8ca4f97a40..dd317270a0 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManagerTest.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/concurrent/TokenCacheNodeManagerTest.java @@ -16,16 +16,16 @@ package com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent; import com.alibaba.csp.sentinel.cluster.flow.rule.ClusterFlowRuleManager; -import com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNode; -import com.alibaba.csp.sentinel.cluster.flow.statistic.concurrent.TokenCacheNodeManager; +import com.alibaba.csp.sentinel.cluster.server.AbstractTimeBasedTest; import com.alibaba.csp.sentinel.slots.block.ClusterRuleConstant; import com.alibaba.csp.sentinel.slots.block.RuleConstant; import com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; -import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.MockedStatic; import java.util.ArrayList; import java.util.List; @@ -52,28 +52,30 @@ public void setUp() { @Test public void testPutTokenCacheNode() throws InterruptedException { - setCurrentMillis(System.currentTimeMillis()); + try (MockedStatic mocked = super.mockTimeUtil()) { + setCurrentMillis(mocked, System.currentTimeMillis()); - for (long i = 0; i < 100; i++) { - final TokenCacheNode node = new TokenCacheNode(); - node.setTokenId(i); - node.setFlowId(111L); - node.setResourceTimeout(10000L); - node.setClientTimeout(10000L); - node.setClientAddress("localhost"); - if (TokenCacheNodeManager.validToken(node)) { - TokenCacheNodeManager.putTokenCacheNode(node.getTokenId(), node); + for (long i = 0; i < 100; i++) { + final TokenCacheNode node = new TokenCacheNode(); + node.setTokenId(i); + node.setFlowId(111L); + node.setResourceTimeout(10000L); + node.setClientTimeout(10000L); + node.setClientAddress("localhost"); + if (TokenCacheNodeManager.validToken(node)) { + TokenCacheNodeManager.putTokenCacheNode(node.getTokenId(), node); + } + } + Assert.assertEquals(100, TokenCacheNodeManager.getSize()); + for (int i = 0; i < 100; i++) { + TokenCacheNodeManager.getTokenCacheNode((long) (Math.random() * 100)); + } + List keyList = new ArrayList<>(TokenCacheNodeManager.getCacheKeySet()); + for (int i = 0; i < 100; i++) { + Assert.assertEquals(i, (long) keyList.get(i)); + TokenCacheNodeManager.removeTokenCacheNode(i); } - } - Assert.assertEquals(100, TokenCacheNodeManager.getSize()); - for (int i = 0; i < 100; i++) { - TokenCacheNodeManager.getTokenCacheNode((long) (Math.random() * 100)); - } - List keyList = new ArrayList<>(TokenCacheNodeManager.getCacheKeySet()); - for (int i = 0; i < 100; i++) { - Assert.assertEquals(i, (long) keyList.get(i)); - TokenCacheNodeManager.removeTokenCacheNode(i); } } } diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/limit/GlobalRequestLimiterTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/limit/GlobalRequestLimiterTest.java index e618d7dec5..5ab847a86c 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/limit/GlobalRequestLimiterTest.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/limit/GlobalRequestLimiterTest.java @@ -16,10 +16,12 @@ package com.alibaba.csp.sentinel.cluster.flow.statistic.limit; import com.alibaba.csp.sentinel.cluster.server.config.ClusterServerConfigManager; -import com.alibaba.csp.sentinel.cluster.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.cluster.server.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.MockedStatic; public class GlobalRequestLimiterTest extends AbstractTimeBasedTest { @Before @@ -29,21 +31,23 @@ public void preTest() { @Test public void testPass() throws InterruptedException { - setCurrentMillis(System.currentTimeMillis()); - GlobalRequestLimiter.initIfAbsent("user"); - Assert.assertNotNull(GlobalRequestLimiter.getRequestLimiter("user")); - Assert.assertEquals(3, GlobalRequestLimiter.getMaxAllowedQps("user"), 0.01); - Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); - Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); - Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); - Assert.assertFalse(GlobalRequestLimiter.tryPass("user")); - Assert.assertEquals(3, GlobalRequestLimiter.getCurrentQps("user"), 0.01); + try (MockedStatic mocked = super.mockTimeUtil()) { + setCurrentMillis(mocked, System.currentTimeMillis()); + GlobalRequestLimiter.initIfAbsent("user"); + Assert.assertNotNull(GlobalRequestLimiter.getRequestLimiter("user")); + Assert.assertEquals(3, GlobalRequestLimiter.getMaxAllowedQps("user"), 0.01); + Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); + Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); + Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); + Assert.assertFalse(GlobalRequestLimiter.tryPass("user")); + Assert.assertEquals(3, GlobalRequestLimiter.getCurrentQps("user"), 0.01); - // wait a second to refresh the window - sleep(1000); - Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); - Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); - Assert.assertEquals(2, GlobalRequestLimiter.getCurrentQps("user"), 0.01); + // wait a second to refresh the window + sleep(mocked, 1000); + Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); + Assert.assertTrue(GlobalRequestLimiter.tryPass("user")); + Assert.assertEquals(2, GlobalRequestLimiter.getCurrentQps("user"), 0.01); + } } @Test diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/limit/RequestLimiterTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/limit/RequestLimiterTest.java index 0d3f95e6af..9b9d7cca81 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/limit/RequestLimiterTest.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/limit/RequestLimiterTest.java @@ -15,8 +15,10 @@ */ package com.alibaba.csp.sentinel.cluster.flow.statistic.limit; -import com.alibaba.csp.sentinel.cluster.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.cluster.server.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Test; +import org.mockito.MockedStatic; import static org.junit.Assert.*; @@ -24,21 +26,23 @@ public class RequestLimiterTest extends AbstractTimeBasedTest { @Test public void testRequestLimiter() { - setCurrentMillis(System.currentTimeMillis()); - RequestLimiter limiter = new RequestLimiter(10); - limiter.add(3); - limiter.add(3); - limiter.add(3); - assertTrue(limiter.canPass()); - assertEquals(9, limiter.getSum()); - limiter.add(3); - assertFalse(limiter.canPass()); + try (MockedStatic mocked = super.mockTimeUtil()) { + setCurrentMillis(mocked, System.currentTimeMillis()); + RequestLimiter limiter = new RequestLimiter(10); + limiter.add(3); + limiter.add(3); + limiter.add(3); + assertTrue(limiter.canPass()); + assertEquals(9, limiter.getSum()); + limiter.add(3); + assertFalse(limiter.canPass()); - // wait a second to refresh the window - sleep(1000); - limiter.add(3); - assertTrue(limiter.tryPass()); - assertTrue(limiter.canPass()); - assertEquals(4, limiter.getSum()); + // wait a second to refresh the window + sleep(mocked, 1000); + limiter.add(3); + assertTrue(limiter.tryPass()); + assertTrue(limiter.canPass()); + assertEquals(4, limiter.getSum()); + } } } diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterMetricTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterMetricTest.java index e8c286bc7c..b7891767f8 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterMetricTest.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterMetricTest.java @@ -16,31 +16,35 @@ package com.alibaba.csp.sentinel.cluster.flow.statistic.metric; import com.alibaba.csp.sentinel.cluster.flow.statistic.data.ClusterFlowEvent; -import com.alibaba.csp.sentinel.cluster.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.cluster.server.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Assert; import org.junit.Test; +import org.mockito.MockedStatic; public class ClusterMetricTest extends AbstractTimeBasedTest { @Test public void testTryOccupyNext() { - setCurrentMillis(System.currentTimeMillis()); - ClusterMetric metric = new ClusterMetric(5, 25); - metric.add(ClusterFlowEvent.PASS, 1); - metric.add(ClusterFlowEvent.PASS, 2); - metric.add(ClusterFlowEvent.PASS, 1); - metric.add(ClusterFlowEvent.BLOCK, 1); - Assert.assertEquals(4, metric.getSum(ClusterFlowEvent.PASS)); - Assert.assertEquals(1, metric.getSum(ClusterFlowEvent.BLOCK)); - Assert.assertEquals(160, metric.getAvg(ClusterFlowEvent.PASS), 0.01); - Assert.assertEquals(200, metric.tryOccupyNext(ClusterFlowEvent.PASS, 111, 900)); - metric.add(ClusterFlowEvent.PASS, 1); - metric.add(ClusterFlowEvent.PASS, 2); - metric.add(ClusterFlowEvent.PASS, 1); - Assert.assertEquals(200, metric.tryOccupyNext(ClusterFlowEvent.PASS, 222, 900)); - metric.add(ClusterFlowEvent.PASS, 1); - metric.add(ClusterFlowEvent.PASS, 2); - metric.add(ClusterFlowEvent.PASS, 1); - Assert.assertEquals(0, metric.tryOccupyNext(ClusterFlowEvent.PASS, 333, 900)); + try (MockedStatic mocked = super.mockTimeUtil()) { + setCurrentMillis(mocked, System.currentTimeMillis()); + ClusterMetric metric = new ClusterMetric(5, 25); + metric.add(ClusterFlowEvent.PASS, 1); + metric.add(ClusterFlowEvent.PASS, 2); + metric.add(ClusterFlowEvent.PASS, 1); + metric.add(ClusterFlowEvent.BLOCK, 1); + Assert.assertEquals(4, metric.getSum(ClusterFlowEvent.PASS)); + Assert.assertEquals(1, metric.getSum(ClusterFlowEvent.BLOCK)); + Assert.assertEquals(160, metric.getAvg(ClusterFlowEvent.PASS), 0.01); + Assert.assertEquals(200, metric.tryOccupyNext(ClusterFlowEvent.PASS, 111, 900)); + metric.add(ClusterFlowEvent.PASS, 1); + metric.add(ClusterFlowEvent.PASS, 2); + metric.add(ClusterFlowEvent.PASS, 1); + Assert.assertEquals(200, metric.tryOccupyNext(ClusterFlowEvent.PASS, 222, 900)); + metric.add(ClusterFlowEvent.PASS, 1); + metric.add(ClusterFlowEvent.PASS, 2); + metric.add(ClusterFlowEvent.PASS, 1); + Assert.assertEquals(0, metric.tryOccupyNext(ClusterFlowEvent.PASS, 333, 900)); + } } } diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterParamMetricTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterParamMetricTest.java index 82645877ad..f75858d4ac 100644 --- a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterParamMetricTest.java +++ b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/flow/statistic/metric/ClusterParamMetricTest.java @@ -15,9 +15,11 @@ */ package com.alibaba.csp.sentinel.cluster.flow.statistic.metric; -import com.alibaba.csp.sentinel.cluster.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.cluster.server.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Assert; import org.junit.Test; +import org.mockito.MockedStatic; import java.util.HashMap; import java.util.Map; @@ -26,26 +28,28 @@ public class ClusterParamMetricTest extends AbstractTimeBasedTest { @Test public void testClusterParamMetric() { - setCurrentMillis(System.currentTimeMillis()); - Map topMap = new HashMap(); - ClusterParamMetric metric = new ClusterParamMetric(5, 25, 100); - metric.addValue("e1", -1); - metric.addValue("e1", -2); - metric.addValue("e2", 100); - metric.addValue("e2", 23); - metric.addValue("e3", 100); - metric.addValue("e3", 230); - Assert.assertEquals(-3, metric.getSum("e1")); - Assert.assertEquals(-120, metric.getAvg("e1"), 0.01); - topMap.put("e3", (double) 13200); - Assert.assertEquals(topMap, metric.getTopValues(1)); - topMap.put("e2", (double) 4920); - topMap.put("e1", (double) -120); - Assert.assertEquals(topMap, metric.getTopValues(5)); - metric.addValue("e2", 100); - metric.addValue("e2", 23); - Assert.assertEquals(246, metric.getSum("e2")); - Assert.assertEquals(9840, metric.getAvg("e2"), 0.01); + try (MockedStatic mocked = super.mockTimeUtil()) { + setCurrentMillis(mocked, System.currentTimeMillis()); + Map topMap = new HashMap(); + ClusterParamMetric metric = new ClusterParamMetric(5, 25, 100); + metric.addValue("e1", -1); + metric.addValue("e1", -2); + metric.addValue("e2", 100); + metric.addValue("e2", 23); + metric.addValue("e3", 100); + metric.addValue("e3", 230); + Assert.assertEquals(-3, metric.getSum("e1")); + Assert.assertEquals(-120, metric.getAvg("e1"), 0.01); + topMap.put("e3", (double) 13200); + Assert.assertEquals(topMap, metric.getTopValues(1)); + topMap.put("e2", (double) 4920); + topMap.put("e1", (double) -120); + Assert.assertEquals(topMap, metric.getTopValues(5)); + metric.addValue("e2", 100); + metric.addValue("e2", 23); + Assert.assertEquals(246, metric.getSum("e2")); + Assert.assertEquals(9840, metric.getAvg("e2"), 0.01); + } } @Test(expected = IllegalArgumentException.class) diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/server/AbstractTimeBasedTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/server/AbstractTimeBasedTest.java new file mode 100644 index 0000000000..684499db58 --- /dev/null +++ b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/server/AbstractTimeBasedTest.java @@ -0,0 +1,55 @@ +/* + * 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.cluster.server; + +import com.alibaba.csp.sentinel.util.TimeUtil; +import org.junit.runner.RunWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** + * Mock support for {@link TimeUtil}. + */ +@RunWith(MockitoJUnitRunner.class) +public abstract class AbstractTimeBasedTest { + + private long currentMillis = 0; + + public MockedStatic mockTimeUtil() { + MockedStatic mocked = Mockito.mockStatic(TimeUtil.class); + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + return mocked; + } + + protected final void useActualTime(MockedStatic mocked) { + mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod(); + } + + protected final void setCurrentMillis(MockedStatic mocked, long cur) { + currentMillis = cur; + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + } + + protected final void sleep(MockedStatic mocked, long t) { + currentMillis += t; + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + } + + protected final void sleepSecond(MockedStatic mocked, long timeSec) { + sleep(mocked, timeSec * 1000); + } +} diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/test/AbstractTimeBasedTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/test/AbstractTimeBasedTest.java deleted file mode 100644 index d4458a0d21..0000000000 --- a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/cluster/test/AbstractTimeBasedTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.cluster.test; - -import com.alibaba.csp.sentinel.util.TimeUtil; -import org.junit.runner.RunWith; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -/** - * Mock support for {@link TimeUtil}. - */ -@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 useActualTime() { - PowerMockito.when(TimeUtil.currentTimeMillis()).thenCallRealMethod(); - } - - 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); - } - - protected final void sleepSecond(int timeSec) { - sleep(timeSec * 1000); - } -} diff --git a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java b/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java deleted file mode 100644 index 6e8bab4d1e..0000000000 --- a/sentinel-cluster/sentinel-cluster-server-default/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 com.alibaba.csp.sentinel.util.TimeUtil; -import org.junit.runner.RunWith; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -/** - * 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 useActualTime() { - PowerMockito.when(TimeUtil.currentTimeMillis()).thenCallRealMethod(); - } - - 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); - } - - protected final void sleepSecond(int timeSec) { - sleep(timeSec * 1000); - } -} diff --git a/sentinel-core/pom.xml b/sentinel-core/pom.xml index 377e46eafd..c120aef8d4 100755 --- a/sentinel-core/pom.xml +++ b/sentinel-core/pom.xml @@ -30,7 +30,7 @@ org.mockito - mockito-core + mockito-inline test @@ -43,16 +43,6 @@ java-hamcrest test - - org.powermock - powermock-module-junit4 - test - - - org.powermock - powermock-api-mockito2 - test - diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/metric/extension/callback/MetricExitCallbackTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/metric/extension/callback/MetricExitCallbackTest.java index f7da610f78..5cc17a273f 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/metric/extension/callback/MetricExitCallbackTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/metric/extension/callback/MetricExitCallbackTest.java @@ -22,11 +22,14 @@ import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper; import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Assert; import org.junit.Test; +import org.mockito.MockedStatic; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; -import static org.powermock.api.mockito.PowerMockito.mock; -import static org.powermock.api.mockito.PowerMockito.when; /** * @author Carpenter Lee @@ -35,64 +38,68 @@ public class MetricExitCallbackTest extends AbstractTimeBasedTest { @Test public void onExit() { - FakeMetricExtension extension = new FakeMetricExtension(); - MetricExtensionProvider.addMetricExtension(extension); + try (MockedStatic mocked = super.mockTimeUtil()) { + FakeMetricExtension extension = new FakeMetricExtension(); + MetricExtensionProvider.addMetricExtension(extension); - MetricExitCallback exitCallback = new MetricExitCallback(); - StringResourceWrapper resourceWrapper = new StringResourceWrapper("resource", EntryType.OUT); - int count = 2; - Object[] args = {"args1", "args2"}; - long prevRt = 20; - extension.rt = prevRt; - extension.success = 6; - extension.thread = 10; - Context context = mock(Context.class); - Entry entry = mock(Entry.class); + MetricExitCallback exitCallback = new MetricExitCallback(); + StringResourceWrapper resourceWrapper = new StringResourceWrapper("resource", EntryType.OUT); + int count = 2; + Object[] args = {"args1", "args2"}; + long prevRt = 20; + extension.rt = prevRt; + extension.success = 6; + extension.thread = 10; + Context context = mock(Context.class); + Entry entry = mock(Entry.class); - // Mock current time - long curMillis = System.currentTimeMillis(); - setCurrentMillis(curMillis); + // Mock current time + long curMillis = System.currentTimeMillis(); + setCurrentMillis(mocked, curMillis); - int deltaMs = 100; - when(entry.getError()).thenReturn(null); - when(entry.getCreateTimestamp()).thenReturn(curMillis - deltaMs); - when(context.getCurEntry()).thenReturn(entry); - exitCallback.onExit(context, resourceWrapper, count, args); - Assert.assertEquals(prevRt + deltaMs, extension.rt); - Assert.assertEquals(extension.success, 6 + count); - Assert.assertEquals(extension.thread, 10 - 1); + int deltaMs = 100; + when(entry.getError()).thenReturn(null); + when(entry.getCreateTimestamp()).thenReturn(curMillis - deltaMs); + when(context.getCurEntry()).thenReturn(entry); + exitCallback.onExit(context, resourceWrapper, count, args); + Assert.assertEquals(prevRt + deltaMs, extension.rt); + Assert.assertEquals(extension.success, 6 + count); + Assert.assertEquals(extension.thread, 10 - 1); + } } - + /** * @author bill_yip */ @Test public void advancedExtensionOnExit() { - FakeAdvancedMetricExtension extension = new FakeAdvancedMetricExtension(); - MetricExtensionProvider.addMetricExtension(extension); + try (MockedStatic mocked = super.mockTimeUtil()) { + FakeAdvancedMetricExtension extension = new FakeAdvancedMetricExtension(); + MetricExtensionProvider.addMetricExtension(extension); - MetricExitCallback exitCallback = new MetricExitCallback(); - StringResourceWrapper resourceWrapper = new StringResourceWrapper("resource", EntryType.OUT); - int count = 2; - Object[] args = {"args1", "args2"}; - long prevRt = 20; - extension.rt = prevRt; - extension.complete = 6; - extension.concurrency = 10; - Context context = mock(Context.class); - Entry entry = mock(Entry.class); + MetricExitCallback exitCallback = new MetricExitCallback(); + StringResourceWrapper resourceWrapper = new StringResourceWrapper("resource", EntryType.OUT); + int count = 2; + Object[] args = {"args1", "args2"}; + long prevRt = 20; + extension.rt = prevRt; + extension.complete = 6; + extension.concurrency = 10; + Context context = mock(Context.class); + Entry entry = mock(Entry.class); - // Mock current time - long curMillis = System.currentTimeMillis(); - setCurrentMillis(curMillis); + // Mock current time + long curMillis = System.currentTimeMillis(); + setCurrentMillis(mocked, curMillis); - int deltaMs = 100; - when(entry.getError()).thenReturn(null); - when(entry.getCreateTimestamp()).thenReturn(curMillis - deltaMs); - when(context.getCurEntry()).thenReturn(entry); - exitCallback.onExit(context, resourceWrapper, count, args); - Assert.assertEquals(prevRt + deltaMs, extension.rt); - Assert.assertEquals(extension.complete, 6 + count); - Assert.assertEquals(extension.concurrency, 10 - 1); + int deltaMs = 100; + when(entry.getError()).thenReturn(null); + when(entry.getCreateTimestamp()).thenReturn(curMillis - deltaMs); + when(context.getCurEntry()).thenReturn(entry); + exitCallback.onExit(context, resourceWrapper, count, args); + Assert.assertEquals(prevRt + deltaMs, extension.rt); + Assert.assertEquals(extension.complete, 6 + count); + Assert.assertEquals(extension.concurrency, 10 - 1); + } } } diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/CircuitBreakingIntegrationTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/CircuitBreakingIntegrationTest.java index ebf49077fc..ffaf6fa985 100755 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/CircuitBreakingIntegrationTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/CircuitBreakingIntegrationTest.java @@ -22,9 +22,11 @@ import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.EventObserverRegistry; import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.MockedStatic; import java.util.ArrayList; import java.util.Arrays; @@ -55,187 +57,193 @@ public void tearDown() { @Test public void testSlowRequestMode() { - CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class); - setCurrentMillis(System.currentTimeMillis() / 1000 * 1000); - int retryTimeoutSec = 5; - int maxRt = 50; - int statIntervalMs = 20000; - int minRequestAmount = 10; - String res = "CircuitBreakingIntegrationTest_testSlowRequestMode"; - EventObserverRegistry.getInstance().addStateChangeObserver(res, observer); - DegradeRuleManager.loadRules(Arrays.asList( - new DegradeRule(res).setTimeWindow(retryTimeoutSec).setCount(maxRt) - .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) - .setSlowRatioThreshold(0.8d).setGrade(0) - )); - - // Try first N requests where N = minRequestAmount. - for (int i = 0; i < minRequestAmount; i++) { - if (i < 7) { - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - } else { - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(-20, -10))); + try (MockedStatic mocked = super.mockTimeUtil()) { + CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class); + setCurrentMillis(mocked, System.currentTimeMillis() / 1000 * 1000); + int retryTimeoutSec = 5; + int maxRt = 50; + int statIntervalMs = 20000; + int minRequestAmount = 10; + String res = "CircuitBreakingIntegrationTest_testSlowRequestMode"; + EventObserverRegistry.getInstance().addStateChangeObserver(res, observer); + DegradeRuleManager.loadRules(Arrays.asList( + new DegradeRule(res).setTimeWindow(retryTimeoutSec).setCount(maxRt) + .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) + .setSlowRatioThreshold(0.8d).setGrade(0) + )); + + // Try first N requests where N = minRequestAmount. + for (int i = 0; i < minRequestAmount; i++) { + if (i < 7) { + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + } else { + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(-20, -10))); + } } - } - // Till now slow ratio should be 70%. - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - // Circuit breaker has transformed to OPEN since here. - verify(observer) - .onStateChange(eq(State.CLOSED), eq(State.OPEN), any(DegradeRule.class), anyDouble()); - assertEquals(State.OPEN, DegradeRuleManager.getCircuitBreakers(res).get(0).currentState()); - assertFalse(entryAndSleepFor(res, 1)); - - sleepSecond(1); - assertFalse(entryAndSleepFor(res, 1)); - sleepSecond(retryTimeoutSec); - // Test HALF-OPEN to OPEN. - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - - verify(observer) - .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); - verify(observer) - .onStateChange(eq(State.HALF_OPEN), eq(State.OPEN), any(DegradeRule.class), anyDouble()); - // Wait for next retry timeout; - reset(observer); - sleepSecond(retryTimeoutSec + 1); - assertTrue(entryAndSleepFor(res, maxRt - ThreadLocalRandom.current().nextInt(10, 20))); - verify(observer) - .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); - verify(observer) - .onStateChange(eq(State.HALF_OPEN), eq(State.CLOSED), any(DegradeRule.class), nullable(Double.class)); - // Now circuit breaker has been closed. - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - - EventObserverRegistry.getInstance().removeStateChangeObserver(res); + // Till now slow ratio should be 70%. + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + // Circuit breaker has transformed to OPEN since here. + verify(observer) + .onStateChange(eq(State.CLOSED), eq(State.OPEN), any(DegradeRule.class), anyDouble()); + assertEquals(State.OPEN, DegradeRuleManager.getCircuitBreakers(res).get(0).currentState()); + assertFalse(entryAndSleepFor(mocked, res, 1)); + + sleepSecond(mocked, 1); + assertFalse(entryAndSleepFor(mocked, res, 1)); + sleepSecond(mocked, retryTimeoutSec); + // Test HALF-OPEN to OPEN. + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + + verify(observer) + .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); + verify(observer) + .onStateChange(eq(State.HALF_OPEN), eq(State.OPEN), any(DegradeRule.class), anyDouble()); + // Wait for next retry timeout; + reset(observer); + sleepSecond(mocked, retryTimeoutSec + 1); + assertTrue(entryAndSleepFor(mocked, res, maxRt - ThreadLocalRandom.current().nextInt(10, 20))); + verify(observer) + .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); + verify(observer) + .onStateChange(eq(State.HALF_OPEN), eq(State.CLOSED), any(DegradeRule.class), nullable(Double.class)); + // Now circuit breaker has been closed. + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + + EventObserverRegistry.getInstance().removeStateChangeObserver(res); + } } @Test public void testSlowRequestModeUseDefaultRule() { - CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class); - setCurrentMillis(System.currentTimeMillis() / 1000 * 1000); - int retryTimeoutSec = 5; - int maxRt = 50; - int statIntervalMs = 20000; - int minRequestAmount = 10; - String res = "CircuitBreakingIntegrationTest_testSlowRequestModeUseDefaultRule"; - EventObserverRegistry.getInstance().addStateChangeObserver(res, observer); - - DefaultCircuitBreakerRuleManager.loadRules(Arrays.asList( - new DegradeRule(DefaultCircuitBreakerRuleManager.DEFAULT_KEY).setTimeWindow(retryTimeoutSec).setCount(maxRt) - .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) - .setSlowRatioThreshold(0.8d).setGrade(0))); - - // Try first N requests where N = minRequestAmount. - for (int i = 0; i < minRequestAmount; i++) { - if (i < 7) { - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - } else { - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(-20, -10))); + try (MockedStatic mocked = super.mockTimeUtil()) { + CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class); + setCurrentMillis(mocked, System.currentTimeMillis() / 1000 * 1000); + int retryTimeoutSec = 5; + int maxRt = 50; + int statIntervalMs = 20000; + int minRequestAmount = 10; + String res = "CircuitBreakingIntegrationTest_testSlowRequestModeUseDefaultRule"; + EventObserverRegistry.getInstance().addStateChangeObserver(res, observer); + + DefaultCircuitBreakerRuleManager.loadRules(Arrays.asList( + new DegradeRule(DefaultCircuitBreakerRuleManager.DEFAULT_KEY).setTimeWindow(retryTimeoutSec).setCount(maxRt) + .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) + .setSlowRatioThreshold(0.8d).setGrade(0))); + + // Try first N requests where N = minRequestAmount. + for (int i = 0; i < minRequestAmount; i++) { + if (i < 7) { + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + } else { + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(-20, -10))); + } } - } - // Till now slow ratio should be 70%. - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - // Circuit breaker has transformed to OPEN since here. - verify(observer) - .onStateChange(eq(State.CLOSED), eq(State.OPEN), any(DegradeRule.class), anyDouble()); - assertEquals(State.OPEN, DefaultCircuitBreakerRuleManager.getDefaultCircuitBreakers(res).get(0).currentState()); - assertFalse(entryAndSleepFor(res, 1)); - - sleepSecond(1); - assertFalse(entryAndSleepFor(res, 1)); - sleepSecond(retryTimeoutSec); - // Test HALF-OPEN to OPEN. - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - - verify(observer) - .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); - verify(observer) - .onStateChange(eq(State.HALF_OPEN), eq(State.OPEN), any(DegradeRule.class), anyDouble()); - // Wait for next retry timeout; - reset(observer); - sleepSecond(retryTimeoutSec + 1); - assertTrue(entryAndSleepFor(res, maxRt - ThreadLocalRandom.current().nextInt(10, 20))); - verify(observer) - .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); - verify(observer) - .onStateChange(eq(State.HALF_OPEN), eq(State.CLOSED), any(DegradeRule.class), nullable(Double.class)); - // Now circuit breaker has been closed. - assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); - - EventObserverRegistry.getInstance().removeStateChangeObserver(res); + // Till now slow ratio should be 70%. + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + // Circuit breaker has transformed to OPEN since here. + verify(observer) + .onStateChange(eq(State.CLOSED), eq(State.OPEN), any(DegradeRule.class), anyDouble()); + assertEquals(State.OPEN, DefaultCircuitBreakerRuleManager.getDefaultCircuitBreakers(res).get(0).currentState()); + assertFalse(entryAndSleepFor(mocked, res, 1)); + + sleepSecond(mocked, 1); + assertFalse(entryAndSleepFor(mocked, res, 1)); + sleepSecond(mocked, retryTimeoutSec); + // Test HALF-OPEN to OPEN. + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + + verify(observer) + .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); + verify(observer) + .onStateChange(eq(State.HALF_OPEN), eq(State.OPEN), any(DegradeRule.class), anyDouble()); + // Wait for next retry timeout; + reset(observer); + sleepSecond(mocked, retryTimeoutSec + 1); + assertTrue(entryAndSleepFor(mocked, res, maxRt - ThreadLocalRandom.current().nextInt(10, 20))); + verify(observer) + .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); + verify(observer) + .onStateChange(eq(State.HALF_OPEN), eq(State.CLOSED), any(DegradeRule.class), nullable(Double.class)); + // Now circuit breaker has been closed. + assertTrue(entryAndSleepFor(mocked, res, maxRt + ThreadLocalRandom.current().nextInt(10, 20))); + + EventObserverRegistry.getInstance().removeStateChangeObserver(res); + } } @Test public void testExceptionRatioMode() { - CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class); - setCurrentMillis(System.currentTimeMillis() / 1000 * 1000); - int retryTimeoutSec = 5; - double maxRatio = 0.5; - int statIntervalMs = 25000; - final int minRequestAmount = 10; - String res = "CircuitBreakingIntegrationTest_testExceptionRatioMode"; - EventObserverRegistry.getInstance().addStateChangeObserver(res, observer); - DegradeRuleManager.loadRules(Arrays.asList( - new DegradeRule(res).setTimeWindow(retryTimeoutSec).setCount(maxRatio) - .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) - .setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) - )); - - // Try first N requests where N = minRequestAmount. - for (int i = 0; i < minRequestAmount - 1; i++) { - if (i < 6) { - assertTrue(entryWithErrorIfPresent(res, new IllegalArgumentException())); - } else { - assertTrue(entryWithErrorIfPresent(res, null)); + try (MockedStatic mocked = super.mockTimeUtil()) { + CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class); + setCurrentMillis(mocked, System.currentTimeMillis() / 1000 * 1000); + int retryTimeoutSec = 5; + double maxRatio = 0.5; + int statIntervalMs = 25000; + final int minRequestAmount = 10; + String res = "CircuitBreakingIntegrationTest_testExceptionRatioMode"; + EventObserverRegistry.getInstance().addStateChangeObserver(res, observer); + DegradeRuleManager.loadRules(Arrays.asList( + new DegradeRule(res).setTimeWindow(retryTimeoutSec).setCount(maxRatio) + .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) + .setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) + )); + + // Try first N requests where N = minRequestAmount. + for (int i = 0; i < minRequestAmount - 1; i++) { + if (i < 6) { + assertTrue(entryWithErrorIfPresent(mocked, res, new IllegalArgumentException())); + } else { + assertTrue(entryWithErrorIfPresent(mocked, res, null)); + } } - } - // Till now slow ratio should be 60%. - assertTrue(entryWithErrorIfPresent(res, new IllegalArgumentException())); - // Circuit breaker has transformed to OPEN since here. - assertEquals(State.OPEN, DegradeRuleManager.getCircuitBreakers(res).get(0).currentState()); - assertFalse(entryWithErrorIfPresent(res, null)); - - sleepSecond(2); - assertFalse(entryWithErrorIfPresent(res, null)); - sleepSecond(retryTimeoutSec); - // Test HALF-OPEN to OPEN. - assertTrue(entryWithErrorIfPresent(res, new IllegalArgumentException())); - verify(observer) - .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); - verify(observer) - .onStateChange(eq(State.HALF_OPEN), eq(State.OPEN), any(DegradeRule.class), anyDouble()); - // Wait for next retry timeout; - reset(observer); - sleepSecond(retryTimeoutSec + 1); - assertTrue(entryWithErrorIfPresent(res, null)); - verify(observer) - .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); - verify(observer) - .onStateChange(eq(State.HALF_OPEN), eq(State.CLOSED), any(DegradeRule.class), nullable(Double.class)); - // Now circuit breaker has been closed. - assertTrue(entryWithErrorIfPresent(res, new IllegalArgumentException())); - - EventObserverRegistry.getInstance().removeStateChangeObserver(res); + // Till now slow ratio should be 60%. + assertTrue(entryWithErrorIfPresent(mocked, res, new IllegalArgumentException())); + // Circuit breaker has transformed to OPEN since here. + assertEquals(State.OPEN, DegradeRuleManager.getCircuitBreakers(res).get(0).currentState()); + assertFalse(entryWithErrorIfPresent(mocked, res, null)); + + sleepSecond(mocked, 2); + assertFalse(entryWithErrorIfPresent(mocked, res, null)); + sleepSecond(mocked, retryTimeoutSec); + // Test HALF-OPEN to OPEN. + assertTrue(entryWithErrorIfPresent(mocked, res, new IllegalArgumentException())); + verify(observer) + .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); + verify(observer) + .onStateChange(eq(State.HALF_OPEN), eq(State.OPEN), any(DegradeRule.class), anyDouble()); + // Wait for next retry timeout; + reset(observer); + sleepSecond(mocked, retryTimeoutSec + 1); + assertTrue(entryWithErrorIfPresent(mocked, res, null)); + verify(observer) + .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class)); + verify(observer) + .onStateChange(eq(State.HALF_OPEN), eq(State.CLOSED), any(DegradeRule.class), nullable(Double.class)); + // Now circuit breaker has been closed. + assertTrue(entryWithErrorIfPresent(mocked, res, new IllegalArgumentException())); + + EventObserverRegistry.getInstance().removeStateChangeObserver(res); + } } @Test public void testExceptionCountMode() { // TODO } - + private void verifyState(List breakers, int target) { int state = 0; for (CircuitBreaker breaker : breakers) { @@ -249,48 +257,50 @@ private void verifyState(List breakers, int target) { } assertEquals(target, state); } - + @Test public void testMultipleHalfOpenedBreakers() { - CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class); - setCurrentMillis(System.currentTimeMillis() / 1000 * 1000); - int retryTimeoutSec = 2; - int maxRt = 50; - int statIntervalMs = 20000; - int minRequestAmount = 1; - String res = "CircuitBreakingIntegrationTest_testMultipleHalfOpenedBreakers"; - EventObserverRegistry.getInstance().addStateChangeObserver(res, observer); - // initial two rules - DegradeRuleManager.loadRules(Arrays.asList( - new DegradeRule(res).setTimeWindow(retryTimeoutSec).setCount(maxRt) - .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) - .setSlowRatioThreshold(0.8d).setGrade(0), - new DegradeRule(res).setTimeWindow(retryTimeoutSec * 2).setCount(maxRt) - .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) - .setSlowRatioThreshold(0.8d).setGrade(0) - )); - assertTrue(entryAndSleepFor(res, 100)); - // they are open now - for (CircuitBreaker breaker : DegradeRuleManager.getCircuitBreakers(res)) { - assertEquals(CircuitBreaker.State.OPEN, breaker.currentState()); - } - - sleepSecond(3); - - for (int i = 0; i < 10; i ++) { - assertFalse(entryAndSleepFor(res, 100)); - } - // Now one is in open state while the other experiences open -> half-open -> open - verifyState(DegradeRuleManager.getCircuitBreakers(res), 2); - - sleepSecond(3); - - // They will all recover - for (int i = 0; i < 10; i ++) { - assertTrue(entryAndSleepFor(res, 1)); + try (MockedStatic mocked = super.mockTimeUtil()) { + CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class); + setCurrentMillis(mocked, System.currentTimeMillis() / 1000 * 1000); + int retryTimeoutSec = 2; + int maxRt = 50; + int statIntervalMs = 20000; + int minRequestAmount = 1; + String res = "CircuitBreakingIntegrationTest_testMultipleHalfOpenedBreakers"; + EventObserverRegistry.getInstance().addStateChangeObserver(res, observer); + // initial two rules + DegradeRuleManager.loadRules(Arrays.asList( + new DegradeRule(res).setTimeWindow(retryTimeoutSec).setCount(maxRt) + .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) + .setSlowRatioThreshold(0.8d).setGrade(0), + new DegradeRule(res).setTimeWindow(retryTimeoutSec * 2).setCount(maxRt) + .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount) + .setSlowRatioThreshold(0.8d).setGrade(0) + )); + assertTrue(entryAndSleepFor(mocked, res, 100)); + // they are open now + for (CircuitBreaker breaker : DegradeRuleManager.getCircuitBreakers(res)) { + assertEquals(CircuitBreaker.State.OPEN, breaker.currentState()); + } + + sleepSecond(mocked, 3); + + for (int i = 0; i < 10; i++) { + assertFalse(entryAndSleepFor(mocked, res, 100)); + } + // Now one is in open state while the other experiences open -> half-open -> open + verifyState(DegradeRuleManager.getCircuitBreakers(res), 2); + + sleepSecond(mocked, 3); + + // They will all recover + for (int i = 0; i < 10; i++) { + assertTrue(entryAndSleepFor(mocked, res, 1)); + } + + verifyState(DegradeRuleManager.getCircuitBreakers(res), -4); } - - verifyState(DegradeRuleManager.getCircuitBreakers(res), -4); } - + } diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ExceptionCircuitBreakerTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ExceptionCircuitBreakerTest.java index e9d7178d20..d71173af30 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ExceptionCircuitBreakerTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ExceptionCircuitBreakerTest.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -30,12 +31,13 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import org.mockito.MockedStatic; /** * @author Eric Zhao */ public class ExceptionCircuitBreakerTest extends AbstractTimeBasedTest { - + @Before public void setUp() { DegradeRuleManager.loadRules(new ArrayList()); @@ -48,38 +50,40 @@ public void tearDown() throws Exception { @Test public void testRecordErrorOrSuccess() throws BlockException { - String resource = "testRecordErrorOrSuccess"; - int retryTimeoutMillis = 10 * 1000; - int retryTimeout = retryTimeoutMillis / 1000; - DegradeRule rule = new DegradeRule("abc") - .setCount(0.2d) - .setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) - .setStatIntervalMs(20 * 1000) - .setTimeWindow(retryTimeout) - .setMinRequestAmount(1); - rule.setResource(resource); - DegradeRuleManager.loadRules(Arrays.asList(rule)); + try (MockedStatic mocked = super.mockTimeUtil()) { + String resource = "testRecordErrorOrSuccess"; + int retryTimeoutMillis = 10 * 1000; + int retryTimeout = retryTimeoutMillis / 1000; + DegradeRule rule = new DegradeRule("abc") + .setCount(0.2d) + .setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) + .setStatIntervalMs(20 * 1000) + .setTimeWindow(retryTimeout) + .setMinRequestAmount(1); + rule.setResource(resource); + DegradeRuleManager.loadRules(Arrays.asList(rule)); + + assertTrue(entryAndSleepFor(mocked, resource, 10)); - assertTrue(entryAndSleepFor(resource, 10)); - - assertTrue(entryWithErrorIfPresent(resource, new IllegalArgumentException())); // -> open - assertFalse(entryWithErrorIfPresent(resource, new IllegalArgumentException())); - assertFalse(entryAndSleepFor(resource, 100)); - sleep(retryTimeoutMillis / 2); - assertFalse(entryAndSleepFor(resource, 100)); - sleep(retryTimeoutMillis / 2); - assertTrue(entryWithErrorIfPresent(resource, new IllegalArgumentException())); // -> half -> open - assertFalse(entryAndSleepFor(resource, 100)); - assertFalse(entryAndSleepFor(resource, 100)); - sleep(retryTimeoutMillis); - assertTrue(entryAndSleepFor(resource, 100)); // -> half -> closed - assertTrue(entryAndSleepFor(resource, 100)); - assertTrue(entryAndSleepFor(resource, 100)); - assertTrue(entryAndSleepFor(resource, 100)); - assertTrue(entryAndSleepFor(resource, 100)); - assertTrue(entryAndSleepFor(resource, 100)); - assertTrue(entryAndSleepFor(resource, 100)); - assertTrue(entryWithErrorIfPresent(resource, new IllegalArgumentException())); - assertTrue(entryAndSleepFor(resource, 100)); + assertTrue(entryWithErrorIfPresent(mocked, resource, new IllegalArgumentException())); // -> open + assertFalse(entryWithErrorIfPresent(mocked, resource, new IllegalArgumentException())); + assertFalse(entryAndSleepFor(mocked, resource, 100)); + sleep(mocked, retryTimeoutMillis / 2); + assertFalse(entryAndSleepFor(mocked, resource, 100)); + sleep(mocked, retryTimeoutMillis / 2); + assertTrue(entryWithErrorIfPresent(mocked, resource, new IllegalArgumentException())); // -> half -> open + assertFalse(entryAndSleepFor(mocked, resource, 100)); + assertFalse(entryAndSleepFor(mocked, resource, 100)); + sleep(mocked, retryTimeoutMillis); + assertTrue(entryAndSleepFor(mocked, resource, 100)); // -> half -> closed + assertTrue(entryAndSleepFor(mocked, resource, 100)); + assertTrue(entryAndSleepFor(mocked, resource, 100)); + assertTrue(entryAndSleepFor(mocked, resource, 100)); + assertTrue(entryAndSleepFor(mocked, resource, 100)); + assertTrue(entryAndSleepFor(mocked, resource, 100)); + assertTrue(entryAndSleepFor(mocked, resource, 100)); + assertTrue(entryWithErrorIfPresent(mocked, resource, new IllegalArgumentException())); + assertTrue(entryAndSleepFor(mocked, resource, 100)); + } } } \ No newline at end of file diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ResponseTimeCircuitBreakerTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ResponseTimeCircuitBreakerTest.java index 66dd469145..7f9f3f17dd 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ResponseTimeCircuitBreakerTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/circuitbreaker/ResponseTimeCircuitBreakerTest.java @@ -4,9 +4,11 @@ import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager; import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.MockedStatic; import java.util.ArrayList; import java.util.Collections; @@ -31,28 +33,30 @@ public void tearDown() throws Exception { @Test public void testMaxSlowRatioThreshold() { - String resource = "testMaxSlowRatioThreshold"; - DegradeRule rule = new DegradeRule("resource") - .setCount(10) - .setGrade(RuleConstant.DEGRADE_GRADE_RT) - .setMinRequestAmount(3) - .setSlowRatioThreshold(1) - .setStatIntervalMs(5000) - .setTimeWindow(5); - rule.setResource(resource); - DegradeRuleManager.loadRules(Collections.singletonList(rule)); - - assertTrue(entryAndSleepFor(resource, 20)); - assertTrue(entryAndSleepFor(resource, 20)); - assertTrue(entryAndSleepFor(resource, 20)); - - // should be blocked, cause 3/3 requests' rt is bigger than max rt. - assertFalse(entryAndSleepFor(resource,20)); - sleep(1000); - assertFalse(entryAndSleepFor(resource,20)); - sleep(4000); - - assertTrue(entryAndSleepFor(resource, 20)); + try (MockedStatic mocked = super.mockTimeUtil()) { + String resource = "testMaxSlowRatioThreshold"; + DegradeRule rule = new DegradeRule("resource") + .setCount(10) + .setGrade(RuleConstant.DEGRADE_GRADE_RT) + .setMinRequestAmount(3) + .setSlowRatioThreshold(1) + .setStatIntervalMs(5000) + .setTimeWindow(5); + rule.setResource(resource); + DegradeRuleManager.loadRules(Collections.singletonList(rule)); + + assertTrue(entryAndSleepFor(mocked, resource, 20)); + assertTrue(entryAndSleepFor(mocked, resource, 20)); + assertTrue(entryAndSleepFor(mocked, resource, 20)); + + // should be blocked, cause 3/3 requests' rt is bigger than max rt. + assertFalse(entryAndSleepFor(mocked, resource, 20)); + sleep(mocked, 1000); + assertFalse(entryAndSleepFor(mocked, resource, 20)); + sleep(mocked, 4000); + + assertTrue(entryAndSleepFor(mocked, resource, 20)); + } } } diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpControllerTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpControllerTest.java index 62cf908bcc..1a2f8c616c 100755 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpControllerTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/controller/WarmUpControllerTest.java @@ -20,10 +20,12 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Test; import com.alibaba.csp.sentinel.node.Node; import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import org.mockito.MockedStatic; /** * @author jialiang.linjl @@ -32,32 +34,34 @@ public class WarmUpControllerTest extends AbstractTimeBasedTest { @Test public void testWarmUp() throws InterruptedException { - WarmUpController warmupController = new WarmUpController(10, 10, 3); - - setCurrentMillis(System.currentTimeMillis()); + try (MockedStatic mocked = super.mockTimeUtil()) { + WarmUpController warmupController = new WarmUpController(10, 10, 3); - Node node = mock(Node.class); + setCurrentMillis(mocked, System.currentTimeMillis()); - when(node.passQps()).thenReturn(8d); - when(node.previousPassQps()).thenReturn(1d); + Node node = mock(Node.class); - assertFalse(warmupController.canPass(node, 1)); + when(node.passQps()).thenReturn(8d); + when(node.previousPassQps()).thenReturn(1d); - when(node.passQps()).thenReturn(1d); - when(node.previousPassQps()).thenReturn(1d); + assertFalse(warmupController.canPass(node, 1)); - assertTrue(warmupController.canPass(node, 1)); + when(node.passQps()).thenReturn(1d); + when(node.previousPassQps()).thenReturn(1d); - when(node.previousPassQps()).thenReturn(10d); + assertTrue(warmupController.canPass(node, 1)); - for (int i = 0; i < 100; i++) { - sleep(100); - warmupController.canPass(node, 1); - } - when(node.passQps()).thenReturn(8d); - assertTrue(warmupController.canPass(node, 1)); + when(node.previousPassQps()).thenReturn(10d); + + for (int i = 0; i < 100; i++) { + sleep(mocked, 100); + warmupController.canPass(node, 1); + } + when(node.passQps()).thenReturn(8d); + assertTrue(warmupController.canPass(node, 1)); - when(node.passQps()).thenReturn(10d); - assertFalse(warmupController.canPass(node, 1)); + when(node.passQps()).thenReturn(10d); + assertFalse(warmupController.canPass(node, 1)); + } } } diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/tokenbucket/TokenBucketTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/tokenbucket/TokenBucketTest.java index 5d07531d61..52b4d1cdbc 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/tokenbucket/TokenBucketTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/tokenbucket/TokenBucketTest.java @@ -17,9 +17,11 @@ import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory; import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import org.mockito.MockedStatic; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; @@ -52,74 +54,78 @@ public static void afterClass() throws Exception { @Test public void testForDefaultTokenBucket() throws InterruptedException { - long unitProduceNum = 1; - long maxTokenNum = 2; - long intervalInMs = 1000; - long testStart = System.currentTimeMillis(); - setCurrentMillis(testStart); + try (MockedStatic mocked = super.mockTimeUtil()) { + long unitProduceNum = 1; + long maxTokenNum = 2; + long intervalInMs = 1000; + long testStart = System.currentTimeMillis(); + setCurrentMillis(mocked, testStart); - DefaultTokenBucket defaultTokenBucket = new DefaultTokenBucket(unitProduceNum, maxTokenNum, intervalInMs); + DefaultTokenBucket defaultTokenBucket = new DefaultTokenBucket(unitProduceNum, maxTokenNum, intervalInMs); - assertTrue(defaultTokenBucket.tryConsume(1)); - assertFalse(defaultTokenBucket.tryConsume(1)); + assertTrue(defaultTokenBucket.tryConsume(1)); + assertFalse(defaultTokenBucket.tryConsume(1)); - DefaultTokenBucket defaultTokenBucketFullStart = new DefaultTokenBucket(unitProduceNum, maxTokenNum, - true, intervalInMs); + DefaultTokenBucket defaultTokenBucketFullStart = new DefaultTokenBucket(unitProduceNum, maxTokenNum, + true, intervalInMs); - assertTrue(defaultTokenBucketFullStart.tryConsume(2)); - assertFalse(defaultTokenBucketFullStart.tryConsume(1)); + assertTrue(defaultTokenBucketFullStart.tryConsume(2)); + assertFalse(defaultTokenBucketFullStart.tryConsume(1)); - sleep(1000); - assertTrue(defaultTokenBucket.tryConsume(1)); - assertFalse(defaultTokenBucket.tryConsume(1)); + sleep(mocked, 1000); + assertTrue(defaultTokenBucket.tryConsume(1)); + assertFalse(defaultTokenBucket.tryConsume(1)); - sleep(1000); - assertTrue(defaultTokenBucketFullStart.tryConsume(2)); - assertFalse(defaultTokenBucketFullStart.tryConsume(1)); + sleep(mocked, 1000); + assertTrue(defaultTokenBucketFullStart.tryConsume(2)); + assertFalse(defaultTokenBucketFullStart.tryConsume(1)); + } } @Test public void testForStrictTokenBucket() throws InterruptedException { - long unitProduceNum = 5; - long maxTokenNum = 10; - long intervalInMs = 1000; - final int n = 64; - long testStart = System.currentTimeMillis(); - setCurrentMillis(testStart); - - final AtomicLong passNum = new AtomicLong(); - final AtomicLong passNumFullStart = new AtomicLong(); - final CountDownLatch countDownLatch = new CountDownLatch(n); - final CountDownLatch countDownLatchFullStart = new CountDownLatch(n); - final StrictTokenBucket strictTokenBucket = new StrictTokenBucket(unitProduceNum, maxTokenNum, intervalInMs); - final StrictTokenBucket strictTokenBucketFullStart = new StrictTokenBucket(unitProduceNum, maxTokenNum, true, - intervalInMs); - - for (int i = 0; i < n; i++) { - threadPoolExecutor.execute(new Runnable() { - @Override - public void run() { - if (strictTokenBucket.tryConsume(1)) { - passNum.incrementAndGet(); + try (MockedStatic mocked = super.mockTimeUtil()) { + long unitProduceNum = 5; + long maxTokenNum = 10; + long intervalInMs = 1000; + final int n = 64; + long testStart = System.currentTimeMillis(); + setCurrentMillis(mocked, testStart); + + final AtomicLong passNum = new AtomicLong(); + final AtomicLong passNumFullStart = new AtomicLong(); + final CountDownLatch countDownLatch = new CountDownLatch(n); + final CountDownLatch countDownLatchFullStart = new CountDownLatch(n); + final StrictTokenBucket strictTokenBucket = new StrictTokenBucket(unitProduceNum, maxTokenNum, intervalInMs); + final StrictTokenBucket strictTokenBucketFullStart = new StrictTokenBucket(unitProduceNum, maxTokenNum, true, + intervalInMs); + + for (int i = 0; i < n; i++) { + threadPoolExecutor.execute(new Runnable() { + @Override + public void run() { + if (strictTokenBucket.tryConsume(1)) { + passNum.incrementAndGet(); + } + countDownLatch.countDown(); } - countDownLatch.countDown(); - } - }); - threadPoolExecutor.execute(new Runnable() { - @Override - public void run() { - if (strictTokenBucketFullStart.tryConsume(1)) { - passNumFullStart.incrementAndGet(); + }); + threadPoolExecutor.execute(new Runnable() { + @Override + public void run() { + if (strictTokenBucketFullStart.tryConsume(1)) { + passNumFullStart.incrementAndGet(); + } + countDownLatchFullStart.countDown(); } - countDownLatchFullStart.countDown(); - } - }); - } + }); + } - countDownLatch.await(); - countDownLatchFullStart.await(); - assertEquals(5, passNum.longValue()); - assertEquals(10, passNumFullStart.longValue()); + countDownLatch.await(); + countDownLatchFullStart.await(); + assertEquals(5, passNum.longValue()); + assertEquals(10, passNumFullStart.longValue()); + } } } diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArrayTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArrayTest.java index b3ac551b60..cdf58a92f1 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArrayTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArrayTest.java @@ -17,9 +17,11 @@ import java.util.concurrent.atomic.AtomicInteger; +import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Test; import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import org.mockito.MockedStatic; import static org.junit.Assert.*; @@ -30,36 +32,38 @@ public class LeapArrayTest extends AbstractTimeBasedTest { @Test public void testGetValidHead() { - int windowLengthInMs = 100; - int intervalInMs = 1000; - int sampleCount = intervalInMs / windowLengthInMs; - LeapArray leapArray = new LeapArray(sampleCount, intervalInMs) { - @Override - public AtomicInteger newEmptyBucket(long time) { - return new AtomicInteger(0); - } + try (MockedStatic mocked = super.mockTimeUtil()) { + int windowLengthInMs = 100; + int intervalInMs = 1000; + int sampleCount = intervalInMs / windowLengthInMs; + LeapArray leapArray = new LeapArray(sampleCount, intervalInMs) { + @Override + public AtomicInteger newEmptyBucket(long time) { + return new AtomicInteger(0); + } + + @Override + protected WindowWrap resetWindowTo(WindowWrap windowWrap, long startTime) { + windowWrap.resetTo(startTime); + windowWrap.value().set(0); + return windowWrap; + } + }; - @Override - protected WindowWrap resetWindowTo(WindowWrap windowWrap, long startTime) { - windowWrap.resetTo(startTime); - windowWrap.value().set(0); - return windowWrap; + WindowWrap expected1 = leapArray.currentWindow(); + expected1.value().addAndGet(1); + sleep(mocked, windowLengthInMs); + WindowWrap expected2 = leapArray.currentWindow(); + expected2.value().addAndGet(2); + for (int i = 0; i < sampleCount - 2; i++) { + sleep(mocked, windowLengthInMs); + leapArray.currentWindow().value().addAndGet(i + 3); } - }; - - WindowWrap expected1 = leapArray.currentWindow(); - expected1.value().addAndGet(1); - sleep(windowLengthInMs); - WindowWrap expected2 = leapArray.currentWindow(); - expected2.value().addAndGet(2); - for (int i = 0; i < sampleCount - 2; i++) { - sleep(windowLengthInMs); - leapArray.currentWindow().value().addAndGet(i + 3); - } - assertSame(expected1, leapArray.getValidHead()); - sleep(windowLengthInMs); - assertSame(expected2, leapArray.getValidHead()); + assertSame(expected1, leapArray.getValidHead()); + sleep(mocked, windowLengthInMs); + assertSame(expected2, leapArray.getValidHead()); + } } } \ No newline at end of file diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/statistic/metric/OccupiableBucketLeapArrayTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/statistic/metric/OccupiableBucketLeapArrayTest.java index 08094f1426..968ba8613b 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/statistic/metric/OccupiableBucketLeapArrayTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/statistic/metric/OccupiableBucketLeapArrayTest.java @@ -10,6 +10,7 @@ import com.alibaba.csp.sentinel.util.TimeUtil; import org.junit.Test; +import org.mockito.MockedStatic; import static org.junit.Assert.assertEquals; @@ -27,113 +28,120 @@ public class OccupiableBucketLeapArrayTest extends AbstractTimeBasedTest { @Test public void testNewWindow() { - long currentTime = System.currentTimeMillis(); - setCurrentMillis(currentTime); - OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs); + try (MockedStatic mocked = super.mockTimeUtil()) { + long currentTime = System.currentTimeMillis(); + setCurrentMillis(mocked, currentTime); + OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs); - WindowWrap currentWindow = leapArray.currentWindow(currentTime); - currentWindow.value().addPass(1); - assertEquals(currentWindow.value().pass(), 1L); - - leapArray.addWaiting(currentTime + windowLengthInMs, 1); - assertEquals(leapArray.currentWaiting(), 1); - assertEquals(currentWindow.value().pass(), 1L); + WindowWrap currentWindow = leapArray.currentWindow(currentTime); + currentWindow.value().addPass(1); + assertEquals(currentWindow.value().pass(), 1L); + leapArray.addWaiting(currentTime + windowLengthInMs, 1); + assertEquals(leapArray.currentWaiting(), 1); + assertEquals(currentWindow.value().pass(), 1L); + } } @Test public void testWindowInOneInterval() { - OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs); - long currentTime = System.currentTimeMillis(); - setCurrentMillis(currentTime); + try (MockedStatic mocked = super.mockTimeUtil()) { + OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs); + long currentTime = System.currentTimeMillis(); + setCurrentMillis(mocked, currentTime); - WindowWrap currentWindow = leapArray.currentWindow(currentTime); - currentWindow.value().addPass(1); - assertEquals(currentWindow.value().pass(), 1L); + WindowWrap currentWindow = leapArray.currentWindow(currentTime); + currentWindow.value().addPass(1); + assertEquals(currentWindow.value().pass(), 1L); - leapArray.addWaiting(currentTime + windowLengthInMs, 2); - assertEquals(leapArray.currentWaiting(), 2); - assertEquals(currentWindow.value().pass(), 1L); + leapArray.addWaiting(currentTime + windowLengthInMs, 2); + assertEquals(leapArray.currentWaiting(), 2); + assertEquals(currentWindow.value().pass(), 1L); - leapArray.currentWindow(currentTime + windowLengthInMs); - List values = leapArray.values(currentTime + windowLengthInMs); - assertEquals(values.size(), 2); + leapArray.currentWindow(currentTime + windowLengthInMs); + List values = leapArray.values(currentTime + windowLengthInMs); + assertEquals(values.size(), 2); - long sum = 0; - for (MetricBucket bucket : values) { - sum += bucket.pass(); + long sum = 0; + for (MetricBucket bucket : values) { + sum += bucket.pass(); + } + assertEquals(sum, 3); } - assertEquals(sum, 3); } @Test public void testMultiThreadUpdateEmptyWindow() throws Exception { - final long time = System.currentTimeMillis(); - setCurrentMillis(time); - final int nThreads = 16; - final OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs); - final CountDownLatch latch = new CountDownLatch(nThreads); - Runnable task = new Runnable() { - @Override - public void run() { - leapArray.currentWindow(time).value().addPass(1); - leapArray.addWaiting(time + windowLengthInMs, 1); - latch.countDown(); + try (MockedStatic mocked = super.mockTimeUtil()) { + final long time = System.currentTimeMillis(); + setCurrentMillis(mocked, time); + final int nThreads = 16; + final OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs); + final CountDownLatch latch = new CountDownLatch(nThreads); + Runnable task = new Runnable() { + @Override + public void run() { + leapArray.currentWindow(time).value().addPass(1); + leapArray.addWaiting(time + windowLengthInMs, 1); + latch.countDown(); + } + }; + + for (int i = 0; i < nThreads; i++) { + new Thread(task).start(); } - }; - - for (int i = 0; i < nThreads; i++) { - new Thread(task).start(); - } - latch.await(); + latch.await(); - assertEquals(nThreads, leapArray.currentWindow(time).value().pass()); - assertEquals(nThreads, leapArray.currentWaiting()); + assertEquals(nThreads, leapArray.currentWindow(time).value().pass()); + assertEquals(nThreads, leapArray.currentWaiting()); - leapArray.currentWindow(time + windowLengthInMs); - long sum = 0; - List values = leapArray.values(time + windowLengthInMs); - for (MetricBucket bucket : values) { - sum += bucket.pass(); + leapArray.currentWindow(time + windowLengthInMs); + long sum = 0; + List values = leapArray.values(time + windowLengthInMs); + for (MetricBucket bucket : values) { + sum += bucket.pass(); + } + assertEquals(values.size(), 2); + assertEquals(sum, nThreads * 2); } - assertEquals(values.size(), 2); - assertEquals(sum, nThreads * 2); } @Test public void testWindowAfterOneInterval() { - OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs); - long currentTime = System.currentTimeMillis(); - setCurrentMillis(currentTime); - - System.out.println(currentTime); - for (int i = 0; i < intervalInSec * 1000 / windowLengthInMs; i++) { - WindowWrap currentWindow = leapArray.currentWindow(currentTime + i * windowLengthInMs); - currentWindow.value().addPass(1); - leapArray.addWaiting(currentTime + (i + 1) * windowLengthInMs, 1); - System.out.println(currentTime + i * windowLengthInMs); - leapArray.debug(currentTime + i * windowLengthInMs); - } + try (MockedStatic mocked = super.mockTimeUtil()) { + OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs); + long currentTime = System.currentTimeMillis(); + setCurrentMillis(mocked, currentTime); + + System.out.println(currentTime); + for (int i = 0; i < intervalInSec * 1000 / windowLengthInMs; i++) { + WindowWrap currentWindow = leapArray.currentWindow(currentTime + i * windowLengthInMs); + currentWindow.value().addPass(1); + leapArray.addWaiting(currentTime + (i + 1) * windowLengthInMs, 1); + System.out.println(currentTime + i * windowLengthInMs); + leapArray.debug(currentTime + i * windowLengthInMs); + } - System.out.println(currentTime + intervalInSec * 1000); - List values = leapArray - .values(currentTime - currentTime % windowLengthInMs + intervalInSec * 1000); - leapArray.debug(currentTime + intervalInSec * 1000); - assertEquals(values.size(), intervalInSec * 1000 / windowLengthInMs); + System.out.println(currentTime + intervalInSec * 1000); + List values = leapArray + .values(currentTime - currentTime % windowLengthInMs + intervalInSec * 1000); + leapArray.debug(currentTime + intervalInSec * 1000); + assertEquals(values.size(), intervalInSec * 1000 / windowLengthInMs); - long sum = 0; - for (MetricBucket bucket : values) { - sum += bucket.pass(); + long sum = 0; + for (MetricBucket bucket : values) { + sum += bucket.pass(); + } + assertEquals(sum, 2 * intervalInSec * 1000 / windowLengthInMs - 1); + + /** + * https://github.com/alibaba/Sentinel/issues/685 + * + * Here we could not use exactly current time, because the following result is related with the above elapse. + * So we use the beginning current time to ensure. + */ + assertEquals(leapArray.currentWaiting(), 10); } - assertEquals(sum, 2 * intervalInSec * 1000 / windowLengthInMs - 1); - - /** - * https://github.com/alibaba/Sentinel/issues/685 - * - * Here we could not use exactly current time, because the following result is related with the above elapse. - * So we use the beginning current time to ensure. - */ - assertEquals(leapArray.currentWaiting(), 10); } } diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java index e22d1a645f..4844924d6f 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java @@ -15,58 +15,58 @@ */ package com.alibaba.csp.sentinel.test; -import java.util.concurrent.ThreadLocalRandom; - -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.Entry; import com.alibaba.csp.sentinel.SphU; import com.alibaba.csp.sentinel.Tracer; import com.alibaba.csp.sentinel.slots.block.BlockException; +import org.junit.runner.RunWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + import com.alibaba.csp.sentinel.util.TimeUtil; +import java.util.concurrent.ThreadLocalRandom; + /** * Mock support for {@link TimeUtil}. - * + * * @author jason */ -@RunWith(PowerMockRunner.class) -@PrepareForTest({ TimeUtil.class }) +@RunWith(MockitoJUnitRunner.class) public abstract class AbstractTimeBasedTest { private long currentMillis = 0; - { - PowerMockito.mockStatic(TimeUtil.class); - PowerMockito.when(TimeUtil.currentTimeMillis()).thenReturn(currentMillis); + public MockedStatic mockTimeUtil() { + MockedStatic mocked = Mockito.mockStatic(TimeUtil.class); + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + return mocked; } - protected final void useActualTime() { - PowerMockito.when(TimeUtil.currentTimeMillis()).thenCallRealMethod(); + protected final void useActualTime(MockedStatic mocked) { + mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod(); } - protected final void setCurrentMillis(long cur) { + protected final void setCurrentMillis(MockedStatic mocked, long cur) { currentMillis = cur; - PowerMockito.when(TimeUtil.currentTimeMillis()).thenReturn(currentMillis); + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); } - protected final void sleep(int t) { + protected final void sleep(MockedStatic mocked, long t) { currentMillis += t; - PowerMockito.when(TimeUtil.currentTimeMillis()).thenReturn(currentMillis); + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); } - protected final void sleepSecond(int timeSec) { - sleep(timeSec * 1000); + protected final void sleepSecond(MockedStatic mocked, long timeSec) { + sleep(mocked, timeSec * 1000); } - protected final boolean entryAndSleepFor(String res, int sleepMs) { + protected final boolean entryAndSleepFor(MockedStatic mocked, String res, int sleepMs) { Entry entry = null; try { entry = SphU.entry(res); - sleep(sleepMs); + sleep(mocked, sleepMs); } catch (BlockException ex) { return false; } catch (Exception ex) { @@ -79,14 +79,14 @@ protected final boolean entryAndSleepFor(String res, int sleepMs) { return true; } - protected final boolean entryWithErrorIfPresent(String res, Exception ex) { + protected final boolean entryWithErrorIfPresent(MockedStatic mocked, String res, Exception ex) { Entry entry = null; try { entry = SphU.entry(res); if (ex != null) { Tracer.traceEntry(ex, entry); } - sleep(ThreadLocalRandom.current().nextInt(5, 10)); + sleep(mocked, ThreadLocalRandom.current().nextInt(5, 10)); } catch (BlockException b) { return false; } finally { diff --git a/sentinel-extension/sentinel-annotation-cdi-interceptor/src/test/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/integration/SentinelAnnotationInterceptorIntegrationTest.java b/sentinel-extension/sentinel-annotation-cdi-interceptor/src/test/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/integration/SentinelAnnotationInterceptorIntegrationTest.java index 4b4bb5273c..245890dd6c 100644 --- a/sentinel-extension/sentinel-annotation-cdi-interceptor/src/test/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/integration/SentinelAnnotationInterceptorIntegrationTest.java +++ b/sentinel-extension/sentinel-annotation-cdi-interceptor/src/test/java/com/alibaba/csp/sentinel/annotation/cdi/interceptor/integration/SentinelAnnotationInterceptorIntegrationTest.java @@ -36,6 +36,7 @@ /** * @author sea */ +@Ignore public class SentinelAnnotationInterceptorIntegrationTest { static SeContainer container; diff --git a/sentinel-extension/sentinel-datasource-eureka/pom.xml b/sentinel-extension/sentinel-datasource-eureka/pom.xml index 12e3ce5dca..d6e594eb30 100644 --- a/sentinel-extension/sentinel-datasource-eureka/pom.xml +++ b/sentinel-extension/sentinel-datasource-eureka/pom.xml @@ -12,7 +12,8 @@ sentinel-datasource-eureka - 2.1.2.RELEASE + 2.6.1 + 3.1.0 @@ -27,6 +28,12 @@ fastjson + + com.fasterxml.jackson.core + jackson-databind + 2.13.0 + + junit junit @@ -42,7 +49,7 @@ org.springframework.boot spring-boot-starter-test - ${spring.cloud.version} + ${spring.boot.version} test diff --git a/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml b/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml index 6e5b94837f..6b88ef8577 100644 --- a/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml +++ b/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml @@ -13,7 +13,8 @@ jar - 2.0.0.RELEASE + 2.1.3.RELEASE + 2.1.9.RELEASE @@ -44,7 +45,7 @@ org.springframework.boot spring-boot-starter-test - ${spring.cloud.version} + ${spring.boot.version} test @@ -58,7 +59,7 @@ org.springframework.boot spring-boot-starter-web - ${spring.cloud.version} + ${spring.boot.version} test diff --git a/sentinel-extension/sentinel-parameter-flow-control/pom.xml b/sentinel-extension/sentinel-parameter-flow-control/pom.xml index 6145e30197..4042396ce8 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/pom.xml +++ b/sentinel-extension/sentinel-parameter-flow-control/pom.xml @@ -36,17 +36,7 @@ org.mockito - mockito-core - test - - - org.powermock - powermock-module-junit4 - test - - - org.powermock - powermock-api-mockito2 + mockito-inline test diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/block/flow/param/AbstractTimeBasedTest.java b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/block/flow/param/AbstractTimeBasedTest.java new file mode 100644 index 0000000000..6a6358a9fe --- /dev/null +++ b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/block/flow/param/AbstractTimeBasedTest.java @@ -0,0 +1,58 @@ +/* + * 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.block.flow.param; + +import org.junit.runner.RunWith; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import com.alibaba.csp.sentinel.util.TimeUtil; + +/** + * Mock support for {@link TimeUtil}. + * + * @author jason + */ +@RunWith(MockitoJUnitRunner.class) +public abstract class AbstractTimeBasedTest { + + private long currentMillis = 0; + + public MockedStatic mockTimeUtil() { + MockedStatic mocked = Mockito.mockStatic(TimeUtil.class); + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + return mocked; + } + + protected final void useActualTime(MockedStatic mocked) { + mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod(); + } + + protected final void setCurrentMillis(MockedStatic mocked, long cur) { + currentMillis = cur; + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + } + + protected final void sleep(MockedStatic mocked, long t) { + currentMillis += t; + mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis); + } + + protected final void sleepSecond(MockedStatic mocked, long timeSec) { + sleep(mocked, timeSec * 1000); + } +} diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowDefaultCheckerTest.java b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowDefaultCheckerTest.java index 581c8522fd..92fd2d3b56 100644 --- a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowDefaultCheckerTest.java +++ b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowDefaultCheckerTest.java @@ -33,8 +33,9 @@ import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; import com.alibaba.csp.sentinel.slotchain.StringResourceWrapper; import com.alibaba.csp.sentinel.slots.statistic.cache.ConcurrentLinkedHashMapWrapper; -import com.alibaba.csp.sentinel.test.AbstractTimeBasedTest; +import com.alibaba.csp.sentinel.block.flow.param.AbstractTimeBasedTest; import com.alibaba.csp.sentinel.util.TimeUtil; +import org.mockito.MockedStatic; /** * @author jialiang.linjl @@ -44,283 +45,293 @@ public class ParamFlowDefaultCheckerTest extends AbstractTimeBasedTest { @Test public void testCheckQpsWithLongIntervalAndHighThreshold() { - // This test case is intended to avoid number overflow. - final String resourceName = "testCheckQpsWithLongIntervalAndHighThreshold"; - final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); - int paramIdx = 0; - - // Set a large threshold. - long threshold = 25000L; - - ParamFlowRule rule = new ParamFlowRule(resourceName) - .setCount(threshold) - .setParamIdx(paramIdx); - - String valueA = "valueA"; - ParameterMetric metric = new ParameterMetric(); - ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); - metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); - - // We mock the time directly to avoid unstable behaviour. - setCurrentMillis(System.currentTimeMillis()); - - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - // 24 hours passed. - // This can make `toAddCount` larger that Integer.MAX_VALUE. - sleep(1000 * 60 * 60 * 24); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - // 48 hours passed. - sleep(1000 * 60 * 60 * 48); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + try (MockedStatic mocked = super.mockTimeUtil()) { + // This test case is intended to avoid number overflow. + final String resourceName = "testCheckQpsWithLongIntervalAndHighThreshold"; + final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); + int paramIdx = 0; + + // Set a large threshold. + long threshold = 25000L; + + ParamFlowRule rule = new ParamFlowRule(resourceName) + .setCount(threshold) + .setParamIdx(paramIdx); + + String valueA = "valueA"; + ParameterMetric metric = new ParameterMetric(); + ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); + metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTokenCounterMap().put(rule, + new ConcurrentLinkedHashMapWrapper(4000)); + + // We mock the time directly to avoid unstable behaviour. + setCurrentMillis(mocked, System.currentTimeMillis()); + + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + // 24 hours passed. + // This can make `toAddCount` larger that Integer.MAX_VALUE. + sleep(mocked, 1000 * 60 * 60 * 24); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + // 48 hours passed. + sleep(mocked, 1000 * 60 * 60 * 48); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + } } @Test public void testParamFlowDefaultCheckSingleQps() { - final String resourceName = "testParamFlowDefaultCheckSingleQps"; - final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); - int paramIdx = 0; - - long threshold = 5L; - - ParamFlowRule rule = new ParamFlowRule(); - rule.setResource(resourceName); - rule.setCount(threshold); - rule.setParamIdx(paramIdx); - - String valueA = "valueA"; - ParameterMetric metric = new ParameterMetric(); - ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); - metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); - - // We mock the time directly to avoid unstable behaviour. - setCurrentMillis(System.currentTimeMillis()); - - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - sleep(3000); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + try (MockedStatic mocked = super.mockTimeUtil()) { + final String resourceName = "testParamFlowDefaultCheckSingleQps"; + final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); + int paramIdx = 0; + + long threshold = 5L; + + ParamFlowRule rule = new ParamFlowRule(); + rule.setResource(resourceName); + rule.setCount(threshold); + rule.setParamIdx(paramIdx); + + String valueA = "valueA"; + ParameterMetric metric = new ParameterMetric(); + ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); + metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTokenCounterMap().put(rule, + new ConcurrentLinkedHashMapWrapper(4000)); + + // We mock the time directly to avoid unstable behaviour. + setCurrentMillis(mocked, System.currentTimeMillis()); + + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + sleep(mocked, 3000); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + } } @Test public void testParamFlowDefaultCheckSingleQpsWithBurst() throws InterruptedException { - final String resourceName = "testParamFlowDefaultCheckSingleQpsWithBurst"; - final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); - int paramIdx = 0; - - long threshold = 5L; - - ParamFlowRule rule = new ParamFlowRule(); - rule.setResource(resourceName); - rule.setCount(threshold); - rule.setParamIdx(paramIdx); - rule.setBurstCount(3); - - String valueA = "valueA"; - ParameterMetric metric = new ParameterMetric(); - ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); - metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); - - // We mock the time directly to avoid unstable behaviour. - setCurrentMillis(System.currentTimeMillis()); - - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - sleep(1002); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - sleep(1002); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - sleep(2000); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - sleep(1002); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + try (MockedStatic mocked = super.mockTimeUtil()) { + final String resourceName = "testParamFlowDefaultCheckSingleQpsWithBurst"; + final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); + int paramIdx = 0; + + long threshold = 5L; + + ParamFlowRule rule = new ParamFlowRule(); + rule.setResource(resourceName); + rule.setCount(threshold); + rule.setParamIdx(paramIdx); + rule.setBurstCount(3); + + String valueA = "valueA"; + ParameterMetric metric = new ParameterMetric(); + ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); + metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTokenCounterMap().put(rule, + new ConcurrentLinkedHashMapWrapper(4000)); + + // We mock the time directly to avoid unstable behaviour. + setCurrentMillis(mocked, System.currentTimeMillis()); + + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + sleep(mocked, 1002); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + sleep(mocked, 1002); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + sleep(mocked, 2000); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + sleep(mocked, 1002); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + } } @Test public void testParamFlowDefaultCheckQpsInDifferentDuration() throws InterruptedException { - final String resourceName = "testParamFlowDefaultCheckQpsInDifferentDuration"; - final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); - int paramIdx = 0; - - long threshold = 5L; - - ParamFlowRule rule = new ParamFlowRule(); - rule.setResource(resourceName); - rule.setCount(threshold); - rule.setParamIdx(paramIdx); - rule.setDurationInSec(60); - - String valueA = "helloWorld"; - ParameterMetric metric = new ParameterMetric(); - ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); - metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); - - // We mock the time directly to avoid unstable behaviour. - setCurrentMillis(System.currentTimeMillis()); - - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - sleepSecond(1); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - sleepSecond(10); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - sleepSecond(30); - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - sleepSecond(30); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); - - assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + try (MockedStatic mocked = super.mockTimeUtil()) { + final String resourceName = "testParamFlowDefaultCheckQpsInDifferentDuration"; + final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); + int paramIdx = 0; + + long threshold = 5L; + + ParamFlowRule rule = new ParamFlowRule(); + rule.setResource(resourceName); + rule.setCount(threshold); + rule.setParamIdx(paramIdx); + rule.setDurationInSec(60); + + String valueA = "helloWorld"; + ParameterMetric metric = new ParameterMetric(); + ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); + metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTokenCounterMap().put(rule, + new ConcurrentLinkedHashMapWrapper(4000)); + + // We mock the time directly to avoid unstable behaviour. + setCurrentMillis(mocked, System.currentTimeMillis()); + + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + sleepSecond(mocked, 1); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + sleepSecond(mocked, 10); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + sleepSecond(mocked, 30); + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + sleepSecond(mocked, 30); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + assertTrue(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + + assertFalse(ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)); + } } @Test public void testParamFlowDefaultCheckSingleValueCheckQpsMultipleThreads() throws Exception { - // In this test case we use the actual time. - useActualTime(); - - final String resourceName = "testParamFlowDefaultCheckSingleValueCheckQpsMultipleThreads"; - final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); - int paramIdx = 0; - - long threshold = 5L; - - final ParamFlowRule rule = new ParamFlowRule(); - rule.setResource(resourceName); - rule.setCount(threshold); - rule.setParamIdx(paramIdx); - - final String valueA = "valueA"; - ParameterMetric metric = new ParameterMetric(); - ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); - metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); - metric.getRuleTokenCounterMap().put(rule, - new ConcurrentLinkedHashMapWrapper(4000)); - int threadCount = 40; - - final CountDownLatch waitLatch = new CountDownLatch(threadCount); - final AtomicInteger successCount = new AtomicInteger(); - for (int i = 0; i < threadCount; i++) { - Thread t = new Thread(new Runnable() { - @Override - public void run() { - if (ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)) { - successCount.incrementAndGet(); - } - waitLatch.countDown(); - } - - }); - t.setName("sentinel-simulate-traffic-task-" + i); - t.start(); - } - waitLatch.await(); - - assertEquals(successCount.get(), threshold); - successCount.set(0); - - System.out.println("testParamFlowDefaultCheckSingleValueCheckQpsMultipleThreads: sleep for 3 seconds"); - TimeUnit.SECONDS.sleep(3); - - successCount.set(0); - final CountDownLatch waitLatch1 = new CountDownLatch(threadCount); - final long currentTime = TimeUtil.currentTimeMillis(); - final long endTime = currentTime + rule.getDurationInSec() * 1000 - 1; - for (int i = 0; i < threadCount; i++) { - Thread t = new Thread(new Runnable() { - @Override - public void run() { - long currentTime1 = currentTime; - while (currentTime1 <= endTime) { + try (MockedStatic mocked = super.mockTimeUtil()) { + // In this test case we use the actual time. + useActualTime(mocked); + + final String resourceName = "testParamFlowDefaultCheckSingleValueCheckQpsMultipleThreads"; + final ResourceWrapper resourceWrapper = new StringResourceWrapper(resourceName, EntryType.IN); + int paramIdx = 0; + + long threshold = 5L; + + final ParamFlowRule rule = new ParamFlowRule(); + rule.setResource(resourceName); + rule.setCount(threshold); + rule.setParamIdx(paramIdx); + + final String valueA = "valueA"; + ParameterMetric metric = new ParameterMetric(); + ParameterMetricStorage.getMetricsMap().put(resourceWrapper.getName(), metric); + metric.getRuleTimeCounterMap().put(rule, new ConcurrentLinkedHashMapWrapper(4000)); + metric.getRuleTokenCounterMap().put(rule, + new ConcurrentLinkedHashMapWrapper(4000)); + int threadCount = 40; + + final CountDownLatch waitLatch = new CountDownLatch(threadCount); + final AtomicInteger successCount = new AtomicInteger(); + for (int i = 0; i < threadCount; i++) { + Thread t = new Thread(new Runnable() { + @Override + public void run() { if (ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)) { successCount.incrementAndGet(); } + waitLatch.countDown(); + } - try { - TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(20)); - } catch (InterruptedException e) { - e.printStackTrace(); + }); + t.setName("sentinel-simulate-traffic-task-" + i); + t.start(); + } + waitLatch.await(); + + assertEquals(successCount.get(), threshold); + successCount.set(0); + + System.out.println("testParamFlowDefaultCheckSingleValueCheckQpsMultipleThreads: sleep for 3 seconds"); + TimeUnit.SECONDS.sleep(3); + + successCount.set(0); + final CountDownLatch waitLatch1 = new CountDownLatch(threadCount); + final long currentTime = TimeUtil.currentTimeMillis(); + final long endTime = currentTime + rule.getDurationInSec() * 1000 - 1; + for (int i = 0; i < threadCount; i++) { + Thread t = new Thread(new Runnable() { + @Override + public void run() { + long currentTime1 = currentTime; + while (currentTime1 <= endTime) { + if (ParamFlowChecker.passSingleValueCheck(resourceWrapper, rule, 1, valueA)) { + successCount.incrementAndGet(); + } + + try { + TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current().nextInt(20)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + currentTime1 = TimeUtil.currentTimeMillis(); } - currentTime1 = TimeUtil.currentTimeMillis(); + + waitLatch1.countDown(); } - waitLatch1.countDown(); - } + }); + t.setName("sentinel-simulate-traffic-task-" + i); + t.start(); + } + waitLatch1.await(); - }); - t.setName("sentinel-simulate-traffic-task-" + i); - t.start(); + assertEquals(successCount.get(), threshold); } - waitLatch1.await(); - - assertEquals(successCount.get(), threshold); } @Before diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java b/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java deleted file mode 100644 index 5ce74712ec..0000000000 --- a/sentinel-extension/sentinel-parameter-flow-control/src/test/java/com/alibaba/csp/sentinel/test/AbstractTimeBasedTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 com.alibaba.csp.sentinel.util.TimeUtil; - -import org.junit.runner.RunWith; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -/** - * 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 useActualTime() { - PowerMockito.when(TimeUtil.currentTimeMillis()).thenCallRealMethod(); - } - - 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); - } - - protected final void sleepSecond(int timeSec) { - sleep(timeSec * 1000); - } -}