Fix black box tests.
This commit is contained in:
		
							parent
							
								
									fba48ee9c5
								
							
						
					
					
						commit
						1330cd932e
					
				@ -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.id.AiModelId;
 | 
				
			||||||
import org.thingsboard.server.common.data.page.PageData;
 | 
					import org.thingsboard.server.common.data.page.PageData;
 | 
				
			||||||
import org.thingsboard.server.config.annotations.ApiOperation;
 | 
					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.ai.AiChatModelService;
 | 
				
			||||||
import org.thingsboard.server.service.security.permission.Operation;
 | 
					import org.thingsboard.server.service.security.permission.Operation;
 | 
				
			||||||
import org.thingsboard.server.service.security.permission.Resource;
 | 
					import org.thingsboard.server.service.security.permission.Resource;
 | 
				
			||||||
@ -59,6 +60,7 @@ import static org.thingsboard.server.controller.ControllerConstants.TENANT_AUTHO
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@Validated
 | 
					@Validated
 | 
				
			||||||
@RestController
 | 
					@RestController
 | 
				
			||||||
 | 
					@TbCoreComponent
 | 
				
			||||||
@RequiredArgsConstructor
 | 
					@RequiredArgsConstructor
 | 
				
			||||||
@RequestMapping("/api/ai/model")
 | 
					@RequestMapping("/api/ai/model")
 | 
				
			||||||
class AiModelController extends BaseController {
 | 
					class AiModelController extends BaseController {
 | 
				
			||||||
 | 
				
			|||||||
@ -38,6 +38,7 @@ import static org.hamcrest.CoreMatchers.is;
 | 
				
			|||||||
import static org.hamcrest.CoreMatchers.not;
 | 
					import static org.hamcrest.CoreMatchers.not;
 | 
				
			||||||
import static org.hamcrest.MatcherAssert.assertThat;
 | 
					import static org.hamcrest.MatcherAssert.assertThat;
 | 
				
			||||||
import static org.testng.Assert.fail;
 | 
					import static org.testng.Assert.fail;
 | 
				
			||||||
 | 
					import static org.thingsboard.server.msa.TestUtils.addComposeVersion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Slf4j
 | 
					@Slf4j
 | 
				
			||||||
public class ContainerTestSuite {
 | 
					public class ContainerTestSuite {
 | 
				
			||||||
@ -53,7 +54,7 @@ public class ContainerTestSuite {
 | 
				
			|||||||
    private static final String TB_JS_EXECUTOR_LOG_REGEXP = ".*template started.*";
 | 
					    private static final String TB_JS_EXECUTOR_LOG_REGEXP = ".*template started.*";
 | 
				
			||||||
    private static final Duration CONTAINER_STARTUP_TIMEOUT = Duration.ofSeconds(400);
 | 
					    private static final Duration CONTAINER_STARTUP_TIMEOUT = Duration.ofSeconds(400);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private DockerComposeContainer<?> testContainer;
 | 
					    private DockerComposeContainerImpl testContainer;
 | 
				
			||||||
    private ThingsBoardDbInstaller installTb;
 | 
					    private ThingsBoardDbInstaller installTb;
 | 
				
			||||||
    private boolean isActive;
 | 
					    private boolean isActive;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,8 +79,6 @@ public class ContainerTestSuite {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void start() {
 | 
					    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.redisCluster is {}", IS_VALKEY_CLUSTER);
 | 
				
			||||||
        log.info("System property of blackBoxTests.redisSentinel is {}", IS_VALKEY_SENTINEL);
 | 
					        log.info("System property of blackBoxTests.redisSentinel is {}", IS_VALKEY_SENTINEL);
 | 
				
			||||||
        log.info("System property of blackBoxTests.redisSsl is {}", IS_VALKEY_SSL);
 | 
					        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));
 | 
					            FileUtils.copyDirectory(new File("src/test/resources"), new File(targetDir));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            class DockerComposeContainerImpl<SELF extends DockerComposeContainer<SELF>> extends DockerComposeContainer<SELF> {
 | 
					            installTb = new ThingsBoardDbInstaller(targetDir);
 | 
				
			||||||
                public DockerComposeContainerImpl(List<File> composeFiles) {
 | 
					            installTb.createVolumes();
 | 
				
			||||||
                    super(composeFiles);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                @Override
 | 
					 | 
				
			||||||
                public void stop() {
 | 
					 | 
				
			||||||
                    super.stop();
 | 
					 | 
				
			||||||
                    tryDeleteDir(targetDir);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (IS_VALKEY_SSL) {
 | 
					            if (IS_VALKEY_SSL) {
 | 
				
			||||||
                addToFile(targetDir, "cache-valkey.env",
 | 
					                addToFile(targetDir, "cache-valkey.env",
 | 
				
			||||||
@ -132,7 +122,9 @@ public class ContainerTestSuite {
 | 
				
			|||||||
                composeFiles.add(new File(targetDir + "docker-compose.cassandra.volumes.yml"));
 | 
					                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)
 | 
					                    .withPull(false)
 | 
				
			||||||
                    .withLocalCompose(true)
 | 
					                    .withLocalCompose(true)
 | 
				
			||||||
                    .withOptions("--compatibility")
 | 
					                    .withOptions("--compatibility")
 | 
				
			||||||
@ -194,7 +186,8 @@ public class ContainerTestSuite {
 | 
				
			|||||||
    public void stop() {
 | 
					    public void stop() {
 | 
				
			||||||
        if (isActive) {
 | 
					        if (isActive) {
 | 
				
			||||||
            testContainer.stop();
 | 
					            testContainer.stop();
 | 
				
			||||||
            installTb.savaLogsAndRemoveVolumes();
 | 
					            installTb.saveLogsAndRemoveVolumes();
 | 
				
			||||||
 | 
					            testContainer.cleanup();
 | 
				
			||||||
            setActive(false);
 | 
					            setActive(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -261,4 +254,23 @@ public class ContainerTestSuite {
 | 
				
			|||||||
    public DockerComposeContainer<?> getTestContainer() {
 | 
					    public DockerComposeContainer<?> getTestContainer() {
 | 
				
			||||||
        return testContainer;
 | 
					        return testContainer;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static class DockerComposeContainerImpl extends DockerComposeContainer<DockerComposeContainerImpl> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private final String targetDir;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DockerComposeContainerImpl(String targetDir, List<File> composeFiles) {
 | 
				
			||||||
 | 
					            super(composeFiles);
 | 
				
			||||||
 | 
					            this.targetDir = targetDir;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
 | 
					        public void stop() {
 | 
				
			||||||
 | 
					            super.stop();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void cleanup() {
 | 
				
			||||||
 | 
					            tryDeleteDir(this.targetDir);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -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<File> 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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -20,6 +20,7 @@ import org.testcontainers.utility.Base58;
 | 
				
			|||||||
import org.thingsboard.server.common.data.StringUtils;
 | 
					import org.thingsboard.server.common.data.StringUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
@ -29,6 +30,8 @@ import java.util.StringJoiner;
 | 
				
			|||||||
import java.util.stream.Collectors;
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
import java.util.stream.IntStream;
 | 
					import java.util.stream.IntStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.thingsboard.server.msa.TestUtils.addComposeVersion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Slf4j
 | 
					@Slf4j
 | 
				
			||||||
public class ThingsBoardDbInstaller {
 | 
					public class ThingsBoardDbInstaller {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -53,6 +56,7 @@ public class ThingsBoardDbInstaller {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private final DockerComposeExecutor dockerCompose;
 | 
					    private final DockerComposeExecutor dockerCompose;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final String targetDir;
 | 
				
			||||||
    private final String postgresDataVolume;
 | 
					    private final String postgresDataVolume;
 | 
				
			||||||
    private final String cassandraDataVolume;
 | 
					    private final String cassandraDataVolume;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -69,27 +73,30 @@ public class ThingsBoardDbInstaller {
 | 
				
			|||||||
    private final String tbEdqsLogVolume;
 | 
					    private final String tbEdqsLogVolume;
 | 
				
			||||||
    private final Map<String, String> env;
 | 
					    private final Map<String, String> 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_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);
 | 
					        log.info("System property of blackBoxTests.hybridMode is {}", IS_HYBRID_MODE);
 | 
				
			||||||
        List<File> composeFiles = new ArrayList<>(Arrays.asList(
 | 
					        List<File> composeFiles = new ArrayList<>(Arrays.asList(
 | 
				
			||||||
                new File("./../../docker/docker-compose.yml"),
 | 
					                new File(targetDir + "docker-compose.yml"),
 | 
				
			||||||
                new File("./../../docker/docker-compose.volumes.yml"),
 | 
					                new File(targetDir + "docker-compose.volumes.yml"),
 | 
				
			||||||
                IS_HYBRID_MODE
 | 
					                IS_HYBRID_MODE
 | 
				
			||||||
                        ? new File("./../../docker/docker-compose.hybrid.yml")
 | 
					                        ? new File(targetDir + "docker-compose.hybrid.yml")
 | 
				
			||||||
                        : new File("./../../docker/docker-compose.postgres.yml"),
 | 
					                        : new File(targetDir + "docker-compose.postgres.yml"),
 | 
				
			||||||
                new File("./../../docker/docker-compose.postgres.volumes.yml"),
 | 
					                new File(targetDir + "docker-compose.postgres.volumes.yml"),
 | 
				
			||||||
                resolveValkeyComposeFile(),
 | 
					                resolveValkeyComposeFile(targetDir),
 | 
				
			||||||
                resolveValkeyComposeVolumesFile()
 | 
					                resolveValkeyComposeVolumesFile(targetDir)
 | 
				
			||||||
        ));
 | 
					        ));
 | 
				
			||||||
        if (IS_HYBRID_MODE) {
 | 
					        if (IS_HYBRID_MODE) {
 | 
				
			||||||
            composeFiles.add(new File("./../../docker/docker-compose.cassandra.volumes.yml"));
 | 
					            composeFiles.add(new File(targetDir + "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.hybrid-test-extras.yml"));
 | 
				
			||||||
        } else {
 | 
					        } 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 identifier = Base58.randomString(6).toLowerCase();
 | 
				
			||||||
        String project = identifier + Base58.randomString(6).toLowerCase();
 | 
					        String project = identifier + Base58.randomString(6).toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -137,24 +144,24 @@ public class ThingsBoardDbInstaller {
 | 
				
			|||||||
        dockerCompose.withEnv(env);
 | 
					        dockerCompose.withEnv(env);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static File resolveValkeyComposeVolumesFile() {
 | 
					    private static File resolveValkeyComposeVolumesFile(String targetDir) {
 | 
				
			||||||
        if (IS_VALKEY_CLUSTER) {
 | 
					        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) {
 | 
					        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) {
 | 
					        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) {
 | 
					        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<String, String> getEnv() {
 | 
					    public Map<String, String> getEnv() {
 | 
				
			||||||
@ -240,7 +247,7 @@ public class ThingsBoardDbInstaller {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public void savaLogsAndRemoveVolumes() {
 | 
					    public void saveLogsAndRemoveVolumes() {
 | 
				
			||||||
        copyLogs(tbLogVolume, "./target/tb-logs/");
 | 
					        copyLogs(tbLogVolume, "./target/tb-logs/");
 | 
				
			||||||
        copyLogs(tbCoapTransportLogVolume, "./target/tb-coap-transport-logs/");
 | 
					        copyLogs(tbCoapTransportLogVolume, "./target/tb-coap-transport-logs/");
 | 
				
			||||||
        copyLogs(tbLwm2mTransportLogVolume, "./target/tb-lwm2m-transport-logs/");
 | 
					        copyLogs(tbLwm2mTransportLogVolume, "./target/tb-lwm2m-transport-logs/");
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user