diff --git a/.travis.yml b/.travis.yml index 59e27d024c..5c3f897009 100755 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,8 @@ matrix: - env: BUILD_JDK=ORACLE_JDK_11 after_success: - - bash <(curl -s https://codecov.io/bash) \ No newline at end of file + - bash <(curl -s https://codecov.io/bash) + +cache: + directories: + - $HOME/.m2/ diff --git a/pom.xml b/pom.xml index e607a910b1..6fcba990af 100755 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,7 @@ 4.12 2.21.0 + 3.1.5 UTF-8 @@ -155,6 +156,18 @@ ${mockito.version} test + + org.awaitility + awaitility + ${awaitility.version} + test + + + org.hamcrest + java-hamcrest + 2.0.0.0 + test + diff --git a/sentinel-core/pom.xml b/sentinel-core/pom.xml index b544fa65bc..1d674c5d41 100755 --- a/sentinel-core/pom.xml +++ b/sentinel-core/pom.xml @@ -16,12 +16,28 @@ junit junit - test + + + org.hamcrest + hamcrest-core + + + org.hamcrest + hamcrest-libray + + org.mockito mockito-core - test + + + org.awaitility + awaitility + + + org.hamcrest + java-hamcrest diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/AsyncEntryIntegrationTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/AsyncEntryIntegrationTest.java index 3b984421bd..7da7b39f35 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/AsyncEntryIntegrationTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/AsyncEntryIntegrationTest.java @@ -15,22 +15,24 @@ */ package com.alibaba.csp.sentinel; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - import com.alibaba.csp.sentinel.context.ContextTestUtil; import com.alibaba.csp.sentinel.context.ContextUtil; import com.alibaba.csp.sentinel.node.DefaultNode; import com.alibaba.csp.sentinel.node.Node; import com.alibaba.csp.sentinel.slots.block.BlockException; - +import org.hamcrest.CoreMatchers; import org.junit.After; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.fail; /** * Integration test for asynchronous entry, including common scenarios. @@ -175,37 +177,59 @@ public void testAsyncEntryUnderSyncEntry() throws Exception { ContextUtil.exit(); } - TimeUnit.SECONDS.sleep(15); + // we keep the original timeout of 15 seconds although the test should + // complete in less than 6 seconds + await().timeout(15, TimeUnit.SECONDS) + .until(new Callable() { + @Override + public DefaultNode call() throws Exception { + return queryInvocationTree(false); + } + }, CoreMatchers.notNullValue()); - testInvocationTreeCorrect(); + queryInvocationTree(true); } - private void testInvocationTreeCorrect() { + private DefaultNode queryInvocationTree(boolean check) { DefaultNode root = Constants.ROOT; - DefaultNode entranceNode = shouldHasChildFor(root, contextName); - DefaultNode testTopNode = shouldHasChildFor(entranceNode, "test-top"); - DefaultNode testAsyncNode = shouldHasChildFor(testTopNode, "test-async"); - shouldHasChildFor(testTopNode, "test-sync"); - shouldHasChildFor(testAsyncNode, "test-sync-in-async"); - DefaultNode anotherAsyncInAsyncNode = shouldHasChildFor(testAsyncNode, "test-another-async"); - shouldHasChildFor(anotherAsyncInAsyncNode, "test-another-in-async"); + DefaultNode entranceNode = shouldHasChildFor(root, contextName, check); + DefaultNode testTopNode = shouldHasChildFor(entranceNode, "test-top", check); + DefaultNode testAsyncNode = shouldHasChildFor(testTopNode, "test-async", check); + shouldHasChildFor(testTopNode, "test-sync", check); + shouldHasChildFor(testAsyncNode, "test-sync-in-async", check); + DefaultNode anotherAsyncInAsyncNode = shouldHasChildFor(testAsyncNode, "test-another-async", check); + return shouldHasChildFor(anotherAsyncInAsyncNode, "test-another-in-async", check); } - private DefaultNode shouldHasChildFor(DefaultNode root, String resourceName) { + private DefaultNode shouldHasChildFor(DefaultNode root, String resourceName, boolean check) { + if (root == null) { + if (check) { + fail("Root node should not be empty"); + } else { + return null; + } + } Set nodeSet = root.getChildList(); if (nodeSet == null || nodeSet.isEmpty()) { - fail("Child nodes should not be empty: " + root.getId().getName()); + if (check) { + fail("Child nodes should not be empty: " + root.getId().getName()); + } else { + return null; + } } for (Node node : nodeSet) { if (node instanceof DefaultNode) { - DefaultNode dn = (DefaultNode)node; + DefaultNode dn = (DefaultNode) node; if (dn.getId().getName().equals(resourceName)) { return dn; } } } - fail(String.format("The given node <%s> does not have child for resource <%s>", - root.getId().getName(), resourceName)); + + if (check) { + fail(String.format("The given node <%s> does not have child for resource <%s>", + root.getId().getName(), resourceName)); + } return null; } diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/base/metric/MetricsLeapArrayTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/base/metric/MetricsLeapArrayTest.java index 99e7e263a9..f6f2b29a2b 100755 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/base/metric/MetricsLeapArrayTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/base/metric/MetricsLeapArrayTest.java @@ -203,7 +203,7 @@ public void testListWindowsNewBucket() throws Exception { windowWraps.add(leapArray.currentWindow(time)); windowWraps.add(leapArray.currentWindow(time + windowLengthInMs)); - Thread.sleep(intervalInSec * 1000 + windowLengthInMs * 3); + Thread.sleep(intervalInMs + windowLengthInMs * 3); List> list = leapArray.list(); for (WindowWrap wrap : list) { diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/FlowPartialIntegrationTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/FlowPartialIntegrationTest.java index 5da8f30b52..a507b5aff6 100755 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/FlowPartialIntegrationTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/flow/FlowPartialIntegrationTest.java @@ -16,6 +16,7 @@ package com.alibaba.csp.sentinel.slots.block.flow; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.util.Arrays; import java.util.Collections; @@ -57,8 +58,8 @@ public void testQPSGrade() { } } - @Test - public void testThreadGrade() throws InterruptedException { + @Test(expected = BlockException.class) + public void testThreadGrade() throws InterruptedException, BlockException { FlowRule flowRule = new FlowRule(); flowRule.setResource("testThreadGrade"); flowRule.setGrade(RuleConstant.FLOW_GRADE_THREAD); @@ -73,17 +74,15 @@ public void run() { Entry e = null; try { e = SphU.entry("testThreadGrade"); - assertTrue(true); synchronized (sequence) { System.out.println("notify up"); sequence.notify(); } - Thread.sleep(1000); + Thread.sleep(100); } catch (BlockException e1) { - assertTrue(false); + fail("Should had failed"); } catch (InterruptedException e1) { - assertTrue(false); - e1.printStackTrace(); + fail("Should had failed"); } e.exit(); } @@ -92,20 +91,14 @@ public void run() { Thread thread = new Thread(runnable); thread.start(); - Entry e = null; synchronized (sequence) { System.out.println("sleep"); sequence.wait(); System.out.println("wake up"); } - try { - e = SphU.entry("testThreadGrade"); - assertTrue(false); - } catch (BlockException e1) { - assertTrue(true); - } - System.out.println("done"); + SphU.entry("testThreadGrade"); + System.out.println("done"); } @Test @@ -129,10 +122,9 @@ public void testOriginFlowRule() { Entry e = null; try { e = SphU.entry("testOriginFlowRule"); - assertTrue(false); + fail("Should had failed"); } catch (BlockException e1) { e1.printStackTrace(); - assertTrue(true); } assertTrue(e == null); @@ -142,10 +134,8 @@ public void testOriginFlowRule() { e = null; try { e = SphU.entry("testOriginFlowRule"); - assertTrue(true); } catch (BlockException e1) { - e1.printStackTrace(); - assertTrue(false); + fail("Should had failed"); } e.exit(); @@ -165,17 +155,14 @@ public void testFlowRule_other() { Entry e = null; try { e = SphU.entry("testOther"); - assertTrue(true); } catch (BlockException e1) { - e1.printStackTrace(); - assertTrue(false); + e1.printStackTrace();fail("Should had failed"); } if (e != null) { - assertTrue(true); e.exit(); } else { - assertTrue(false); + fail("Should had failed"); } } @@ -194,10 +181,9 @@ public void testStrategy() { Entry e = null; try { e = SphU.entry("testStrategy"); - assertTrue(false); + fail("Should had failed"); } catch (BlockException e1) { e1.printStackTrace(); - assertTrue(true); } ContextUtil.exit(); @@ -215,10 +201,9 @@ public void testStrategy() { ContextUtil.enter("entry1"); try { e = SphU.entry("testStrategy"); - assertTrue(true); } catch (BlockException e1) { e1.printStackTrace(); - assertTrue(false); + fail("Should had failed"); } e.exit(); ContextUtil.exit(); @@ -238,10 +223,9 @@ public void testStrategy_chain() { ContextUtil.enter("entry1"); try { e = SphU.entry("entry2"); - assertTrue(false); + fail("Should had failed"); } catch (BlockException e1) { e1.printStackTrace(); - assertTrue(true); } ContextUtil.exit(); @@ -250,13 +234,11 @@ public void testStrategy_chain() { ContextUtil.enter("entry3"); try { e = SphU.entry("entry2"); - assertTrue(true); } catch (BlockException e1) { - assertTrue(false); + fail("Should had failed"); } e.exit(); ContextUtil.exit(); - } } 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 7482f489b8..6e9f7d0854 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 @@ -23,7 +23,6 @@ import org.junit.Test; import com.alibaba.csp.sentinel.node.Node; -import com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController; /** * @author jialiang.linjl @@ -49,7 +48,7 @@ public void testWarmUp() throws InterruptedException { when(node.previousPassQps()).thenReturn(10L); for (int i = 0; i < 100; i++) { - Thread.sleep(1000); + Thread.sleep(100); warmupController.canPass(node, 1); } when(node.passQps()).thenReturn(8L); diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtilTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtilTest.java index b2b769d0bf..fd9e9f4318 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtilTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtilTest.java @@ -1,12 +1,18 @@ package com.alibaba.csp.sentinel.slots.logger; import java.io.File; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; import com.alibaba.csp.sentinel.log.LogBase; import com.alibaba.csp.sentinel.log.RecordLog; +import org.hamcrest.CoreMatchers; +import org.hamcrest.Matchers; +import org.hamcrest.io.FileMatchers; import org.junit.Test; +import static org.awaitility.Awaitility.await; import static org.junit.Assert.*; /** @@ -17,9 +23,15 @@ public class EagleEyeLogUtilTest { @Test public void testWriteLog() throws Exception { EagleEyeLogUtil.log("resourceName", "BlockException", "app1", "origin", 1); - Thread.sleep(1100); - String file = RecordLog.getLogBaseDir() + EagleEyeLogUtil.FILE_NAME; - assertTrue(new File(file).exists()); + + final File file = new File(RecordLog.getLogBaseDir() + EagleEyeLogUtil.FILE_NAME); + await().timeout(2, TimeUnit.SECONDS) + .until(new Callable() { + @Override + public File call() throws Exception { + return file; + } + }, FileMatchers.anExistingFile()); } @Test @@ -29,8 +41,14 @@ public void testChangeLogBase() throws Exception { System.setProperty(LogBase.LOG_DIR, newLogBase); EagleEyeLogUtil.log("resourceName", "BlockException", "app1", "origin", 1); - Thread.sleep(1100); - String file = RecordLog.getLogBaseDir() + EagleEyeLogUtil.FILE_NAME; - assertTrue(new File(file).exists()); + + final File file = new File(RecordLog.getLogBaseDir() + EagleEyeLogUtil.FILE_NAME); + await().timeout(2, TimeUnit.SECONDS) + .until(new Callable() { + @Override + public File call() throws Exception { + return file; + } + }, FileMatchers.anExistingFile()); } } \ No newline at end of file diff --git a/sentinel-extension/sentinel-datasource-redis/pom.xml b/sentinel-extension/sentinel-datasource-redis/pom.xml index 34b720f76f..3fbd5d5648 100644 --- a/sentinel-extension/sentinel-datasource-redis/pom.xml +++ b/sentinel-extension/sentinel-datasource-redis/pom.xml @@ -34,7 +34,10 @@ junit junit - test + + + org.awaitility + awaitility com.alibaba diff --git a/sentinel-extension/sentinel-datasource-redis/src/test/java/com/alibaba/csp/sentinel/datasource/redis/SentinelModeRedisDataSourceTest.java b/sentinel-extension/sentinel-datasource-redis/src/test/java/com/alibaba/csp/sentinel/datasource/redis/SentinelModeRedisDataSourceTest.java index 054e7dc3fb..ee43287ad9 100644 --- a/sentinel-extension/sentinel-datasource-redis/src/test/java/com/alibaba/csp/sentinel/datasource/redis/SentinelModeRedisDataSourceTest.java +++ b/sentinel-extension/sentinel-datasource-redis/src/test/java/com/alibaba/csp/sentinel/datasource/redis/SentinelModeRedisDataSourceTest.java @@ -27,10 +27,15 @@ import io.lettuce.core.RedisClient; import io.lettuce.core.RedisURI; import io.lettuce.core.api.sync.RedisCommands; +import org.hamcrest.Matchers; import org.junit.*; import java.util.List; import java.util.Random; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import static org.awaitility.Awaitility.await; /** * Redis redisSentinel mode test cases for {@link RedisDataSource}. @@ -79,14 +84,16 @@ public void testConnectToSentinelAndPubMsgSuccess() { subCommands.set(ruleKey, flowRulesJson); subCommands.publish(channel, flowRulesJson); subCommands.exec(); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + + await().timeout(2, TimeUnit.SECONDS) + .until(new Callable>() { + @Override + public List call() throws Exception { + return FlowRuleManager.getRules(); + } + }, Matchers.hasSize(1)); + List rules = FlowRuleManager.getRules(); - Assert.assertEquals(1, rules.size()); - rules = FlowRuleManager.getRules(); Assert.assertEquals(rules.get(0).getMaxQueueingTimeMs(), maxQueueingTimeMs); String value = subCommands.get(ruleKey); List flowRulesValuesInRedis = buildFlowConfigParser().convert(value); diff --git a/sentinel-extension/sentinel-datasource-redis/src/test/java/com/alibaba/csp/sentinel/datasource/redis/StandaloneRedisDataSourceTest.java b/sentinel-extension/sentinel-datasource-redis/src/test/java/com/alibaba/csp/sentinel/datasource/redis/StandaloneRedisDataSourceTest.java index 408d0bc443..9a9ba63d27 100644 --- a/sentinel-extension/sentinel-datasource-redis/src/test/java/com/alibaba/csp/sentinel/datasource/redis/StandaloneRedisDataSourceTest.java +++ b/sentinel-extension/sentinel-datasource-redis/src/test/java/com/alibaba/csp/sentinel/datasource/redis/StandaloneRedisDataSourceTest.java @@ -31,6 +31,7 @@ import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; import io.lettuce.core.pubsub.api.sync.RedisPubSubCommands; +import org.hamcrest.Matchers; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -39,6 +40,10 @@ import java.io.IOException; import java.util.List; import java.util.Random; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +import static org.awaitility.Awaitility.await; /** * Redis stand-alone mode test cases for {@link RedisDataSource}. @@ -92,11 +97,15 @@ public void testPubMsgAndReceiveSuccess() { subCommands.set(ruleKey, flowRules); subCommands.publish(channel, flowRules); subCommands.exec(); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + + await().timeout(2, TimeUnit.SECONDS) + .until(new Callable>() { + @Override + public List call() throws Exception { + return FlowRuleManager.getRules(); + } + }, Matchers.hasSize(1)); + rules = FlowRuleManager.getRules(); Assert.assertEquals(rules.get(0).getMaxQueueingTimeMs(), maxQueueingTimeMs); String value = subCommands.get(ruleKey); diff --git a/sentinel-extension/sentinel-datasource-zookeeper/pom.xml b/sentinel-extension/sentinel-datasource-zookeeper/pom.xml index e4a247271f..343d97568e 100644 --- a/sentinel-extension/sentinel-datasource-zookeeper/pom.xml +++ b/sentinel-extension/sentinel-datasource-zookeeper/pom.xml @@ -46,7 +46,10 @@ junit junit - test + + + org.awaitility + awaitility org.apache.curator diff --git a/sentinel-extension/sentinel-datasource-zookeeper/src/test/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSourceTest.java b/sentinel-extension/sentinel-datasource-zookeeper/src/test/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSourceTest.java index 2425b7c275..14a8d767dd 100644 --- a/sentinel-extension/sentinel-datasource-zookeeper/src/test/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSourceTest.java +++ b/sentinel-extension/sentinel-datasource-zookeeper/src/test/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSourceTest.java @@ -2,6 +2,8 @@ import java.util.Collections; import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; import com.alibaba.csp.sentinel.datasource.Converter; import com.alibaba.csp.sentinel.datasource.ReadableDataSource; @@ -19,6 +21,7 @@ import org.apache.zookeeper.data.Stat; import org.junit.Test; +import static org.awaitility.Awaitility.await; import static org.junit.Assert.*; /** @@ -68,10 +71,16 @@ private void publishThenTestFor(CuratorFramework zkClient, String path, String r String ruleString = JSON.toJSONString(Collections.singletonList(rule)); zkClient.setData().forPath(path, ruleString.getBytes()); - Thread.sleep(5000); + await().timeout(5, TimeUnit.SECONDS) + .until(new Callable() { + @Override + public Boolean call() throws Exception { + List rules = FlowRuleManager.getRules(); + return rules != null && !rules.isEmpty(); + } + }); List rules = FlowRuleManager.getRules(); - assertTrue(rules != null && !rules.isEmpty()); boolean exists = false; for (FlowRule r : rules) { if (resourceName.equals(r.getResource())) {