diff --git a/docs/modules/toxiproxy.md b/docs/modules/toxiproxy.md index 1b8229982e6..99178935b9a 100644 --- a/docs/modules/toxiproxy.md +++ b/docs/modules/toxiproxy.md @@ -17,7 +17,7 @@ A Toxiproxy container can be placed in between test code and a container, or in In either scenario, it is necessary to create a `ToxiproxyContainer` instance on the same Docker network, as follows: -[Creating a Toxiproxy container](../../modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java) inside_block:creatingProxy +[Creating a Toxiproxy container](../../modules/toxiproxy/src/test/java/org/testcontainers/toxiproxy/ToxiproxyContainerTest.java) inside_block:creatingProxy Next, it is necessary to instruct Toxiproxy to start proxying connections. @@ -26,13 +26,13 @@ Each `ToxiproxyContainer` can proxy to many target containers if necessary. We do this as follows: -[Starting proxying connections to a target container](../../modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java) inside_block:obtainProxyObject +[Starting proxying connections to a target container](../../modules/toxiproxy/src/test/java/org/testcontainers/toxiproxy/ToxiproxyContainerTest.java) inside_block:obtainProxyObject To establish a connection from the test code (on the host machine) to the target container via Toxiproxy, we obtain **Toxiproxy's** proxy host IP and port: -[Obtaining proxied host and port](../../modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java) inside_block:obtainProxiedHostAndPortForHostMachine +[Obtaining proxied host and port](../../modules/toxiproxy/src/test/java/org/testcontainers/toxiproxy/ToxiproxyContainerTest.java) inside_block:obtainProxiedHostAndPortForHostMachine Code under test should connect to this proxied host IP and port. @@ -56,13 +56,13 @@ Please see the [Toxiproxy documentation](https://github.com/Shopify/toxiproxy#to As one example, we can introduce latency and random jitter to proxied connections as follows: -[Adding latency to a connection](../../modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java) inside_block:addingLatency +[Adding latency to a connection](../../modules/toxiproxy/src/test/java/org/testcontainers/toxiproxy/ToxiproxyContainerTest.java) inside_block:addingLatency Additionally we can disable the proxy to simulate a complete interruption to the network connection: -[Cutting a connection](../../modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java) inside_block:disableProxy +[Cutting a connection](../../modules/toxiproxy/src/test/java/org/testcontainers/toxiproxy/ToxiproxyContainerTest.java) inside_block:disableProxy ## Adding this module to your project dependencies @@ -86,5 +86,3 @@ Add the following dependency to your `pom.xml`/`build.gradle` file: ## Acknowledgements This module was inspired by a [hotels.com blog post](https://medium.com/hotels-com-technology/i-dont-know-about-resilience-testing-and-so-can-you-b3c59d80012d). - -[toxiproxy-java](https://github.com/trekawek/toxiproxy-java) is used to help control failure conditions. diff --git a/modules/toxiproxy/src/main/java/org/testcontainers/containers/ToxiproxyContainer.java b/modules/toxiproxy/src/main/java/org/testcontainers/containers/ToxiproxyContainer.java index c28c4e93ddf..4a3d1af003e 100644 --- a/modules/toxiproxy/src/main/java/org/testcontainers/containers/ToxiproxyContainer.java +++ b/modules/toxiproxy/src/main/java/org/testcontainers/containers/ToxiproxyContainer.java @@ -26,7 +26,10 @@ *
  • HTTP: 8474
  • *
  • Proxied Ports: 8666-8697
  • * + * + * @deprecated use {@link org.testcontainers.toxiproxy.ToxiproxyContainer} instead. */ +@Deprecated public class ToxiproxyContainer extends GenericContainer { private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("shopify/toxiproxy"); diff --git a/modules/toxiproxy/src/main/java/org/testcontainers/toxiproxy/ToxiproxyContainer.java b/modules/toxiproxy/src/main/java/org/testcontainers/toxiproxy/ToxiproxyContainer.java new file mode 100644 index 00000000000..b4ab7e29c96 --- /dev/null +++ b/modules/toxiproxy/src/main/java/org/testcontainers/toxiproxy/ToxiproxyContainer.java @@ -0,0 +1,54 @@ +package org.testcontainers.toxiproxy; + +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; +import org.testcontainers.utility.DockerImageName; + +/** + * Testcontainers implementation for Toxiproxy. + *

    + * Supported images: {@code ghcr.io/shopify/toxiproxy}, {@code shopify/toxiproxy} + *

    + * Exposed ports: + *

    + */ +public class ToxiproxyContainer extends GenericContainer { + + private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("shopify/toxiproxy"); + + private static final DockerImageName GHCR_IMAGE_NAME = DockerImageName.parse("ghcr.io/shopify/toxiproxy"); + + private static final int TOXIPROXY_CONTROL_PORT = 8474; + + private static final int FIRST_PROXIED_PORT = 8666; + + private static final int LAST_PROXIED_PORT = 8666 + 31; + + public ToxiproxyContainer(String dockerImageName) { + this(DockerImageName.parse(dockerImageName)); + } + + public ToxiproxyContainer(final DockerImageName dockerImageName) { + super(dockerImageName); + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME, GHCR_IMAGE_NAME); + + addExposedPorts(TOXIPROXY_CONTROL_PORT); + setWaitStrategy(new HttpWaitStrategy().forPath("/version").forPort(TOXIPROXY_CONTROL_PORT)); + + // allow up to 32 ports to be proxied (arbitrary value). Here we make the ports exposed; whether or not + // Toxiproxy will listen is controlled at runtime using getProxy(...) + for (int i = FIRST_PROXIED_PORT; i <= LAST_PROXIED_PORT; i++) { + addExposedPort(i); + } + } + + /** + * @return Publicly exposed Toxiproxy HTTP API control port. + */ + public int getControlPort() { + return getMappedPort(TOXIPROXY_CONTROL_PORT); + } +} diff --git a/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java b/modules/toxiproxy/src/test/java/org/testcontainers/toxiproxy/ToxiproxyContainerTest.java similarity index 83% rename from modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java rename to modules/toxiproxy/src/test/java/org/testcontainers/toxiproxy/ToxiproxyContainerTest.java index 1e35c2d7206..2247f135f7b 100644 --- a/modules/toxiproxy/src/test/java/org/testcontainers/containers/ToxiproxyTest.java +++ b/modules/toxiproxy/src/test/java/org/testcontainers/toxiproxy/ToxiproxyContainerTest.java @@ -1,4 +1,4 @@ -package org.testcontainers.containers; +package org.testcontainers.toxiproxy; import eu.rekawek.toxiproxy.Proxy; import eu.rekawek.toxiproxy.ToxiproxyClient; @@ -6,6 +6,8 @@ import org.junit.jupiter.api.AutoClose; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.Network; import redis.clients.jedis.Jedis; import redis.clients.jedis.exceptions.JedisConnectionException; @@ -16,7 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; -public class ToxiproxyTest { +public class ToxiproxyContainerTest { private static final Duration JEDIS_TIMEOUT = Duration.ofSeconds(10); @@ -157,33 +159,6 @@ public void testMultipleProxiesCanBeCreated() throws IOException { } } - @Test - public void testOriginalAndMappedPorts() { - final ToxiproxyContainer.ContainerProxy proxy = toxiproxy.getProxy("hostname", 7070); - - final int portViaToxiproxy = proxy.getOriginalProxyPort(); - assertThat(portViaToxiproxy).as("original port is correct").isEqualTo(8666); - - final ToxiproxyContainer.ContainerProxy proxy1 = toxiproxy.getProxy("hostname1", 8080); - assertThat(proxy1.getOriginalProxyPort()).as("original port is correct").isEqualTo(8667); - assertThat(proxy1.getProxyPort()) - .as("mapped port is correct") - .isEqualTo(toxiproxy.getMappedPort(proxy1.getOriginalProxyPort())); - - final ToxiproxyContainer.ContainerProxy proxy2 = toxiproxy.getProxy("hostname2", 9090); - assertThat(proxy2.getOriginalProxyPort()).as("original port is correct").isEqualTo(8668); - assertThat(proxy2.getProxyPort()) - .as("mapped port is correct") - .isEqualTo(toxiproxy.getMappedPort(proxy2.getOriginalProxyPort())); - } - - @Test - public void testProxyName() { - final ToxiproxyContainer.ContainerProxy proxy = toxiproxy.getProxy("hostname", 7070); - - assertThat(proxy.getName()).as("proxy name is hostname and port").isEqualTo("hostname:7070"); - } - private void checkCallWithLatency( Jedis jedis, final String description,