protected void ping(DockerClient client, int timeoutInSeconds) { try { Unreliables.retryUntilSuccess(timeoutInSeconds, TimeUnit.SECONDS, () -> { return PING_RATE_LIMITER.getWhenReady(() -> { LOGGER.debug("Pinging docker daemon..."); client.pingCmd().exec(); return true; }); }); } catch (TimeoutException e) { IOUtils.closeQuietly(client); throw e; } }
protected void doStart() { try { configure(); logger().debug("Starting container: {}", getDockerImageName()); logger().debug("Trying to start container: {}", image.get()); AtomicInteger attempt = new AtomicInteger(0); Unreliables.retryUntilSuccess(startupAttempts, () -> { logger().debug("Trying to start container: {} (attempt {}/{})", image.get(), attempt.incrementAndGet(), startupAttempts); tryStart(); return true; }); } catch (Exception e) { throw new ContainerLaunchException("Container startup failed", e); } }
@Override protected void containerIsStarted(InspectContainerResponse containerInfo) { driver = Unreliables.retryUntilSuccess(30, TimeUnit.SECONDS, Timeouts.getWithTimeout(10, TimeUnit.SECONDS, () -> () -> new RemoteWebDriver(getSeleniumAddress(), capabilities))); if (vncRecordingContainer != null) { LOGGER.debug("Starting VNC recording"); vncRecordingContainer.start(); } }
/** * Creates a connection to the underlying containerized database instance. * * @param queryString query string parameters that should be appended to the JDBC connection URL. * The '?' character must be included * @return a Connection * @throws SQLException if there is a repeated failure to create the connection */ public Connection createConnection(String queryString) throws SQLException { final Properties info = new Properties(); info.put("user", this.getUsername()); info.put("password", this.getPassword()); final String url = constructUrlForConnection(queryString); final Driver jdbcDriverInstance = getJdbcDriverInstance(); try { return Unreliables.retryUntilSuccess(getConnectTimeoutSeconds(), TimeUnit.SECONDS, () -> DB_CONNECT_RATE_LIMIT.getWhenReady(() -> jdbcDriverInstance.connect(url, info))); } catch (Exception e) { throw new SQLException("Could not create new connection", e); } }
retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> { getRateLimiter().doWhenReady(() -> { try {
private BufferedReader getReaderForContainerPort80(GenericContainer container) { return Unreliables.retryUntilSuccess(10, TimeUnit.SECONDS, () -> { Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); Socket socket = new Socket(container.getContainerIpAddress(), container.getFirstMappedPort()); return new BufferedReader(new InputStreamReader(socket.getInputStream())); }); }
@Override protected void waitUntilReady() { // execute select version query until success or timeout try { retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> { getRateLimiter().doWhenReady(() -> { try (DatabaseDelegate databaseDelegate = getDatabaseDelegate()) { databaseDelegate.execute(SELECT_VERSION_QUERY, "", 1, false, false); } }); return true; }); } catch (TimeoutException e) { throw new ContainerLaunchException(TIMEOUT_ERROR); } }
@Override protected void waitUntilContainerStarted() { // Repeatedly try and open a connection to the DB and execute a test query logger().info("Waiting for database connection to become available at {} using query '{}'", getJdbcUrl(), getTestQueryString()); Unreliables.retryUntilSuccess(getStartupTimeoutSeconds(), TimeUnit.SECONDS, () -> { if (!isRunning()) { throw new ContainerLaunchException("Container failed to start"); } try (Connection connection = createConnection("")) { boolean success = connection.createStatement().execute(JdbcDatabaseContainer.this.getTestQueryString()); if (success) { logger().info("Obtained a connection to container ({})", JdbcDatabaseContainer.this.getJdbcUrl()); return null; } else { throw new SQLException("Failed to execute test query"); } } }); }
@Override protected void waitUntilReady() { log.info("Waiting for {} seconds for QUERY service", startupTimeout.getSeconds()); // try to connect to the URL try { retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> { getRateLimiter().doWhenReady(() -> { GetClusterConfigResponse clusterConfig = bucket.core() .<GetClusterConfigResponse>send(new GetClusterConfigRequest()) .toBlocking().single(); boolean queryServiceEnabled = clusterConfig.config() .bucketConfig(bucket.name()) .serviceEnabled(ServiceType.QUERY); if (!queryServiceEnabled) { throw new ContainerLaunchException("Query service not ready yet"); } }); return true; }); } catch (TimeoutException e) { throw new ContainerLaunchException("Timed out waiting for QUERY service"); } } }
@Test public void test() { try (DockerComposeContainer compose = new DockerComposeContainer(composeFiles) .withLocalCompose(localMode) .withExposedService(SERVICE_NAME, SERVICE_PORT)) { compose.start(); BufferedReader br = Unreliables.retryUntilSuccess(10, TimeUnit.SECONDS, () -> { Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); Socket socket = new Socket(compose.getServiceHost(SERVICE_NAME, SERVICE_PORT), compose.getServicePort(SERVICE_NAME, SERVICE_PORT)); return new BufferedReader(new InputStreamReader(socket.getInputStream())); }); Unreliables.retryUntilTrue(10, TimeUnit.SECONDS, () -> { while (br.ready()) { String line = br.readLine(); if (line.contains(expectedEnvVar)) { pass("Mapped environment variable was found"); return true; } } info("Mapped environment variable was not found yet - process probably not ready"); Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS); return false; }); } }
@Test public void simpleRabbitMqTest() throws IOException, TimeoutException { ConnectionFactory factory = new ConnectionFactory(); factory.setHost(rabbitMq.getContainerIpAddress()); factory.setPort(rabbitMq.getMappedPort(RABBITMQ_PORT)); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.exchangeDeclare(RABBIQMQ_TEST_EXCHANGE, "direct", true); String queueName = channel.queueDeclare().getQueue(); channel.queueBind(queueName, RABBIQMQ_TEST_EXCHANGE, RABBITMQ_TEST_ROUTING_KEY); // Set up a consumer on the queue final boolean[] messageWasReceived = new boolean[1]; channel.basicConsume(queueName, false, new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { messageWasReceived[0] = Arrays.equals(body, RABBITMQ_TEST_MESSAGE.getBytes()); } }); // post a message channel.basicPublish(RABBIQMQ_TEST_EXCHANGE, RABBITMQ_TEST_ROUTING_KEY, null, RABBITMQ_TEST_MESSAGE.getBytes()); // check the message was received assertTrue("The message was received", Unreliables.retryUntilSuccess(5, TimeUnit.SECONDS, () -> { if (!messageWasReceived[0]) { throw new IllegalStateException("Message not received yet"); } return true; })); }
/** * Call a callable repeatedly until it returns true. If an exception is thrown, the call * will be retried repeatedly until the timeout is hit. * * @param timeout how long to wait * @param timeUnit time unit for time interval * @param lambda supplier lambda expression */ public static void retryUntilTrue(final int timeout, @NotNull final TimeUnit timeUnit, @NotNull final Callable<Boolean> lambda) { retryUntilSuccess(timeout, timeUnit, () -> { if (!lambda.call()) { throw new RuntimeException("Not ready yet"); } else { return null; } }); }
/** * Call a callable repeatedly until it returns true. If an exception is thrown, the call * will be retried repeatedly until the timeout is hit. * * @param tryLimit how many times to try calling the supplier * @param lambda supplier lambda expression */ public static void retryUntilTrue(final int tryLimit, @NotNull final Callable<Boolean> lambda) { retryUntilSuccess(tryLimit, () -> { if (!lambda.call()) { throw new RuntimeException("Not ready yet"); } else { return null; } }); } }
/** * Call a callable repeatedly until it returns true. If an exception is thrown, the call * will be retried repeatedly until the timeout is hit. * * @param tryLimit how many times to try calling the supplier * @param lambda supplier lambda expression */ public static void retryUntilTrue(final int tryLimit, @NotNull final Callable<Boolean> lambda) { retryUntilSuccess(tryLimit, () -> { if (!lambda.call()) { throw new RuntimeException("Not ready yet"); } else { return null; } }); } }
/** * Call a callable repeatedly until it returns true. If an exception is thrown, the call * will be retried repeatedly until the timeout is hit. * * @param timeout how long to wait * @param timeUnit time unit for time interval * @param lambda supplier lambda expression */ public static void retryUntilTrue(final int timeout, @NotNull final TimeUnit timeUnit, @NotNull final Callable<Boolean> lambda) { retryUntilSuccess(timeout, timeUnit, () -> { if (!lambda.call()) { throw new RuntimeException("Not ready yet"); } else { return null; } }); }
protected void doStart() { try { configure(); logger().debug("Starting container: {}", getDockerImageName()); logger().debug("Trying to start container: {}", image.get()); AtomicInteger attempt = new AtomicInteger(0); Unreliables.retryUntilSuccess(startupAttempts, () -> { logger().debug("Trying to start container: {} (attempt {}/{})", image.get(), attempt.incrementAndGet(), startupAttempts); tryStart(); return true; }); } catch (Exception e) { throw new ContainerLaunchException("Container startup failed", e); } }
@Override protected void containerIsStarted(InspectContainerResponse containerInfo) { driver = Unreliables.retryUntilSuccess(30, TimeUnit.SECONDS, Timeouts.getWithTimeout(10, TimeUnit.SECONDS, () -> () -> new RemoteWebDriver(getSeleniumAddress(), capabilities))); if (vncRecordingContainer != null) { LOGGER.debug("Starting VNC recording"); vncRecordingContainer.start(); } }
protected void ping(DockerClient client, int timeoutInSeconds) { try { Unreliables.retryUntilSuccess(timeoutInSeconds, TimeUnit.SECONDS, () -> { return PING_RATE_LIMITER.getWhenReady(() -> { LOGGER.debug("Pinging docker daemon..."); client.pingCmd().exec(); return true; }); }); } catch (TimeoutException e) { IOUtils.closeQuietly(client); throw e; } }
@Override protected void waitUntilContainerStarted() { // Repeatedly try and open a connection to the DB and execute a test query logger().info("Waiting for database connection to become available at {} using query \'{}\'", getJdbcUrl(), getTestQueryString()); Unreliables.retryUntilSuccess(getStartupTimeoutSeconds(), TimeUnit.SECONDS, () -> { if (!isRunning()) { throw new ContainerLaunchException("Container failed to start"); } try (Connection connection = createConnection("")) { boolean success = connection.createStatement().execute(JdbcDatabaseContainer.this.getTestQueryString()); if (success) { logger().info("Obtained a connection to container ({})", JdbcDatabaseContainer.this.getJdbcUrl()); return null; } else { throw new SQLException("Failed to execute test query"); } } }); }
@Override protected void waitUntilReady() { logger().info("Waiting for {} seconds for QUERY service", startupTimeout.getSeconds()); // try to connect to the URL try { retryUntilSuccess((int) startupTimeout.getSeconds(), TimeUnit.SECONDS, () -> { getRateLimiter().doWhenReady(() -> { GetClusterConfigResponse clusterConfig = bucket.core() .<GetClusterConfigResponse>send(new GetClusterConfigRequest()) .toBlocking().single(); boolean queryServiceEnabled = clusterConfig.config() .bucketConfig(bucket.name()) .serviceEnabled(ServiceType.QUERY); if (!queryServiceEnabled) { throw new RuntimeException("Query service not ready yet"); } }); return true; }); } catch (TimeoutException e) { throw new ContainerLaunchException("Timed out waiting for QUERY service"); } } }