Skip to content

Commit 6d99516

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 8377288 commit 6d99516

File tree

2 files changed

+31
-10
lines changed

2 files changed

+31
-10
lines changed

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

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public class DockerComposeContainer<SELF extends DockerComposeContainer<SELF>> e
7474
private final List<File> composeFiles;
7575
private Set<ParsedDockerComposeFile> parsedComposeFiles;
7676
private final Map<String, Integer> scalingPreferences = new HashMap<>();
77+
private final Map<String, String> customContainerNames = new HashMap<>();
7778
private DockerClient dockerClient;
7879
private boolean localCompose;
7980
private boolean pull = true;
@@ -121,6 +122,8 @@ public DockerComposeContainer(String identifier, List<File> composeFiles) {
121122

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

125128
// Use a unique identifier so that containers created for this compose environment can be identified
126129
this.identifier = identifier;
@@ -285,11 +288,18 @@ private void registerContainersForShutdown() {
285288
}
286289

287290
private List<Container> listChildContainers() {
291+
Set<String> names = customContainerNames.values()
292+
.stream()
293+
.map(name -> String.format("/%s", name))
294+
.collect(Collectors.toSet());
288295
return dockerClient.listContainersCmd()
289296
.withShowAll(true)
290297
.exec().stream()
291-
.filter(container -> Arrays.stream(container.getNames()).anyMatch(name ->
292-
name.startsWith("/" + project)))
298+
.filter(
299+
container -> Arrays.stream(container.getNames()).anyMatch(name ->
300+
names.contains(name) || name.startsWith("/" + project)
301+
)
302+
)
293303
.collect(toList());
294304
}
295305

@@ -353,7 +363,8 @@ public SELF withExposedService(String serviceName, int servicePort, @NonNull Wai
353363
int ambassadorPort = nextAmbassadorPort.getAndIncrement();
354364
ambassadorPortMappings.computeIfAbsent(serviceInstanceName, __ -> new ConcurrentHashMap<>()).put(servicePort, ambassadorPort);
355365
ambassadorContainer.withTarget(ambassadorPort, serviceInstanceName, servicePort);
356-
ambassadorContainer.addLink(new FutureContainer(this.project + "_" + serviceInstanceName), serviceInstanceName);
366+
String containerName = getContainerName(serviceInstanceName);
367+
ambassadorContainer.addLink(new FutureContainer(containerName), serviceInstanceName);
357368
addWaitStrategy(serviceInstanceName, waitStrategy);
358369
return self();
359370
}
@@ -366,6 +377,17 @@ private String getServiceInstanceName(String serviceName) {
366377
return serviceInstanceName;
367378
}
368379

380+
private String getContainerName(String serviceName) {
381+
String serviceInstanceName = serviceName;
382+
if (serviceInstanceName.matches(".*_[0-9]+")) {
383+
serviceName = serviceInstanceName.substring(0, serviceInstanceName.indexOf('_'));
384+
if (customContainerNames.containsKey(serviceName)) {
385+
return customContainerNames.get(serviceName);
386+
}
387+
}
388+
return String.format("%s_%s", project, serviceInstanceName);
389+
}
390+
369391
/*
370392
* can have multiple wait strategies for a single container, e.g. if waiting on several ports
371393
* 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)