DATAMONGO-1038 - Assert Mongo instances cleaned up properly after test runs.
Add JUnit rule and RunListener taking care of clean up task. Original pull request: #221.
This commit is contained in:
committed by
Oliver Gierke
parent
703f24ae1c
commit
92926befc9
@@ -2,7 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<artifactId>spring-data-mongodb</artifactId>
|
||||
|
||||
<name>Spring Data MongoDB - Core</name>
|
||||
@@ -21,7 +21,7 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<!-- Spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
@@ -77,7 +77,7 @@
|
||||
<version>1.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- CDI -->
|
||||
<dependency>
|
||||
<groupId>javax.enterprise</groupId>
|
||||
@@ -86,21 +86,21 @@
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.el</groupId>
|
||||
<artifactId>el-api</artifactId>
|
||||
<version>${cdi}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.openwebbeans.test</groupId>
|
||||
<artifactId>cditest-owb</artifactId>
|
||||
<version>${webbeans}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
@@ -115,7 +115,7 @@
|
||||
<version>${validation}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.objenesis</groupId>
|
||||
<artifactId>objenesis</artifactId>
|
||||
@@ -129,23 +129,23 @@
|
||||
<version>4.2.0.Final</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${jodatime}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jul-to-slf4j</artifactId>
|
||||
<version>${slf4j}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
@@ -189,9 +189,14 @@
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.config.file>src/test/resources/logging.properties</java.util.logging.config.file>
|
||||
</systemPropertyVariables>
|
||||
<properties>
|
||||
<property>
|
||||
<name>listener</name>
|
||||
<value>org.springframework.data.mongodb.test.util.CleanMongoDBJunitRunListener</value>
|
||||
</property>
|
||||
</properties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.test.util;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.rules.TestRule;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class CleanMongoDB implements TestRule {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CleanMongoDB.class);
|
||||
|
||||
public enum Types {
|
||||
DATABASE, COLLECTION, INDEX;
|
||||
}
|
||||
|
||||
private Set<String> preserveDatabases = new HashSet<String>() {
|
||||
|
||||
private static final long serialVersionUID = -8698807376808700046L;
|
||||
|
||||
{
|
||||
add("admin");
|
||||
add("local");
|
||||
}
|
||||
};
|
||||
|
||||
private Set<String> dbNames = new HashSet<String>();
|
||||
private Set<String> collectionNames = new HashSet<String>();
|
||||
private Set<Types> types = new HashSet<CleanMongoDB.Types>();
|
||||
private MongoClient client;
|
||||
|
||||
public CleanMongoDB() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public CleanMongoDB(String host, int port) throws UnknownHostException {
|
||||
this(new MongoClient(host, port));
|
||||
}
|
||||
|
||||
public CleanMongoDB(MongoClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public static CleanMongoDB everything() {
|
||||
|
||||
CleanMongoDB cleanMongoDB = new CleanMongoDB();
|
||||
cleanMongoDB.clean(Types.DATABASE);
|
||||
return cleanMongoDB;
|
||||
}
|
||||
|
||||
public static CleanMongoDB databases(String... dbNames) {
|
||||
|
||||
CleanMongoDB cleanMongoDB = new CleanMongoDB();
|
||||
cleanMongoDB.clean(Types.DATABASE);
|
||||
cleanMongoDB.collectionNames.addAll(Arrays.asList(dbNames));
|
||||
return cleanMongoDB;
|
||||
}
|
||||
|
||||
public static CleanMongoDB indexes() {
|
||||
|
||||
CleanMongoDB cleanMongoDB = new CleanMongoDB();
|
||||
cleanMongoDB.clean(Types.INDEX);
|
||||
return cleanMongoDB;
|
||||
}
|
||||
|
||||
public CleanMongoDB clean(Types... types) {
|
||||
|
||||
this.types.addAll(Arrays.asList(types));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Statement apply() {
|
||||
return apply(null, null);
|
||||
}
|
||||
|
||||
public Statement apply(Statement base, Description description) {
|
||||
return new MongoCleanStatement(base);
|
||||
}
|
||||
|
||||
private class MongoCleanStatement extends Statement {
|
||||
|
||||
private final Statement base;
|
||||
|
||||
public MongoCleanStatement(Statement base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluate() throws Throwable {
|
||||
|
||||
if (base != null) {
|
||||
base.evaluate();
|
||||
}
|
||||
|
||||
boolean isInternal = false;
|
||||
if (client == null) {
|
||||
client = new MongoClient();
|
||||
isInternal = true;
|
||||
}
|
||||
|
||||
Collection<String> dbNamesToUse = dbNames;
|
||||
if (dbNamesToUse.isEmpty()) {
|
||||
dbNamesToUse = client.getDatabaseNames();
|
||||
}
|
||||
|
||||
for (String dbName : dbNamesToUse) {
|
||||
|
||||
if (preserveDatabases.contains(dbName.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (types.contains(Types.DATABASE)) {
|
||||
client.dropDatabase(dbName);
|
||||
LOGGER.debug("Dropping DB '{}'. ", dbName);
|
||||
}
|
||||
|
||||
if (types.contains(Types.COLLECTION)) {
|
||||
|
||||
DB db = client.getDB(dbName);
|
||||
Collection<String> collectionsToUse = initCollectionNames(db);
|
||||
for (String collectionName : collectionsToUse) {
|
||||
if (db.collectionExists(collectionName)) {
|
||||
db.getCollectionFromString(collectionName).drop();
|
||||
LOGGER.debug("Dropping collection '{}' for DB '{}'. ", collectionName, dbName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (types.contains(Types.INDEX)) {
|
||||
|
||||
DB db = client.getDB(dbName);
|
||||
Collection<String> collectionsToUse = initCollectionNames(db);
|
||||
for (String collectionName : collectionsToUse) {
|
||||
if (db.collectionExists(collectionName)) {
|
||||
db.getCollectionFromString(collectionName).dropIndexes();
|
||||
LOGGER.debug("Dropping indexes in collection '{}' for DB '{}'. ", collectionName, dbName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isInternal) {
|
||||
client.close();
|
||||
client = null;
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<String> initCollectionNames(DB db) {
|
||||
|
||||
Collection<String> collectionsToUse = collectionNames;
|
||||
if (CollectionUtils.isEmpty(collectionsToUse)) {
|
||||
collectionsToUse = db.getCollectionNames();
|
||||
}
|
||||
return collectionsToUse;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.test.util;
|
||||
|
||||
import org.junit.runner.Result;
|
||||
import org.junit.runner.notification.RunListener;
|
||||
import org.springframework.data.mongodb.test.util.CleanMongoDB.Types;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class CleanMongoDBJunitRunListener extends RunListener {
|
||||
|
||||
@Override
|
||||
public void testRunFinished(Result result) throws Exception {
|
||||
super.testRunFinished(result);
|
||||
try {
|
||||
new CleanMongoDB().clean(Types.INDEX).apply().evaluate();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.test.util;
|
||||
|
||||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.data.mongodb.test.util.CleanMongoDB.Types;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CleanMongoDBTests {
|
||||
|
||||
private CleanMongoDB cleaner;
|
||||
private @Mock Statement baseStatementMock;
|
||||
private @Mock Description descriptionMock;
|
||||
private @Mock MongoClient mongoClientMock;
|
||||
private @Mock DB db1mock;
|
||||
private @Mock DB db2mock;
|
||||
private @Mock DBCollection collection1mock;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
when(mongoClientMock.getDatabaseNames()).thenReturn(Arrays.asList("admin", "db1", "db2"));
|
||||
when(mongoClientMock.getDB(eq("db1"))).thenReturn(db1mock);
|
||||
when(mongoClientMock.getDB(eq("db2"))).thenReturn(db2mock);
|
||||
when(db1mock.collectionExists(anyString())).thenReturn(true);
|
||||
when(db2mock.collectionExists(anyString())).thenReturn(true);
|
||||
when(db1mock.getCollectionNames()).thenReturn(Collections.singleton("collection-1"));
|
||||
when(db2mock.getCollectionNames()).thenReturn(Collections.<String> emptySet());
|
||||
when(db1mock.getCollectionFromString(eq("collection-1"))).thenReturn(collection1mock);
|
||||
|
||||
cleaner = new CleanMongoDB(mongoClientMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preservesSystemCollectionsCorrectly() throws Throwable {
|
||||
|
||||
cleaner.clean(Types.DATABASE);
|
||||
|
||||
cleaner.apply(baseStatementMock, descriptionMock).evaluate();
|
||||
|
||||
verify(mongoClientMock, times(1)).dropDatabase(eq("db1"));
|
||||
verify(mongoClientMock, times(1)).dropDatabase(eq("db2"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("admin"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removesCollectionsCorrectly() throws Throwable {
|
||||
|
||||
cleaner.clean(Types.COLLECTION);
|
||||
|
||||
cleaner.apply(baseStatementMock, descriptionMock).evaluate();
|
||||
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("db1"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("db2"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("admin"));
|
||||
|
||||
verify(collection1mock, times(1)).drop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removesIndexesCorrectly() throws Throwable {
|
||||
|
||||
cleaner.clean(Types.INDEX);
|
||||
|
||||
cleaner.apply(baseStatementMock, descriptionMock).evaluate();
|
||||
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("db1"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("db2"));
|
||||
verify(mongoClientMock, never()).dropDatabase(eq("admin"));
|
||||
|
||||
verify(collection1mock, times(1)).dropIndexes();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user