Skip to content

Commit

Permalink
Add utility class to allow image names to be configured via a classpa…
Browse files Browse the repository at this point in the history
…th file

Replace static string names for ambassador and vnc recorder container images with classpath lookup.

Add note to readme re overriding hardcoded image names

Refs #259, #276
  • Loading branch information
rnorth committed Jan 21, 2017
1 parent db2c918 commit c412994
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.testcontainers.containers.traits.LinkableContainer;
import org.testcontainers.utility.TestcontainersConfiguration;

import java.util.List;

Expand All @@ -24,7 +25,7 @@ public class AmbassadorContainer<SELF extends AmbassadorContainer<SELF>> extends
private final int servicePort;

public AmbassadorContainer(LinkableContainer otherContainer, String serviceName, int servicePort) {
super("richnorth/ambassador:latest");
super(TestcontainersConfiguration.getInstance().ambassadorContainerImage);

/*
Use the unique 'identifierPrefix' (random compose project name) so that the ambassador can see
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.github.dockerjava.api.command.InspectContainerResponse;
import org.testcontainers.containers.traits.LinkableContainer;
import org.testcontainers.containers.traits.VncService;
import org.testcontainers.utility.TestcontainersConfiguration;

import java.io.File;
import java.io.IOException;
Expand All @@ -23,7 +24,7 @@ public class VncRecordingSidekickContainer<SELF extends VncRecordingSidekickCont
* @param vncServiceContainer the container whose screen should be recorded. This container must implement VncService and LinkableContainer.
*/
public VncRecordingSidekickContainer(T vncServiceContainer) {
super("richnorth/vnc-recorder:latest");
super(TestcontainersConfiguration.getInstance().vncRecordedContainerImage);

this.vncServiceContainer = vncServiceContainer;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.testcontainers.utility;

import com.google.common.base.MoreObjects;
import lombok.Data;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

/**
* Provides a mechanism for fetching configuration/defaults from the classpath.
*/
@Data
@Slf4j
public class TestcontainersConfiguration {

// No public constructor - must use getInstance() method.
private TestcontainersConfiguration() {
}

@Getter(lazy = true)
private static final TestcontainersConfiguration instance = loadConfiguration();

private static TestcontainersConfiguration loadConfiguration() {
final TestcontainersConfiguration config = new TestcontainersConfiguration();

ClassLoader loader = MoreObjects.firstNonNull(
Thread.currentThread().getContextClassLoader(),
TestcontainersConfiguration.class.getClassLoader());
final URL configOverrides = loader.getResource("testcontainers.properties");
if (configOverrides != null) {

log.debug("Testcontainers configuration overrides will be loaded from {}", configOverrides);

final Properties properties = new Properties();
try (final InputStream inputStream = configOverrides.openStream()) {
properties.load(inputStream);

config.ambassadorContainerImage = properties.getProperty("ambassador.container.image", config.ambassadorContainerImage);
config.vncRecordedContainerImage = properties.getProperty("vncrecorder.container.image", config.vncRecordedContainerImage);

log.debug("Testcontainers configuration overrides loaded from {}: {}", configOverrides, config);

} catch (IOException e) {
log.error("Testcontainers config override was found on classpath but could not be loaded", e);
}
}

return config;
}

public String ambassadorContainerImage = "richnorth/ambassador:latest";
public String vncRecordedContainerImage = "richnorth/vnc-recorder:latest";
}
16 changes: 16 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,20 @@ should be included in your classpath to show a reasonable level of log output:
<logger name="com.github.dockerjava" level="WARN"/>
<logger name="org.zeroturnaround.exec" level="WARN"/>
</configuration>
```

## Using custom utility images

Testcontainers uses additional docker images under some modes of execution:

* `richnorth/ambassador:latest`, which is a TCP proxy used to expose Docker Compose container ports outside of the compose network.
* `richnorth/vncrecorder:latest`, which is a VNC->FLV recorder, used for capturing Webdriver test videos.

> *N.B.:* both these images use the 'latest' tag, which could potentially affect repeatability of tests and compatibility with Testcontainers _if the image is ever changed_. This is a [known issue](https://github.com/testcontainers/testcontainers-java/issues/276) which will be addressed in the future. The current 'latest' version of these images will never be changed until they are replaced by a new image altogether.
If it is necessary to override these image names (e.g. when using a private registry), you should create a file named `testcontainers.properties` and place it on the classpath with the following content:

```properties
ambassador.container.image=replacement image name here
vncrecorder.container.image=replacement image name here
```

0 comments on commit c412994

Please sign in to comment.