diff --git a/ci/accept-third-party-license.sh b/ci/accept-third-party-license.sh index f1650edf..7b895f3c 100755 --- a/ci/accept-third-party-license.sh +++ b/ci/accept-third-party-license.sh @@ -4,3 +4,8 @@ echo "mcr.microsoft.com/mssql/server:2019-CU16-ubuntu-20.04" echo "ibmcom/db2:11.5.7.0a" } > spring-data-jdbc/src/test/resources/container-license-acceptance.txt + +{ + echo "mcr.microsoft.com/mssql/server:2022-latest" + echo "ibmcom/db2:11.5.7.0a" +} > spring-data-r2dbc/src/test/resources/container-license-acceptance.txt diff --git a/spring-data-r2dbc/pom.xml b/spring-data-r2dbc/pom.xml index 130d4a19..48d57abb 100644 --- a/spring-data-r2dbc/pom.xml +++ b/spring-data-r2dbc/pom.xml @@ -29,6 +29,7 @@ 42.4.0 1.0.0.RC1 1.0.0.RC1 + 1.0.0.RC1 1.0.0 1.0.0.RELEASE 1.0.4 @@ -213,6 +214,13 @@ test + + io.r2dbc + r2dbc-mssql + ${r2dbc-mssql.version} + test + + com.oracle.database.r2dbc oracle-r2dbc @@ -253,6 +261,18 @@ + + org.testcontainers + mssqlserver + test + + + org.slf4j + jcl-over-slf4j + + + + org.testcontainers oracle-xe diff --git a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/repository/SqlServerR2dbcRepositoryIntegrationTests.java b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/repository/SqlServerR2dbcRepositoryIntegrationTests.java index a7146bcb..e4027466 100644 --- a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/repository/SqlServerR2dbcRepositoryIntegrationTests.java +++ b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/repository/SqlServerR2dbcRepositoryIntegrationTests.java @@ -21,7 +21,6 @@ import reactor.core.publisher.Mono; import javax.sql.DataSource; -import org.junit.Ignore; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; @@ -45,7 +44,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; */ @ExtendWith(SpringExtension.class) @ContextConfiguration -@Disabled("Requires 1.0 driver") public class SqlServerR2dbcRepositoryIntegrationTests extends AbstractR2dbcRepositoryIntegrationTests { @RegisterExtension public static final ExternalDatabase database = SqlServerTestSupport.database(); @@ -82,7 +80,7 @@ public class SqlServerR2dbcRepositoryIntegrationTests extends AbstractR2dbcRepos return SqlServerLegoSetRepository.class; } - @Ignore("SQL server locks a SELECT COUNT so we cannot proceed.") + @Disabled("SQL server locks a SELECT COUNT so we cannot proceed.") @Override public void shouldInsertItemsTransactional() {} diff --git a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/repository/SqlServerR2dbcRepositoryWithMixedCaseNamesIntegrationTests.java b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/repository/SqlServerR2dbcRepositoryWithMixedCaseNamesIntegrationTests.java index 7f3a3ca3..6503509e 100644 --- a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/repository/SqlServerR2dbcRepositoryWithMixedCaseNamesIntegrationTests.java +++ b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/repository/SqlServerR2dbcRepositoryWithMixedCaseNamesIntegrationTests.java @@ -21,7 +21,6 @@ import java.util.Optional; import javax.sql.DataSource; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; @@ -48,7 +47,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; */ @ExtendWith(SpringExtension.class) @ContextConfiguration -@Disabled("Requires 1.0 driver") public class SqlServerR2dbcRepositoryWithMixedCaseNamesIntegrationTests extends AbstractR2dbcRepositoryWithMixedCaseNamesIntegrationTests { diff --git a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/testing/PostgresTestSupport.java b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/testing/PostgresTestSupport.java index 7173dcd8..04698572 100644 --- a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/testing/PostgresTestSupport.java +++ b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/testing/PostgresTestSupport.java @@ -63,8 +63,10 @@ public class PostgresTestSupport { + ");"; public static final String DROP_TABLE_LEGOSET_WITH_MIXED_CASE_NAMES = "DROP TABLE \"LegoSet\""; + /** - * Returns a database either hosted locally at {@code postgres:@localhost:5432/postgres} or running inside Docker. + * Returns a database either hosted locally at {@code jdbc:postgres//localhost:5432/postgres} or running inside + * Docker. * * @return information about the database. Guaranteed to be not {@literal null}. */ diff --git a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/testing/SqlServerTestSupport.java b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/testing/SqlServerTestSupport.java index 7ff53969..3c6fc772 100644 --- a/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/testing/SqlServerTestSupport.java +++ b/spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/testing/SqlServerTestSupport.java @@ -17,10 +17,15 @@ package org.springframework.data.r2dbc.testing; import io.r2dbc.spi.ConnectionFactory; +import java.util.function.Supplier; +import java.util.stream.Stream; + import javax.sql.DataSource; import org.springframework.data.r2dbc.testing.ExternalDatabase.ProvidedDatabase; +import org.testcontainers.containers.MSSQLServerContainer; + import com.microsoft.sqlserver.jdbc.SQLServerDataSource; /** @@ -31,6 +36,9 @@ import com.microsoft.sqlserver.jdbc.SQLServerDataSource; * @author Jens Schauder */ public class SqlServerTestSupport { + + private static ExternalDatabase testContainerDatabase; + public static String CREATE_TABLE_LEGOSET = "CREATE TABLE legoset (\n" // + " id integer PRIMARY KEY,\n" // + " version integer NULL,\n" // @@ -59,14 +67,37 @@ public class SqlServerTestSupport { public static final String DROP_TABLE_LEGOSET_WITH_MIXED_CASE_NAMES = "DROP TABLE LegoSet"; /** - * Returns a locally provided database at {@code sqlserver:@localhost:1433/master}. + * Returns a database either hosted locally at {@code jdbc:sqlserver://localhost:1433;database=master;} or running + * inside Docker. */ public static ExternalDatabase database() { - return local(); + + if (Boolean.getBoolean("spring.data.r2dbc.test.preferLocalDatabase")) { + + return getFirstWorkingDatabase( // + SqlServerTestSupport::local, // + SqlServerTestSupport::testContainer // + ); + } else { + + return getFirstWorkingDatabase( // + SqlServerTestSupport::testContainer, // + SqlServerTestSupport::local // + ); + } + } + + @SafeVarargs + private static ExternalDatabase getFirstWorkingDatabase(Supplier... suppliers) { + + return Stream.of(suppliers).map(Supplier::get) // + .filter(ExternalDatabase::checkValidity) // + .findFirst() // + .orElse(ExternalDatabase.unavailable()); } /** - * Returns a locally provided database at {@code sqlserver:@localhost:1433/master}. + * Returns a locally provided database at {@code jdbc:sqlserver://localhost:1433;database=master}. */ private static ExternalDatabase local() { @@ -76,9 +107,41 @@ public class SqlServerTestSupport { .database("master") // .username("sa") // .password("A_Str0ng_Required_Password") // + .jdbcUrl("jdbc:sqlserver://localhost:1433;database=master;encrypt=false") .build(); } + /** + * Returns a database provided via Testcontainers. + */ + @SuppressWarnings("rawtypes") + private static ExternalDatabase testContainer() { + + if (testContainerDatabase == null) { + + try { + MSSQLServerContainer container = new MSSQLServerContainer("mcr.microsoft.com/mssql/server:2022-latest") { + @Override + public String getDatabaseName() { + return "master"; + } + }; + container.withReuse(true); + container.withUrlParam("encrypt", "false"); + container.start(); + + testContainerDatabase = ProvidedDatabase.builder(container).database(container.getDatabaseName()).build(); + + } catch (IllegalStateException ise) { + // docker not available. + testContainerDatabase = ExternalDatabase.unavailable(); + } + + } + + return testContainerDatabase; + } + /** * Creates a new {@link ConnectionFactory} configured from the {@link ExternalDatabase}. */