diff --git a/Jenkinsfile b/Jenkinsfile index 1eb84755a5..14afea42be 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -14,6 +14,22 @@ pipeline { stages { stage("Docker images") { parallel { + stage('Publish JDK 8 + MongoDB 5.0') { + when { + changeset "ci/openjdk8-mongodb-5.0/**" + } + agent { label 'data' } + options { timeout(time: 30, unit: 'MINUTES') } + + steps { + script { + def image = docker.build("springci/spring-data-openjdk8-with-mongodb-5.0.0", "ci/openjdk8-mongodb-5.0/") + docker.withRegistry('', 'hub.docker.com-springbuildmaster') { + image.push() + } + } + } + } stage('Publish JDK 8 + MongoDB 4.0') { when { changeset "ci/openjdk8-mongodb-4.0/**" @@ -98,7 +114,7 @@ pipeline { stage("Test other configurations") { when { allOf { - branch 'main' + branch 'issue/3696' not { triggeredBy 'UpstreamCause' } } } @@ -151,6 +167,30 @@ pipeline { } } + stage("test: mongodb 5.0 (jdk8)") { + agent { + label 'data' + } + options { timeout(time: 30, unit: 'MINUTES') } + environment { + ARTIFACTORY = credentials('02bd1690-b54f-4c9f-819d-a77cb7a9822c') + } + steps { + script { + docker.withRegistry('', 'hub.docker.com-springbuildmaster') { + docker.image('springci/spring-data-openjdk8-with-mongodb-5.0.0:latest').inside('-v $HOME:/tmp/jenkins-home') { + sh 'mkdir -p /tmp/mongodb/db /tmp/mongodb/log' + sh 'mongod --setParameter transactionLifetimeLimitSeconds=90 --setParameter maxTransactionLockRequestTimeoutMillis=10000 --dbpath /tmp/mongodb/db --replSet rs0 --fork --logpath /tmp/mongodb/log/mongod.log &' + sh 'sleep 10' + sh 'mongo --eval "rs.initiate({_id: \'rs0\', members:[{_id: 0, host: \'127.0.0.1:27017\'}]});"' + sh 'sleep 15' + sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -s settings.xml clean dependency:list test -Duser.name=jenkins -Dsort -U -B' + } + } + } + } + } + stage("test: baseline (jdk16)") { agent { label 'data' diff --git a/ci/openjdk8-mongodb-5.0/Dockerfile b/ci/openjdk8-mongodb-5.0/Dockerfile new file mode 100644 index 0000000000..658b615bbd --- /dev/null +++ b/ci/openjdk8-mongodb-5.0/Dockerfile @@ -0,0 +1,17 @@ +FROM adoptopenjdk/openjdk8:latest + +ENV TZ=Etc/UTC +ENV DEBIAN_FRONTEND=noninteractive + +RUN set -eux; \ + apt-get update && apt-get install -y apt-transport-https apt-utils gnupg2 wget ; \ + # MongoDB 5.0 release signing key + apt-key adv --keyserver hkps://keyserver.ubuntu.com:443 --recv B00A0BD1E2C63C11 ; \ + # Needed when MongoDB creates a 5.0 folder. + echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/5.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-5.0.list; \ + echo ${TZ} > /etc/timezone; + +RUN apt-get update; \ + apt-get install -y mongodb-org=5.0.0 mongodb-org-server=5.0.0 mongodb-org-shell=5.0.0 mongodb-org-mongos=5.0.0 mongodb-org-tools=5.0.0; \ + apt-get clean; \ + rm -rf /var/lib/apt/lists/*; diff --git a/pom.xml b/pom.xml index b688f3ee50..ec52e25d08 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 3.3.0-SNAPSHOT + 3.3.0-GH-3696-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml index 0033bd11d5..b9bf3d963a 100644 --- a/spring-data-mongodb-benchmarks/pom.xml +++ b/spring-data-mongodb-benchmarks/pom.xml @@ -7,7 +7,7 @@ org.springframework.data spring-data-mongodb-parent - 3.3.0-SNAPSHOT + 3.3.0-GH-3696-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index f62c8dc7f4..f7315a7771 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-mongodb-parent - 3.3.0-SNAPSHOT + 3.3.0-GH-3696-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index 1f157e75bc..f4490bf3fb 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -11,7 +11,7 @@ org.springframework.data spring-data-mongodb-parent - 3.3.0-SNAPSHOT + 3.3.0-GH-3696-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AbstractIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AbstractIntegrationTests.java index 701e2eb986..00a4e9d935 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AbstractIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AbstractIntegrationTests.java @@ -21,10 +21,9 @@ import java.util.Set; import org.bson.Document; -import org.junit.After; -import org.junit.Before; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.dao.DataAccessException; @@ -32,7 +31,7 @@ import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import com.mongodb.MongoException; import com.mongodb.client.MongoClient; @@ -41,7 +40,7 @@ /** * @author Oliver Gierke */ -@RunWith(SpringRunner.class) +@ExtendWith(SpringExtension.class) @ContextConfiguration public abstract class AbstractIntegrationTests { @@ -71,8 +70,8 @@ protected boolean autoIndexCreation() { @Autowired MongoOperations operations; - @Before - @After + @BeforeEach + @AfterEach public void cleanUp() { for (String collectionName : operations.getCollectionNames()) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialIndexTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialIndexTests.java index 449c78f225..10984e0a1c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialIndexTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/geo/GeoSpatialIndexTests.java @@ -21,8 +21,8 @@ import java.util.List; import java.util.Map; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.geo.Point; @@ -35,6 +35,7 @@ import org.springframework.data.mongodb.core.index.IndexInfo; import org.springframework.data.mongodb.core.index.IndexOperations; import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; import com.mongodb.MongoException; import com.mongodb.WriteConcern; @@ -52,7 +53,7 @@ public class GeoSpatialIndexTests extends AbstractIntegrationTests { @Autowired private MongoTemplate template; - @Before + @BeforeEach public void setUp() { template.setWriteConcern(WriteConcern.JOURNALED); @@ -82,6 +83,7 @@ public void test2dSphereIndex() { } @Test // DATAMONGO-778 + @EnableIfMongoServerVersion(isLessThan = "5.0") public void testHaystackIndex() { try { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java index 2c61b0fdbf..7c731a37c4 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/index/IndexingIntegrationTests.java @@ -155,7 +155,11 @@ public void evaluatesTimeoutSpelExpresssionWithBeanReference() { }); assertThat(indexInfo).isPresent(); - assertThat(indexInfo.get()).containsEntry("expireAfterSeconds", 11L); + assertThat(indexInfo.get()).hasEntrySatisfying("expireAfterSeconds", timeout -> { + + // MongoDB 5 returns int not long + assertThat(timeout).isIn(11, 11L); + }); } @Target({ ElementType.FIELD }) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainerTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainerTests.java index b973de0cf1..c47918c565 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainerTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/messaging/DefaultMessageListenerContainerTests.java @@ -38,13 +38,16 @@ import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.messaging.ChangeStreamRequest.ChangeStreamRequestOptions; import org.springframework.data.mongodb.core.messaging.SubscriptionRequest.RequestOptions; +import org.springframework.data.mongodb.test.util.Client; import org.springframework.data.mongodb.test.util.EnableIfMongoServerVersion; import org.springframework.data.mongodb.test.util.EnableIfReplicaSetAvailable; import org.springframework.data.mongodb.test.util.MongoServerCondition; import org.springframework.data.mongodb.test.util.MongoTemplateExtension; +import org.springframework.data.mongodb.test.util.MongoTestUtils; import org.springframework.data.mongodb.test.util.Template; import org.springframework.util.ErrorHandler; +import com.mongodb.client.MongoClient; import com.mongodb.client.MongoCollection; import com.mongodb.client.model.CreateCollectionOptions; import com.mongodb.client.model.changestream.ChangeStreamDocument; @@ -60,9 +63,12 @@ public class DefaultMessageListenerContainerTests { static final String DATABASE_NAME = "change-stream-events"; static final String COLLECTION_NAME = "collection-1"; static final String COLLECTION_2_NAME = "collection-2"; + static final String COLLECTION_3_NAME = "collection-3"; static final Duration TIMEOUT = Duration.ofSeconds(2); + @Client static MongoClient client; + @Template(database = DATABASE_NAME, initialEntitySet = Person.class) // static MongoTemplate template; @@ -74,10 +80,13 @@ public class DefaultMessageListenerContainerTests { private CollectingMessageListener messageListener; @BeforeEach - void beforeEach() { + void beforeEach() throws InterruptedException { + + MongoTestUtils.dropCollectionNow(DATABASE_NAME, COLLECTION_NAME, client); + MongoTestUtils.dropCollectionNow(DATABASE_NAME, COLLECTION_2_NAME, client); + MongoTestUtils.dropCollectionNow(DATABASE_NAME, COLLECTION_3_NAME, client); - template.dropCollection(COLLECTION_NAME); - template.dropCollection(COLLECTION_2_NAME); + Thread.sleep(100); messageListener = new CollectingMessageListener<>(); } @@ -281,7 +290,7 @@ public void abortsSubscriptionOnError() throws InterruptedException { @Test // DATAMONGO-1803 public void callsDefaultErrorHandlerOnError() throws InterruptedException { - dbFactory.getMongoDatabase().createCollection(COLLECTION_NAME, + dbFactory.getMongoDatabase().createCollection(COLLECTION_3_NAME, new CreateCollectionOptions().capped(true).maxDocuments(10000).sizeInBytes(10000)); collection.insertOne(new Document("_id", "id-1").append("value", "foo")); @@ -298,10 +307,7 @@ public void callsDefaultErrorHandlerOnError() throws InterruptedException { Document.class); SubscriptionUtils.awaitSubscription(subscription); - - template.dropCollection(COLLECTION_NAME); - - Thread.sleep(20); + dbFactory.getMongoDatabase().drop(); verify(errorHandler, atLeast(1)).handleError(any(DataAccessException.class)); } finally { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java index 5a41e8a68c..7e29d2a272 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/test/util/MongoTestUtils.java @@ -166,6 +166,23 @@ public static void dropCollectionNow(String dbName, String collectionName, .verifyComplete(); } + /** + * Create a {@link com.mongodb.client.MongoCollection} if it does not exist, or drop and recreate it if it does and + * verify operation result. + * + * @param dbName must not be {@literal null}. + * @param collectionName must not be {@literal null}. + * @param client must not be {@literal null}. + */ + public static void dropCollectionNow(String dbName, String collectionName, + com.mongodb.client.MongoClient client) { + + com.mongodb.client.MongoDatabase database = client.getDatabase(dbName) + .withWriteConcern(WriteConcern.MAJORITY).withReadPreference(ReadPreference.primary()); + + database.getCollection(collectionName).drop(); + } + /** * Remove all documents from the {@link MongoCollection} with given name in the according {@link MongoDatabase * database}.