You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2021/04/11 20:42:13 UTC

[directory-studio] branch DIRSTUDIO-1274-rework-integration-tests created (now e4f48e7)

This is an automated email from the ASF dual-hosted git repository.

seelmann pushed a change to branch DIRSTUDIO-1274-rework-integration-tests
in repository https://gitbox.apache.org/repos/asf/directory-studio.git.


      at e4f48e7  DIRSTUDIO-1274: Rework integation tests

This branch includes the following new commits:

     new e4f48e7  DIRSTUDIO-1274: Rework integation tests

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[directory-studio] 01/01: DIRSTUDIO-1274: Rework integation tests

Posted by se...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

seelmann pushed a commit to branch DIRSTUDIO-1274-rework-integration-tests
in repository https://gitbox.apache.org/repos/asf/directory-studio.git

commit e4f48e7fc8014f01cc44e3db92a490e207f76ec3
Author: Stefan Seelmann <ma...@stefan-seelmann.de>
AuthorDate: Sun Apr 11 22:36:19 2021 +0200

    DIRSTUDIO-1274: Rework integation tests
    
    * Setup framework which uses JUnit parametrized tests to tests against multiiple LDAP servers
    * Migration integration-core tests to JUnit 5
    * Update Tycho version and fix certificate generation
---
 README.md                                          |   5 +-
 ...directory.studio.eclipse-trgt-platform.template |   3 +-
 pom.xml                                            |   2 +-
 tests/test.integration.core/pom-first.xml          |  17 +-
 .../test/integration/core/ComputeDiffTest.java     |  20 +-
 .../core/DirectoryApiConnectionWrapperTest.java    | 630 ++++++++++++---------
 .../studio/test/integration/core/SchemaTest.java   |  12 +-
 .../integration/junit5/ApacheDirectoryServer.java  |  95 ++++
 .../integration/{core => junit5}/Constants.java    |   2 +-
 .../integration/junit5/Fedora389dsLdapServer.java  |  53 ++
 .../Constants.java => junit5/LdapServerType.java}  |  25 +-
 .../junit5/LdapServersArgumentsProvider.java       |  60 ++
 .../LdapServersSource.java}                        |  21 +-
 .../test/integration/junit5/OpenLdapServer.java    |  82 +++
 ...pTestIfLdapServerIsNotAvailableInterceptor.java |  53 ++
 .../test/integration/junit5/TestFixture.java       | 198 +++++++
 .../test/integration/junit5/TestLdapServer.java    | 172 ++++++
 .../test/integration/junit5/OpenLdapConfig.ldif    |  25 +
 .../test/integration/junit5/TestFixture.ldif       | 250 ++++++++
 tests/test.integration.ui/pom-first.xml            |  13 +-
 .../test/integration/ui/Fedora389dsTest.java       |   2 +
 .../studio/test/integration/ui/OpenLdapTest.java   |   2 +
 .../test/integration/ui/PreferencesTest.java       |  23 +-
 .../integration/ui/bots/ConnectionsViewBot.java    |  10 +
 .../studio/test/integration/ui/bots/StudioBot.java |   7 +-
 25 files changed, 1446 insertions(+), 336 deletions(-)

diff --git a/README.md b/README.md
index 23a1aef..15f8b0f 100644
--- a/README.md
+++ b/README.md
@@ -62,10 +62,11 @@ or on Windows :
     export DISPLAY=:99
     Xvfb :99 -screen 0 1024x768x16 &
 
-* Some UI integration tests expect a running OpenLDAP server and are skipped otherwise:
+* The core and UI integration tests run against ApacheDS, OpenLDAP, and 389ds. The ApacheDS is always started in embedded mode. The others are expected to run, e.g. with the following commands, otherwise those tests are skipped. 
 
     docker run -it --rm -p 20389:389 -p 20636:636 --name openldap osixia/openldap:1.3.0
-
+    docker run -it --rm -p 21389:3389 -p 21636:3636  --name fedora389ds -e DS_DM_PASSWORD=admin 389ds/dirsrv bash -c "set -m; /usr/lib/dirsrv/dscontainer -r & while ! /usr/lib/dirsrv/dscontainer -H; do sleep 5; done; sleep 5; /usr/sbin/dsconf localhost backend create --suffix dc=example,dc=org --be-name example; fg"
+	
 ### Build issues
 
 Tycho doesn't handle snapshot dependencies well. The first time a snapshot dependency is used within the build it is cached in `~/.m2/repository/p2`. Afterwards any change in the dependency (e.g. ApacheDS or LDAP API) is not considered unless it is deleted from the cache.
diff --git a/eclipse-trgt-platform/template/org.apache.directory.studio.eclipse-trgt-platform.template b/eclipse-trgt-platform/template/org.apache.directory.studio.eclipse-trgt-platform.template
index 457ecd5..5fdc2f5 100644
--- a/eclipse-trgt-platform/template/org.apache.directory.studio.eclipse-trgt-platform.template
+++ b/eclipse-trgt-platform/template/org.apache.directory.studio.eclipse-trgt-platform.template
@@ -19,7 +19,7 @@
   @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 -->
 <?pde version="3.8"?>
-<target name="Apache Directory Studio Platform" sequenceNumber="463">
+<target name="Apache Directory Studio Platform" sequenceNumber="465">
   <locations>
 
     <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
@@ -131,6 +131,7 @@
 
     <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
       <unit id="org.eclipse.swtbot.eclipse.feature.group" version="3.0.0.202006031738"/>
+      <unit id="org.eclipse.swtbot.junit5.feature.group" version="3.0.0.202006031738"/>
       <unit id="org.hamcrest.core" version="1.3.0.v20180420-1519"/>
       <unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
       <unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
diff --git a/pom.xml b/pom.xml
index 4bbda5d..66c6422 100644
--- a/pom.xml
+++ b/pom.xml
@@ -69,7 +69,7 @@
     <maven.compiler.source>1.8</maven.compiler.source>
     <maven.compiler.target>1.8</maven.compiler.target>
 
-    <tycho.version>1.7.0</tycho.version>
+    <tycho.version>2.3.0</tycho.version>
 
     <!-- Set versions for dependencies -->
     <antlr.version>2.7.7</antlr.version>
diff --git a/tests/test.integration.core/pom-first.xml b/tests/test.integration.core/pom-first.xml
index 9a1a9ad..d9ab520 100644
--- a/tests/test.integration.core/pom-first.xml
+++ b/tests/test.integration.core/pom-first.xml
@@ -47,23 +47,36 @@
             <Eclipse-LazyStart>true</Eclipse-LazyStart>
             <Bundle-Activator>org.apache.directory.studio.test.integration.core.Activator</Bundle-Activator>
             
+            <Export-Package>org.apache.directory.studio.test.integration.junit5</Export-Package>
+            
             <Require-Bundle>org.junit;bundle-version="4.11.0",
  org.hamcrest.library;bundle-version="1.3.0",
+ org.junit.jupiter.api;bundle-version="5.7.0",
+ org.junit.jupiter.params;bundle-version="5.7.0",
+ org.opentest4j;bundle-version="1.2.0",
+
  org.apache.directory.server.apacheds-test-framework;bundle-version="${org.apache.directory.server.version}",
  org.apache.directory.server.annotations;bundle-version="${org.apache.directory.server.version}",
- org.apache.directory.server.xdbm.partition;bundle-version="${org.apache.directory.server.version}",
- org.apache.directory.server.jdbm.partition;bundle-version="${org.apache.directory.server.version}",
  org.apache.directory.server.core.annotations;bundle-version="${org.apache.directory.server.version}",
  org.apache.directory.server.core.api;bundle-version="${org.apache.directory.server.version}",
+ org.apache.directory.server.core;bundle-version="${org.apache.directory.server.version}",
  org.apache.directory.server.protocol.ldap;bundle-version="${org.apache.directory.server.version}",
+ org.apache.directory.server.protocol.shared;bundle-version="${org.apache.directory.server.version}",
+ org.apache.directory.server.jdbm.partition;bundle-version="${org.apache.directory.server.version}",
+ org.apache.directory.server.xdbm.partition;bundle-version="${org.apache.directory.server.version}",
+
  org.apache.directory.api.asn1.api;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.api.ldap.client.api;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.api.ldap.codec.core;bundle-version="${org.apache.directory.api.bundleversion}",
+ org.apache.directory.api.ldap.extras.codec;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.api.ldap.extras.codec.api;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.api.ldap.model;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.api.ldap.net.mina;bundle-version="${org.apache.directory.api.bundleversion}",
+ org.apache.directory.api.ldap.schema;bundle-version="${org.apache.directory.api.bundleversion}",
+ org.apache.directory.api.ldap.schema.converter;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.directory.api.util;bundle-version="${org.apache.directory.api.bundleversion}",
  org.apache.mina.core;bundle-version="${org.apache.mina.bundleversion}",
+
  org.apache.directory.studio.connection.core,
  org.apache.directory.studio.common.core,
  org.apache.directory.studio.ldapbrowser.core,
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/ComputeDiffTest.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/ComputeDiffTest.java
index 1f7cc8e..755a730 100644
--- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/ComputeDiffTest.java
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/ComputeDiffTest.java
@@ -25,7 +25,7 @@ import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.instanceOf;
-import static org.junit.Assert.assertNull;
+import static org.hamcrest.Matchers.nullValue;
 
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.studio.connection.core.event.ConnectionEventRegistry;
@@ -41,8 +41,8 @@ import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
 import org.apache.directory.studio.ldifparser.LdifParserConstants;
 import org.apache.directory.studio.ldifparser.model.LdifFile;
 import org.apache.directory.studio.ldifparser.model.container.LdifChangeModifyRecord;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 
 public class ComputeDiffTest
@@ -90,7 +90,7 @@ public class ComputeDiffTest
 
     }
 
-    @Before
+    @BeforeEach
     public void setup() throws Exception
     {
         ConnectionEventRegistry.suspendEventFiringInCurrentThread();
@@ -104,18 +104,18 @@ public class ComputeDiffTest
     public void shouldReturnNullForEqualEntries()
     {
         // entries without attribute
-        assertNull( Utils.computeDiff( oldEntry, newEntry ) );
-        assertNull( Utils.computeDiff( oldEntry, oldEntry ) );
-        assertNull( Utils.computeDiff( newEntry, newEntry ) );
+        assertThat( Utils.computeDiff( oldEntry, newEntry ), nullValue() );
+        assertThat( Utils.computeDiff( oldEntry, oldEntry ), nullValue() );
+        assertThat( Utils.computeDiff( newEntry, newEntry ), nullValue() );
 
         // entries with attributes
         addAttribute( oldEntry, "cn", "1" );
         addAttribute( oldEntry, "member", "cn=1", "cn=2", "cn=3" );
         addAttribute( newEntry, "cn", "1" );
         addAttribute( newEntry, "member", "cn=1", "cn=2", "cn=3" );
-        assertNull( Utils.computeDiff( oldEntry, newEntry ) );
-        assertNull( Utils.computeDiff( oldEntry, oldEntry ) );
-        assertNull( Utils.computeDiff( newEntry, newEntry ) );
+        assertThat( Utils.computeDiff( oldEntry, newEntry ), nullValue() );
+        assertThat( Utils.computeDiff( oldEntry, oldEntry ), nullValue() );
+        assertThat( Utils.computeDiff( newEntry, newEntry ), nullValue() );
     }
 
 
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java
index 25209d9..5a9ee4a 100644
--- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/DirectoryApiConnectionWrapperTest.java
@@ -21,18 +21,21 @@
 package org.apache.directory.studio.test.integration.core;
 
 
-import static org.apache.directory.studio.test.integration.core.Constants.LOCALHOST;
+import static org.apache.directory.studio.test.integration.junit5.Constants.LOCALHOST;
+import static org.apache.directory.studio.test.integration.junit5.TestFixture.CONTEXT_DN;
+import static org.apache.directory.studio.test.integration.junit5.TestFixture.REFERRALS_OU_DN;
+import static org.apache.directory.studio.test.integration.junit5.TestFixture.USERS_OU_DN;
 import static org.hamcrest.CoreMatchers.hasItems;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 import java.net.ConnectException;
 import java.nio.channels.UnresolvedAddressException;
-import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -69,24 +72,15 @@ import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.util.Strings;
 import org.apache.directory.ldap.client.api.exception.InvalidConnectionException;
-import org.apache.directory.server.annotations.CreateLdapServer;
-import org.apache.directory.server.annotations.CreateTransport;
-import org.apache.directory.server.core.annotations.ApplyLdifFiles;
-import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
-import org.apache.directory.server.core.integ.FrameworkRunner;
-//import org.apache.directory.server.ldap.handlers.extended.EndTransactionHandler;
-import org.apache.directory.server.ldap.handlers.extended.PwdModifyHandler;
-//import org.apache.directory.server.ldap.handlers.extended.StartTransactionHandler;
-import org.apache.directory.server.ldap.handlers.extended.WhoAmIHandler;
 import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
 import org.apache.directory.studio.connection.core.Connection;
-import org.apache.directory.studio.connection.core.ConnectionCorePlugin;
 import org.apache.directory.studio.connection.core.Connection.AliasDereferencingMethod;
 import org.apache.directory.studio.connection.core.Connection.ReferralHandlingMethod;
+import org.apache.directory.studio.connection.core.ConnectionCorePlugin;
 import org.apache.directory.studio.connection.core.ConnectionParameter;
-import org.apache.directory.studio.connection.core.IReferralHandler;
 import org.apache.directory.studio.connection.core.ConnectionParameter.AuthenticationMethod;
 import org.apache.directory.studio.connection.core.ConnectionParameter.EncryptionMethod;
+import org.apache.directory.studio.connection.core.IReferralHandler;
 import org.apache.directory.studio.connection.core.event.ConnectionEventRegistry;
 import org.apache.directory.studio.connection.core.io.ConnectionWrapper;
 import org.apache.directory.studio.connection.core.io.StudioLdapException;
@@ -95,13 +89,18 @@ import org.apache.directory.studio.connection.core.io.api.StudioSearchResult;
 import org.apache.directory.studio.connection.core.io.api.StudioSearchResultEnumeration;
 import org.apache.directory.studio.ldapbrowser.core.jobs.InitializeRootDSERunnable;
 import org.apache.directory.studio.ldapbrowser.core.model.impl.BrowserConnection;
+import org.apache.directory.studio.test.integration.junit5.LdapServerType;
+import org.apache.directory.studio.test.integration.junit5.LdapServersSource;
+import org.apache.directory.studio.test.integration.junit5.SkipTestIfLdapServerIsNotAvailableInterceptor;
+import org.apache.directory.studio.test.integration.junit5.TestLdapServer;
 import org.apache.mina.util.AvailablePortFinder;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
 
 
 /**
@@ -110,67 +109,27 @@ import org.junit.runner.RunWith;
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
-@RunWith(FrameworkRunner.class)
-@CreateLdapServer(transports =
-    { @CreateTransport(protocol = "LDAP"), @CreateTransport(protocol = "LDAPS") }, extendedOpHandlers =
-    { PwdModifyHandler.class, WhoAmIHandler.class })
-@ApplyLdifFiles(clazz = DirectoryApiConnectionWrapperTest.class, value = "org/apache/directory/studio/test/integration/core/TestData.ldif")
-public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
+@ExtendWith(SkipTestIfLdapServerIsNotAvailableInterceptor.class)
+public class DirectoryApiConnectionWrapperTest
 {
 
     protected ConnectionWrapper connectionWrapper;
 
-    @Before
-    public void setUp() throws Exception
+    @BeforeAll
+    public static void suspendEventFiringInCurrentThread()
+    {
+        ConnectionEventRegistry.suspendEventFiringInCurrentThread();
+    }
+
+
+    @AfterAll
+    public static void resumeEventFiringInCurrentThread()
     {
-        // create referral entries
-        Entry referralsOu = new DefaultEntry( getService().getSchemaManager() );
-        referralsOu.setDn( new Dn( "ou=referrals,ou=system" ) );
-        referralsOu.add( "objectClass", "top", "organizationalUnit" );
-        referralsOu.add( "ou", "referrals" );
-        service.getAdminSession().add( referralsOu );
-
-        // direct referral
-        Entry r1 = new DefaultEntry( getService().getSchemaManager() );
-        r1.setDn( new Dn( "cn=referral1,ou=referrals,ou=system" ) );
-        r1.add( "objectClass", "top", "referral", "extensibleObject" );
-        r1.add( "cn", "referral1" );
-        r1.add( "ref", "ldap://" + LOCALHOST + ":" + ldapServer.getPort() + "/ou=users,ou=system" );
-        service.getAdminSession().add( r1 );
-
-        // referral via another immediate referral
-        Entry r2 = new DefaultEntry( getService().getSchemaManager() );
-        r2.setDn( new Dn( "cn=referral2,ou=referrals,ou=system" ) );
-        r2.add( "objectClass", "top", "referral", "extensibleObject" );
-        r2.add( "cn", "referral2" );
-        r2.add( "ref", "ldap://" + LOCALHOST + ":" + ldapServer.getPort() + "/cn=referral1,ou=referrals,ou=system" );
-        service.getAdminSession().add( r2 );
-
-        // referral to parent which contains this referral
-        Entry r3 = new DefaultEntry( getService().getSchemaManager() );
-        r3.setDn( new Dn( "cn=referral3,ou=referrals,ou=system" ) );
-        r3.add( "objectClass", "top", "referral", "extensibleObject" );
-        r3.add( "cn", "referral3" );
-        r3.add( "ref", "ldap://" + LOCALHOST + ":" + ldapServer.getPort() + "/ou=referrals,ou=system" );
-        service.getAdminSession().add( r3 );
-
-        // referrals pointing to each other (loop)
-        Entry r4a = new DefaultEntry( getService().getSchemaManager() );
-        r4a.setDn( new Dn( "cn=referral4a,ou=referrals,ou=system" ) );
-        r4a.add( "objectClass", "top", "referral", "extensibleObject" );
-        r4a.add( "cn", "referral4a" );
-        r4a.add( "ref", "ldap://" + LOCALHOST + ":" + ldapServer.getPort() + "/cn=referral4b,ou=referrals,ou=system" );
-        service.getAdminSession().add( r4a );
-        Entry r4b = new DefaultEntry( getService().getSchemaManager() );
-        r4b.setDn( new Dn( "cn=referral4b,ou=referrals,ou=system" ) );
-        r4b.add( "objectClass", "top", "referral", "extensibleObject" );
-        r4b.add( "cn", "referral4b" );
-        r4b.add( "ref", "ldap://" + LOCALHOST + ":" + ldapServer.getPort() + "/cn=referral4a,ou=referrals,ou=system" );
-        service.getAdminSession().add( r4b );
+        ConnectionEventRegistry.resumeEventFiringInCurrentThread();
     }
 
 
-    @After
+    @AfterEach
     public void tearDown() throws Exception
     {
         if ( connectionWrapper != null )
@@ -183,8 +142,9 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     /**
      * Tests connecting to the server.
      */
-    @Test
-    public void testConnect()
+    @ParameterizedTest
+    @LdapServersSource
+    public void testConnect( TestLdapServer ldapServer )
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         ConnectionParameter connectionParameter = new ConnectionParameter( null, LOCALHOST, ldapServer.getPort(),
@@ -208,8 +168,9 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     /**
      * Test failed connections to the server.
      */
-    @Test
-    public void testConnectFailures()
+    @ParameterizedTest
+    @LdapServersSource
+    public void testConnectFailures( TestLdapServer ldapServer )
     {
         StudioProgressMonitor monitor = null;
         ConnectionParameter connectionParameter = null;
@@ -253,13 +214,14 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     /**
      * Test binding to the server.
      */
-    @Test
-    public void testBind()
+    @ParameterizedTest
+    @LdapServersSource
+    public void testBind( TestLdapServer ldapServer )
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         ConnectionParameter connectionParameter = new ConnectionParameter( null, LOCALHOST, ldapServer.getPort(),
-            EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, "uid=admin,ou=system", "secret", null, true,
-            null, 30000L );
+            EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, ldapServer.getAdminDn(), ldapServer.getAdminPassword(),
+            null, true, null, 30000L );
         Connection connection = new Connection( connectionParameter );
         ConnectionWrapper connectionWrapper = connection.getConnectionWrapper();
 
@@ -279,18 +241,19 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     /**
      * Test failed binds to the server.
      */
-    @Test
-    public void testBindFailures()
+    @ParameterizedTest
+    @LdapServersSource
+    public void testBindFailures( TestLdapServer ldapServer )
     {
         StudioProgressMonitor monitor = null;
         ConnectionParameter connectionParameter = null;
         Connection connection = null;
         ConnectionWrapper connectionWrapper = null;
 
-        // simple auth without principal and credential
+        // simple auth with invalid user
         monitor = getProgressMonitor();
         connectionParameter = new ConnectionParameter( null, LOCALHOST, ldapServer.getPort(), EncryptionMethod.NONE,
-            AuthenticationMethod.SIMPLE, "uid=admin", "invalid", null, true, null, 30000L );
+            AuthenticationMethod.SIMPLE, "cn=invalid," + USERS_OU_DN, "invalid", null, true, null, 30000L );
         connection = new Connection( connectionParameter );
         connectionWrapper = connection.getConnectionWrapper();
         connectionWrapper.connect( monitor );
@@ -299,14 +262,17 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertNotNull( monitor.getException() );
         assertTrue( monitor.getException() instanceof StudioLdapException );
         assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 49 - invalidCredentials]" ) );
-        assertTrue( monitor.getException().getMessage().contains( "INVALID_CREDENTIALS" ) );
         assertTrue( monitor.getException().getCause() instanceof LdapAuthenticationException );
-        assertTrue( monitor.getException().getCause().getMessage().contains( "INVALID_CREDENTIALS" ) );
+        if ( ldapServer.getType() == LdapServerType.ApacheDS )
+        {
+            assertTrue( monitor.getException().getMessage().contains( "INVALID_CREDENTIALS" ) );
+            assertTrue( monitor.getException().getCause().getMessage().contains( "INVALID_CREDENTIALS" ) );
+        }
 
-        // simple auth with invalid principal and credential
+        // simple auth with invalid password
         monitor = getProgressMonitor();
         connectionParameter = new ConnectionParameter( null, LOCALHOST, ldapServer.getPort(), EncryptionMethod.NONE,
-            AuthenticationMethod.SIMPLE, "uid=admin,ou=system", "bar", null, true, null, 30000L );
+            AuthenticationMethod.SIMPLE, ldapServer.getAdminDn(), "invalid", null, true, null, 30000L );
         connection = new Connection( connectionParameter );
         connectionWrapper = connection.getConnectionWrapper();
         connectionWrapper.connect( monitor );
@@ -315,22 +281,27 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertNotNull( monitor.getException() );
         assertTrue( monitor.getException() instanceof StudioLdapException );
         assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 49 - invalidCredentials]" ) );
-        assertTrue( monitor.getException().getMessage().contains( "INVALID_CREDENTIALS" ) );
         assertTrue( monitor.getException().getCause() instanceof LdapAuthenticationException );
-        assertTrue( monitor.getException().getCause().getMessage().contains( "INVALID_CREDENTIALS" ) );
+        if ( ldapServer.getType() == LdapServerType.ApacheDS )
+        {
+            assertTrue( monitor.getException().getMessage().contains( "INVALID_CREDENTIALS" ) );
+            assertTrue( monitor.getException().getCause().getMessage().contains( "INVALID_CREDENTIALS" ) );
+        }
     }
 
 
     /**
      * Test searching.
      */
-    @Test
-    public void testSearch() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testSearch( TestLdapServer ldapServer ) throws Exception
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         SearchControls searchControls = new SearchControls();
-        StudioSearchResultEnumeration result = getConnectionWrapper( monitor ).search( "ou=system", "(objectClass=*)",
-            searchControls, AliasDereferencingMethod.NEVER, ReferralHandlingMethod.IGNORE, null, monitor, null );
+        StudioSearchResultEnumeration result = getConnectionWrapper( monitor, ldapServer ).search( CONTEXT_DN,
+            "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER, ReferralHandlingMethod.IGNORE, null,
+            monitor, null );
 
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
@@ -343,15 +314,16 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     /**
      * Test binary attributes.
      */
-    @Test
-    public void testSearchBinaryAttributes() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testSearchBinaryAttributes( TestLdapServer ldapServer ) throws Exception
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         SearchControls searchControls = new SearchControls();
         searchControls.setSearchScope( SearchControls.OBJECT_SCOPE );
-        StudioSearchResultEnumeration result = getConnectionWrapper( monitor ).search( "uid=admin,ou=system",
-            "(objectClass=*)",
-            searchControls, AliasDereferencingMethod.NEVER, ReferralHandlingMethod.IGNORE, null, monitor, null );
+        StudioSearchResultEnumeration result = getConnectionWrapper( monitor, ldapServer ).search(
+            "uid=user.1,ou=users,dc=example,dc=org", "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER,
+            ReferralHandlingMethod.IGNORE, null, monitor, null );
 
         assertNotNull( result );
         assertTrue( result.hasMore() );
@@ -360,17 +332,18 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
 
         Object userPasswordValue = entry.getEntry().get( "userPassword" ).getBytes();
         assertEquals( byte[].class, userPasswordValue.getClass() );
-        assertEquals( "secret", new String( ( byte[] ) userPasswordValue, StandardCharsets.UTF_8 ) );
     }
 
 
-    @Test
-    public void testSearchContinuation_Follow_DirectReferral() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testSearchContinuation_Follow_DirectReferral( TestLdapServer ldapServer ) throws Exception
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         SearchControls searchControls = new SearchControls();
-        StudioSearchResultEnumeration result = getConnectionWrapper( monitor ).search(
-            "cn=referral1,ou=referrals,ou=system", "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER,
+        StudioSearchResultEnumeration result = getConnectionWrapper( monitor, ldapServer ).search(
+            "cn=referral1," + REFERRALS_OU_DN, "(objectClass=*)", searchControls,
+            AliasDereferencingMethod.NEVER,
             ReferralHandlingMethod.FOLLOW, null, monitor, null );
 
         assertFalse( monitor.isCanceled() );
@@ -378,19 +351,25 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertNotNull( result );
 
         List<String> dns = consume( result, sr -> sr.getDn().getName() );
-        assertEquals( 1, dns.size() );
-        assertEquals( "uid=user.1,ou=users,ou=system", dns.get( 0 ) );
+        if ( ldapServer.getType() != LdapServerType.Fedora389ds )
+        {
+            // TODO: check why 389ds returns ou=users
+            assertEquals( 8, dns.size() );
+            assertThat( dns, hasItems( "uid=user.1," + USERS_OU_DN, "uid=user.8," + USERS_OU_DN ) );
+        }
     }
 
 
-    @Test
-    public void testSearchContinuation_Follow_IntermediateReferral() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testSearchContinuation_Follow_IntermediateReferral( TestLdapServer ldapServer ) throws Exception
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         SearchControls searchControls = new SearchControls();
         searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-        StudioSearchResultEnumeration result = getConnectionWrapper( monitor ).search(
-            "cn=referral2,ou=referrals,ou=system", "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER,
+        StudioSearchResultEnumeration result = getConnectionWrapper( monitor, ldapServer ).search(
+            "cn=referral2," + REFERRALS_OU_DN, "(objectClass=*)", searchControls,
+            AliasDereferencingMethod.NEVER,
             ReferralHandlingMethod.FOLLOW, null, monitor, null );
 
         assertFalse( monitor.isCanceled() );
@@ -398,19 +377,24 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertNotNull( result );
 
         List<String> dns = consume( result, sr -> sr.getDn().getName() );
-        assertEquals( 2, dns.size() );
-        assertThat( dns, hasItems( "ou=users,ou=system", "uid=user.1,ou=users,ou=system" ) );
+        if ( ldapServer.getType() != LdapServerType.Fedora389ds )
+        {
+            // TODO: check why 389ds returns ou=users only
+            assertEquals( 9, dns.size() );
+            assertThat( dns, hasItems( USERS_OU_DN, "uid=user.1," + USERS_OU_DN, "uid=user.8," + USERS_OU_DN ) );
+        }
     }
 
 
-    @Test
-    public void testSearchContinuation_Follow_ReferralToParent() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testSearchContinuation_Follow_ReferralToParent( TestLdapServer ldapServer ) throws Exception
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         SearchControls searchControls = new SearchControls();
         searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-        StudioSearchResultEnumeration result = getConnectionWrapper( monitor ).search(
-            "cn=referral3,ou=referrals,ou=system", "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER,
+        StudioSearchResultEnumeration result = getConnectionWrapper( monitor, ldapServer ).search(
+            "cn=referral3," + REFERRALS_OU_DN, "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER,
             ReferralHandlingMethod.FOLLOW, null, monitor, null );
 
         assertFalse( monitor.isCanceled() );
@@ -418,19 +402,25 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertNotNull( result );
 
         List<String> dns = consume( result, sr -> sr.getDn().getName() );
-        assertEquals( 3, dns.size() );
-        assertThat( dns, hasItems( "ou=referrals,ou=system", "ou=users,ou=system", "uid=user.1,ou=users,ou=system" ) );
+        if ( ldapServer.getType() != LdapServerType.Fedora389ds )
+        {
+            // TODO: check why 389ds returns nothing
+            assertEquals( 10, dns.size() );
+            assertThat( dns,
+                hasItems( REFERRALS_OU_DN, USERS_OU_DN, "uid=user.1," + USERS_OU_DN, "uid=user.8," + USERS_OU_DN ) );
+        }
     }
 
 
-    @Test
-    public void testSearchContinuation_Follow_ReferralLoop() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testSearchContinuation_Follow_ReferralLoop( TestLdapServer ldapServer ) throws Exception
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         SearchControls searchControls = new SearchControls();
         searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-        StudioSearchResultEnumeration result = getConnectionWrapper( monitor ).search(
-            "cn=referral4a,ou=referrals,ou=system", "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER,
+        StudioSearchResultEnumeration result = getConnectionWrapper( monitor, ldapServer ).search(
+            "cn=referral4a," + REFERRALS_OU_DN, "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER,
             ReferralHandlingMethod.FOLLOW, null, monitor, null );
 
         assertFalse( monitor.isCanceled() );
@@ -442,15 +432,16 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     }
 
 
-    @Test
-    public void testSearchContinuationFollowManually() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testSearchContinuationFollowManually( TestLdapServer ldapServer ) throws Exception
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         SearchControls searchControls = new SearchControls();
         searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-        ConnectionWrapper connectionWrapper = getConnectionWrapper( monitor );
+        ConnectionWrapper connectionWrapper = getConnectionWrapper( monitor, ldapServer );
         ConnectionCorePlugin.getDefault().setReferralHandler( null );
-        StudioSearchResultEnumeration result = connectionWrapper.search( "ou=referrals,ou=system", "(objectClass=*)",
+        StudioSearchResultEnumeration result = connectionWrapper.search( REFERRALS_OU_DN, "(objectClass=*)",
             searchControls, AliasDereferencingMethod.NEVER, ReferralHandlingMethod.FOLLOW_MANUALLY, null, monitor,
             null );
 
@@ -461,18 +452,19 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         List<String> dns = consume( result, sr -> sr.getDn().getName() );
         assertEquals( 6, dns.size() );
         assertThat( dns,
-            hasItems( "ou=referrals,ou=system", "ou=users,ou=system", "cn=referral1,ou=referrals,ou=system",
-                "cn=referral4a,ou=referrals,ou=system", "cn=referral4b,ou=referrals,ou=system" ) );
+            hasItems( REFERRALS_OU_DN, USERS_OU_DN, "cn=referral1," + REFERRALS_OU_DN,
+                "cn=referral4a," + REFERRALS_OU_DN, "cn=referral4b," + REFERRALS_OU_DN ) );
     }
 
 
-    @Test
-    public void testSearchContinuationIgnore() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testSearchContinuationIgnore( TestLdapServer ldapServer ) throws Exception
     {
         StudioProgressMonitor monitor = getProgressMonitor();
         SearchControls searchControls = new SearchControls();
         searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-        StudioSearchResultEnumeration result = getConnectionWrapper( monitor ).search( "ou=referrals,ou=system",
+        StudioSearchResultEnumeration result = getConnectionWrapper( monitor, ldapServer ).search( REFERRALS_OU_DN,
             "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER, ReferralHandlingMethod.IGNORE, null,
             monitor, null );
 
@@ -482,7 +474,33 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
 
         List<String> dns = consume( result, sr -> sr.getDn().getName() );
         assertEquals( 1, dns.size() );
-        assertThat( dns, hasItems( "ou=referrals,ou=system" ) );
+        assertThat( dns, hasItems( REFERRALS_OU_DN ) );
+    }
+
+
+    @ParameterizedTest
+    @LdapServersSource
+    public void testSearchContinuationFollowParent( TestLdapServer ldapServer ) throws Exception
+    {
+        StudioProgressMonitor monitor = getProgressMonitor();
+        SearchControls searchControls = new SearchControls();
+        searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+        StudioSearchResultEnumeration result = getConnectionWrapper( monitor, ldapServer ).search( REFERRALS_OU_DN,
+            "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER, ReferralHandlingMethod.FOLLOW, null,
+            monitor, null );
+
+        assertFalse( monitor.isCanceled() );
+        assertFalse( monitor.errorsReported() );
+        assertNotNull( result );
+
+        List<String> dns = consume( result, sr -> sr.getDn().getName() );
+        if ( ldapServer.getType() != LdapServerType.Fedora389ds )
+        {
+            // TODO: check why 389ds missed uid=user.1
+            assertEquals( 11, dns.size() );
+            assertThat( dns, hasItems( REFERRALS_OU_DN, REFERRALS_OU_DN, USERS_OU_DN,
+                "uid=user.1," + USERS_OU_DN, "uid=user.8," + USERS_OU_DN ) );
+        }
     }
 
 
@@ -499,67 +517,71 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     }
 
 
-    @Test
-    public void testAdd() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testAdd( TestLdapServer ldapServer ) throws Exception
     {
-        String dn = "uid=user.X,ou=users,ou=system";
+        String dn = "uid=user.X," + USERS_OU_DN;
 
         StudioProgressMonitor monitor = getProgressMonitor();
         Entry entry = new DefaultEntry( dn, "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" );
-        getConnectionWrapper( monitor ).createEntry( entry, null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).createEntry( entry, null, monitor, null );
 
         // should have created entry
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
-        assertTrue( service.getAdminSession().exists( dn ) );
+        assertTrue( ldapServer.withAdminConnectionAndGet( connection -> connection.exists( dn ) ) );
     }
 
 
-    @Test
-    public void testAddFollowsReferral_DirectReferral() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testAddFollowsReferral_DirectReferral( TestLdapServer ldapServer ) throws Exception
     {
-        String targetDn = "uid=user.X,ou=users,ou=system";
-        String referralDn = "uid=user.X,cn=referral1,ou=referrals,ou=system";
+        String targetDn = "uid=user.X," + USERS_OU_DN;
+        String referralDn = "uid=user.X,cn=referral1," + REFERRALS_OU_DN;
 
         // create entry under referral
         StudioProgressMonitor monitor = getProgressMonitor();
         Entry entry = new DefaultEntry( referralDn, "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" );
-        getConnectionWrapper( monitor ).createEntry( entry, null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).createEntry( entry, null, monitor, null );
 
         // should have created target entry
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
-        assertTrue( service.getAdminSession().exists( targetDn ) );
+        assertTrue( ldapServer.withAdminConnectionAndGet( connection -> connection.exists( targetDn ) ) );
     }
 
 
-    @Test
-    public void testAddFollowsReferral_IntermediateReferral() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testAddFollowsReferral_IntermediateReferral( TestLdapServer ldapServer ) throws Exception
     {
-        String targetDn = "uid=user.X,ou=users,ou=system";
-        String referralDn = "uid=user.X,cn=referral2,ou=referrals,ou=system";
+        String targetDn = "uid=user.X," + USERS_OU_DN;
+        String referralDn = "uid=user.X,cn=referral2," + REFERRALS_OU_DN;
 
         // create entry under referral
         StudioProgressMonitor monitor = getProgressMonitor();
         Entry entry = new DefaultEntry( referralDn, "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" );
-        getConnectionWrapper( monitor ).createEntry( entry, null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).createEntry( entry, null, monitor, null );
 
         // should have created target entry
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
-        assertTrue( service.getAdminSession().exists( targetDn ) );
+        assertTrue( ldapServer.withAdminConnectionAndGet( connection -> connection.exists( targetDn ) ) );
     }
 
 
-    @Test
-    public void testAddFollowsReferral_ReferralLoop() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testAddFollowsReferral_ReferralLoop( TestLdapServer ldapServer ) throws Exception
     {
-        String referralDn = "uid=user.X,cn=referral4a,ou=referrals,ou=system";
+        String referralDn = "uid=user.X,cn=referral4a," + REFERRALS_OU_DN;
 
         // create entry under referral
         StudioProgressMonitor monitor = getProgressMonitor();
         Entry entry = new DefaultEntry( referralDn, "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" );
-        getConnectionWrapper( monitor ).createEntry( entry, null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).createEntry( entry, null, monitor, null );
 
         // should not have created target entry
         assertFalse( monitor.isCanceled() );
@@ -572,96 +594,103 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     }
 
 
-    @Test
-    public void testModify() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testModify( TestLdapServer ldapServer ) throws Exception
     {
-        String dn = "uid=user.X,ou=users,ou=system";
+        String dn = "uid=user.X," + USERS_OU_DN;
 
         // create entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), dn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) );
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( dn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) ) );
 
         // modify entry
         StudioProgressMonitor monitor = getProgressMonitor();
         List<Modification> modifications = Collections.singletonList(
             new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
                 new DefaultAttribute( "sn", "modified" ) ) );
-        getConnectionWrapper( monitor ).modifyEntry( new Dn( dn ), modifications, null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).modifyEntry( new Dn( dn ), modifications, null, monitor, null );
 
         // should have modified the entry
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
-        Entry entry = service.getAdminSession().lookup( new Dn( dn ) );
+        Entry entry = ldapServer.withAdminConnectionAndGet( connection -> connection.lookup( new Dn( dn ) ) );
         assertEquals( "modified", entry.get( "sn" ).getString() );
     }
 
 
-    @Test
-    public void testModifyFollowsReferral_DirectReferral() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testModifyFollowsReferral_DirectReferral( TestLdapServer ldapServer ) throws Exception
     {
-        String targetDn = "uid=user.X,ou=users,ou=system";
-        String referralDn = "uid=user.X,cn=referral1,ou=referrals,ou=system";
+        String targetDn = "uid=user.X," + USERS_OU_DN;
+        String referralDn = "uid=user.X,cn=referral1," + REFERRALS_OU_DN;
 
         // create target entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), targetDn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) );
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( targetDn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) ) );
 
         // modify referral entry 
         StudioProgressMonitor monitor = getProgressMonitor();
         List<Modification> modifications = Collections.singletonList(
             new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
                 new DefaultAttribute( "sn", "modified" ) ) );
-        getConnectionWrapper( monitor ).modifyEntry( new Dn( referralDn ), modifications, null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).modifyEntry( new Dn( referralDn ), modifications, null, monitor,
+            null );
 
         // should have modified the target entry
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
-        Entry entry = service.getAdminSession().lookup( new Dn( targetDn ) );
+        Entry entry = ldapServer.withAdminConnectionAndGet( connection -> connection.lookup( new Dn( targetDn ) ) );
         assertEquals( "modified", entry.get( "sn" ).getString() );
     }
 
 
-    @Test
-    public void testModifyFollowsReferral_IntermediateReferral() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testModifyFollowsReferral_IntermediateReferral( TestLdapServer ldapServer ) throws Exception
     {
-        String targetDn = "uid=user.X,ou=users,ou=system";
-        String referralDn = "uid=user.X,cn=referral2,ou=referrals,ou=system";
+        String targetDn = "uid=user.X," + USERS_OU_DN;
+        String referralDn = "uid=user.X,cn=referral2," + REFERRALS_OU_DN;
 
         // create target entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), targetDn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) );
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( targetDn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) ) );
 
         // modify referral entry 
         StudioProgressMonitor monitor = getProgressMonitor();
         List<Modification> modifications = Collections.singletonList(
             new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
                 new DefaultAttribute( "sn", "modified" ) ) );
-        getConnectionWrapper( monitor ).modifyEntry( new Dn( referralDn ), modifications, null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).modifyEntry( new Dn( referralDn ), modifications, null, monitor,
+            null );
 
         // should have modified the target entry
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
-        Entry entry = service.getAdminSession().lookup( new Dn( targetDn ) );
+        Entry entry = ldapServer.withAdminConnectionAndGet( connection -> connection.lookup( new Dn( targetDn ) ) );
         assertEquals( "modified", entry.get( "sn" ).getString() );
     }
 
 
-    @Test
-    public void testModifyFollowsReferral_ReferralLoop() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testModifyFollowsReferral_ReferralLoop( TestLdapServer ldapServer ) throws Exception
     {
-        String targetDn = "uid=user.X,ou=users,ou=system";
-        String referralDn = "uid=user.X,cn=referral4a,ou=referrals,ou=system";
+        String targetDn = "uid=user.X," + USERS_OU_DN;
+        String referralDn = "uid=user.X,cn=referral4a," + REFERRALS_OU_DN;
 
         // create target entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), targetDn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) );
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( targetDn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) ) );
 
         // modify referral entry 
         StudioProgressMonitor monitor = getProgressMonitor();
         List<Modification> modifications = Collections.singletonList(
             new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE,
                 new DefaultAttribute( "sn", "modified" ) ) );
-        getConnectionWrapper( monitor ).modifyEntry( new Dn( referralDn ), modifications, null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).modifyEntry( new Dn( referralDn ), modifications, null, monitor,
+            null );
 
         // should not have modified the target entry
         assertFalse( monitor.isCanceled() );
@@ -674,81 +703,85 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     }
 
 
-    @Test
-    public void testDelete() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testDelete( TestLdapServer ldapServer ) throws Exception
     {
-        String dn = "uid=user.X,ou=users,ou=system";
+        String dn = "uid=user.X," + USERS_OU_DN;
 
         // create entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), dn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) );
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( dn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) ) );
 
         // delete entry
         StudioProgressMonitor monitor = getProgressMonitor();
-        getConnectionWrapper( monitor ).deleteEntry( new Dn( dn ), null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).deleteEntry( new Dn( dn ), null, monitor, null );
 
         // should have deleted the entry
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
-        assertFalse( service.getAdminSession().exists( dn ) );
+        assertFalse( ldapServer.withAdminConnectionAndGet( connection -> connection.exists( dn ) ) );
     }
 
 
-    @Test
-    public void testDeleteFollowsReferral_DirectReferral() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testDeleteFollowsReferral_DirectReferral( TestLdapServer ldapServer ) throws Exception
     {
-        String targetDn = "uid=user.X,ou=users,ou=system";
-        String referralDn = "uid=user.X,cn=referral1,ou=referrals,ou=system";
+        String targetDn = "uid=user.X," + USERS_OU_DN;
+        String referralDn = "uid=user.X,cn=referral1," + REFERRALS_OU_DN;
 
         // create target entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), targetDn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) );
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( targetDn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) ) );
 
         // delete referral entry 
         StudioProgressMonitor monitor = getProgressMonitor();
-        getConnectionWrapper( monitor ).deleteEntry( new Dn( referralDn ), null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).deleteEntry( new Dn( referralDn ), null, monitor, null );
 
         // should have deleted the target entry
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
-        assertFalse( service.getAdminSession().exists( targetDn ) );
+        assertFalse( ldapServer.withAdminConnectionAndGet( connection -> connection.exists( targetDn ) ) );
     }
 
 
-    @Test
-    public void testDeleteFollowsReferral_IntermediateReferral() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testDeleteFollowsReferral_IntermediateReferral( TestLdapServer ldapServer ) throws Exception
     {
-        String targetDn = "uid=user.X,ou=users,ou=system";
-        String referralDn = "uid=user.X,cn=referral2,ou=referrals,ou=system";
+        String targetDn = "uid=user.X," + USERS_OU_DN;
+        String referralDn = "uid=user.X,cn=referral2," + REFERRALS_OU_DN;
 
         // create target entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), targetDn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) );
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( targetDn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) ) );
 
         // delete referral entry 
         StudioProgressMonitor monitor = getProgressMonitor();
-        getConnectionWrapper( monitor ).deleteEntry( new Dn( referralDn ), null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).deleteEntry( new Dn( referralDn ), null, monitor, null );
 
         // should have deleted the target entry
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
-        assertFalse( service.getAdminSession().exists( targetDn ) );
+        assertFalse( ldapServer.withAdminConnectionAndGet( connection -> connection.exists( targetDn ) ) );
     }
 
 
-    @Test
-    public void testDeleteFollowsReferral_ReferralLoop() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testDeleteFollowsReferral_ReferralLoop( TestLdapServer ldapServer ) throws Exception
     {
-        String targetDn = "uid=user.X,ou=users,ou=system";
-        String referralDn = "uid=user.X,cn=referral4a,ou=referrals,ou=system";
+        String targetDn = "uid=user.X," + USERS_OU_DN;
+        String referralDn = "uid=user.X,cn=referral4a," + REFERRALS_OU_DN;
 
         // create target entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), targetDn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) );
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( targetDn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X" ) ) );
 
         // delete referral entry 
         StudioProgressMonitor monitor = getProgressMonitor();
-        getConnectionWrapper( monitor ).deleteEntry( new Dn( referralDn ), null, monitor, null );
+        getConnectionWrapper( monitor, ldapServer ).deleteEntry( new Dn( referralDn ), null, monitor, null );
 
         // should not have deleted the target entry
         assertFalse( monitor.isCanceled() );
@@ -758,41 +791,21 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         assertTrue( monitor.getException().getMessage().contains( "[LDAP result code 54 - loopDetect]" ) );
         assertTrue( monitor.getException().getMessage().contains( "already processed" ) );
         assertTrue( monitor.getException().getCause() instanceof LdapLoopDetectedException );
-        assertTrue( service.getAdminSession().exists( targetDn ) );
-    }
-
-
-    @Test
-    public void testSearchContinuationFollowParent() throws Exception
-    {
-        StudioProgressMonitor monitor = getProgressMonitor();
-        SearchControls searchControls = new SearchControls();
-        searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
-        StudioSearchResultEnumeration result = getConnectionWrapper( monitor ).search( "ou=referrals,ou=system",
-            "(objectClass=*)", searchControls, AliasDereferencingMethod.NEVER, ReferralHandlingMethod.FOLLOW, null,
-            monitor, null );
-
-        assertFalse( monitor.isCanceled() );
-        assertFalse( monitor.errorsReported() );
-        assertNotNull( result );
-
-        List<String> dns = consume( result, sr -> sr.getDn().getName() );
-        assertEquals( 4, dns.size() );
-        assertThat( dns, hasItems( "ou=referrals,ou=system", "ou=referrals,ou=system", "ou=users,ou=system",
-            "uid=user.1,ou=users,ou=system" ) );
+        assertTrue( ldapServer.withAdminConnectionAndGet( connection -> connection.exists( targetDn ) ) );
     }
 
 
     /**
      * Test initializing of Root DSE.
      */
-    @Test
-    public void testInitializeAttributesRunnable() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testInitializeAttributesRunnable( TestLdapServer ldapServer ) throws Exception
     {
         StudioProgressMonitor monitor = getProgressMonitor();
-        ConnectionParameter connectionParameter = new ConnectionParameter( null, LOCALHOST, ldapServer.getPort(),
-            EncryptionMethod.NONE, AuthenticationMethod.SIMPLE,
-            "uid=admin,ou=system", "secret", null, true, null, 30000L );
+        ConnectionParameter connectionParameter = new ConnectionParameter( null, ldapServer.getHost(),
+            ldapServer.getPort(), EncryptionMethod.NONE, AuthenticationMethod.SIMPLE,
+            ldapServer.getAdminDn(), ldapServer.getAdminPassword(), null, true, null, 30000L );
         Connection connection = new Connection( connectionParameter );
         BrowserConnection browserConnection = new BrowserConnection( connection );
 
@@ -807,14 +820,16 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     /**
      * DIRSTUDIO-1039
      */
-    @Ignore
-    @Test
-    public void testConcurrentUseAndCloseOfConnection() throws Exception
+    @Disabled("Flaky test")
+    @ParameterizedTest
+    @LdapServersSource
+    public void testConcurrentUseAndCloseOfConnection( TestLdapServer ldapServer ) throws Exception
     {
         final StudioProgressMonitor monitor = getProgressMonitor();
-        final ConnectionParameter connectionParameter = new ConnectionParameter( null, LOCALHOST, ldapServer.getPort(),
+        final ConnectionParameter connectionParameter = new ConnectionParameter( null, ldapServer.getHost(),
+            ldapServer.getPort(),
             EncryptionMethod.NONE, AuthenticationMethod.SIMPLE,
-            "uid=admin,ou=system", "secret", null, true, null, 30000L );
+            ldapServer.getAdminDn(), ldapServer.getAdminPassword(), null, true, null, 30000L );
         final Connection connection = new Connection( connectionParameter );
         final BrowserConnection browserConnection = new BrowserConnection( connection );
 
@@ -876,14 +891,20 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     }
 
 
-    @Test
-    public void testPasswordModifyRequestExtendedOperation_AdminChangesUserPassword() throws Exception
+    @ParameterizedTest
+    @LdapServersSource
+    public void testPasswordModifyRequestExtendedOperation_AdminChangesUserPassword( TestLdapServer ldapServer )
+        throws Exception
     {
-        String dn = "uid=user.X,ou=users,ou=system";
+        String dn = "uid=user.X," + USERS_OU_DN;
 
         // create target entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), dn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X", "userPassword:  secret" ) );
+        String password0 = "{SSHA}VHg6ewDaPUmVWw3efXL5NF6bVuRHGWhrCRH1xA==";
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( dn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X",
+            "userPassword: " + password0 ) ) );
+        Entry entry0 = ldapServer.withAdminConnectionAndGet( connection -> connection.lookup( new Dn( dn ) ) );
+        assertEquals( password0, Strings.utf8ToString( entry0.get( "userPassword" ).getBytes() ) );
 
         // modify password
         LdapApiService ldapApiService = LdapApiServiceFactory.getSingleton();
@@ -892,42 +913,66 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         request.setUserIdentity( Strings.getBytesUtf8( dn ) );
         request.setNewPassword( Strings.getBytesUtf8( "s3cre3t" ) );
         StudioProgressMonitor monitor = getProgressMonitor();
-        ExtendedResponse response = getConnectionWrapper( monitor ).extended( request, monitor );
+        ExtendedResponse response = getConnectionWrapper( monitor, ldapServer ).extended( request, monitor );
 
-        // should have modified password of the target entry
-        assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
-        assertFalse( monitor.isCanceled() );
-        assertFalse( monitor.errorsReported() );
-        Entry entry = service.getAdminSession().lookup( new Dn( dn ) );
-        assertEquals( "s3cre3t", Strings.utf8ToString( entry.get( "userPassword" ).getBytes() ) );
+        if ( ldapServer.getType() == LdapServerType.Fedora389ds )
+        {
+            assertEquals( ResultCodeEnum.CONFIDENTIALITY_REQUIRED, response.getLdapResult().getResultCode() );
+            assertFalse( monitor.isCanceled() );
+            assertTrue( monitor.errorsReported() );
+        }
+        else
+        {
+            // should have modified password of the target entry
+            assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
+            assertFalse( monitor.isCanceled() );
+            assertFalse( monitor.errorsReported() );
+            Entry entry = ldapServer.withAdminConnectionAndGet( connection -> connection.lookup( new Dn( dn ) ) );
+            assertNotEquals( password0, Strings.utf8ToString( entry.get( "userPassword" ).getBytes() ) );
+        }
     }
 
 
-    @Test
-    public void testPasswordModifyRequestExtendedOperation_UserChangesOwnPassword() throws Exception
+    @ParameterizedTest
+    @LdapServersSource(types =
+        { LdapServerType.ApacheDS, LdapServerType.OpenLdap })
+    public void testPasswordModifyRequestExtendedOperation_UserChangesOwnPassword( TestLdapServer ldapServer )
+        throws Exception
     {
-        LdapApiService ldapApiService = LdapApiServiceFactory.getSingleton();
-        String dn = "uid=user.X,ou=users,ou=system";
+        String dn = "uid=user.X," + USERS_OU_DN;
 
         // create target entry
-        service.getAdminSession().add( new DefaultEntry( service.getSchemaManager(), dn,
-            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X", "userPassword:  secret" ) );
+        String password0 = "{SSHA}VHg6ewDaPUmVWw3efXL5NF6bVuRHGWhrCRH1xA==";
+        ldapServer.withAdminConnection( connection -> connection.add( new DefaultEntry( dn,
+            "objectClass: inetOrgPerson", "sn: X", "cn: X", "uid: user.X",
+            "userPassword: " + password0 ) ) );
+        Entry entry0 = ldapServer.withAdminConnectionAndGet( connection -> connection.lookup( new Dn( dn ) ) );
+        assertEquals( password0, Strings.utf8ToString( entry0.get( "userPassword" ).getBytes() ) );
 
         // modify password with wrong old password
+        LdapApiService ldapApiService = LdapApiServiceFactory.getSingleton();
         PasswordModifyRequest request1 = ( PasswordModifyRequest ) ldapApiService.getExtendedRequestFactories()
             .get( PasswordModifyRequest.EXTENSION_OID ).newRequest();
         request1.setUserIdentity( Strings.getBytesUtf8( dn ) );
         request1.setOldPassword( Strings.getBytesUtf8( "wrong" ) );
         request1.setNewPassword( Strings.getBytesUtf8( "s3cre3t" ) );
         StudioProgressMonitor monitor1 = getProgressMonitor();
-        ExtendedResponse response1 = getConnectionWrapper( monitor1, dn, "secret" ).extended( request1, monitor1 );
+        ExtendedResponse response1 = getConnectionWrapper( monitor1, ldapServer, dn, "secret" ).extended( request1,
+            monitor1 );
 
         // should not have modified password of the target entry
-        assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, response1.getLdapResult().getResultCode() );
+        if ( ldapServer.getType() == LdapServerType.OpenLdap )
+        {
+            assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, response1.getLdapResult().getResultCode() );
+        }
+        else
+        {
+            assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, response1.getLdapResult().getResultCode() );
+        }
         assertFalse( monitor1.isCanceled() );
         assertTrue( monitor1.errorsReported() );
-        Entry entry1 = service.getAdminSession().lookup( new Dn( dn ) );
-        assertEquals( "secret", Strings.utf8ToString( entry1.get( "userPassword" ).getBytes() ) );
+        Entry entry1 = ldapServer.withAdminConnectionAndGet( connection -> connection.lookup( new Dn( dn ) ) );
+        assertEquals( password0, Strings.utf8ToString( entry1.get( "userPassword" ).getBytes() ) );
 
         // modify password with correct old password
         PasswordModifyRequest request2 = ( PasswordModifyRequest ) ldapApiService.getExtendedRequestFactories()
@@ -936,38 +981,41 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
         request2.setOldPassword( Strings.getBytesUtf8( "secret" ) );
         request2.setNewPassword( Strings.getBytesUtf8( "s3cre3t" ) );
         StudioProgressMonitor monitor2 = getProgressMonitor();
-        ExtendedResponse response2 = getConnectionWrapper( monitor2, dn, "secret" ).extended( request2, monitor2 );
+        ExtendedResponse response2 = getConnectionWrapper( monitor2, ldapServer, dn, "secret" ).extended( request2,
+            monitor2 );
 
         // should have modified password of the target entry
         assertEquals( ResultCodeEnum.SUCCESS, response2.getLdapResult().getResultCode() );
         assertFalse( monitor2.isCanceled() );
         assertFalse( monitor2.errorsReported() );
-        Entry entry2 = service.getAdminSession().lookup( new Dn( dn ) );
-        assertEquals( "s3cre3t", Strings.utf8ToString( entry2.get( "userPassword" ).getBytes() ) );
+        Entry entry2 = ldapServer.withAdminConnectionAndGet( connection -> connection.lookup( new Dn( dn ) ) );
+        assertNotEquals( password0, Strings.utf8ToString( entry2.get( "userPassword" ).getBytes() ) );
     }
 
 
-    @Ignore
-    @Test
-    public void testWhoAmIExtendedOperation() throws Exception
+    @ParameterizedTest
+    @LdapServersSource(types =
+        { LdapServerType.OpenLdap, LdapServerType.Fedora389ds })
+    public void testWhoAmIExtendedOperation( TestLdapServer ldapServer ) throws Exception
     {
         LdapApiService ldapApiService = LdapApiServiceFactory.getSingleton();
         WhoAmIRequest request = ( WhoAmIRequest ) ldapApiService.getExtendedRequestFactories()
             .get( WhoAmIRequest.EXTENSION_OID ).newRequest();
         StudioProgressMonitor monitor = getProgressMonitor();
-        WhoAmIResponse response = ( WhoAmIResponse ) getConnectionWrapper( monitor ).extended( request, monitor );
+        WhoAmIResponse response = ( WhoAmIResponse ) getConnectionWrapper( monitor, ldapServer ).extended( request,
+            monitor );
 
         assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
         assertFalse( monitor.isCanceled() );
         assertFalse( monitor.errorsReported() );
         assertTrue( response.isDnAuthzId() );
-        assertEquals( "uid=admin,ou=system", response.getDn().toString() );
+        assertEquals( ldapServer.getAdminDn().toLowerCase(), response.getDn().toString().toLowerCase().trim() );
     }
 
     /*
     @Ignore
     @Test
-    public void testStartEndTransactionExtendedOperation() throws Exception
+    public void testStartEndTransactionExtendedOperation( TestLdapServer ldapServer ) throws Exception
     {
         LdapApiService ldapApiService = LdapApiServiceFactory.getSingleton();
     
@@ -1003,17 +1051,39 @@ public class DirectoryApiConnectionWrapperTest extends AbstractLdapTestUnit
     }
 
 
-    protected ConnectionWrapper getConnectionWrapper( StudioProgressMonitor monitor )
+    protected ConnectionWrapper getConnectionWrapper( StudioProgressMonitor monitor, TestLdapServer ldapServer,
+        String dn, String password )
     {
-        return getConnectionWrapper( monitor, "uid=admin,ou=system", "secret" );
+        // simple auth without principal and credential
+        ConnectionParameter connectionParameter = new ConnectionParameter( null, LOCALHOST, ldapServer.getPort(),
+            EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, dn, password, null, false, null, 30000L );
+
+        Connection connection = new Connection( connectionParameter );
+
+        connectionWrapper = connection.getConnectionWrapper();
+        connectionWrapper.connect( monitor );
+        connectionWrapper.bind( monitor );
+
+        assertTrue( connectionWrapper.isConnected() );
+
+        IReferralHandler referralHandler = referralUrls -> {
+            return connection;
+        };
+        ConnectionCorePlugin.getDefault().setReferralHandler( referralHandler );
+
+        assertTrue( connectionWrapper.isConnected() );
+        assertNull( monitor.getException() );
+
+        return connectionWrapper;
     }
 
 
-    protected ConnectionWrapper getConnectionWrapper( StudioProgressMonitor monitor, String dn, String password )
+    protected ConnectionWrapper getConnectionWrapper( StudioProgressMonitor monitor, TestLdapServer ldapServer )
     {
         // simple auth without principal and credential
         ConnectionParameter connectionParameter = new ConnectionParameter( null, LOCALHOST, ldapServer.getPort(),
-            EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, dn, password, null, false, null, 30000L );
+            EncryptionMethod.NONE, AuthenticationMethod.SIMPLE, ldapServer.getAdminDn(), ldapServer.getAdminPassword(),
+            null, false, null, 30000L );
 
         Connection connection = new Connection( connectionParameter );
 
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/SchemaTest.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/SchemaTest.java
index a779804..bca53f7 100644
--- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/SchemaTest.java
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/SchemaTest.java
@@ -28,13 +28,8 @@ import java.util.Collection;
 
 import org.apache.directory.api.ldap.model.schema.AttributeType;
 import org.apache.directory.api.ldap.model.schema.ObjectClass;
-import org.apache.directory.server.annotations.CreateLdapServer;
-import org.apache.directory.server.annotations.CreateTransport;
-import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
-import org.apache.directory.server.core.integ.FrameworkRunner;
 import org.apache.directory.studio.ldapbrowser.core.model.schema.Schema;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
 
 
 /**
@@ -42,10 +37,7 @@ import org.junit.runner.RunWith;
  *
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  */
-@RunWith(FrameworkRunner.class)
-@CreateLdapServer(transports =
-    { @CreateTransport(protocol = "LDAP"), @CreateTransport(protocol = "LDAPS") })
-public class SchemaTest extends AbstractLdapTestUnit
+public class SchemaTest
 {
 
     /**
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/ApacheDirectoryServer.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/ApacheDirectoryServer.java
new file mode 100644
index 0000000..d47e044
--- /dev/null
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/ApacheDirectoryServer.java
@@ -0,0 +1,95 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.directory.studio.test.integration.junit5;
+
+
+import static org.apache.directory.studio.test.integration.junit5.Constants.LOCALHOST;
+
+import java.io.File;
+
+import org.apache.directory.server.core.api.DirectoryService;
+import org.apache.directory.server.core.api.partition.Partition;
+import org.apache.directory.server.core.factory.DefaultDirectoryServiceFactory;
+import org.apache.directory.server.ldap.LdapServer;
+import org.apache.directory.server.ldap.handlers.extended.PwdModifyHandler;
+import org.apache.directory.server.ldap.handlers.extended.WhoAmIHandler;
+import org.apache.directory.server.protocol.shared.transport.TcpTransport;
+import org.apache.directory.server.protocol.shared.transport.Transport;
+import org.apache.mina.util.AvailablePortFinder;
+
+
+/**
+ * An ApacheDS implementation of a test LDAP server.
+ * 
+ * This implementation starts an embedded LdapServer and adds a partition dc=example,dc=org.
+ */
+public class ApacheDirectoryServer extends TestLdapServer
+{
+
+    private static DirectoryService service;
+    private static LdapServer server;
+
+    public static ApacheDirectoryServer getInstance()
+    {
+        if ( server == null )
+        {
+            startServer();
+        }
+        return new ApacheDirectoryServer();
+    }
+
+
+    private static void startServer()
+    {
+        try
+        {
+            DefaultDirectoryServiceFactory factory = new DefaultDirectoryServiceFactory();
+            factory.init( "test" );
+            service = factory.getDirectoryService();
+            Partition partition = factory.getPartitionFactory().createPartition( service.getSchemaManager(),
+                service.getDnFactory(), "example.org", "dc=example,dc=org", 1024,
+                new File( service.getInstanceLayout().getPartitionsDirectory(), "example.org" ) );
+            partition.initialize();
+            service.addPartition( partition );
+
+            server = new LdapServer();
+            server.setDirectoryService( service );
+            int port = AvailablePortFinder.getNextAvailable( 1024 );
+            Transport ldap = new TcpTransport( port );
+            server.addTransports( ldap );
+            server.addExtendedOperationHandler( new PwdModifyHandler() );
+            server.addExtendedOperationHandler( new WhoAmIHandler() );
+
+            server.start();
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( e );
+        }
+    }
+
+
+    private ApacheDirectoryServer()
+    {
+        super( LdapServerType.ApacheDS, LOCALHOST, server.getPort(), "uid=admin,ou=system", "secret" );
+    }
+
+}
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/Constants.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Constants.java
similarity index 94%
copy from tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/Constants.java
copy to tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Constants.java
index d7b4332..6c7e879 100644
--- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/Constants.java
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Constants.java
@@ -17,7 +17,7 @@
  *  under the License. 
  *  
  */
-package org.apache.directory.studio.test.integration.core;
+package org.apache.directory.studio.test.integration.junit5;
 
 
 import org.apache.directory.api.util.Network;
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Fedora389dsLdapServer.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Fedora389dsLdapServer.java
new file mode 100644
index 0000000..fedca3c
--- /dev/null
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/Fedora389dsLdapServer.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.directory.studio.test.integration.junit5;
+
+
+import static org.apache.directory.studio.test.integration.junit5.Constants.LOCALHOST;
+
+
+/**
+ * An 389ds implementation of a test LDAP server.
+ * 
+ * This implementation expects that an existing 389ds server is running
+ * and connection parameters are provided via environment variables.
+ */
+public class Fedora389dsLdapServer extends TestLdapServer
+{
+    private static final String FEDORA_389DS_HOST = getEnvOrDefault( "FEDORA_389DS_HOST", LOCALHOST );
+    private static final int FEDORA_389DS_PORT = Integer.parseInt( getEnvOrDefault( "FEDORA_389DS_PORT", "21389" ) );
+    private static final String FEDORA_389DS_ADMIN_DN = getEnvOrDefault( "FEDORA_389DS_ADMIN_DN",
+        "cn=Directory Manager" );
+    private static final String FEDORA_389DS_ADMIN_PASSWORD = getEnvOrDefault( "FEDORA_389DS_ADMIN_PASSWORD", "admin" );
+
+    public static Fedora389dsLdapServer getInstance()
+    {
+        return new Fedora389dsLdapServer();
+    }
+
+
+    private Fedora389dsLdapServer()
+    {
+        super( LdapServerType.Fedora389ds, FEDORA_389DS_HOST, FEDORA_389DS_PORT, FEDORA_389DS_ADMIN_DN,
+            FEDORA_389DS_ADMIN_PASSWORD );
+    }
+
+}
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/Constants.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/LdapServerType.java
similarity index 58%
copy from tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/Constants.java
copy to tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/LdapServerType.java
index d7b4332..0ffe045 100644
--- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/Constants.java
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/LdapServerType.java
@@ -17,14 +17,29 @@
  *  under the License. 
  *  
  */
-package org.apache.directory.studio.test.integration.core;
 
+package org.apache.directory.studio.test.integration.junit5;
 
-import org.apache.directory.api.util.Network;
 
-
-public final class Constants
+public enum LdapServerType
 {
-    public static final String LOCALHOST = Network.LOOPBACK_HOSTNAME;
+    ApacheDS,
+    OpenLdap,
+    Fedora389ds,
+    ;
 
+    public TestLdapServer getLdapServer()
+    {
+        switch ( this )
+        {
+            case ApacheDS:
+                return ApacheDirectoryServer.getInstance();
+            case OpenLdap:
+                return OpenLdapServer.getInstance();
+            case Fedora389ds:
+                return Fedora389dsLdapServer.getInstance();
+            default:
+                throw new IllegalArgumentException( "Unknown LDAP server type " + this );
+        }
+    }
 }
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/LdapServersArgumentsProvider.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/LdapServersArgumentsProvider.java
new file mode 100644
index 0000000..b5ff2dd
--- /dev/null
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/LdapServersArgumentsProvider.java
@@ -0,0 +1,60 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.directory.studio.test.integration.junit5;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+
+
+public class LdapServersArgumentsProvider implements ArgumentsProvider
+{
+
+    @Override
+    public Stream<Arguments> provideArguments( ExtensionContext context ) throws Exception
+    {
+        List<LdapServerType> types = Arrays
+            .asList( context.getTestMethod().get().getAnnotation( LdapServersSource.class ).types() );
+
+        List<Arguments> arguments = new ArrayList<>();
+
+        for ( LdapServerType type : LdapServerType.values() )
+        {
+            if ( types.contains( type ) )
+            {
+                if ( type.getLdapServer().isAvailable() )
+                {
+                    type.getLdapServer().prepare();
+                }
+                arguments.add( Arguments.of( type.getLdapServer() ) );
+            }
+        }
+
+        return arguments.stream();
+    }
+
+}
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/Constants.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/LdapServersSource.java
similarity index 57%
rename from tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/Constants.java
rename to tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/LdapServersSource.java
index d7b4332..9673561 100644
--- a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/core/Constants.java
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/LdapServersSource.java
@@ -17,14 +17,25 @@
  *  under the License. 
  *  
  */
-package org.apache.directory.studio.test.integration.core;
 
+package org.apache.directory.studio.test.integration.junit5;
 
-import org.apache.directory.api.util.Network;
 
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.jupiter.params.provider.ArgumentsSource;
 
-public final class Constants
-{
-    public static final String LOCALHOST = Network.LOOPBACK_HOSTNAME;
 
+@Documented
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@ArgumentsSource(LdapServersArgumentsProvider.class)
+public @interface LdapServersSource
+{
+    LdapServerType[] types() default
+        { LdapServerType.ApacheDS, LdapServerType.OpenLdap, LdapServerType.Fedora389ds };
 }
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/OpenLdapServer.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/OpenLdapServer.java
new file mode 100644
index 0000000..0ee2292
--- /dev/null
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/OpenLdapServer.java
@@ -0,0 +1,82 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.directory.studio.test.integration.junit5;
+
+
+import static org.apache.directory.studio.test.integration.junit5.Constants.LOCALHOST;
+
+import org.apache.directory.api.ldap.model.entry.Modification;
+import org.apache.directory.api.ldap.model.ldif.LdifEntry;
+import org.apache.directory.api.ldap.model.ldif.LdifReader;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+
+
+/**
+ * An OpenLDAP implementation of a test LDAP server.
+ * 
+ * This implementation expects that an existing OpenLDAP server is running
+ * and connection parameters are provided via environment variables.
+ */
+public class OpenLdapServer extends TestLdapServer
+{
+    private static final String OPENLDAP_HOST = getEnvOrDefault( "OPENLDAP_HOST", LOCALHOST );
+    private static final int OPENLDAP_PORT = Integer.parseInt( getEnvOrDefault( "OPENLDAP_PORT", "20389" ) );
+    private static final String OPENLDAP_ADMIN_DN = getEnvOrDefault( "OPENLDAP_ADMIN_DN",
+        "cn=admin,dc=example,dc=org" );
+    private static final String OPENLDAP_ADMIN_PASSWORD = getEnvOrDefault( "OPENLDAP_ADMIN_PASSWORD", "admin" );
+    private static final String OPENLDAP_CONFIG_DN = getEnvOrDefault( "OPENLDAP_CONFIG_DN", "cn=admin,cn=config" );
+    private static final String OPENLDAP_CONFIG_PASSWORD = getEnvOrDefault( "OPENLDAP_CONFIG_PASSWORD", "config" );
+
+    public static OpenLdapServer getInstance()
+    {
+        return new OpenLdapServer();
+    }
+
+
+    private OpenLdapServer()
+    {
+        super( LdapServerType.OpenLdap, OPENLDAP_HOST, OPENLDAP_PORT, OPENLDAP_ADMIN_DN, OPENLDAP_ADMIN_PASSWORD );
+    }
+
+
+    public void prepare()
+    {
+        super.prepare();
+
+        try ( LdapNetworkConnection connection = new LdapNetworkConnection( OPENLDAP_HOST, OPENLDAP_PORT );
+            LdifReader ldifReader = new LdifReader( TestFixture.class.getResourceAsStream( "OpenLdapConfig.ldif" ) ) )
+        {
+            connection.bind( OPENLDAP_CONFIG_DN, OPENLDAP_CONFIG_PASSWORD );
+            for ( LdifEntry entry : ldifReader )
+            {
+                for ( Modification modification : entry.getModifications() )
+                {
+                    connection.modify( entry.getDn(), modification );
+                }
+            }
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( "Unexpected exception: " + e, e );
+        }
+    }
+
+}
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/SkipTestIfLdapServerIsNotAvailableInterceptor.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/SkipTestIfLdapServerIsNotAvailableInterceptor.java
new file mode 100644
index 0000000..95fe2f9
--- /dev/null
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/SkipTestIfLdapServerIsNotAvailableInterceptor.java
@@ -0,0 +1,53 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.directory.studio.test.integration.junit5;
+
+
+import java.lang.reflect.Method;
+
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.InvocationInterceptor;
+import org.junit.jupiter.api.extension.ReflectiveInvocationContext;
+
+
+public class SkipTestIfLdapServerIsNotAvailableInterceptor implements InvocationInterceptor
+{
+
+    @Override
+    public void interceptTestTemplateMethod( Invocation<Void> invocation,
+        ReflectiveInvocationContext<Method> invocationContext, ExtensionContext extensionContext ) throws Throwable
+    {
+        invocationContext.getArguments().stream()
+            .filter( TestLdapServer.class::isInstance )
+            .map( TestLdapServer.class::cast )
+            .forEach( server -> {
+                if ( !server.isAvailable() )
+                {
+                    invocation.skip();
+                    Assumptions.assumeTrue( false,
+                        "Skip test because server " + server.getType() + " is not available" );
+                }
+            } );
+        invocation.proceed();
+    }
+
+}
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestFixture.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestFixture.java
new file mode 100644
index 0000000..44ed782
--- /dev/null
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestFixture.java
@@ -0,0 +1,198 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.directory.studio.test.integration.junit5;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.ldif.LdifEntry;
+import org.apache.directory.api.ldap.model.ldif.LdifReader;
+import org.apache.directory.api.ldap.model.message.Control;
+import org.apache.directory.api.ldap.model.message.DeleteRequest;
+import org.apache.directory.api.ldap.model.message.DeleteRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.ldap.model.schema.comparators.DnComparator;
+import org.apache.directory.ldap.client.api.EntryCursorImpl;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.studio.connection.core.Controls;
+
+
+/**
+ * A unified test fixture that defines the DIT structure for all tests and for all test LDAP servers.
+ */
+public class TestFixture
+{
+
+    public static final String OBJECT_CLASS_ALL_FILTER = "(objectClass=*)";
+
+    public static final String TEST_FIXTURE_LDIF = "TestFixture.ldif";
+
+    public static final String CONTEXT_DN = "dc=example,dc=org";
+
+    public static final String MISC_OU_DN = "ou=misc," + CONTEXT_DN;
+
+    public static final String USERS_OU_DN = "ou=users," + CONTEXT_DN;
+
+    public static final String REFERRALS_OU_DN = "ou=referrals," + CONTEXT_DN;
+
+    /**
+     * Creates the context entry "dc=example,dc=org" if it doesn't exist yet.
+     */
+    public static void createContextEntry( TestLdapServer ldapServer )
+    {
+        ldapServer.withAdminConnection( connection -> {
+            if ( !connection.exists( CONTEXT_DN ) )
+            {
+                connection.add(
+                    new DefaultEntry( CONTEXT_DN, "objectClass", "top", "objectClass", "domain", "dc", "example" ) );
+            }
+        } );
+    }
+
+
+    public static void importData( TestLdapServer ldapServer )
+    {
+        ldapServer.withAdminConnection( connection -> {
+            try ( LdifReader ldifReader = new LdifReader( TestFixture.class.getResourceAsStream( TEST_FIXTURE_LDIF ) ) )
+            {
+                for ( LdifEntry entry : ldifReader )
+                {
+                    connection.add( entry.getEntry() );
+                }
+            }
+        } );
+    }
+
+
+    public static void importReferrals( TestLdapServer ldapServer )
+    {
+        ldapServer.withAdminConnection( connection -> {
+            connection.bind( ldapServer.getAdminDn(), ldapServer.getAdminPassword() );
+
+            // create referral entries
+            Entry referralsOu = new DefaultEntry( connection.getSchemaManager() );
+            referralsOu.setDn( new Dn( REFERRALS_OU_DN ) );
+            referralsOu.add( "objectClass", "top", "organizationalUnit" );
+            referralsOu.add( "ou", "referrals" );
+            connection.add( referralsOu );
+
+            // direct referral
+            Entry r1 = new DefaultEntry( connection.getSchemaManager() );
+            r1.setDn( new Dn( "cn=referral1", REFERRALS_OU_DN ) );
+            r1.add( "objectClass", "top", "referral", "extensibleObject" );
+            r1.add( "cn", "referral1" );
+            r1.add( "ref", ldapServer.getLdapUrl() + "/" + TestFixture.USERS_OU_DN );
+            connection.add( r1 );
+
+            // referral via another immediate referral
+            Entry r2 = new DefaultEntry( connection.getSchemaManager() );
+            r2.setDn( new Dn( "cn=referral2", REFERRALS_OU_DN ) );
+            r2.add( "objectClass", "top", "referral", "extensibleObject" );
+            r2.add( "cn", "referral2" );
+            r2.add( "ref", ldapServer.getLdapUrl() + "/" + r1.getDn().getName() );
+            connection.add( r2 );
+
+            // referral to parent which contains this referral
+            Entry r3 = new DefaultEntry( connection.getSchemaManager() );
+            r3.setDn( new Dn( "cn=referral3", REFERRALS_OU_DN ) );
+            r3.add( "objectClass", "top", "referral", "extensibleObject" );
+            r3.add( "cn", "referral3" );
+            r3.add( "ref", ldapServer.getLdapUrl() + "/" + REFERRALS_OU_DN );
+            connection.add( r3 );
+
+            // referrals pointing to each other (loop)
+            Entry r4a = new DefaultEntry( connection.getSchemaManager() );
+            r4a.setDn( new Dn( "cn=referral4a", REFERRALS_OU_DN ) );
+            r4a.add( "objectClass", "top", "referral", "extensibleObject" );
+            r4a.add( "cn", "referral4a" );
+            r4a.add( "ref", ldapServer.getLdapUrl() + "/cn=referral4b," + REFERRALS_OU_DN );
+            connection.add( r4a );
+            Entry r4b = new DefaultEntry( connection.getSchemaManager() );
+            r4b.setDn( new Dn( "cn=referral4b", REFERRALS_OU_DN ) );
+            r4b.add( "objectClass", "top", "referral", "extensibleObject" );
+            r4b.add( "cn", "referral4b" );
+            r4b.add( "ref", ldapServer.getLdapUrl() + "/cn=referral4a," + REFERRALS_OU_DN );
+            connection.add( r4b );
+        } );
+    }
+
+
+    /**
+     * Cleans all test data.
+     */
+    public static void cleanup( TestLdapServer ldapServer )
+    {
+        ldapServer.withAdminConnection( connection -> {
+            // skip cleanup if context entry doesn't exist yet
+            if ( !connection.exists( CONTEXT_DN ) )
+            {
+                return;
+            }
+
+            // delete ou=referrals
+            deleteTree( connection, REFERRALS_OU_DN, Optional.of( Controls.MANAGEDSAIT_CONTROL ) );
+            // delete ou=users
+            deleteTree( connection, USERS_OU_DN, Optional.empty() );
+            // delete ou=misc
+            deleteTree( connection, MISC_OU_DN, Optional.empty() );
+        } );
+
+    }
+
+
+    private static void deleteTree( LdapConnection connection, String baseDn, Optional<Control> control )
+        throws Exception
+    {
+        SearchRequest searchRequest = new SearchRequestImpl();
+        searchRequest.setBase( new Dn( baseDn ) );
+        searchRequest.setFilter( OBJECT_CLASS_ALL_FILTER );
+        searchRequest.setScope( SearchScope.SUBTREE );
+        control.ifPresent( c -> searchRequest.addControl( c ) );
+
+        try ( SearchCursor searchCursor = connection.search( searchRequest );
+            EntryCursor entryCursor = new EntryCursorImpl( searchCursor ) )
+        {
+            List<Dn> dns = new ArrayList<>();
+            for ( Entry entry : entryCursor )
+            {
+                dns.add( entry.getDn() );
+            }
+            dns.sort( new DnComparator( "1.1" ) );
+            for ( Dn dn : dns )
+            {
+                DeleteRequest deleteRequest = new DeleteRequestImpl();
+                deleteRequest.setName( dn );
+                control.ifPresent( c -> deleteRequest.addControl( c ) );
+                connection.delete( deleteRequest );
+            }
+        }
+    }
+
+}
diff --git a/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestLdapServer.java b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestLdapServer.java
new file mode 100644
index 0000000..945fa19
--- /dev/null
+++ b/tests/test.integration.core/src/main/java/org/apache/directory/studio/test/integration/junit5/TestLdapServer.java
@@ -0,0 +1,172 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.apache.directory.studio.test.integration.junit5;
+
+
+import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.ldap.client.api.exception.InvalidConnectionException;
+
+
+/**
+ * An abstraction around an LDAP server that can be used for testing.
+ * Provides the LDAP server type and connection parameters.
+ */
+public abstract class TestLdapServer
+{
+    public static String getEnvOrDefault( String key, String defaultValue )
+    {
+        return System.getenv().getOrDefault( key, defaultValue );
+    }
+
+    protected final LdapServerType type;
+    protected final String host;
+    protected final int port;
+    protected final String adminDn;
+    protected final String adminPassword;
+
+    protected TestLdapServer( LdapServerType type, String host, int port, String adminDn, String adminPassword )
+    {
+        this.type = type;
+        this.host = host;
+        this.port = port;
+        this.adminDn = adminDn;
+        this.adminPassword = adminPassword;
+    }
+
+
+    public boolean isAvailable()
+    {
+        try ( LdapConnection connection = openAdminConnection() )
+        {
+        }
+        catch ( InvalidConnectionException e )
+        {
+            return false;
+        }
+        catch ( LdapAuthenticationException e )
+        {
+            return false;
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( "Unexpected exception: " + e, e );
+        }
+        return true;
+    }
+
+
+    public LdapConnection openAdminConnection() throws LdapException
+    {
+        LdapConnection connection = new LdapNetworkConnection( host, port );
+        connection.connect();
+        connection.bind( adminDn, adminPassword );
+        return connection;
+    }
+
+
+    public void withAdminConnection( LdapConnectionConsumer consumer )
+    {
+        try ( LdapConnection connection = openAdminConnection() )
+        {
+            consumer.accept( connection );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( "Unexpected exception: " + e, e );
+        }
+    }
+
+    public static interface LdapConnectionConsumer
+    {
+        void accept( LdapConnection connection ) throws Exception;
+    }
+
+    public <T> T withAdminConnectionAndGet( LdapConnectionFunction<T> function )
+    {
+        try ( LdapConnection connection = openAdminConnection() )
+        {
+            return function.apply( connection );
+        }
+        catch ( Exception e )
+        {
+            throw new RuntimeException( "Unexpected exception: " + e, e );
+        }
+    }
+
+    public static interface LdapConnectionFunction<T>
+    {
+        T apply( LdapConnection connection ) throws Exception;
+    }
+
+    public void prepare()
+    {
+        TestFixture.createContextEntry( this );
+        TestFixture.cleanup( this );
+        TestFixture.importData( this );
+        TestFixture.importReferrals( this );
+    }
+
+
+    public LdapServerType getType()
+    {
+        return type;
+    }
+
+
+    public String getHost()
+    {
+        return host;
+    }
+
+
+    public int getPort()
+    {
+        return port;
+    }
+
+
+    public String getLdapUrl()
+    {
+        return "ldap://" + host + ":" + port;
+    }
+
+
+    public String getAdminDn()
+    {
+        return adminDn;
+    }
+
+
+    public String getAdminPassword()
+    {
+        return adminPassword;
+    }
+
+
+    @Override
+    public String toString()
+    {
+        return type.name();
+    }
+}
diff --git a/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/OpenLdapConfig.ldif b/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/OpenLdapConfig.ldif
new file mode 100644
index 0000000..f28f338
--- /dev/null
+++ b/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/OpenLdapConfig.ldif
@@ -0,0 +1,25 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you 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.
+#
+dn: olcDatabase={-1}frontend,cn=config
+changetype: modify
+replace: olcAccess
+olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external
+ ,cn=auth manage by * break
+olcAccess: {1}to dn.exact="" by * read
+olcAccess: {2}to dn.base="cn=Subschema" by dn.exact="uid=user.1,ou=users,dc=example,dc=org" none by * read
+-
diff --git a/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/TestFixture.ldif b/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/TestFixture.ldif
new file mode 100644
index 0000000..7ad9af4
--- /dev/null
+++ b/tests/test.integration.core/src/main/resources/org/apache/directory/studio/test/integration/junit5/TestFixture.ldif
@@ -0,0 +1,250 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you 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.
+#
+
+#
+# ou=misc
+# Entries for specific test scenarios. Other tests should not rely on the number or structure of this ou.
+# Add here new specific entries for specific test scenarios.
+#
+
+dn: ou=misc,dc=example,dc=org
+objectClass: top
+objectClass: organizationalUnit
+ou: users
+
+dn: cn=Barbara Jensen+uid=bjensen,ou=misc,dc=example,dc=org
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+objectClass: top
+cn: Barbara Jensen
+sn: Jensen
+givenName: Barbara
+uid: bjensen
+
+#
+# ou=users
+# Fixed number of users used by severals search tests that expect a fixed entry set.
+# Avoid add or modify those entries if not required as many tests need to be adjusted otherwise.
+#
+
+dn: ou=users,dc=example,dc=org
+objectClass: top
+objectClass: organizationalUnit
+ou: users
+
+dn: uid=user.1,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aaccf
+sn: Amar
+cn: Aaccf Amar
+initials: AA
+uid: user.1
+mail: user.1@null
+userPassword: password
+telephoneNumber: 976-893-3312
+homePhone: 337-310-0727
+pager: 185-156-4071
+mobile: 626-188-0934
+employeeNumber: 1
+street: 27919 Broadway Street
+l: Tallahassee
+st: DE
+postalCode: 67698
+postalAddress: Aaccf Amar$27919 Broadway Street$Tallahassee, DE  67698
+description: This is the description for Aaccf Amar.
+roomNumber: 1388
+
+dn: uid=user.2,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aaren
+sn: Atp
+cn: Aaren Atp
+initials: AA
+uid: user.2
+mail: user.2@null
+userPassword: password
+telephoneNumber: 147-953-0396
+homePhone: 174-439-5329
+pager: 617-443-8449
+mobile: 045-464-2512
+employeeNumber: 2
+street: 36109 Center Street
+l: Harlingen
+st: CO
+postalCode: 21733
+postalAddress: Aaren Atp$36109 Center Street$Harlingen, CO  21733
+description: This is the description for Aaren Atp.
+roomNumber: 1198
+
+dn: uid=user.3,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aarika
+sn: Atpco
+cn: Aarika Atpco
+initials: AA
+uid: user.3
+mail: user.3@null
+userPassword: password
+telephoneNumber: 925-356-4943
+homePhone: 099-983-0308
+pager: 806-672-7363
+mobile: 425-493-8009
+employeeNumber: 3
+street: 14730 Fourteenth Street
+l: Evansville
+st: ND
+postalCode: 95526
+postalAddress: Aarika Atpco$14730 Fourteenth Street$Evansville, ND  95526
+description: This is the description for Aarika Atpco.
+roomNumber: 1135
+
+dn: uid=user.4,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aaron
+sn: Atrc
+cn: Aaron Atrc
+initials: AA
+uid: user.4
+mail: user.4@null
+userPassword: password
+telephoneNumber: 696-981-0488
+homePhone: 854-401-1330
+pager: 389-028-9518
+mobile: 117-882-4912
+employeeNumber: 4
+street: 98495 Fifteenth Street
+l: Miami
+st: PA
+postalCode: 16887
+postalAddress: Aaron Atrc$98495 Fifteenth Street$Miami, PA  16887
+description: This is the description for Aaron Atrc.
+roomNumber: 1311
+
+dn: uid=user.5,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Aartjan
+sn: Aalders
+cn: Aartjan Aalders
+initials: AA
+uid: user.5
+mail: user.5@null
+userPassword: password
+telephoneNumber: 657-627-9753
+homePhone: 109-158-4533
+pager: 801-392-0010
+mobile: 763-973-0947
+employeeNumber: 5
+street: 52408 Ridge Street
+l: Omaha
+st: AR
+postalCode: 08015
+postalAddress: Aartjan Aalders$52408 Ridge Street$Omaha, AR  08015
+description: This is the description for Aartjan Aalders.
+roomNumber: 1090
+
+dn: uid=user.6,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Abagael
+sn: Aasen
+cn: Abagael Aasen
+initials: AA
+uid: user.6
+mail: user.6@null
+userPassword: password
+telephoneNumber: 600-556-9017
+homePhone: 543-731-7797
+pager: 349-743-6572
+mobile: 042-921-9717
+employeeNumber: 6
+street: 87514 Dogwood Street
+l: Bloomington
+st: ID
+postalCode: 56762
+postalAddress: Abagael Aasen$87514 Dogwood Street$Bloomington, ID  56762
+description: This is the description for Abagael Aasen.
+roomNumber: 1449
+
+dn: uid=user.7,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Abagail
+sn: Abadines
+cn: Abagail Abadines
+initials: AA
+uid: user.7
+mail: user.7@null
+userPassword: password
+telephoneNumber: 628-294-0713
+homePhone: 313-764-3970
+pager: 118-541-2978
+mobile: 111-360-9243
+employeeNumber: 7
+street: 60751 Main Street
+l: Macon
+st: MI
+postalCode: 38755
+postalAddress: Abagail Abadines$60751 Main Street$Macon, MI  38755
+description: This is the description for Abagail Abadines.
+roomNumber: 1312
+
+dn: uid=user.8,ou=users,dc=example,dc=org
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+givenName: Abahri
+sn: Abazari
+cn: Abahri Abazari
+initials: AA
+uid: user.8
+mail: user.8@null
+userPassword: password
+telephoneNumber: 760-373-5805
+homePhone: 856-861-3648
+pager: 271-218-0027
+mobile: 957-465-6928
+employeeNumber: 8
+street: 81023 River Street
+l: Monroe
+st: SD
+postalCode: 51865
+postalAddress: Abahri Abazari$81023 River Street$Monroe, SD  51865
+description: This is the description for Abahri Abazari.
+roomNumber: 1963
+
diff --git a/tests/test.integration.ui/pom-first.xml b/tests/test.integration.ui/pom-first.xml
index 9079550..3656cd9 100644
--- a/tests/test.integration.ui/pom-first.xml
+++ b/tests/test.integration.ui/pom-first.xml
@@ -48,11 +48,15 @@
             <Bundle-Activator>org.apache.directory.studio.test.integration.ui.Activator</Bundle-Activator>
             
             <Require-Bundle>org.junit;bundle-version="4.11.0",
+ org.junit.jupiter.api;bundle-version="5.7.0",
+ org.junit.jupiter.params;bundle-version="5.7.0",
+ org.opentest4j;bundle-version="1.2.0",
  org.hamcrest.library;bundle-version="1.3.0",
- org.eclipse.swtbot.eclipse.finder;bundle-version="2.2.1",
- org.eclipse.swtbot.eclipse.core;bundle-version="2.2.1",
- org.eclipse.swtbot.forms.finder;bundle-version="2.2.1",
- org.eclipse.swtbot.junit4_x;bundle-version="2.2.1",
+ org.eclipse.swtbot.eclipse.finder;bundle-version="3.0.0",
+ org.eclipse.swtbot.eclipse.core;bundle-version="3.0.0",
+ org.eclipse.swtbot.forms.finder;bundle-version="3.0.0",
+ org.eclipse.swtbot.junit4_x;bundle-version="3.0.0",
+ org.eclipse.swtbot.junit5_x;bundle-version="3.0.0",
  
  org.apache.directory.server.apacheds-test-framework;bundle-version="${org.apache.directory.server.version}",
  org.apache.directory.server.annotations;bundle-version="${org.apache.directory.server.version}",
@@ -100,6 +104,7 @@
  org.apache.directory.studio.schemaeditor,
  org.apache.directory.studio.schemaeditor.help,
  org.apache.directory.studio.valueeditors,
+ org.apache.directory.studio.test.integration.core,
  org.eclipse.core.runtime,
  org.eclipse.e4.ui.css.swt.theme,
  org.eclipse.ui</Require-Bundle>
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/Fedora389dsTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/Fedora389dsTest.java
index 7c3b488..7324714 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/Fedora389dsTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/Fedora389dsTest.java
@@ -56,6 +56,7 @@ import org.junit.After;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -69,6 +70,7 @@ import org.junit.runner.RunWith;
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
+@Ignore
 @RunWith(FrameworkRunnerWithScreenshotCaptureListener.class)
 public class Fedora389dsTest
 {
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/OpenLdapTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/OpenLdapTest.java
index d5a6af0..f33bf92 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/OpenLdapTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/OpenLdapTest.java
@@ -69,6 +69,7 @@ import org.junit.After;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -82,6 +83,7 @@ import org.junit.runner.RunWith;
  * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  * @version $Rev$, $Date$
  */
+@Ignore
 @RunWith(FrameworkRunnerWithScreenshotCaptureListener.class)
 public class OpenLdapTest
 {
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/PreferencesTest.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/PreferencesTest.java
index cf6c224..ba30500 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/PreferencesTest.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/PreferencesTest.java
@@ -28,16 +28,17 @@ import static org.junit.Assert.assertTrue;
 import java.io.File;
 import java.net.URL;
 import java.nio.charset.StandardCharsets;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
 import java.security.cert.X509Certificate;
+import java.util.Date;
 import java.util.List;
 
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
 import org.apache.directory.api.util.FileUtils;
 import org.apache.directory.server.annotations.CreateLdapServer;
 import org.apache.directory.server.annotations.CreateTransport;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
-import org.apache.directory.server.core.security.CertificateUtil;
+import org.apache.directory.server.core.security.TlsKeyGenerator;
 import org.apache.directory.studio.connection.core.Connection;
 import org.apache.directory.studio.connection.core.ConnectionCorePlugin;
 import org.apache.directory.studio.connection.core.PasswordsKeyStoreManager;
@@ -58,8 +59,6 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import sun.security.x509.X500Name;
-
 
 /**
  * Tests the preferences.
@@ -157,11 +156,15 @@ public class PreferencesTest extends AbstractLdapTestUnit
         preferencesBot.clickCancelButton();
 
         // add a certificate (not possible via native file dialog)
-        X500Name issuer = new X500Name( "apacheds", "directory", "apache", "US" );
-        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( "EC" );
-        keyPairGenerator.initialize( 256 );
-        KeyPair keyPair = keyPairGenerator.generateKeyPair();
-        X509Certificate certificate = CertificateUtil.generateSelfSignedCertificate( issuer, keyPair, 365, "SHA256WithECDSA" );
+        Entry entry = new DefaultEntry();
+        String issuerDn = "cn=apacheds,ou=directory,o=apache,c=US";
+        Date startDate = new Date();
+        Date expiryDate = new Date( System.currentTimeMillis() + TlsKeyGenerator.YEAR_MILLIS );
+        String keyAlgo = "RSA";
+        int keySize = 1024;
+        CertificateValidationTest.addKeyPair( entry, issuerDn, issuerDn, startDate, expiryDate, keyAlgo, keySize,
+            null );
+        X509Certificate certificate = TlsKeyGenerator.getCertificate( entry );
         ConnectionCorePlugin.getDefault().getPermanentTrustStoreManager().addCertificate( certificate );
 
         // verify there is one certificate now
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ConnectionsViewBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ConnectionsViewBot.java
index 1a7b2c9..ac5d679 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ConnectionsViewBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/ConnectionsViewBot.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.directory.studio.connection.core.Connection;
 import org.apache.directory.studio.connection.core.ConnectionCorePlugin;
 import org.apache.directory.studio.connection.core.ConnectionFolder;
@@ -39,6 +40,7 @@ import org.apache.directory.studio.connection.core.jobs.OpenConnectionsRunnable;
 import org.apache.directory.studio.connection.core.jobs.StudioConnectionJob;
 import org.apache.directory.studio.test.integration.ui.ContextMenuHelper;
 import org.apache.directory.studio.test.integration.ui.bots.utils.JobWatcher;
+import org.apache.directory.studio.test.integration.junit5.TestLdapServer;
 import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
 import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
 import org.eclipse.swtbot.swt.finder.utils.TableCollection;
@@ -213,6 +215,14 @@ public class ConnectionsViewBot
     }
 
 
+    public Connection createTestConnection( TestLdapServer server ) throws Exception
+    {
+        return createTestConnection( server.getType() + "_" + RandomStringUtils.randomAscii( 10 ), server.getHost(),
+            server.getPort(), server.getAdminDn(),
+            server.getAdminPassword() );
+    }
+
+
     /**
      * Creates the test connection.
      *
diff --git a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/StudioBot.java b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/StudioBot.java
index 341afbe..f781dab 100644
--- a/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/StudioBot.java
+++ b/tests/test.integration.ui/src/main/java/org/apache/directory/studio/test/integration/ui/bots/StudioBot.java
@@ -203,11 +203,8 @@ public class StudioBot
                     }
 
                     // reset LDAP perspective
-                    if ( page.getActivePart() != null )
-                    {
-                        page.closeAllEditors( false );
-                        page.resetPerspective();
-                    }
+                    page.closeAllEditors( false );
+                    page.resetPerspective();
                 }
                 catch ( Exception e )
                 {