Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fixed host port test #1355

Merged
merged 7 commits into from Aug 25, 2019
@@ -1,10 +1,19 @@
package org.testcontainers.junit;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import com.google.common.util.concurrent.Uninterruptibles;
import org.junit.Test;
import org.rnorth.ducttape.unreliables.Unreliables;
import org.testcontainers.containers.FixedHostPortGenericContainer;
import org.testcontainers.containers.GenericContainer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.concurrent.TimeUnit;

/**
* Test of {@link FixedHostPortGenericContainer}. Note that this is not an example of typical use (usually, a container
Expand All @@ -14,28 +23,74 @@
*/
public class FixedHostPortContainerTest {

private static final int REDIS_PORT = 6379;
private static final String TEST_IMAGE = "alpine:3.2";
glebsts marked this conversation as resolved.
Show resolved Hide resolved

/**
* Default http server port (just something different from default)
*/
private static final int TEST_PORT = 5678;

/**
* test response
*/
private static final String TEST_RESPONSE = "test-response";

/**
* *nix pipe to fire test response on test port
*/
private static final String HTTP_ECHO_CMD =
String.format("while true; do echo \"%s\" | nc -l -p %d; done", TEST_RESPONSE, TEST_PORT);

@Test
public void testFixedHostPortMapping() throws IOException {
// first find a free port on the docker host that will work for testing
GenericContainer portDiscoveryRedis = new GenericContainer("redis:3.0.2").withExposedPorts(REDIS_PORT);
portDiscoveryRedis.start();
Integer freePort = portDiscoveryRedis.getMappedPort(REDIS_PORT);
portDiscoveryRedis.stop();


// Set up a FixedHostPortGenericContainer as if this were a @Rule
FixedHostPortGenericContainer redis = new FixedHostPortGenericContainer("redis:3.0.2").withFixedExposedPort(freePort, REDIS_PORT);
redis.start();

// Config redisConfig = new Config();
// redisConfig.useSingleServer().setAddress(redis.getContainerIpAddress() + ":" + freePort);
// Redisson redisson = Redisson.create(redisConfig);
//
// redisson.getBucket("test").set("foo");
//
// assertEquals("The bucket content was successfully set", "foo", redisson.getBucket("test").get());
// assertEquals("The container returns the fixed port from getMappedPort(...)", freePort, redis.getMappedPort(REDIS_PORT));
final Integer unusedHostPort;
try (
final GenericContainer echoServer = new GenericContainer<>(TEST_IMAGE)
.withExposedPorts(TEST_PORT)
.withCommand("/bin/sh", "-c", HTTP_ECHO_CMD)
) {
echoServer.start();
unusedHostPort = echoServer.getMappedPort(TEST_PORT);
}

// now starting echo server container mapped to known-as-free host port
try (
final GenericContainer echoServer = new FixedHostPortGenericContainer(TEST_IMAGE)
// using workaround for port bind+expose
.withFixedExposedPort(unusedHostPort, TEST_PORT)
.withExposedPorts(TEST_PORT)
.withCommand("/bin/sh", "-c", HTTP_ECHO_CMD)
) {
echoServer.start();

assertThat("Port mapping does not seem to match given fixed port",
echoServer.getMappedPort(TEST_PORT), equalTo(unusedHostPort));

final String content = this.readResponse(echoServer, unusedHostPort);
assertThat("Returned echo from fixed port does not match expected", content, equalTo(TEST_RESPONSE));
}
}

/**
* Simple socket content reader from given container:port
*
* @param container to query
* @param port to send request to
* @return socket reader content
* @throws IOException if any
*/
private String readResponse(GenericContainer container, Integer port) throws IOException {
try (
final BufferedReader reader = Unreliables.retryUntilSuccess(10, TimeUnit.SECONDS,
() -> {
Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
final Socket socket = new Socket(container.getContainerIpAddress(), port);
return new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
)
) {
return reader.readLine();
}
}
}