From 0e18dd96f55dac5893c0bf6d979c849457a78eee Mon Sep 17 00:00:00 2001 From: jackygurui <jackygurui@gmail.com> Date: Tue, 15 Mar 2016 00:21:44 +0000 Subject: [PATCH 1/6] Make RedisRunner Accepts redis-server cli options WIP --- src/test/java/org/redisson/RedisRunner.java | 44 ++++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/redisson/RedisRunner.java b/src/test/java/org/redisson/RedisRunner.java index dfdf7bdc6..0be95b479 100644 --- a/src/test/java/org/redisson/RedisRunner.java +++ b/src/test/java/org/redisson/RedisRunner.java @@ -3,20 +3,60 @@ package org.redisson; import java.io.File; import java.io.IOException; import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; public class RedisRunner { + private static final String redisFolder = "C:\\Devel\\projects\\redis\\Redis-x64-3.0.500\\"; + private static final String redisBinary = redisFolder + "redis-server.exe"; + + private final List<String> options = new ArrayList<>(); - public static Process runRedis(String configPath) throws IOException, InterruptedException { + { + options.add(Optional.ofNullable(System.getProperty("redisBinary")).orElse(redisBinary)); + } + + /** + * To change the <b>redisBinary</b> system property for running the test, + * use <i>argLine</i> option from surefire plugin: + * + * $ mvn -DargLine="-DredisBinary=`which redis-server`" -Punit-test clean \ + * verify + * + * @param configPath + * @return Process running redis instance + * @throws IOException + * @throws InterruptedException + * @see + * <a href="http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#argLine"> + * http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#argLine</a> + */ + public static Process runRedisWithConfigFile(String configPath) throws IOException, InterruptedException { URL resource = RedisRunner.class.getResource(configPath); - ProcessBuilder master = new ProcessBuilder(redisFolder + "redis-server.exe", resource.getFile().substring(1)); + ProcessBuilder master = new ProcessBuilder( + Optional.ofNullable(System.getProperty("redisBinary")).orElse(redisBinary), + resource.getFile().substring(1)); master.directory(new File(redisFolder)); Process p = master.start(); Thread.sleep(1000); return p; } + public RedisRunner withPort(int port) { + this.options.add("--port " + port); + return this; + } + + public Process run() throws IOException, InterruptedException { + ProcessBuilder master = new ProcessBuilder(options); + master.directory(new File(redisBinary).getParentFile()); + Process p = master.start(); + Thread.sleep(1000); + return p; + } } From 5b1818516b667c234002faeb5a97bd42fc768064 Mon Sep 17 00:00:00 2001 From: jackygurui <jackygurui@gmail.com> Date: Tue, 15 Mar 2016 23:12:33 +0000 Subject: [PATCH 2/6] added all the redis v3.0.7 config options as enum type --- src/test/java/org/redisson/RedisRunner.java | 169 +++++++++++++++++++- 1 file changed, 162 insertions(+), 7 deletions(-) diff --git a/src/test/java/org/redisson/RedisRunner.java b/src/test/java/org/redisson/RedisRunner.java index 0be95b479..8d59e57de 100644 --- a/src/test/java/org/redisson/RedisRunner.java +++ b/src/test/java/org/redisson/RedisRunner.java @@ -3,20 +3,148 @@ package org.redisson; import java.io.File; import java.io.IOException; import java.net.URL; -import java.util.ArrayList; -import java.util.List; +import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.Optional; +import java.util.stream.Collectors; public class RedisRunner { + enum OPTIONS { + BINARY_PATH, + DAEMONIZE, + PIDFILE, + PORT, + TCP_BACKLOG, + BIND, + UNIXSOCKET, + UNIXSOCKETPERM, + TIMEOUT, + TCP_KEEPALIVE, + LOGLEVEL, + LOGFILE, + SYSLOG_ENABLED, + SYSLOG_IDENT, + SYSLOG_FACILITY, + DATABASES, + SAVE, + STOP_WRITES_ON_BGSAVE_ERROR, + RDBCOMPRESSION, + RDBCHECKSUM, + DBFILENAME, + DIR, + SLAVEOF, + MASTERAUTH, + SLAVE_SERVE_STALE_DATA, + SLAVE_READ_ONLY, + REPL_DISKLESS_SYNC, + REPL_DISKLESS_SYNC_DELAY, + REPL_PING_SLAVE_PERIOD, + REPL_TIMEOUT, + REPL_DISABLE_TCP_NODELAY, + REPL_BACKLOG_SIZE, + REPL_BACKLOG_TTL, + SLAVE_PRIORITY, + MIN_SLAVES_TO_WRITE, + MIN_SLAVES_MAX_LAG, + REQUREPASS, + RENAME_COMMAND, + MAXCLIENTS, + MAXMEMORY, + MAXMEMORY_POLICY, + MAXMEMORY_SAMPLE, + APPEND_ONLY, + APPENDFILENAME, + APPENDFSYNC, + NO_APPENDFSYNC_ON_REWRITE, + AUTO_AOF_REWRITE_PERCENTAGE, + AUTO_AOF_REWRITE_MIN_SIZE, + AOF_LOAD_TRUNCATED, + LUA_TIME_LIMIT, + CLUSTER_ENABLED, + CLUSTER_CONFIG_FILE, + CLUSTER_NODE_TIMEOUT, + CLUSTER_SLAVE_VALIDITY_FACTOR, + CLUSTER_MIGRATION_BARRIER, + CLUSTER_REQUIRE_FULL_COVERAGE, + SLOWLOG_LOG_SLOWER_THAN, + SLOWLOG_MAX_LEN, + LATENCY_MONITOR_THRESHOLD, + NOFITY_KEYSPACE_EVENTS, + HASH_MAX_ZIPLIST_ENTRIES, + HASH_MAX_ZIPLIST_VALUE, + LIST_MAX_ZIPLIST_ENTRIES, + LIST_MAX_ZIPLIST_VALUE, + SET_MAX_INTSET_ENTRIES, + ZSET_MAX_ZIPLIST_ENTRIES, + ZSET_MAX_ZIPLIST_VALUE, + HLL_SPARSE_MAX_BYTES, + ACTIVEREHASHING, + CLIENT_OUTPUT_BUFFER_LIMIT,//MULTI + HZ, + AOF_REWRITE_INCREMENTAL_FSYNC + } + + enum LOGLEVEL_OPTIONS { + DEBUG, + VERBOSE, + NOTICE, + WARNING + } + + enum SYSLOG_FACILITY_OPTIONS { + USER, + LOCAL0, + LOCAL1, + LOCAL2, + LOCAL3, + LOCAL4, + LOCAL5, + LOCAL6, + LOCAL7 + } + + enum MAX_MEMORY_POLICY_OPTIONS { + VOLATILE_LRU, + ALLKEYS_LRU, + VOLATILE_RANDOM, + ALLKEYS_RANDOM, + VOLATILE_TTL, + NOEVICTION + } + enum APPEND_FSYNC_MODE_OPTIONS { + ALWAYS, + EVERYSEC, + NO + } + + enum KEYSPACE_EVENTS_OPTIONS { + K, + E, + g, + $, + l, + s, + h, + z, + x, + e, + A + } + + enum CLIENT_CLASS_OPTIONS { + NORMAL, + SLAVE, + PUBSUB + } private static final String redisFolder = "C:\\Devel\\projects\\redis\\Redis-x64-3.0.500\\"; private static final String redisBinary = redisFolder + "redis-server.exe"; - private final List<String> options = new ArrayList<>(); + private final LinkedHashMap<OPTIONS, String> options = new LinkedHashMap<>(); { - options.add(Optional.ofNullable(System.getProperty("redisBinary")).orElse(redisBinary)); + options.put(OPTIONS.BINARY_PATH, Optional.ofNullable(System.getProperty("redisBinary")).orElse(redisBinary)); } /** @@ -46,13 +174,40 @@ public class RedisRunner { return p; } - public RedisRunner withPort(int port) { - this.options.add("--port " + port); + private void addConfigOption(OPTIONS option, String... args) { + StringBuilder sb = new StringBuilder("--"); + sb.append(option.toString().replaceAll("_", "-").toLowerCase()); + sb.append(" "); + sb.append(Arrays.stream(args).collect(Collectors.joining(" "))); + this.options.put(option, sb.toString()); + } + + private String convertBoolean(boolean b) { + return b ? "yes" : "no"; + } + + public RedisRunner daemonize(boolean daemonize) { + addConfigOption(OPTIONS.DAEMONIZE, convertBoolean(daemonize)); + return this; + } + + public RedisRunner pidfile(String pidfile) { + addConfigOption(OPTIONS.PIDFILE, pidfile); + return this; + } + + public RedisRunner port(int port) { + addConfigOption(OPTIONS.PORT, port + ""); + return this; + } + + public RedisRunner tcpBacklog(int tcpBacklog) { + addConfigOption(OPTIONS.TCP_BACKLOG, "" + tcpBacklog); return this; } public Process run() throws IOException, InterruptedException { - ProcessBuilder master = new ProcessBuilder(options); + ProcessBuilder master = new ProcessBuilder(options.values().stream().collect(Collectors.joining(" "))); master.directory(new File(redisBinary).getParentFile()); Process p = master.start(); Thread.sleep(1000); From 76c5ece35abc4a50b0a5e878c0576152a1ad7e89 Mon Sep 17 00:00:00 2001 From: jackygurui <jackygurui@gmail.com> Date: Tue, 15 Mar 2016 23:13:04 +0000 Subject: [PATCH 3/6] changed existing test code to use runRedisWithConfigFile method --- src/test/java/org/redisson/RedissonMultiLockTest.java | 6 +++--- src/test/java/org/redisson/RedissonTest.java | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/java/org/redisson/RedissonMultiLockTest.java b/src/test/java/org/redisson/RedissonMultiLockTest.java index d7a2e2a2e..22e0cd1e7 100644 --- a/src/test/java/org/redisson/RedissonMultiLockTest.java +++ b/src/test/java/org/redisson/RedissonMultiLockTest.java @@ -17,9 +17,9 @@ public class RedissonMultiLockTest { @Test public void test() throws IOException, InterruptedException { - Process redis1 = RedisRunner.runRedis("/redis_multiLock_test_instance1.conf"); - Process redis2 = RedisRunner.runRedis("/redis_multiLock_test_instance2.conf"); - Process redis3 = RedisRunner.runRedis("/redis_multiLock_test_instance3.conf"); + Process redis1 = RedisRunner.runRedisWithConfigFile("/redis_multiLock_test_instance1.conf"); + Process redis2 = RedisRunner.runRedisWithConfigFile("/redis_multiLock_test_instance2.conf"); + Process redis3 = RedisRunner.runRedisWithConfigFile("/redis_multiLock_test_instance3.conf"); NioEventLoopGroup group = new NioEventLoopGroup(); Config config1 = new Config(); diff --git a/src/test/java/org/redisson/RedissonTest.java b/src/test/java/org/redisson/RedissonTest.java index 449669448..73588a006 100644 --- a/src/test/java/org/redisson/RedissonTest.java +++ b/src/test/java/org/redisson/RedissonTest.java @@ -61,7 +61,7 @@ public class RedissonTest { @Test(expected = RedisOutOfMemoryException.class) public void testMemoryScript() throws IOException, InterruptedException { - Process p = RedisRunner.runRedis("/redis_oom_test.conf"); + Process p = RedisRunner.runRedisWithConfigFile("/redis_oom_test.conf"); Config config = new Config(); config.useSingleServer().setAddress("127.0.0.1:6319").setTimeout(100000); @@ -78,7 +78,7 @@ public class RedissonTest { @Test(expected = RedisOutOfMemoryException.class) public void testMemoryCommand() throws IOException, InterruptedException { - Process p = RedisRunner.runRedis("/redis_oom_test.conf"); + Process p = RedisRunner.runRedisWithConfigFile("/redis_oom_test.conf"); Config config = new Config(); config.useSingleServer().setAddress("127.0.0.1:6319").setTimeout(100000); @@ -97,7 +97,7 @@ public class RedissonTest { @Test public void testConnectionListener() throws IOException, InterruptedException, TimeoutException { - Process p = RedisRunner.runRedis("/redis_connectionListener_test.conf"); + Process p = RedisRunner.runRedisWithConfigFile("/redis_connectionListener_test.conf"); final AtomicInteger connectCounter = new AtomicInteger(); final AtomicInteger disconnectCounter = new AtomicInteger(); @@ -134,7 +134,7 @@ public class RedissonTest { } catch (Exception e) { } - p = RedisRunner.runRedis("/redis_connectionListener_test.conf"); + p = RedisRunner.runRedisWithConfigFile("/redis_connectionListener_test.conf"); r.getBucket("1").get(); From c1695e0ac8734353dc8130bb43c87b115c7f1ff9 Mon Sep 17 00:00:00 2001 From: jackygurui <jackygurui@gmail.com> Date: Thu, 17 Mar 2016 00:09:57 +0000 Subject: [PATCH 4/6] WIP update --- src/test/java/org/redisson/RedisRunner.java | 128 ++++++++++++++------ 1 file changed, 91 insertions(+), 37 deletions(-) diff --git a/src/test/java/org/redisson/RedisRunner.java b/src/test/java/org/redisson/RedisRunner.java index 8d59e57de..d4c4db1b6 100644 --- a/src/test/java/org/redisson/RedisRunner.java +++ b/src/test/java/org/redisson/RedisRunner.java @@ -10,13 +10,14 @@ import java.util.stream.Collectors; public class RedisRunner { - enum OPTIONS { + public enum OPTIONS { + BINARY_PATH, DAEMONIZE, PIDFILE, PORT, TCP_BACKLOG, - BIND, + BIND(true), UNIXSOCKET, UNIXSOCKETPERM, TIMEOUT, @@ -27,7 +28,7 @@ public class RedisRunner { SYSLOG_IDENT, SYSLOG_FACILITY, DATABASES, - SAVE, + SAVE(true), STOP_WRITES_ON_BGSAVE_ERROR, RDBCOMPRESSION, RDBCHECKSUM, @@ -48,7 +49,7 @@ public class RedisRunner { MIN_SLAVES_TO_WRITE, MIN_SLAVES_MAX_LAG, REQUREPASS, - RENAME_COMMAND, + RENAME_COMMAND(true), MAXCLIENTS, MAXMEMORY, MAXMEMORY_POLICY, @@ -80,19 +81,37 @@ public class RedisRunner { ZSET_MAX_ZIPLIST_VALUE, HLL_SPARSE_MAX_BYTES, ACTIVEREHASHING, - CLIENT_OUTPUT_BUFFER_LIMIT,//MULTI + CLIENT_OUTPUT_BUFFER_LIMIT$NORMAL, + CLIENT_OUTPUT_BUFFER_LIMIT$SLAVE, + CLIENT_OUTPUT_BUFFER_LIMIT$PUBSUB, HZ, - AOF_REWRITE_INCREMENTAL_FSYNC + AOF_REWRITE_INCREMENTAL_FSYNC; + + private final boolean allowMutiple; + + private OPTIONS() { + this.allowMutiple = false; + } + + private OPTIONS(boolean allowMutiple) { + this.allowMutiple = allowMutiple; + } + + public boolean isAllowMultiple() { + return allowMutiple; + } } - - enum LOGLEVEL_OPTIONS { + + public enum LOGLEVEL_OPTIONS { + DEBUG, VERBOSE, NOTICE, WARNING } - - enum SYSLOG_FACILITY_OPTIONS { + + public enum SYSLOG_FACILITY_OPTIONS { + USER, LOCAL0, LOCAL1, @@ -103,8 +122,9 @@ public class RedisRunner { LOCAL6, LOCAL7 } - - enum MAX_MEMORY_POLICY_OPTIONS { + + public enum MAX_MEMORY_POLICY_OPTIONS { + VOLATILE_LRU, ALLKEYS_LRU, VOLATILE_RANDOM, @@ -112,14 +132,16 @@ public class RedisRunner { VOLATILE_TTL, NOEVICTION } - - enum APPEND_FSYNC_MODE_OPTIONS { + + public enum APPEND_FSYNC_MODE_OPTIONS { + ALWAYS, EVERYSEC, NO } - - enum KEYSPACE_EVENTS_OPTIONS { + + public enum KEYSPACE_EVENTS_OPTIONS { + K, E, g, @@ -132,21 +154,18 @@ public class RedisRunner { e, A } - - enum CLIENT_CLASS_OPTIONS { - NORMAL, - SLAVE, - PUBSUB - } + private static final String redisFolder = "C:\\Devel\\projects\\redis\\Redis-x64-3.0.500\\"; private static final String redisBinary = redisFolder + "redis-server.exe"; - + private final LinkedHashMap<OPTIONS, String> options = new LinkedHashMap<>(); { - options.put(OPTIONS.BINARY_PATH, Optional.ofNullable(System.getProperty("redisBinary")).orElse(redisBinary)); + options.put(OPTIONS.BINARY_PATH, + Optional.ofNullable(System.getProperty("redisBinary")) + .orElse(redisBinary)); } - + /** * To change the <b>redisBinary</b> system property for running the test, * use <i>argLine</i> option from surefire plugin: @@ -166,7 +185,8 @@ public class RedisRunner { URL resource = RedisRunner.class.getResource(configPath); ProcessBuilder master = new ProcessBuilder( - Optional.ofNullable(System.getProperty("redisBinary")).orElse(redisBinary), + Optional.ofNullable(System.getProperty("redisBinary")) + .orElse(redisBinary), resource.getFile().substring(1)); master.directory(new File(redisFolder)); Process p = master.start(); @@ -175,39 +195,73 @@ public class RedisRunner { } private void addConfigOption(OPTIONS option, String... args) { - StringBuilder sb = new StringBuilder("--"); - sb.append(option.toString().replaceAll("_", "-").toLowerCase()); - sb.append(" "); - sb.append(Arrays.stream(args).collect(Collectors.joining(" "))); - this.options.put(option, sb.toString()); + StringBuilder sb = new StringBuilder(" --") + .append(option.toString() + .replaceAll("_", "-") + .replaceAll("\\$", " ") + .toLowerCase()) + .append(" ") + .append(Arrays.stream(args) + .collect(Collectors.joining(" "))); + this.options.put(option, + option.isAllowMultiple() + ? sb.insert(0, this.options.getOrDefault(option, "")).toString() + : sb.toString()); } - + private String convertBoolean(boolean b) { return b ? "yes" : "no"; } - + public RedisRunner daemonize(boolean daemonize) { addConfigOption(OPTIONS.DAEMONIZE, convertBoolean(daemonize)); return this; } - + public RedisRunner pidfile(String pidfile) { addConfigOption(OPTIONS.PIDFILE, pidfile); return this; } - + public RedisRunner port(int port) { addConfigOption(OPTIONS.PORT, port + ""); return this; } - + public RedisRunner tcpBacklog(int tcpBacklog) { addConfigOption(OPTIONS.TCP_BACKLOG, "" + tcpBacklog); return this; } + + public RedisRunner bind(String bind) { + addConfigOption(OPTIONS.BIND, bind); + return this; + } + + public RedisRunner timeout(long timeout) { + addConfigOption(OPTIONS.TIMEOUT, "" + timeout); + return this; + } + + public RedisRunner tcpKeepalive(long tcpKeepalive) { + addConfigOption(OPTIONS.TCP_KEEPALIVE, "" + tcpKeepalive); + return this; + } + public RedisRunner loglevel(LOGLEVEL_OPTIONS loglevel) { + addConfigOption(OPTIONS.LOGLEVEL, loglevel.toString()); + return this; + } + + public RedisRunner logfile(String logfile) { + addConfigOption(OPTIONS.LOGLEVEL, logfile); + return this; + } + public Process run() throws IOException, InterruptedException { - ProcessBuilder master = new ProcessBuilder(options.values().stream().collect(Collectors.joining(" "))); + ProcessBuilder master = new ProcessBuilder( + options.values().stream() + .collect(Collectors.joining())); master.directory(new File(redisBinary).getParentFile()); Process p = master.start(); Thread.sleep(1000); From 6ef404b2782ee6a1779ef5ab3e6045d4277ec81b Mon Sep 17 00:00:00 2001 From: jackygurui <jackygurui@gmail.com> Date: Thu, 17 Mar 2016 00:13:55 +0000 Subject: [PATCH 5/6] WIP update --- src/test/java/org/redisson/RedisRunner.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/java/org/redisson/RedisRunner.java b/src/test/java/org/redisson/RedisRunner.java index d4c4db1b6..f04506021 100644 --- a/src/test/java/org/redisson/RedisRunner.java +++ b/src/test/java/org/redisson/RedisRunner.java @@ -238,6 +238,16 @@ public class RedisRunner { return this; } + public RedisRunner unixsocket(String unixsocket) { + addConfigOption(OPTIONS.UNIXSOCKET, unixsocket); + return this; + } + + public RedisRunner unixsocketperm(String unixsocketperm) { + addConfigOption(OPTIONS.UNIXSOCKETPERM, unixsocketperm); + return this; + } + public RedisRunner timeout(long timeout) { addConfigOption(OPTIONS.TIMEOUT, "" + timeout); return this; From 4caa8f48294588a5fd3941c2192eb5d4a5ee1785 Mon Sep 17 00:00:00 2001 From: jackygurui <jackygurui@gmail.com> Date: Fri, 18 Mar 2016 01:40:26 +0000 Subject: [PATCH 6/6] Completed RedisRunner mods * RedisRunner now able to launch redis-server using command line options. * Added RedisProcess class which wraps Process class and ensures unified exit code value in both windows and Mac/Unix/Linux. * Removed argLine configuration from surefire plugin in pom.xml because it shadows the command line options. * Changed test files to launch redis-server programmatically. --- pom.xml | 3 - src/test/java/org/redisson/RedisRunner.java | 441 ++++++++++++++++-- .../org/redisson/RedissonMultiLockTest.java | 35 +- src/test/java/org/redisson/RedissonTest.java | 31 +- 4 files changed, 444 insertions(+), 66 deletions(-) diff --git a/pom.xml b/pom.xml index 2411aa90c..8907f379a 100644 --- a/pom.xml +++ b/pom.xml @@ -351,9 +351,6 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.16</version> - <configuration> - <argLine>-Dfile.encoding=utf-8</argLine> - </configuration> </plugin> <plugin> diff --git a/src/test/java/org/redisson/RedisRunner.java b/src/test/java/org/redisson/RedisRunner.java index f04506021..54a152693 100644 --- a/src/test/java/org/redisson/RedisRunner.java +++ b/src/test/java/org/redisson/RedisRunner.java @@ -1,16 +1,24 @@ package org.redisson; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; +import java.io.InputStreamReader; +import java.net.Inet4Address; import java.net.URL; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; +import java.util.Locale; import java.util.Optional; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Collectors; public class RedisRunner { - public enum OPTIONS { + public enum REDIS_OPTIONS { BINARY_PATH, DAEMONIZE, @@ -54,7 +62,7 @@ public class RedisRunner { MAXMEMORY, MAXMEMORY_POLICY, MAXMEMORY_SAMPLE, - APPEND_ONLY, + APPENDONLY, APPENDFILENAME, APPENDFSYNC, NO_APPENDFSYNC_ON_REWRITE, @@ -89,11 +97,11 @@ public class RedisRunner { private final boolean allowMutiple; - private OPTIONS() { + private REDIS_OPTIONS() { this.allowMutiple = false; } - private OPTIONS(boolean allowMutiple) { + private REDIS_OPTIONS(boolean allowMutiple) { this.allowMutiple = allowMutiple; } @@ -155,15 +163,17 @@ public class RedisRunner { A } - private static final String redisFolder = "C:\\Devel\\projects\\redis\\Redis-x64-3.0.500\\"; - private static final String redisBinary = redisFolder + "redis-server.exe"; + private static final String redisBinary; - private final LinkedHashMap<OPTIONS, String> options = new LinkedHashMap<>(); + private final LinkedHashMap<REDIS_OPTIONS, String> options = new LinkedHashMap<>(); + + static { + redisBinary = Optional.ofNullable(System.getProperty("redisBinary")) + .orElse("C:\\Devel\\projects\\redis\\Redis-x64-3.0.500\\redis-server.exe"); + } { - options.put(OPTIONS.BINARY_PATH, - Optional.ofNullable(System.getProperty("redisBinary")) - .orElse(redisBinary)); + this.options.put(REDIS_OPTIONS.BINARY_PATH, redisBinary); } /** @@ -181,21 +191,40 @@ public class RedisRunner { * <a href="http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#argLine"> * http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#argLine</a> */ - public static Process runRedisWithConfigFile(String configPath) throws IOException, InterruptedException { + public static RedisProcess runRedisWithConfigFile(String configPath) throws IOException, InterruptedException { URL resource = RedisRunner.class.getResource(configPath); + return runWithOptions(redisBinary, resource.getFile()); + } - ProcessBuilder master = new ProcessBuilder( - Optional.ofNullable(System.getProperty("redisBinary")) - .orElse(redisBinary), - resource.getFile().substring(1)); - master.directory(new File(redisFolder)); + private static RedisProcess runWithOptions(String... options) throws IOException, InterruptedException { + System.out.println("REDIS LAUNCH OPTIONS: " + Arrays.toString(options)); + ProcessBuilder master = new ProcessBuilder(options) + .redirectErrorStream(true) + .directory(new File(redisBinary).getParentFile()); Process p = master.start(); + new Thread(() -> { + BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); + String line; + try { + while (p.isAlive() && (line = reader.readLine()) != null) { + System.out.println("REDIS PROCESS: " + line); + } + } catch (IOException ex) { + System.out.println("Exception: " + ex.getLocalizedMessage()); + } + }).start(); Thread.sleep(1000); - return p; + return new RedisProcess(p); + } + + + + public RedisProcess run() throws IOException, InterruptedException { + return runWithOptions(options.values().toArray(new String[0])); } - private void addConfigOption(OPTIONS option, String... args) { - StringBuilder sb = new StringBuilder(" --") + private void addConfigOption(REDIS_OPTIONS option, String... args) { + StringBuilder sb = new StringBuilder("--") .append(option.toString() .replaceAll("_", "-") .replaceAll("\\$", " ") @@ -203,7 +232,7 @@ public class RedisRunner { .append(" ") .append(Arrays.stream(args) .collect(Collectors.joining(" "))); - this.options.put(option, + this.options.put(option, option.isAllowMultiple() ? sb.insert(0, this.options.getOrDefault(option, "")).toString() : sb.toString()); @@ -214,68 +243,394 @@ public class RedisRunner { } public RedisRunner daemonize(boolean daemonize) { - addConfigOption(OPTIONS.DAEMONIZE, convertBoolean(daemonize)); + addConfigOption(REDIS_OPTIONS.DAEMONIZE, convertBoolean(daemonize)); return this; } public RedisRunner pidfile(String pidfile) { - addConfigOption(OPTIONS.PIDFILE, pidfile); + addConfigOption(REDIS_OPTIONS.PIDFILE, pidfile); return this; } public RedisRunner port(int port) { - addConfigOption(OPTIONS.PORT, port + ""); + addConfigOption(REDIS_OPTIONS.PORT, "" + port); return this; } - public RedisRunner tcpBacklog(int tcpBacklog) { - addConfigOption(OPTIONS.TCP_BACKLOG, "" + tcpBacklog); + public RedisRunner tcpBacklog(long tcpBacklog) { + addConfigOption(REDIS_OPTIONS.TCP_BACKLOG, "" + tcpBacklog); return this; } public RedisRunner bind(String bind) { - addConfigOption(OPTIONS.BIND, bind); + addConfigOption(REDIS_OPTIONS.BIND, bind); return this; } public RedisRunner unixsocket(String unixsocket) { - addConfigOption(OPTIONS.UNIXSOCKET, unixsocket); + addConfigOption(REDIS_OPTIONS.UNIXSOCKET, unixsocket); return this; } - public RedisRunner unixsocketperm(String unixsocketperm) { - addConfigOption(OPTIONS.UNIXSOCKETPERM, unixsocketperm); + public RedisRunner unixsocketperm(int unixsocketperm) { + addConfigOption(REDIS_OPTIONS.UNIXSOCKETPERM, "" + unixsocketperm); return this; } public RedisRunner timeout(long timeout) { - addConfigOption(OPTIONS.TIMEOUT, "" + timeout); + addConfigOption(REDIS_OPTIONS.TIMEOUT, "" + timeout); return this; } public RedisRunner tcpKeepalive(long tcpKeepalive) { - addConfigOption(OPTIONS.TCP_KEEPALIVE, "" + tcpKeepalive); + addConfigOption(REDIS_OPTIONS.TCP_KEEPALIVE, "" + tcpKeepalive); return this; } - + public RedisRunner loglevel(LOGLEVEL_OPTIONS loglevel) { - addConfigOption(OPTIONS.LOGLEVEL, loglevel.toString()); + addConfigOption(REDIS_OPTIONS.LOGLEVEL, loglevel.toString()); return this; } - + public RedisRunner logfile(String logfile) { - addConfigOption(OPTIONS.LOGLEVEL, logfile); + addConfigOption(REDIS_OPTIONS.LOGLEVEL, logfile); return this; } - public Process run() throws IOException, InterruptedException { - ProcessBuilder master = new ProcessBuilder( - options.values().stream() - .collect(Collectors.joining())); - master.directory(new File(redisBinary).getParentFile()); - Process p = master.start(); - Thread.sleep(1000); - return p; + public RedisRunner syslogEnabled(boolean syslogEnabled) { + addConfigOption(REDIS_OPTIONS.SYSLOG_ENABLED, convertBoolean(syslogEnabled)); + return this; + } + + public RedisRunner syslogIdent(String syslogIdent) { + addConfigOption(REDIS_OPTIONS.SYSLOG_IDENT, syslogIdent); + return this; + } + + public RedisRunner syslogFacility(SYSLOG_FACILITY_OPTIONS syslogFacility) { + addConfigOption(REDIS_OPTIONS.SYSLOG_IDENT, syslogFacility.toString()); + return this; + } + + public RedisRunner databases(int databases) { + addConfigOption(REDIS_OPTIONS.DATABASES, "" + databases); + return this; + } + + public RedisRunner save(long seconds, long changes) { + addConfigOption(REDIS_OPTIONS.SAVE, "" + seconds, "" + changes); + return this; + } + + public RedisRunner stopWritesOnBgsaveError(boolean stopWritesOnBgsaveError) { + addConfigOption(REDIS_OPTIONS.STOP_WRITES_ON_BGSAVE_ERROR, convertBoolean(stopWritesOnBgsaveError)); + return this; + } + + public RedisRunner rdbcompression(boolean rdbcompression) { + addConfigOption(REDIS_OPTIONS.RDBCOMPRESSION, convertBoolean(rdbcompression)); + return this; + } + + public RedisRunner rdbchecksum(boolean rdbchecksum) { + addConfigOption(REDIS_OPTIONS.RDBCHECKSUM, convertBoolean(rdbchecksum)); + return this; + } + + public RedisRunner dbfilename(String dbfilename) { + addConfigOption(REDIS_OPTIONS.DBFILENAME, dbfilename); + return this; + } + + public RedisRunner dir(String dir) { + addConfigOption(REDIS_OPTIONS.DIR, dir); + return this; + } + + public RedisRunner slaveof(Inet4Address masterip, int port) { + addConfigOption(REDIS_OPTIONS.SLAVEOF, masterip.getHostAddress(), "" + port); + return this; + } + + public RedisRunner masterauth(String masterauth) { + addConfigOption(REDIS_OPTIONS.MASTERAUTH, masterauth); + return this; + } + + public RedisRunner slaveServeStaleData(boolean slaveServeStaleData) { + addConfigOption(REDIS_OPTIONS.SLAVE_SERVE_STALE_DATA, convertBoolean(slaveServeStaleData)); + return this; + } + + public RedisRunner slaveReadOnly(boolean slaveReadOnly) { + addConfigOption(REDIS_OPTIONS.SLAVE_READ_ONLY, convertBoolean(slaveReadOnly)); + return this; + } + + public RedisRunner replDisklessSync(boolean replDisklessSync) { + addConfigOption(REDIS_OPTIONS.REPL_DISKLESS_SYNC, convertBoolean(replDisklessSync)); + return this; + } + + public RedisRunner replDisklessSyncDelay(long replDisklessSyncDelay) { + addConfigOption(REDIS_OPTIONS.REPL_DISKLESS_SYNC_DELAY, "" + replDisklessSyncDelay); + return this; + } + + public RedisRunner replPingSlavePeriod(long replPingSlavePeriod) { + addConfigOption(REDIS_OPTIONS.REPL_PING_SLAVE_PERIOD, "" + replPingSlavePeriod); + return this; + } + + public RedisRunner replTimeout(long replTimeout) { + addConfigOption(REDIS_OPTIONS.REPL_TIMEOUT, "" + replTimeout); + return this; + } + + public RedisRunner replDisableTcpNodelay(boolean replDisableTcpNodelay) { + addConfigOption(REDIS_OPTIONS.REPL_DISABLE_TCP_NODELAY, convertBoolean(replDisableTcpNodelay)); + return this; + } + + public RedisRunner replBacklogSize(String replBacklogSize) { + addConfigOption(REDIS_OPTIONS.REPL_BACKLOG_SIZE, "" + replBacklogSize); + return this; + } + + public RedisRunner replBacklogTtl(long replBacklogTtl) { + addConfigOption(REDIS_OPTIONS.REPL_BACKLOG_TTL, "" + replBacklogTtl); + return this; + } + + public RedisRunner slavePriority(long slavePriority) { + addConfigOption(REDIS_OPTIONS.SLAVE_PRIORITY, "" + slavePriority); + return this; + } + + public RedisRunner minSlaveToWrite(long minSlaveToWrite) { + addConfigOption(REDIS_OPTIONS.MIN_SLAVES_TO_WRITE, "" + minSlaveToWrite); + return this; + } + + public RedisRunner minSlaveMaxLag(long minSlaveMaxLag) { + addConfigOption(REDIS_OPTIONS.MIN_SLAVES_MAX_LAG, "" + minSlaveMaxLag); + return this; + } + + public RedisRunner requirepass(String requirepass) { + addConfigOption(REDIS_OPTIONS.REQUREPASS, requirepass); + return this; + } + + public RedisRunner renameCommand(String renameCommand) { + addConfigOption(REDIS_OPTIONS.RENAME_COMMAND, renameCommand); + return this; + } + + public RedisRunner maxclients(long maxclients) { + addConfigOption(REDIS_OPTIONS.MAXCLIENTS, "" + maxclients); + return this; + } + + public RedisRunner maxmemory(String maxmemory) { + addConfigOption(REDIS_OPTIONS.MAXMEMORY, "" + maxmemory); + return this; + } + + public RedisRunner maxmemoryPolicy(MAX_MEMORY_POLICY_OPTIONS maxmemoryPolicy) { + addConfigOption(REDIS_OPTIONS.MAXMEMORY, maxmemoryPolicy.toString()); + return this; + } + + public RedisRunner maxmemorySamples(long maxmemorySamples) { + addConfigOption(REDIS_OPTIONS.MAXMEMORY, "" + maxmemorySamples); + return this; + } + + public RedisRunner appendonly(boolean appendonly) { + addConfigOption(REDIS_OPTIONS.APPENDONLY, convertBoolean(appendonly)); + return this; + } + + public RedisRunner appendfilename(String appendfilename) { + addConfigOption(REDIS_OPTIONS.APPENDFILENAME, appendfilename); + return this; + } + + public RedisRunner appendfsync(APPEND_FSYNC_MODE_OPTIONS appendfsync) { + addConfigOption(REDIS_OPTIONS.APPENDFSYNC, appendfsync.toString()); + return this; + } + + public RedisRunner noAppendfsyncOnRewrite(boolean noAppendfsyncOnRewrite) { + addConfigOption(REDIS_OPTIONS.NO_APPENDFSYNC_ON_REWRITE, convertBoolean(noAppendfsyncOnRewrite)); + return this; + } + + public RedisRunner autoAofRewritePercentage(int autoAofRewritePercentage) { + addConfigOption(REDIS_OPTIONS.AUTO_AOF_REWRITE_PERCENTAGE, "" + autoAofRewritePercentage); + return this; + } + + public RedisRunner autoAofRewriteMinSize(String autoAofRewriteMinSize) { + addConfigOption(REDIS_OPTIONS.AUTO_AOF_REWRITE_MIN_SIZE, autoAofRewriteMinSize); + return this; + } + + public RedisRunner aofLoadTruncated(boolean aofLoadTruncated) { + addConfigOption(REDIS_OPTIONS.AOF_LOAD_TRUNCATED, convertBoolean(aofLoadTruncated)); + return this; + } + + public RedisRunner luaTimeLimit(long luaTimeLimit) { + addConfigOption(REDIS_OPTIONS.AOF_LOAD_TRUNCATED, "" + luaTimeLimit); + return this; + } + + public RedisRunner clusterEnabled(boolean clusterEnabled) { + addConfigOption(REDIS_OPTIONS.CLUSTER_ENABLED, convertBoolean(clusterEnabled)); + return this; + } + + public RedisRunner clusterConfigFile(String clusterConfigFile) { + addConfigOption(REDIS_OPTIONS.CLUSTER_CONFIG_FILE, clusterConfigFile); + return this; + } + + public RedisRunner clusterNodeTimeout(long clusterNodeTimeout) { + addConfigOption(REDIS_OPTIONS.CLUSTER_NODE_TIMEOUT, "" + clusterNodeTimeout); + return this; + } + + public RedisRunner clusterSlaveValidityFactor(long clusterSlaveValidityFactor) { + addConfigOption(REDIS_OPTIONS.CLUSTER_SLAVE_VALIDITY_FACTOR, "" + clusterSlaveValidityFactor); + return this; + } + + public RedisRunner clusterMigrationBarrier(long clusterMigrationBarrier) { + addConfigOption(REDIS_OPTIONS.CLUSTER_MIGRATION_BARRIER, "" + clusterMigrationBarrier); + return this; + } + + public RedisRunner clusterRequireFullCoverage(boolean clusterRequireFullCoverage) { + addConfigOption(REDIS_OPTIONS.CLUSTER_REQUIRE_FULL_COVERAGE, convertBoolean(clusterRequireFullCoverage)); + return this; + } + + public RedisRunner slowlogLogSlowerThan(long slowlogLogSlowerThan) { + addConfigOption(REDIS_OPTIONS.SLOWLOG_LOG_SLOWER_THAN, "" + slowlogLogSlowerThan); + return this; + } + + public RedisRunner slowlogMaxLen(long slowlogMaxLen) { + addConfigOption(REDIS_OPTIONS.SLOWLOG_MAX_LEN, "" + slowlogMaxLen); + return this; + } + + public RedisRunner latencyMonitorThreshold(long latencyMonitorThreshold) { + addConfigOption(REDIS_OPTIONS.LATENCY_MONITOR_THRESHOLD, "" + latencyMonitorThreshold); + return this; + } + + public RedisRunner notifyKeyspaceEvents(KEYSPACE_EVENTS_OPTIONS notifyKeyspaceEvents) { + String existing = this.options.getOrDefault(REDIS_OPTIONS.CLUSTER_CONFIG_FILE, ""); + addConfigOption(REDIS_OPTIONS.CLUSTER_CONFIG_FILE, + existing.contains(notifyKeyspaceEvents.toString()) + ? existing + : (existing + notifyKeyspaceEvents.toString())); + return this; + } + + public RedisRunner hashMaxZiplistEntries(long hashMaxZiplistEntries) { + addConfigOption(REDIS_OPTIONS.HASH_MAX_ZIPLIST_ENTRIES, "" + hashMaxZiplistEntries); + return this; + } + + public RedisRunner hashMaxZiplistValue(long hashMaxZiplistValue) { + addConfigOption(REDIS_OPTIONS.HASH_MAX_ZIPLIST_VALUE, "" + hashMaxZiplistValue); + return this; + } + + public RedisRunner listMaxZiplistEntries(long listMaxZiplistEntries) { + addConfigOption(REDIS_OPTIONS.LIST_MAX_ZIPLIST_ENTRIES, "" + listMaxZiplistEntries); + return this; + } + + public RedisRunner listMaxZiplistValue(long listMaxZiplistValue) { + addConfigOption(REDIS_OPTIONS.LIST_MAX_ZIPLIST_VALUE, "" + listMaxZiplistValue); + return this; + } + + public RedisRunner setMaxIntsetEntries(long setMaxIntsetEntries) { + addConfigOption(REDIS_OPTIONS.SET_MAX_INTSET_ENTRIES, "" + setMaxIntsetEntries); + return this; + } + + public RedisRunner zsetMaxZiplistEntries(long zsetMaxZiplistEntries) { + addConfigOption(REDIS_OPTIONS.ZSET_MAX_ZIPLIST_ENTRIES, "" + zsetMaxZiplistEntries); + return this; + } + + public RedisRunner zsetMaxZiplistValue(long zsetMaxZiplistValue) { + addConfigOption(REDIS_OPTIONS.ZSET_MAX_ZIPLIST_VALUE, "" + zsetMaxZiplistValue); + return this; + } + + public RedisRunner hllSparseMaxBytes(long hllSparseMaxBytes) { + addConfigOption(REDIS_OPTIONS.HLL_SPARSE_MAX_BYTES, "" + hllSparseMaxBytes); + return this; } + public RedisRunner activerehashing(boolean activerehashing) { + addConfigOption(REDIS_OPTIONS.ACTIVEREHASHING, convertBoolean(activerehashing)); + return this; + } + + public RedisRunner clientOutputBufferLimit$Normal(String hardLimit, String softLimit, long softSeconds) { + addConfigOption(REDIS_OPTIONS.CLIENT_OUTPUT_BUFFER_LIMIT$NORMAL, hardLimit, softLimit, "" + softSeconds); + return this; + } + + public RedisRunner clientOutputBufferLimit$Slave(String hardLimit, String softLimit, long softSeconds) { + addConfigOption(REDIS_OPTIONS.CLIENT_OUTPUT_BUFFER_LIMIT$SLAVE, hardLimit, softLimit, "" + softSeconds); + return this; + } + + public RedisRunner clientOutputBufferLimit$Pubsub(String hardLimit, String softLimit, long softSeconds) { + addConfigOption(REDIS_OPTIONS.CLIENT_OUTPUT_BUFFER_LIMIT$PUBSUB, hardLimit, softLimit, "" + softSeconds); + return this; + } + + public RedisRunner hz(int hz) { + addConfigOption(REDIS_OPTIONS.HZ, "" + hz); + return this; + } + + public RedisRunner aofRewriteIncrementalFsync(boolean aofRewriteIncrementalFsync) { + addConfigOption(REDIS_OPTIONS.AOF_REWRITE_INCREMENTAL_FSYNC, convertBoolean(aofRewriteIncrementalFsync)); + return this; + } + + public static final class RedisProcess { + private final Process redisProcess; + + private RedisProcess(Process redisProcess) { + this.redisProcess = redisProcess; + } + + public int stop() throws InterruptedException { + redisProcess.destroy(); + int exitCode = redisProcess.waitFor(); + return exitCode == 1 && isWindows() ? 0 : exitCode ; + } + + public Process getRedisProcess() { + return redisProcess; + } + + private boolean isWindows() { + return System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH).contains("win"); + } + } + } diff --git a/src/test/java/org/redisson/RedissonMultiLockTest.java b/src/test/java/org/redisson/RedissonMultiLockTest.java index 22e0cd1e7..9b5446a80 100644 --- a/src/test/java/org/redisson/RedissonMultiLockTest.java +++ b/src/test/java/org/redisson/RedissonMultiLockTest.java @@ -12,14 +12,15 @@ import org.redisson.core.RLock; import org.redisson.core.RedissonMultiLock; import io.netty.channel.nio.NioEventLoopGroup; +import org.redisson.RedisRunner.RedisProcess; public class RedissonMultiLockTest { @Test public void test() throws IOException, InterruptedException { - Process redis1 = RedisRunner.runRedisWithConfigFile("/redis_multiLock_test_instance1.conf"); - Process redis2 = RedisRunner.runRedisWithConfigFile("/redis_multiLock_test_instance2.conf"); - Process redis3 = RedisRunner.runRedisWithConfigFile("/redis_multiLock_test_instance3.conf"); + RedisProcess redis1 = redisTestMultilockInstance1(); + RedisProcess redis2 = redisTestMultilockInstance2(); + RedisProcess redis3 = redisTestMultilockInstance3(); NioEventLoopGroup group = new NioEventLoopGroup(); Config config1 = new Config(); @@ -65,14 +66,28 @@ public class RedissonMultiLockTest { lock.unlock(); - redis1.destroy(); - assertThat(redis1.waitFor()).isEqualTo(1); + assertThat(redis1.stop()).isEqualTo(0); - redis2.destroy(); - assertThat(redis2.waitFor()).isEqualTo(1); + assertThat(redis2.stop()).isEqualTo(0); - redis3.destroy(); - assertThat(redis3.waitFor()).isEqualTo(1); + assertThat(redis3.stop()).isEqualTo(0); + } + + private RedisProcess redisTestMultilockInstance1() throws IOException, InterruptedException { + return new RedisRunner() + .port(6320) + .run(); + } + + private RedisProcess redisTestMultilockInstance2() throws IOException, InterruptedException { + return new RedisRunner() + .port(6321) + .run(); + } + + private RedisProcess redisTestMultilockInstance3() throws IOException, InterruptedException { + return new RedisRunner() + .port(6322) + .run(); } - } diff --git a/src/test/java/org/redisson/RedissonTest.java b/src/test/java/org/redisson/RedissonTest.java index 73588a006..1cbeff418 100644 --- a/src/test/java/org/redisson/RedissonTest.java +++ b/src/test/java/org/redisson/RedissonTest.java @@ -41,6 +41,7 @@ import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.util.concurrent.GenericFutureListener; import static com.jayway.awaitility.Awaitility.*; +import org.redisson.RedisRunner.RedisProcess; public class RedissonTest { @@ -61,7 +62,7 @@ public class RedissonTest { @Test(expected = RedisOutOfMemoryException.class) public void testMemoryScript() throws IOException, InterruptedException { - Process p = RedisRunner.runRedisWithConfigFile("/redis_oom_test.conf"); + RedisProcess p = redisTestSmallMemory(); Config config = new Config(); config.useSingleServer().setAddress("127.0.0.1:6319").setTimeout(100000); @@ -72,13 +73,13 @@ public class RedissonTest { r.getMap("test").put("" + i, "" + i); } } finally { - p.destroy(); + p.stop(); } } @Test(expected = RedisOutOfMemoryException.class) public void testMemoryCommand() throws IOException, InterruptedException { - Process p = RedisRunner.runRedisWithConfigFile("/redis_oom_test.conf"); + RedisProcess p = redisTestSmallMemory(); Config config = new Config(); config.useSingleServer().setAddress("127.0.0.1:6319").setTimeout(100000); @@ -89,7 +90,7 @@ public class RedissonTest { r.getMap("test").fastPut("" + i, "" + i); } } finally { - p.destroy(); + p.stop(); } } @@ -97,7 +98,7 @@ public class RedissonTest { @Test public void testConnectionListener() throws IOException, InterruptedException, TimeoutException { - Process p = RedisRunner.runRedisWithConfigFile("/redis_connectionListener_test.conf"); + RedisProcess p = redisTestConnection(); final AtomicInteger connectCounter = new AtomicInteger(); final AtomicInteger disconnectCounter = new AtomicInteger(); @@ -126,22 +127,20 @@ public class RedissonTest { assertThat(id).isNotZero(); r.getBucket("1").get(); - p.destroy(); - Assert.assertEquals(1, p.waitFor()); + Assert.assertEquals(0, p.stop()); try { r.getBucket("1").get(); } catch (Exception e) { } - p = RedisRunner.runRedisWithConfigFile("/redis_connectionListener_test.conf"); + p = redisTestConnection(); r.getBucket("1").get(); r.shutdown(); - p.destroy(); - Assert.assertEquals(1, p.waitFor()); + Assert.assertEquals(0, p.stop()); await().atMost(1, TimeUnit.SECONDS).until(() -> assertThat(connectCounter.get()).isEqualTo(2)); await().until(() -> assertThat(disconnectCounter.get()).isEqualTo(1)); @@ -282,5 +281,17 @@ public class RedissonTest { r.shutdown(); } + private RedisProcess redisTestSmallMemory() throws IOException, InterruptedException { + return new RedisRunner() + .maxmemory("1mb") + .port(6319) + .run(); + } + private RedisProcess redisTestConnection() throws IOException, InterruptedException { + return new RedisRunner() + .port(6319) + .run(); + } + }