You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by za...@apache.org on 2021/02/12 13:06:24 UTC

[calcite] branch master updated: [CALCITE-4344] Run Redis tests using Docker containers

This is an automated email from the ASF dual-hosted git repository.

zabetak pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new 7f92a46  [CALCITE-4344] Run Redis tests using Docker containers
7f92a46 is described below

commit 7f92a46dfc00e6c0af09d639b02c5e0ebeeeb23d
Author: Tugdual Grall <tu...@gmail.com>
AuthorDate: Sun Oct 18 08:12:49 2020 +0200

    [CALCITE-4344] Run Redis tests using Docker containers
    
    Close apache/calcite#2223
---
 bom/build.gradle.kts                               |  1 +
 .../calcite/config/CalciteSystemProperty.java      | 17 ++++++
 gradle.properties                                  |  1 +
 redis/build.gradle.kts                             |  1 +
 .../adapter/redis/RedisAdapterCaseBase.java        |  2 +-
 .../calcite/adapter/redis/RedisCaseBase.java       | 67 +++++++++++++++++++---
 .../calcite/adapter/redis/RedisDataCaseBase.java   |  8 ++-
 7 files changed, 87 insertions(+), 10 deletions(-)

diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts
index 3de4e44..83c54c5 100644
--- a/bom/build.gradle.kts
+++ b/bom/build.gradle.kts
@@ -146,6 +146,7 @@ dependencies {
         apiv("org.scala-lang:scala-library")
         apiv("org.slf4j:slf4j-api", "slf4j")
         apiv("org.slf4j:slf4j-log4j12", "slf4j")
+        apiv("org.testcontainers:testcontainers")
         apiv("redis.clients:jedis")
         apiv("sqlline:sqlline")
         runtimev("org.junit.jupiter:junit-jupiter-engine", "junit5")
diff --git a/core/src/main/java/org/apache/calcite/config/CalciteSystemProperty.java b/core/src/main/java/org/apache/calcite/config/CalciteSystemProperty.java
index 30d9617..87b6f66 100644
--- a/core/src/main/java/org/apache/calcite/config/CalciteSystemProperty.java
+++ b/core/src/main/java/org/apache/calcite/config/CalciteSystemProperty.java
@@ -242,6 +242,23 @@ public final class CalciteSystemProperty<T> {
       booleanProperty("calcite.test.redis", true);
 
   /**
+   * Whether to use Docker containers (https://www.testcontainers.org/) in tests.
+   *
+   * If the property is set to <code>true</code>, affected tests will attempt to start Docker
+   * containers; when Docker is not available tests fallback to other execution modes and if it's
+   * not possible they are skipped entirely.
+   *
+   * If the property is set to <code>false</code>, Docker containers are not used at all and
+   * affected tests either fallback to other execution modes or skipped entirely.
+   *
+   * Users can override the default behavior to force non-Dockerized execution even when Docker
+   * is installed on the machine; this can be useful for replicating an issue that appears only in
+   * non-docker test mode or for running tests both with & without containers in CI.
+   */
+  public static final CalciteSystemProperty<Boolean> TEST_WITH_DOCKER_CONTAINER =
+      booleanProperty("calcite.test.docker", true);
+
+  /**
    * A list of ids designating the queries
    * (from query.json in new.hydromatic:foodmart-queries:0.4.1)
    * that should be run as part of FoodmartTest.
diff --git a/gradle.properties b/gradle.properties
index 55ab23c..99382e2 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -141,6 +141,7 @@ slf4j.version=1.7.25
 spark.version=2.2.2
 sqlline.version=1.9.0
 teradata.tpcds.version=1.2
+testcontainers.version=1.15.1
 tpch.version=1.0
 uzaygezen.version=0.2
 xalan.version=2.7.1
diff --git a/redis/build.gradle.kts b/redis/build.gradle.kts
index 248d3dc..22d27c2 100644
--- a/redis/build.gradle.kts
+++ b/redis/build.gradle.kts
@@ -33,4 +33,5 @@ dependencies {
     testImplementation("com.github.kstyrc:embedded-redis")
     testImplementation("org.mockito:mockito-core")
     testRuntimeOnly("org.slf4j:slf4j-log4j12")
+    testImplementation("org.testcontainers:testcontainers")
 }
diff --git a/redis/src/test/java/org/apache/calcite/adapter/redis/RedisAdapterCaseBase.java b/redis/src/test/java/org/apache/calcite/adapter/redis/RedisAdapterCaseBase.java
index 503acb0..f1d564a 100644
--- a/redis/src/test/java/org/apache/calcite/adapter/redis/RedisAdapterCaseBase.java
+++ b/redis/src/test/java/org/apache/calcite/adapter/redis/RedisAdapterCaseBase.java
@@ -103,7 +103,7 @@ public class RedisAdapterCaseBase extends RedisDataCaseBase {
       if (file.exists()) {
         JsonNode rootNode = objMapper.readTree(file);
         strResult = rootNode.toString().replace(Integer.toString(Protocol.DEFAULT_PORT),
-            Integer.toString(PORT));
+            Integer.toString(getRedisServerPort()));
       }
     } catch (Exception ignored) {
     }
diff --git a/redis/src/test/java/org/apache/calcite/adapter/redis/RedisCaseBase.java b/redis/src/test/java/org/apache/calcite/adapter/redis/RedisCaseBase.java
index 15af4b8..c139ab7 100644
--- a/redis/src/test/java/org/apache/calcite/adapter/redis/RedisCaseBase.java
+++ b/redis/src/test/java/org/apache/calcite/adapter/redis/RedisCaseBase.java
@@ -16,13 +16,20 @@
  */
 package org.apache.calcite.adapter.redis;
 
+import org.apache.calcite.config.CalciteSystemProperty;
+
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.parallel.Execution;
 import org.junit.jupiter.api.parallel.ExecutionMode;
+import org.testcontainers.DockerClientFactory;
+import org.testcontainers.containers.GenericContainer;
 
 import java.io.IOException;
 import java.net.ServerSocket;
+import java.util.logging.Logger;
 
 import redis.embedded.RedisServer;
 
@@ -32,20 +39,46 @@ import redis.embedded.RedisServer;
 @Execution(ExecutionMode.SAME_THREAD)
 public abstract class RedisCaseBase {
 
-  public static final int PORT = getAvailablePort();
-  public static final String HOST = "127.0.0.1";
+  private static final int PORT = getAvailablePort();
+  private static final String HOST = "127.0.0.1";
   private static final String MAX_HEAP = "maxheap 51200000";
 
+  /**
+   * The Redis Docker container.
+   *
+   * Uses the Redis 2.8.19 version to be aligned with the embedded server.
+   */
+  private static final GenericContainer<?> REDIS_CONTAINER =
+      new GenericContainer<>("redis:2.8.19").withExposedPorts(6379);
+
+  /**
+   * The embedded Redis server.
+   *
+   * With the existing dependencies (com.github.kstyrc:embedded-redis:0.6) it uses by default
+   * Redis 2.8.19 version.
+   */
   private static RedisServer redisServer;
 
+  @BeforeAll
+  public static void startRedisContainer() {
+    // Check if docker is running, and start container if possible
+    if (CalciteSystemProperty.TEST_WITH_DOCKER_CONTAINER.value()
+        && DockerClientFactory.instance().isDockerAvailable()) {
+      REDIS_CONTAINER.start();
+    }
+  }
+
   @BeforeEach
   public void createRedisServer() throws IOException {
-    if (isWindows()) {
-      redisServer = RedisServer.builder().port(PORT).setting(MAX_HEAP).build();
-    } else {
-      redisServer = new RedisServer(PORT);
+    if (!REDIS_CONTAINER.isRunning()) {
+      if (isWindows()) {
+        redisServer = RedisServer.builder().port(PORT).setting(MAX_HEAP).build();
+      } else {
+        redisServer = new RedisServer(PORT);
+      }
+      Logger.getAnonymousLogger().info("Not using Docker, starting RedisMiniServer");
+      redisServer.start();
     }
-    redisServer.start();
   }
 
   private static boolean isWindows() {
@@ -54,7 +87,9 @@ public abstract class RedisCaseBase {
 
   @AfterEach
   public void stopRedisServer() {
-    redisServer.stop();
+    if (!REDIS_CONTAINER.isRunning()) {
+      redisServer.stop();
+    }
   }
 
   /**
@@ -75,4 +110,20 @@ public abstract class RedisCaseBase {
 
     throw new RuntimeException("Could not find an available port on the host.");
   }
+
+  @AfterAll
+  public static void stopRedisContainer() {
+    if (REDIS_CONTAINER != null && REDIS_CONTAINER.isRunning()) {
+      REDIS_CONTAINER.stop();
+    }
+  }
+
+  static int getRedisServerPort() {
+    return  REDIS_CONTAINER.isRunning() ? REDIS_CONTAINER.getMappedPort(6379) : PORT;
+  }
+
+  static String getRedisServerHost() {
+    return REDIS_CONTAINER.isRunning() ? REDIS_CONTAINER.getContainerIpAddress() : HOST;
+  }
+
 }
diff --git a/redis/src/test/java/org/apache/calcite/adapter/redis/RedisDataCaseBase.java b/redis/src/test/java/org/apache/calcite/adapter/redis/RedisDataCaseBase.java
index 6e167f7..eb9923d 100644
--- a/redis/src/test/java/org/apache/calcite/adapter/redis/RedisDataCaseBase.java
+++ b/redis/src/test/java/org/apache/calcite/adapter/redis/RedisDataCaseBase.java
@@ -43,7 +43,13 @@ public class RedisDataCaseBase extends RedisCaseBase {
     try {
       JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
       jedisPoolConfig.setMaxTotal(10);
-      pool = new JedisPool(jedisPoolConfig, HOST, PORT);
+      pool = new JedisPool(jedisPoolConfig,  getRedisServerHost(), getRedisServerPort());
+
+      // Flush all data
+      try (Jedis jedis = pool.getResource()) {
+        jedis.flushAll();
+      }
+
     } catch (Exception e) {
       throw e;
     }