ソースを参照

优化redis测试用例

houxinyu 1 年間 前
コミット
d3db183903

+ 1 - 0
liteflow-testcase-el/liteflow-testcase-el-redis-springboot/pom.xml

@@ -35,6 +35,7 @@
             <groupId>com.yomahub</groupId>
             <artifactId>liteflow-script-groovy</artifactId>
             <version>${revision}</version>
+            <scope>test</scope>
         </dependency>
 
         <dependency>

+ 31 - 0
liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/java/com/yomahub/liteflow/test/redis/RedisSubscribeTestCondition.java

@@ -0,0 +1,31 @@
+package com.yomahub.liteflow.test.redis;
+
+import cn.hutool.core.util.StrUtil;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.api.redisnode.RedisNodes;
+import org.redisson.api.redisnode.RedisSingle;
+import org.redisson.config.Config;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 判断本地6379端口是否启动了Redis
+ */
+public class RedisSubscribeTestCondition {
+
+    /**
+     * @return true为本地未启动Redis
+     */
+    public static boolean notStartRedis() {
+        try{
+            Config config = new Config();
+            config.useSingleServer().setAddress("redis://127.0.0.1:6379");
+            RedissonClient redissonClient = Redisson.create(config);
+            RedisSingle redisNode = redissonClient.getRedisNodes(RedisNodes.SINGLE);
+            return !redisNode.pingAll(15000, TimeUnit.MICROSECONDS);
+        } catch (Exception e) {
+            return true;
+        }
+    }
+}

+ 141 - 64
liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/java/com/yomahub/liteflow/test/redis/RedisWithXmlELSubscribeSpringbootTest.java

@@ -1,118 +1,195 @@
 package com.yomahub.liteflow.test.redis;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.yomahub.liteflow.core.FlowExecutor;
-import com.yomahub.liteflow.flow.FlowBus;
 import com.yomahub.liteflow.flow.LiteflowResponse;
-import com.yomahub.liteflow.parser.redis.mode.RClient;
+import com.yomahub.liteflow.parser.redis.vo.RedisParserVO;
+import com.yomahub.liteflow.property.LiteflowConfig;
+import com.yomahub.liteflow.property.LiteflowConfigGetter;
 import com.yomahub.liteflow.slot.DefaultContext;
 import com.yomahub.liteflow.test.BaseTest;
-import org.junit.jupiter.api.AfterEach;
+import com.yomahub.liteflow.util.JsonUtil;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.redisson.Redisson;
+import org.redisson.api.RMapCache;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.DisabledIf;
+import org.springframework.test.context.junit.jupiter.DisabledIfCondition;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 import javax.annotation.Resource;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.mockito.Mockito.when;
-
 /**
  * springboot环境下的redis配置源订阅模式功能测试
  *
+ * 由于redisson中RMapCache监听器功能无法mock测试
+ * 故Sub模式测试用例需本地启动Redis服务 连接地址: 127.0.0.1:6379
+ * 若本地该端口号未启动Redis服务 则自动忽略本类中测试用例
+ *
  * @author hxinyu
  * @since 2.11.0
  */
-@ExtendWith(SpringExtension.class)
+@ExtendWith({SpringExtension.class, DisabledIfCondition.class})
 @TestPropertySource(value = "classpath:/redis/application-sub-xml.properties")
 @SpringBootTest(classes = RedisWithXmlELSubscribeSpringbootTest.class)
 @EnableAutoConfiguration
 @ComponentScan({"com.yomahub.liteflow.test.redis.cmp"})
+@DisabledIf("#{T(com.yomahub.liteflow.test.redis.RedisSubscribeTestCondition).notStartRedis()}")
 public class RedisWithXmlELSubscribeSpringbootTest extends BaseTest {
 
-    @MockBean(name = "chainClient")
-    private static RClient chainClient;
-
-    @MockBean(name = "scriptClient")
-    private static RClient scriptClient;
+    private static RedissonClient redissonClient;
 
     @Resource
     private FlowExecutor flowExecutor;
 
-    @AfterEach
-    public void after() {
-        FlowBus.cleanCache();
+    @BeforeAll
+    public static void setUpBeforeClass() {
+        Config config = new Config();
+        config.useSingleServer().setAddress("redis://127.0.0.1:6379").setDatabase(1);
+        redissonClient = Redisson.create(config);
+        RMapCache<String, String> chainKey = redissonClient.getMapCache("chainKey");
+        RMapCache<String, String> scriptKey = redissonClient.getMapCache("scriptKey");
+        scriptKey.put("s1:script:脚本s1:groovy", "defaultContext.setData(\"test1\",\"hello s1\");");
+        scriptKey.put("s2:script:脚本s2:js", "defaultContext.setData(\"test2\",\"hello s2\");");
+        scriptKey.put("s3:script:脚本s3", "defaultContext.setData(\"test3\",\"hello s3\");");
+        chainKey.put("chain1", "THEN(a, b, c);");
+        chainKey.put("chain2", "THEN(a, b, c, s3);");
+        chainKey.put("chain3", "THEN(a, b, c, s1, s2);");
+    }
+
+    @AfterAll
+    public static void after(){
+        System.out.println("after");
+        testCleanData();
     }
 
     /**
-     * 测试 chain
+     * 测试chain
      */
     @Test
-    public void testSubWithXml() {
-        Map<String, String> chainMap = new HashMap<>();
-        chainMap.put("chain1", "THEN(a, b, c);");
-        //修改chain值
-        Map<String, String> changeChainMap = new HashMap<>();
-        changeChainMap.put("chain1", "THEN(a, c);");
-        when(chainClient.getMap("chainKey")).thenReturn(chainMap).thenReturn(changeChainMap);
-
-        //测试修改前的chain
+    public void testSubWithXml() throws InterruptedException {
         LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
         Assertions.assertTrue(response.isSuccess());
         Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr());
 
-        flowExecutor.reloadRule();
+        //修改redis中规则
+        changeXMLData();
+        //重新加载规则
+        Thread.sleep(50);
+        Assertions.assertEquals("a==>c==>b", flowExecutor.execute2Resp("chain1", "arg").getExecuteStepStr());
 
-        //测试修改后的chain
+        //删除redis中规则
+        deleteXMLData();
+        //重新加载规则
+        Thread.sleep(50);
         response = flowExecutor.execute2Resp("chain1", "arg");
-        Assertions.assertTrue(response.isSuccess());
-        Assertions.assertEquals("a==>c", response.getExecuteStepStr());
+        Assertions.assertTrue(!response.isSuccess());
+
+        //添加redis中规则
+        addXMLData();
+        //重新加载规则
+        Thread.sleep(50);
+        Assertions.assertEquals("b==>c", flowExecutor.execute2Resp("chain4", "arg").getExecuteStepStr());
     }
 
+    /**
+     * 测试script
+     */
     @Test
-    public void testSubWithScriptXml() {
-        Map<String, String> chainMap = new HashMap<>();
-        chainMap.put("chain2", "THEN(a, b, c, s1, s2, s3);");
-
-        Map<String, String> scriptMap = new HashMap<>();
-        scriptMap.put("s1:script:脚本s1:groovy", "defaultContext.setData(\"test1\",\"hello s1\");");
-        scriptMap.put("s2:script:脚本s2:js", "defaultContext.setData(\"test2\",\"hello s2\");");
-        scriptMap.put("s3:script:脚本s3", "defaultContext.setData(\"test3\",\"hello s3\");");
-        //修改chain值和script值
-        Map<String, String> changeChainMap = new HashMap<>();
-        changeChainMap.put("chain2", "THEN(a, c, s1, s3);");
-        Map<String, String> changeScriptMap = new HashMap<>();
-        changeScriptMap.put("s1:script:脚本s1:groovy", "defaultContext.setData(\"test1\",\"hello world\");");
-        changeScriptMap.put("s2:script:脚本s2:js", "defaultContext.setData(\"test2\",\"hello s2\");");
-        changeScriptMap.put("s3:script:脚本s3", "defaultContext.setData(\"test3\",\"hello s3\");");
-
-        when(chainClient.getMap("chainKey")).thenReturn(chainMap).thenReturn(changeChainMap);
-        //这里是因为脚本的getMap方法在一次流程里会执行到两次
-        when(scriptClient.getMap("scriptKey")).thenReturn(scriptMap).thenReturn(scriptMap)
-                .thenReturn(changeScriptMap).thenReturn(changeScriptMap);
-
-        //测试修改前的chain和script
-        LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg");
+    public void testSubWithScriptXml() throws InterruptedException {
+        LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
         DefaultContext context = response.getFirstContextBean();
         Assertions.assertTrue(response.isSuccess());
         Assertions.assertEquals("hello s1", context.getData("test1"));
-        Assertions.assertEquals("hello s2", context.getData("test2"));
-        Assertions.assertEquals("a==>b==>c==>s1[脚本s1]==>s2[脚本s2]==>s3[脚本s3]", response.getExecuteStepStrWithoutTime());
+        Assertions.assertEquals("a==>b==>c==>s1[脚本s1]==>s2[脚本s2]", response.getExecuteStepStrWithoutTime());
+
+        //添加和删除脚本
+        addAndDeleteScriptData();
+        //修改redis脚本
+        changeScriptData();
+        Thread.sleep(50);
+        context = flowExecutor.execute2Resp("chain3", "arg").getFirstContextBean();
+        Assertions.assertEquals("hello s1 version2", context.getData("test1"));
+        context = flowExecutor.execute2Resp("chain2", "arg").getFirstContextBean();
+        Assertions.assertEquals("hello s3 version2", context.getData("test2"));
+    }
 
-        flowExecutor.reloadRule();
+    /**
+     * 修改redisson中的chain
+     */
+    public void changeXMLData() {
+        LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
+        RedisParserVO redisParserVO = JsonUtil.parseObject(liteflowConfig.getRuleSourceExtData(), RedisParserVO.class);
+        RMapCache<String, String> chainKey = redissonClient.getMapCache(redisParserVO.getChainKey());
+        chainKey.put("chain1", "THEN(a, c, b);");
+    }
 
-        //测试修改后的chain和script
-        response = flowExecutor.execute2Resp("chain2", "arg");
-        context = response.getFirstContextBean();
-        Assertions.assertTrue(response.isSuccess());
-        Assertions.assertEquals("hello world", context.getData("test1"));
-        Assertions.assertEquals("a==>c==>s1[脚本s1]==>s3[脚本s3]", response.getExecuteStepStrWithoutTime());
+    /**
+     * 删除redisson中的chain
+     */
+    public void deleteXMLData() {
+        LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
+        RedisParserVO redisParserVO = JsonUtil.parseObject(liteflowConfig.getRuleSourceExtData(), RedisParserVO.class);
+        RMapCache<String, String> chainKey = redissonClient.getMapCache(redisParserVO.getChainKey());
+        chainKey.remove("chain1");
+        chainKey.remove("chain4");
+    }
+
+    /**
+     * 新增redisson中的chain
+     */
+    public void addXMLData() {
+        LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
+        RedisParserVO redisParserVO = JsonUtil.parseObject(liteflowConfig.getRuleSourceExtData(), RedisParserVO.class);
+        RMapCache<String, String> chainKey = redissonClient.getMapCache(redisParserVO.getChainKey());
+        chainKey.put("chain4","THEN(b, c);");
+    }
+
+    /**
+     * 修改redisson中的脚本
+     */
+    public void changeScriptData() {
+        LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
+        RedisParserVO redisParserVO = JsonUtil.parseObject(liteflowConfig.getRuleSourceExtData(), RedisParserVO.class);
+        RMapCache<String, String> scriptKey = redissonClient.getMapCache(redisParserVO.getScriptKey());
+        scriptKey.put("s1:script:脚本s1:groovy", "defaultContext.setData(\"test1\",\"hello s1 version2\");");
+        scriptKey.put("s3:script:脚本s3", "defaultContext.setData(\"test2\",\"hello s3 version2\");");
+    }
+
+    /**
+     * 新增和删除redisson中的chain
+     */
+    public void addAndDeleteScriptData() {
+        LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
+        RedisParserVO redisParserVO = JsonUtil.parseObject(liteflowConfig.getRuleSourceExtData(), RedisParserVO.class);
+        RMapCache<String, String> scriptKey = redissonClient.getMapCache(redisParserVO.getScriptKey());
+        scriptKey.remove("s3:script:脚本s3");
+        scriptKey.put("s5:script:脚本s5:groovy", "defaultContext.setData(\"test1\",\"hello s5\");");
+    }
+
+    //redis内规则数据数据清空
+    public static void testCleanData(){
+        if(ObjectUtil.isNotNull(redissonClient)){
+            RMapCache<String, String> scriptKey = redissonClient.getMapCache("chainKey");
+            RMapCache<String, String> chainKey = redissonClient.getMapCache("scriptKey");
+            for (String key : chainKey.keySet()) {
+                chainKey.remove(key);
+            }
+            for (String key : scriptKey.keySet()) {
+                scriptKey.remove(key);
+            }
+            chainKey.keySet().forEach(System.out::println);
+            System.out.println("");
+            scriptKey.keySet().forEach(System.out::println);
+        }
     }
 }