diff --git a/msa/black-box-tests/pom.xml b/msa/black-box-tests/pom.xml index 5e8e06c1a3..6a3f9bf360 100644 --- a/msa/black-box-tests/pom.xml +++ b/msa/black-box-tests/pom.xml @@ -62,6 +62,21 @@ takari-cpsuite test + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + test + + + org.awaitility + awaitility + test + ch.qos.logback logback-classic diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java index 7f54298069..fd3604be5e 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ContainerTestSuite.java @@ -16,26 +16,34 @@ package org.thingsboard.server.msa; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; import org.junit.ClassRule; import org.junit.extensions.cpsuite.ClasspathSuite; -import org.junit.rules.ExternalResource; import org.junit.runner.RunWith; import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.wait.strategy.Wait; -import org.testcontainers.utility.Base58; import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.time.Duration; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.UUID; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.fail; @RunWith(ClasspathSuite.class) @ClasspathSuite.ClassnameFilters({"org.thingsboard.server.msa.*Test"}) @Slf4j public class ContainerTestSuite { + private static final String SOURCE_DIR = "./../../docker/"; + private static final String TB_CORE_LOG_REGEXP = ".*Starting polling for events.*"; + private static final String TRANSPORTS_LOG_REGEXP = ".*Going to recalculate partitions.*"; + private static DockerComposeContainer testContainer; @ClassRule @@ -46,31 +54,78 @@ public class ContainerTestSuite { if (testContainer == null) { boolean skipTailChildContainers = Boolean.valueOf(System.getProperty("blackBoxTests.skipTailChildContainers")); try { - String tbCoreLogRegexp = ".*Starting polling for events.*"; - String transportsLogRegexp = ".*Going to recalculate partitions.*"; + final String targetDir = FileUtils.getTempDirectoryPath() + "/" + "ContainerTestSuite-" + UUID.randomUUID() + "/"; + log.info("targetDir {}", targetDir); + FileUtils.copyDirectory(new File(SOURCE_DIR), new File(targetDir)); + replaceInFile(targetDir + "docker-compose.yml", " container_name: \"${LOAD_BALANCER_NAME}\"", "", "container_name"); - testContainer = new DockerComposeContainer<>( - new File("./../../docker/docker-compose.yml"), - new File("./../../docker/docker-compose.postgres.yml"), - new File("./../../docker/docker-compose.postgres.volumes.yml"), - new File("./../../docker/docker-compose.kafka.yml")) + class DockerComposeContainerImpl> extends DockerComposeContainer { + public DockerComposeContainerImpl(File... composeFiles) { + super(composeFiles); + } + + @Override + public void stop() { + super.stop(); + tryDeleteDir(targetDir); + } + } + + testContainer = new DockerComposeContainerImpl<>( + new File(targetDir + "docker-compose.yml"), + new File(targetDir + "docker-compose.postgres.yml"), + new File(targetDir + "docker-compose.postgres.volumes.yml"), + new File(targetDir + "docker-compose.kafka.yml")) .withPull(false) .withLocalCompose(true) .withTailChildContainers(!skipTailChildContainers) .withEnv(installTb.getEnv()) .withEnv("LOAD_BALANCER_NAME", "") .withExposedService("haproxy", 80, Wait.forHttp("/swagger-ui.html").withStartupTimeout(Duration.ofSeconds(400))) - .waitingFor("tb-core1", Wait.forLogMessage(tbCoreLogRegexp, 1).withStartupTimeout(Duration.ofSeconds(400))) - .waitingFor("tb-core2", Wait.forLogMessage(tbCoreLogRegexp, 1).withStartupTimeout(Duration.ofSeconds(400))) - .waitingFor("tb-http-transport1", Wait.forLogMessage(transportsLogRegexp, 1).withStartupTimeout(Duration.ofSeconds(400))) - .waitingFor("tb-http-transport2", Wait.forLogMessage(transportsLogRegexp, 1).withStartupTimeout(Duration.ofSeconds(400))) - .waitingFor("tb-mqtt-transport1", Wait.forLogMessage(transportsLogRegexp, 1).withStartupTimeout(Duration.ofSeconds(400))) - .waitingFor("tb-mqtt-transport2", Wait.forLogMessage(transportsLogRegexp, 1).withStartupTimeout(Duration.ofSeconds(400))); + .waitingFor("tb-core1", Wait.forLogMessage(TB_CORE_LOG_REGEXP, 1).withStartupTimeout(Duration.ofSeconds(400))) + .waitingFor("tb-core2", Wait.forLogMessage(TB_CORE_LOG_REGEXP, 1).withStartupTimeout(Duration.ofSeconds(400))) + .waitingFor("tb-http-transport1", Wait.forLogMessage(TRANSPORTS_LOG_REGEXP, 1).withStartupTimeout(Duration.ofSeconds(400))) + .waitingFor("tb-http-transport2", Wait.forLogMessage(TRANSPORTS_LOG_REGEXP, 1).withStartupTimeout(Duration.ofSeconds(400))) + .waitingFor("tb-mqtt-transport1", Wait.forLogMessage(TRANSPORTS_LOG_REGEXP, 1).withStartupTimeout(Duration.ofSeconds(400))) + .waitingFor("tb-mqtt-transport2", Wait.forLogMessage(TRANSPORTS_LOG_REGEXP, 1).withStartupTimeout(Duration.ofSeconds(400))); } catch (Exception e) { log.error("Failed to create test container", e); - throw e; + fail("Failed to create test container"); } } return testContainer; } + + private static void tryDeleteDir(String targetDir) { + try { + log.info("Trying to delete temp dir {}", targetDir); + FileUtils.deleteDirectory(new File(targetDir)); + } catch (IOException e) { + log.error("Can't delete temp directory " + targetDir, e); + } + } + + /** + * This workaround is actual until issue will be resolved: + * Support container_name in docker-compose file #2472 https://github.com/testcontainers/testcontainers-java/issues/2472 + * docker-compose files which contain container_name are not supported and the creation of DockerComposeContainer fails due to IllegalStateException. + * This has been introduced in #1151 as a quick fix for unintuitive feedback. https://github.com/testcontainers/testcontainers-java/issues/1151 + * Using the latest testcontainers and waiting for the fix... + * */ + private static void replaceInFile(String sourceFilename, String target, String replacement, String verifyPhrase) { + try { + File file = new File(sourceFilename); + String sourceContent = FileUtils.readFileToString(file, StandardCharsets.UTF_8); + + String outputContent = sourceContent.replace(target, replacement); + assertThat(outputContent, (not(containsString(target)))); + assertThat(outputContent, (not(containsString(verifyPhrase)))); + + FileUtils.writeStringToFile(file, outputContent, StandardCharsets.UTF_8); + assertThat(FileUtils.readFileToString(file, StandardCharsets.UTF_8), is(outputContent)); + } catch (IOException e) { + log.error("failed to update file " + sourceFilename, e); + fail("failed to update file"); + } + } } diff --git a/pom.xml b/pom.xml index 869646d220..592dff41ae 100755 --- a/pom.xml +++ b/pom.xml @@ -123,8 +123,8 @@ 1.3.0 1.2.7 - 1.11.4 - 1.10 + 1.16.0 + 1.12 @@ -1736,6 +1736,12 @@ testcontainers ${testcontainers.version} test + + + junit + junit + + org.zeroturnaround