RedisVersionRule.java
package redis.clients.jedis.util;
import io.redis.test.annotations.SinceRedisVersion;
import io.redis.test.utils.RedisInfo;
import io.redis.test.utils.RedisVersion;
import org.junit.Assume;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.EndpointConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisClientConfig;
import java.lang.reflect.Method;
import static redis.clients.jedis.util.RedisVersionUtil.forcedVersion;
public class RedisVersionRule implements TestRule {
private static final Logger logger = LoggerFactory.getLogger(RedisVersionRule.class);
private final HostAndPort hostPort;
private final JedisClientConfig config;
public RedisVersionRule(EndpointConfig endpoint) {
this.hostPort = endpoint.getHostAndPort();
this.config = endpoint.getClientConfigBuilder().build();
}
public RedisVersionRule(HostAndPort hostPort, JedisClientConfig config) {
this.hostPort = hostPort;
this.config = config;
}
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try ( Jedis jedisClient = new Jedis(hostPort, config)) {
SinceRedisVersion descriptionVersionAnnotation = description.getAnnotation(SinceRedisVersion.class);
if (descriptionVersionAnnotation != null) {
checkRedisVersion(jedisClient, descriptionVersionAnnotation);
}
SinceRedisVersion classVersionAnnotation = description.getTestClass().getAnnotation(SinceRedisVersion.class);
if (classVersionAnnotation != null) {
checkRedisVersion(jedisClient, classVersionAnnotation);
}
SinceRedisVersion methodVersionAnnotation = getMethodAnnotation(description);
if (methodVersionAnnotation != null) {
checkRedisVersion(jedisClient, methodVersionAnnotation);
}
// Return the base statement to execute the test
base.evaluate();
}
}
private void checkRedisVersion(Jedis jedisClient, SinceRedisVersion versionAnnotation) {
// Check if the environment variable is set
RedisVersion currentVersion;
if (forcedVersion != null) {
logger.info("Using forced Redis server version from environment variable: " + forcedVersion);
currentVersion = forcedVersion;
} else {
RedisInfo info = RedisInfo.parseInfoServer(jedisClient.info("server"));
currentVersion = RedisVersion.of(info.getRedisVersion());
}
RedisVersion minRequiredVersion = RedisVersion.of(versionAnnotation.value());
if (currentVersion.isLessThan(minRequiredVersion)) {
Assume.assumeTrue("Test requires Redis version " + minRequiredVersion + " or later, but found " + currentVersion, false);
}
}
private SinceRedisVersion getMethodAnnotation(Description description) {
try {
// description.getAnnotation() does not return any method level annotation when used
// with parametrised tests
String methodName = description.getMethodName();
if (methodName != null) {
Class<?> testClass = description.getTestClass();
if (testClass != null) {
for (Method method : testClass.getDeclaredMethods()) {
if (method.getName().equals(methodName)) {
return method.getAnnotation(SinceRedisVersion.class);
}
}
}
}
} catch (Exception e) {
throw new RuntimeException("Could not resolve EnabledOnCommand annotation", e);
}
return null;
}
};
}
}