You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2020/02/13 13:36:21 UTC

[camel] branch master updated: CAMEL-14543: Execute camel-etcd tests with testcontainers

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 639ad83  CAMEL-14543: Execute camel-etcd tests with testcontainers
639ad83 is described below

commit 639ad830b955ae3c85413f008f248cb5e31542c9
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Wed Feb 12 16:35:49 2020 +0100

    CAMEL-14543: Execute camel-etcd tests with testcontainers
---
 components/camel-etcd/pom.xml                      | 40 +++++++--
 .../apache/camel/component/etcd/EtcdKeysTest.java  | 15 ++--
 .../apache/camel/component/etcd/EtcdStatsTest.java |  3 +-
 .../camel/component/etcd/EtcdTestSupport.java      | 46 -----------
 .../apache/camel/component/etcd/EtcdWatchTest.java |  5 +-
 .../etcd/cloud/EtcdServiceCallRouteTest.java       | 11 ++-
 .../etcd/cloud/EtcdServiceDiscoveryTest.java       | 30 ++++---
 .../SpringEtcdServiceCallDefaultRouteTest.java     | 29 +++----
 .../etcd/cloud/SpringEtcdServiceCallRouteTest.java | 33 +++-----
 .../component/etcd/policy/EtcdRoutePolicyMain.java |  2 +-
 .../component/etcd/support/EtcdTestSupport.java    | 95 ++++++++++++++++++++++
 .../etcd/support/SpringEtcdTestSupport.java        | 74 +++++++++++++++++
 .../src/test/resources/log4j2.properties           |  2 +-
 .../SpringEtcdServiceCallDefaultRouteTest.xml      |  2 +-
 .../etcd/cloud/SpringEtcdServiceCallRouteTest.xml  | 12 ++-
 parent/pom.xml                                     |  2 +-
 16 files changed, 279 insertions(+), 122 deletions(-)

diff --git a/components/camel-etcd/pom.xml b/components/camel-etcd/pom.xml
index 7979a35..a91a738 100644
--- a/components/camel-etcd/pom.xml
+++ b/components/camel-etcd/pom.xml
@@ -71,12 +71,12 @@
         <!-- testing -->
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test</artifactId>
+            <artifactId>camel-testcontainers-spring-junit5</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
-            <artifactId>camel-test-spring</artifactId>
+            <artifactId>camel-testcontainers-junit5</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -109,17 +109,47 @@
                 </plugins>
             </build>
         </profile>
+
+        <!-- activate test if the docker socket file is accessible -->
+        <profile>
+            <id>etcd-tests-docker-file</id>
+            <activation>
+                <file>
+                    <exists>/var/run/docker.sock</exists>
+                </file>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <skipTests>${skipTests}</skipTests>
+                            <systemPropertyVariables>
+                                <visibleassertions.silence>true</visibleassertions.silence>
+                            </systemPropertyVariables>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <!-- activate test if the DOCKER_HOST env var is set -->
         <profile>
-            <id>etcd-tests</id>
+            <id>etcd-tests-docker-env</id>
             <activation>
-                <activeByDefault>false</activeByDefault>
+                <property>
+                    <name>env.DOCKER_HOST</name>
+                </property>
             </activation>
             <build>
                 <plugins>
                     <plugin>
                         <artifactId>maven-surefire-plugin</artifactId>
                         <configuration>
-                            <skipTests>false</skipTests>
+                            <skipTests>${skipTests}</skipTests>
+                            <systemPropertyVariables>
+                                <visibleassertions.silence>true</visibleassertions.silence>
+                            </systemPropertyVariables>
                         </configuration>
                     </plugin>
                 </plugins>
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdKeysTest.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdKeysTest.java
index 3e0ac31..9ca98fa 100644
--- a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdKeysTest.java
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdKeysTest.java
@@ -26,12 +26,17 @@ import mousio.etcd4j.responses.EtcdKeysResponse;
 import org.apache.camel.Exchange;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.etcd.support.EtcdTestSupport;
 import org.apache.camel.component.mock.MockEndpoint;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.fail;
 
 public class EtcdKeysTest extends EtcdTestSupport {
 
-    @Test(expected = EtcdException.class)
+    @Test
     public void testKeys() throws Exception {
         final String path = "/camel/" + UUID.randomUUID().toString();
         final String value = UUID.randomUUID().toString();
@@ -102,9 +107,9 @@ public class EtcdKeysTest extends EtcdTestSupport {
         // VALIDATION
         // *******************************************
 
-        client.get(path).send().get();
-
-        fail("EtcdException should have been thrown");
+        assertThrows(EtcdException.class, () -> {
+            client.get(path).send().get();
+        });
     }
 
     @Override
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdStatsTest.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdStatsTest.java
index ab6657b..c9db4c4 100644
--- a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdStatsTest.java
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdStatsTest.java
@@ -22,8 +22,9 @@ import mousio.etcd4j.responses.EtcdStoreStatsResponse;
 import org.apache.camel.Exchange;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.etcd.support.EtcdTestSupport;
 import org.apache.camel.component.mock.MockEndpoint;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class EtcdStatsTest extends EtcdTestSupport {
 
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdTestSupport.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdTestSupport.java
deleted file mode 100644
index c5f28c5..0000000
--- a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdTestSupport.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.etcd;
-
-import java.net.URI;
-
-import mousio.etcd4j.EtcdClient;
-import mousio.etcd4j.responses.EtcdKeysResponse;
-import org.apache.camel.Exchange;
-import org.apache.camel.Processor;
-import org.apache.camel.test.junit4.CamelTestSupport;
-
-public class EtcdTestSupport extends CamelTestSupport {
-    protected static final Processor NODE_TO_VALUE_IN = new Processor() {
-        @Override
-        public void process(Exchange exchange) throws Exception {
-            EtcdKeysResponse response = exchange.getIn().getBody(EtcdKeysResponse.class);
-            if (response != null) {
-                exchange.getIn().setBody(response.node.key + "=" + response.node.value);
-            }
-        }
-    };
-
-    @Override
-    public boolean isCreateCamelContextPerClass() {
-        return false;
-    }
-
-    protected EtcdClient getClient() {
-        return new EtcdClient(URI.create("http://localhost:2379"));
-    }
-}
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdWatchTest.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdWatchTest.java
index a11ba36..d35e609 100644
--- a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdWatchTest.java
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/EtcdWatchTest.java
@@ -20,8 +20,9 @@ import mousio.etcd4j.EtcdClient;
 import mousio.etcd4j.responses.EtcdErrorCode;
 import mousio.etcd4j.responses.EtcdException;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.etcd.support.EtcdTestSupport;
 import org.apache.camel.component.mock.MockEndpoint;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public class EtcdWatchTest extends EtcdTestSupport {
 
@@ -76,7 +77,7 @@ public class EtcdWatchTest extends EtcdTestSupport {
     }
 
     private void testWatch(String mockEndpoint, final String key, int updates) throws Exception {
-        final String[] values = new String[updates];
+        final Object[] values = new String[updates];
         for (int i = 0; i < updates; i++) {
             values[i] = key + "=myValue-" + i;
         }
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/EtcdServiceCallRouteTest.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/EtcdServiceCallRouteTest.java
index f9cbd3c..bb6ca66 100644
--- a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/EtcdServiceCallRouteTest.java
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/EtcdServiceCallRouteTest.java
@@ -27,9 +27,8 @@ import mousio.etcd4j.EtcdClient;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.etcd.EtcdHelper;
-import org.apache.camel.component.etcd.EtcdTestSupport;
-import org.junit.After;
-import org.junit.Test;
+import org.apache.camel.component.etcd.support.EtcdTestSupport;
+import org.junit.jupiter.api.Test;
 
 public class EtcdServiceCallRouteTest extends EtcdTestSupport {
     private static final ObjectMapper MAPPER = EtcdHelper.createObjectMapper();
@@ -66,10 +65,9 @@ public class EtcdServiceCallRouteTest extends EtcdTestSupport {
     }
 
     @Override
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
+    protected void cleanupResources() throws Exception {
         client.deleteDir("/services/").recursive().send().get();
+        super.cleanupResources();
     }
 
     // *************************************************************************
@@ -99,6 +97,7 @@ public class EtcdServiceCallRouteTest extends EtcdTestSupport {
                     .serviceCall()
                         .name(SERVICE_NAME)
                         .etcdServiceDiscovery()
+                            .uris(getClientUri())
                             .type("on-demand")
                         .endParent()
                     .to("log:org.apache.camel.component.etcd.processor.service?level=INFO&showAll=true&multiline=true")
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/EtcdServiceDiscoveryTest.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/EtcdServiceDiscoveryTest.java
index d67fdf1..5289a16 100644
--- a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/EtcdServiceDiscoveryTest.java
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/EtcdServiceDiscoveryTest.java
@@ -27,37 +27,45 @@ import mousio.etcd4j.responses.EtcdException;
 import org.apache.camel.cloud.ServiceDefinition;
 import org.apache.camel.component.etcd.EtcdConfiguration;
 import org.apache.camel.component.etcd.EtcdHelper;
-import org.apache.camel.component.etcd.EtcdTestSupport;
-import org.junit.After;
-import org.junit.Test;
+import org.apache.camel.component.etcd.support.EtcdTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class EtcdServiceDiscoveryTest extends EtcdTestSupport {
     private static final ObjectMapper MAPPER = EtcdHelper.createObjectMapper();
-    private static final EtcdConfiguration CONFIGURATION = new EtcdConfiguration(null);
     private static final AtomicInteger PORT = new AtomicInteger(0);
 
     private EtcdClient client;
+    private EtcdConfiguration configuration;
 
     @Override
     public void doPreSetup() throws Exception {
+        configuration = new EtcdConfiguration();
+        configuration.setCamelContext(context);
+        configuration.setUris(getClientUri());
+
         client = getClient();
         try {
-            client.deleteDir(CONFIGURATION.getServicePath()).recursive().send().get();
+            client.deleteDir(configuration.getServicePath()).recursive().send().get();
         } catch (EtcdException e) {
             // Ignore
         }
     }
 
     @Override
-    @After
-    public void tearDown() throws Exception {
+    protected void cleanupResources() throws Exception {
         try {
-            client.deleteDir(CONFIGURATION.getServicePath()).recursive().send().get();
+            client.deleteDir(configuration.getServicePath()).recursive().send().get();
             client.close();
             client = null;
         } catch (EtcdException e) {
             // Ignore
         }
+
+        super.cleanupResources();
     }
 
     @Test
@@ -69,7 +77,7 @@ public class EtcdServiceDiscoveryTest extends EtcdTestSupport {
             addServer(client, "serviceType-2");
         }
 
-        EtcdOnDemandServiceDiscovery strategy = new EtcdOnDemandServiceDiscovery(CONFIGURATION);
+        EtcdOnDemandServiceDiscovery strategy = new EtcdOnDemandServiceDiscovery(configuration);
         strategy.start();
 
         List<ServiceDefinition> type1 = strategy.getServices("serviceType-1");
@@ -95,7 +103,7 @@ public class EtcdServiceDiscoveryTest extends EtcdTestSupport {
     public void testWatchDiscovery() throws Exception {
         addServer(client, "serviceType-3");
 
-        EtcdWatchServiceDiscovery strategy = new EtcdWatchServiceDiscovery(CONFIGURATION);
+        EtcdWatchServiceDiscovery strategy = new EtcdWatchServiceDiscovery(configuration);
         strategy.start();
 
         assertEquals(1, strategy.getServices("serviceType-3").size());
@@ -124,6 +132,6 @@ public class EtcdServiceDiscoveryTest extends EtcdTestSupport {
         server.put("port", 8000 + port);
         server.put("tags", tags);
 
-        client.put(CONFIGURATION.getServicePath() + "service-" + port, MAPPER.writeValueAsString(server)).send().get();
+        client.put(configuration.getServicePath() + "service-" + port, MAPPER.writeValueAsString(server)).send().get();
     }
 }
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.java
index 31c0ba7..4225c36 100644
--- a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.java
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.java
@@ -16,24 +16,14 @@
  */
 package org.apache.camel.component.etcd.cloud;
 
-import java.net.URI;
-
 import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import mousio.etcd4j.EtcdClient;
-import org.apache.camel.component.etcd.EtcdConfiguration;
-import org.apache.camel.component.etcd.EtcdHelper;
-import org.apache.camel.test.spring.CamelSpringTestSupport;
-import org.junit.After;
-import org.junit.Test;
+import org.apache.camel.component.etcd.support.SpringEtcdTestSupport;
+import org.junit.jupiter.api.Test;
 import org.springframework.context.support.AbstractApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
-public class SpringEtcdServiceCallDefaultRouteTest extends CamelSpringTestSupport {
-    private static final ObjectMapper MAPPER = EtcdHelper.createObjectMapper();
-    private static final EtcdConfiguration CONFIGURATION = new EtcdConfiguration();
-    private static final EtcdClient CLIENT = new EtcdClient(URI.create("http://localhost:2379"));
-
+public class SpringEtcdServiceCallDefaultRouteTest extends SpringEtcdTestSupport {
     @Override
     protected AbstractApplicationContext createApplicationContext() {
         return new ClassPathXmlApplicationContext("org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml");
@@ -54,17 +44,18 @@ public class SpringEtcdServiceCallDefaultRouteTest extends CamelSpringTestSuppor
             .put("address", "127.0.0.1")
             .put("port", "9092");
 
-        CLIENT.put(CONFIGURATION.getServicePath() + "service-1", MAPPER.writeValueAsString(service1)).send().get();
-        CLIENT.put(CONFIGURATION.getServicePath() + "service-2", MAPPER.writeValueAsString(service2)).send().get();
+        EtcdClient client = getClient();
+        client.put(CONFIGURATION.getServicePath() + "service-1", MAPPER.writeValueAsString(service1)).send().get();
+        client.put(CONFIGURATION.getServicePath() + "service-2", MAPPER.writeValueAsString(service2)).send().get();
 
         super.doPreSetup();
     }
 
     @Override
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-        CLIENT.deleteDir(CONFIGURATION.getServicePath()).recursive().send().get();
+    protected void cleanupResources() throws Exception {
+        getClient().deleteDir(CONFIGURATION.getServicePath()).recursive().send().get();
+
+        super.cleanupResources();
     }
 
     // *************************************************************************
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallRouteTest.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallRouteTest.java
index fda5e02..9e35df5 100644
--- a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallRouteTest.java
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallRouteTest.java
@@ -16,22 +16,14 @@
  */
 package org.apache.camel.component.etcd.cloud;
 
-import java.net.URI;
-
 import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import mousio.etcd4j.EtcdClient;
-import org.apache.camel.component.etcd.EtcdHelper;
-import org.apache.camel.test.spring.CamelSpringTestSupport;
-import org.junit.After;
-import org.junit.Test;
+import org.apache.camel.component.etcd.support.SpringEtcdTestSupport;
+import org.junit.jupiter.api.Test;
 import org.springframework.context.support.AbstractApplicationContext;
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 
-public class SpringEtcdServiceCallRouteTest extends CamelSpringTestSupport {
-    private static final ObjectMapper MAPPER = EtcdHelper.createObjectMapper();
-    private static final EtcdClient CLIENT = new EtcdClient(URI.create("http://localhost:2379"));
-
+public class SpringEtcdServiceCallRouteTest extends SpringEtcdTestSupport {
     @Override
     protected AbstractApplicationContext createApplicationContext() {
         return new ClassPathXmlApplicationContext("org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallRouteTest.xml");
@@ -60,20 +52,21 @@ public class SpringEtcdServiceCallRouteTest extends CamelSpringTestSupport {
             .put("address", "127.0.0.1")
             .put("port", "9094");
 
-        CLIENT.put("/etcd-services-1/" + "service-1", MAPPER.writeValueAsString(service1)).send().get();
-        CLIENT.put("/etcd-services-1/" + "service-2", MAPPER.writeValueAsString(service2)).send().get();
-        CLIENT.put("/etcd-services-2/" + "service-3", MAPPER.writeValueAsString(service3)).send().get();
-        CLIENT.put("/etcd-services-2/" + "service-4", MAPPER.writeValueAsString(service4)).send().get();
+        EtcdClient client = getClient();
+        client.put("/etcd-services-1/" + "service-1", MAPPER.writeValueAsString(service1)).send().get();
+        client.put("/etcd-services-1/" + "service-2", MAPPER.writeValueAsString(service2)).send().get();
+        client.put("/etcd-services-2/" + "service-3", MAPPER.writeValueAsString(service3)).send().get();
+        client.put("/etcd-services-2/" + "service-4", MAPPER.writeValueAsString(service4)).send().get();
 
         super.doPreSetup();
     }
 
     @Override
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-        CLIENT.deleteDir("/etcd-services-1/").recursive().send().get();
-        CLIENT.deleteDir("/etcd-services-2/").recursive().send().get();
+    protected void cleanupResources() throws Exception {
+        getClient().deleteDir("/etcd-services-1/").recursive().send().get();
+        getClient().deleteDir("/etcd-services-2/").recursive().send().get();
+
+        super.cleanupResources();
     }
 
     // *************************************************************************
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/policy/EtcdRoutePolicyMain.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/policy/EtcdRoutePolicyMain.java
index 402b3ba..480cf86 100644
--- a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/policy/EtcdRoutePolicyMain.java
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/policy/EtcdRoutePolicyMain.java
@@ -27,7 +27,7 @@ public final class EtcdRoutePolicyMain {
 
     public static void main(final String[] args) throws Exception {
         Main main = new Main();
-        main.addRouteBuilder(new RouteBuilder() {
+        main.addRoutesBuilder(new RouteBuilder() {
             public void configure() {
                 EtcdRoutePolicy policy = new EtcdRoutePolicy();
                 policy.setClientUris(EtcdConstants.ETCD_DEFAULT_URIS);
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/support/EtcdTestSupport.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/support/EtcdTestSupport.java
new file mode 100644
index 0000000..4d04908
--- /dev/null
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/support/EtcdTestSupport.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.etcd.support;
+
+import java.net.URI;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import mousio.etcd4j.EtcdClient;
+import mousio.etcd4j.responses.EtcdKeysResponse;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Processor;
+import org.apache.camel.component.etcd.EtcdHelper;
+import org.apache.camel.component.etcd.EtcdKeysComponent;
+import org.apache.camel.component.etcd.EtcdStatsComponent;
+import org.apache.camel.component.etcd.EtcdWatchComponent;
+import org.apache.camel.test.testcontainers.junit5.ContainerAwareTestSupport;
+import org.apache.camel.test.testcontainers.junit5.Wait;
+import org.testcontainers.DockerClientFactory;
+import org.testcontainers.containers.GenericContainer;
+
+public abstract class EtcdTestSupport extends ContainerAwareTestSupport {
+    public static final ObjectMapper MAPPER = EtcdHelper.createObjectMapper();
+    public static final String CONTAINER_IMAGE = "quay.io/coreos/etcd:v2.3.7";
+    public static final String CONTAINER_NAME = "etcd";
+    public static final int ETCD_CLIENT_PORT = 2379;
+    public static final int ETCD_PEER_PORT = 2380;
+
+    protected static final Processor NODE_TO_VALUE_IN = exchange -> {
+        EtcdKeysResponse response = exchange.getMessage().getBody(EtcdKeysResponse.class);
+        if (response != null) {
+            exchange.getMessage().setBody(response.node.key + "=" + response.node.value);
+        }
+    };
+
+    protected String getClientUri() {
+        return String.format(
+            "http://%s:%d",
+            getContainerHost(CONTAINER_NAME),
+            getContainerPort(CONTAINER_NAME, ETCD_CLIENT_PORT));
+    }
+
+    protected EtcdClient getClient() {
+        return new EtcdClient(URI.create(getClientUri()));
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        EtcdKeysComponent keys = new EtcdKeysComponent();
+        keys.setUris(getClientUri());
+
+        EtcdStatsComponent stats = new EtcdStatsComponent();
+        stats.setUris(getClientUri());
+
+        EtcdWatchComponent watch = new EtcdWatchComponent();
+        watch.setUris(getClientUri());
+
+        CamelContext context = super.createCamelContext();
+        context.addComponent("etcd-keys", keys);
+        context.addComponent("etcd-stats", stats);
+        context.addComponent("etcd-watch", watch);
+
+        return context;
+    }
+
+    @Override
+    protected GenericContainer<?> createContainer() {
+        return etcdContainer();
+    }
+
+    public static GenericContainer etcdContainer() {
+        return new GenericContainer(CONTAINER_IMAGE)
+            .withNetworkAliases(CONTAINER_NAME)
+            .withExposedPorts(ETCD_CLIENT_PORT, ETCD_PEER_PORT)
+            .waitingFor(Wait.forLogMessageContaining("etcdserver: set the initial cluster version", 1))
+            .withCommand(
+                "-name", CONTAINER_NAME + "-0",
+                "-advertise-client-urls", "http://" + DockerClientFactory.instance().dockerHostIpAddress() + ":" + ETCD_CLIENT_PORT,
+                "-listen-client-urls", "http://0.0.0.0:" + ETCD_CLIENT_PORT
+            );
+    }
+}
diff --git a/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/support/SpringEtcdTestSupport.java b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/support/SpringEtcdTestSupport.java
new file mode 100644
index 0000000..aa0de4b
--- /dev/null
+++ b/components/camel-etcd/src/test/java/org/apache/camel/component/etcd/support/SpringEtcdTestSupport.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.etcd.support;
+
+import java.net.URI;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import mousio.etcd4j.EtcdClient;
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.etcd.EtcdConfiguration;
+import org.apache.camel.component.etcd.EtcdHelper;
+import org.apache.camel.component.etcd.EtcdKeysComponent;
+import org.apache.camel.component.etcd.EtcdStatsComponent;
+import org.apache.camel.component.etcd.EtcdWatchComponent;
+import org.apache.camel.test.testcontainers.spring.junit5.ContainerAwareSpringTestSupport;
+import org.testcontainers.containers.GenericContainer;
+
+public abstract class SpringEtcdTestSupport extends ContainerAwareSpringTestSupport {
+    protected static final ObjectMapper MAPPER = EtcdHelper.createObjectMapper();
+    protected static final EtcdConfiguration CONFIGURATION = new EtcdConfiguration();
+
+    @Override
+    protected GenericContainer<?> createContainer() {
+        return EtcdTestSupport.etcdContainer();
+    }
+
+    protected String getClientUri() {
+        return String.format(
+            "http://%s:%d",
+            getContainerHost(EtcdTestSupport.CONTAINER_NAME),
+            getContainerPort(EtcdTestSupport.CONTAINER_NAME, EtcdTestSupport.ETCD_CLIENT_PORT));
+    }
+
+    protected EtcdClient getClient() {
+        return new EtcdClient(URI.create(getClientUri()));
+    }
+
+    // *************************************************************************
+    // Setup / tear down
+    // *************************************************************************
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        EtcdKeysComponent keys = new EtcdKeysComponent();
+        keys.setUris(getClientUri());
+
+        EtcdStatsComponent stats = new EtcdStatsComponent();
+        stats.setUris(getClientUri());
+
+        EtcdWatchComponent watch = new EtcdWatchComponent();
+        watch.setUris(getClientUri());
+
+        CamelContext context = super.createCamelContext();
+        context.addComponent("etcd-keys", keys);
+        context.addComponent("etcd-stats", stats);
+        context.addComponent("etcd-watch", watch);
+
+        return context;
+    }
+}
diff --git a/components/camel-etcd/src/test/resources/log4j2.properties b/components/camel-etcd/src/test/resources/log4j2.properties
index bd42f41..58ce90a 100644
--- a/components/camel-etcd/src/test/resources/log4j2.properties
+++ b/components/camel-etcd/src/test/resources/log4j2.properties
@@ -29,6 +29,6 @@ logger.etcd4j.level = INFO
 logger.camel.name = org.apache.camel
 logger.camel.level = INFO
 logger.etcd.name = org.apache.camel.component.etcd
-logger.etcd.level = DEBUG
+logger.etcd.level = INFO
 rootLogger.level = INFO
 rootLogger.appenderRef.file.ref = file
diff --git a/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml b/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml
index 7d945fb..4dec9b7 100644
--- a/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml
+++ b/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml
@@ -29,7 +29,7 @@
     <route>
       <from uri="direct:start"/>
       <serviceCall name="http-service">
-        <etcdServiceDiscovery/>
+        <etcdServiceDiscovery uris="http://{{container:host:etcd}}:{{container:port:2379@etcd}}"/>
       </serviceCall>
       <to uri="mock:result"/>
     </route>
diff --git a/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallRouteTest.xml b/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallRouteTest.xml
index 312c110..b426679 100644
--- a/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallRouteTest.xml
+++ b/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallRouteTest.xml
@@ -27,7 +27,9 @@
 
   <camelContext xmlns="http://camel.apache.org/schema/spring">
     <serviceCallConfiguration id="service-0">
-      <etcdServiceDiscovery servicePath="/etcd-services-0/"/>
+      <etcdServiceDiscovery
+          uris="http://{{container:host:etcd}}:{{container:port:2379@etcd}}"
+          servicePath="/etcd-services-0/"/>
     </serviceCallConfiguration>
 
     <route>
@@ -41,14 +43,18 @@
         <when>
           <simple>${body} == 'service-1'</simple>
           <serviceCall name="http-service">
-            <etcdServiceDiscovery servicePath="/etcd-services-1/"/>
+            <etcdServiceDiscovery
+                uris="http://{{container:host:etcd}}:{{container:port:2379@etcd}}"
+                servicePath="/etcd-services-1/"/>
           </serviceCall>
           <to uri="mock:result-1"/>
         </when>
         <when>
           <simple>${body} == 'service-2'</simple>
           <serviceCall name="http-service">
-            <etcdServiceDiscovery servicePath="/etcd-services-2/"/>
+            <etcdServiceDiscovery
+                uris="http://{{container:host:etcd}}:{{container:port:2379@etcd}}"
+                servicePath="/etcd-services-2/"/>
           </serviceCall>
           <to uri="mock:result-2"/>
         </when>
diff --git a/parent/pom.xml b/parent/pom.xml
index 8f879cc..2b61d8a 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -189,7 +189,7 @@
         <elytron-web>1.7.0.CR3</elytron-web>
         <eddsa-version>0.3.0</eddsa-version>
         <embedmongo-version>2.1.1</embedmongo-version>
-        <etcd4j-version>2.17.0</etcd4j-version>
+        <etcd4j-version>2.18.0</etcd4j-version>
         <exec-maven-plugin-version>1.6.0</exec-maven-plugin-version>
         <fabric8-maven-plugin-version>4.3.1</fabric8-maven-plugin-version>
         <facebook4j-core-version>2.4.13</facebook4j-core-version>