Support MongoDB in unit tests. Added parameterized test, so ImportTest and AdapterTest work with both picketlink and mongo
This commit is contained in:
parent
4db738689f
commit
68ed19f15d
12 changed files with 255 additions and 64 deletions
5
pom.xml
5
pom.xml
|
@ -254,6 +254,11 @@
|
|||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>2.11.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<version>1.27</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
|
@ -152,6 +152,11 @@
|
|||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
|
|
@ -48,7 +48,7 @@ public class MongoDBImpl implements NoSQL {
|
|||
new ConcurrentHashMap<Class<? extends NoSQLObject>, ObjectInfo>();
|
||||
|
||||
|
||||
public MongoDBImpl(DB database, boolean removeAllObjectsAtStartup, Class<? extends NoSQLObject>[] managedDataTypes) {
|
||||
public MongoDBImpl(DB database, boolean dropDatabaseOnStartup, Class<? extends NoSQLObject>[] managedDataTypes) {
|
||||
this.database = database;
|
||||
|
||||
typeConverter = new TypeConverter();
|
||||
|
@ -70,20 +70,9 @@ public class MongoDBImpl implements NoSQL {
|
|||
typeConverter.addDBObjectConverter(new BasicDBObjectConverter(this, typeConverter, type));
|
||||
}
|
||||
|
||||
if (removeAllObjectsAtStartup) {
|
||||
for (Class<? extends NoSQLObject> type : managedDataTypes) {
|
||||
ObjectInfo objectInfo = getObjectInfo(type);
|
||||
String collectionName = objectInfo.getDbCollectionName();
|
||||
if (collectionName != null) {
|
||||
logger.debug("Dropping collection " + collectionName);
|
||||
|
||||
DBCollection dbCollection = this.database.getCollection(collectionName);
|
||||
dbCollection.drop();
|
||||
} else {
|
||||
logger.debug("Skip removing objects of type " + type + " as it doesn't have it's own collection");
|
||||
}
|
||||
}
|
||||
logger.info("All objects successfully removed from MongoDB");
|
||||
if (dropDatabaseOnStartup) {
|
||||
this.database.dropDatabase();
|
||||
logger.info("Database " + this.database.getName() + " dropped in MongoDB");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,14 +43,14 @@ public class MongoDBSessionFactory implements KeycloakSessionFactory {
|
|||
private final MongoClient mongoClient;
|
||||
private final NoSQL mongoDB;
|
||||
|
||||
public MongoDBSessionFactory(String host, int port, String dbName, boolean removeAllObjectsAtStartup) {
|
||||
logger.info(String.format("Going to use MongoDB database. host: %s, port: %d, databaseName: %s, removeAllObjectsAtStartup: %b", host, port, dbName, removeAllObjectsAtStartup));
|
||||
public MongoDBSessionFactory(String host, int port, String dbName, boolean dropDatabaseOnStartup) {
|
||||
logger.info(String.format("Going to use MongoDB database. host: %s, port: %d, databaseName: %s, removeAllObjectsAtStartup: %b", host, port, dbName, dropDatabaseOnStartup));
|
||||
try {
|
||||
// TODO: authentication support
|
||||
mongoClient = new MongoClient(host, port);
|
||||
|
||||
DB db = mongoClient.getDB(dbName);
|
||||
mongoDB = new MongoDBImpl(db, removeAllObjectsAtStartup, MANAGED_DATA_TYPES);
|
||||
mongoDB = new MongoDBImpl(db, dropDatabaseOnStartup, MANAGED_DATA_TYPES);
|
||||
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
|
|
@ -37,6 +37,16 @@ import java.util.Set;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class KeycloakApplication extends Application {
|
||||
|
||||
public static final String SESSION_FACTORY = "keycloak.sessionFactory";
|
||||
public static final String SESSION_FACTORY_PICKETLINK = "picketlink";
|
||||
public static final String SESSION_FACTORY_MONGO = "mongo";
|
||||
public static final String MONGO_HOST = "keycloak.mongodb.host";
|
||||
public static final String MONGO_PORT = "keycloak.mongodb.port";
|
||||
public static final String MONGO_DB_NAME = "keycloak.mongodb.databaseName";
|
||||
public static final String MONGO_DROP_DB_ON_STARTUP = "keycloak.mongodb.dropDatabaseOnStartup";
|
||||
|
||||
|
||||
protected Set<Object> singletons = new HashSet<Object>();
|
||||
protected Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
|
||||
|
@ -62,8 +72,8 @@ public class KeycloakApplication extends Application {
|
|||
}
|
||||
|
||||
public static KeycloakSessionFactory buildSessionFactory() {
|
||||
String sessionFactoryType = System.getProperty("keycloak.sessionFactory", "picketlink");
|
||||
if ("mongo".equals(sessionFactoryType)) {
|
||||
String sessionFactoryType = System.getProperty(SESSION_FACTORY, SESSION_FACTORY_PICKETLINK);
|
||||
if (SESSION_FACTORY_MONGO.equals(sessionFactoryType)) {
|
||||
return buildMongoDBSessionFactory();
|
||||
} else {
|
||||
return buildPicketlinkSessionFactory();
|
||||
|
@ -76,11 +86,11 @@ public class KeycloakApplication extends Application {
|
|||
}
|
||||
|
||||
private static KeycloakSessionFactory buildMongoDBSessionFactory() {
|
||||
String host = System.getProperty("keycloak.mongodb.host", "localhost");
|
||||
int port = Integer.parseInt(System.getProperty("keycloak.mongodb.port", "27017"));
|
||||
String dbName = System.getProperty("keycloak.mongodb.databaseName", "keycloak");
|
||||
boolean removeAllObjectsOnStartup = Boolean.parseBoolean(System.getProperty("keycloak.mongodb.removeAllObjectsOnStartup", "true"));
|
||||
return new MongoDBSessionFactory(host, port, dbName, removeAllObjectsOnStartup);
|
||||
String host = System.getProperty(MONGO_HOST, "localhost");
|
||||
int port = Integer.parseInt(System.getProperty(MONGO_PORT, "27017"));
|
||||
String dbName = System.getProperty(MONGO_DB_NAME, "keycloak");
|
||||
boolean dropDatabaseOnStartup = Boolean.parseBoolean(System.getProperty(MONGO_DROP_DB_ON_STARTUP, "true"));
|
||||
return new MongoDBSessionFactory(host, port, dbName, dropDatabaseOnStartup);
|
||||
}
|
||||
|
||||
public KeycloakSessionFactory getFactory() {
|
||||
|
|
|
@ -12,6 +12,8 @@ import org.keycloak.services.managers.OAuthClientManager;
|
|||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.models.UserModel.RequiredAction;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.keycloak.test.common.AbstractKeycloakTest;
|
||||
import org.keycloak.test.common.SessionFactoryTestContext;
|
||||
|
||||
|
||||
import java.util.HashSet;
|
||||
|
@ -24,30 +26,16 @@ import java.util.StringTokenizer;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class AdapterTest {
|
||||
private KeycloakSessionFactory factory;
|
||||
private KeycloakSession identitySession;
|
||||
private RealmManager adapter;
|
||||
public class AdapterTest extends AbstractKeycloakTest {
|
||||
private RealmModel realmModel;
|
||||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
factory = KeycloakApplication.buildSessionFactory();
|
||||
identitySession = factory.createSession();
|
||||
identitySession.getTransaction().begin();
|
||||
adapter = new RealmManager(identitySession);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws Exception {
|
||||
identitySession.getTransaction().commit();
|
||||
identitySession.close();
|
||||
factory.close();
|
||||
public AdapterTest(SessionFactoryTestContext testContext) {
|
||||
super(testContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void installTest() throws Exception {
|
||||
new InstallationManager().install(adapter);
|
||||
new InstallationManager().install(getRealmManager());
|
||||
|
||||
}
|
||||
|
||||
|
@ -63,7 +51,7 @@ public class AdapterTest {
|
|||
|
||||
@Test
|
||||
public void test1CreateRealm() throws Exception {
|
||||
realmModel = adapter.createRealm("JUGGLER");
|
||||
realmModel = getRealmManager().createRealm("JUGGLER");
|
||||
realmModel.setAccessCodeLifespan(100);
|
||||
realmModel.setAccessCodeLifespanUserAction(600);
|
||||
realmModel.setCookieLoginAllowed(true);
|
||||
|
@ -76,7 +64,7 @@ public class AdapterTest {
|
|||
realmModel.addDefaultRole("foo");
|
||||
|
||||
System.out.println(realmModel.getId());
|
||||
realmModel = adapter.getRealm(realmModel.getId());
|
||||
realmModel = getRealmManager().getRealm(realmModel.getId());
|
||||
Assert.assertNotNull(realmModel);
|
||||
Assert.assertEquals(realmModel.getAccessCodeLifespan(), 100);
|
||||
Assert.assertEquals(600, realmModel.getAccessCodeLifespanUserAction());
|
||||
|
|
|
@ -19,6 +19,8 @@ import org.keycloak.models.SocialLinkModel;
|
|||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.keycloak.services.resources.SaasService;
|
||||
import org.keycloak.test.common.AbstractKeycloakTest;
|
||||
import org.keycloak.test.common.SessionFactoryTestContext;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -28,29 +30,15 @@ import java.util.Set;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class ImportTest {
|
||||
private KeycloakSessionFactory factory;
|
||||
private KeycloakSession identitySession;
|
||||
private RealmManager manager;
|
||||
private RealmModel realmModel;
|
||||
public class ImportTest extends AbstractKeycloakTest {
|
||||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
factory = KeycloakApplication.buildSessionFactory();
|
||||
identitySession = factory.createSession();
|
||||
identitySession.getTransaction().begin();
|
||||
manager = new RealmManager(identitySession);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws Exception {
|
||||
identitySession.getTransaction().commit();
|
||||
identitySession.close();
|
||||
factory.close();
|
||||
public ImportTest(SessionFactoryTestContext testContext) {
|
||||
super(testContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void install() throws Exception {
|
||||
RealmManager manager = getRealmManager();
|
||||
RealmModel defaultRealm = manager.createRealm(RealmModel.DEFAULT_REALM, RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setName(RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setEnabled(true);
|
||||
|
@ -93,7 +81,7 @@ public class ImportTest {
|
|||
|
||||
List<ApplicationModel> resources = realm.getApplications();
|
||||
Assert.assertEquals(2, resources.size());
|
||||
List<RealmModel> realms = identitySession.getRealms(admin);
|
||||
List<RealmModel> realms = getIdentitySession().getRealms(admin);
|
||||
Assert.assertEquals(1, realms.size());
|
||||
|
||||
// Test scope relationship
|
||||
|
@ -129,6 +117,7 @@ public class ImportTest {
|
|||
|
||||
@Test
|
||||
public void install2() throws Exception {
|
||||
RealmManager manager = getRealmManager();
|
||||
RealmModel defaultRealm = manager.createRealm(RealmModel.DEFAULT_REALM, RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setName(RealmModel.DEFAULT_REALM);
|
||||
defaultRealm.setEnabled(true);
|
||||
|
|
|
@ -11,6 +11,11 @@ import org.keycloak.services.managers.AuthenticationManager;
|
|||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.RealmModel;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
import org.keycloak.test.common.AbstractKeycloakTest;
|
||||
import org.keycloak.test.common.SessionFactoryTestContext;
|
||||
|
||||
import javax.ws.rs.NotAuthorizedException;
|
||||
import javax.ws.rs.client.Entity;
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
package org.keycloak.test.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.services.models.KeycloakSession;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public abstract class AbstractKeycloakTest {
|
||||
|
||||
protected static final SessionFactoryTestContext[] TEST_CONTEXTS;
|
||||
|
||||
private final SessionFactoryTestContext testContext;
|
||||
private KeycloakSessionFactory factory;
|
||||
private KeycloakSession identitySession;
|
||||
private RealmManager realmManager;
|
||||
|
||||
// STATIC METHODS
|
||||
|
||||
static
|
||||
{
|
||||
// TODO: Disable MongoDB by default and enable it just for some specific maven profile (system property)?
|
||||
TEST_CONTEXTS = new SessionFactoryTestContext[] {
|
||||
new PicketlinkSessionFactoryTestContext(),
|
||||
new MongoDBSessionFactoryTestContext()
|
||||
};
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Iterable<Object[]> parameters() {
|
||||
List<Object[]> params = new ArrayList<Object[]>();
|
||||
|
||||
for (SessionFactoryTestContext testContext : TEST_CONTEXTS) {
|
||||
params.add(new Object[] {testContext});
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void baseBeforeClass() {
|
||||
for (SessionFactoryTestContext testContext : TEST_CONTEXTS) {
|
||||
testContext.beforeTestClass();
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void baseAfterClass() {
|
||||
for (SessionFactoryTestContext testContext : TEST_CONTEXTS) {
|
||||
testContext.afterTestClass();
|
||||
}
|
||||
}
|
||||
|
||||
// NON-STATIC METHODS
|
||||
|
||||
public AbstractKeycloakTest(SessionFactoryTestContext testContext) {
|
||||
this.testContext = testContext;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
testContext.initEnvironment();
|
||||
factory = KeycloakApplication.buildSessionFactory();
|
||||
identitySession = factory.createSession();
|
||||
identitySession.getTransaction().begin();
|
||||
realmManager = new RealmManager(identitySession);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws Exception {
|
||||
identitySession.getTransaction().commit();
|
||||
identitySession.close();
|
||||
factory.close();
|
||||
}
|
||||
|
||||
protected RealmManager getRealmManager() {
|
||||
return realmManager;
|
||||
}
|
||||
|
||||
protected KeycloakSession getIdentitySession() {
|
||||
return identitySession;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package org.keycloak.test.common;
|
||||
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.MongoClient;
|
||||
import de.flapdoodle.embed.mongo.MongodExecutable;
|
||||
import de.flapdoodle.embed.mongo.MongodProcess;
|
||||
import de.flapdoodle.embed.mongo.MongodStarter;
|
||||
import de.flapdoodle.embed.mongo.config.MongodConfig;
|
||||
import de.flapdoodle.embed.mongo.distribution.Version;
|
||||
import de.flapdoodle.embed.process.runtime.Network;
|
||||
import org.jboss.resteasy.logging.Logger;
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class MongoDBSessionFactoryTestContext implements SessionFactoryTestContext {
|
||||
|
||||
protected static final Logger logger = Logger.getLogger(MongoDBSessionFactoryTestContext.class);
|
||||
private static final int PORT = 27777;
|
||||
|
||||
private MongodExecutable mongodExe;
|
||||
private MongodProcess mongod;
|
||||
|
||||
@Override
|
||||
public void beforeTestClass() {
|
||||
logger.info("Bootstrapping MongoDB on localhost, port " + PORT);
|
||||
try {
|
||||
mongodExe = MongodStarter.getDefaultInstance().prepare(new MongodConfig(Version.V2_0_5, PORT, Network.localhostIsIPv6()));
|
||||
mongod = mongodExe.start();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
logger.info("MongoDB bootstrapped successfully");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTestClass() {
|
||||
if (mongodExe != null) {
|
||||
if (mongod != null) {
|
||||
mongod.stop();
|
||||
}
|
||||
mongodExe.stop();
|
||||
}
|
||||
logger.info("MongoDB stopped successfully");
|
||||
|
||||
// Null this, so other tests are not affected
|
||||
System.setProperty(KeycloakApplication.SESSION_FACTORY, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initEnvironment() {
|
||||
System.setProperty(KeycloakApplication.SESSION_FACTORY, KeycloakApplication.SESSION_FACTORY_MONGO);
|
||||
System.setProperty(KeycloakApplication.MONGO_HOST, "localhost");
|
||||
System.setProperty(KeycloakApplication.MONGO_PORT, String.valueOf(PORT));
|
||||
System.setProperty(KeycloakApplication.MONGO_DB_NAME, "keycloakTest");
|
||||
System.setProperty(KeycloakApplication.MONGO_DROP_DB_ON_STARTUP, "true");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.keycloak.test.common;
|
||||
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
import org.keycloak.services.resources.KeycloakApplication;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class PicketlinkSessionFactoryTestContext implements SessionFactoryTestContext {
|
||||
|
||||
@Override
|
||||
public void beforeTestClass() {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTestClass() {
|
||||
//To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initEnvironment() {
|
||||
System.setProperty(KeycloakApplication.SESSION_FACTORY, KeycloakApplication.SESSION_FACTORY_PICKETLINK);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.keycloak.test.common;
|
||||
|
||||
import org.keycloak.services.models.KeycloakSessionFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface SessionFactoryTestContext {
|
||||
|
||||
void beforeTestClass();
|
||||
|
||||
void afterTestClass();
|
||||
|
||||
/**
|
||||
* Init system properties (or other configuration) to ensure that KeycloakApplication.buildSessionFactory() will return correct
|
||||
* instance of KeycloakSessionFactory for our test
|
||||
*/
|
||||
void initEnvironment();
|
||||
}
|
Loading…
Reference in a new issue