Skip to content

Commit 6211310

Browse files
Added ability to include container_name in compose file
This commit updates the ParsedDockerComposeFile to pull out the container name for a service if included in the compose file. DockerComposeContainer was then updated with logic to use this specified name if present.
1 parent 25a9aa5 commit 6211310

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed

core/src/main/java/org/testcontainers/containers/DockerComposeContainer.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public class DockerComposeContainer<SELF extends DockerComposeContainer<SELF>> e
7575
private final List<File> composeFiles;
7676
private Set<ParsedDockerComposeFile> parsedComposeFiles;
7777
private final Map<String, Integer> scalingPreferences = new HashMap<>();
78+
private final Map<String, String> customContainerNames = new HashMap<>();
7879
private DockerClient dockerClient;
7980
private boolean localCompose;
8081
private boolean pull = true;
@@ -122,6 +123,8 @@ public DockerComposeContainer(String identifier, List<File> composeFiles) {
122123

123124
this.composeFiles = composeFiles;
124125
this.parsedComposeFiles = composeFiles.stream().map(ParsedDockerComposeFile::new).collect(Collectors.toSet());
126+
this.parsedComposeFiles
127+
.forEach(composeFile -> this.customContainerNames.putAll(composeFile.getContainerNames()));
125128

126129
// Use a unique identifier so that containers created for this compose environment can be identified
127130
this.identifier = identifier;
@@ -300,12 +303,19 @@ private void registerContainersForShutdown() {
300303

301304
@VisibleForTesting
302305
List<Container> listChildContainers() {
306+
Set<String> names = customContainerNames.values()
307+
.stream()
308+
.map(name -> String.format("/%s", name))
309+
.collect(Collectors.toSet());
303310
return dockerClient.listContainersCmd()
304-
.withShowAll(true)
305-
.exec().stream()
306-
.filter(container -> Arrays.stream(container.getNames()).anyMatch(name ->
307-
name.startsWith("/" + project)))
308-
.collect(toList());
311+
.withShowAll(true)
312+
.exec().stream()
313+
.filter(
314+
container -> Arrays.stream(container.getNames()).anyMatch(name ->
315+
names.contains(name) || name.startsWith("/" + project)
316+
)
317+
)
318+
.collect(toList());
309319
}
310320

311321
private void startAmbassadorContainers() {
@@ -368,7 +378,8 @@ public SELF withExposedService(String serviceName, int servicePort, @NonNull Wai
368378
int ambassadorPort = nextAmbassadorPort.getAndIncrement();
369379
ambassadorPortMappings.computeIfAbsent(serviceInstanceName, __ -> new ConcurrentHashMap<>()).put(servicePort, ambassadorPort);
370380
ambassadorContainer.withTarget(ambassadorPort, serviceInstanceName, servicePort);
371-
ambassadorContainer.addLink(new FutureContainer(this.project + "_" + serviceInstanceName), serviceInstanceName);
381+
String containerName = getContainerName(serviceInstanceName);
382+
ambassadorContainer.addLink(new FutureContainer(containerName), serviceInstanceName);
372383
addWaitStrategy(serviceInstanceName, waitStrategy);
373384
return self();
374385
}
@@ -381,6 +392,17 @@ private String getServiceInstanceName(String serviceName) {
381392
return serviceInstanceName;
382393
}
383394

395+
private String getContainerName(String serviceName) {
396+
String serviceInstanceName = serviceName;
397+
if (serviceInstanceName.matches(".*_[0-9]+")) {
398+
serviceName = serviceInstanceName.substring(0, serviceInstanceName.indexOf('_'));
399+
if (customContainerNames.containsKey(serviceName)) {
400+
return customContainerNames.get(serviceName);
401+
}
402+
}
403+
return String.format("%s_%s", project, serviceInstanceName);
404+
}
405+
384406
/*
385407
* can have multiple wait strategies for a single container, e.g. if waiting on several ports
386408
* if no wait strategy is defined, the WaitAllStrategy will return immediately.

core/src/main/java/org/testcontainers/containers/ParsedDockerComposeFile.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.io.FileInputStream;
1313
import java.nio.file.Files;
1414
import java.nio.file.Path;
15+
import java.util.HashMap;
1516
import java.util.HashSet;
1617
import java.util.Map;
1718
import java.util.Set;
@@ -30,6 +31,8 @@ class ParsedDockerComposeFile {
3031

3132
@Getter
3233
private Set<String> dependencyImageNames = new HashSet<>();
34+
@Getter
35+
private Map<String, String> containerNames = new HashMap<>();
3336

3437
ParsedDockerComposeFile(File composeFile) {
3538
Yaml yaml = new Yaml();
@@ -86,19 +89,15 @@ private void parseAndValidate() {
8689

8790
final Map serviceDefinitionMap = (Map) serviceDefinition;
8891

89-
validateNoContainerNameSpecified(serviceName, serviceDefinitionMap);
92+
findContainerName(serviceName, serviceDefinitionMap);
9093
findServiceImageName(serviceDefinitionMap);
9194
findImageNamesInDockerfile(serviceDefinitionMap);
9295
}
9396
}
9497

95-
private void validateNoContainerNameSpecified(String serviceName, Map serviceDefinitionMap) {
98+
private void findContainerName(String serviceName, Map serviceDefinitionMap) {
9699
if (serviceDefinitionMap.containsKey("container_name")) {
97-
throw new IllegalStateException(String.format(
98-
"Compose file %s has 'container_name' property set for service '%s' but this property is not supported by Testcontainers, consider removing it",
99-
composeFileName,
100-
serviceName
101-
));
100+
this.containerNames.put(serviceName, (String) serviceDefinitionMap.get("container_name"));
102101
}
103102
}
104103

0 commit comments

Comments
 (0)