From 88b031c647ab17c0db902197006742c29fa47be8 Mon Sep 17 00:00:00 2001 From: Kugaaa Date: Fri, 3 Nov 2023 14:59:08 +0800 Subject: [PATCH] =?UTF-8?q?feature=20=E8=B6=85=E6=97=B6=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=AF=AB=E7=A7=92=20decl=20springboot=20UT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...xWaitMillisecondsELDeclSpringbootTest.java | 204 ++++++++++++++++++ .../test/maxWaitMilliseconds/cmp/ACmp.java | 21 ++ .../test/maxWaitMilliseconds/cmp/BCmp.java | 21 ++ .../test/maxWaitMilliseconds/cmp/CCmp.java | 21 ++ .../test/maxWaitMilliseconds/cmp/DCmp.java | 26 +++ .../test/maxWaitMilliseconds/cmp/FCmp.java | 18 ++ .../test/maxWaitMilliseconds/cmp/SCmp.java | 18 ++ .../test/maxWaitMilliseconds/cmp/WCmp.java | 31 +++ .../test/maxWaitMilliseconds/cmp/XCmp.java | 23 ++ .../application.properties | 1 + .../resources/maxWaitMilliseconds/flow.el.xml | 110 ++++++++++ 11 files changed, 494 insertions(+) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/MaxWaitMillisecondsELDeclSpringbootTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/CCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/DCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/FCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/SCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/WCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/XCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/maxWaitMilliseconds/application.properties create mode 100644 liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/maxWaitMilliseconds/flow.el.xml diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/MaxWaitMillisecondsELDeclSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/MaxWaitMillisecondsELDeclSpringbootTest.java new file mode 100644 index 000000000..61b5f4234 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/MaxWaitMillisecondsELDeclSpringbootTest.java @@ -0,0 +1,204 @@ +package com.yomahub.liteflow.test.maxWaitMilliseconds; + +import com.yomahub.liteflow.builder.LiteFlowNodeBuilder; +import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder; +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.enums.NodeTypeEnum; +import com.yomahub.liteflow.exception.WhenTimeoutException; +import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.slot.DefaultContext; +import com.yomahub.liteflow.test.BaseTest; +import com.yomahub.liteflow.test.maxWaitMilliseconds.cmp.ACmp; +import com.yomahub.liteflow.test.maxWaitMilliseconds.cmp.BCmp; +import com.yomahub.liteflow.test.maxWaitMilliseconds.cmp.CCmp; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import javax.annotation.Resource; +import java.util.concurrent.TimeoutException; + +import static com.yomahub.liteflow.test.maxWaitSeconds.cmp.DCmp.CONTENT_KEY; + +/** + * Spring Boot 环境下超时控制测试 - maxWaitMilliseconds + * + * @author Kugaaa + * @since 2.11.1 + */ +@ExtendWith(SpringExtension.class) +@TestPropertySource(value = "classpath:/maxWaitMilliseconds/application.properties") +@SpringBootTest(classes = MaxWaitMillisecondsELDeclSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({"com.yomahub.liteflow.test.maxWaitMilliseconds.cmp"}) +public class MaxWaitMillisecondsELDeclSpringbootTest extends BaseTest { + + @Resource + private FlowExecutor flowExecutor; + + // 测试 THEN 的超时情况 + @Test + public void testThen1() { + assertTimeout("then1"); + } + + // 测试 THEN 的非超时情况 + @Test + public void testThen2() { + assertNotTimeout("then2"); + } + + // 测试 When 的超时情况 + @Test + public void testWhen1() { + // WHEN 抛出的是 WhenTimeoutException + assertWhenTimeout("when1"); + } + + // 测试 WHEN 的非超时情况 + @Test + public void testWhen2() { + assertNotTimeout("when2"); + } + + // 测试 FOR 的超时情况 + @Test + public void testFor1() { + assertTimeout("for1"); + } + + // 测试 FOR 的非超时情况 + @Test + public void testFor2() { + assertNotTimeout("for2"); + } + + // 测试 WHILE 的超时情况 + @Test + public void testWhile1() { + assertTimeout("while1"); + } + + // 测试 WHILE 的非超时情况 + @Test + public void testWhile2() { + assertNotTimeout("while2"); + } + + // 测试 ITERATOR 的超时情况 + @Test + public void testIterator1() { + assertTimeout("iterator1"); + } + + // 测试 ITERATOR 的非超时情况 + @Test + public void testIterator2() { + assertNotTimeout("iterator2"); + } + + // 测试 SWITCH 的超时情况 + @Test + public void testSwitch1() { + assertTimeout("switch1"); + } + + // 测试 SWITCH 的非超时情况 + @Test + public void testSwitch2() { + assertNotTimeout("switch2"); + } + + // 测试 IF 的超时情况 + @Test + public void testIf1() { + assertTimeout("if1"); + } + + // 测试 SWITCH 的非超时情况 + @Test + public void testIf2() { + assertNotTimeout("if2"); + } + + // 测试单个组件的超时情况 + @Test + public void testComponent1() { + assertTimeout("component1"); + } + + // 测试单个组件的非超时情况 + @Test + public void testComponent2() { + assertNotTimeout("component2"); + } + + // 测试 FINALLY,虽然超时,但 FINALLY 仍会执行 + @Test + public void testFinally1() { + LiteflowResponse response = flowExecutor.execute2Resp("finally", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(TimeoutException.class, response.getCause().getClass()); + // FINALLY 执行时在默认数据上下文中放入了 CONTENT_KEY + DefaultContext contextBean = response.getFirstContextBean(); + Assertions.assertTrue(contextBean.hasData(CONTENT_KEY)); + } + + // 测试 maxWaitMilliseconds 关键字不能作用于 Finally + @Test + public void testFinally2() { + LiteFlowNodeBuilder.createNode() + .setId("a") + .setName("组件A") + .setType(NodeTypeEnum.COMMON) + .setClazz(ACmp.class) + .build(); + LiteFlowNodeBuilder.createNode() + .setId("b") + .setName("组件B") + .setType(NodeTypeEnum.COMMON) + .setClazz(BCmp.class) + .build(); + LiteFlowNodeBuilder.createNode() + .setId("c") + .setName("组件C") + .setType(NodeTypeEnum.COMMON) + .setClazz(CCmp.class) + .build(); + Assertions.assertFalse(LiteFlowChainELBuilder.validate("THEN(a, b, FINALLY(c).maxWaitMilliseconds(100))")); + } + + // 测试 chain 的超时情况 + @Test + public void testChain1() { + assertTimeout("chain1"); + } + + // 测试 chain 的非超时情况 + @Test + public void testChain2() { + assertNotTimeout("chain2"); + } + + private void assertTimeout(String chainId) { + LiteflowResponse response = flowExecutor.execute2Resp(chainId, "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(TimeoutException.class, response.getCause().getClass()); + } + + private void assertWhenTimeout(String chainId) { + LiteflowResponse response = flowExecutor.execute2Resp(chainId, "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(WhenTimeoutException.class, response.getCause().getClass()); + } + + private void assertNotTimeout(String chainId) { + LiteflowResponse response = flowExecutor.execute2Resp(chainId, "arg"); + Assertions.assertTrue(response.isSuccess()); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/ACmp.java new file mode 100644 index 000000000..52bc5fe1f --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/ACmp.java @@ -0,0 +1,21 @@ +package com.yomahub.liteflow.test.maxWaitMilliseconds.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; + +@LiteflowComponent("a") +public class ACmp { + + @LiteflowMethod(LiteFlowMethodEnum.PROCESS) + public void process(NodeComponent bindCmp) { + try { + Thread.sleep(100); + } catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/BCmp.java new file mode 100644 index 000000000..9bf05392a --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/BCmp.java @@ -0,0 +1,21 @@ +package com.yomahub.liteflow.test.maxWaitMilliseconds.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; + +@LiteflowComponent("b") +public class BCmp { + + @LiteflowMethod(LiteFlowMethodEnum.PROCESS) + public void process(NodeComponent bindCmp) { + try { + Thread.sleep(200); + } catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("BCmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/CCmp.java new file mode 100644 index 000000000..5bb5225fc --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/CCmp.java @@ -0,0 +1,21 @@ +package com.yomahub.liteflow.test.maxWaitMilliseconds.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; + +@LiteflowComponent("c") +public class CCmp { + + @LiteflowMethod(LiteFlowMethodEnum.PROCESS) + public void process(NodeComponent bindCmp) { + try { + Thread.sleep(500); + } catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("CCmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/DCmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/DCmp.java new file mode 100644 index 000000000..b844e256c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/DCmp.java @@ -0,0 +1,26 @@ +package com.yomahub.liteflow.test.maxWaitMilliseconds.cmp; + +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; +import com.yomahub.liteflow.slot.DefaultContext; + +@LiteflowComponent("d") +public class DCmp { + + public static final String CONTENT_KEY = "testKey"; + + @LiteflowMethod(LiteFlowMethodEnum.PROCESS) + public void process(NodeComponent bindCmp) { + try { + Thread.sleep(500); + DefaultContext contextBean = bindCmp.getFirstContextBean(); + contextBean.setData(CONTENT_KEY, "value"); + } catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("DCmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/FCmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/FCmp.java new file mode 100644 index 000000000..652e2e682 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/FCmp.java @@ -0,0 +1,18 @@ +package com.yomahub.liteflow.test.maxWaitMilliseconds.cmp; + +import com.yomahub.liteflow.annotation.LiteflowCmpDefine; +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; +import com.yomahub.liteflow.enums.NodeTypeEnum; + +@LiteflowComponent("f") +@LiteflowCmpDefine(NodeTypeEnum.IF) +public class FCmp { + + @LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_IF, nodeType = NodeTypeEnum.IF) + public boolean processIf(NodeComponent bindCmp) throws Exception { + return true; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/SCmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/SCmp.java new file mode 100644 index 000000000..68c7a1775 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/SCmp.java @@ -0,0 +1,18 @@ +package com.yomahub.liteflow.test.maxWaitMilliseconds.cmp; + +import com.yomahub.liteflow.annotation.LiteflowCmpDefine; +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; +import com.yomahub.liteflow.enums.NodeTypeEnum; + +@LiteflowComponent("s") +@LiteflowCmpDefine(NodeTypeEnum.SWITCH) +public class SCmp { + + @LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_SWITCH, nodeType = NodeTypeEnum.SWITCH) + public String processSwitch(NodeComponent bindCmp) throws Exception { + return "b"; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/WCmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/WCmp.java new file mode 100644 index 000000000..4809d114c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/WCmp.java @@ -0,0 +1,31 @@ +package com.yomahub.liteflow.test.maxWaitMilliseconds.cmp; + +import com.yomahub.liteflow.annotation.LiteflowCmpDefine; +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; +import com.yomahub.liteflow.enums.NodeTypeEnum; + +import java.util.HashSet; +import java.util.Set; + +@LiteflowComponent("w") +@LiteflowCmpDefine(NodeTypeEnum.WHILE) +public class WCmp { + private int count = 0; + + // 执行过的 chain + Set executedChain = new HashSet<>(); + + @LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_WHILE, nodeType = NodeTypeEnum.WHILE) + public boolean processWhile(NodeComponent bindCmp) throws Exception { + // 判断是否切换了 chain + if (!executedChain.contains(bindCmp.getCurrChainId())) { + count = 0; + executedChain.add(bindCmp.getCurrChainId()); + } + count++; + return count <= 2; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/XCmp.java b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/XCmp.java new file mode 100644 index 000000000..a25d33cdb --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/java/com/yomahub/liteflow/test/maxWaitMilliseconds/cmp/XCmp.java @@ -0,0 +1,23 @@ +package com.yomahub.liteflow.test.maxWaitMilliseconds.cmp; + +import cn.hutool.core.collection.ListUtil; +import com.yomahub.liteflow.annotation.LiteflowCmpDefine; +import com.yomahub.liteflow.annotation.LiteflowComponent; +import com.yomahub.liteflow.annotation.LiteflowMethod; +import com.yomahub.liteflow.core.NodeComponent; +import com.yomahub.liteflow.enums.LiteFlowMethodEnum; +import com.yomahub.liteflow.enums.NodeTypeEnum; + +import java.util.Iterator; +import java.util.List; + +@LiteflowComponent("x") +@LiteflowCmpDefine(NodeTypeEnum.ITERATOR) +public class XCmp { + + @LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_ITERATOR, nodeType = NodeTypeEnum.ITERATOR) + public Iterator processIterator(NodeComponent bindCmp) throws Exception { + List list = ListUtil.toList("one", "two"); + return list.iterator(); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/maxWaitMilliseconds/application.properties b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/maxWaitMilliseconds/application.properties new file mode 100644 index 000000000..678dc827e --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/maxWaitMilliseconds/application.properties @@ -0,0 +1 @@ +liteflow.rule-source=maxWaitMilliseconds/flow.el.xml \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/maxWaitMilliseconds/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/maxWaitMilliseconds/flow.el.xml new file mode 100644 index 000000000..13ead3d38 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-declare-springboot/src/test/resources/maxWaitMilliseconds/flow.el.xml @@ -0,0 +1,110 @@ + + + + + + + THEN(a,b).maxWaitMilliseconds(200); + + + + THEN(a,b).maxWaitMilliseconds(500); + + + + + + WHEN(a,c).maxWaitMilliseconds(300); + + + + WHEN(a,b).maxWaitMilliseconds(300); + + + + + + FOR(2).DO(a).maxWaitMilliseconds(100); + + + + FOR(2).DO(a).maxWaitMilliseconds(300); + + + + + WHILE(w).DO(a).maxWaitMilliseconds(100); + + + + WHILE(w).DO(a).maxWaitMilliseconds(300); + + + + + ITERATOR(x).DO(a).maxWaitMilliseconds(100); + + + + ITERATOR(x).DO(a).maxWaitMilliseconds(300); + + + + + + + SWITCH(s).TO(a, b).maxWaitMilliseconds(100); + + + + SWITCH(s).TO(a, b).maxWaitMilliseconds(300); + + + + + + + IF(f, b, c).maxWaitMilliseconds(100); + + + + IF(f, b, c).maxWaitMilliseconds(300); + + + + + + WHEN( + a.maxWaitMilliseconds(200), + c.maxWaitMilliseconds(300) + ); + + + + WHEN( + a.maxWaitMilliseconds(200), + b.maxWaitMilliseconds(300) + ); + + + + + + THEN(PRE(a), b, FINALLY(d)).maxWaitMilliseconds(200); + + + + + THEN(b) + + + + testChain.maxWaitMilliseconds(100); + + + + testChain.maxWaitMilliseconds(300); + + \ No newline at end of file