diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1079da3..8a2c014 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,9 @@ jobs: - name: 'oceanbase-client' language: 'java' with_oceanbase_container: true + - name: 'testcontainers-java' + language: 'java' + with_oceanbase_container: false - name: 'pymysql' language: 'python' with_oceanbase_container: true diff --git a/java/testcontainers-java/pom.xml b/java/testcontainers-java/pom.xml new file mode 100644 index 0000000..82e92fc --- /dev/null +++ b/java/testcontainers-java/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + com.oceanbase.samples + testcontainers-java + 1.0-SNAPSHOT + + ob-samples-testcontainers-java + + + UTF-8 + 1.8 + 1.8 + + + + + com.oceanbase + oceanbase-client + 2.4.9 + + + org.testcontainers + oceanbase + 1.19.7 + test + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.17.1 + test + + + + diff --git a/java/testcontainers-java/run.sh b/java/testcontainers-java/run.sh new file mode 100644 index 0000000..7b5ea53 --- /dev/null +++ b/java/testcontainers-java/run.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +mvn verify diff --git a/java/testcontainers-java/src/test/java/com/oceanbase/samples/OceanBaseCEContainerTest.java b/java/testcontainers-java/src/test/java/com/oceanbase/samples/OceanBaseCEContainerTest.java new file mode 100644 index 0000000..0ee616c --- /dev/null +++ b/java/testcontainers-java/src/test/java/com/oceanbase/samples/OceanBaseCEContainerTest.java @@ -0,0 +1,96 @@ +package com.oceanbase.samples; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.output.Slf4jLogConsumer; +import org.testcontainers.lifecycle.Startables; +import org.testcontainers.oceanbase.OceanBaseCEContainer; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.stream.Stream; + +public class OceanBaseCEContainerTest { + + private static final Logger LOG = LoggerFactory.getLogger(OceanBaseCEContainerTest.class); + + public static final OceanBaseCEContainer CONTAINER = + new OceanBaseCEContainer("oceanbase/oceanbase-ce:latest") + .withEnv("MODE", "slim") + .withEnv("FASTBOOT", "true") + .withLogConsumer(new Slf4jLogConsumer(LOG)); + + @BeforeClass + public static void startContainers() { + Startables.deepStart(Stream.of(CONTAINER)).join(); + LOG.info( + "OceanBase docker container started, image: {}, host: {}, sql port: {}, rpc port:{}.", + CONTAINER.getDockerImageName(), + CONTAINER.getHost(), + CONTAINER.getMappedPort(2881), + CONTAINER.getMappedPort(2882)); + } + + @AfterClass + public static void closeContainers() { + CONTAINER.close(); + LOG.info("OceanBase docker container stopped."); + } + + @Test + public void test() { + String database = "testcontainers"; + String table = "person"; + String tableName = String.format("`%s`.`%s`", database, table); + + LOG.info( + "Try to connect to OceanBase docker container with url: {}.", + CONTAINER.getJdbcUrl()); + try (Connection connection = CONTAINER.createConnection("?useSSL=false")) { + LOG.info("Connect to OceanBase docker container successfully."); + + LOG.info("Prepare database and table."); + try (Statement statement = connection.createStatement()) { + statement.execute("CREATE DATABASE IF NOT EXISTS " + database); + statement.execute("USE " + database); + statement.execute( + "CREATE TABLE IF NOT EXISTS " + table + " (name VARCHAR(50), age INT)"); + } catch (SQLException e) { + throw new RuntimeException(e); + } + + LOG.info("Insert data to table {}.", tableName); + try (PreparedStatement ps = + connection.prepareStatement("INSERT INTO " + tableName + " values(?, ?)")) { + ps.setString(1, "Adam"); + ps.setInt(2, 28); + ps.executeUpdate(); + ps.setString(1, "Eve"); + ps.setInt(2, 26); + ps.executeUpdate(); + } + + LOG.info("Query rows from {}.", tableName); + try (PreparedStatement ps = + connection.prepareStatement( + "SELECT * from " + tableName, + ResultSet.TYPE_FORWARD_ONLY, + ResultSet.CONCUR_READ_ONLY)) { + ResultSet rs = ps.executeQuery(); + int count = 0; + while (rs.next()) { + LOG.info("Row {}: name {}, age {}.", count++, rs.getString(1), rs.getInt(2)); + } + assert count == 2; + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/java/testcontainers-java/src/test/resources/log4j2-test.properties b/java/testcontainers-java/src/test/resources/log4j2-test.properties new file mode 100644 index 0000000..f43aa2a --- /dev/null +++ b/java/testcontainers-java/src/test/resources/log4j2-test.properties @@ -0,0 +1,8 @@ +rootLogger.level=INFO +rootLogger.appenderRef.test.ref = TestLogger + +appender.testlogger.name = TestLogger +appender.testlogger.type = CONSOLE +appender.testlogger.target = SYSTEM_ERR +appender.testlogger.layout.type = PatternLayout +appender.testlogger.layout.pattern = %-4r [%t] %-5p %c - %m%n