Skip to content

Commit

Permalink
Fix the connection leak problem caused by improper configuration of u…
Browse files Browse the repository at this point in the history
…nit test lifecycle
  • Loading branch information
linghengqian committed Jan 20, 2025
1 parent 64ef5d5 commit a1987ee
Show file tree
Hide file tree
Showing 25 changed files with 477 additions and 342 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"name":"[Lcom.github.dockerjava.api.model.VolumesFrom;"
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007f258bdf9c28"},
"condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007fe21bdf9c28"},
"name":"[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;"
},
{
Expand Down Expand Up @@ -749,11 +749,6 @@
"queryAllPublicConstructors":true,
"methods":[{"name":"<init>","parameterTypes":[] }, {"name":"add","parameterTypes":["long"] }, {"name":"sum","parameterTypes":[] }]
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.proxy.frontend.command.CommandExecutorTask"},
"name":"java.util.concurrent.atomic.Striped64$Cell",
"fields":[{"name":"value"}]
},
{
"condition":{"typeReachable":"org.apache.shardingsphere.infra.expr.groovy.GroovyInlineExpressionParser"},
"name":"java.util.function.DoubleFunction",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager"},
"pattern":"\\QMETA-INF/services/com.clickhouse.client.ClickHouseClient\\E"
}, {
"condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007f258bca2b10"},
"condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.connection.DriverDatabaseConnectionManager$$Lambda/0x00007fe21bca2710"},
"pattern":"\\QMETA-INF/services/com.clickhouse.client.ClickHouseClient\\E"
}, {
"condition":{"typeReachable":"org.apache.shardingsphere.driver.jdbc.core.datasource.ShardingSphereDataSource"},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection;
import org.apache.shardingsphere.infra.database.core.DefaultDatabase;
import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.test.natived.commons.TestShardingService;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledInNativeImage;
import org.testcontainers.containers.GenericContainer;
Expand Down Expand Up @@ -58,53 +61,57 @@
@Testcontainers
class ClickHouseTest {

private static final Network NETWORK = Network.newNetwork();
private final Network network = Network.newNetwork();

@Container
private static final GenericContainer<?> CLICKHOUSE_KEEPER_CONTAINER = new GenericContainer<>("clickhouse/clickhouse-keeper:24.11.1.2557")
private final GenericContainer<?> clickhouseKeeperContainer = new GenericContainer<>("clickhouse/clickhouse-keeper:24.11.1.2557")
.withCopyFileToContainer(
MountableFile.forHostPath(Paths.get("src/test/resources/test-native/xml/keeper_config.xml").toAbsolutePath()),
"/etc/clickhouse-keeper/keeper_config.xml")
.withNetwork(NETWORK)
.withNetwork(network)
.withExposedPorts(9181)
.withNetworkAliases("clickhouse-keeper-01");

@Container
public static final GenericContainer<?> CONTAINER = new GenericContainer<>("clickhouse/clickhouse-server:24.11.1.2557")
private final GenericContainer<?> container = new GenericContainer<>("clickhouse/clickhouse-server:24.11.1.2557")
.withCopyFileToContainer(
MountableFile.forHostPath(Paths.get("src/test/resources/test-native/xml/transactions.xml").toAbsolutePath()),
"/etc/clickhouse-server/config.d/transactions.xml")
.withNetwork(NETWORK)
.withNetwork(network)
.withExposedPorts(8123)
.dependsOn(CLICKHOUSE_KEEPER_CONTAINER);
.dependsOn(clickhouseKeeperContainer);

private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.clickhouse.";
private final String systemPropKeyPrefix = "fixture.test-native.yaml.database.clickhouse.";

private static DataSource logicDataSource;
private DataSource logicDataSource;

private String jdbcUrlPrefix;

@BeforeAll
static void beforeAll() {
assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url"), is(nullValue()));
assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url"), is(nullValue()));
assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url"), is(nullValue()));
@BeforeEach
void beforeEach() {
assertThat(System.getProperty(systemPropKeyPrefix + "ds0.jdbc-url"), is(nullValue()));
assertThat(System.getProperty(systemPropKeyPrefix + "ds1.jdbc-url"), is(nullValue()));
assertThat(System.getProperty(systemPropKeyPrefix + "ds2.jdbc-url"), is(nullValue()));
}

@AfterAll
static void afterAll() throws SQLException {
@AfterEach
void afterEach() throws SQLException {
try (Connection connection = logicDataSource.getConnection()) {
connection.unwrap(ShardingSphereConnection.class).getContextManager().close();
ContextManager contextManager = connection.unwrap(ShardingSphereConnection.class).getContextManager();
for (StorageUnit each : contextManager.getStorageUnits(DefaultDatabase.LOGIC_NAME).values()) {
each.getDataSource().unwrap(HikariDataSource.class).close();
}
contextManager.close();
}
NETWORK.close();
System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url");
System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url");
System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url");
network.close();
System.clearProperty(systemPropKeyPrefix + "ds0.jdbc-url");
System.clearProperty(systemPropKeyPrefix + "ds1.jdbc-url");
System.clearProperty(systemPropKeyPrefix + "ds2.jdbc-url");
}

@Test
void assertShardingInLocalTransactions() throws SQLException {
jdbcUrlPrefix = "jdbc:ch://localhost:" + CONTAINER.getMappedPort(8123) + "/";
jdbcUrlPrefix = "jdbc:ch://localhost:" + container.getMappedPort(8123) + "/";
logicDataSource = createDataSource();
TestShardingService testShardingService = new TestShardingService(logicDataSource);
testShardingService.processSuccessInClickHouse();
Expand All @@ -118,7 +125,7 @@ private Connection openConnection(final String databaseName) throws SQLException
}

private DataSource createDataSource() throws SQLException {
String connectionString = CLICKHOUSE_KEEPER_CONTAINER.getHost() + ":" + CLICKHOUSE_KEEPER_CONTAINER.getMappedPort(9181);
String connectionString = clickhouseKeeperContainer.getHost() + ":" + clickhouseKeeperContainer.getMappedPort(9181);
Awaitility.await().atMost(Duration.ofMinutes(1L)).ignoreExceptions().until(() -> {
try (
CuratorFramework client = CuratorFrameworkFactory.builder().connectString(connectionString)
Expand All @@ -139,9 +146,9 @@ private DataSource createDataSource() throws SQLException {
HikariConfig config = new HikariConfig();
config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver");
config.setJdbcUrl("jdbc:shardingsphere:classpath:test-native/yaml/jdbc/databases/clickhouse.yaml?placeholder-type=system_props");
System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url", jdbcUrlPrefix + "demo_ds_0?transactionSupport=true");
System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url", jdbcUrlPrefix + "demo_ds_1?transactionSupport=true");
System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url", jdbcUrlPrefix + "demo_ds_2?transactionSupport=true");
System.setProperty(systemPropKeyPrefix + "ds0.jdbc-url", jdbcUrlPrefix + "demo_ds_0?transactionSupport=true");
System.setProperty(systemPropKeyPrefix + "ds1.jdbc-url", jdbcUrlPrefix + "demo_ds_1?transactionSupport=true");
System.setProperty(systemPropKeyPrefix + "ds2.jdbc-url", jdbcUrlPrefix + "demo_ds_2?transactionSupport=true");
return new HikariDataSource(config);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection;
import org.apache.shardingsphere.infra.database.core.DefaultDatabase;
import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.test.natived.commons.TestShardingService;
import org.awaitility.Awaitility;
import org.firebirdsql.management.FBManager;
import org.firebirdsql.management.PageSizeConstants;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledInNativeImage;
import org.testcontainers.containers.GenericContainer;
Expand All @@ -47,46 +50,50 @@
@Testcontainers
class FirebirdTest {

private static final String SYSTEM_PROP_KEY_PREFIX = "fixture.test-native.yaml.database.firebird.";
private final String systemPropKeyPrefix = "fixture.test-native.yaml.database.firebird.";

private static final String PASSWORD = "masterkey";
private final String password = "masterkey";

@SuppressWarnings("resource")
@Container
private static final GenericContainer<?> CONTAINER = new GenericContainer<>("ghcr.io/fdcastel/firebird:5.0.1")
.withEnv("FIREBIRD_ROOT_PASSWORD", PASSWORD)
private final GenericContainer<?> container = new GenericContainer<>("ghcr.io/fdcastel/firebird:5.0.1")
.withEnv("FIREBIRD_ROOT_PASSWORD", password)
.withEnv("FIREBIRD_USER", "alice")
.withEnv("FIREBIRD_PASSWORD", PASSWORD)
.withEnv("FIREBIRD_PASSWORD", password)
.withEnv("FIREBIRD_DATABASE", "mirror.fdb")
.withEnv("FIREBIRD_DATABASE_DEFAULT_CHARSET", "UTF8")
.withExposedPorts(3050);

private static DataSource logicDataSource;
private DataSource logicDataSource;

private String jdbcUrlPrefix;

private TestShardingService testShardingService;

@BeforeAll
static void beforeAll() {
assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url"), is(nullValue()));
assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url"), is(nullValue()));
assertThat(System.getProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url"), is(nullValue()));
@BeforeEach
void beforeEach() {
assertThat(System.getProperty(systemPropKeyPrefix + "ds0.jdbc-url"), is(nullValue()));
assertThat(System.getProperty(systemPropKeyPrefix + "ds1.jdbc-url"), is(nullValue()));
assertThat(System.getProperty(systemPropKeyPrefix + "ds2.jdbc-url"), is(nullValue()));
}

@AfterAll
static void afterAll() throws SQLException {
@AfterEach
void afterEach() throws SQLException {
try (Connection connection = logicDataSource.getConnection()) {
connection.unwrap(ShardingSphereConnection.class).getContextManager().close();
ContextManager contextManager = connection.unwrap(ShardingSphereConnection.class).getContextManager();
for (StorageUnit each : contextManager.getStorageUnits(DefaultDatabase.LOGIC_NAME).values()) {
each.getDataSource().unwrap(HikariDataSource.class).close();
}
contextManager.close();
}
System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url");
System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url");
System.clearProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url");
System.clearProperty(systemPropKeyPrefix + "ds0.jdbc-url");
System.clearProperty(systemPropKeyPrefix + "ds1.jdbc-url");
System.clearProperty(systemPropKeyPrefix + "ds2.jdbc-url");
}

@Test
void assertShardingInLocalTransactions() throws Exception {
jdbcUrlPrefix = "jdbc:firebird://localhost:" + CONTAINER.getMappedPort(3050) + "//var/lib/firebird/data/";
jdbcUrlPrefix = "jdbc:firebird://localhost:" + container.getMappedPort(3050) + "//var/lib/firebird/data/";
logicDataSource = createDataSource();
testShardingService = new TestShardingService(logicDataSource);
initEnvironment();
Expand All @@ -109,7 +116,7 @@ private void initEnvironment() throws SQLException {
private Connection openConnection() throws SQLException {
Properties props = new Properties();
props.setProperty("user", "alice");
props.setProperty("password", PASSWORD);
props.setProperty("password", password);
return DriverManager.getConnection(jdbcUrlPrefix + "mirror.fdb", props);
}

Expand All @@ -131,22 +138,22 @@ private DataSource createDataSource() throws Exception {
try (FBManager fbManager = new FBManager()) {
fbManager.setServer("localhost");
fbManager.setUserName("alice");
fbManager.setPassword(PASSWORD);
fbManager.setPassword(password);
fbManager.setFileName("/var/lib/firebird/data/mirror.fdb");
fbManager.setPageSize(PageSizeConstants.SIZE_16K);
fbManager.setDefaultCharacterSet("UTF8");
fbManager.setPort(CONTAINER.getMappedPort(3050));
fbManager.setPort(container.getMappedPort(3050));
fbManager.start();
fbManager.createDatabase("/var/lib/firebird/data/demo_ds_0.fdb", "alice", PASSWORD);
fbManager.createDatabase("/var/lib/firebird/data/demo_ds_1.fdb", "alice", PASSWORD);
fbManager.createDatabase("/var/lib/firebird/data/demo_ds_2.fdb", "alice", PASSWORD);
fbManager.createDatabase("/var/lib/firebird/data/demo_ds_0.fdb", "alice", password);
fbManager.createDatabase("/var/lib/firebird/data/demo_ds_1.fdb", "alice", password);
fbManager.createDatabase("/var/lib/firebird/data/demo_ds_2.fdb", "alice", password);
}
HikariConfig config = new HikariConfig();
config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver");
config.setJdbcUrl("jdbc:shardingsphere:classpath:test-native/yaml/jdbc/databases/firebird.yaml?placeholder-type=system_props");
System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds0.jdbc-url", jdbcUrlPrefix + "demo_ds_0.fdb");
System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds1.jdbc-url", jdbcUrlPrefix + "demo_ds_1.fdb");
System.setProperty(SYSTEM_PROP_KEY_PREFIX + "ds2.jdbc-url", jdbcUrlPrefix + "demo_ds_2.fdb");
System.setProperty(systemPropKeyPrefix + "ds0.jdbc-url", jdbcUrlPrefix + "demo_ds_0.fdb");
System.setProperty(systemPropKeyPrefix + "ds1.jdbc-url", jdbcUrlPrefix + "demo_ds_1.fdb");
System.setProperty(systemPropKeyPrefix + "ds2.jdbc-url", jdbcUrlPrefix + "demo_ds_2.fdb");
return new HikariDataSource(config);
}
}
Loading

0 comments on commit a1987ee

Please sign in to comment.