How to use LocalDockerCompose method of org.testcontainers.containers.DockerComposeContainer class

Best Testcontainers-java code snippet using org.testcontainers.containers.DockerComposeContainer.LocalDockerCompose

Source:DockerComposeContainer.java Github

copy

Full Screen

...149 }150 private void runWithCompose(String cmd) {151 final DockerCompose dockerCompose;152 if (localCompose) {153 dockerCompose = new LocalDockerCompose(composeFiles, project);154 } else {155 dockerCompose = new ContainerisedDockerCompose(composeFiles, project);156 }157 dockerCompose158 .withCommand(cmd)159 .withEnv(env)160 .invoke();161 }162 private void applyScaling() {163 // Apply scaling164 if (!scalingPreferences.isEmpty()) {165 StringBuilder sb = new StringBuilder("scale");166 for (Map.Entry<String, Integer> scale : scalingPreferences.entrySet()) {167 sb.append(" ").append(scale.getKey()).append("=").append(scale.getValue());168 }169 runWithCompose(sb.toString());170 }171 }172 private void registerContainersForShutdown() {173 ResourceReaper.instance().registerFilterForCleanup(Arrays.asList(174 new SimpleEntry<>("label", "com.docker.compose.project=" + project)175 ));176 }177 private List<Container> listChildContainers() {178 return dockerClient.listContainersCmd()179 .withShowAll(true)180 .exec().stream()181 .filter(container -> Arrays.stream(container.getNames()).anyMatch(name ->182 name.startsWith("/" + project)))183 .collect(toList());184 }185 private void startAmbassadorContainers(Profiler profiler) {186 profiler.start("Ambassador container startup");187 ambassadorContainer.start();188 profiler.stop().log();189 }190 private Logger logger() {191 return LoggerFactory.getLogger(DockerComposeContainer.class);192 }193 @Override194 @VisibleForTesting195 public void finished(Description description) {196 synchronized (MUTEX) {197 try {198 // shut down the ambassador container199 ambassadorContainer.stop();200 // Kill the services using docker-compose201 try {202 runWithCompose("down -v");203 // If we reach here then docker-compose down has cleared networks and containers;204 // we can unregister from ResourceReaper205 spawnedContainerIds.forEach(ResourceReaper.instance()::unregisterContainer);206 spawnedNetworkIds.forEach(ResourceReaper.instance()::unregisterNetwork);207 } catch (Exception e) {208 // docker-compose down failed; use ResourceReaper to ensure cleanup209 // kill the spawned service containers210 spawnedContainerIds.forEach(ResourceReaper.instance()::stopAndRemoveContainer);211 // remove the networks after removing the containers212 spawnedNetworkIds.forEach(ResourceReaper.instance()::removeNetworkById);213 }214 spawnedContainerIds.clear();215 spawnedNetworkIds.clear();216 } finally {217 project = randomProjectId();218 }219 }220 }221 public SELF withExposedService(String serviceName, int servicePort) {222 return withExposedService(serviceName, servicePort, Wait.defaultWaitStrategy());223 }224 public DockerComposeContainer withExposedService(String serviceName, int instance, int servicePort) {225 return withExposedService(serviceName + "_" + instance, servicePort);226 }227 public DockerComposeContainer withExposedService(String serviceName, int instance, int servicePort, WaitStrategy waitStrategy) {228 return withExposedService(serviceName + "_" + instance, servicePort, waitStrategy);229 }230 public SELF withExposedService(String serviceName, int servicePort, @NonNull WaitStrategy waitStrategy) {231 String serviceInstanceName = getServiceInstanceName(serviceName);232 /*233 * For every service/port pair that needs to be exposed, we register a target on an 'ambassador container'.234 *235 * The ambassador container's role is to link (within the Docker network) to one of the236 * compose services, and proxy TCP network I/O out to a port that the ambassador container237 * exposes.238 *239 * This avoids the need for the docker compose file to explicitly expose ports on all the240 * services.241 *242 * {@link GenericContainer} should ensure that the ambassador container is on the same network243 * as the rest of the compose environment.244 */245 // Ambassador container will be started together after docker compose has started246 int ambassadorPort = nextAmbassadorPort.getAndIncrement();247 ambassadorPortMappings.computeIfAbsent(serviceInstanceName, __ -> new ConcurrentHashMap<>()).put(servicePort, ambassadorPort);248 ambassadorContainer.withTarget(ambassadorPort, serviceInstanceName, servicePort);249 ambassadorContainer.addLink(new FutureContainer(this.project + "_" + serviceInstanceName), serviceInstanceName);250 addWaitStrategy(serviceInstanceName, waitStrategy);251 return self();252 }253 private String getServiceInstanceName(String serviceName) {254 String serviceInstanceName = serviceName;255 if (!serviceInstanceName.matches(".*_[0-9]+")) {256 serviceInstanceName += "_1"; // implicit first instance of this service257 }258 return serviceInstanceName;259 }260 /*261 * can have multiple wait strategies for a single container, e.g. if waiting on several ports262 * if no wait strategy is defined, the WaitAllStrategy will return immediately.263 * The WaitAllStrategy uses an long timeout, because timeouts should be handled by the inner strategies.264 */265 private void addWaitStrategy(String serviceInstanceName, @NonNull WaitStrategy waitStrategy) {266 final WaitAllStrategy waitAllStrategy = waitStrategyMap.computeIfAbsent(serviceInstanceName, __ ->267 (WaitAllStrategy) new WaitAllStrategy().withStartupTimeout(Duration.ofMinutes(30)));268 waitAllStrategy.withStrategy(waitStrategy);269 }270 /**271 Specify the {@link WaitStrategy} to use to determine if the container is ready.272 *273 * @see org.testcontainers.containers.wait.strategy.Wait#defaultWaitStrategy()274 * @param serviceName the name of the service to wait for275 * @param waitStrategy the WaitStrategy to use276 * @return this277 */278 public SELF waitingFor(String serviceName, @NonNull WaitStrategy waitStrategy) {279 String serviceInstanceName = getServiceInstanceName(serviceName);280 addWaitStrategy(serviceInstanceName, waitStrategy);281 return self();282 }283 /**284 * Get the host (e.g. IP address or hostname) that an exposed service can be found at, from the host machine285 * (i.e. should be the machine that's running this Java process).286 * <p>287 * The service must have been declared using DockerComposeContainer#withExposedService.288 *289 * @param serviceName the name of the service as set in the docker-compose.yml file.290 * @param servicePort the port exposed by the service container.291 * @return a host IP address or hostname that can be used for accessing the service container.292 */293 public String getServiceHost(String serviceName, Integer servicePort) {294 return ambassadorContainer.getContainerIpAddress();295 }296 /**297 * Get the port that an exposed service can be found at, from the host machine298 * (i.e. should be the machine that's running this Java process).299 * <p>300 * The service must have been declared using DockerComposeContainer#withExposedService.301 *302 * @param serviceName the name of the service as set in the docker-compose.yml file.303 * @param servicePort the port exposed by the service container.304 * @return a port that can be used for accessing the service container.305 */306 public Integer getServicePort(String serviceName, Integer servicePort) {307 return ambassadorContainer.getMappedPort(ambassadorPortMappings.get(getServiceInstanceName(serviceName)).get(servicePort));308 }309 public SELF withScaledService(String serviceBaseName, int numInstances) {310 scalingPreferences.put(serviceBaseName, numInstances);311 return self();312 }313 public SELF withEnv(String key, String value) {314 env.put(key, value);315 return self();316 }317 public SELF withEnv(Map<String, String> env) {318 env.forEach(this.env::put);319 return self();320 }321 /**322 * Use a local Docker Compose binary instead of a container.323 *324 * @return this instance, for chaining325 */326 public SELF withLocalCompose(boolean localCompose) {327 this.localCompose = localCompose;328 return self();329 }330 /**331 * Whether to pull images first.332 *333 * @return this instance, for chaining334 */335 public SELF withPull(boolean pull) {336 this.pull = pull;337 return self();338 }339 /**340 * Whether to tail child container logs.341 *342 * @return this instance, for chaining343 */344 public SELF withTailChildContainers(boolean tailChildContainers) {345 this.tailChildContainers = tailChildContainers;346 return self();347 }348 /**349 * Attach an output consumer at container startup, enabling stdout and stderr to be followed, waited on, etc.350 * <p>351 * More than one consumer may be registered.352 *353 * @param serviceName the name of the service as set in the docker-compose.yml file354 * @param consumer consumer that output frames should be sent to355 * @return this instance, for chaining356 */357 public SELF withLogConsumer(String serviceName, Consumer<OutputFrame> consumer) {358 String serviceInstanceName = getServiceInstanceName(serviceName);359 final List<Consumer<OutputFrame>> consumers = this.logConsumers.getOrDefault(serviceInstanceName, new ArrayList<>());360 consumers.add(consumer);361 this.logConsumers.putIfAbsent(serviceInstanceName, consumers);362 return self();363 }364 private void followLogs(String containerId, Consumer<OutputFrame> consumer) {365 LogUtils.followOutput(DockerClientFactory.instance().client(), containerId, consumer);366 }367 private SELF self() {368 return (SELF) this;369 }370 private String randomProjectId() {371 return identifier + Base58.randomString(6).toLowerCase();372 }373}374interface DockerCompose {375 String ENV_PROJECT_NAME = "COMPOSE_PROJECT_NAME";376 String ENV_COMPOSE_FILE = "COMPOSE_FILE";377 DockerCompose withCommand(String cmd);378 DockerCompose withEnv(Map<String, String> env);379 void invoke();380 default void validateFileList(List<File> composeFiles) {381 checkNotNull(composeFiles);382 checkArgument(!composeFiles.isEmpty(), "No docker compose file have been provided");383 }384}385/**386 * Use Docker Compose container.387 */388class ContainerisedDockerCompose extends GenericContainer<ContainerisedDockerCompose> implements DockerCompose {389 private static final String DOCKER_SOCKET_PATH = "/var/run/docker.sock";390 private static final String DOCKER_CONFIG_FILE = "/root/.docker/config.json";391 private static final String DOCKER_CONFIG_ENV = "DOCKER_CONFIG_FILE";392 private static final String DOCKER_CONFIG_PROPERTY = "dockerConfigFile";393 public static final char UNIX_PATH_SEPERATOR = ':';394 public ContainerisedDockerCompose(List<File> composeFiles, String identifier) {395 super(TestcontainersConfiguration.getInstance().getDockerComposeContainerImage());396 validateFileList(composeFiles);397 addEnv(ENV_PROJECT_NAME, identifier);398 // Map the docker compose file into the container399 final File dockerComposeBaseFile = composeFiles.get(0);400 final String pwd = dockerComposeBaseFile.getAbsoluteFile().getParentFile().getAbsolutePath();401 final String containerPwd = MountableFile.forHostPath(pwd).getFilesystemPath();402 final List<String> absoluteDockerComposeFiles = composeFiles.stream()403 .map(File::getAbsolutePath)404 .map(MountableFile::forHostPath)405 .map(MountableFile::getFilesystemPath)406 .collect(toList());407 final String composeFileEnvVariableValue = Joiner.on(UNIX_PATH_SEPERATOR).join(absoluteDockerComposeFiles); // we always need the UNIX path separator408 logger().debug("Set env COMPOSE_FILE={}", composeFileEnvVariableValue);409 addEnv(ENV_COMPOSE_FILE, composeFileEnvVariableValue);410 addFileSystemBind(pwd, containerPwd, READ_ONLY);411 // Ensure that compose can access docker. Since the container is assumed to be running on the same machine412 // as the docker daemon, just mapping the docker control socket is OK.413 // As there seems to be a problem with mapping to the /var/run directory in certain environments (e.g. CircleCI)414 // we map the socket file outside of /var/run, as just /docker.sock415 addFileSystemBind(getDockerSocketHostPath(), "/docker.sock", READ_WRITE);416 addEnv("DOCKER_HOST", "unix:///docker.sock");417 setStartupCheckStrategy(new IndefiniteWaitOneShotStartupCheckStrategy());418 setWorkingDirectory(containerPwd);419 String dockerConfigPath = determineDockerConfigPath();420 if (dockerConfigPath != null && !dockerConfigPath.isEmpty()) {421 addFileSystemBind(dockerConfigPath, DOCKER_CONFIG_FILE, READ_ONLY);422 }423 }424 private String determineDockerConfigPath() {425 String dockerConfigEnv = System.getenv(DOCKER_CONFIG_ENV);426 String dockerConfigProperty = System.getProperty(DOCKER_CONFIG_PROPERTY);427 Path dockerConfig = Paths.get(System.getProperty("user.home"), ".docker", "config.json");428 if (dockerConfigEnv != null && !dockerConfigEnv.trim().isEmpty() && Files.exists(Paths.get(dockerConfigEnv))) {429 return dockerConfigEnv;430 } else if (dockerConfigProperty != null && !dockerConfigProperty.trim().isEmpty() && Files.exists(Paths.get(dockerConfigProperty))) {431 return dockerConfigProperty;432 } else if (Files.exists(dockerConfig)) {433 return dockerConfig.toString();434 } else {435 return null;436 }437 }438 private String getDockerSocketHostPath() {439 return SystemUtils.IS_OS_WINDOWS440 ? "/" + DOCKER_SOCKET_PATH441 : DOCKER_SOCKET_PATH;442 }443 @Override444 public void invoke() {445 super.start();446 this.followOutput(new Slf4jLogConsumer(logger()));447 // wait for the compose container to stop, which should only happen after it has spawned all the service containers448 logger().info("Docker Compose container is running for command: {}", Joiner.on(" ").join(this.getCommandParts()));449 while (this.isRunning()) {450 logger().trace("Compose container is still running");451 Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);452 }453 logger().info("Docker Compose has finished running");454 AuditLogger.doComposeLog(this.getCommandParts(), this.getEnv());455 final Integer exitCode = this.dockerClient.inspectContainerCmd(containerId)456 .exec()457 .getState()458 .getExitCode();459 if (exitCode == null || exitCode != 0) {460 throw new ContainerLaunchException(461 "Containerised Docker Compose exited abnormally with code " +462 exitCode +463 " whilst running command: " +464 StringUtils.join(this.getCommandParts(), ' '));465 }466 }467}468/**469 * Use local Docker Compose binary, if present.470 */471class LocalDockerCompose implements DockerCompose {472 /**473 * Executable name for Docker Compose.474 */475 private static final String COMPOSE_EXECUTABLE = SystemUtils.IS_OS_WINDOWS ? "docker-compose.exe" : "docker-compose";476 private final List<File> composeFiles;477 private final String identifier;478 private String cmd = "";479 private Map<String, String> env = new HashMap<>();480 public LocalDockerCompose(List<File> composeFiles, String identifier) {481 validateFileList(composeFiles);482 this.composeFiles = composeFiles;483 this.identifier = identifier;484 }485 @Override486 public DockerCompose withCommand(String cmd) {487 this.cmd = cmd;488 return this;489 }490 @Override491 public DockerCompose withEnv(Map<String, String> env) {492 this.env = env;493 return this;494 }...

Full Screen

Full Screen

LocalDockerCompose

Using AI Code Generation

copy

Full Screen

1import org.testcontainers.containers.DockerComposeContainer2import org.testcontainers.containers.wait.strategy.Wait3import org.testcontainers.utility.MountableFile4import org.testcontainers.containers.output.Slf4jLogConsumer5import org.slf4j.LoggerFactory6def logger = LoggerFactory.getLogger("testcontainers")7def dockerComposeContainer = new DockerComposeContainer(new File("docker-compose.yml"))8 .withLocalCompose(true)9 .withExposedService("selenium-hub", 4444, Wait.forLogMessage(".*Selenium Server is up and running.*", 1))10 .withExposedService("chrome", 5555, Wait.forLogMessage(".*Listening for transport dt_socket at address: 5555.*", 1))11 .withExposedService("firefox", 5555, Wait.forLogMessage(".*Listening for transport dt_socket at address: 5555.*", 1))12 .withLogConsumer("selenium-hub", new Slf4jLogConsumer(logger))13 .withLogConsumer("chrome", new Slf4jLogConsumer(logger))14 .withLogConsumer("firefox", new Slf4jLogConsumer(logger))15 .withFileFromPath("/opt/selenium/config.json", MountableFile.forClasspathResource("config.json"))16dockerComposeContainer.start()17dockerComposeContainer.stop()18dockerComposeContainer.remove()19def dockerComposeContainer = new DockerComposeContainer(new File("docker-compose.yml"))20 .withLocalCompose(true)21 .withExposedService("selenium-hub", 4444, Wait.forLogMessage(".*Selenium Server is up and running.*", 1))22 .withExposedService("chrome", 5555, Wait.forLogMessage(".*Listening for transport dt_socket at address: 5555.*", 1))23 .withExposedService("firefox", 5555, Wait.forLogMessage(".*Listening for transport dt_socket at address: 5555.*", 1))24 .withLogConsumer("selenium-hub", new Slf4jLogConsumer(logger))25 .withLogConsumer("chrome", new Slf4jLogConsumer(logger))26 .withLogConsumer("firefox", new Slf4jLogConsumer(logger))

Full Screen

Full Screen

LocalDockerCompose

Using AI Code Generation

copy

Full Screen

1import org.testcontainers.containers.DockerComposeContainer2import org.testcontainers.containers.wait.strategy.Wait3import org.testcontainers.containers.wait.strategy.WaitAllStrategy4import org.testcontainers.utility.MountableFile5class LocalDockerCompose extends DockerComposeContainer<LocalDockerCompose> {6 LocalDockerCompose(File composeFile) {7 super(composeFile)8 withLocalCompose(true)9 withPull(false)10 withExposedService("nginx_1", 80)11 withExposedService("nginx_1", 443)12 withExposedService("nginx_1", 8080)13 withExposedService("nginx_1", 8443)14 withExposedService("nginx_1", 8081)15 withExposedService("nginx_1", 8444)16 withExposedService("nginx_1", 8082)17 withExposedService("nginx_1", 8445)18 withExposedService("nginx_1", 8083)19 withExposedService("nginx_1", 8446)20 withExposedService("nginx_1", 8084)21 withExposedService("nginx_1", 8447)22 withExposedService("nginx_1", 8085)23 withExposedService("nginx_1", 8448)24 withExposedService("nginx_1", 8086)25 withExposedService("nginx_1", 8449)26 withExposedService("nginx_1", 8087)27 withExposedService("nginx_1", 8450)28 withExposedService("nginx_1", 8088)29 withExposedService("nginx_1", 8451)30 withExposedService("nginx_1", 8089)31 withExposedService("nginx_1", 8452)32 withExposedService("nginx_1", 8090)33 withExposedService("nginx_1", 8453)34 withExposedService("nginx_1", 8091)35 withExposedService("nginx_1", 8454)36 withExposedService("nginx_1", 8092)37 withExposedService("nginx_1", 8455)38 withExposedService("nginx_1", 8093)39 withExposedService("nginx_1", 8456)40 withExposedService("nginx_1", 8094)41 withExposedService("nginx_1", 845

Full Screen

Full Screen

LocalDockerCompose

Using AI Code Generation

copy

Full Screen

1 public void testDockerCompose() throws IOException {2 File file = new File("src/test/resources/docker-compose.yml");3 DockerComposeContainer dockerComposeContainer = new DockerComposeContainer(file)4 .withLocalCompose(true);5 dockerComposeContainer.start();6 dockerComposeContainer.stop();7 }8}

Full Screen

Full Screen

LocalDockerCompose

Using AI Code Generation

copy

Full Screen

1DockerComposeContainer compose = new DockerComposeContainer(new File("docker-compose.yml"))2 .withLocalCompose(true)3 .withPull(true);4compose.start();5DockerComposeContainer compose = new DockerComposeContainer(new File("docker-compose.yml"))6 .withLocalCompose(false)7 .withPull(true);8compose.start();9DockerComposeContainer compose = new DockerComposeContainer(new File("docker-compose.yml"))10 .withLocalCompose(false)11 .withPull(true)12 .withExposedService("db_1", 3306, Wait.forListeningPort());13compose.start();14DockerComposeContainer compose = new DockerComposeContainer(new File("docker-compose.yml"))15 .withLocalCompose(false)16 .withPull(true)17 .withExposedService("db_1", 3306, Wait.forListeningPort())18 .withExposedService("web_1", 80, Wait.forHttp("/").forStatusCode(200));19compose.start();20DockerComposeContainer compose = new DockerComposeContainer(new File("docker-compose.yml"))21 .withLocalCompose(false)22 .withPull(true)23 .withExposedService("db_1", 3306, Wait.forListeningPort())24 .withExposedService("web_1", 80, Wait.forHttp("/").forStatusCode(200))25 .withScaledService("web_1", 2);26compose.start();27DockerComposeContainer compose = new DockerComposeContainer(new File("docker-compose.yml"))28 .withLocalCompose(false)29 .withPull(true)30 .withExposedService("db_1", 3306, Wait.forListeningPort())31 .withExposedService("web_1", 80, Wait.forHttp("/").forStatusCode(200))32 .withScaledService("web_1", 2)33 .withScaledService("worker_1", 3);34compose.start();35DockerComposeContainer compose = new DockerComposeContainer(new File("docker-compose.yml"))36 .withLocalCompose(false)37 .withPull(true)38 .withExposedService("db_1", 3306, Wait.forListeningPort())39 .withExposedService("web_1", 80, Wait.forHttp("/").forStatusCode(200))40 .withScaledService("web_1", 2)41 .withScaledService("worker_1",

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful