package com.cameleer3.server.app; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.testcontainers.clickhouse.ClickHouseContainer; import org.junit.jupiter.api.BeforeAll; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; /** * Base class for integration tests requiring a ClickHouse instance. *

* Uses Testcontainers to spin up a ClickHouse server and initializes the schema * from {@code clickhouse/init/01-schema.sql} before the first test runs. * Subclasses get a {@link JdbcTemplate} for direct database assertions. *

* Container lifecycle is managed manually (started once, shared across all test classes). */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") public abstract class AbstractClickHouseIT { protected static final ClickHouseContainer CLICKHOUSE; static { CLICKHOUSE = new ClickHouseContainer("clickhouse/clickhouse-server:25.3"); CLICKHOUSE.start(); } @Autowired protected JdbcTemplate jdbcTemplate; @DynamicPropertySource static void overrideProperties(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url", CLICKHOUSE::getJdbcUrl); registry.add("spring.datasource.username", CLICKHOUSE::getUsername); registry.add("spring.datasource.password", CLICKHOUSE::getPassword); } @BeforeAll static void initSchema() throws Exception { // Surefire runs from the module directory; schema is in the project root Path baseDir = Path.of("clickhouse/init"); if (!Files.exists(baseDir)) { baseDir = Path.of("../clickhouse/init"); } // Load all schema files in order String[] schemaFiles = {"01-schema.sql", "02-search-columns.sql"}; try (Connection conn = DriverManager.getConnection( CLICKHOUSE.getJdbcUrl(), CLICKHOUSE.getUsername(), CLICKHOUSE.getPassword()); Statement stmt = conn.createStatement()) { for (String schemaFile : schemaFiles) { Path schemaPath = baseDir.resolve(schemaFile); if (Files.exists(schemaPath)) { String sql = Files.readString(schemaPath, StandardCharsets.UTF_8); // Execute each statement separately (separated by semicolons) for (String statement : sql.split(";")) { String trimmed = statement.trim(); if (!trimmed.isEmpty()) { stmt.execute(trimmed); } } } } } } }