Redis embedded server for Java integration testing.
This was forked from spinnaker/embedded-redis to utilize the redis upgrade and other cleanup from the original. Resetting this back to work with JDK 7 for our purposes, and build with maven again.
Add the maven dependency
<dependency>
<groupId>com.parchment.io.embedded-redis</groupId>
<artifactId>embedded-redis-starter</artifactId>
<version>0.9.x</version>
</dependency>
Then set some properties
spring.redis.embedded.enabled=true
spring.redis.host=localhost
# spring will pick a random port in the given range and use that port
spring.redis.port=${random.int[1024,65536]}
# if using Redisson, you MUST set a password
spring.redis.password=password
Add the maven dependency
<dependency>
<groupId>com.parchment.io.embedded-redis</groupId>
<artifactId>embedded-redis</artifactId>
<version>0.9.x</version>
</dependency>
Then follow the Usage guide below
Previous release of spinnaker fork: None and/or internal to Netflix
Previous release on Maven Central:
<dependency>
<groupId>com.github.kstyrc</groupId>
<artifactId>embedded-redis</artifactId>
<version>0.6</version>
</dependency>
Note: in any of the following, if you wish to requirepass on the server, you must create a config file with a minimum of 'requirepass <password>' in it and use RedisServerBuilder's configFile().
Running RedisServer is as simple as:
RedisServer redisServer = new RedisServer(6379);
redisServer.start();
// do some work
redisServer.stop();
You can also provide RedisServer with your own executable:
// 1) given explicit file (os-independence broken!)
RedisServer redisServer = new RedisServer("/path/to/your/redis", 6379);
// 2) given os-independent matrix
RedisExecProvider customProvider = RedisExecProvider.defaultProvider()
.override(OS.UNIX, "/path/to/unix/redis")
.override(OS.WINDOWS, Architecture.x86, "/path/to/windows/redis")
.override(OS.Windows, Architecture.x86_64, "/path/to/windows/redis")
.override(OS.MAC_OS_X, Architecture.x86, "/path/to/macosx/redis")
.override(OS.MAC_OS_X, Architecture.x86_64, "/path/to/macosx/redis")
RedisServer redisServer = new RedisServer(customProvider, 6379);
You can also use fluent API to create RedisServer:
RedisServer redisServer = RedisServer.builder()
.redisExecProvider(customRedisProvider)
.port(6379)
.slaveOf("locahost", 6378)
.configFile("/path/to/your/redis.conf")
.build();
Or even create simple redis.conf file from scratch:
RedisServer redisServer = RedisServer.builder()
.redisExecProvider(customRedisProvider)
.port(6379)
.slaveOf("locahost", 6378)
.setting("daemonize no")
.setting("appendonly no")
.setting("maxheap 128M")
.build();
Our Embedded Redis has support for HA Redis clusters with Sentinels and master-slave replication
A simple redis integration test with Redis cluster on ephemeral ports, with setup similar to that from production would look like this:
public class SomeIntegrationTestThatRequiresRedis {
private RedisCluster cluster;
private Set<String> jedisSentinelHosts;
@Before
public void setup() throws Exception {
//creates a cluster with 3 sentinels, quorum size of 2 and 3 replication groups, each with one master and one slave
cluster = RedisCluster.builder().ephemeral().sentinelCount(3).quorumSize(2)
.replicationGroup("master1", 1)
.replicationGroup("master2", 1)
.replicationGroup("master3", 1)
.build();
cluster.start();
//retrieve ports on which sentinels have been started, using a simple Jedis utility class
jedisSentinelHosts = JedisUtil.sentinelHosts(cluster);
}
@Test
public void test() throws Exception {
// testing code that requires redis running
JedisSentinelPool pool = new JedisSentinelPool("master1", jedisSentinelHosts);
}
@After
public void tearDown() throws Exception {
cluster.stop();
}
}
The above example starts Redis cluster on ephemeral ports, which you can later get with cluster.ports()
,
which will return a list of all ports of the cluster. You can also get ports of sentinels with cluster.sentinelPorts()
or servers with cluster.serverPorts()
. JedisUtil
class contains utility methods for use with Jedis client.
You can also start Redis cluster on predefined ports and even mix both approaches:
public class SomeIntegrationTestThatRequiresRedis {
private RedisCluster cluster;
@Before
public void setup() throws Exception {
final List<Integer> sentinels = Arrays.asList(26739, 26912);
final List<Integer> group1 = Arrays.asList(6667, 6668);
final List<Integer> group2 = Arrays.asList(6387, 6379);
//creates a cluster with 3 sentinels, quorum size of 2 and 3 replication groups, each with one master and one slave
cluster = RedisCluster.builder().sentinelPorts(sentinels).quorumSize(2)
.serverPorts(group1).replicationGroup("master1", 1)
.serverPorts(group2).replicationGroup("master2", 1)
.ephemeralServers().replicationGroup("master3", 1)
.build();
cluster.start();
}
//(...)
The above will create and start a cluster with sentinels on ports 26739, 26912
, first replication group on 6667, 6668
,
second replication group on 6387, 6379
and third replication group on ephemeral ports.
When not provided with the desired redis executable, RedisServer runs os-dependent executable enclosed in jar. Currently is uses:
- Redis 3.2.11 in case of Linux/Unix
- Redis 3.2.11 in case of OSX
- Windows support not provided
However, you should provide RedisServer with redis executable if you need specific version.
Licensed under the Apache License, Version 2.0
- Krzysztof Styrc (@kstyrc)
- Piotr Turek (@turu)
- anthonyu (@anthonyu)
- Artem Orobets (@enisher)
- Sean Simonsen (@SeanSimonsen)
- Rob Winch (@rwinch)
- Support for Redis 3.2.11
- Removed Windows support
- Support JDK 6 +
- OS detection fix
- redis binary per OS/arch pair
- Updated to 2.8.19 binary for Windows
- Updated for Java 8
- Added Sentinel support
- Ability to create arbitrary clusters on arbitrary (ephemeral) ports
- Updated to latest guava
- Throw an exception if redis has not been started
- Redis errorStream logged to System.out
- Fluent API for RedisServer creation
- Initial decent release