Repository: alibaba/Sentinel
Pull request #3339 (2024-02-20 03:45:36)

Support jdk17
<!--  Thanks for submitting a pull request! Here are some tips for you:
1. Please make sure you have read and understood the contributing guidelines: https://github.com/alibaba/Sentinel/blob/master/CONTRIBUTING.md
2. Please make sure the PR has a corresponding issue.
-->

### Describe what this PR does / why we need it

Support JDK17: 
1. Adjust the test logic, use jdk17 to build, 8, 11, 17 to run 
2. Spring boot test version was upgraded to 2.4 in order to run under jdk17 
3. 'sentinel-annotation-cdi-interceptor' module, because the related dependency does not support jdk17, so ignore the test case for the time being
<details>
  <summary>Chinese/中文</summary>

支持JDK17:
1. 调整测试逻辑，使用jdk17构建，8、11、17运行
2. Spring boot 测试版本升级到2.4，为了能够在jdk17下运行
3. `sentinel-annotation-cdi-interceptor`模块，因为相关依赖没有支持jdk17，所以暂时忽略测试用例
</details>

### Does this pull request fix one issue?

https://github.com/alibaba/Sentinel/issues/2797

<!--If that, add "Fixes #xxxx" below in the next line. For example, Fixes #15. Otherwise, add "NONE" -->

### Describe how you did it


### Describe how to verify it


### Special notes for reviews


panxiaojun233: LGTM

Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 1f0edcc1..6b3dccf5 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 0e6363fe..71fafc00 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 8cd76731..cb5cc7b1 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 95bc66e7..23596e56 100755
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,7 @@
 
         <!-- Test libs -->
         <junit.version>4.12</junit.version>
-        <mockito.version>2.28.2</mockito.version>
+        <mockito.version>3.12.4</mockito.version>
         <assertj.version>3.12.1</assertj.version>
         <awaitility.version>3.1.5</awaitility.version>
         <powermock.version>2.0.0</powermock.version>
@@ -56,14 +56,14 @@
         <java.source.version>1.8</java.source.version>
         <java.target.version>1.8</java.target.version>
         <java.encoding>UTF-8</java.encoding>
-        <maven.compiler.version>3.8.0</maven.compiler.version>
-        <maven.surefire.version>2.22.1</maven.surefire.version>
+        <maven.compiler.version>3.12.0</maven.compiler.version>
+        <maven.surefire.version>3.2.5</maven.surefire.version>
         <maven.source.version>3.0.1</maven.source.version>
         <maven.javadoc.version>3.0.1</maven.javadoc.version>
         <maven.deploy.version>2.8.2</maven.deploy.version>
         <maven.gpg.version>1.6</maven.gpg.version>
         <maven.jacoco.version>0.8.3</maven.jacoco.version>
-        <maven.jar.version>3.1.0</maven.jar.version>
+        <maven.jar.version>3.3.0</maven.jar.version>
         <maven.pmd.version>3.8</maven.pmd.version>
     </properties>
 
@@ -189,6 +189,12 @@
                 <version>${mockito.version}</version>
                 <scope>test</scope>
             </dependency>
+            <dependency>
+                <groupId>org.mockito</groupId>
+                <artifactId>mockito-inline</artifactId>
+                <version>${mockito.version}</version>
+                <scope>test</scope>
+            </dependency>
             <dependency>
                 <groupId>org.assertj</groupId>
                 <artifactId>assertj-core</artifactId>
@@ -207,18 +213,6 @@
                 <version>2.0.0.0</version>
                 <scope>test</scope>
             </dependency>
-            <dependency>
-                <groupId>org.powermock</groupId>
-                <artifactId>powermock-module-junit4</artifactId>
-                <version>${powermock.version}</version>
-                <scope>test</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.powermock</groupId>
-                <artifactId>powermock-api-mockito2</artifactId>
-                <version>${powermock.version}</version>
-                <scope>test</scope>
-            </dependency>
         </dependencies>
     </dependencyManagement>
 
@@ -271,15 +265,33 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>${maven.compiler.version}</version>
+                <executions>
+                    <execution>
+                        <id>default-compile</id>
+                        <configuration>
+                            <release>17</release>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>base-compile</id>
+                        <goals>
+                            <goal>compile</goal>
+                        </goals>
+                        <configuration>
+                            <excludes>
+                                <exclude>module-info.java</exclude>
+                            </excludes>
+                        </configuration>
+                    </execution>
+                </executions>
                 <configuration>
-                    <source>${java.source.version}</source>
-                    <target>${java.target.version}</target>
-                    <encoding>${java.encoding}</encoding>
+                    <release>8</release>
                 </configuration>
             </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
+                <version>${maven.surefire.version}</version>
                 <configuration>
                     <!-- CircleCI build workaround -->
                     <argLine>@{argLine} -Xms1024m -Xmx2048m</argLine>
@@ -394,6 +406,30 @@
                 </repository>
             </distributionManagement>
         </profile>
+        <profile>
+            <id>custom-test-runtime-version</id>
+            <activation>
+                <property>
+                    <name>surefire.jdk-toolchain-version</name>
+                </property>
+            </activation>
+            <build>
+                <pluginManagement>
+                    <plugins>
+                        <plugin>
+                            <groupId>org.apache.maven.plugins</groupId>
+                            <artifactId>maven-surefire-plugin</artifactId>
+                            <version>${maven.surefire.version}</version>
+                            <configuration>
+                                <jdkToolchain>
+                                    <version>${surefire.jdk-toolchain-version}</version>
+                                </jdkToolchain>
+                            </configuration>
+                        </plugin>
+                    </plugins>
+                </pluginManagement>
+            </build>
+        </profile>
     </profiles>
 
 </project>
diff --git a/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml b/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml
index e48d676f..2f538099 100755
--- a/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml
@@ -43,7 +43,7 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
-            <version>2.2.6.RELEASE</version>
+            <version>2.4.13</version>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -66,7 +66,7 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-surefire-plugin</artifactId>
                 <configuration>
-                    <forkMode>always</forkMode>
+                    <reuseForks>false</reuseForks>
                 </configuration>
             </plugin>
         </plugins>
diff --git a/sentinel-adapter/sentinel-web-servlet/pom.xml b/sentinel-adapter/sentinel-web-servlet/pom.xml
index 23186bf7..c8df0801 100755
--- a/sentinel-adapter/sentinel-web-servlet/pom.xml
+++ b/sentinel-adapter/sentinel-web-servlet/pom.xml
@@ -14,6 +14,7 @@
 
     <properties>
         <servlet.api.version>3.1.0</servlet.api.version>
+        <spring.boot.version>2.4.13</spring.boot.version>
     </properties>
 
     <dependencies>
@@ -37,13 +38,13 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
-            <version>1.5.17.RELEASE</version>
+            <version>${spring.boot.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
-            <version>1.5.17.RELEASE</version>
+            <version>${spring.boot.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/sentinel-cluster/sentinel-cluster-server-default/pom.xml b/sentinel-cluster/sentinel-cluster-server-default/pom.xml
index 12450b76..33928db4 100644
--- a/sentinel-cluster/sentinel-cluster-server-default/pom.xml
+++ b/sentinel-cluster/sentinel-cluster-server-default/pom.xml
@@ -41,16 +41,6 @@
             <artifactId>sentinel-datasource-nacos</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-module-junit4</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-api-mockito2</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
@@ -58,7 +48,7 @@
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
-            <artifactId>mockito-core</artifactId>
+            <artifactId>mockito-inline</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/sentinel-core/pom.xml b/sentinel-core/pom.xml
index 377e46ea..c120aef8 100755
--- a/sentinel-core/pom.xml
+++ b/sentinel-core/pom.xml
@@ -30,7 +30,7 @@
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
-            <artifactId>mockito-core</artifactId>
+            <artifactId>mockito-inline</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -43,16 +43,6 @@
             <artifactId>java-hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-module-junit4</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-api-mockito2</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
     <build>
         <plugins>
diff --git a/sentinel-extension/sentinel-datasource-eureka/pom.xml b/sentinel-extension/sentinel-datasource-eureka/pom.xml
index 12e3ce5d..d6e594eb 100644
--- a/sentinel-extension/sentinel-datasource-eureka/pom.xml
+++ b/sentinel-extension/sentinel-datasource-eureka/pom.xml
@@ -12,7 +12,8 @@
     <artifactId>sentinel-datasource-eureka</artifactId>
 
     <properties>
-        <spring.cloud.version>2.1.2.RELEASE</spring.cloud.version>
+        <spring.boot.version>2.6.1</spring.boot.version>
+        <spring.cloud.version>3.1.0</spring.cloud.version>
     </properties>
 
 
@@ -27,6 +28,12 @@
             <artifactId>fastjson</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.13.0</version>
+        </dependency>
+
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
@@ -42,7 +49,7 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
-            <version>${spring.cloud.version}</version>
+            <version>${spring.boot.version}</version>
             <scope>test</scope>
         </dependency>
 
diff --git a/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml b/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml
index 6e5b9483..6b88ef85 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 @@
     <packaging>jar</packaging>
 
     <properties>
-        <spring.cloud.version>2.0.0.RELEASE</spring.cloud.version>
+        <spring.boot.version>2.1.3.RELEASE</spring.boot.version>
+        <spring.cloud.version>2.1.9.RELEASE</spring.cloud.version>
     </properties>
 
     <dependencies>
@@ -44,7 +45,7 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
-            <version>${spring.cloud.version}</version>
+            <version>${spring.boot.version}</version>
             <scope>test</scope>
         </dependency>
 
@@ -58,7 +59,7 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
-            <version>${spring.cloud.version}</version>
+            <version>${spring.boot.version}</version>
             <scope>test</scope>
         </dependency>
 
diff --git a/sentinel-extension/sentinel-parameter-flow-control/pom.xml b/sentinel-extension/sentinel-parameter-flow-control/pom.xml
index 6145e301..4042396c 100644
--- a/sentinel-extension/sentinel-parameter-flow-control/pom.xml
+++ b/sentinel-extension/sentinel-parameter-flow-control/pom.xml
@@ -36,17 +36,7 @@
         </dependency>
         <dependency>
             <groupId>org.mockito</groupId>
-            <artifactId>mockito-core</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-module-junit4</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.powermock</groupId>
-            <artifactId>powermock-api-mockito2</artifactId>
+            <artifactId>mockito-inline</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>


Test patch:
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 00000000..2b06e151
--- /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<TimeUtil> mockTimeUtil() {
+        MockedStatic<TimeUtil> mocked = Mockito.mockStatic(TimeUtil.class);
+        mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
+        return mocked;
+    }
+
+    protected final void useActualTime(MockedStatic<TimeUtil> mocked) {
+        mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod();
+    }
+
+    protected final void setCurrentMillis(MockedStatic<TimeUtil> mocked, long cur) {
+        currentMillis = cur;
+        mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
+    }
+
+    protected final void sleep(MockedStatic<TimeUtil> mocked, long t) {
+        currentMillis += t;
+        mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
+    }
+
+    protected final void sleepSecond(MockedStatic<TimeUtil> 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 3a7e2e96..c9761cc1 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.rule.ClusterFlowRuleManager;
 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 class ConcurrentClusterFlowCheckerTest extends AbstractTimeBasedTest {
 
     @Test
     public void testEasyAcquireAndRelease() throws InterruptedException {
-        setCurrentMillis(System.currentTimeMillis());
-        FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(111L);
-        ArrayList<Long> 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<TimeUtil> mocked = super.mockTimeUtil()) {
+            setCurrentMillis(mocked, System.currentTimeMillis());
+            FlowRule rule = ClusterFlowRuleManager.getFlowRuleById(111L);
+            ArrayList<Long> 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<TimeUtil> 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 8ca4f97a..dd317270 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 class TokenCacheNodeManagerTest extends AbstractTimeBasedTest {
 
     @Test
     public void testPutTokenCacheNode() throws InterruptedException {
-        setCurrentMillis(System.currentTimeMillis());
+        try (MockedStatic<TimeUtil> 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<Long> 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<Long> 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 e618d7de..5ab847a8 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 class GlobalRequestLimiterTest extends AbstractTimeBasedTest {
 
     @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<TimeUtil> 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 0d3f95e6..9b9d7cca 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<TimeUtil> 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 e8c286bc..b7891767 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<TimeUtil> 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 82645877..f75858d4 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<Object, Double> topMap = new HashMap<Object, Double>();
-        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<TimeUtil> mocked = super.mockTimeUtil()) {
+            setCurrentMillis(mocked, System.currentTimeMillis());
+            Map<Object, Double> topMap = new HashMap<Object, Double>();
+            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 00000000..684499db
--- /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<TimeUtil> mockTimeUtil() {
+        MockedStatic<TimeUtil> mocked = Mockito.mockStatic(TimeUtil.class);
+        mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
+        return mocked;
+    }
+
+    protected final void useActualTime(MockedStatic<TimeUtil> mocked) {
+        mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod();
+    }
+
+    protected final void setCurrentMillis(MockedStatic<TimeUtil> mocked, long cur) {
+        currentMillis = cur;
+        mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
+    }
+
+    protected final void sleep(MockedStatic<TimeUtil> mocked, long t) {
+        currentMillis += t;
+        mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
+    }
+
+    protected final void sleepSecond(MockedStatic<TimeUtil> 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 d4458a0d..00000000
--- 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 6e8bab4d..00000000
--- 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/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 f7da610f..5cc17a27 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.metric.extension.MetricExtensionProvider;
 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<TimeUtil> 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<TimeUtil> 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 ebf49077..ffaf6fa9 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.CircuitBreake
 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 class CircuitBreakingIntegrationTest extends AbstractTimeBasedTest {
 
     @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<TimeUtil> 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<TimeUtil> 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<TimeUtil> 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<CircuitBreaker> breakers, int target) {
         int state = 0;
         for (CircuitBreaker breaker : breakers) {
@@ -249,48 +257,50 @@ public class CircuitBreakingIntegrationTest extends AbstractTimeBasedTest {
         }
         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<TimeUtil> 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 e9d7178d..d71173af 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 static org.junit.Assert.assertTrue;
 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.RuleConstant;
 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<DegradeRule>());
@@ -48,38 +50,40 @@ public class ExceptionCircuitBreakerTest extends AbstractTimeBasedTest {
 
     @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<TimeUtil> 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 66dd4691..7f9f3f17 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.RuleConstant;
 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 class ResponseTimeCircuitBreakerTest extends AbstractTimeBasedTest {
 
     @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<TimeUtil> 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 62cf908b..1a2f8c61 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.junit.Assert.assertTrue;
 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<TimeUtil> 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 5d07531d..52b4d1cd 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 @@ package com.alibaba.csp.sentinel.slots.block.flow.tokenbucket;
 
 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 class TokenBucketTest extends AbstractTimeBasedTest {
 
     @Test
     public void testForDefaultTokenBucket() throws InterruptedException {
-        long unitProduceNum = 1;
-        long maxTokenNum = 2;
-        long intervalInMs = 1000;
-        long testStart = System.currentTimeMillis();
-        setCurrentMillis(testStart);
+        try (MockedStatic<TimeUtil> 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<TimeUtil> 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 b3ac551b..cdf58a92 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 @@ package com.alibaba.csp.sentinel.slots.statistic.base;
 
 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<AtomicInteger> leapArray = new LeapArray<AtomicInteger>(sampleCount, intervalInMs) {
-            @Override
-            public AtomicInteger newEmptyBucket(long time) {
-                return new AtomicInteger(0);
-            }
+        try (MockedStatic<TimeUtil> mocked = super.mockTimeUtil()) {
+            int windowLengthInMs = 100;
+            int intervalInMs = 1000;
+            int sampleCount = intervalInMs / windowLengthInMs;
+            LeapArray<AtomicInteger> leapArray = new LeapArray<AtomicInteger>(sampleCount, intervalInMs) {
+                @Override
+                public AtomicInteger newEmptyBucket(long time) {
+                    return new AtomicInteger(0);
+                }
+
+                @Override
+                protected WindowWrap<AtomicInteger> resetWindowTo(WindowWrap<AtomicInteger> windowWrap, long startTime) {
+                    windowWrap.resetTo(startTime);
+                    windowWrap.value().set(0);
+                    return windowWrap;
+                }
+            };
 
-            @Override
-            protected WindowWrap<AtomicInteger> resetWindowTo(WindowWrap<AtomicInteger> windowWrap, long startTime) {
-                windowWrap.resetTo(startTime);
-                windowWrap.value().set(0);
-                return windowWrap;
+            WindowWrap<AtomicInteger> expected1 = leapArray.currentWindow();
+            expected1.value().addAndGet(1);
+            sleep(mocked, windowLengthInMs);
+            WindowWrap<AtomicInteger> 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<AtomicInteger> expected1 = leapArray.currentWindow();
-        expected1.value().addAndGet(1);
-        sleep(windowLengthInMs);
-        WindowWrap<AtomicInteger> 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 08094f14..968ba861 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.test.AbstractTimeBasedTest;
 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<TimeUtil> mocked = super.mockTimeUtil()) {
+            long currentTime = System.currentTimeMillis();
+            setCurrentMillis(mocked, currentTime);
+            OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs);
 
-        WindowWrap<MetricBucket> 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<MetricBucket> 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<TimeUtil> mocked = super.mockTimeUtil()) {
+            OccupiableBucketLeapArray leapArray = new OccupiableBucketLeapArray(sampleCount, intervalInMs);
+            long currentTime = System.currentTimeMillis();
+            setCurrentMillis(mocked, currentTime);
 
-        WindowWrap<MetricBucket> currentWindow = leapArray.currentWindow(currentTime);
-        currentWindow.value().addPass(1);
-        assertEquals(currentWindow.value().pass(), 1L);
+            WindowWrap<MetricBucket> 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<MetricBucket> values = leapArray.values(currentTime + windowLengthInMs);
-        assertEquals(values.size(), 2);
+            leapArray.currentWindow(currentTime + windowLengthInMs);
+            List<MetricBucket> 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<TimeUtil> 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<MetricBucket> values = leapArray.values(time + windowLengthInMs);
-        for (MetricBucket bucket : values) {
-            sum += bucket.pass();
+            leapArray.currentWindow(time + windowLengthInMs);
+            long sum = 0;
+            List<MetricBucket> 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<MetricBucket> 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<TimeUtil> 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<MetricBucket> 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<MetricBucket> 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<MetricBucket> 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 e22d1a64..4844924d 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<TimeUtil> mockTimeUtil() {
+        MockedStatic<TimeUtil> 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<TimeUtil> mocked) {
+        mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod();
     }
 
-    protected final void setCurrentMillis(long cur) {
+    protected final void setCurrentMillis(MockedStatic<TimeUtil> 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<TimeUtil> 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<TimeUtil> mocked, long timeSec) {
+        sleep(mocked, timeSec * 1000);
     }
     
-    protected final boolean entryAndSleepFor(String res, int sleepMs) {
+    protected final boolean entryAndSleepFor(MockedStatic<TimeUtil> 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 @@ public abstract class AbstractTimeBasedTest {
         return true;
     }
 
-    protected final boolean entryWithErrorIfPresent(String res, Exception ex) {
+    protected final boolean entryWithErrorIfPresent(MockedStatic<TimeUtil> 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 4b4bb527..245890dd 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 @@ import static org.assertj.core.api.Assertions.fail;
 /**
  * @author sea
  */
+@Ignore
 public class SentinelAnnotationInterceptorIntegrationTest {
 
     static SeContainer container;
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 00000000..6a6358a9
--- /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<TimeUtil> mockTimeUtil() {
+        MockedStatic<TimeUtil> mocked = Mockito.mockStatic(TimeUtil.class);
+        mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
+        return mocked;
+    }
+
+    protected final void useActualTime(MockedStatic<TimeUtil> mocked) {
+        mocked.when(TimeUtil::currentTimeMillis).thenCallRealMethod();
+    }
+
+    protected final void setCurrentMillis(MockedStatic<TimeUtil> mocked, long cur) {
+        currentMillis = cur;
+        mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
+    }
+
+    protected final void sleep(MockedStatic<TimeUtil> mocked, long t) {
+        currentMillis += t;
+        mocked.when(TimeUtil::currentTimeMillis).thenReturn(currentMillis);
+    }
+
+    protected final void sleepSecond(MockedStatic<TimeUtil> 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 581c8522..92fd2d3b 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.EntryType;
 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<Object, AtomicLong>(4000));
-        metric.getRuleTokenCounterMap().put(rule,
-            new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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<TimeUtil> 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<Object, AtomicLong>(4000));
+            metric.getRuleTokenCounterMap().put(rule,
+                    new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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<Object, AtomicLong>(4000));
-        metric.getRuleTokenCounterMap().put(rule,
-            new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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<TimeUtil> 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<Object, AtomicLong>(4000));
+            metric.getRuleTokenCounterMap().put(rule,
+                    new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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<Object, AtomicLong>(4000));
-        metric.getRuleTokenCounterMap().put(rule,
-            new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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<TimeUtil> 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<Object, AtomicLong>(4000));
+            metric.getRuleTokenCounterMap().put(rule,
+                    new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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<Object, AtomicLong>(4000));
-        metric.getRuleTokenCounterMap().put(rule,
-            new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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<TimeUtil> 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<Object, AtomicLong>(4000));
+            metric.getRuleTokenCounterMap().put(rule,
+                    new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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<Object, AtomicLong>(4000));
-        metric.getRuleTokenCounterMap().put(rule,
-            new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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<TimeUtil> 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<Object, AtomicLong>(4000));
+            metric.getRuleTokenCounterMap().put(rule,
+                    new ConcurrentLinkedHashMapWrapper<Object, AtomicLong>(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 5ce74712..00000000
--- 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);
-    }
-}