curator-test:Contains the TestingServer, the TestingCluster and a few other tools useful for testing.
深坑:
curator竟然不是向下兼容的,issues.apache.org/jira/browse…(使用版本)
log4j-over-slf4j竟然也不是向下兼容的,扯犊子呢,而且外文文档也是一通瞎扯
[惊恐]
[惊恐]
[惊恐]
原理:
启动java的嵌入式zookeeper,然后获取启动时的随机端口,还是使用CuratorFramework封装好的框架进行测试,本来使用的嵌入式curator-test就是它提供的
zookeeper使用步骤:
test-tools项目已经封装了对zookeeper的依赖和默认设置,故只需引入pom即可
| ```html com.xueqiu.infra test-tools 1.0.3
| ------------------------------------------------------------------------------------------------------------------------------------------ |
version版本根据实时情况更新
zookeeper使用示例:
只需指定你要启动的节点数(示例中启动了三个节点),详情见如下示例地址
示例地址:
源码版:<http://git.snowballfinance.com/lib/test-tools>
| ```html
/** * zookeeper unit test * * zookeeper的单元测试 */ @Test public void testZookeeper(){ TestEnvironment env = new TestEnvironmentBuilder() .withZookeeper(3) .build(); // zookeeper test try{ TestingCluster cluster = env.zookeepers().get(); String connectString = cluster.getServers().stream().map(server->server.getInstanceSpec().getConnectString()).collect(Collectors.joining(",")); CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, new ExponentialBackoffRetry(1000, 3)); client.start(); client.getConnectionStateListenable().addListener((cl, newState)-> { System.out.println("连接状态:" + newState.name()); }); List<String> paths = client.getChildren().forPath("/"); System.out.println(paths); client.create().forPath("/test"); paths = client.getChildren().forPath("/"); System.out.println(paths); CloseableUtils.closeQuietly(client); Assert.assertTrue(paths.contains("test")); }catch (Exception e){ Assert.assertTrue(false); throw new RuntimeException("zookeeper test error.", e); } }
``` |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
示例地址:
spring版:[http://git.snowballfinance.com/hekuangsheng/xueqiu-push](http://git.snowballfinance.com/lib/xueqiu-push)
| `test的resource目录下添加sql文件` `src` ` ``--main` ` ``--test` ` ``--java` ` ``--包路径` ` ``--TestConfig.java` ` ``--BaseTests.java` ` ``--ZookeeperServerTest.java` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
TestConfig.java
| ```html
package com.xueqiu.infra.push.server; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.xueqiu.infra.test.tools.TestEnvironment; import com.xueqiu.infra.test.tools.TestEnvironmentBuilder; import com.xueqiu.infra.test.tools.entity.RedisCluster4; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.test.TestingCluster; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @Configuration @AutoConfigureOrder(0) public class BaseTestConfig { private TestEnvironment env = new TestEnvironmentBuilder() .withZookeeper(3) .withH2Database(Arrays.asList("sql/demo_schema.sql", "sql/demo_data.sql")) .withRedisCluster4(4) .build(); @Bean public CuratorFramework curatorFramework(){ TestingCluster cluster = TestEnvironment.zookeepers(). orElseThrow(() -> new RuntimeException("init test TestingServer fail")); String connectString = cluster.getServers().stream().map(server->server.getInstanceSpec().getConnectString()).collect(Collectors.joining(",")); return CuratorFrameworkFactory.newClient(connectString, new ExponentialBackoffRetry(1000, 3)); } @Bean public DataSource dataSource() { return TestEnvironment.jdbcDataSource() .orElseThrow(() -> new RuntimeException("init test data source fail")); } @Bean(name = "xueqiupushTemplate") public JdbcTemplate jdbcTemplate() { return new JdbcTemplate(dataSource()); } @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { DataSourceTransactionManager tm = new DataSourceTransactionManager(); tm.setDataSource(dataSource); return tm; } @Bean public RedisConnectionFactory factory(){ RedisCluster4 redisCluster4 = TestEnvironment.redisCluster4() .orElseThrow(() -> new RuntimeException("init test redis cluster fail")); List<String> connectionStringList = redisCluster4.getConnectionStringList(); RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(connectionStringList); RedisConnectionFactory connectionFactory = new LettuceConnectionFactory(redisClusterConfiguration); return connectionFactory; } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); return template; } @Bean("rateLimitLua") public DefaultRedisScript getRedisScript() { DefaultRedisScript redisScript = new DefaultRedisScript(); redisScript.setLocation(new ClassPathResource("limit/ratelimit.lua")); redisScript.setResultType(java.util.List.class); return redisScript; } @Bean("rateLimitInitLua") public DefaultRedisScript getInitRedisScript() { DefaultRedisScript redisScript = new DefaultRedisScript(); redisScript.setLocation(new ClassPathResource("limit/ratelimitInit.lua")); redisScript.setResultType(Long.class); return redisScript; } }
``` |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
BaseJunit4Test.java
| ```html
package com.xueqiu.infra.push.server; import org.junit.Ignore; import org.junit.runner.RunWith; import org.springframework.context.annotation.ComponentScan; import org.springframework.stereotype.Controller; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionalTestExecutionListener; import org.springframework.transaction.annotation.Transactional; @Ignore @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = BaseTestConfig.class) @TestExecutionListeners(TransactionalTestExecutionListener.class) @Transactional @ComponentScan( basePackages = { "com.xueqiu.infra.push.server.entity", "com.xueqiu.infra.push.server.limit", }, excludeFilters = { @ComponentScan.Filter(Controller.class) } ) public class BaseJunit4Test extends AbstractJUnit4SpringContextTests { }
``` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
ZookeeperServerTest.java
| ```html
package com.xueqiu.infra.push.server; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.utils.CloseableUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; public class ZookeeperServerTest extends BaseJunit4Test { @Autowired CuratorFramework curatorFramework; @Before public void before(){ curatorFramework.start(); } @Test public void zookeeper_server_test() throws Exception { List<String> paths = curatorFramework.getChildren().forPath("/"); System.out.println(paths); curatorFramework.create().forPath("/test"); paths = curatorFramework.getChildren().forPath("/"); System.out.println(paths); Assert.assertTrue(paths.contains("test")); } @After public void after(){ CloseableUtils.closeQuietly(curatorFramework); } }
``` |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
相关资料:
<https://github.com/apache/zookeeper/search?q=HierarchyDynamicMBean&unscoped_q=HierarchyDynamicMBean>
<https://issues.apache.org/jira/browse/CURATOR-428>
<http://curator.apache.org/zk-compatibility.html>
<https://mvnrepository.com/artifact/org.apache.curator/curator-test>
<https://stackoverflow.com/questions/59539375/zookeeper-unit-test-quorumpeer-never-got-set>