From 1330cd932ee949c5753bbe4025cf979a6ac82764 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 18 Jul 2025 13:54:32 +0300 Subject: [PATCH] Fix black box tests. --- .../server/controller/AiModelController.java | 2 + .../server/msa/ContainerTestSuite.java | 44 +++++++++++------ .../org/thingsboard/server/msa/TestUtils.java | 43 ++++++++++++++++ .../server/msa/ThingsBoardDbInstaller.java | 49 +++++++++++-------- 4 files changed, 101 insertions(+), 37 deletions(-) create mode 100644 msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestUtils.java diff --git a/application/src/main/java/org/thingsboard/server/controller/AiModelController.java b/application/src/main/java/org/thingsboard/server/controller/AiModelController.java index 5a00e26f17..34a0bbebfc 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AiModelController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AiModelController.java @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.AiModelId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.config.annotations.ApiOperation; +import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.ai.AiChatModelService; import org.thingsboard.server.service.security.permission.Operation; import org.thingsboard.server.service.security.permission.Resource; @@ -59,6 +60,7 @@ import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHO @Validated @RestController +@TbCoreComponent @RequiredArgsConstructor @RequestMapping("/api/ai/model") class AiModelController extends BaseController { 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 3a337dbb8b..77e80f25ac 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 @@ -38,6 +38,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; import static org.testng.Assert.fail; +import static org.thingsboard.server.msa.TestUtils.addComposeVersion; @Slf4j public class ContainerTestSuite { @@ -53,7 +54,7 @@ public class ContainerTestSuite { private static final String TB_JS_EXECUTOR_LOG_REGEXP = ".*template started.*"; private static final Duration CONTAINER_STARTUP_TIMEOUT = Duration.ofSeconds(400); - private DockerComposeContainer testContainer; + private DockerComposeContainerImpl testContainer; private ThingsBoardDbInstaller installTb; private boolean isActive; @@ -78,8 +79,6 @@ public class ContainerTestSuite { } public void start() { - installTb = new ThingsBoardDbInstaller(); - installTb.createVolumes(); log.info("System property of blackBoxTests.redisCluster is {}", IS_VALKEY_CLUSTER); log.info("System property of blackBoxTests.redisSentinel is {}", IS_VALKEY_SENTINEL); log.info("System property of blackBoxTests.redisSsl is {}", IS_VALKEY_SSL); @@ -93,17 +92,8 @@ public class ContainerTestSuite { FileUtils.copyDirectory(new File("src/test/resources"), new File(targetDir)); - class DockerComposeContainerImpl> extends DockerComposeContainer { - public DockerComposeContainerImpl(List composeFiles) { - super(composeFiles); - } - - @Override - public void stop() { - super.stop(); - tryDeleteDir(targetDir); - } - } + installTb = new ThingsBoardDbInstaller(targetDir); + installTb.createVolumes(); if (IS_VALKEY_SSL) { addToFile(targetDir, "cache-valkey.env", @@ -132,7 +122,9 @@ public class ContainerTestSuite { composeFiles.add(new File(targetDir + "docker-compose.cassandra.volumes.yml")); } - testContainer = new DockerComposeContainerImpl<>(composeFiles) + addComposeVersion(composeFiles, "3.0"); + + testContainer = new DockerComposeContainerImpl(targetDir, composeFiles) .withPull(false) .withLocalCompose(true) .withOptions("--compatibility") @@ -194,7 +186,8 @@ public class ContainerTestSuite { public void stop() { if (isActive) { testContainer.stop(); - installTb.savaLogsAndRemoveVolumes(); + installTb.saveLogsAndRemoveVolumes(); + testContainer.cleanup(); setActive(false); } } @@ -261,4 +254,23 @@ public class ContainerTestSuite { public DockerComposeContainer getTestContainer() { return testContainer; } + + static class DockerComposeContainerImpl extends DockerComposeContainer { + + private final String targetDir; + + public DockerComposeContainerImpl(String targetDir, List composeFiles) { + super(composeFiles); + this.targetDir = targetDir; + } + + @Override + public void stop() { + super.stop(); + } + + public void cleanup() { + tryDeleteDir(this.targetDir); + } + } } diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestUtils.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestUtils.java new file mode 100644 index 0000000000..e70e020e88 --- /dev/null +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/TestUtils.java @@ -0,0 +1,43 @@ +/** + * Copyright © 2016-2025 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.msa; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +public class TestUtils { + + public static void addComposeVersion(List composeFiles, String version) throws IOException { + for (File composeFile : composeFiles) { + addComposeVersion(composeFile, version); + } + } + + public static void addComposeVersion(File composeFile, String version) throws IOException { + Path composeFilePath = composeFile.toPath(); + String data = Files.readString(composeFilePath); + String versionString = "version: '" + version + "'"; + if (!data.contains(versionString)) { + data += "\n" + versionString + "\n"; + } + Files.writeString(composeFilePath, data); + } + +} diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java index 3c57e08487..72be05922b 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/ThingsBoardDbInstaller.java @@ -20,6 +20,7 @@ import org.testcontainers.utility.Base58; import org.thingsboard.server.common.data.StringUtils; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -29,6 +30,8 @@ import java.util.StringJoiner; import java.util.stream.Collectors; import java.util.stream.IntStream; +import static org.thingsboard.server.msa.TestUtils.addComposeVersion; + @Slf4j public class ThingsBoardDbInstaller { @@ -53,6 +56,7 @@ public class ThingsBoardDbInstaller { private final DockerComposeExecutor dockerCompose; + private final String targetDir; private final String postgresDataVolume; private final String cassandraDataVolume; @@ -69,27 +73,30 @@ public class ThingsBoardDbInstaller { private final String tbEdqsLogVolume; private final Map env; - public ThingsBoardDbInstaller() { + public ThingsBoardDbInstaller(String targetDir) throws IOException { + this.targetDir = targetDir; log.info("System property of blackBoxTests.redisCluster is {}", IS_VALKEY_CLUSTER); - log.info("System property of blackBoxTests.redisCluster is {}", IS_VALKEY_SENTINEL); + log.info("System property of blackBoxTests.redisSentinel is {}", IS_VALKEY_SENTINEL); log.info("System property of blackBoxTests.hybridMode is {}", IS_HYBRID_MODE); List composeFiles = new ArrayList<>(Arrays.asList( - new File("./../../docker/docker-compose.yml"), - new File("./../../docker/docker-compose.volumes.yml"), + new File(targetDir + "docker-compose.yml"), + new File(targetDir + "docker-compose.volumes.yml"), IS_HYBRID_MODE - ? new File("./../../docker/docker-compose.hybrid.yml") - : new File("./../../docker/docker-compose.postgres.yml"), - new File("./../../docker/docker-compose.postgres.volumes.yml"), - resolveValkeyComposeFile(), - resolveValkeyComposeVolumesFile() + ? new File(targetDir + "docker-compose.hybrid.yml") + : new File(targetDir + "docker-compose.postgres.yml"), + new File(targetDir + "docker-compose.postgres.volumes.yml"), + resolveValkeyComposeFile(targetDir), + resolveValkeyComposeVolumesFile(targetDir) )); if (IS_HYBRID_MODE) { - composeFiles.add(new File("./../../docker/docker-compose.cassandra.volumes.yml")); - composeFiles.add(new File("src/test/resources/docker-compose.hybrid-test-extras.yml")); + composeFiles.add(new File(targetDir + "docker-compose.cassandra.volumes.yml")); + composeFiles.add(new File(targetDir + "docker-compose.hybrid-test-extras.yml")); } else { - composeFiles.add(new File("src/test/resources/docker-compose.postgres-test-extras.yml")); + composeFiles.add(new File(targetDir + "docker-compose.postgres-test-extras.yml")); } + addComposeVersion(composeFiles, "3.0"); + String identifier = Base58.randomString(6).toLowerCase(); String project = identifier + Base58.randomString(6).toLowerCase(); @@ -137,24 +144,24 @@ public class ThingsBoardDbInstaller { dockerCompose.withEnv(env); } - private static File resolveValkeyComposeVolumesFile() { + private static File resolveValkeyComposeVolumesFile(String targetDir) { if (IS_VALKEY_CLUSTER) { - return new File("./../../docker/docker-compose.valkey-cluster.volumes.yml"); + return new File(targetDir + "docker-compose.valkey-cluster.volumes.yml"); } if (IS_VALKEY_SENTINEL) { - return new File("./../../docker/docker-compose.valkey-sentinel.volumes.yml"); + return new File(targetDir + "docker-compose.valkey-sentinel.volumes.yml"); } - return new File("./../../docker/docker-compose.valkey.volumes.yml"); + return new File(targetDir + "docker-compose.valkey.volumes.yml"); } - private static File resolveValkeyComposeFile() { + private static File resolveValkeyComposeFile(String targetDir) { if (IS_VALKEY_CLUSTER) { - return new File("./../../docker/docker-compose.valkey-cluster.yml"); + return new File(targetDir + "docker-compose.valkey-cluster.yml"); } if (IS_VALKEY_SENTINEL) { - return new File("./../../docker/docker-compose.valkey-sentinel.yml"); + return new File(targetDir + "docker-compose.valkey-sentinel.yml"); } - return new File("./../../docker/docker-compose.valkey.yml"); + return new File(targetDir + "docker-compose.valkey.yml"); } public Map getEnv() { @@ -240,7 +247,7 @@ public class ThingsBoardDbInstaller { } } - public void savaLogsAndRemoveVolumes() { + public void saveLogsAndRemoveVolumes() { copyLogs(tbLogVolume, "./target/tb-logs/"); copyLogs(tbCoapTransportLogVolume, "./target/tb-coap-transport-logs/"); copyLogs(tbLwm2mTransportLogVolume, "./target/tb-lwm2m-transport-logs/");