/*
* Copyright (c) 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florent Guillaume
*/
package org.nuxeo.ecm.core.storage.mongodb;
import static org.junit.Assert.assertNotNull;
import static org.nuxeo.ecm.core.api.security.SecurityConstants.ADMINISTRATOR;
import java.net.UnknownHostException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.CoreInstance;
import org.nuxeo.ecm.core.api.CoreSession;
import org.nuxeo.ecm.core.api.NuxeoPrincipal;
import org.nuxeo.ecm.core.event.EventService;
import org.nuxeo.ecm.core.repository.RepositoryService;
import org.nuxeo.runtime.api.Framework;
import org.nuxeo.runtime.datasource.ConnectionHelper;
import org.nuxeo.runtime.test.NXRuntimeTestCase;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.MongoClient;
public class MongoDBRepositoryTestCase extends NXRuntimeTestCase {
private static final Log log = LogFactory.getLog(MongoDBRepositoryTestCase.class);
protected String repositoryName = "test";
protected MongoDBRepositoryDescriptor descriptor;
protected CoreSession session;
protected int initialOpenSessions;
protected int initialSingleConnections;
/**
* Query of NOT (something) matches docs where (something) did not match
* because the field was null. field.
*/
public boolean notMatchesNull() {
return true;
}
@Override
@Before
public void setUp() throws Exception {
initCheckLeaks();
super.setUp();
deployBundle("org.nuxeo.ecm.core.schema");
deployBundle("org.nuxeo.ecm.core.api");
deployBundle("org.nuxeo.ecm.core");
deployBundle("org.nuxeo.ecm.core.event");
deployBundle("org.nuxeo.ecm.core.storage");
deployBundle("org.nuxeo.ecm.core.storage.mongodb");
deployContrib("org.nuxeo.ecm.core.storage.mongodb.tests",
"OSGI-INF/test-repo-types.xml");
initRepository();
setUpTx();
openSession();
}
protected void setUpTx() throws Exception {
// to be subclassed
}
@Override
@After
public void tearDown() throws Exception {
if (session != null) {
session.save();
}
waitForAsyncCompletion();
closeSession();
closeRepository();
super.tearDown();
checkLeaks();
}
protected void initRepository() throws Exception {
descriptor = new MongoDBRepositoryDescriptor();
descriptor.name = repositoryName;
descriptor.server = null; // use defaults
MongoDBRepositoryService repositoryService = Framework.getLocalService(MongoDBRepositoryService.class);
repositoryService.addContribution(descriptor);
clearMongoDb();
}
protected void clearMongoDb() throws UnknownHostException {
MongoClient mongoClient = MongoDBRepository.newMongoClient(descriptor);
try {
DBCollection coll = MongoDBRepository.getCollection(descriptor,
mongoClient);
coll.dropIndexes();
coll.remove(new BasicDBObject());
coll = MongoDBRepository.getCountersCollection(descriptor,
mongoClient);
coll.dropIndexes();
coll.remove(new BasicDBObject());
} finally {
mongoClient.close();
}
}
protected void closeRepository() {
Framework.getService(RepositoryService.class).shutdown();
MongoDBRepositoryService repositoryService = Framework.getLocalService(MongoDBRepositoryService.class);
repositoryService.removeContribution(descriptor);
}
protected void initCheckLeaks() {
initialOpenSessions = CoreInstance.getInstance().getNumberOfSessions();
initialSingleConnections = ConnectionHelper.countConnectionReferences();
}
protected void checkLeaks() {
int finalOpenSessions = CoreInstance.getInstance().getNumberOfSessions();
int leakedOpenSessions = finalOpenSessions - initialOpenSessions;
if (leakedOpenSessions != 0) {
log.error(String.format(
"There are %s open session(s) at tear down; it seems "
+ "the test leaked %s session(s).",
Integer.valueOf(finalOpenSessions),
Integer.valueOf(leakedOpenSessions)));
for (CoreInstance.RegistrationInfo info : CoreInstance.getInstance().getRegistrationInfos()) {
log.warn("Leaking session", info);
}
}
int finalSingleConnections = ConnectionHelper.countConnectionReferences();
int leakedSingleConnections = finalSingleConnections
- initialSingleConnections;
if (leakedSingleConnections > 0) {
log.error(String.format(
"There are %s single datasource connection(s) open at tear down; "
+ "the test leaked %s connection(s).",
Integer.valueOf(finalSingleConnections),
Integer.valueOf(leakedSingleConnections)));
}
ConnectionHelper.clearConnectionReferences();
}
public void waitForAsyncCompletion() {
Framework.getLocalService(EventService.class).waitForAsyncCompletion();
}
public void waitForFulltextIndexing() {
waitForAsyncCompletion();
// DatabaseHelper.DATABASE.sleepForFulltext();
}
public void openSession() throws ClientException {
if (session != null) {
log.warn("Closing session for you");
closeSession();
}
session = openSessionAs(ADMINISTRATOR);
assertNotNull(session);
}
public CoreSession openSessionAs(String username) throws ClientException {
return CoreInstance.openCoreSession(repositoryName, username);
}
public CoreSession openSessionAs(NuxeoPrincipal principal)
throws ClientException {
return CoreInstance.openCoreSession(repositoryName, principal);
}
public void closeSession() {
closeSession(session);
session = null;
}
public void closeSession(CoreSession session) {
if (session != null) {
session.close();
}
}
}