- Apply awaitility to core tests - Cache maven local repo in Travismaster
@@ -13,4 +13,8 @@ matrix: | |||
- env: BUILD_JDK=ORACLE_JDK_11 | |||
after_success: | |||
- bash <(curl -s https://codecov.io/bash) | |||
- bash <(curl -s https://codecov.io/bash) | |||
cache: | |||
directories: | |||
- $HOME/.m2/ |
@@ -46,6 +46,7 @@ | |||
<!-- Test libs --> | |||
<junit.version>4.12</junit.version> | |||
<mockito.version>2.21.0</mockito.version> | |||
<awaitility.version>3.1.5</awaitility.version> | |||
<!-- Build --> | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
@@ -155,6 +156,18 @@ | |||
<version>${mockito.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.awaitility</groupId> | |||
<artifactId>awaitility</artifactId> | |||
<version>${awaitility.version}</version> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hamcrest</groupId> | |||
<artifactId>java-hamcrest</artifactId> | |||
<version>2.0.0.0</version> | |||
<scope>test</scope> | |||
</dependency> | |||
</dependencies> | |||
</dependencyManagement> | |||
@@ -16,12 +16,28 @@ | |||
<dependency> | |||
<groupId>junit</groupId> | |||
<artifactId>junit</artifactId> | |||
<scope>test</scope> | |||
<exclusions> | |||
<exclusion> | |||
<groupId>org.hamcrest</groupId> | |||
<artifactId>hamcrest-core</artifactId> | |||
</exclusion> | |||
<exclusion> | |||
<groupId>org.hamcrest</groupId> | |||
<artifactId>hamcrest-libray</artifactId> | |||
</exclusion> | |||
</exclusions> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.mockito</groupId> | |||
<artifactId>mockito-core</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.awaitility</groupId> | |||
<artifactId>awaitility</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.hamcrest</groupId> | |||
<artifactId>java-hamcrest</artifactId> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
@@ -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 class AsyncEntryIntegrationTest { | |||
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<DefaultNode>() { | |||
@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<Node> 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; | |||
} | |||
@@ -203,7 +203,7 @@ public class MetricsLeapArrayTest { | |||
windowWraps.add(leapArray.currentWindow(time)); | |||
windowWraps.add(leapArray.currentWindow(time + windowLengthInMs)); | |||
Thread.sleep(intervalInSec * 1000 + windowLengthInMs * 3); | |||
Thread.sleep(intervalInMs + windowLengthInMs * 3); | |||
List<WindowWrap<MetricBucket>> list = leapArray.list(); | |||
for (WindowWrap<MetricBucket> wrap : list) { | |||
@@ -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 class FlowPartialIntegrationTest { | |||
} | |||
} | |||
@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 class FlowPartialIntegrationTest { | |||
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 class FlowPartialIntegrationTest { | |||
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 class FlowPartialIntegrationTest { | |||
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 class FlowPartialIntegrationTest { | |||
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 class FlowPartialIntegrationTest { | |||
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 class FlowPartialIntegrationTest { | |||
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 class FlowPartialIntegrationTest { | |||
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 class FlowPartialIntegrationTest { | |||
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 class FlowPartialIntegrationTest { | |||
ContextUtil.enter("entry3"); | |||
try { | |||
e = SphU.entry("entry2"); | |||
assertTrue(true); | |||
} catch (BlockException e1) { | |||
assertTrue(false); | |||
fail("Should had failed"); | |||
} | |||
e.exit(); | |||
ContextUtil.exit(); | |||
} | |||
} |
@@ -23,7 +23,6 @@ import static org.mockito.Mockito.when; | |||
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 class WarmUpControllerTest { | |||
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); | |||
@@ -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<File>() { | |||
@Override | |||
public File call() throws Exception { | |||
return file; | |||
} | |||
}, FileMatchers.anExistingFile()); | |||
} | |||
@Test | |||
@@ -29,8 +41,14 @@ public class EagleEyeLogUtilTest { | |||
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<File>() { | |||
@Override | |||
public File call() throws Exception { | |||
return file; | |||
} | |||
}, FileMatchers.anExistingFile()); | |||
} | |||
} |
@@ -34,7 +34,10 @@ | |||
<dependency> | |||
<groupId>junit</groupId> | |||
<artifactId>junit</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.awaitility</groupId> | |||
<artifactId>awaitility</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.alibaba</groupId> | |||
@@ -27,10 +27,15 @@ import com.alibaba.fastjson.TypeReference; | |||
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 class SentinelModeRedisDataSourceTest { | |||
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<List<FlowRule>>() { | |||
@Override | |||
public List<FlowRule> call() throws Exception { | |||
return FlowRuleManager.getRules(); | |||
} | |||
}, Matchers.hasSize(1)); | |||
List<FlowRule> rules = FlowRuleManager.getRules(); | |||
Assert.assertEquals(1, rules.size()); | |||
rules = FlowRuleManager.getRules(); | |||
Assert.assertEquals(rules.get(0).getMaxQueueingTimeMs(), maxQueueingTimeMs); | |||
String value = subCommands.get(ruleKey); | |||
List<FlowRule> flowRulesValuesInRedis = buildFlowConfigParser().convert(value); | |||
@@ -31,6 +31,7 @@ import io.lettuce.core.RedisURI; | |||
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 org.junit.Test; | |||
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 class StandaloneRedisDataSourceTest { | |||
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<List<FlowRule>>() { | |||
@Override | |||
public List<FlowRule> call() throws Exception { | |||
return FlowRuleManager.getRules(); | |||
} | |||
}, Matchers.hasSize(1)); | |||
rules = FlowRuleManager.getRules(); | |||
Assert.assertEquals(rules.get(0).getMaxQueueingTimeMs(), maxQueueingTimeMs); | |||
String value = subCommands.get(ruleKey); | |||
@@ -46,7 +46,10 @@ | |||
<dependency> | |||
<groupId>junit</groupId> | |||
<artifactId>junit</artifactId> | |||
<scope>test</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.awaitility</groupId> | |||
<artifactId>awaitility</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.curator</groupId> | |||
@@ -2,6 +2,8 @@ package com.alibaba.csp.sentinel.datasource.zookeeper; | |||
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.CreateMode; | |||
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 @@ public class ZookeeperDataSourceTest { | |||
String ruleString = JSON.toJSONString(Collections.singletonList(rule)); | |||
zkClient.setData().forPath(path, ruleString.getBytes()); | |||
Thread.sleep(5000); | |||
await().timeout(5, TimeUnit.SECONDS) | |||
.until(new Callable<Boolean>() { | |||
@Override | |||
public Boolean call() throws Exception { | |||
List<FlowRule> rules = FlowRuleManager.getRules(); | |||
return rules != null && !rules.isEmpty(); | |||
} | |||
}); | |||
List<FlowRule> rules = FlowRuleManager.getRules(); | |||
assertTrue(rules != null && !rules.isEmpty()); | |||
boolean exists = false; | |||
for (FlowRule r : rules) { | |||
if (resourceName.equals(r.getResource())) { | |||