From 1d281bc2df51fba823f65dfd48ea9e1aa5e40458 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Tue, 1 Dec 2015 15:33:09 -0500
Subject: [PATCH] Ticket 48358 - Prepare lib389 for Fedora Packaging

Description:  Created spec file, and updated setup.py/setup.cfg.  Also
              restructured the code layout to all be under /lib389

https://fedorahosted.org/389/ticket/48358

Reviewed by: ?
---
 VERSION                                          |   2 +-
 clitools/__init__.py                             |  58 ---
 clitools/ds_list_instances.py                    |  25 --
 clitools/ds_monitor_backend.py                   |  37 --
 clitools/ds_monitor_server.py                    |  33 --
 clitools/ds_schema_attributetype_list.py         |  33 --
 clitools/ds_schema_attributetype_query.py        |  44 ---
 clitools/ds_start.py                             |  34 --
 clitools/ds_stop.py                              |  34 --
 clitools/krb_create_keytab.py                    |  40 --
 clitools/krb_create_principal.py                 |  38 --
 clitools/krb_create_realm.py                     |  34 --
 clitools/krb_destroy_realm.py                    |  34 --
 lib389.spec                                      |  48 +++
 lib389/clitools/__init__.py                      |  58 +++
 lib389/clitools/ds_list_instances.py             |  25 ++
 lib389/clitools/ds_monitor_backend.py            |  37 ++
 lib389/clitools/ds_monitor_server.py             |  33 ++
 lib389/clitools/ds_schema_attributetype_list.py  |  33 ++
 lib389/clitools/ds_schema_attributetype_query.py |  44 +++
 lib389/clitools/ds_start.py                      |  34 ++
 lib389/clitools/ds_stop.py                       |  34 ++
 lib389/clitools/krb_create_keytab.py             |  40 ++
 lib389/clitools/krb_create_principal.py          |  38 ++
 lib389/clitools/krb_create_realm.py              |  34 ++
 lib389/clitools/krb_destroy_realm.py             |  34 ++
 lib389/tests/__init__.py                         |   7 +
 lib389/tests/aci_parse_test.py                   |  98 +++++
 lib389/tests/agreement_test.py                   | 322 ++++++++++++++++
 lib389/tests/backend_test.py                     | 278 ++++++++++++++
 lib389/tests/config.py                           |  40 ++
 lib389/tests/config_test.py                      |  87 +++++
 lib389/tests/conftest.py                         | 116 ++++++
 lib389/tests/dereference_test.py                 |  99 +++++
 lib389/tests/dirsrv_test.py                      | 223 +++++++++++
 lib389/tests/dsadmin_basic_test.py               | 126 +++++++
 lib389/tests/dsadmin_create_remove_test.py       |  97 +++++
 lib389/tests/dsadmin_test.py                     | 263 +++++++++++++
 lib389/tests/effective_rights_test.py            |  93 +++++
 lib389/tests/entry_test.py                       |  98 +++++
 lib389/tests/krb5_create_test.py                 |  99 +++++
 lib389/tests/mappingTree_test.py                 | 271 +++++++++++++
 lib389/tests/replica_test.py                     | 459 +++++++++++++++++++++++
 lib389/tests/schema_test.py                      |  61 +++
 lib389/tests/suffix_test.py                      | 102 +++++
 lib389/tests/test_module_proxy.py                |  79 ++++
 lib389/tests/utils_test.py                       | 132 +++++++
 setup.cfg                                        |   2 +-
 setup.py                                         |   8 +-
 tests/__init__.py                                |   7 -
 tests/aci_parse_test.py                          |  98 -----
 tests/agreement_test.py                          | 322 ----------------
 tests/backend_test.py                            | 278 --------------
 tests/config.py                                  |  40 --
 tests/config_test.py                             |  87 -----
 tests/conftest.py                                | 116 ------
 tests/dereference_test.py                        |  99 -----
 tests/dirsrv_test.py                             | 223 -----------
 tests/dsadmin_basic_test.py                      | 126 -------
 tests/dsadmin_create_remove_test.py              |  97 -----
 tests/dsadmin_test.py                            | 263 -------------
 tests/effective_rights_test.py                   |  93 -----
 tests/entry_test.py                              |  98 -----
 tests/krb5_create_test.py                        |  99 -----
 tests/mappingTree_test.py                        | 271 -------------
 tests/replica_test.py                            | 459 -----------------------
 tests/schema_test.py                             |  61 ---
 tests/suffix_test.py                             | 102 -----
 tests/test_module_proxy.py                       |  79 ----
 tests/utils_test.py                              | 132 -------
 70 files changed, 3648 insertions(+), 3600 deletions(-)
 delete mode 100644 clitools/__init__.py
 delete mode 100644 clitools/ds_list_instances.py
 delete mode 100644 clitools/ds_monitor_backend.py
 delete mode 100644 clitools/ds_monitor_server.py
 delete mode 100644 clitools/ds_schema_attributetype_list.py
 delete mode 100644 clitools/ds_schema_attributetype_query.py
 delete mode 100644 clitools/ds_start.py
 delete mode 100644 clitools/ds_stop.py
 delete mode 100644 clitools/krb_create_keytab.py
 delete mode 100644 clitools/krb_create_principal.py
 delete mode 100644 clitools/krb_create_realm.py
 delete mode 100644 clitools/krb_destroy_realm.py
 create mode 100644 lib389.spec
 create mode 100644 lib389/clitools/__init__.py
 create mode 100644 lib389/clitools/ds_list_instances.py
 create mode 100644 lib389/clitools/ds_monitor_backend.py
 create mode 100644 lib389/clitools/ds_monitor_server.py
 create mode 100644 lib389/clitools/ds_schema_attributetype_list.py
 create mode 100644 lib389/clitools/ds_schema_attributetype_query.py
 create mode 100644 lib389/clitools/ds_start.py
 create mode 100644 lib389/clitools/ds_stop.py
 create mode 100644 lib389/clitools/krb_create_keytab.py
 create mode 100644 lib389/clitools/krb_create_principal.py
 create mode 100644 lib389/clitools/krb_create_realm.py
 create mode 100644 lib389/clitools/krb_destroy_realm.py
 create mode 100644 lib389/tests/__init__.py
 create mode 100644 lib389/tests/aci_parse_test.py
 create mode 100644 lib389/tests/agreement_test.py
 create mode 100644 lib389/tests/backend_test.py
 create mode 100644 lib389/tests/config.py
 create mode 100644 lib389/tests/config_test.py
 create mode 100644 lib389/tests/conftest.py
 create mode 100644 lib389/tests/dereference_test.py
 create mode 100644 lib389/tests/dirsrv_test.py
 create mode 100644 lib389/tests/dsadmin_basic_test.py
 create mode 100644 lib389/tests/dsadmin_create_remove_test.py
 create mode 100644 lib389/tests/dsadmin_test.py
 create mode 100644 lib389/tests/effective_rights_test.py
 create mode 100644 lib389/tests/entry_test.py
 create mode 100644 lib389/tests/krb5_create_test.py
 create mode 100644 lib389/tests/mappingTree_test.py
 create mode 100644 lib389/tests/replica_test.py
 create mode 100644 lib389/tests/schema_test.py
 create mode 100644 lib389/tests/suffix_test.py
 create mode 100644 lib389/tests/test_module_proxy.py
 create mode 100644 lib389/tests/utils_test.py
 delete mode 100644 tests/__init__.py
 delete mode 100644 tests/aci_parse_test.py
 delete mode 100644 tests/agreement_test.py
 delete mode 100644 tests/backend_test.py
 delete mode 100644 tests/config.py
 delete mode 100644 tests/config_test.py
 delete mode 100644 tests/conftest.py
 delete mode 100644 tests/dereference_test.py
 delete mode 100644 tests/dirsrv_test.py
 delete mode 100644 tests/dsadmin_basic_test.py
 delete mode 100644 tests/dsadmin_create_remove_test.py
 delete mode 100644 tests/dsadmin_test.py
 delete mode 100644 tests/effective_rights_test.py
 delete mode 100644 tests/entry_test.py
 delete mode 100644 tests/krb5_create_test.py
 delete mode 100644 tests/mappingTree_test.py
 delete mode 100644 tests/replica_test.py
 delete mode 100644 tests/schema_test.py
 delete mode 100644 tests/suffix_test.py
 delete mode 100644 tests/test_module_proxy.py
 delete mode 100644 tests/utils_test.py

diff --git a/VERSION b/VERSION
index 5bc4571..658aed9 100644
--- a/VERSION
+++ b/VERSION
@@ -1,2 +1,2 @@
-1.0.0
+1.0.1
 
diff --git a/clitools/__init__.py b/clitools/__init__.py
deleted file mode 100644
index c9ed790..0000000
--- a/clitools/__init__.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-# Probably need some helpers for argparse and instance selection
-
-from argparse import ArgumentParser
-from getpass import getpass
-from lib389 import DirSrv
-from lib389._constants import *
-
-
-class CliTool(object):
-    def __init__(self, args=None):
-        self.ds = DirSrv()
-        if args is not None:
-            self.args = args
-
-    def populate_instance_dict(self, instance):
-        insts = self.ds.list(serverid=instance)
-        if len(insts) != 1:
-            # Raise an exception here?
-            self.inst = None
-        else:
-            self.inst = insts[0]
-
-    def get_rootdn_pass(self):
-        # There is a dict get key thing somewhere ...
-        if self.inst.get(SER_ROOT_PW, None) is None:
-            prompt_txt = ('Enter password for %s on instance %s: ' %
-                          (self.inst[SER_ROOT_DN],
-                           self.inst[SER_SERVERID_PROP]))
-            self.inst[SER_ROOT_PW] = getpass(prompt_txt)
-        return
-
-    def connect(self):
-        self.get_rootdn_pass()
-        self.ds.allocate(self.inst)
-        self.ds.open()
-
-    def disconnect(self):
-        # Is there a ds unbind / disconnect?
-        self.ds.close()
-
-
-def _clitools_parser():
-    parser = ArgumentParser(add_help=False)
-    parser.add_argument('--instance',
-                        '-i',
-                        help='The name of the DS instance to connect to and ' +
-                             'work upon.')
-    return parser
-
-clitools_parser = _clitools_parser()
diff --git a/clitools/ds_list_instances.py b/clitools/ds_list_instances.py
deleted file mode 100644
index 433edbe..0000000
--- a/clitools/ds_list_instances.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-from lib389._constants import *
-from clitools import CliTool
-
-
-class ListTool(CliTool):
-    def list_instances(self):
-        # Remember, the prefix can be set with the os environment
-        instances = self.ds.list(all=True)
-        print('Instances on this system:')
-        for instance in instances:
-            print(instance[CONF_SERVER_ID])
-
-if __name__ == '__main__':
-    listtool = ListTool()
-    listtool.list_instances()
diff --git a/clitools/ds_monitor_backend.py b/clitools/ds_monitor_backend.py
deleted file mode 100644
index c1e40df..0000000
--- a/clitools/ds_monitor_backend.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
-from clitools import CliTool, clitools_parser
-# from lib389 import DirSrv
-from lib389._constants import *
-from argparse import ArgumentParser
-
-
-class MonitorTool(CliTool):
-    def monitor_backend_list(self):
-        try:
-            self.populate_instance_dict(self.args.instance)
-            self.connect()
-            # This is pretty rough, it just dumps the objects
-            for monitor in self.ds.monitor.backend(self.args.backend):
-                print(monitor)
-        finally:
-            self.disconnect()
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    parser = ArgumentParser(parents=[clitools_parser])
-    parser.add_argument('--backend', '-b', help='The name of the backend to ' +
-                        ' retrieve monitoring information for.', required=True)
-    args = parser.parse_args()
-    monitortool = MonitorTool(args)
-    monitortool.monitor_backend_list()
diff --git a/clitools/ds_monitor_server.py b/clitools/ds_monitor_server.py
deleted file mode 100644
index 544a033..0000000
--- a/clitools/ds_monitor_server.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
-from clitools import CliTool, clitools_parser
-# from lib389 import DirSrv
-from lib389._constants import *
-
-
-class MonitorTool(CliTool):
-    def monitor_server_list(self):
-        try:
-            self.populate_instance_dict(self.args.instance)
-            self.connect()
-            # This is pretty rough, it just dumps the objects
-            for monitor in self.ds.monitor.server():
-                print(monitor)
-        finally:
-            self.disconnect()
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    args = clitools_parser.parse_args()
-    monitortool = MonitorTool(args)
-    monitortool.monitor_server_list()
diff --git a/clitools/ds_schema_attributetype_list.py b/clitools/ds_schema_attributetype_list.py
deleted file mode 100644
index 5bd6d7d..0000000
--- a/clitools/ds_schema_attributetype_list.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
-from clitools import CliTool, clitools_parser
-# from lib389 import DirSrv
-from lib389._constants import *
-import ldap
-
-
-class SchemaTool(CliTool):
-    def schema_attributetype_list(self):
-        try:
-            self.populate_instance_dict(self.args.instance)
-            self.connect()
-            for attributetype in self.ds.schema.get_attributetypes():
-                print(attributetype)
-        finally:
-            self.disconnect()
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    args = clitools_parser.parse_args()
-    schematool = SchemaTool(args)
-    schematool.schema_attributetype_list()
diff --git a/clitools/ds_schema_attributetype_query.py b/clitools/ds_schema_attributetype_query.py
deleted file mode 100644
index 5b4ad62..0000000
--- a/clitools/ds_schema_attributetype_query.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-from clitools import CliTool, clitools_parser
-from lib389._constants import *
-import ldap
-from argparse import ArgumentParser
-
-
-class SchemaTool(CliTool):
-    def schema_attributetype_query(self):
-        try:
-            self.populate_instance_dict(self.args.instance)
-            self.connect()
-            attributetype, must, may = \
-                self.ds.schema.query_attributetype(self.args.attributetype)
-            print(attributetype)
-            print('MUST')
-            for objectclass in must:
-                print(objectclass)
-            print('MAY')
-            for objectclass in may:
-                print(objectclass)
-        finally:
-            self.disconnect()
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    parser = ArgumentParser(parents=[clitools_parser])
-    parser.add_argument('--attributetype',
-                        '-a',
-                        help='The name of the attribute type to query',
-                        required=True)
-    args = parser.parse_args()
-    schematool = SchemaTool(args)
-    schematool.schema_attributetype_query()
diff --git a/clitools/ds_start.py b/clitools/ds_start.py
deleted file mode 100644
index a4927cc..0000000
--- a/clitools/ds_start.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
-from clitools import CliTool, clitools_parser
-# from lib389 import DirSrv
-from lib389._constants import *
-from lib389.tools import DirSrvTools
-
-
-class StartTool(CliTool):
-    def start(self):
-        try:
-            self.populate_instance_dict(self.args.instance)
-            self.ds.allocate(self.inst)
-
-            DirSrvTools.serverCmd(self.ds, "start", True)
-        finally:
-            pass
-            # self.disconnect()
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    args = clitools_parser.parse_args()
-    tool = StartTool(args)
-    tool.start()
diff --git a/clitools/ds_stop.py b/clitools/ds_stop.py
deleted file mode 100644
index e3eb37f..0000000
--- a/clitools/ds_stop.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
-from clitools import CliTool, clitools_parser
-# from lib389 import DirSrv
-from lib389._constants import *
-from lib389.tools import DirSrvTools
-
-
-class StartTool(CliTool):
-    def start(self):
-        try:
-            self.populate_instance_dict(self.args.instance)
-            self.ds.allocate(self.inst)
-
-            DirSrvTools.serverCmd(self.ds, "stop", True)
-        finally:
-            pass
-            # self.disconnect()
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    args = clitools_parser.parse_args()
-    tool = StartTool(args)
-    tool.start()
diff --git a/clitools/krb_create_keytab.py b/clitools/krb_create_keytab.py
deleted file mode 100644
index 4fc1b9f..0000000
--- a/clitools/krb_create_keytab.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-from clitools import CliTool, clitools_parser
-from lib389._constants import *
-from lib389.mit_krb5 import MitKrb5
-from argparse import ArgumentParser
-
-
-class MitKrb5Tool(CliTool):
-    def mit_krb5_realm_create(self):
-        try:
-            krb = MitKrb5(realm=args.realm, warnings=True)
-            krb.create_keytab(principal=args.principal, keytab=args.keytab)
-        finally:
-            pass
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    parser = ArgumentParser(parents=[clitools_parser])
-    parser.add_argument('--realm', '-r',
-                        help='The name of the realm to create',
-                        required=True)
-    parser.add_argument('--principal', '-p',
-                        help='The name of the principal to create',
-                        required=True)
-    parser.add_argument('--keytab', '-k',
-                        help='The path to the keytab to create',
-                        required=True)
-    args = parser.parse_args()
-    mittool = MitKrb5Tool(args)
-    mittool.mit_krb5_realm_create()
diff --git a/clitools/krb_create_principal.py b/clitools/krb_create_principal.py
deleted file mode 100644
index cee295e..0000000
--- a/clitools/krb_create_principal.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-
-from clitools import CliTool, clitools_parser
-from lib389._constants import *
-from lib389.mit_krb5 import MitKrb5
-from argparse import ArgumentParser
-
-
-class MitKrb5Tool(CliTool):
-    def mit_krb5_realm_create(self):
-        try:
-            krb = MitKrb5(realm=args.realm, warnings=True)
-            krb.create_principal(principal=args.principal)
-        finally:
-            pass
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    parser = ArgumentParser(parents=[clitools_parser])
-    parser.add_argument('--realm', '-r',
-                        help='The name of the realm to create',
-                        required=True)
-    parser.add_argument('--principal', '-p',
-                        help='The name of the principal to create',
-                        required=True)
-    args = parser.parse_args()
-    mittool = MitKrb5Tool(args)
-    mittool.mit_krb5_realm_create()
diff --git a/clitools/krb_create_realm.py b/clitools/krb_create_realm.py
deleted file mode 100644
index bf818e1..0000000
--- a/clitools/krb_create_realm.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-from clitools import CliTool, clitools_parser
-from lib389._constants import *
-from lib389.mit_krb5 import MitKrb5
-from argparse import ArgumentParser
-
-
-class MitKrb5Tool(CliTool):
-    def mit_krb5_realm_create(self):
-        try:
-            krb = MitKrb5(realm=args.realm, warnings=True)
-            krb.create_realm()
-        finally:
-            pass
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    parser = ArgumentParser(parents=[clitools_parser])
-    parser.add_argument('--realm', '-r',
-                        help='The name of the realm to create',
-                        required=True)
-    args = parser.parse_args()
-    mittool = MitKrb5Tool(args)
-    mittool.mit_krb5_realm_create()
diff --git a/clitools/krb_destroy_realm.py b/clitools/krb_destroy_realm.py
deleted file mode 100644
index d42d8c5..0000000
--- a/clitools/krb_destroy_realm.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/python
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-from clitools import CliTool, clitools_parser
-from lib389._constants import *
-from lib389.mit_krb5 import MitKrb5
-from argparse import ArgumentParser
-
-
-class MitKrb5Tool(CliTool):
-    def mit_krb5_realm_destroy(self):
-        try:
-            krb = MitKrb5(realm=args.realm, warnings=True)
-            krb.destroy_realm()
-        finally:
-            pass
-
-if __name__ == '__main__':
-    # Do some arg parse stuff
-    # You can always add a child parser here too ...
-    parser = ArgumentParser(parents=[clitools_parser])
-    parser.add_argument('--realm', '-r',
-                        help='The name of the realm to DESTROY',
-                        required=True)
-    args = parser.parse_args()
-    mittool = MitKrb5Tool(args)
-    mittool.mit_krb5_realm_destroy()
diff --git a/lib389.spec b/lib389.spec
new file mode 100644
index 0000000..c63e2d0
--- /dev/null
+++ b/lib389.spec
@@ -0,0 +1,48 @@
+%define name lib389
+%define version 1.0.1
+%define release 1
+
+Summary: A library for accessing, testing, and configuring the 389 Directory Server
+Name: %{name}
+Version: %{version}
+Release: %{release}
+Source0: %{name}-%{version}.tar.gz
+License: GPLv3+
+Group: Development/Libraries
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
+Prefix: %{_prefix}
+BuildArch: noarch
+Vendor: Red Hat Inc. <389-devel@lists.fedoraproject.org>
+Url: http://port389.org/wiki/Upstream_test_framework
+Requires: python-ldap pytest python-krbV
+
+# Currently python-ldap is not python3 compatible, so lib389 only works with 
+# python 2.7
+
+%description
+This repository contains tools and libraries for accessing, testing, and
+configuring the 389 Directory Server.
+
+%prep
+%setup -n %{name}-%{version}
+
+%build
+python setup.py build
+
+%install
+python setup.py install --single-version-externally-managed -O1 --root=$RPM_BUILD_ROOT
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root,-)
+%{python_sitelib}/*
+
+%changelog
+* Tue Dec 1 2015 Mark Reynolds <mreynolds@redhat.com> - 1.0.1-1
+- Initial Fedora Package
+
+
+
+
diff --git a/lib389/clitools/__init__.py b/lib389/clitools/__init__.py
new file mode 100644
index 0000000..c9ed790
--- /dev/null
+++ b/lib389/clitools/__init__.py
@@ -0,0 +1,58 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+# Probably need some helpers for argparse and instance selection
+
+from argparse import ArgumentParser
+from getpass import getpass
+from lib389 import DirSrv
+from lib389._constants import *
+
+
+class CliTool(object):
+    def __init__(self, args=None):
+        self.ds = DirSrv()
+        if args is not None:
+            self.args = args
+
+    def populate_instance_dict(self, instance):
+        insts = self.ds.list(serverid=instance)
+        if len(insts) != 1:
+            # Raise an exception here?
+            self.inst = None
+        else:
+            self.inst = insts[0]
+
+    def get_rootdn_pass(self):
+        # There is a dict get key thing somewhere ...
+        if self.inst.get(SER_ROOT_PW, None) is None:
+            prompt_txt = ('Enter password for %s on instance %s: ' %
+                          (self.inst[SER_ROOT_DN],
+                           self.inst[SER_SERVERID_PROP]))
+            self.inst[SER_ROOT_PW] = getpass(prompt_txt)
+        return
+
+    def connect(self):
+        self.get_rootdn_pass()
+        self.ds.allocate(self.inst)
+        self.ds.open()
+
+    def disconnect(self):
+        # Is there a ds unbind / disconnect?
+        self.ds.close()
+
+
+def _clitools_parser():
+    parser = ArgumentParser(add_help=False)
+    parser.add_argument('--instance',
+                        '-i',
+                        help='The name of the DS instance to connect to and ' +
+                             'work upon.')
+    return parser
+
+clitools_parser = _clitools_parser()
diff --git a/lib389/clitools/ds_list_instances.py b/lib389/clitools/ds_list_instances.py
new file mode 100644
index 0000000..433edbe
--- /dev/null
+++ b/lib389/clitools/ds_list_instances.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+from lib389._constants import *
+from clitools import CliTool
+
+
+class ListTool(CliTool):
+    def list_instances(self):
+        # Remember, the prefix can be set with the os environment
+        instances = self.ds.list(all=True)
+        print('Instances on this system:')
+        for instance in instances:
+            print(instance[CONF_SERVER_ID])
+
+if __name__ == '__main__':
+    listtool = ListTool()
+    listtool.list_instances()
diff --git a/lib389/clitools/ds_monitor_backend.py b/lib389/clitools/ds_monitor_backend.py
new file mode 100644
index 0000000..c1e40df
--- /dev/null
+++ b/lib389/clitools/ds_monitor_backend.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
+from clitools import CliTool, clitools_parser
+# from lib389 import DirSrv
+from lib389._constants import *
+from argparse import ArgumentParser
+
+
+class MonitorTool(CliTool):
+    def monitor_backend_list(self):
+        try:
+            self.populate_instance_dict(self.args.instance)
+            self.connect()
+            # This is pretty rough, it just dumps the objects
+            for monitor in self.ds.monitor.backend(self.args.backend):
+                print(monitor)
+        finally:
+            self.disconnect()
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    parser = ArgumentParser(parents=[clitools_parser])
+    parser.add_argument('--backend', '-b', help='The name of the backend to ' +
+                        ' retrieve monitoring information for.', required=True)
+    args = parser.parse_args()
+    monitortool = MonitorTool(args)
+    monitortool.monitor_backend_list()
diff --git a/lib389/clitools/ds_monitor_server.py b/lib389/clitools/ds_monitor_server.py
new file mode 100644
index 0000000..544a033
--- /dev/null
+++ b/lib389/clitools/ds_monitor_server.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
+from clitools import CliTool, clitools_parser
+# from lib389 import DirSrv
+from lib389._constants import *
+
+
+class MonitorTool(CliTool):
+    def monitor_server_list(self):
+        try:
+            self.populate_instance_dict(self.args.instance)
+            self.connect()
+            # This is pretty rough, it just dumps the objects
+            for monitor in self.ds.monitor.server():
+                print(monitor)
+        finally:
+            self.disconnect()
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    args = clitools_parser.parse_args()
+    monitortool = MonitorTool(args)
+    monitortool.monitor_server_list()
diff --git a/lib389/clitools/ds_schema_attributetype_list.py b/lib389/clitools/ds_schema_attributetype_list.py
new file mode 100644
index 0000000..5bd6d7d
--- /dev/null
+++ b/lib389/clitools/ds_schema_attributetype_list.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
+from clitools import CliTool, clitools_parser
+# from lib389 import DirSrv
+from lib389._constants import *
+import ldap
+
+
+class SchemaTool(CliTool):
+    def schema_attributetype_list(self):
+        try:
+            self.populate_instance_dict(self.args.instance)
+            self.connect()
+            for attributetype in self.ds.schema.get_attributetypes():
+                print(attributetype)
+        finally:
+            self.disconnect()
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    args = clitools_parser.parse_args()
+    schematool = SchemaTool(args)
+    schematool.schema_attributetype_list()
diff --git a/lib389/clitools/ds_schema_attributetype_query.py b/lib389/clitools/ds_schema_attributetype_query.py
new file mode 100644
index 0000000..5b4ad62
--- /dev/null
+++ b/lib389/clitools/ds_schema_attributetype_query.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+from clitools import CliTool, clitools_parser
+from lib389._constants import *
+import ldap
+from argparse import ArgumentParser
+
+
+class SchemaTool(CliTool):
+    def schema_attributetype_query(self):
+        try:
+            self.populate_instance_dict(self.args.instance)
+            self.connect()
+            attributetype, must, may = \
+                self.ds.schema.query_attributetype(self.args.attributetype)
+            print(attributetype)
+            print('MUST')
+            for objectclass in must:
+                print(objectclass)
+            print('MAY')
+            for objectclass in may:
+                print(objectclass)
+        finally:
+            self.disconnect()
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    parser = ArgumentParser(parents=[clitools_parser])
+    parser.add_argument('--attributetype',
+                        '-a',
+                        help='The name of the attribute type to query',
+                        required=True)
+    args = parser.parse_args()
+    schematool = SchemaTool(args)
+    schematool.schema_attributetype_query()
diff --git a/lib389/clitools/ds_start.py b/lib389/clitools/ds_start.py
new file mode 100644
index 0000000..a4927cc
--- /dev/null
+++ b/lib389/clitools/ds_start.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
+from clitools import CliTool, clitools_parser
+# from lib389 import DirSrv
+from lib389._constants import *
+from lib389.tools import DirSrvTools
+
+
+class StartTool(CliTool):
+    def start(self):
+        try:
+            self.populate_instance_dict(self.args.instance)
+            self.ds.allocate(self.inst)
+
+            DirSrvTools.serverCmd(self.ds, "start", True)
+        finally:
+            pass
+            # self.disconnect()
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    args = clitools_parser.parse_args()
+    tool = StartTool(args)
+    tool.start()
diff --git a/lib389/clitools/ds_stop.py b/lib389/clitools/ds_stop.py
new file mode 100644
index 0000000..e3eb37f
--- /dev/null
+++ b/lib389/clitools/ds_stop.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+# from clitools import clitools_parser, get_instance_dict, get_rootdn_pass
+from clitools import CliTool, clitools_parser
+# from lib389 import DirSrv
+from lib389._constants import *
+from lib389.tools import DirSrvTools
+
+
+class StartTool(CliTool):
+    def start(self):
+        try:
+            self.populate_instance_dict(self.args.instance)
+            self.ds.allocate(self.inst)
+
+            DirSrvTools.serverCmd(self.ds, "stop", True)
+        finally:
+            pass
+            # self.disconnect()
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    args = clitools_parser.parse_args()
+    tool = StartTool(args)
+    tool.start()
diff --git a/lib389/clitools/krb_create_keytab.py b/lib389/clitools/krb_create_keytab.py
new file mode 100644
index 0000000..4fc1b9f
--- /dev/null
+++ b/lib389/clitools/krb_create_keytab.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+from clitools import CliTool, clitools_parser
+from lib389._constants import *
+from lib389.mit_krb5 import MitKrb5
+from argparse import ArgumentParser
+
+
+class MitKrb5Tool(CliTool):
+    def mit_krb5_realm_create(self):
+        try:
+            krb = MitKrb5(realm=args.realm, warnings=True)
+            krb.create_keytab(principal=args.principal, keytab=args.keytab)
+        finally:
+            pass
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    parser = ArgumentParser(parents=[clitools_parser])
+    parser.add_argument('--realm', '-r',
+                        help='The name of the realm to create',
+                        required=True)
+    parser.add_argument('--principal', '-p',
+                        help='The name of the principal to create',
+                        required=True)
+    parser.add_argument('--keytab', '-k',
+                        help='The path to the keytab to create',
+                        required=True)
+    args = parser.parse_args()
+    mittool = MitKrb5Tool(args)
+    mittool.mit_krb5_realm_create()
diff --git a/lib389/clitools/krb_create_principal.py b/lib389/clitools/krb_create_principal.py
new file mode 100644
index 0000000..cee295e
--- /dev/null
+++ b/lib389/clitools/krb_create_principal.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+
+from clitools import CliTool, clitools_parser
+from lib389._constants import *
+from lib389.mit_krb5 import MitKrb5
+from argparse import ArgumentParser
+
+
+class MitKrb5Tool(CliTool):
+    def mit_krb5_realm_create(self):
+        try:
+            krb = MitKrb5(realm=args.realm, warnings=True)
+            krb.create_principal(principal=args.principal)
+        finally:
+            pass
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    parser = ArgumentParser(parents=[clitools_parser])
+    parser.add_argument('--realm', '-r',
+                        help='The name of the realm to create',
+                        required=True)
+    parser.add_argument('--principal', '-p',
+                        help='The name of the principal to create',
+                        required=True)
+    args = parser.parse_args()
+    mittool = MitKrb5Tool(args)
+    mittool.mit_krb5_realm_create()
diff --git a/lib389/clitools/krb_create_realm.py b/lib389/clitools/krb_create_realm.py
new file mode 100644
index 0000000..bf818e1
--- /dev/null
+++ b/lib389/clitools/krb_create_realm.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+from clitools import CliTool, clitools_parser
+from lib389._constants import *
+from lib389.mit_krb5 import MitKrb5
+from argparse import ArgumentParser
+
+
+class MitKrb5Tool(CliTool):
+    def mit_krb5_realm_create(self):
+        try:
+            krb = MitKrb5(realm=args.realm, warnings=True)
+            krb.create_realm()
+        finally:
+            pass
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    parser = ArgumentParser(parents=[clitools_parser])
+    parser.add_argument('--realm', '-r',
+                        help='The name of the realm to create',
+                        required=True)
+    args = parser.parse_args()
+    mittool = MitKrb5Tool(args)
+    mittool.mit_krb5_realm_create()
diff --git a/lib389/clitools/krb_destroy_realm.py b/lib389/clitools/krb_destroy_realm.py
new file mode 100644
index 0000000..d42d8c5
--- /dev/null
+++ b/lib389/clitools/krb_destroy_realm.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+from clitools import CliTool, clitools_parser
+from lib389._constants import *
+from lib389.mit_krb5 import MitKrb5
+from argparse import ArgumentParser
+
+
+class MitKrb5Tool(CliTool):
+    def mit_krb5_realm_destroy(self):
+        try:
+            krb = MitKrb5(realm=args.realm, warnings=True)
+            krb.destroy_realm()
+        finally:
+            pass
+
+if __name__ == '__main__':
+    # Do some arg parse stuff
+    # You can always add a child parser here too ...
+    parser = ArgumentParser(parents=[clitools_parser])
+    parser.add_argument('--realm', '-r',
+                        help='The name of the realm to DESTROY',
+                        required=True)
+    args = parser.parse_args()
+    mittool = MitKrb5Tool(args)
+    mittool.mit_krb5_realm_destroy()
diff --git a/lib389/tests/__init__.py b/lib389/tests/__init__.py
new file mode 100644
index 0000000..f5bbefe
--- /dev/null
+++ b/lib389/tests/__init__.py
@@ -0,0 +1,7 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
diff --git a/lib389/tests/aci_parse_test.py b/lib389/tests/aci_parse_test.py
new file mode 100644
index 0000000..5eefcd7
--- /dev/null
+++ b/lib389/tests/aci_parse_test.py
@@ -0,0 +1,98 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+from lib389._constants import *
+from lib389 import DirSrv, Entry
+import pytest
+
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'aciparseds'
+# INSTANCE_PREFIX   = None
+
+
+class TopologyStandalone(object):
+    def __init__(self, standalone):
+        standalone.open()
+        self.standalone = standalone
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    standalone = DirSrv(verbose=False)
+    standalone.log.debug("Instance allocated")
+    args = {SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT,
+            # SER_DEPLOYED_DIR:  INSTANCE_PREFIX,
+            SER_SERVERID_PROP: INSTANCE_SERVERID}
+    standalone.allocate(args)
+    if standalone.exists():
+        standalone.delete()
+    standalone.create()
+    standalone.open()
+
+    def fin():
+        standalone.delete()
+    request.addfinalizer(fin)
+
+    return TopologyStandalone(standalone)
+
+
+@pytest.fixture(scope="module")
+def complex_aci(topology):
+    ACI_TARGET = ('(targetfilter ="(ou=groups)")(targetattr ="uniqueMember '
+                  '|| member")')
+    ACI_ALLOW = ('(version 3.0; acl "Allow test aci";allow (read, search, '
+                 'write)')
+    ACI_SUBJECT = ('(userdn="ldap:///dc=example,dc=com??sub?(ou=engineering)" '
+                   'and userdn="ldap:///dc=example,dc=com??sub?(manager=uid='
+                   'wbrown,ou=managers,dc=example,dc=com) || ldap:///dc=examp'
+                   'le,dc=com??sub?(manager=uid=tbrown,ou=managers,dc=exampl'
+                   'e,dc=com)" );)')
+    ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
+
+    gentry = Entry('cn=testgroup,%s' % DEFAULT_SUFFIX)
+    gentry.setValues('objectclass', 'top', 'extensibleobject')
+    gentry.setValues('cn', 'testgroup')
+    gentry.setValues('aci', ACI_BODY)
+
+    topology.standalone.add_s(gentry)
+
+    return ACI_BODY
+
+
+def test_aci(topology, complex_aci):
+    """Checks content of previously added aci"""
+
+    acis = topology.standalone.aci.list('cn=testgroup,%s' % DEFAULT_SUFFIX)
+    assert len(acis) == 1
+    aci = acis[0]
+    assert aci.acidata == {
+        'allow': [{'values': ['read', 'search', 'write']}],
+        'target': [], 'targetattr': [{'values': ['uniqueMember', 'member'],
+                                      'equal': True}],
+        'targattrfilters': [],
+        'deny': [],
+        'acl': [{'values': ['Allow test aci']}],
+        'deny_raw_bindrules': [],
+        'targetattrfilters': [],
+        'allow_raw_bindrules': [{'values': [(
+            'userdn="ldap:///dc=example,dc=com??sub?(ou=engineering)" and'
+            ' userdn="ldap:///dc=example,dc=com??sub?(manager=uid=wbrown,'
+            'ou=managers,dc=example,dc=com) || ldap:///dc=example,dc=com'
+            '??sub?(manager=uid=tbrown,ou=managers,dc=example,dc=com)" ')]}],
+        'targetfilter': [{'values': ['(ou=groups)'], 'equal': True}],
+        'targetscope': [],
+        'version 3.0;': [],
+        'rawaci': complex_aci
+    }
+    assert aci.getRawAci() == complex_aci
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -vv %s" % CURRENT_FILE)
diff --git a/lib389/tests/agreement_test.py b/lib389/tests/agreement_test.py
new file mode 100644
index 0000000..5b0af12
--- /dev/null
+++ b/lib389/tests/agreement_test.py
@@ -0,0 +1,322 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import ldap
+import time
+import os
+import pytest
+
+from lib389 import NoSuchEntryError
+from lib389.agreement import Agreement
+from lib389._constants import *
+from lib389.properties import *
+from lib389 import DirSrv, Entry
+
+# Used for One master / One consumer topology
+HOST_MASTER = LOCALHOST
+PORT_MASTER = 40389
+SERVERID_MASTER = 'master'
+REPLICAID_MASTER = 1
+
+HOST_CONSUMER = LOCALHOST
+PORT_CONSUMER = 50389
+SERVERID_CONSUMER = 'consumer'
+
+SUFFIX = DEFAULT_SUFFIX
+ENTRY_DN = "cn=test_entry, %s" % SUFFIX
+
+
+class TopologyReplication(object):
+    def __init__(self, master, consumer):
+        master.open()
+        consumer.open()
+        self.master = master
+        self.consumer = consumer
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    # Master
+    #
+    # Create the master instance
+    master = DirSrv(verbose=False)
+    master.log.debug("Master allocated")
+    args = {SER_HOST: HOST_MASTER,
+            SER_PORT: PORT_MASTER,
+            SER_SERVERID_PROP: SERVERID_MASTER}
+    master.allocate(args)
+    if master.exists():
+        master.delete()
+    master.create()
+    master.open()
+
+    # Enable replication
+    master.replica.enableReplication(suffix=SUFFIX,
+                                     role=REPLICAROLE_MASTER,
+                                     replicaId=REPLICAID_MASTER)
+
+    # Consumer
+    #
+    # Create the consumer instance
+    consumer = DirSrv(verbose=False)
+    consumer.log.debug("Consumer allocated")
+    args = {SER_HOST: HOST_CONSUMER,
+            SER_PORT: PORT_CONSUMER,
+            SER_SERVERID_PROP: SERVERID_CONSUMER}
+    consumer.allocate(args)
+    if consumer.exists():
+        consumer.delete()
+    consumer.create()
+    consumer.open()
+
+    # Enable replication
+    consumer.replica.enableReplication(suffix=SUFFIX,
+                                       role=REPLICAROLE_CONSUMER)
+
+    # Delete each instance in the end
+    def fin():
+        master.delete()
+        consumer.delete()
+    request.addfinalizer(fin)
+
+    return TopologyReplication(master, consumer)
+
+
+def test_create(topology):
+    """Test to create a replica agreement and initialize the consumer.
+    Test on a unknown suffix
+    """
+
+    topology.master.log.info("\n\n##############\n## CREATE\n##############\n")
+    properties = {RA_NAME: ('meTo_%s:%d' % (topology.consumer.host,
+                                            topology.consumer.port)),
+                  RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
+                  RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
+                  RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
+                  RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
+    repl_agreement = topology.master.agreement.create(
+        suffix=SUFFIX, host=topology.consumer.host,
+        port=topology.consumer.port, properties=properties)
+    topology.master.log.debug("%s created" % repl_agreement)
+    topology.master.agreement.init(SUFFIX, HOST_CONSUMER, PORT_CONSUMER)
+    topology.master.waitForReplInit(repl_agreement)
+
+    # Add a test entry
+    topology.master.add_s(Entry((ENTRY_DN, {'objectclass':
+                                            "top person".split(),
+                                            'sn': 'test_entry',
+                                            'cn': 'test_entry'})))
+
+    # Check replication is working
+    loop = 0
+    while loop <= 10:
+        try:
+            ent = topology.consumer.getEntry(ENTRY_DN, ldap.SCOPE_BASE,
+                                             "(objectclass=*)")
+            break
+        except ldap.NO_SUCH_OBJECT:
+            time.sleep(1)
+            loop += 1
+    assert loop <= 10
+
+    # Check that with an invalid suffix it raises NoSuchEntryError
+    with pytest.raises(NoSuchEntryError):
+        properties = {RA_NAME: r'meAgainTo_%s:%d' %
+                      (topology.consumer.host, topology.consumer.port)}
+        topology.master.agreement.create(suffix="ou=dummy",
+                                         host=topology.consumer.host,
+                                         port=topology.consumer.port,
+                                         properties=properties)
+
+
+def test_list(topology):
+    """List the replica agreement on a suffix => 1
+    Add a RA
+    List the replica agreements on that suffix again => 2
+    List a specific RA
+
+    PREREQUISITE: it exists a replica for SUFFIX and a replica agreement
+    """
+
+    topology.master.log.info("\n\n###########\n## LIST\n#############\n")
+    ents = topology.master.agreement.list(suffix=SUFFIX)
+    assert len(ents) == 1
+    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_CONSUMER_HOST]) == \
+        topology.consumer.host
+    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_CONSUMER_PORT]) == \
+        str(topology.consumer.port)
+
+    # Create a second RA to check .list returns 2 RA
+    properties = {RA_NAME: r'meTo_%s:%d' % (topology.consumer.host, 12345),
+                  RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
+                  RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
+                  RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
+                  RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
+    topology.master.agreement.create(suffix=SUFFIX,
+                                     host=topology.consumer.host,
+                                     port=12345,
+                                     properties=properties)
+    ents = topology.master.agreement.list(suffix=SUFFIX)
+    assert len(ents) == 2
+
+    # Check we can .list a specific RA
+    ents = topology.master.agreement.list(suffix=SUFFIX,
+                                          consumer_host=topology.consumer.host,
+                                          consumer_port=topology.consumer.port)
+    assert len(ents) == 1
+    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_CONSUMER_HOST]) == \
+        topology.consumer.host
+    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_CONSUMER_PORT]) == \
+        str(topology.consumer.port)
+
+
+def test_status(topology):
+    """Test that status is returned from agreement"""
+
+    topology.master.log.info("\n\n###########\n## STATUS\n##########")
+    ents = topology.master.agreement.list(suffix=SUFFIX)
+    for ent in ents:
+        ra_status = topology.master.agreement.status(ent.dn)
+        assert ra_status
+        topology.master.log.info("Status of %s: %s" % (ent.dn, ra_status))
+
+
+def test_schedule(topology):
+    """Test the schedule behaviour with valid and invalid values"""
+
+    topology.master.log.info("\n\n###########\n## SCHEDULE\n#########")
+    ents = topology.master.agreement.list(suffix=SUFFIX,
+                                          consumer_host=topology.consumer.host,
+                                          consumer_port=topology.consumer.port)
+    assert len(ents) == 1
+
+    topology.master.agreement.schedule(ents[0].dn, Agreement.ALWAYS)
+    ents = topology.master.agreement.list(suffix=SUFFIX,
+                                          consumer_host=topology.consumer.host,
+                                          consumer_port=topology.consumer.port)
+    assert len(ents) == 1
+    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_SCHEDULE]) == \
+        Agreement.ALWAYS
+
+    topology.master.agreement.schedule(ents[0].dn, Agreement.NEVER)
+    ents = topology.master.agreement.list(suffix=SUFFIX,
+                                          consumer_host=topology.consumer.host,
+                                          consumer_port=topology.consumer.port)
+    assert len(ents) == 1
+    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_SCHEDULE]) == \
+        Agreement.NEVER
+
+    CUSTOM_SCHEDULE = "0000-1234 6420"
+    topology.master.agreement.schedule(ents[0].dn, CUSTOM_SCHEDULE)
+    ents = topology.master.agreement.list(suffix=SUFFIX,
+                                          consumer_host=topology.consumer.host,
+                                          consumer_port=topology.consumer.port)
+    assert len(ents) == 1
+    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_SCHEDULE]) == \
+        CUSTOM_SCHEDULE
+
+    CUSTOM_SCHEDULES = ("2500-1234 6420",  # Invalid HOUR schedule
+                        "0000-2534 6420",  # ^^
+                        "1300-1234 6420",  # Starting HOUR after ending HOUR
+                        "0062-1234 6420",  # Invalid MIN schedule
+                        "0000-1362 6420",  # ^^
+                        "0000-1234 6-420",  # Invalid DAYS schedule
+                        "0000-1362 64209",  # ^^
+                        "0000-1362 01234560")  # ^^
+
+    for CUSTOM_SCHEDULE in CUSTOM_SCHEDULES:
+        with pytest.raises(ValueError):
+            topology.master.agreement.schedule(ents[0].dn, CUSTOM_SCHEDULE)
+
+
+def test_getProperties(topology):
+    """Check the correct behaviour of getProperties function"""
+
+    topology.master.log.info("\n\n###########\n## GETPROPERTIES\n############")
+    ents = topology.master.agreement.list(suffix=SUFFIX,
+                                          consumer_host=topology.consumer.host,
+                                          consumer_port=topology.consumer.port)
+    assert len(ents) == 1
+    properties = topology.master.agreement.getProperties(agmnt_dn=ents[0].dn)
+    for prop in properties:
+        topology.master.log.info("RA %s : %s -> %s" %
+                                 (prop, RA_PROPNAME_TO_ATTRNAME[prop],
+                                  properties[prop]))
+
+    properties = topology.master.agreement.getProperties(
+        agmnt_dn=ents[0].dn, properties=[RA_BINDDN])
+    assert len(properties) == 1
+    for prop in properties:
+        topology.master.log.info("RA %s : %s -> %s" %
+                                 (prop, RA_PROPNAME_TO_ATTRNAME[prop],
+                                  properties[prop]))
+
+
+def test_setProperties(topology):
+    """Set properties to the agreement and check, if it was successful"""
+
+    topology.master.log.info("\n\n###########\n### SETPROPERTIES\n##########")
+    ents = topology.master.agreement.list(suffix=SUFFIX,
+                                          consumer_host=topology.consumer.host,
+                                          consumer_port=topology.consumer.port)
+    assert len(ents) == 1
+    test_schedule = "1234-2345 12345"
+    test_desc = "test_desc"
+    topology.master.agreement.setProperties(
+        agmnt_dn=ents[0].dn, properties={RA_SCHEDULE: test_schedule,
+                                         RA_DESCRIPTION: test_desc})
+    properties = topology.master.agreement.getProperties(
+        agmnt_dn=ents[0].dn, properties=[RA_SCHEDULE, RA_DESCRIPTION])
+    assert len(properties) == 2
+    assert properties[RA_SCHEDULE][0] == test_schedule
+    assert properties[RA_DESCRIPTION][0] == test_desc
+
+
+def test_changes(topology):
+    """Test the changes counter behaviour after making some changes
+    to the replicated suffix
+    """
+
+    topology.master.log.info("\n\n##########\n### CHANGES\n##########")
+    ents = topology.master.agreement.list(suffix=SUFFIX,
+                                          consumer_host=topology.consumer.host,
+                                          consumer_port=topology.consumer.port)
+    assert len(ents) == 1
+    value = topology.master.agreement.changes(agmnt_dn=ents[0].dn)
+    topology.master.log.info("\ntest_changes: %d changes\n" % value)
+    assert value > 0
+
+    # Do an update
+    TEST_STRING = 'test_string'
+    mod = [(ldap.MOD_REPLACE, 'description', [TEST_STRING])]
+    topology.master.modify_s(ENTRY_DN, mod)
+
+    ent = topology.consumer.getEntry(ENTRY_DN, ldap.SCOPE_BASE,
+                                     "(objectclass=*)")
+
+    # The update has been replicated
+    loop = 0
+    while loop <= 10:
+        ent = topology.consumer.getEntry(ENTRY_DN, ldap.SCOPE_BASE,
+                                         "(objectclass=*)")
+        if ent and ent.hasValue('description'):
+            if ent.getValue('description') == TEST_STRING:
+                break
+        time.sleep(1)
+        loop += 1
+    assert loop <= 10
+
+    # Check change number
+    newvalue = topology.master.agreement.changes(agmnt_dn=ents[0].dn)
+    topology.master.log.info("\ntest_changes: %d changes\n" % newvalue)
+    assert (value + 1) == newvalue
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/lib389/tests/backend_test.py b/lib389/tests/backend_test.py
new file mode 100644
index 0000000..4f3afb2
--- /dev/null
+++ b/lib389/tests/backend_test.py
@@ -0,0 +1,278 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import pytest
+import logging
+
+from lib389._constants import *
+from lib389.properties import *
+from lib389 import DirSrv, InvalidArgumentError, UnwillingToPerformError
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+TEST_REPL_DN = "uid=test,%s" % DEFAULT_SUFFIX
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'dirsrv'
+INSTANCE_PREFIX = None
+INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
+NEW_SUFFIX_1 = 'o=test_create'
+NEW_BACKEND_1 = 'test_createdb'
+NEW_CHILDSUFFIX_1 = 'o=child1,o=test_create'
+NEW_CHILDBACKEND_1 = 'test_createchilddb'
+NEW_SUFFIX_2 = 'o=test_bis_create'
+NEW_BACKEND_2 = 'test_bis_createdb'
+NEW_CHILDSUFFIX_2 = 'o=child2,o=test_bis_create'
+NEW_CHILDBACKEND_2 = 'test_bis_createchilddb'
+
+
+class TopologyStandalone(object):
+    def __init__(self, standalone):
+        standalone.open()
+        self.standalone = standalone
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    standalone = DirSrv(verbose=False)
+    standalone.log.debug("Instance allocated")
+    args = {SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT,
+            SER_DEPLOYED_DIR: INSTANCE_PREFIX,
+            SER_SERVERID_PROP: INSTANCE_SERVERID}
+    standalone.allocate(args)
+    if standalone.exists():
+        standalone.delete()
+    standalone.create()
+    standalone.open()
+
+    def fin():
+        standalone.delete()
+    request.addfinalizer(fin)
+
+    return TopologyStandalone(standalone)
+
+
+def test_list(topology):
+    """Test backend.list() function behaviour after:
+    - creating new suffixes
+    - filter with suffix
+    - filter with backend name (bename)
+    - filter with backend dn
+    - filter with invalid suffix/bename
+    """
+
+    ents = topology.standalone.backend.list()
+    nb_backend = len(ents)
+    for ent in ents:
+        topology.standalone.log.info("List(%d): backend %s" %
+                                     (nb_backend, ent.dn))
+
+    log.info("Create a first backend and check list all backends")
+    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
+                                       properties={BACKEND_NAME:
+                                                   NEW_BACKEND_1})
+    ents = topology.standalone.backend.list()
+    for ent in ents:
+        topology.standalone.log.info("List(%d): backend %s" %
+                                     (nb_backend + 1, ent.dn))
+    assert len(ents) == (nb_backend + 1)
+
+    log.info("Create a second backend and check list all backends")
+    topology.standalone.backend.create(suffix=NEW_SUFFIX_2,
+                                       properties={BACKEND_NAME:
+                                                   NEW_BACKEND_2})
+    ents = topology.standalone.backend.list()
+    for ent in ents:
+        topology.standalone.log.info("List(%d): backend %s" %
+                                     (nb_backend + 2, ent.dn))
+    assert len(ents) == (nb_backend + 2)
+
+    log.info("Check list a backend per suffix")
+    ents = topology.standalone.backend.list(suffix=NEW_SUFFIX_1)
+    for ent in ents:
+        topology.standalone.log.info("List suffix (%d): backend %s" %
+                                     (1, ent.dn))
+    assert len(ents) == 1
+
+    log.info("Check list a backend by its name")
+    ents = topology.standalone.backend.list(bename=NEW_BACKEND_2)
+    for ent in ents:
+        topology.standalone.log.info("List name (%d): backend %s" %
+                                     (1, ent.dn))
+    assert len(ents) == 1
+
+    log.info("Check list backends by their DN")
+    all = topology.standalone.backend.list()
+    for ent in all:
+        ents = topology.standalone.backend.list(backend_dn=ent.dn)
+        for bck in ents:
+            topology.standalone.log.info("List DN (%d): backend %s" %
+                                         (1, bck.dn))
+        assert len(ents) == 1
+
+    log.info("Check list with valid backend DN but invalid suffix/bename")
+    all = topology.standalone.backend.list()
+    for ent in all:
+        ents = topology.standalone.backend.list(suffix="o=dummy",
+                                                backend_dn=ent.dn,
+                                                bename="dummydb")
+        for bck in ents:
+            topology.standalone.log.info("List invalid suffix+bename "
+                                         "(%d): backend %s" % (1, bck.dn))
+        assert len(ents) == 1
+
+    log.info("Just to make it clean in the end")
+    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
+    topology.standalone.backend.delete(suffix=NEW_SUFFIX_2)
+
+
+def test_create(topology):
+    """Test backend.create() function with:
+    - specifying no suffix
+    - specifying already existing backend suffix
+    - specifying already existing backend name, but new suffix
+    - specifying no properties
+    """
+
+    log.info("Create a backend")
+    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
+                                       properties={BACKEND_NAME:
+                                                   NEW_BACKEND_1})
+
+    log.info("Check behaviour with missing suffix")
+    with pytest.raises(ValueError) as excinfo:
+        topology.standalone.backend.create()
+    assert 'suffix is mandatory' in str(excinfo.value)
+
+    log.info("Check behaviour with already existing backend for that suffix")
+    with pytest.raises(InvalidArgumentError) as excinfo:
+        topology.standalone.backend.create(suffix=NEW_SUFFIX_1)
+    assert 'It already exists backend(s)' in str(excinfo.value)
+
+    log.info("Check behaviour with already existing backend DN, "
+             "but new suffix")
+    with pytest.raises(InvalidArgumentError) as excinfo:
+        topology.standalone.backend.create(suffix=NEW_SUFFIX_2,
+                                           properties={BACKEND_NAME:
+                                                       NEW_BACKEND_1})
+    assert 'It already exists a backend with that DN' in str(excinfo.value)
+
+    log.info("Create a backend without properties")
+    topology.standalone.backend.create(suffix=NEW_SUFFIX_2)
+    ents = topology.standalone.backend.list(suffix=NEW_SUFFIX_2)
+    assert len(ents) == 1
+
+    log.info("Just to make it clean in the end")
+    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
+    topology.standalone.backend.delete(suffix=NEW_SUFFIX_2)
+
+
+def test_delete_valid(topology):
+    """Test the various possibilities to delete a backend:
+    - with suffix
+    - with backend name
+    - with backend DN
+    """
+
+    ents = topology.standalone.backend.list()
+    nb_backend = len(ents)
+
+    log.info("Try to delete a backend with suffix")
+    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
+                                       properties={BACKEND_NAME:
+                                                   NEW_BACKEND_1})
+    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
+    ents = topology.standalone.backend.list()
+    assert len(ents) == nb_backend
+
+    log.info("Try to delete a backend with backend name")
+    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
+                                       properties={BACKEND_NAME:
+                                                   NEW_BACKEND_1})
+    topology.standalone.backend.delete(bename=NEW_BACKEND_1)
+    ents = topology.standalone.backend.list()
+    assert len(ents) == nb_backend
+
+    log.info("Try to delete a backend with backend DN")
+    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
+                                       properties={BACKEND_NAME:
+                                                   NEW_BACKEND_1})
+    ents = topology.standalone.backend.list(suffix=NEW_SUFFIX_1)
+    assert len(ents) == 1
+    topology.standalone.backend.delete(backend_dn=ents[0].dn)
+    ents = topology.standalone.backend.list()
+    assert len(ents) == nb_backend
+
+
+def test_delete_invalid(topology):
+    """Test the invalid situations with the backend removal:
+    - no argument
+    - invalid suffix
+    - existing a mapping tree
+    - backend name differs
+    """
+
+    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
+                                       properties={BACKEND_NAME:
+                                                   NEW_BACKEND_1})
+    topology.standalone.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
+
+    log.info("First no argument -> InvalidArgumentError")
+    with pytest.raises(InvalidArgumentError) as excinfo:
+        topology.standalone.backend.delete()
+    assert 'suffix and backend DN and backend name are missing' in \
+        str(excinfo.value)
+
+    log.info("Second invalid suffix -> InvalidArgumentError")
+    with pytest.raises(InvalidArgumentError) as excinfo:
+        topology.standalone.backend.delete(suffix=NEW_SUFFIX_2)
+    assert 'Unable to retrieve the backend' in str(excinfo.value)
+
+    log.info("Existing a mapping tree -> UnwillingToPerformError")
+    with pytest.raises(UnwillingToPerformError) as excinfo:
+        topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
+    assert 'It still exists a mapping tree' in str(excinfo.value)
+    topology.standalone.mappingtree.delete(suffix=NEW_SUFFIX_1,
+                                           bename=NEW_BACKEND_1)
+
+    log.info("Backend name differs -> UnwillingToPerformError")
+    with pytest.raises(UnwillingToPerformError) as excinfo:
+        topology.standalone.backend.delete(suffix=NEW_SUFFIX_1,
+                                           bename='dummydb')
+    assert 'Backend name specified (dummydb) differs from' in \
+        str(excinfo.value)
+    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
+
+
+def test_toSuffix(topology):
+    """Test backend.toSuffix() function
+    by comparing its result to the true value
+    """
+
+    log.info("Create one backend")
+    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
+                                       properties={BACKEND_NAME:
+                                                   NEW_BACKEND_1})
+
+    log.info("Run through all backends and compare backend.toSuffix() "
+             "function results with true values taken from attributes")
+    ents = topology.standalone.backend.list()
+    for ent in ents:
+        suffix = ent.getValues(BACKEND_PROPNAME_TO_ATTRNAME[BACKEND_SUFFIX])
+        values = topology.standalone.backend.toSuffix(name=ent.dn)
+        assert suffix[0] in values
+
+    log.info("Clean up after test")
+    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/lib389/tests/config.py b/lib389/tests/config.py
new file mode 100644
index 0000000..3b9a472
--- /dev/null
+++ b/lib389/tests/config.py
@@ -0,0 +1,40 @@
+import logging
+import six
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger(__name__)
+
+DN_RMANAGER = 'uid=rmanager,cn=config'
+
+auth = {'host': 'localhost',
+        'port': 22389,
+        'binddn': 'cn=directory manager',
+        'bindpw': 'password'}
+
+
+class MockDirSrv(object):
+    host = 'localhost'
+    port = 22389
+    sslport = 0
+
+    def __str__(self):
+        if self.sslport:
+            return 'ldaps://%s:%s' % (self.host, self.sslport)
+        else:
+            return 'ldap://%s:%s' % (self.host, self.port)
+
+
+def expect(entry, name, value):
+    assert entry, "Bad entry %r " % entry
+    assert entry.getValue(name) == value, \
+        ("Bad value for entry %s. Expected %r vs %r" %
+         (entry, entry.getValue(name), value))
+
+
+def entry_equals(e1, e2):
+    """compare using str()"""
+    return str(e1) == str(e2)
+
+
+def dfilter(my_dict, keys):
+    """Filter a dict in a 2.4-compatible way"""
+    return dict([(k, v) for k, v in six.iteritems(my_dict) if k in keys])
diff --git a/lib389/tests/config_test.py b/lib389/tests/config_test.py
new file mode 100644
index 0000000..7966dab
--- /dev/null
+++ b/lib389/tests/config_test.py
@@ -0,0 +1,87 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+"""Brooker classes to organize ldap methods.
+   Stuff is split in classes, like:
+   * Replica
+   * Backend
+   * Suffix
+
+   You will access this from:
+   DirSrv.backend.methodName()
+"""
+
+from . import config
+from .config import *
+
+import lib389
+from lib389 import DirSrv
+
+
+conn = None
+added_entries = None
+added_backends = None
+
+MOCK_REPLICA_ID = '12'
+MOCK_TESTREPLICA_DN = "cn=testReplica,cn=ldbm database,cn=plugins,cn=config"
+
+
+def setup():
+    # uses an existing 389 instance
+    # add a suffix
+    # add an agreement
+    # This setup is quite verbose but to test DirSrv method we should
+    # do things manually. A better solution would be to use an LDIF.
+    global conn
+    conn = DirSrv(**config.auth)
+    conn.verbose = True
+    conn.added_entries = []
+    conn.added_backends = set(['o=mockbe1'])
+    conn.added_replicas = []
+    """
+    # add a backend for testing ruv and agreements
+    addbackend_harn(conn, 'testReplica')
+
+    # add another backend for testing replica.add()
+    addbackend_harn(conn, 'testReplicaCreation')
+    """
+
+
+def teardown():
+    global conn
+    conn.config.loglevel([lib389.LOG_CACHE])
+    conn.config.loglevel([256], service='access')
+
+    """
+    drop_added_entries(conn)
+    conn.delete_s(','.join(['cn="o=testreplica"', DN_MAPPING_TREE]))
+    drop_backend(conn, 'o=testreplica')
+    #conn.delete_s('o=testreplica')
+    """
+
+
+def loglevel_test():
+    vals = [lib389.LOG_CACHE, lib389.LOG_REPLICA, lib389.LOG_CONNECT]
+    expected = sum(vals)
+    assert conn.config.loglevel(vals) == expected
+    ret = conn.config.get('nsslapd-errorlog-level')
+    assert ret == str(expected), "expected: %r got: %r" % (expected, ret)
+
+
+def loglevel_update_test():
+    vals = [lib389.LOG_CACHE, lib389.LOG_CONNECT]
+    e = sum(vals)
+    assert conn.config.loglevel(vals) == e
+    vals = [lib389.LOG_REPLICA]
+    ret = conn.config.loglevel(vals, update=True)
+    assert ret == (e + sum(vals)), "expected %s got %s" % (e + sum(vals), ret)
+
+
+def access_loglevel_test():
+    vals = [lib389.LOG_CACHE, lib389.LOG_REPLICA, lib389.LOG_CONNECT]
+    assert conn.config.loglevel(vals, service='access') == sum(vals)
diff --git a/lib389/tests/conftest.py b/lib389/tests/conftest.py
new file mode 100644
index 0000000..caf507c
--- /dev/null
+++ b/lib389/tests/conftest.py
@@ -0,0 +1,116 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import string
+import os
+import sys
+import pytest
+from tempfile import mkdtemp
+from shutil import rmtree
+
+
+def ldrop(numchar, inputstr):
+    """
+        Drop numchar characters from the beginning of each line in inputstring.
+    """
+    return "\n".join([x[numchar:] for x in string.split(inputstr, "\n")])
+
+
+@pytest.fixture
+def fake_ds_class():
+    """
+        Returns fake DSInstance-like class
+    """
+    class FakeDSInstance(object):
+        def return_one(self):
+            return 1
+
+    return FakeDSInstance
+
+
+@pytest.fixture(scope="module")
+def fake_ds_modules(request):
+    """
+        Returns path to directory containing fake modules.
+    """
+
+    # module_dir contains fake ds modules, that can be used for testing
+    module_dir = mkdtemp()
+    old_cwd = os.getcwd()
+
+    # when fixture is destroyed, we change back to old cwd
+    # and delete fake module dir
+    def fin():
+        os.chdir(old_cwd)
+        rmtree(module_dir)
+    request.addfinalizer(fin)
+
+    # make module_dir a python package
+    with open(module_dir + "/__init__.py", 'a'):
+        os.utime(module_dir + "/__init__.py", None)
+
+    # create module module_dir/repl.py with few functions
+    with open(module_dir + "/repl.py", "w") as repl_file:
+        repl_module = """
+            def with_no_arg(ds):
+                return ds
+
+            def with_one_arg(ds, arg):
+                return ds, arg
+
+            def return_argument_given(ds, arg):
+                return arg
+
+            def with_kwarg(ds, kwarg=2):
+                return kwarg
+
+            def with_all(ds, arg1, arg2, kwarg1=1, kwarg2=2):
+                return arg1, arg2, kwarg1, kwarg2
+
+            """
+        # Drop 12 chars from left and write to file
+        repl_file.write(ldrop(12, repl_module))
+
+    os.mkdir(module_dir + "/plugin")
+
+    # make module_dir/plugin a python package
+    with open(module_dir + "/plugin/__init__.py", 'a'):
+        os.utime(module_dir + "/plugin/__init__.py", None)
+
+    # create module module_dir/plugin/automember.py with few functions
+    with open(module_dir + "/plugin/automember.py", "w") as automem_file:
+        automember_module = """
+            def with_no_arg(ds):
+                return ds
+
+            def with_one_arg(ds, arg):
+                return ds, arg
+
+            def calling_ds_method(ds, arg):
+                return (ds, ds.return_one(), arg)
+
+            def calling_repl(ds, arg1, arg2):
+                return ds.repl.return_argument_given(1) + arg1 + arg2
+
+            def calling_repl_with_kwarg2(ds):
+                return ds.repl.with_kwarg()
+
+            def calling_repl_with_kwarg1(ds):
+                return ds.repl.with_kwarg(kwarg=1)
+
+            def with_all(ds, arg1, arg2, kwarg1=1, kwarg2=2):
+                a, b, c, d = ds.repl.with_all(1, 4, kwarg1=3)
+                return a + arg1, b + arg2, c + kwarg1, d + kwarg2
+
+            """
+        # Drop 12 chars from left and write to file
+        automem_file.write(ldrop(12, automember_module))
+
+    os.chdir(os.path.dirname(module_dir))
+    sys.path.append(os.path.dirname(module_dir))
+    return module_dir
diff --git a/lib389/tests/dereference_test.py b/lib389/tests/dereference_test.py
new file mode 100644
index 0000000..19b3f5c
--- /dev/null
+++ b/lib389/tests/dereference_test.py
@@ -0,0 +1,99 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+from lib389._constants import *
+from lib389 import DirSrv, Entry
+import ldap
+import pytest
+import logging
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'dereferenceds'
+
+
+class TopologyStandalone(object):
+    def __init__(self, standalone):
+        standalone.open()
+        self.standalone = standalone
+
+
+@pytest.fixture(scope='module')
+def topology(request):
+    standalone = DirSrv(verbose=False)
+    standalone.log.debug('Instance allocated')
+    args = {SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT,
+            SER_SERVERID_PROP: INSTANCE_SERVERID}
+    standalone.allocate(args)
+    if standalone.exists():
+        standalone.delete()
+    standalone.create()
+    standalone.open()
+
+    def fin():
+        standalone.delete()
+    request.addfinalizer(fin)
+
+    return TopologyStandalone(standalone)
+
+
+@pytest.fixture(scope='module')
+def user(topology):
+    """Create user entries"""
+
+    for i in range(0, 2):
+        uentry = Entry('uid=test%s,%s' % (i, DEFAULT_SUFFIX))
+        uentry.setValues('objectclass', 'top', 'extensibleobject')
+        uentry.setValues('uid', 'test')
+        topology.standalone.add_s(uentry)
+
+
+@pytest.fixture(scope='module')
+def group(topology):
+    """Create a group entry"""
+
+    gentry = Entry('cn=testgroup,%s' % DEFAULT_SUFFIX)
+    gentry.setValues('objectclass', 'top', 'extensibleobject')
+    gentry.setValues('cn', 'testgroup')
+    for i in range(0, 2):
+        gentry.setValues('uniqueMember', 'uid=test%s,%s' % (i, DEFAULT_SUFFIX))
+    topology.standalone.add_s(gentry)
+
+
+def test_dereference(topology, user, group):
+    """Test dereference search argument formating
+    Check, that result is correct
+    """
+
+    log.info('Check, that our deref Control Value is correctly formatted')
+    with pytest.raises(ldap.UNAVAILABLE_CRITICAL_EXTENSION):
+        result, control_response = topology.standalone.dereference(
+            'uniqueMember:dn,uid;uniqueMember:dn,uid',
+            filterstr='(cn=testgroup)')
+
+    result, control_response = topology.standalone.dereference(
+        'uniqueMember:cn,uid,objectclass', filterstr='(cn=testgroup)')
+
+    log.info('Check, that the dereference search result is correct')
+    assert result[0][2][0].entry == [{'derefVal':
+                                      'uid=test1,dc=example,dc=com',
+                                      'derefAttr': 'uniqueMember',
+                                      'attrVals': [{'vals':
+                                                    ['top',
+                                                     'extensibleobject'],
+                                                    'type': 'objectclass'},
+                                                   {'vals': ['test', 'test1'],
+                                                    'type': 'uid'}]}]
+
+
+if __name__ == '__main__':
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main('-s -v %s' % CURRENT_FILE)
diff --git a/lib389/tests/dirsrv_test.py b/lib389/tests/dirsrv_test.py
new file mode 100644
index 0000000..8255181
--- /dev/null
+++ b/lib389/tests/dirsrv_test.py
@@ -0,0 +1,223 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import pwd
+import logging
+import pytest
+from lib389._constants import *
+from lib389.properties import *
+from lib389 import DirSrv, Entry
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+TEST_DN = "uid=test,%s" % DEFAULT_SUFFIX
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'dirsrv'
+INSTANCE_PREFIX = '/'
+INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
+
+
+class TopologyInstance(object):
+    def __init__(self, instance):
+        self.instance = instance
+
+
+@pytest.fixture(scope='module')
+def topology(request):
+    instance = DirSrv(verbose=False)
+
+    if instance.exists():
+        instance.delete()
+
+    def fin():
+        if instance.exists():
+            instance.delete()
+    request.addfinalizer(fin)
+
+    return TopologyInstance(instance)
+
+
+def _add_user(topology):
+    """Add a user to the instance"""
+
+    topology.instance.add_s(Entry((TEST_DN, {'objectclass':
+                                             "top person".split(),
+                                             'objectclass':
+                                             "organizationalPerson",
+                                             'objectclass': "inetOrgPerson",
+                                             'uid': 'test',
+                                             'sn': 'test',
+                                             'cn': 'test'})))
+    log.info('User %s was added' % TEST_DN)
+
+
+def test_allocate(topology):
+    """Test instance.allocate() function
+    for correct state and arguments
+    """
+
+    log.info('Check instance state is initial')
+    assert topology.instance.state == DIRSRV_STATE_INIT
+
+    log.info('Allocate the instance')
+    args = {SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT,
+            SER_SERVERID_PROP: INSTANCE_SERVERID}
+    topology.instance.allocate(args)
+
+    log.info('Check instance state is allocated')
+    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
+
+    log.info('Try to add user. Failure is excpected')
+    with pytest.raises(Exception):
+        _add_user(topology)
+
+    if os.getuid() == 0:
+        userid = DEFAULT_USER
+    else:
+        userid = pwd.getpwuid(os.getuid())[0]
+
+    log.info('Verify the settings')
+    assert topology.instance.host == LOCALHOST
+    assert topology.instance.port == INSTANCE_PORT
+    assert topology.instance.sslport is None
+    assert topology.instance.binddn == DN_DM
+    assert topology.instance.bindpw == PW_DM
+    assert topology.instance.creation_suffix == DEFAULT_SUFFIX
+    assert topology.instance.userid == userid
+    assert topology.instance.serverid == INSTANCE_SERVERID
+    assert topology.instance.groupid == topology.instance.userid
+    assert topology.instance.prefix == INSTANCE_PREFIX
+    assert topology.instance.backupdir == INSTANCE_BACKUP
+
+    log.info('Check that we can change the settings of an allocated DirSrv')
+    args = {SER_SERVERID_PROP: INSTANCE_SERVERID,
+            SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT,
+            SER_ROOT_DN: "uid=foo"}
+    topology.instance.allocate(args)
+
+    log.info('Check instance state is allocated')
+    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
+
+    log.info('Verify the settings')
+    assert topology.instance.host == LOCALHOST
+    assert topology.instance.port == INSTANCE_PORT
+    assert topology.instance.sslport is None
+    assert topology.instance.binddn == "uid=foo"
+    assert topology.instance.bindpw == PW_DM
+    assert topology.instance.creation_suffix == DEFAULT_SUFFIX
+    assert topology.instance.userid == userid
+    assert topology.instance.serverid == INSTANCE_SERVERID
+    assert topology.instance.groupid == topology.instance.userid
+    assert topology.instance.prefix == INSTANCE_PREFIX
+    assert topology.instance.backupdir == INSTANCE_BACKUP
+
+    log.info('Restore back the valid parameters and check')
+    args = {SER_SERVERID_PROP: INSTANCE_SERVERID,
+            SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT}
+    topology.instance.allocate(args)
+
+    log.info('Check instance state is allocated')
+    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
+
+    log.info('Verify the settings')
+    assert topology.instance.host == LOCALHOST
+    assert topology.instance.port == INSTANCE_PORT
+    assert topology.instance.sslport is None
+    assert topology.instance.binddn == DN_DM
+    assert topology.instance.bindpw == PW_DM
+    assert topology.instance.creation_suffix == DEFAULT_SUFFIX
+    assert topology.instance.userid == userid
+    assert topology.instance.serverid == INSTANCE_SERVERID
+    assert topology.instance.groupid == topology.instance.userid
+    assert topology.instance.prefix == INSTANCE_PREFIX
+    assert topology.instance.backupdir == INSTANCE_BACKUP
+
+
+def test_create(topology):
+    """Test instance creation
+    Check status before and after
+    Try to add a user
+    """
+
+    log.info('Check instance state is allocated')
+    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
+
+    topology.instance.create()
+
+    log.info('Check instance state is offline')
+    assert topology.instance.state == DIRSRV_STATE_OFFLINE
+
+    log.info('Try to add user. Failure is excpected')
+    with pytest.raises(Exception):
+        _add_user(topology)
+
+
+def test_open(topology):
+    """Test instance opening
+    Check status before and after
+    Try to add a user
+    """
+
+    log.info('Check instance state is offline')
+    assert topology.instance.state == DIRSRV_STATE_OFFLINE
+
+    topology.instance.open()
+
+    log.info('Check instance state is online')
+    assert topology.instance.state == DIRSRV_STATE_ONLINE
+
+    log.info('Try to add user. Success is excpected')
+    _add_user(topology)
+
+
+def test_close(topology):
+    """Test instance closing
+    Check status before and after
+    Try to add a user
+    """
+
+    log.info('Check instance state is online')
+    assert topology.instance.state == DIRSRV_STATE_ONLINE
+
+    topology.instance.close()
+
+    log.info('Check instance state is offline')
+    assert topology.instance.state == DIRSRV_STATE_OFFLINE
+
+    log.info('Try to add user. Failure is excpected')
+    with pytest.raises(Exception):
+        _add_user(topology)
+
+
+def test_delete(topology):
+    """Test instance deletion
+    Check status before and after
+    Try to add a user
+    """
+
+    log.info('Check instance state is offline')
+    assert topology.instance.state == DIRSRV_STATE_OFFLINE
+
+    topology.instance.delete()
+
+    log.info('Check instance state is allocated')
+    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
+
+    log.info('Try to add user. Failure is excpected')
+    with pytest.raises(Exception):
+        _add_user(topology)
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main('-s -v %s' % CURRENT_FILE)
diff --git a/lib389/tests/dsadmin_basic_test.py b/lib389/tests/dsadmin_basic_test.py
new file mode 100644
index 0000000..6426d41
--- /dev/null
+++ b/lib389/tests/dsadmin_basic_test.py
@@ -0,0 +1,126 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+""" Testing basic functionalities of DirSrv
+
+
+"""
+import ldap
+import lib389
+from lib389 import DirSrv
+from lib389 import NoSuchEntryError
+from ldap import *
+from nose.tools import *
+from . import config
+from .config import *
+
+conn = None
+added_entries = None
+
+
+def setup():
+    global conn
+    try:
+        conn = DirSrv(**config.auth)
+        conn.verbose = True
+        conn.added_entries = []
+    except SERVER_DOWN as e:
+        log.error("To run tests you need a working 389 instance %s" %
+                  config.auth)
+        raise e
+
+
+def tearDown():
+    global conn
+
+    # reduce log level
+    conn.config.loglevel([lib389.LOG_CACHE])
+    conn.config.loglevel([256], service='access')
+
+    for e in conn.added_entries:
+        try:
+            conn.delete_s(e)
+        except ldap.NO_SUCH_OBJECT:
+            log.warn("entry not found %r" % e)
+
+
+def bind_test():
+    print ("conn: %s" % conn)
+
+
+def setupBindDN_UID_test():
+    user = {
+        'binddn': 'uid=rmanager1,cn=config',
+        'bindpw': 'password'
+    }
+    e = conn.setupBindDN(**user)
+    conn.added_entries.append(e.dn)
+
+    assert e.dn == user['binddn'], "Bad entry: %r " % e
+    expected = conn.getEntry(user['binddn'], ldap.SCOPE_BASE)
+    assert entry_equals(
+        e, expected), "Mismatching entry %r vs %r" % (e, expected)
+
+
+def setupBindDN_CN_test():
+    user = {
+        'binddn': 'cn=rmanager1,cn=config',
+        'bindpw': 'password'
+    }
+    e = conn.setupBindDN(**user)
+    conn.added_entries.append(e.dn)
+    assert e.dn == user['binddn'], "Bad entry: %r " % e
+    expected = conn.getEntry(user['binddn'], ldap.SCOPE_BASE)
+    assert entry_equals(
+        e, expected), "Mismatching entry %r vs %r" % (e, expected)
+
+
+def setupChangelog_default_test():
+    e = conn.replica.changelog()
+    conn.added_entries.append(e.dn)
+    assert e.dn, "Bad changelog entry: %r " % e
+    assert e.getValue('nsslapd-changelogdir').endswith("changelogdb"), \
+        "Mismatching entry %r " % e.data.get('nsslapd-changelogdir')
+    conn.delete_s("cn=changelog5,cn=config")
+
+
+def setupChangelog_test():
+    e = conn.replica.changelog(dbname="mockChangelogDb")
+    conn.added_entries.append(e.dn)
+    assert e.dn, "Bad changelog entry: %r " % e
+    assert e.getValue('nsslapd-changelogdir').endswith("mockChangelogDb"), \
+        "Mismatching entry %r " % e.data.get('nsslapd-changelogdir')
+    conn.delete_s("cn=changelog5,cn=config")
+
+
+def setupChangelog_full_test():
+    e = conn.replica.changelog(dbname="/tmp/mockChangelogDb")
+    conn.added_entries.append(e.dn)
+
+    assert e.dn, "Bad changelog entry: %r " % e
+    expect(e, 'nsslapd-changelogdir', "/tmp/mockChangelogDb")
+    conn.delete_s("cn=changelog5,cn=config")
+
+
+@raises(NoSuchEntryError)
+def getMTEntry_missing_test():
+    e = conn.getMTEntry('o=MISSING')
+    return e
+
+
+def getMTEntry_present_test():
+    suffix = 'o=addressbook16'
+    bename = 'addressbookd16db'
+    backendEntry, dummy = conn.backend.add(suffix, benamebase=bename)
+    suffixEntry = conn.backend.setup_mt(suffix, bename)
+
+    e = conn.getMTEntry(suffix)
+
+    conn.backend.delete(bename)
+    conn.delete_s(suffixEntry.dn)
+    assert e, "Entry should be present %s" % suffix
diff --git a/lib389/tests/dsadmin_create_remove_test.py b/lib389/tests/dsadmin_create_remove_test.py
new file mode 100644
index 0000000..c0dea2d
--- /dev/null
+++ b/lib389/tests/dsadmin_create_remove_test.py
@@ -0,0 +1,97 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+"""
+Test creation and deletion of instances
+"""
+import ldap
+import os
+import socket
+from lib389 import DirSrv, DN_CONFIG
+from lib389.tools import DirSrvTools
+from nose import *
+
+added_instances = []
+
+
+def setup():
+    global added_instances
+
+
+def teardown():
+    global added_instances
+    for instance in added_instances:
+        cmd = "/usr/bin/sudo remove-ds.pl -i slapd-%s" % instance
+        try:
+            os.system(cmd)
+        except:
+            log.exception("error executing %r" % cmd)
+
+
+def default_test():
+    host = socket.gethostname()
+    port = 10200
+    binddn = "cn=directory manager"
+    bindpw = "password"
+    suffix = 'dc=example,dc=com'
+    basedn = DN_CONFIG
+    scope = ldap.SCOPE_BASE
+    filt = "(objectclass=*)"
+    instance_name = ['m1', 'm2']
+
+    instance_config = {
+        'cfgdshost': host,
+        'cfgdsport': port,
+        'cfgdsuser': 'admin',
+        'cfgdspwd': 'admin',
+        'newrootpw': 'password',
+        'newhost': host,
+        'newport': port,
+        'newinstance': instance_name[0],
+        'newsuffix': suffix,
+        'setup_admin': True,
+    }
+    try:
+        m1 = DirSrv(host, port, binddn, bindpw)
+    except:
+        m1 = DirSrvTools.createInstance(instance_config, verbose=0)
+        added_instances.append(instance_config['newinstance'])
+
+#        filename = "%s/slapd-%s/ldif/Example.ldif" % (m1.sroot, m1.inst)
+#        m1.importLDIF(filename, "dc=example,dc=com", None, True)
+#        m1.exportLDIF('/tmp/ldif', "dc=example,dc=com", False, True)
+    print (m1.sroot, m1.inst, m1.errlog)
+    ent = m1.getEntry(basedn, scope, filt, None)
+    if ent:
+        print (ent.passwordmaxage)
+    instance_config.update({
+                           'newinstance': instance_name[1],
+                           'newport': port + 10,
+
+                           })
+    m1 = DirSrvTools.createInstance(instance_config, verbose=0)
+    added_instances.append(instance_config['newinstance'])
+    #     m1.stop(True)
+    #     m1.start(True)
+    suffix = "dc=example2,dc=com"
+    bename = "example2db"
+    backendEntry, dummy = m1.backend.add(suffix, bename)
+    suffixEntry = m1.backend.setup_mt(suffix, bename)
+    cn = backendEntry.getValue('cn')
+    print (cn)
+    entry = m1.getEntry(DN_CONFIG, ldap.SCOPE_SUBTREE, "(cn=" + cn + ")")
+    print ("new backend entry is:")
+    print (entry)
+    print (entry.getValues('objectclass'))
+    print (entry.OBJECTCLASS)
+    results = m1.search_s("cn=monitor", ldap.SCOPE_SUBTREE)
+    print (results)
+    results = m1.getBackendsForSuffix("dc=example,dc=com")
+    print (results)
+
+    print ("done")
diff --git a/lib389/tests/dsadmin_test.py b/lib389/tests/dsadmin_test.py
new file mode 100644
index 0000000..a59ddb8
--- /dev/null
+++ b/lib389/tests/dsadmin_test.py
@@ -0,0 +1,263 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+from nose import *
+from nose.tools import *
+
+from . import config
+from .config import log
+from .config import *
+
+import ldap
+import time
+import lib389
+from lib389 import DirSrv, Entry
+from lib389 import utils
+from lib389.tools import DirSrvTools
+from subprocess import Popen
+
+
+conn = None
+added_entries = None
+added_backends = None
+
+
+def harn_nolog():
+    conn.config.loglevel([lib389.LOG_DEFAULT])
+    conn.config.loglevel([lib389.LOG_DEFAULT], service='access')
+
+
+def setup():
+    global conn
+    conn = DirSrv(**config.auth)
+    conn.verbose = True
+    conn.added_entries = []
+    conn.added_backends = set(['o=mockbe2'])
+    conn.added_replicas = []
+    harn_nolog()
+
+
+def setup_backend():
+    global conn
+    suffix = 'o=addressbook6'
+    backend = 'addressbook6db'
+
+    # create backend and suffix
+    backendEntry, dummy = conn.backend.add(suffix, benamebase=backend)
+    suffixEntry = conn.backend.setup_mt(suffix, backend)
+
+
+def teardown():
+    global conn
+    conn.rebind()
+    drop_added_entries(conn)
+
+
+def drop_added_entries(conn):
+    while conn.added_entries:
+        try:
+            e = conn.added_entries.pop()
+            log.info("removing entries %r" % conn.added_backends)
+            conn.delete_s(e)
+        except ldap.NOT_ALLOWED_ON_NONLEAF:
+            log.error("Entry is not a leaf: %r" % e)
+        except ldap.NO_SUCH_OBJECT:
+            log.error("Cannot remove entry: %r" % e)
+
+    log.info("removing backends %r" % conn.added_backends)
+    for suffix in conn.added_backends:
+        try:
+            drop_backend(conn, suffix)
+        except:
+            log.exception("error removing %r" % suffix)
+    for r in conn.added_replicas:
+        try:
+            drop_backend(conn, suffix=None, bename=r)
+        except:
+            log.exception("error removing %r" % r)
+
+
+def drop_backend(conn, suffix, bename=None, maxnum=50):
+    if not bename:
+        bename = [x.dn for x in conn.getBackendsForSuffix(suffix)]
+
+    if not bename:
+        return None
+
+    assert bename, "Missing bename for %r" % suffix
+    if not hasattr(bename, '__iter__'):
+        bename = [','.join(['cn=%s' % bename, lib389.DN_LDBM])]
+    for be in bename:
+        log.debug("removing entry from %r" % be)
+        leaves = [x.dn for x in conn.search_s(
+            be, ldap.SCOPE_SUBTREE, '(objectclass=*)', ['cn'])]
+        # start deleting the leaves - which have the max number of ","
+        leaves.sort(key=lambda x: x.count(","))
+        while leaves and maxnum:
+            # to avoid infinite loops
+            # limit the iterations
+            maxnum -= 1
+            try:
+                log.debug("removing %s" % leaves[-1])
+                conn.delete_s(leaves[-1])
+                leaves.pop()
+            except:
+                leaves.insert(0, leaves.pop())
+
+        if not maxnum:
+            raise Exception("BAD")
+
+
+#
+# Tests
+#
+
+
+def addbackend_harn(conn, name, beattrs=None):
+    """Create the suffix o=name and its backend."""
+    suffix = "o=%s" % name
+    e = Entry((suffix, {
+               'objectclass': ['top', 'organization'],
+               'o': [name]
+               }))
+
+    try:
+        ret = conn.addSuffix(suffix, bename=name, beattrs=beattrs)
+    except ldap.ALREADY_EXISTS:
+        raise
+    finally:
+        conn.added_backends.add(suffix)
+
+    conn.add(e)
+    conn.added_entries.append(e.dn)
+
+    return ret
+
+
+def setupBackend_ok_test():
+    "setupBackend_ok calls brooker.Backend.add"
+    try:
+        backendEntry, dummy = conn.backend.add('o=mockbe5',
+                                               benamebase='mockbe5')
+        assert backendEntry
+    except ldap.ALREADY_EXISTS:
+        raise
+    finally:
+        conn.backend.delete(benamebase='mockbe5')
+
+
+@raises(ldap.ALREADY_EXISTS)
+def setupBackend_double_test():
+    "setupBackend_double calls brooker.Backend.add"
+    backendEntry, dummy = conn.backend.add('o=mockbe3', benamebase='mockbe3')
+    backendEntry, dummy = conn.backend.add('o=mockbe3', benamebase='mockbe3')
+
+
+def addsuffix_test():
+    # identical to getMTEntry_present_test in dsadmin_basic_test
+    # addbackend_harn(conn, 'addressbook16')
+    # conn.added_backends.add('o=addressbook16')
+    pass
+
+
+def addreplica_write_test():
+    suffix = 'o=ab3'
+    backend = 'ab3'
+    user = {
+        'binddn': 'uid=rmanager,cn=config',
+        'bindpw': 'password'
+    }
+    replica = {
+        'suffix': suffix,
+        'type': lib389.MASTER_TYPE,
+        'id': 124
+    }
+    replica.update(user)
+
+    # create backend and suffix
+    backendEntry, dummy = conn.backend.add(suffix, benamebase=backend)
+    suffixEntry = conn.backend.setup_mt(suffix, backend)
+
+    ret = conn.replicaSetupAll(replica)
+
+    assert ret != -1, "Error in setup replica: %s" % ret
+
+
+def prepare_master_replica_test():
+    """prepare_master_replica -> Replica.changelog"""
+    user = {
+        'binddn': 'uid=rmanager,cn=config',
+        'bindpw': 'password'
+    }
+    conn.enableReplLogging()
+    e = conn.setupBindDN(**user)
+    conn.added_entries.append(e.dn)
+
+    # only for Writable
+    e = conn.replica.changelog()
+    conn.added_entries.append(e.dn)
+
+
+@with_setup(setup_backend)
+def setupAgreement_test():
+    consumer = MockDirSrv()
+    args = {
+        'suffix': "o=addressbook6",
+        # 'bename': "userRoot",
+        'binddn': "uid=rmanager,cn=config",
+        'bindpw': "password",
+        'rtype': lib389.MASTER_TYPE,
+        'rid': '1234'
+    }
+    conn.replica.add(**args)
+    conn.added_entries.append(args['binddn'])
+
+    dn_replica = conn.createAgreement(consumer, args)
+
+
+def stop_start_test():
+    # dunno why DirSrv.start|stop writes to dirsrv error-log
+    conn.errlog = "/tmp/dirsrv-errlog"
+    open(conn.errlog, "w").close()
+    DirSrvTools.stop(conn)
+    log.info("server stopped")
+    DirSrvTools.start(conn)
+    log.info("server start")
+    time.sleep(5)
+    # save and restore conn settings after restart
+    tmp = conn.added_backends, conn.added_entries
+    setup()
+    conn.added_backends, conn.added_entries = tmp
+    assert conn.search_s(
+        *utils.searches['NAMINGCONTEXTS']), "Missing namingcontexts"
+
+
+def setupSSL_test():
+    ssl_args = {
+        'dirsrv': conn,
+        'secport': 22636,
+        'sourcedir': None,
+        'secargs': {'nsSSLPersonalitySSL': 'localhost'},
+    }
+    cert_dir = conn.getDseAttr('nsslapd-certdir')
+    assert cert_dir, "Cannot retrieve cert dir"
+
+    log.info("Initialize the cert store with an empty password: %r", cert_dir)
+    fd_null = open('/dev/null', 'w')
+    open('%s/pin.txt' % cert_dir, 'w').close()
+    cmd_initialize = 'certutil -d %s -N -f %s/pin.txt' % (cert_dir, cert_dir)
+    Popen(cmd_initialize.split(), stderr=fd_null)
+
+    log.info("Creating a self-signed cert for the server in %r" % cert_dir)
+    cmd_mkcert = ('certutil -d %s -S -n localhost  -t CTu,Cu,Cu  '
+                  '-s cn=localhost -x' % cert_dir)
+    Popen(cmd_mkcert.split(), stdin=open("/dev/urandom"), stderr=fd_null)
+
+    log.info("Testing ssl configuration")
+    ssl_args.update({'dirsrv': conn})
+    DirSrvTools.setupSSL(**ssl_args)
diff --git a/lib389/tests/effective_rights_test.py b/lib389/tests/effective_rights_test.py
new file mode 100644
index 0000000..84a0418
--- /dev/null
+++ b/lib389/tests/effective_rights_test.py
@@ -0,0 +1,93 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+from lib389._constants import *
+from lib389 import DirSrv, Entry
+import pytest
+import logging
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'effectiverightsds'
+TEST_USER = 'uid=test,%s' % DEFAULT_SUFFIX
+TEST_GROUP = 'cn=testgroup,%s' % DEFAULT_SUFFIX
+
+
+class TopologyInstance(object):
+    def __init__(self, instance):
+        instance.open()
+        self.instance = instance
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    instance = DirSrv(verbose=False)
+    instance.log.debug("Instance allocated")
+    args = {SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT,
+            SER_SERVERID_PROP: INSTANCE_SERVERID}
+    instance.allocate(args)
+    if instance.exists():
+        instance.delete()
+    instance.create()
+    instance.open()
+
+    def fin():
+        if instance.exists():
+            instance.delete()
+    request.addfinalizer(fin)
+
+    return TopologyInstance(instance)
+
+
+@pytest.fixture(scope="module")
+def add_user(topology):
+    """Create a user entry"""
+
+    log.info('Create a user entry: %s' % TEST_USER)
+    uentry = Entry(TEST_USER)
+    uentry.setValues('objectclass', 'top', 'extensibleobject')
+    uentry.setValues('uid', 'test')
+    topology.instance.add_s(uentry)
+    # topology.instance.log.debug("Created user entry as:" ,uentry.dn)
+
+
+@pytest.fixture(scope="module")
+def add_group(topology):
+    """Create a group for the user to have some rights to"""
+
+    log.info('Create a group entry: %s' % TEST_GROUP)
+    gentry = Entry(TEST_GROUP)
+    gentry.setValues('objectclass', 'top', 'extensibleobject')
+    gentry.setValues('cn', 'testgroup')
+    topology.instance.add_s(gentry)
+
+
+def test_effective_rights(topology, add_user, add_group):
+    """Run an effective rights search
+    and compare actual results with expected
+    """
+
+    log.info('Search for effective rights with get_effective_rights() '
+             'function')
+    result = topology.instance.get_effective_rights(TEST_USER,
+                                                    filterstr='(cn=testgroup)',
+                                                    attrlist=['cn'])
+
+    rights = result[0]
+    log.info('Assert that "attributeLevelRights: cn:rsc" and '
+             '"entryLevelRights: v"')
+    assert rights.getValue('attributeLevelRights') == 'cn:rsc'
+    assert rights.getValue('entryLevelRights') == 'v'
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/lib389/tests/entry_test.py b/lib389/tests/entry_test.py
new file mode 100644
index 0000000..46fee29
--- /dev/null
+++ b/lib389/tests/entry_test.py
@@ -0,0 +1,98 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+from lib389 import Entry
+import lib389
+import pytest
+
+import logging
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger(__name__)
+
+
+class TestEntry(object):
+    """A properly initialized Entry:
+        - accepts well-formed or empty dn and tuples;
+        - refuses empty dn
+    """
+    def test_init_empty(self):
+        e = Entry('')
+        assert not e.dn
+
+    def test_init_with_str(self):
+        e = Entry('o=pippo')
+        assert e.dn == 'o=pippo'
+
+    def test_init_badstr(self):
+        # This should not be allowed
+        with pytest.raises(ValueError):
+            e = Entry('no equal sign here')
+
+    def test_init_with_tuple(self):
+        expected = 'pippo'
+        given = 'o=pippo'
+        t = (given, {
+             'o': [expected],
+             'objectclass': ['organization', 'top']
+             })
+        e = Entry(t)
+        assert e.dn == given
+        assert expected in e.o
+
+    def test_update(self):
+        expected = 'pluto minnie'
+        given = {'cn': expected}
+        t = ('o=pippo', {
+             'o': ['pippo'],
+             'objectclass': ['organization', 'top']
+             })
+
+        e = Entry(t)
+        e.update(given)
+        assert e.cn == expected, "Bad cn: %s, expected: %s" % (e.cn, expected)
+
+    def test_update_complex(self):
+        # compare two entries created with different methods
+        nsuffix, replid, replicatype = ("dc=example,dc=com", 5,
+                                        lib389.REPLICA_RDWR_TYPE)
+        binddnlist, legacy = ['uid=pippo, cn=config'], 'off'
+        dn = "dc=example,dc=com"
+        entry = Entry(dn)
+        entry.setValues(
+            'objectclass', "top", "nsds5replica", "extensibleobject")
+        entry.setValues('cn', "replica")
+        entry.setValues('nsds5replicaroot', nsuffix)
+        entry.setValues('nsds5replicaid', str(replid))
+        entry.setValues('nsds5replicatype', str(replicatype))
+        entry.setValues('nsds5flags', "1")
+        entry.setValues('nsds5replicabinddn', binddnlist)
+        entry.setValues('nsds5replicalegacyconsumer', legacy)
+
+        uentry = Entry((
+            dn, {'objectclass': ["top", "nsds5replica", "extensibleobject"],
+                 'cn': ["replica"]})
+        )
+        log.debug("Entry created with dict:", uentry)
+        # Entry.update *replaces*, so be careful with multi-valued attrs
+        uentry.update({
+            'nsds5replicaroot': nsuffix,
+            'nsds5replicaid': str(replid),
+            'nsds5replicatype': str(replicatype),
+            'nsds5flags': '1',
+            'nsds5replicabinddn': binddnlist,
+            'nsds5replicalegacyconsumer': legacy
+        })
+        uentry_s, entry_s = list(map(str, (uentry, entry)))
+        assert uentry_s == entry_s, "Mismatching entries [%r] vs [%r]" % (
+            uentry, entry)
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/lib389/tests/krb5_create_test.py b/lib389/tests/krb5_create_test.py
new file mode 100644
index 0000000..efdb298
--- /dev/null
+++ b/lib389/tests/krb5_create_test.py
@@ -0,0 +1,99 @@
+
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+from lib389._constants import *
+from lib389.mit_krb5 import MitKrb5, KrbClient
+from lib389 import DirSrv, Entry
+import pytest
+import logging
+
+import ldap
+import ldap.sasl
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'gssapi'
+REALM = "EXAMPLE.COM"
+TEST_USER = 'uid=test,%s' % DEFAULT_SUFFIX
+
+
+class TopologyInstance(object):
+    def __init__(self, instance):
+        instance.open()
+        self.instance = instance
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    # Create the realm
+    krb = MitKrb5(realm=REALM)
+    instance = DirSrv(verbose=False)
+    instance.log.debug("Instance allocated")
+    args = {SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT,
+            SER_REALM: REALM,
+            SER_SERVERID_PROP: INSTANCE_SERVERID}
+    instance.allocate(args)
+    if instance.exists():
+        instance.delete()
+    # Its likely our realm exists too
+    if krb.check_realm():
+        krb.destroy_realm()
+    # This will automatically create the krb entries
+    krb.create_realm()
+    instance.create()
+    instance.open()
+
+    def fin():
+        if instance.exists():
+            instance.delete()
+        if krb.check_realm():
+            krb.destroy_realm()
+    request.addfinalizer(fin)
+
+    return TopologyInstance(instance)
+
+
+@pytest.fixture(scope="module")
+def add_user(topology):
+    """
+    Create a user entry
+    """
+
+    log.info('Create a user entry: %s' % TEST_USER)
+    uentry = Entry(TEST_USER)
+    uentry.setValues('objectclass', 'top', 'extensibleobject')
+    uentry.setValues('uid', 'test')
+    topology.instance.add_s(uentry)
+    # This doesn't matter that we re-open the realm
+    krb = MitKrb5(realm=REALM)
+    krb.create_principal("test")
+    # We extract the kt so we can kinit from it
+    krb.create_keytab("test", "/tmp/test.keytab")
+
+
+def test_gssapi(topology, add_user):
+    """
+    Check that our bind completese with ldapwhoami correctly mapped from
+    the principal to our test user object.
+    """
+    # Init our local ccache
+    kclient = KrbClient("test@%s" % REALM, "/tmp/test.keytab")
+    # Probably need to change this to NOT be raw python ldap
+    conn = ldap.initialize("ldap://%s:%s" % (LOCALHOST, INSTANCE_PORT))
+    sasl = ldap.sasl.gssapi()
+    conn.sasl_interactive_bind_s('', sasl)
+    assert(conn.whoami_s() == "dn: uid=test,dc=example,dc=com")
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/lib389/tests/mappingTree_test.py b/lib389/tests/mappingTree_test.py
new file mode 100644
index 0000000..b26e90d
--- /dev/null
+++ b/lib389/tests/mappingTree_test.py
@@ -0,0 +1,271 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import pytest
+import logging
+from lib389._constants import *
+from lib389.properties import *
+from lib389 import DirSrv, InvalidArgumentError
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+TEST_REPL_DN = "uid=test,%s" % DEFAULT_SUFFIX
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'dirsrv'
+INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
+NEW_SUFFIX_1 = 'o=test_create'
+NEW_BACKEND_1 = 'test_createdb'
+NEW_CHILDSUFFIX_1 = 'o=child1,o=test_create'
+NEW_CHILDBACKEND_1 = 'test_createchilddb'
+NEW_SUFFIX_2 = 'o=test_bis_create'
+NEW_BACKEND_2 = 'test_bis_createdb'
+NEW_CHILDSUFFIX_2 = 'o=child2,o=test_bis_create'
+NEW_CHILDBACKEND_2 = 'test_bis_createchilddb'
+
+
+class TopologyInstance(object):
+    def __init__(self, instance):
+        instance.open()
+        self.instance = instance
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    instance = DirSrv(verbose=False)
+    instance.log.debug("Instance allocated")
+    args = {SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT,
+            SER_SERVERID_PROP: INSTANCE_SERVERID}
+    instance.allocate(args)
+    if instance.exists():
+        instance.delete()
+    instance.create()
+    instance.open()
+
+    def fin():
+        instance.delete()
+    request.addfinalizer(fin)
+
+    return TopologyInstance(instance)
+
+
+def test_list(topology):
+    """This test list with only no param, suffix,
+    bename, suffix+bename (also with invalid values)
+    """
+
+    ents = topology.instance.mappingtree.list()
+    for ent in ents:
+            log.info('test_list: %r' % ent)
+
+    log.info("get with a dedicated suffix")
+    ents = topology.instance.mappingtree.list(suffix=DEFAULT_SUFFIX)
+    assert len(ents) == 1
+    log.info('test_list(suffix): %r' % ent)
+
+    ents = topology.instance.mappingtree.list(suffix="dc=dummy")
+    assert len(ents) == 0
+
+    log.info("get with a dedicated backend name")
+    ents = topology.instance.mappingtree.list(bename=DEFAULT_BENAME)
+    assert len(ents) == 1
+    log.info('test_list(bename): %r' % ent)
+
+    ents = topology.instance.mappingtree.list(bename="dummy")
+    assert len(ents) == 0
+
+    log.info("check backend is taken first")
+    ents = topology.instance.mappingtree.list(suffix="dc=dummy",
+                                              bename=DEFAULT_BENAME)
+    assert len(ents) == 1
+    log.info('test_list(suffix, bename): %r' % ent)
+
+
+def test_create(topology):
+    """This test will create 2 backends/mapping trees,
+    then 2 childs backend/mapping tree
+    """
+
+    log.info("before creating mapping trees, the backends must exists")
+    backendEntry = topology.instance.backend.create(
+        NEW_SUFFIX_1, {BACKEND_NAME: NEW_BACKEND_1})
+    backendEntry = topology.instance.backend.create(
+        NEW_SUFFIX_2, {BACKEND_NAME: NEW_BACKEND_2})
+
+    ents = topology.instance.mappingtree.list()
+    nb_mappingtree = len(ents)
+
+    log.info("create a first additional mapping tree")
+    topology.instance.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree + 1)
+
+    log.info("create a second additional mapping tree")
+    topology.instance.mappingtree.create(NEW_SUFFIX_2, bename=NEW_BACKEND_2)
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree + 2)
+
+    log.info("Creating a mapping tree that already exists => "
+             "it just returns the existing MT")
+    topology.instance.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree + 2)
+
+    log.info("Creating a mapping tree that already exists => "
+             "it just returns the existing MT")
+    topology.instance.mappingtree.create(NEW_SUFFIX_2, bename=NEW_BACKEND_2)
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree + 2)
+
+    log.info("before creating mapping trees, the backends must exists")
+    backendEntry = topology.instance.backend.create(
+        NEW_CHILDSUFFIX_1, {BACKEND_NAME: NEW_CHILDBACKEND_1})
+    backendEntry = topology.instance.backend.create(
+        NEW_CHILDSUFFIX_2, {BACKEND_NAME: NEW_CHILDBACKEND_2})
+
+    log.info("create a third additional mapping tree, that is child "
+             "of NEW_SUFFIX_1")
+    topology.instance.mappingtree.create(
+        NEW_CHILDSUFFIX_1, bename=NEW_CHILDBACKEND_1, parent=NEW_SUFFIX_1)
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree + 3)
+
+    ents = topology.instance.mappingtree.list(suffix=NEW_CHILDSUFFIX_1)
+    assert len(ents) == 1
+    ent = ents[0]
+    assert ent.hasAttr(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX]) and \
+        (ent.getValue(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX]) ==
+         NEW_SUFFIX_1)
+
+    log.info("create a fourth additional mapping tree, that is child "
+             "of NEW_SUFFIX_2")
+    topology.instance.mappingtree.create(NEW_CHILDSUFFIX_2,
+                                         bename=NEW_CHILDBACKEND_2,
+                                         parent=NEW_SUFFIX_2)
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree + 4)
+
+    ents = topology.instance.mappingtree.list(suffix=NEW_CHILDSUFFIX_2)
+    assert len(ents) == 1
+    ent = ents[0]
+    assert ent.hasAttr(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX]) and \
+        (ent.getValue(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX]) ==
+         NEW_SUFFIX_2)
+
+
+def test_delete(topology):
+    """Delete the mapping tree and check the remaining number.
+    Delete the sub-suffix first.
+    """
+
+    ents = topology.instance.mappingtree.list()
+    nb_mappingtree = len(ents)
+    deleted = 0
+
+    log.debug("delete MT for suffix " + NEW_CHILDSUFFIX_1)
+    topology.instance.mappingtree.delete(suffix=NEW_CHILDSUFFIX_1)
+    deleted += 1
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree - deleted)
+
+    log.debug("delete MT with backend " + NEW_CHILDBACKEND_2)
+    topology.instance.mappingtree.delete(bename=NEW_CHILDBACKEND_2)
+    deleted += 1
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree - deleted)
+
+    log.debug("delete MT for suffix %s and with backend %s" %
+              (NEW_SUFFIX_1, NEW_BACKEND_1))
+    topology.instance.mappingtree.delete(suffix=NEW_SUFFIX_1,
+                                         bename=NEW_BACKEND_1)
+    deleted += 1
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree - deleted)
+
+    ents = topology.instance.mappingtree.list(suffix=NEW_SUFFIX_2)
+    assert len(ents) == 1
+    log.debug("delete MT with DN %s (dummy suffix/backend)" % (ents[0].dn))
+    topology.instance.mappingtree.delete(suffix="o=dummy", bename="foo",
+                                         name=ents[0].dn)
+
+
+def test_getProperties(topology):
+    """Create one additional mapping tree
+    and try to get properties from it
+    """
+
+    ents = topology.instance.mappingtree.list()
+    nb_mappingtree = len(ents)
+
+    log.info("create a first additional mapping tree")
+    topology.instance.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
+    ents = topology.instance.mappingtree.list()
+    assert len(ents) == (nb_mappingtree + 1)
+
+    log.info("check we can get properties from suffix")
+    prop_ref = topology.instance.mappingtree.getProperties(suffix=NEW_SUFFIX_1)
+    log.info("properties [suffix] %s: %r" % (NEW_SUFFIX_1, prop_ref))
+
+    log.info("check we can get properties from backend name")
+    properties = topology.instance.mappingtree.getProperties(
+        bename=NEW_BACKEND_1)
+    for key in list(properties.keys()):
+        assert prop_ref[key] == properties[key]
+    log.info("properties [backend] %s: %r" % (NEW_SUFFIX_1, properties))
+
+    log.info("check we can get properties from suffix AND backend name")
+    properties = topology.instance.mappingtree.getProperties(
+        suffix=NEW_SUFFIX_1, bename=NEW_BACKEND_1)
+    for key in list(properties.keys()):
+        assert prop_ref[key] == properties[key]
+    log.info("properties [suffix+backend]%s: %r" % (NEW_SUFFIX_1, properties))
+
+    log.info("check we can get properties from MT entry")
+    ents = topology.instance.mappingtree.list(suffix=NEW_SUFFIX_1)
+    assert len(ents) == 1
+    ent = ents[0]
+    properties = topology.instance.mappingtree.getProperties(name=ent.dn)
+    for key in list(properties.keys()):
+        assert prop_ref[key] == properties[key]
+    log.info("properties [MT entry DN] %s: %r" % (NEW_SUFFIX_1, properties))
+
+    log.info("check we can get only one properties")
+    properties = topology.instance.mappingtree.getProperties(
+        name=ent.dn, properties=[MT_STATE])
+    assert len(properties) == 1
+    assert properties[MT_STATE] == prop_ref[MT_STATE]
+
+    with pytest.raises(KeyError):
+        properties = topology.instance.mappingtree.getProperties(
+            name=ent.dn, properties=['dummy'])
+
+
+def test_toSuffix(topology):
+    """Try to get suffix name from existing mapping tree"""
+
+    ents = topology.instance.mappingtree.list()
+    log.info("check we can get suffix from a mapping tree by entry")
+    suffix = topology.instance.mappingtree.toSuffix(entry=ents[0])
+    assert len(suffix) > 0
+    log.info("suffix (entry) is %s" % suffix[0])
+
+    log.info("check we can get suffix from a mapping tree by name")
+    suffix = topology.instance.mappingtree.toSuffix(name=ents[0].dn)
+    assert len(suffix) > 0
+    log.info("suffix (dn) is %s" % suffix[0])
+
+    log.info("check we can not get suffix from a mapping tree by nothing")
+    with pytest.raises(InvalidArgumentError):
+        suffix = topology.instance.mappingtree.toSuffix()
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/lib389/tests/replica_test.py b/lib389/tests/replica_test.py
new file mode 100644
index 0000000..9eb0078
--- /dev/null
+++ b/lib389/tests/replica_test.py
@@ -0,0 +1,459 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import ldap
+import os
+import pytest
+import logging
+
+from lib389 import InvalidArgumentError
+from lib389._constants import *
+from lib389.properties import *
+from lib389 import DirSrv, Entry
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+# Used for One master / One consumer topology
+HOST_MASTER = LOCALHOST
+PORT_MASTER = 40389
+SERVERID_MASTER = 'master'
+REPLICAID_MASTER = 1
+
+HOST_CONSUMER = LOCALHOST
+PORT_CONSUMER = 50389
+SERVERID_CONSUMER = 'consumer'
+
+TEST_REPL_DN = "uid=test,%s" % DEFAULT_SUFFIX
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'dirsrv'
+INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
+NEW_SUFFIX_1 = 'ou=test_master'
+NEW_BACKEND_1 = 'test_masterdb'
+NEW_RM_1 = "cn=replrepl,%s" % NEW_SUFFIX_1
+
+NEW_SUFFIX_2 = 'ou=test_consumer'
+NEW_BACKEND_2 = 'test_consumerdb'
+
+NEW_SUFFIX_3 = 'ou=test_enablereplication_1'
+NEW_BACKEND_3 = 'test_enablereplicationdb_1'
+
+NEW_SUFFIX_4 = 'ou=test_enablereplication_2'
+NEW_BACKEND_4 = 'test_enablereplicationdb_2'
+
+NEW_SUFFIX_5 = 'ou=test_enablereplication_3'
+NEW_BACKEND_5 = 'test_enablereplicationdb_3'
+
+
+class TopologyReplication(object):
+    def __init__(self, master, consumer):
+        master.open()
+        consumer.open()
+        self.master = master
+        self.consumer = consumer
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    # Create the master instance
+    master = DirSrv(verbose=False)
+    master.log.debug("Master allocated")
+    args = {SER_HOST: HOST_MASTER,
+            SER_PORT: PORT_MASTER,
+            SER_SERVERID_PROP: SERVERID_MASTER}
+    master.allocate(args)
+    if master.exists():
+        master.delete()
+    master.create()
+    master.open()
+
+    # Create the consumer instance
+    consumer = DirSrv(verbose=False)
+    consumer.log.debug("Consumer allocated")
+    args = {SER_HOST: HOST_CONSUMER,
+            SER_PORT: PORT_CONSUMER,
+            SER_SERVERID_PROP: SERVERID_CONSUMER}
+    consumer.allocate(args)
+    if consumer.exists():
+        consumer.delete()
+    consumer.create()
+    consumer.open()
+
+    # Delete each instance in the end
+    def fin():
+        master.delete()
+        consumer.delete()
+    request.addfinalizer(fin)
+
+    return TopologyReplication(master, consumer)
+
+
+def test_create(topology):
+    """This test creates
+         - suffix/backend (NEW_SUFFIX_[12], NEW_BACKEND_[12]) : Master
+         - suffix/backend (NEW_SUFFIX_[12], NEW_BACKEND_[12]) : Consumer
+         - replica NEW_SUFFIX_1 as MASTER : Master
+         - replica NEW_SUFFIX_2 as CONSUMER : Master
+    """
+
+    log.info("\n\n##########\n### CREATE\n############")
+    #
+    # MASTER (suffix/backend)
+    #
+    backendEntry = topology.master.backend.create(
+        suffix=NEW_SUFFIX_1, properties={BACKEND_NAME: NEW_BACKEND_1})
+    backendEntry = topology.master.backend.create(
+        suffix=NEW_SUFFIX_2, properties={BACKEND_NAME: NEW_BACKEND_2})
+
+    ents = topology.master.mappingtree.list()
+    master_nb_mappingtree = len(ents)
+
+    # create a first additional mapping tree
+    topology.master.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
+    ents = topology.master.mappingtree.list()
+    assert len(ents) == (master_nb_mappingtree + 1)
+    topology.master.add_s(Entry((NEW_SUFFIX_1,
+                          {'objectclass': "top organizationalunit".split(),
+                           'ou': NEW_SUFFIX_1.split('=', 1)[1]})))
+
+    # create a second additional mapping tree
+    topology.master.mappingtree.create(NEW_SUFFIX_2, bename=NEW_BACKEND_2)
+    ents = topology.master.mappingtree.list()
+    assert len(ents) == (master_nb_mappingtree + 2)
+    topology.master.add_s(Entry((NEW_SUFFIX_2,
+                          {'objectclass': "top organizationalunit".split(),
+                           'ou': NEW_SUFFIX_2.split('=', 1)[1]})))
+    log.info('Master it exists now %d suffix(es)' % len(ents))
+
+    #
+    # CONSUMER (suffix/backend)
+    #
+    backendEntry = topology.consumer.backend.create(
+        suffix=NEW_SUFFIX_1, properties={BACKEND_NAME: NEW_BACKEND_1})
+    backendEntry = topology.consumer.backend.create(
+        suffix=NEW_SUFFIX_2, properties={BACKEND_NAME: NEW_BACKEND_2})
+
+    ents = topology.consumer.mappingtree.list()
+    consumer_nb_mappingtree = len(ents)
+
+    # create a first additional mapping tree
+    topology.consumer.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
+    ents = topology.consumer.mappingtree.list()
+    assert len(ents) == (consumer_nb_mappingtree + 1)
+    topology.consumer.add_s(Entry((NEW_SUFFIX_1,
+                            {'objectclass': "top organizationalunit".split(),
+                             'ou': NEW_SUFFIX_1.split('=', 1)[1]})))
+
+    # create a second additional mapping tree
+    topology.consumer.mappingtree.create(NEW_SUFFIX_2, bename=NEW_BACKEND_2)
+    ents = topology.consumer.mappingtree.list()
+    assert len(ents) == (consumer_nb_mappingtree + 2)
+    topology.consumer.add_s(Entry((NEW_SUFFIX_2,
+                            {'objectclass': "top organizationalunit".split(),
+                             'ou': NEW_SUFFIX_2.split('=', 1)[1]})))
+    log.info('Consumer it exists now %d suffix(es)' % len(ents))
+
+    #
+    # Now create REPLICAS on master
+    #
+    # check it exists this entry to stores the changelogs
+    topology.master.changelog.create()
+
+    # create a master
+    topology.master.replica.create(suffix=NEW_SUFFIX_1,
+                                   role=REPLICAROLE_MASTER,
+                                   rid=1)
+    ents = topology.master.replica.list()
+    assert len(ents) == 1
+    log.info('Master replica %s' % ents[0].dn)
+
+    # create a consumer
+    topology.master.replica.create(suffix=NEW_SUFFIX_2,
+                                   role=REPLICAROLE_CONSUMER)
+    ents = topology.master.replica.list()
+    assert len(ents) == 2
+    ents = topology.master.replica.list(suffix=NEW_SUFFIX_2)
+    log.info('Consumer replica %s' % ents[0].dn)
+
+    #
+    # Now create REPLICAS on consumer
+    #
+    # create a master
+    topology.consumer.replica.create(suffix=NEW_SUFFIX_1,
+                                     role=REPLICAROLE_CONSUMER)
+    ents = topology.consumer.replica.list()
+    assert len(ents) == 1
+    log.info('Consumer replica %s' % ents[0].dn)
+
+    # create a consumer
+    topology.consumer.replica.create(suffix=NEW_SUFFIX_2,
+                                     role=REPLICAROLE_CONSUMER)
+    ents = topology.consumer.replica.list()
+    assert len(ents) == 2
+    ents = topology.consumer.replica.list(suffix=NEW_SUFFIX_2)
+    log.info('Consumer replica %s' % ents[0].dn)
+
+
+def test_list(topology):
+    """This test checks:
+         - existing replicas can be retrieved
+         - access to unknown replica does not fail
+
+    PRE-CONDITION:
+         It exists on MASTER two replicas NEW_SUFFIX_1 and NEW_SUFFIX_2
+         created by test_create()
+    """
+
+    log.info("\n\n############\n### LIST\n############")
+    ents = topology.master.replica.list()
+    assert len(ents) == 2
+
+    # Check we can retrieve a replica with its suffix
+    ents = topology.master.replica.list(suffix=NEW_SUFFIX_1)
+    assert len(ents) == 1
+    replica_dn_1 = ents[0].dn
+
+    # Check we can retrieve a replica with its suffix
+    ents = topology.master.replica.list(suffix=NEW_SUFFIX_2)
+    assert len(ents) == 1
+    replica_dn_2 = ents[0].dn
+
+    # Check we can retrieve a replica with its DN
+    ents = topology.master.replica.list(replica_dn=replica_dn_1)
+    assert len(ents) == 1
+    assert replica_dn_1 == ents[0].dn
+
+    # Check we can retrieve a replica if we provide DN and suffix
+    ents = topology.master.replica.list(suffix=NEW_SUFFIX_2,
+                                        replica_dn=replica_dn_2)
+    assert len(ents) == 1
+    assert replica_dn_2 == ents[0].dn
+
+    # Check DN is used before suffix name
+    ents = topology.master.replica.list(suffix=NEW_SUFFIX_2,
+                                        replica_dn=replica_dn_1)
+    assert len(ents) == 1
+    assert replica_dn_1 == ents[0].dn
+
+    # Check that invalid value does not break
+    ents = topology.master.replica.list(suffix="X")
+    for ent in ents:
+        log.critical("Unexpected replica: %s" % ent.dn)
+    assert len(ents) == 0
+
+
+def test_create_repl_manager(topology):
+    """The tests are
+         - create the default Replication manager/Password
+         - create a specific Replication manager/ default Password
+         - Check we can bind successfully
+         - create a specific Replication manager / specific Password
+         - Check we can bind successfully
+    """
+
+    log.info("\n\n###########\n### CREATE_REPL_MANAGER\n###########")
+    # First create the default replication manager
+    topology.consumer.replica.create_repl_manager()
+    ents = topology.consumer.search_s(defaultProperties[REPLICATION_BIND_DN],
+                                      ldap.SCOPE_BASE, "objectclass=*")
+    assert len(ents) == 1
+    assert ents[0].dn == defaultProperties[REPLICATION_BIND_DN]
+
+    # Second create a custom replication manager under NEW_SUFFIX_2
+    rm_dn = "cn=replrepl,%s" % NEW_SUFFIX_2
+    topology.consumer.replica.create_repl_manager(repl_manager_dn=rm_dn)
+    ents = topology.consumer.search_s(rm_dn, ldap.SCOPE_BASE, "objectclass=*")
+    assert len(ents) == 1
+    assert ents[0].dn == rm_dn
+
+    # Check we can bind
+    topology.consumer.simple_bind_s(rm_dn,
+                                    defaultProperties[REPLICATION_BIND_PW])
+
+    # Check we fail to bind
+    with pytest.raises(ldap.INVALID_CREDENTIALS) as excinfo:
+        topology.consumer.simple_bind_s(rm_dn, "dummy")
+    log.info("Exception: %s" % str(excinfo.value))
+
+    # now rebind
+    topology.consumer.simple_bind_s(topology.consumer.binddn,
+                                    topology.consumer.bindpw)
+
+    # Create a custom replication manager under NEW_SUFFIX_1
+    # with a specified password
+    rm_dn = NEW_RM_1
+    topology.consumer.replica.create_repl_manager(repl_manager_dn=rm_dn,
+                                                  repl_manager_pw="Secret123")
+    ents = topology.consumer.search_s(rm_dn, ldap.SCOPE_BASE, "objectclass=*")
+    assert len(ents) == 1
+    assert ents[0].dn == rm_dn
+
+    # Check we can bind
+    topology.consumer.simple_bind_s(rm_dn, "Secret123")
+
+    # Check we fail to bind
+    with pytest.raises(ldap.INVALID_CREDENTIALS) as excinfo:
+        topology.consumer.simple_bind_s(rm_dn, "dummy")
+    log.info("Exception: %s" % str(excinfo.value))
+    topology.consumer.simple_bind_s(topology.consumer.binddn,
+                                    topology.consumer.bindpw)
+
+
+def test_enableReplication(topology):
+    """It checks
+         - Ability to enable replication on a supplier
+         - Ability to enable replication on a consumer
+         - Failure to enable replication with wrong replicaID on supplier
+         - Failure to enable replication with wrong replicaID on consumer
+    """
+
+    log.info("\n\n############\n### ENABLEREPLICATION\n##########")
+    #
+    # MASTER (suffix/backend)
+    #
+    backendEntry = topology.master.backend.create(suffix=NEW_SUFFIX_3,
+                                                  properties={BACKEND_NAME:
+                                                              NEW_BACKEND_3})
+
+    ents = topology.master.mappingtree.list()
+    master_nb_mappingtree = len(ents)
+
+    # create a first additional mapping tree
+    topology.master.mappingtree.create(NEW_SUFFIX_3, bename=NEW_BACKEND_3)
+    ents = topology.master.mappingtree.list()
+    assert len(ents) == (master_nb_mappingtree + 1)
+    topology.master.add_s(Entry((NEW_SUFFIX_3,
+                          {'objectclass': "top organizationalunit".split(),
+                           'ou': NEW_SUFFIX_3.split('=', 1)[1]})))
+
+    # a supplier should have replicaId in [1..CONSUMER_REPLICAID[
+    with pytest.raises(ValueError) as excinfo:
+        topology.master.replica.enableReplication(suffix=NEW_SUFFIX_3,
+                                                  role=REPLICAROLE_MASTER,
+                                                  replicaId=CONSUMER_REPLICAID)
+    log.info("Exception (expected): %s" % str(excinfo.value))
+    topology.master.replica.enableReplication(suffix=NEW_SUFFIX_3,
+                                              role=REPLICAROLE_MASTER,
+                                              replicaId=1)
+
+    #
+    # MASTER (suffix/backend)
+    #
+    backendEntry = topology.master.backend.create(suffix=NEW_SUFFIX_4,
+                                                  properties={BACKEND_NAME:
+                                                              NEW_BACKEND_4})
+
+    ents = topology.master.mappingtree.list()
+    master_nb_mappingtree = len(ents)
+
+    # create a first additional mapping tree
+    topology.master.mappingtree.create(NEW_SUFFIX_4, bename=NEW_BACKEND_4)
+    ents = topology.master.mappingtree.list()
+    assert len(ents) == (master_nb_mappingtree + 1)
+    topology.master.add_s(Entry((NEW_SUFFIX_4,
+                          {'objectclass': "top organizationalunit".split(),
+                           'ou': NEW_SUFFIX_4.split('=', 1)[1]})))
+
+    # A consumer should have CONSUMER_REPLICAID not '1'
+    with pytest.raises(ValueError) as excinfo:
+        topology.master.replica.enableReplication(suffix=NEW_SUFFIX_4,
+                                                  role=REPLICAROLE_CONSUMER,
+                                                  replicaId=1)
+    log.info("Exception (expected): %s" % str(excinfo.value))
+    topology.master.replica.enableReplication(suffix=NEW_SUFFIX_4,
+                                              role=REPLICAROLE_CONSUMER)
+
+
+def test_disableReplication(topology):
+    """It checks
+         - Ability to disable replication on a supplier
+         - Ability to disable replication on a consumer
+         - Failure to disable replication with wrong suffix on supplier
+         - Failure to disable replication with wrong suffix on consumer
+    """
+
+    log.info("\n\n############\n### DISABLEREPLICATION\n##########")
+    topology.master.replica.disableReplication(suffix=NEW_SUFFIX_3)
+    with pytest.raises(ldap.LDAPError) as excinfo:
+        topology.master.replica.disableReplication(suffix=NEW_SUFFIX_3)
+    log.info("Exception (expected): %s" % str(excinfo.value))
+
+    topology.master.replica.disableReplication(suffix=NEW_SUFFIX_4)
+    with pytest.raises(ldap.LDAPError) as excinfo:
+        topology.master.replica.disableReplication(suffix=NEW_SUFFIX_4)
+    log.info("Exception (expected): %s" % str(excinfo.value))
+
+
+def test_setProperties(topology):
+    """Set some properties
+    Verified that valid properties are set
+    Verified that invalid properties raise an Exception
+
+    PRE-REQUISITE: it exists a replica for NEW_SUFFIX_1
+    """
+
+    log.info("\n\n##########\n### SETPROPERTIES\n############")
+    # set valid values to SUFFIX_1
+    properties = {REPLICA_LEGACY_CONS: 'off',
+                  REPLICA_BINDDN: NEW_RM_1,
+                  REPLICA_PURGE_INTERVAL: str(3600),
+                  REPLICA_PURGE_DELAY: str(5 * 24 * 3600),
+                  REPLICA_REFERRAL: "ldap://%s:1234/" % LOCALHOST}
+    topology.master.replica.setProperties(suffix=NEW_SUFFIX_1,
+                                          properties=properties)
+
+    # Check the values have been written
+    replicas = topology.master.replica.list(suffix=NEW_SUFFIX_1)
+    assert len(replicas) == 1
+    for prop in properties:
+        attr = REPLICA_PROPNAME_TO_ATTRNAME[prop]
+        val = replicas[0].getValue(attr)
+        log.info("Replica[%s] -> %s: %s" % (prop, attr, val))
+        assert val == properties[prop]
+
+    # Check invalid properties raise exception
+    with pytest.raises(ValueError) as excinfo:
+        properties = {"dummy": 'dummy'}
+        topology.master.replica.setProperties(suffix=NEW_SUFFIX_1,
+                                              properties=properties)
+    log.info("Exception (expected): %s" % str(excinfo.value))
+
+    # check call without suffix/dn/entry raise InvalidArgumentError
+    with pytest.raises(InvalidArgumentError) as excinfo:
+        properties = {REPLICA_LEGACY_CONS: 'off'}
+        topology.master.replica.setProperties(properties=properties)
+    log.info("Exception (expected): %s" % str(excinfo.value))
+
+    # check that if we do not provide a valid entry it raises ValueError
+    with pytest.raises(ValueError) as excinfo:
+        properties = {REPLICA_LEGACY_CONS: 'off'}
+        topology.master.replica.setProperties(replica_entry="dummy",
+                                              properties=properties)
+    log.info("Exception (expected): %s" % str(excinfo.value))
+
+    # check that with an invalid suffix or replica_dn it raise ValueError
+    with pytest.raises(ValueError) as excinfo:
+        properties = {REPLICA_LEGACY_CONS: 'off'}
+        topology.master.replica.setProperties(suffix="dummy",
+                                              properties=properties)
+    log.info("Exception (expected): %s" % str(excinfo.value))
+
+
+def test_getProperties(topology):
+    """Currently not implemented"""
+
+    log.info("\n\n############\n### GETPROPERTIES\n###########")
+    with pytest.raises(NotImplementedError) as excinfo:
+        properties = {REPLICA_LEGACY_CONS: 'off'}
+        topology.master.replica.getProperties(suffix=NEW_SUFFIX_1)
+    log.info("Exception (expected): %s" % str(excinfo.value))
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/lib389/tests/schema_test.py b/lib389/tests/schema_test.py
new file mode 100644
index 0000000..35b82bd
--- /dev/null
+++ b/lib389/tests/schema_test.py
@@ -0,0 +1,61 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import pytest
+from lib389._constants import *
+from lib389 import DirSrv
+
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'schemainspectds'
+
+
+class TopologyInstance(object):
+    def __init__(self, instance):
+        instance.open()
+        self.instance = instance
+
+
+@pytest.fixture(scope="module")
+def topology(request):
+    instance = DirSrv(verbose=False)
+    instance.log.debug("Instance allocated")
+    args = {SER_HOST: LOCALHOST,
+            SER_PORT: INSTANCE_PORT,
+            SER_SERVERID_PROP: INSTANCE_SERVERID}
+    instance.allocate(args)
+    if instance.exists():
+        instance.delete()
+    instance.create()
+    instance.open()
+
+    def fin():
+        instance.delete()
+    request.addfinalizer(fin)
+
+    return TopologyInstance(instance)
+
+
+def test_schema(topology):
+    must_expect = ['uidObject', 'account', 'posixAccount', 'shadowAccount']
+    may_expect = ['cosDefinition', 'inetOrgPerson', 'inetUser',
+                  'mailRecipient']
+    attrtype, must, may = topology.instance.schema.query_attributetype('uid')
+    assert attrtype.names == ('uid', 'userid')
+    for oc in must:
+        assert oc.names[0] in must_expect
+    for oc in may:
+        assert oc.names[0] in may_expect
+    assert topology.instance.schema.query_objectclass('account').names == \
+        ('account', )
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s %s" % CURRENT_FILE)
diff --git a/lib389/tests/suffix_test.py b/lib389/tests/suffix_test.py
new file mode 100644
index 0000000..e3df10b
--- /dev/null
+++ b/lib389/tests/suffix_test.py
@@ -0,0 +1,102 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+
+import os
+from lib389._constants import *
+from lib389.properties import *
+from lib389 import DirSrv
+
+
+TEST_REPL_DN = "uid=test,%s" % DEFAULT_SUFFIX
+INSTANCE_PORT = 54321
+INSTANCE_SERVERID = 'dirsrv'
+# INSTANCE_PREFIX = os.environ.get('PREFIX', None)
+INSTANCE_PREFIX = None
+INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
+NEW_SUFFIX_1 = 'o=test_create'
+NEW_BACKEND_1 = 'test_createdb'
+NEW_CHILDSUFFIX_1 = 'o=child1,o=test_create'
+NEW_CHILDBACKEND_1 = 'test_createchilddb'
+NEW_SUFFIX_2 = 'o=test_bis_create'
+NEW_BACKEND_2 = 'test_bis_createdb'
+NEW_CHILDSUFFIX_2 = 'o=child2,o=test_bis_create'
+NEW_CHILDBACKEND_2 = 'test_bis_createchilddb'
+
+
+class Test_suffix():
+    def setUp(self):
+        instance = DirSrv(verbose=False)
+        instance.log.debug("Instance allocated")
+        args = {SER_HOST: LOCALHOST,
+                SER_PORT: INSTANCE_PORT,
+                SER_DEPLOYED_DIR: INSTANCE_PREFIX,
+                SER_SERVERID_PROP: INSTANCE_SERVERID
+                }
+        instance.allocate(args)
+        if instance.exists():
+            instance.delete()
+        instance.create()
+        instance.open()
+        self.instance = instance
+
+    def tearDown(self):
+        if self.instance.exists():
+            self.instance.delete()
+
+    def test_list(self):
+        # before creating mapping trees, the backends must exists
+        backendEntry = self.instance.backend.create(
+            NEW_SUFFIX_1, {BACKEND_NAME: NEW_BACKEND_1})
+
+        ents = self.instance.mappingtree.list()
+        nb_mappingtree = len(ents)
+
+        # create a first additional mapping tree
+        self.instance.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
+        ents = self.instance.mappingtree.list()
+        assert len(ents) == (nb_mappingtree + 1)
+
+        suffixes = self.instance.suffix.list()
+        assert len(suffixes) == 2
+        for suffix in suffixes:
+            self.instance.log.info("suffix is %s" % suffix)
+
+    def test_toBackend(self):
+        backends = self.instance.suffix.toBackend(suffix=NEW_SUFFIX_1)
+        assert len(backends) == 1
+        backend = backends[0]
+        self.instance.log.info("backend entry is %r" % backend)
+        assert backend.getValue(
+            BACKEND_PROPNAME_TO_ATTRNAME[BACKEND_SUFFIX]) == NEW_SUFFIX_1
+        assert backend.getValue(
+            BACKEND_PROPNAME_TO_ATTRNAME[BACKEND_NAME]) == NEW_BACKEND_1
+
+    def test_getParent(self):
+        parent = self.instance.suffix.getParent(suffix=NEW_SUFFIX_1)
+        assert parent is None
+
+        backendEntry = self.instance.backend.create(
+            NEW_CHILDSUFFIX_1, {BACKEND_NAME: NEW_CHILDBACKEND_1})
+        # create a third additional mapping tree, that is child of NEW_SUFFIX_1
+        self.instance.mappingtree.create(
+            NEW_CHILDSUFFIX_1, bename=NEW_CHILDBACKEND_1, parent=NEW_SUFFIX_1)
+        parent = self.instance.suffix.getParent(suffix=NEW_CHILDSUFFIX_1)
+        self.instance.log.info("Retrieved parent of %s:  %s" %
+                               (NEW_CHILDSUFFIX_1, parent))
+        assert parent == NEW_SUFFIX_1
+
+
+if __name__ == "__main__":
+    test = Test_suffix()
+    test.setUp()
+
+    test.test_list()
+    test.test_toBackend()
+    test.test_getParent()
+
+    test.tearDown()
diff --git a/lib389/tests/test_module_proxy.py b/lib389/tests/test_module_proxy.py
new file mode 100644
index 0000000..288b9ab
--- /dev/null
+++ b/lib389/tests/test_module_proxy.py
@@ -0,0 +1,79 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import pytest
+import os
+from lib389.ds_instance import DSModuleProxy
+
+
+def test_module_proxy_fun_with_no_arg(fake_ds_class, fake_ds_modules):
+    ds_inst = fake_ds_class()
+    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
+                                        os.path.basename(fake_ds_modules))
+    assert ds_inst.repl.with_no_arg() == ds_inst
+
+
+def test_module_proxy_fun_with_one_arg(fake_ds_class, fake_ds_modules):
+    ds_inst = fake_ds_class()
+    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
+                                        os.path.basename(fake_ds_modules))
+    assert ds_inst.repl.with_one_arg(1) == (ds_inst, 1)
+
+
+def test_module_proxy_plugin_fun_with_no_arg(fake_ds_class, fake_ds_modules):
+    ds_inst = fake_ds_class()
+    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
+                                        os.path.basename(fake_ds_modules))
+    assert ds_inst.plugin.automember.with_no_arg() == ds_inst
+
+
+def test_module_proxy_plugin_fun_with_one_arg(fake_ds_class, fake_ds_modules):
+    ds_inst = fake_ds_class()
+    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
+                                        os.path.basename(fake_ds_modules))
+    assert ds_inst.plugin.automember.with_one_arg(2) == (ds_inst, 2)
+
+
+def test_module_proxy_plugin_call_ds_method(fake_ds_class, fake_ds_modules):
+    ds_inst = fake_ds_class()
+    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
+                                        os.path.basename(fake_ds_modules))
+    assert ds_inst.plugin.automember.calling_ds_method(2) == (ds_inst, 1, 2)
+
+
+def test_module_proxy_plugin_call_another_module(fake_ds_class,
+                                                 fake_ds_modules):
+    ds_inst = fake_ds_class()
+    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
+                                        os.path.basename(fake_ds_modules))
+    assert ds_inst.plugin.automember.calling_repl(2, 3) == 6
+
+
+def test_module_proxy_plugin_call_another_module_kwarg(fake_ds_class,
+                                                       fake_ds_modules):
+    ds_inst = fake_ds_class()
+    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
+                                        os.path.basename
+                                        (fake_ds_modules))
+    assert ds_inst.plugin.automember.calling_repl_with_kwarg1() == 1
+    assert ds_inst.plugin.automember.calling_repl_with_kwarg2() == 2
+
+
+def test_module_proxy_plugin_call_with_all(fake_ds_class, fake_ds_modules):
+    ds_inst = fake_ds_class()
+    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
+                                        os.path.basename
+                                        (fake_ds_modules))
+    assert ds_inst.plugin.automember.with_all(0, 3, 2, 1) == (1, 7, 5, 3)
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mo     de
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/lib389/tests/utils_test.py b/lib389/tests/utils_test.py
new file mode 100644
index 0000000..d1af6aa
--- /dev/null
+++ b/lib389/tests/utils_test.py
@@ -0,0 +1,132 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2015 Red Hat, Inc
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import pytest
+from lib389.utils import *
+
+
+def test_normalizeDN():
+    test = [
+        (r'dc=example,dc=com', r'dc=example,dc=com'),
+        (r'dc=example, dc=com', r'dc=example,dc=com'),
+        (r'cn="dc=example,dc=com",cn=config',
+         'cn=dc\\=example\\,dc\\=com,cn=config'),
+    ]
+    for k, v in test:
+        r = normalizeDN(k)
+        assert r == v, "Mismatch %r vs %r" % (r, v)
+
+
+def test_escapeDNValue():
+    test = [(r'"dc=example, dc=com"', r'\"dc\=example\,\ dc\=com\"')]
+    for k, v in test:
+        r = escapeDNValue(k)
+        assert r == v, "Mismatch %r vs %r" % (r, v)
+
+
+def test_escapeDNFiltValue():
+    test = [(r'"dc=example, dc=com"',
+             '\\22dc\\3dexample\\2c\\20dc\\3dcom\\22')]
+    for k, v in test:
+        r = escapeDNFiltValue(k)
+        assert r == v, "Mismatch %r vs %r" % (r, v)
+
+#
+# socket related functions
+#
+import socket
+
+
+def test_isLocalHost():
+    test = [
+        ('localhost', True),
+        ('localhost.localdomain', True),
+        (socket.gethostname(), True),
+        ('www.google.it', False)]
+    for k, v in test:
+        r = isLocalHost(k)
+        assert r == v, "Mismatch %r vs %r on %r" % (r, v, k)
+
+
+def test_update_jewhost_with_fqdn():
+    test = [
+        ({'hostname': 'localhost'}, ('localhost.localdomain', True)),
+        ({'hostname': 'remote'}, ('remote', False)),
+    ]
+    for k, v in test:
+        old = k.copy()
+        expected_host, expected_r = v
+        r = update_newhost_with_fqdn(k)
+        assert expected_r == r, "Mismatch %r vs %r for %r" % (
+            r, expected_r, old)
+        assert expected_host == k['hostname'], "Mismatch %r vs %r for %r" % (
+            k['hostname'], expected_host, old)
+
+
+def test_formatInfData():
+    ret = formatInfData({
+        'hostname': 'localhost.localdomain',
+        'user-id': 'dirsrv',
+        'group-id': 'dirsrv',
+        'ldap-port': 12345,
+        'root-dn': 'cn=directory manager',
+        'root-pw': 'password',
+        'server-id': 'dirsrv',
+        'suffix': 'o=base1',
+    })
+    log.info("content: %r" % ret)
+
+
+def test_formatInfData_withadmin():
+    instance_params = {
+        'hostname': 'localhost.localdomain',
+        'user-id': 'dirsrv',
+        'group-id': 'dirsrv',
+        'ldap-port': 12346,
+        'root-dn': 'cn=directory manager',
+        'root-pw': 'password',
+        'server-id': 'dirsrv',
+        'suffix': 'o=base1'}
+    admin_params = {
+        'have_admin': True,
+        'create_admin': True,
+        'admin_domain': 'example.com',
+        'cfgdshost': 'localhost',
+        'cfgdsport': 12346,
+        'cfgdsuser': 'admin',
+        'cfgdspwd': 'admin'}
+    instance_params.update(admin_params)
+    ret = formatInfData(instance_params)
+    log.info("content: %r" % ret)
+
+
+def test_formatInfData_withconfigserver():
+    instance_params = {
+        'hostname': 'localhost.localdomain',
+        'user-id': 'dirsrv',
+        'group-id': 'dirsrv',
+        'ldap-port': 12346,
+        'root-dn': 'cn=directory manager',
+        'root-pw': 'password',
+        'server-id': 'dirsrv',
+        'suffix': 'o=base1'}
+    admin_params = {
+        'have_admin': True,
+        'cfgdshost': 'localhost',
+        'cfgdsport': 12346,
+        'cfgdsuser': 'admin',
+        'cfgdspwd': 'admin',
+        'admin_domain': 'example.com'}
+    instance_params.update(admin_params)
+    ret = formatInfData(instance_params)
+    log.info("content: %r" % ret)
+
+
+if __name__ == "__main__":
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/setup.cfg b/setup.cfg
index 33fb3da..62bdb21 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,3 +1,3 @@
 [bdist_rpm]
-requires=python-ldap pytest
+requires=python-ldap pytest python-krbV
 
diff --git a/setup.py b/setup.py
index 2e3ed39..5b47b1a 100644
--- a/setup.py
+++ b/setup.py
@@ -26,10 +26,11 @@ with open(path.join(here, 'README'), 'r') as f:
 
 setup(
     name='lib389',
+    license='GPLv3+',
     version=version,
-    description='A library for accessing 389 directory server',
+    description='A library for accessing and configuring the 389 Directory ' +
+                'Server',
     long_description=long_description,
-
     url='http://port389.org/wiki/Upstream_test_framework',
 
     author='Red Hat Inc.',
@@ -46,8 +47,7 @@ setup(
             'Topic :: Software Development :: Quality Assurance',
             'Topic :: Software Development :: Testing'],
 
-    keywords='389 directory server test',
+    keywords='389 directory server test configure',
     packages=find_packages(exclude=['tests*']),
-
     install_requires=['python-ldap', 'pytest', 'python-krbV'],
 )
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index f5bbefe..0000000
--- a/tests/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
diff --git a/tests/aci_parse_test.py b/tests/aci_parse_test.py
deleted file mode 100644
index 5eefcd7..0000000
--- a/tests/aci_parse_test.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-from lib389._constants import *
-from lib389 import DirSrv, Entry
-import pytest
-
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'aciparseds'
-# INSTANCE_PREFIX   = None
-
-
-class TopologyStandalone(object):
-    def __init__(self, standalone):
-        standalone.open()
-        self.standalone = standalone
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    standalone = DirSrv(verbose=False)
-    standalone.log.debug("Instance allocated")
-    args = {SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT,
-            # SER_DEPLOYED_DIR:  INSTANCE_PREFIX,
-            SER_SERVERID_PROP: INSTANCE_SERVERID}
-    standalone.allocate(args)
-    if standalone.exists():
-        standalone.delete()
-    standalone.create()
-    standalone.open()
-
-    def fin():
-        standalone.delete()
-    request.addfinalizer(fin)
-
-    return TopologyStandalone(standalone)
-
-
-@pytest.fixture(scope="module")
-def complex_aci(topology):
-    ACI_TARGET = ('(targetfilter ="(ou=groups)")(targetattr ="uniqueMember '
-                  '|| member")')
-    ACI_ALLOW = ('(version 3.0; acl "Allow test aci";allow (read, search, '
-                 'write)')
-    ACI_SUBJECT = ('(userdn="ldap:///dc=example,dc=com??sub?(ou=engineering)" '
-                   'and userdn="ldap:///dc=example,dc=com??sub?(manager=uid='
-                   'wbrown,ou=managers,dc=example,dc=com) || ldap:///dc=examp'
-                   'le,dc=com??sub?(manager=uid=tbrown,ou=managers,dc=exampl'
-                   'e,dc=com)" );)')
-    ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
-
-    gentry = Entry('cn=testgroup,%s' % DEFAULT_SUFFIX)
-    gentry.setValues('objectclass', 'top', 'extensibleobject')
-    gentry.setValues('cn', 'testgroup')
-    gentry.setValues('aci', ACI_BODY)
-
-    topology.standalone.add_s(gentry)
-
-    return ACI_BODY
-
-
-def test_aci(topology, complex_aci):
-    """Checks content of previously added aci"""
-
-    acis = topology.standalone.aci.list('cn=testgroup,%s' % DEFAULT_SUFFIX)
-    assert len(acis) == 1
-    aci = acis[0]
-    assert aci.acidata == {
-        'allow': [{'values': ['read', 'search', 'write']}],
-        'target': [], 'targetattr': [{'values': ['uniqueMember', 'member'],
-                                      'equal': True}],
-        'targattrfilters': [],
-        'deny': [],
-        'acl': [{'values': ['Allow test aci']}],
-        'deny_raw_bindrules': [],
-        'targetattrfilters': [],
-        'allow_raw_bindrules': [{'values': [(
-            'userdn="ldap:///dc=example,dc=com??sub?(ou=engineering)" and'
-            ' userdn="ldap:///dc=example,dc=com??sub?(manager=uid=wbrown,'
-            'ou=managers,dc=example,dc=com) || ldap:///dc=example,dc=com'
-            '??sub?(manager=uid=tbrown,ou=managers,dc=example,dc=com)" ')]}],
-        'targetfilter': [{'values': ['(ou=groups)'], 'equal': True}],
-        'targetscope': [],
-        'version 3.0;': [],
-        'rawaci': complex_aci
-    }
-    assert aci.getRawAci() == complex_aci
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -vv %s" % CURRENT_FILE)
diff --git a/tests/agreement_test.py b/tests/agreement_test.py
deleted file mode 100644
index 5b0af12..0000000
--- a/tests/agreement_test.py
+++ /dev/null
@@ -1,322 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import ldap
-import time
-import os
-import pytest
-
-from lib389 import NoSuchEntryError
-from lib389.agreement import Agreement
-from lib389._constants import *
-from lib389.properties import *
-from lib389 import DirSrv, Entry
-
-# Used for One master / One consumer topology
-HOST_MASTER = LOCALHOST
-PORT_MASTER = 40389
-SERVERID_MASTER = 'master'
-REPLICAID_MASTER = 1
-
-HOST_CONSUMER = LOCALHOST
-PORT_CONSUMER = 50389
-SERVERID_CONSUMER = 'consumer'
-
-SUFFIX = DEFAULT_SUFFIX
-ENTRY_DN = "cn=test_entry, %s" % SUFFIX
-
-
-class TopologyReplication(object):
-    def __init__(self, master, consumer):
-        master.open()
-        consumer.open()
-        self.master = master
-        self.consumer = consumer
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    # Master
-    #
-    # Create the master instance
-    master = DirSrv(verbose=False)
-    master.log.debug("Master allocated")
-    args = {SER_HOST: HOST_MASTER,
-            SER_PORT: PORT_MASTER,
-            SER_SERVERID_PROP: SERVERID_MASTER}
-    master.allocate(args)
-    if master.exists():
-        master.delete()
-    master.create()
-    master.open()
-
-    # Enable replication
-    master.replica.enableReplication(suffix=SUFFIX,
-                                     role=REPLICAROLE_MASTER,
-                                     replicaId=REPLICAID_MASTER)
-
-    # Consumer
-    #
-    # Create the consumer instance
-    consumer = DirSrv(verbose=False)
-    consumer.log.debug("Consumer allocated")
-    args = {SER_HOST: HOST_CONSUMER,
-            SER_PORT: PORT_CONSUMER,
-            SER_SERVERID_PROP: SERVERID_CONSUMER}
-    consumer.allocate(args)
-    if consumer.exists():
-        consumer.delete()
-    consumer.create()
-    consumer.open()
-
-    # Enable replication
-    consumer.replica.enableReplication(suffix=SUFFIX,
-                                       role=REPLICAROLE_CONSUMER)
-
-    # Delete each instance in the end
-    def fin():
-        master.delete()
-        consumer.delete()
-    request.addfinalizer(fin)
-
-    return TopologyReplication(master, consumer)
-
-
-def test_create(topology):
-    """Test to create a replica agreement and initialize the consumer.
-    Test on a unknown suffix
-    """
-
-    topology.master.log.info("\n\n##############\n## CREATE\n##############\n")
-    properties = {RA_NAME: ('meTo_%s:%d' % (topology.consumer.host,
-                                            topology.consumer.port)),
-                  RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
-                  RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
-                  RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
-                  RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
-    repl_agreement = topology.master.agreement.create(
-        suffix=SUFFIX, host=topology.consumer.host,
-        port=topology.consumer.port, properties=properties)
-    topology.master.log.debug("%s created" % repl_agreement)
-    topology.master.agreement.init(SUFFIX, HOST_CONSUMER, PORT_CONSUMER)
-    topology.master.waitForReplInit(repl_agreement)
-
-    # Add a test entry
-    topology.master.add_s(Entry((ENTRY_DN, {'objectclass':
-                                            "top person".split(),
-                                            'sn': 'test_entry',
-                                            'cn': 'test_entry'})))
-
-    # Check replication is working
-    loop = 0
-    while loop <= 10:
-        try:
-            ent = topology.consumer.getEntry(ENTRY_DN, ldap.SCOPE_BASE,
-                                             "(objectclass=*)")
-            break
-        except ldap.NO_SUCH_OBJECT:
-            time.sleep(1)
-            loop += 1
-    assert loop <= 10
-
-    # Check that with an invalid suffix it raises NoSuchEntryError
-    with pytest.raises(NoSuchEntryError):
-        properties = {RA_NAME: r'meAgainTo_%s:%d' %
-                      (topology.consumer.host, topology.consumer.port)}
-        topology.master.agreement.create(suffix="ou=dummy",
-                                         host=topology.consumer.host,
-                                         port=topology.consumer.port,
-                                         properties=properties)
-
-
-def test_list(topology):
-    """List the replica agreement on a suffix => 1
-    Add a RA
-    List the replica agreements on that suffix again => 2
-    List a specific RA
-
-    PREREQUISITE: it exists a replica for SUFFIX and a replica agreement
-    """
-
-    topology.master.log.info("\n\n###########\n## LIST\n#############\n")
-    ents = topology.master.agreement.list(suffix=SUFFIX)
-    assert len(ents) == 1
-    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_CONSUMER_HOST]) == \
-        topology.consumer.host
-    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_CONSUMER_PORT]) == \
-        str(topology.consumer.port)
-
-    # Create a second RA to check .list returns 2 RA
-    properties = {RA_NAME: r'meTo_%s:%d' % (topology.consumer.host, 12345),
-                  RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
-                  RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
-                  RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
-                  RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
-    topology.master.agreement.create(suffix=SUFFIX,
-                                     host=topology.consumer.host,
-                                     port=12345,
-                                     properties=properties)
-    ents = topology.master.agreement.list(suffix=SUFFIX)
-    assert len(ents) == 2
-
-    # Check we can .list a specific RA
-    ents = topology.master.agreement.list(suffix=SUFFIX,
-                                          consumer_host=topology.consumer.host,
-                                          consumer_port=topology.consumer.port)
-    assert len(ents) == 1
-    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_CONSUMER_HOST]) == \
-        topology.consumer.host
-    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_CONSUMER_PORT]) == \
-        str(topology.consumer.port)
-
-
-def test_status(topology):
-    """Test that status is returned from agreement"""
-
-    topology.master.log.info("\n\n###########\n## STATUS\n##########")
-    ents = topology.master.agreement.list(suffix=SUFFIX)
-    for ent in ents:
-        ra_status = topology.master.agreement.status(ent.dn)
-        assert ra_status
-        topology.master.log.info("Status of %s: %s" % (ent.dn, ra_status))
-
-
-def test_schedule(topology):
-    """Test the schedule behaviour with valid and invalid values"""
-
-    topology.master.log.info("\n\n###########\n## SCHEDULE\n#########")
-    ents = topology.master.agreement.list(suffix=SUFFIX,
-                                          consumer_host=topology.consumer.host,
-                                          consumer_port=topology.consumer.port)
-    assert len(ents) == 1
-
-    topology.master.agreement.schedule(ents[0].dn, Agreement.ALWAYS)
-    ents = topology.master.agreement.list(suffix=SUFFIX,
-                                          consumer_host=topology.consumer.host,
-                                          consumer_port=topology.consumer.port)
-    assert len(ents) == 1
-    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_SCHEDULE]) == \
-        Agreement.ALWAYS
-
-    topology.master.agreement.schedule(ents[0].dn, Agreement.NEVER)
-    ents = topology.master.agreement.list(suffix=SUFFIX,
-                                          consumer_host=topology.consumer.host,
-                                          consumer_port=topology.consumer.port)
-    assert len(ents) == 1
-    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_SCHEDULE]) == \
-        Agreement.NEVER
-
-    CUSTOM_SCHEDULE = "0000-1234 6420"
-    topology.master.agreement.schedule(ents[0].dn, CUSTOM_SCHEDULE)
-    ents = topology.master.agreement.list(suffix=SUFFIX,
-                                          consumer_host=topology.consumer.host,
-                                          consumer_port=topology.consumer.port)
-    assert len(ents) == 1
-    assert ents[0].getValue(RA_PROPNAME_TO_ATTRNAME[RA_SCHEDULE]) == \
-        CUSTOM_SCHEDULE
-
-    CUSTOM_SCHEDULES = ("2500-1234 6420",  # Invalid HOUR schedule
-                        "0000-2534 6420",  # ^^
-                        "1300-1234 6420",  # Starting HOUR after ending HOUR
-                        "0062-1234 6420",  # Invalid MIN schedule
-                        "0000-1362 6420",  # ^^
-                        "0000-1234 6-420",  # Invalid DAYS schedule
-                        "0000-1362 64209",  # ^^
-                        "0000-1362 01234560")  # ^^
-
-    for CUSTOM_SCHEDULE in CUSTOM_SCHEDULES:
-        with pytest.raises(ValueError):
-            topology.master.agreement.schedule(ents[0].dn, CUSTOM_SCHEDULE)
-
-
-def test_getProperties(topology):
-    """Check the correct behaviour of getProperties function"""
-
-    topology.master.log.info("\n\n###########\n## GETPROPERTIES\n############")
-    ents = topology.master.agreement.list(suffix=SUFFIX,
-                                          consumer_host=topology.consumer.host,
-                                          consumer_port=topology.consumer.port)
-    assert len(ents) == 1
-    properties = topology.master.agreement.getProperties(agmnt_dn=ents[0].dn)
-    for prop in properties:
-        topology.master.log.info("RA %s : %s -> %s" %
-                                 (prop, RA_PROPNAME_TO_ATTRNAME[prop],
-                                  properties[prop]))
-
-    properties = topology.master.agreement.getProperties(
-        agmnt_dn=ents[0].dn, properties=[RA_BINDDN])
-    assert len(properties) == 1
-    for prop in properties:
-        topology.master.log.info("RA %s : %s -> %s" %
-                                 (prop, RA_PROPNAME_TO_ATTRNAME[prop],
-                                  properties[prop]))
-
-
-def test_setProperties(topology):
-    """Set properties to the agreement and check, if it was successful"""
-
-    topology.master.log.info("\n\n###########\n### SETPROPERTIES\n##########")
-    ents = topology.master.agreement.list(suffix=SUFFIX,
-                                          consumer_host=topology.consumer.host,
-                                          consumer_port=topology.consumer.port)
-    assert len(ents) == 1
-    test_schedule = "1234-2345 12345"
-    test_desc = "test_desc"
-    topology.master.agreement.setProperties(
-        agmnt_dn=ents[0].dn, properties={RA_SCHEDULE: test_schedule,
-                                         RA_DESCRIPTION: test_desc})
-    properties = topology.master.agreement.getProperties(
-        agmnt_dn=ents[0].dn, properties=[RA_SCHEDULE, RA_DESCRIPTION])
-    assert len(properties) == 2
-    assert properties[RA_SCHEDULE][0] == test_schedule
-    assert properties[RA_DESCRIPTION][0] == test_desc
-
-
-def test_changes(topology):
-    """Test the changes counter behaviour after making some changes
-    to the replicated suffix
-    """
-
-    topology.master.log.info("\n\n##########\n### CHANGES\n##########")
-    ents = topology.master.agreement.list(suffix=SUFFIX,
-                                          consumer_host=topology.consumer.host,
-                                          consumer_port=topology.consumer.port)
-    assert len(ents) == 1
-    value = topology.master.agreement.changes(agmnt_dn=ents[0].dn)
-    topology.master.log.info("\ntest_changes: %d changes\n" % value)
-    assert value > 0
-
-    # Do an update
-    TEST_STRING = 'test_string'
-    mod = [(ldap.MOD_REPLACE, 'description', [TEST_STRING])]
-    topology.master.modify_s(ENTRY_DN, mod)
-
-    ent = topology.consumer.getEntry(ENTRY_DN, ldap.SCOPE_BASE,
-                                     "(objectclass=*)")
-
-    # The update has been replicated
-    loop = 0
-    while loop <= 10:
-        ent = topology.consumer.getEntry(ENTRY_DN, ldap.SCOPE_BASE,
-                                         "(objectclass=*)")
-        if ent and ent.hasValue('description'):
-            if ent.getValue('description') == TEST_STRING:
-                break
-        time.sleep(1)
-        loop += 1
-    assert loop <= 10
-
-    # Check change number
-    newvalue = topology.master.agreement.changes(agmnt_dn=ents[0].dn)
-    topology.master.log.info("\ntest_changes: %d changes\n" % newvalue)
-    assert (value + 1) == newvalue
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/tests/backend_test.py b/tests/backend_test.py
deleted file mode 100644
index 4f3afb2..0000000
--- a/tests/backend_test.py
+++ /dev/null
@@ -1,278 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import os
-import pytest
-import logging
-
-from lib389._constants import *
-from lib389.properties import *
-from lib389 import DirSrv, InvalidArgumentError, UnwillingToPerformError
-
-logging.getLogger(__name__).setLevel(logging.DEBUG)
-log = logging.getLogger(__name__)
-
-TEST_REPL_DN = "uid=test,%s" % DEFAULT_SUFFIX
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'dirsrv'
-INSTANCE_PREFIX = None
-INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
-NEW_SUFFIX_1 = 'o=test_create'
-NEW_BACKEND_1 = 'test_createdb'
-NEW_CHILDSUFFIX_1 = 'o=child1,o=test_create'
-NEW_CHILDBACKEND_1 = 'test_createchilddb'
-NEW_SUFFIX_2 = 'o=test_bis_create'
-NEW_BACKEND_2 = 'test_bis_createdb'
-NEW_CHILDSUFFIX_2 = 'o=child2,o=test_bis_create'
-NEW_CHILDBACKEND_2 = 'test_bis_createchilddb'
-
-
-class TopologyStandalone(object):
-    def __init__(self, standalone):
-        standalone.open()
-        self.standalone = standalone
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    standalone = DirSrv(verbose=False)
-    standalone.log.debug("Instance allocated")
-    args = {SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT,
-            SER_DEPLOYED_DIR: INSTANCE_PREFIX,
-            SER_SERVERID_PROP: INSTANCE_SERVERID}
-    standalone.allocate(args)
-    if standalone.exists():
-        standalone.delete()
-    standalone.create()
-    standalone.open()
-
-    def fin():
-        standalone.delete()
-    request.addfinalizer(fin)
-
-    return TopologyStandalone(standalone)
-
-
-def test_list(topology):
-    """Test backend.list() function behaviour after:
-    - creating new suffixes
-    - filter with suffix
-    - filter with backend name (bename)
-    - filter with backend dn
-    - filter with invalid suffix/bename
-    """
-
-    ents = topology.standalone.backend.list()
-    nb_backend = len(ents)
-    for ent in ents:
-        topology.standalone.log.info("List(%d): backend %s" %
-                                     (nb_backend, ent.dn))
-
-    log.info("Create a first backend and check list all backends")
-    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
-                                       properties={BACKEND_NAME:
-                                                   NEW_BACKEND_1})
-    ents = topology.standalone.backend.list()
-    for ent in ents:
-        topology.standalone.log.info("List(%d): backend %s" %
-                                     (nb_backend + 1, ent.dn))
-    assert len(ents) == (nb_backend + 1)
-
-    log.info("Create a second backend and check list all backends")
-    topology.standalone.backend.create(suffix=NEW_SUFFIX_2,
-                                       properties={BACKEND_NAME:
-                                                   NEW_BACKEND_2})
-    ents = topology.standalone.backend.list()
-    for ent in ents:
-        topology.standalone.log.info("List(%d): backend %s" %
-                                     (nb_backend + 2, ent.dn))
-    assert len(ents) == (nb_backend + 2)
-
-    log.info("Check list a backend per suffix")
-    ents = topology.standalone.backend.list(suffix=NEW_SUFFIX_1)
-    for ent in ents:
-        topology.standalone.log.info("List suffix (%d): backend %s" %
-                                     (1, ent.dn))
-    assert len(ents) == 1
-
-    log.info("Check list a backend by its name")
-    ents = topology.standalone.backend.list(bename=NEW_BACKEND_2)
-    for ent in ents:
-        topology.standalone.log.info("List name (%d): backend %s" %
-                                     (1, ent.dn))
-    assert len(ents) == 1
-
-    log.info("Check list backends by their DN")
-    all = topology.standalone.backend.list()
-    for ent in all:
-        ents = topology.standalone.backend.list(backend_dn=ent.dn)
-        for bck in ents:
-            topology.standalone.log.info("List DN (%d): backend %s" %
-                                         (1, bck.dn))
-        assert len(ents) == 1
-
-    log.info("Check list with valid backend DN but invalid suffix/bename")
-    all = topology.standalone.backend.list()
-    for ent in all:
-        ents = topology.standalone.backend.list(suffix="o=dummy",
-                                                backend_dn=ent.dn,
-                                                bename="dummydb")
-        for bck in ents:
-            topology.standalone.log.info("List invalid suffix+bename "
-                                         "(%d): backend %s" % (1, bck.dn))
-        assert len(ents) == 1
-
-    log.info("Just to make it clean in the end")
-    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
-    topology.standalone.backend.delete(suffix=NEW_SUFFIX_2)
-
-
-def test_create(topology):
-    """Test backend.create() function with:
-    - specifying no suffix
-    - specifying already existing backend suffix
-    - specifying already existing backend name, but new suffix
-    - specifying no properties
-    """
-
-    log.info("Create a backend")
-    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
-                                       properties={BACKEND_NAME:
-                                                   NEW_BACKEND_1})
-
-    log.info("Check behaviour with missing suffix")
-    with pytest.raises(ValueError) as excinfo:
-        topology.standalone.backend.create()
-    assert 'suffix is mandatory' in str(excinfo.value)
-
-    log.info("Check behaviour with already existing backend for that suffix")
-    with pytest.raises(InvalidArgumentError) as excinfo:
-        topology.standalone.backend.create(suffix=NEW_SUFFIX_1)
-    assert 'It already exists backend(s)' in str(excinfo.value)
-
-    log.info("Check behaviour with already existing backend DN, "
-             "but new suffix")
-    with pytest.raises(InvalidArgumentError) as excinfo:
-        topology.standalone.backend.create(suffix=NEW_SUFFIX_2,
-                                           properties={BACKEND_NAME:
-                                                       NEW_BACKEND_1})
-    assert 'It already exists a backend with that DN' in str(excinfo.value)
-
-    log.info("Create a backend without properties")
-    topology.standalone.backend.create(suffix=NEW_SUFFIX_2)
-    ents = topology.standalone.backend.list(suffix=NEW_SUFFIX_2)
-    assert len(ents) == 1
-
-    log.info("Just to make it clean in the end")
-    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
-    topology.standalone.backend.delete(suffix=NEW_SUFFIX_2)
-
-
-def test_delete_valid(topology):
-    """Test the various possibilities to delete a backend:
-    - with suffix
-    - with backend name
-    - with backend DN
-    """
-
-    ents = topology.standalone.backend.list()
-    nb_backend = len(ents)
-
-    log.info("Try to delete a backend with suffix")
-    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
-                                       properties={BACKEND_NAME:
-                                                   NEW_BACKEND_1})
-    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
-    ents = topology.standalone.backend.list()
-    assert len(ents) == nb_backend
-
-    log.info("Try to delete a backend with backend name")
-    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
-                                       properties={BACKEND_NAME:
-                                                   NEW_BACKEND_1})
-    topology.standalone.backend.delete(bename=NEW_BACKEND_1)
-    ents = topology.standalone.backend.list()
-    assert len(ents) == nb_backend
-
-    log.info("Try to delete a backend with backend DN")
-    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
-                                       properties={BACKEND_NAME:
-                                                   NEW_BACKEND_1})
-    ents = topology.standalone.backend.list(suffix=NEW_SUFFIX_1)
-    assert len(ents) == 1
-    topology.standalone.backend.delete(backend_dn=ents[0].dn)
-    ents = topology.standalone.backend.list()
-    assert len(ents) == nb_backend
-
-
-def test_delete_invalid(topology):
-    """Test the invalid situations with the backend removal:
-    - no argument
-    - invalid suffix
-    - existing a mapping tree
-    - backend name differs
-    """
-
-    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
-                                       properties={BACKEND_NAME:
-                                                   NEW_BACKEND_1})
-    topology.standalone.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
-
-    log.info("First no argument -> InvalidArgumentError")
-    with pytest.raises(InvalidArgumentError) as excinfo:
-        topology.standalone.backend.delete()
-    assert 'suffix and backend DN and backend name are missing' in \
-        str(excinfo.value)
-
-    log.info("Second invalid suffix -> InvalidArgumentError")
-    with pytest.raises(InvalidArgumentError) as excinfo:
-        topology.standalone.backend.delete(suffix=NEW_SUFFIX_2)
-    assert 'Unable to retrieve the backend' in str(excinfo.value)
-
-    log.info("Existing a mapping tree -> UnwillingToPerformError")
-    with pytest.raises(UnwillingToPerformError) as excinfo:
-        topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
-    assert 'It still exists a mapping tree' in str(excinfo.value)
-    topology.standalone.mappingtree.delete(suffix=NEW_SUFFIX_1,
-                                           bename=NEW_BACKEND_1)
-
-    log.info("Backend name differs -> UnwillingToPerformError")
-    with pytest.raises(UnwillingToPerformError) as excinfo:
-        topology.standalone.backend.delete(suffix=NEW_SUFFIX_1,
-                                           bename='dummydb')
-    assert 'Backend name specified (dummydb) differs from' in \
-        str(excinfo.value)
-    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
-
-
-def test_toSuffix(topology):
-    """Test backend.toSuffix() function
-    by comparing its result to the true value
-    """
-
-    log.info("Create one backend")
-    topology.standalone.backend.create(suffix=NEW_SUFFIX_1,
-                                       properties={BACKEND_NAME:
-                                                   NEW_BACKEND_1})
-
-    log.info("Run through all backends and compare backend.toSuffix() "
-             "function results with true values taken from attributes")
-    ents = topology.standalone.backend.list()
-    for ent in ents:
-        suffix = ent.getValues(BACKEND_PROPNAME_TO_ATTRNAME[BACKEND_SUFFIX])
-        values = topology.standalone.backend.toSuffix(name=ent.dn)
-        assert suffix[0] in values
-
-    log.info("Clean up after test")
-    topology.standalone.backend.delete(suffix=NEW_SUFFIX_1)
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/tests/config.py b/tests/config.py
deleted file mode 100644
index 3b9a472..0000000
--- a/tests/config.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import logging
-import six
-logging.basicConfig(level=logging.DEBUG)
-log = logging.getLogger(__name__)
-
-DN_RMANAGER = 'uid=rmanager,cn=config'
-
-auth = {'host': 'localhost',
-        'port': 22389,
-        'binddn': 'cn=directory manager',
-        'bindpw': 'password'}
-
-
-class MockDirSrv(object):
-    host = 'localhost'
-    port = 22389
-    sslport = 0
-
-    def __str__(self):
-        if self.sslport:
-            return 'ldaps://%s:%s' % (self.host, self.sslport)
-        else:
-            return 'ldap://%s:%s' % (self.host, self.port)
-
-
-def expect(entry, name, value):
-    assert entry, "Bad entry %r " % entry
-    assert entry.getValue(name) == value, \
-        ("Bad value for entry %s. Expected %r vs %r" %
-         (entry, entry.getValue(name), value))
-
-
-def entry_equals(e1, e2):
-    """compare using str()"""
-    return str(e1) == str(e2)
-
-
-def dfilter(my_dict, keys):
-    """Filter a dict in a 2.4-compatible way"""
-    return dict([(k, v) for k, v in six.iteritems(my_dict) if k in keys])
diff --git a/tests/config_test.py b/tests/config_test.py
deleted file mode 100644
index 7966dab..0000000
--- a/tests/config_test.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-"""Brooker classes to organize ldap methods.
-   Stuff is split in classes, like:
-   * Replica
-   * Backend
-   * Suffix
-
-   You will access this from:
-   DirSrv.backend.methodName()
-"""
-
-from . import config
-from .config import *
-
-import lib389
-from lib389 import DirSrv
-
-
-conn = None
-added_entries = None
-added_backends = None
-
-MOCK_REPLICA_ID = '12'
-MOCK_TESTREPLICA_DN = "cn=testReplica,cn=ldbm database,cn=plugins,cn=config"
-
-
-def setup():
-    # uses an existing 389 instance
-    # add a suffix
-    # add an agreement
-    # This setup is quite verbose but to test DirSrv method we should
-    # do things manually. A better solution would be to use an LDIF.
-    global conn
-    conn = DirSrv(**config.auth)
-    conn.verbose = True
-    conn.added_entries = []
-    conn.added_backends = set(['o=mockbe1'])
-    conn.added_replicas = []
-    """
-    # add a backend for testing ruv and agreements
-    addbackend_harn(conn, 'testReplica')
-
-    # add another backend for testing replica.add()
-    addbackend_harn(conn, 'testReplicaCreation')
-    """
-
-
-def teardown():
-    global conn
-    conn.config.loglevel([lib389.LOG_CACHE])
-    conn.config.loglevel([256], service='access')
-
-    """
-    drop_added_entries(conn)
-    conn.delete_s(','.join(['cn="o=testreplica"', DN_MAPPING_TREE]))
-    drop_backend(conn, 'o=testreplica')
-    #conn.delete_s('o=testreplica')
-    """
-
-
-def loglevel_test():
-    vals = [lib389.LOG_CACHE, lib389.LOG_REPLICA, lib389.LOG_CONNECT]
-    expected = sum(vals)
-    assert conn.config.loglevel(vals) == expected
-    ret = conn.config.get('nsslapd-errorlog-level')
-    assert ret == str(expected), "expected: %r got: %r" % (expected, ret)
-
-
-def loglevel_update_test():
-    vals = [lib389.LOG_CACHE, lib389.LOG_CONNECT]
-    e = sum(vals)
-    assert conn.config.loglevel(vals) == e
-    vals = [lib389.LOG_REPLICA]
-    ret = conn.config.loglevel(vals, update=True)
-    assert ret == (e + sum(vals)), "expected %s got %s" % (e + sum(vals), ret)
-
-
-def access_loglevel_test():
-    vals = [lib389.LOG_CACHE, lib389.LOG_REPLICA, lib389.LOG_CONNECT]
-    assert conn.config.loglevel(vals, service='access') == sum(vals)
diff --git a/tests/conftest.py b/tests/conftest.py
deleted file mode 100644
index caf507c..0000000
--- a/tests/conftest.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-import string
-import os
-import sys
-import pytest
-from tempfile import mkdtemp
-from shutil import rmtree
-
-
-def ldrop(numchar, inputstr):
-    """
-        Drop numchar characters from the beginning of each line in inputstring.
-    """
-    return "\n".join([x[numchar:] for x in string.split(inputstr, "\n")])
-
-
-@pytest.fixture
-def fake_ds_class():
-    """
-        Returns fake DSInstance-like class
-    """
-    class FakeDSInstance(object):
-        def return_one(self):
-            return 1
-
-    return FakeDSInstance
-
-
-@pytest.fixture(scope="module")
-def fake_ds_modules(request):
-    """
-        Returns path to directory containing fake modules.
-    """
-
-    # module_dir contains fake ds modules, that can be used for testing
-    module_dir = mkdtemp()
-    old_cwd = os.getcwd()
-
-    # when fixture is destroyed, we change back to old cwd
-    # and delete fake module dir
-    def fin():
-        os.chdir(old_cwd)
-        rmtree(module_dir)
-    request.addfinalizer(fin)
-
-    # make module_dir a python package
-    with open(module_dir + "/__init__.py", 'a'):
-        os.utime(module_dir + "/__init__.py", None)
-
-    # create module module_dir/repl.py with few functions
-    with open(module_dir + "/repl.py", "w") as repl_file:
-        repl_module = """
-            def with_no_arg(ds):
-                return ds
-
-            def with_one_arg(ds, arg):
-                return ds, arg
-
-            def return_argument_given(ds, arg):
-                return arg
-
-            def with_kwarg(ds, kwarg=2):
-                return kwarg
-
-            def with_all(ds, arg1, arg2, kwarg1=1, kwarg2=2):
-                return arg1, arg2, kwarg1, kwarg2
-
-            """
-        # Drop 12 chars from left and write to file
-        repl_file.write(ldrop(12, repl_module))
-
-    os.mkdir(module_dir + "/plugin")
-
-    # make module_dir/plugin a python package
-    with open(module_dir + "/plugin/__init__.py", 'a'):
-        os.utime(module_dir + "/plugin/__init__.py", None)
-
-    # create module module_dir/plugin/automember.py with few functions
-    with open(module_dir + "/plugin/automember.py", "w") as automem_file:
-        automember_module = """
-            def with_no_arg(ds):
-                return ds
-
-            def with_one_arg(ds, arg):
-                return ds, arg
-
-            def calling_ds_method(ds, arg):
-                return (ds, ds.return_one(), arg)
-
-            def calling_repl(ds, arg1, arg2):
-                return ds.repl.return_argument_given(1) + arg1 + arg2
-
-            def calling_repl_with_kwarg2(ds):
-                return ds.repl.with_kwarg()
-
-            def calling_repl_with_kwarg1(ds):
-                return ds.repl.with_kwarg(kwarg=1)
-
-            def with_all(ds, arg1, arg2, kwarg1=1, kwarg2=2):
-                a, b, c, d = ds.repl.with_all(1, 4, kwarg1=3)
-                return a + arg1, b + arg2, c + kwarg1, d + kwarg2
-
-            """
-        # Drop 12 chars from left and write to file
-        automem_file.write(ldrop(12, automember_module))
-
-    os.chdir(os.path.dirname(module_dir))
-    sys.path.append(os.path.dirname(module_dir))
-    return module_dir
diff --git a/tests/dereference_test.py b/tests/dereference_test.py
deleted file mode 100644
index 19b3f5c..0000000
--- a/tests/dereference_test.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-from lib389._constants import *
-from lib389 import DirSrv, Entry
-import ldap
-import pytest
-import logging
-
-logging.getLogger(__name__).setLevel(logging.DEBUG)
-log = logging.getLogger(__name__)
-
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'dereferenceds'
-
-
-class TopologyStandalone(object):
-    def __init__(self, standalone):
-        standalone.open()
-        self.standalone = standalone
-
-
-@pytest.fixture(scope='module')
-def topology(request):
-    standalone = DirSrv(verbose=False)
-    standalone.log.debug('Instance allocated')
-    args = {SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT,
-            SER_SERVERID_PROP: INSTANCE_SERVERID}
-    standalone.allocate(args)
-    if standalone.exists():
-        standalone.delete()
-    standalone.create()
-    standalone.open()
-
-    def fin():
-        standalone.delete()
-    request.addfinalizer(fin)
-
-    return TopologyStandalone(standalone)
-
-
-@pytest.fixture(scope='module')
-def user(topology):
-    """Create user entries"""
-
-    for i in range(0, 2):
-        uentry = Entry('uid=test%s,%s' % (i, DEFAULT_SUFFIX))
-        uentry.setValues('objectclass', 'top', 'extensibleobject')
-        uentry.setValues('uid', 'test')
-        topology.standalone.add_s(uentry)
-
-
-@pytest.fixture(scope='module')
-def group(topology):
-    """Create a group entry"""
-
-    gentry = Entry('cn=testgroup,%s' % DEFAULT_SUFFIX)
-    gentry.setValues('objectclass', 'top', 'extensibleobject')
-    gentry.setValues('cn', 'testgroup')
-    for i in range(0, 2):
-        gentry.setValues('uniqueMember', 'uid=test%s,%s' % (i, DEFAULT_SUFFIX))
-    topology.standalone.add_s(gentry)
-
-
-def test_dereference(topology, user, group):
-    """Test dereference search argument formating
-    Check, that result is correct
-    """
-
-    log.info('Check, that our deref Control Value is correctly formatted')
-    with pytest.raises(ldap.UNAVAILABLE_CRITICAL_EXTENSION):
-        result, control_response = topology.standalone.dereference(
-            'uniqueMember:dn,uid;uniqueMember:dn,uid',
-            filterstr='(cn=testgroup)')
-
-    result, control_response = topology.standalone.dereference(
-        'uniqueMember:cn,uid,objectclass', filterstr='(cn=testgroup)')
-
-    log.info('Check, that the dereference search result is correct')
-    assert result[0][2][0].entry == [{'derefVal':
-                                      'uid=test1,dc=example,dc=com',
-                                      'derefAttr': 'uniqueMember',
-                                      'attrVals': [{'vals':
-                                                    ['top',
-                                                     'extensibleobject'],
-                                                    'type': 'objectclass'},
-                                                   {'vals': ['test', 'test1'],
-                                                    'type': 'uid'}]}]
-
-
-if __name__ == '__main__':
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main('-s -v %s' % CURRENT_FILE)
diff --git a/tests/dirsrv_test.py b/tests/dirsrv_test.py
deleted file mode 100644
index 8255181..0000000
--- a/tests/dirsrv_test.py
+++ /dev/null
@@ -1,223 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import os
-import pwd
-import logging
-import pytest
-from lib389._constants import *
-from lib389.properties import *
-from lib389 import DirSrv, Entry
-
-logging.getLogger(__name__).setLevel(logging.DEBUG)
-log = logging.getLogger(__name__)
-
-TEST_DN = "uid=test,%s" % DEFAULT_SUFFIX
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'dirsrv'
-INSTANCE_PREFIX = '/'
-INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
-
-
-class TopologyInstance(object):
-    def __init__(self, instance):
-        self.instance = instance
-
-
-@pytest.fixture(scope='module')
-def topology(request):
-    instance = DirSrv(verbose=False)
-
-    if instance.exists():
-        instance.delete()
-
-    def fin():
-        if instance.exists():
-            instance.delete()
-    request.addfinalizer(fin)
-
-    return TopologyInstance(instance)
-
-
-def _add_user(topology):
-    """Add a user to the instance"""
-
-    topology.instance.add_s(Entry((TEST_DN, {'objectclass':
-                                             "top person".split(),
-                                             'objectclass':
-                                             "organizationalPerson",
-                                             'objectclass': "inetOrgPerson",
-                                             'uid': 'test',
-                                             'sn': 'test',
-                                             'cn': 'test'})))
-    log.info('User %s was added' % TEST_DN)
-
-
-def test_allocate(topology):
-    """Test instance.allocate() function
-    for correct state and arguments
-    """
-
-    log.info('Check instance state is initial')
-    assert topology.instance.state == DIRSRV_STATE_INIT
-
-    log.info('Allocate the instance')
-    args = {SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT,
-            SER_SERVERID_PROP: INSTANCE_SERVERID}
-    topology.instance.allocate(args)
-
-    log.info('Check instance state is allocated')
-    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
-
-    log.info('Try to add user. Failure is excpected')
-    with pytest.raises(Exception):
-        _add_user(topology)
-
-    if os.getuid() == 0:
-        userid = DEFAULT_USER
-    else:
-        userid = pwd.getpwuid(os.getuid())[0]
-
-    log.info('Verify the settings')
-    assert topology.instance.host == LOCALHOST
-    assert topology.instance.port == INSTANCE_PORT
-    assert topology.instance.sslport is None
-    assert topology.instance.binddn == DN_DM
-    assert topology.instance.bindpw == PW_DM
-    assert topology.instance.creation_suffix == DEFAULT_SUFFIX
-    assert topology.instance.userid == userid
-    assert topology.instance.serverid == INSTANCE_SERVERID
-    assert topology.instance.groupid == topology.instance.userid
-    assert topology.instance.prefix == INSTANCE_PREFIX
-    assert topology.instance.backupdir == INSTANCE_BACKUP
-
-    log.info('Check that we can change the settings of an allocated DirSrv')
-    args = {SER_SERVERID_PROP: INSTANCE_SERVERID,
-            SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT,
-            SER_ROOT_DN: "uid=foo"}
-    topology.instance.allocate(args)
-
-    log.info('Check instance state is allocated')
-    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
-
-    log.info('Verify the settings')
-    assert topology.instance.host == LOCALHOST
-    assert topology.instance.port == INSTANCE_PORT
-    assert topology.instance.sslport is None
-    assert topology.instance.binddn == "uid=foo"
-    assert topology.instance.bindpw == PW_DM
-    assert topology.instance.creation_suffix == DEFAULT_SUFFIX
-    assert topology.instance.userid == userid
-    assert topology.instance.serverid == INSTANCE_SERVERID
-    assert topology.instance.groupid == topology.instance.userid
-    assert topology.instance.prefix == INSTANCE_PREFIX
-    assert topology.instance.backupdir == INSTANCE_BACKUP
-
-    log.info('Restore back the valid parameters and check')
-    args = {SER_SERVERID_PROP: INSTANCE_SERVERID,
-            SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT}
-    topology.instance.allocate(args)
-
-    log.info('Check instance state is allocated')
-    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
-
-    log.info('Verify the settings')
-    assert topology.instance.host == LOCALHOST
-    assert topology.instance.port == INSTANCE_PORT
-    assert topology.instance.sslport is None
-    assert topology.instance.binddn == DN_DM
-    assert topology.instance.bindpw == PW_DM
-    assert topology.instance.creation_suffix == DEFAULT_SUFFIX
-    assert topology.instance.userid == userid
-    assert topology.instance.serverid == INSTANCE_SERVERID
-    assert topology.instance.groupid == topology.instance.userid
-    assert topology.instance.prefix == INSTANCE_PREFIX
-    assert topology.instance.backupdir == INSTANCE_BACKUP
-
-
-def test_create(topology):
-    """Test instance creation
-    Check status before and after
-    Try to add a user
-    """
-
-    log.info('Check instance state is allocated')
-    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
-
-    topology.instance.create()
-
-    log.info('Check instance state is offline')
-    assert topology.instance.state == DIRSRV_STATE_OFFLINE
-
-    log.info('Try to add user. Failure is excpected')
-    with pytest.raises(Exception):
-        _add_user(topology)
-
-
-def test_open(topology):
-    """Test instance opening
-    Check status before and after
-    Try to add a user
-    """
-
-    log.info('Check instance state is offline')
-    assert topology.instance.state == DIRSRV_STATE_OFFLINE
-
-    topology.instance.open()
-
-    log.info('Check instance state is online')
-    assert topology.instance.state == DIRSRV_STATE_ONLINE
-
-    log.info('Try to add user. Success is excpected')
-    _add_user(topology)
-
-
-def test_close(topology):
-    """Test instance closing
-    Check status before and after
-    Try to add a user
-    """
-
-    log.info('Check instance state is online')
-    assert topology.instance.state == DIRSRV_STATE_ONLINE
-
-    topology.instance.close()
-
-    log.info('Check instance state is offline')
-    assert topology.instance.state == DIRSRV_STATE_OFFLINE
-
-    log.info('Try to add user. Failure is excpected')
-    with pytest.raises(Exception):
-        _add_user(topology)
-
-
-def test_delete(topology):
-    """Test instance deletion
-    Check status before and after
-    Try to add a user
-    """
-
-    log.info('Check instance state is offline')
-    assert topology.instance.state == DIRSRV_STATE_OFFLINE
-
-    topology.instance.delete()
-
-    log.info('Check instance state is allocated')
-    assert topology.instance.state == DIRSRV_STATE_ALLOCATED
-
-    log.info('Try to add user. Failure is excpected')
-    with pytest.raises(Exception):
-        _add_user(topology)
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main('-s -v %s' % CURRENT_FILE)
diff --git a/tests/dsadmin_basic_test.py b/tests/dsadmin_basic_test.py
deleted file mode 100644
index 6426d41..0000000
--- a/tests/dsadmin_basic_test.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-""" Testing basic functionalities of DirSrv
-
-
-"""
-import ldap
-import lib389
-from lib389 import DirSrv
-from lib389 import NoSuchEntryError
-from ldap import *
-from nose.tools import *
-from . import config
-from .config import *
-
-conn = None
-added_entries = None
-
-
-def setup():
-    global conn
-    try:
-        conn = DirSrv(**config.auth)
-        conn.verbose = True
-        conn.added_entries = []
-    except SERVER_DOWN as e:
-        log.error("To run tests you need a working 389 instance %s" %
-                  config.auth)
-        raise e
-
-
-def tearDown():
-    global conn
-
-    # reduce log level
-    conn.config.loglevel([lib389.LOG_CACHE])
-    conn.config.loglevel([256], service='access')
-
-    for e in conn.added_entries:
-        try:
-            conn.delete_s(e)
-        except ldap.NO_SUCH_OBJECT:
-            log.warn("entry not found %r" % e)
-
-
-def bind_test():
-    print ("conn: %s" % conn)
-
-
-def setupBindDN_UID_test():
-    user = {
-        'binddn': 'uid=rmanager1,cn=config',
-        'bindpw': 'password'
-    }
-    e = conn.setupBindDN(**user)
-    conn.added_entries.append(e.dn)
-
-    assert e.dn == user['binddn'], "Bad entry: %r " % e
-    expected = conn.getEntry(user['binddn'], ldap.SCOPE_BASE)
-    assert entry_equals(
-        e, expected), "Mismatching entry %r vs %r" % (e, expected)
-
-
-def setupBindDN_CN_test():
-    user = {
-        'binddn': 'cn=rmanager1,cn=config',
-        'bindpw': 'password'
-    }
-    e = conn.setupBindDN(**user)
-    conn.added_entries.append(e.dn)
-    assert e.dn == user['binddn'], "Bad entry: %r " % e
-    expected = conn.getEntry(user['binddn'], ldap.SCOPE_BASE)
-    assert entry_equals(
-        e, expected), "Mismatching entry %r vs %r" % (e, expected)
-
-
-def setupChangelog_default_test():
-    e = conn.replica.changelog()
-    conn.added_entries.append(e.dn)
-    assert e.dn, "Bad changelog entry: %r " % e
-    assert e.getValue('nsslapd-changelogdir').endswith("changelogdb"), \
-        "Mismatching entry %r " % e.data.get('nsslapd-changelogdir')
-    conn.delete_s("cn=changelog5,cn=config")
-
-
-def setupChangelog_test():
-    e = conn.replica.changelog(dbname="mockChangelogDb")
-    conn.added_entries.append(e.dn)
-    assert e.dn, "Bad changelog entry: %r " % e
-    assert e.getValue('nsslapd-changelogdir').endswith("mockChangelogDb"), \
-        "Mismatching entry %r " % e.data.get('nsslapd-changelogdir')
-    conn.delete_s("cn=changelog5,cn=config")
-
-
-def setupChangelog_full_test():
-    e = conn.replica.changelog(dbname="/tmp/mockChangelogDb")
-    conn.added_entries.append(e.dn)
-
-    assert e.dn, "Bad changelog entry: %r " % e
-    expect(e, 'nsslapd-changelogdir', "/tmp/mockChangelogDb")
-    conn.delete_s("cn=changelog5,cn=config")
-
-
-@raises(NoSuchEntryError)
-def getMTEntry_missing_test():
-    e = conn.getMTEntry('o=MISSING')
-    return e
-
-
-def getMTEntry_present_test():
-    suffix = 'o=addressbook16'
-    bename = 'addressbookd16db'
-    backendEntry, dummy = conn.backend.add(suffix, benamebase=bename)
-    suffixEntry = conn.backend.setup_mt(suffix, bename)
-
-    e = conn.getMTEntry(suffix)
-
-    conn.backend.delete(bename)
-    conn.delete_s(suffixEntry.dn)
-    assert e, "Entry should be present %s" % suffix
diff --git a/tests/dsadmin_create_remove_test.py b/tests/dsadmin_create_remove_test.py
deleted file mode 100644
index c0dea2d..0000000
--- a/tests/dsadmin_create_remove_test.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-"""
-Test creation and deletion of instances
-"""
-import ldap
-import os
-import socket
-from lib389 import DirSrv, DN_CONFIG
-from lib389.tools import DirSrvTools
-from nose import *
-
-added_instances = []
-
-
-def setup():
-    global added_instances
-
-
-def teardown():
-    global added_instances
-    for instance in added_instances:
-        cmd = "/usr/bin/sudo remove-ds.pl -i slapd-%s" % instance
-        try:
-            os.system(cmd)
-        except:
-            log.exception("error executing %r" % cmd)
-
-
-def default_test():
-    host = socket.gethostname()
-    port = 10200
-    binddn = "cn=directory manager"
-    bindpw = "password"
-    suffix = 'dc=example,dc=com'
-    basedn = DN_CONFIG
-    scope = ldap.SCOPE_BASE
-    filt = "(objectclass=*)"
-    instance_name = ['m1', 'm2']
-
-    instance_config = {
-        'cfgdshost': host,
-        'cfgdsport': port,
-        'cfgdsuser': 'admin',
-        'cfgdspwd': 'admin',
-        'newrootpw': 'password',
-        'newhost': host,
-        'newport': port,
-        'newinstance': instance_name[0],
-        'newsuffix': suffix,
-        'setup_admin': True,
-    }
-    try:
-        m1 = DirSrv(host, port, binddn, bindpw)
-    except:
-        m1 = DirSrvTools.createInstance(instance_config, verbose=0)
-        added_instances.append(instance_config['newinstance'])
-
-#        filename = "%s/slapd-%s/ldif/Example.ldif" % (m1.sroot, m1.inst)
-#        m1.importLDIF(filename, "dc=example,dc=com", None, True)
-#        m1.exportLDIF('/tmp/ldif', "dc=example,dc=com", False, True)
-    print (m1.sroot, m1.inst, m1.errlog)
-    ent = m1.getEntry(basedn, scope, filt, None)
-    if ent:
-        print (ent.passwordmaxage)
-    instance_config.update({
-                           'newinstance': instance_name[1],
-                           'newport': port + 10,
-
-                           })
-    m1 = DirSrvTools.createInstance(instance_config, verbose=0)
-    added_instances.append(instance_config['newinstance'])
-    #     m1.stop(True)
-    #     m1.start(True)
-    suffix = "dc=example2,dc=com"
-    bename = "example2db"
-    backendEntry, dummy = m1.backend.add(suffix, bename)
-    suffixEntry = m1.backend.setup_mt(suffix, bename)
-    cn = backendEntry.getValue('cn')
-    print (cn)
-    entry = m1.getEntry(DN_CONFIG, ldap.SCOPE_SUBTREE, "(cn=" + cn + ")")
-    print ("new backend entry is:")
-    print (entry)
-    print (entry.getValues('objectclass'))
-    print (entry.OBJECTCLASS)
-    results = m1.search_s("cn=monitor", ldap.SCOPE_SUBTREE)
-    print (results)
-    results = m1.getBackendsForSuffix("dc=example,dc=com")
-    print (results)
-
-    print ("done")
diff --git a/tests/dsadmin_test.py b/tests/dsadmin_test.py
deleted file mode 100644
index a59ddb8..0000000
--- a/tests/dsadmin_test.py
+++ /dev/null
@@ -1,263 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-from nose import *
-from nose.tools import *
-
-from . import config
-from .config import log
-from .config import *
-
-import ldap
-import time
-import lib389
-from lib389 import DirSrv, Entry
-from lib389 import utils
-from lib389.tools import DirSrvTools
-from subprocess import Popen
-
-
-conn = None
-added_entries = None
-added_backends = None
-
-
-def harn_nolog():
-    conn.config.loglevel([lib389.LOG_DEFAULT])
-    conn.config.loglevel([lib389.LOG_DEFAULT], service='access')
-
-
-def setup():
-    global conn
-    conn = DirSrv(**config.auth)
-    conn.verbose = True
-    conn.added_entries = []
-    conn.added_backends = set(['o=mockbe2'])
-    conn.added_replicas = []
-    harn_nolog()
-
-
-def setup_backend():
-    global conn
-    suffix = 'o=addressbook6'
-    backend = 'addressbook6db'
-
-    # create backend and suffix
-    backendEntry, dummy = conn.backend.add(suffix, benamebase=backend)
-    suffixEntry = conn.backend.setup_mt(suffix, backend)
-
-
-def teardown():
-    global conn
-    conn.rebind()
-    drop_added_entries(conn)
-
-
-def drop_added_entries(conn):
-    while conn.added_entries:
-        try:
-            e = conn.added_entries.pop()
-            log.info("removing entries %r" % conn.added_backends)
-            conn.delete_s(e)
-        except ldap.NOT_ALLOWED_ON_NONLEAF:
-            log.error("Entry is not a leaf: %r" % e)
-        except ldap.NO_SUCH_OBJECT:
-            log.error("Cannot remove entry: %r" % e)
-
-    log.info("removing backends %r" % conn.added_backends)
-    for suffix in conn.added_backends:
-        try:
-            drop_backend(conn, suffix)
-        except:
-            log.exception("error removing %r" % suffix)
-    for r in conn.added_replicas:
-        try:
-            drop_backend(conn, suffix=None, bename=r)
-        except:
-            log.exception("error removing %r" % r)
-
-
-def drop_backend(conn, suffix, bename=None, maxnum=50):
-    if not bename:
-        bename = [x.dn for x in conn.getBackendsForSuffix(suffix)]
-
-    if not bename:
-        return None
-
-    assert bename, "Missing bename for %r" % suffix
-    if not hasattr(bename, '__iter__'):
-        bename = [','.join(['cn=%s' % bename, lib389.DN_LDBM])]
-    for be in bename:
-        log.debug("removing entry from %r" % be)
-        leaves = [x.dn for x in conn.search_s(
-            be, ldap.SCOPE_SUBTREE, '(objectclass=*)', ['cn'])]
-        # start deleting the leaves - which have the max number of ","
-        leaves.sort(key=lambda x: x.count(","))
-        while leaves and maxnum:
-            # to avoid infinite loops
-            # limit the iterations
-            maxnum -= 1
-            try:
-                log.debug("removing %s" % leaves[-1])
-                conn.delete_s(leaves[-1])
-                leaves.pop()
-            except:
-                leaves.insert(0, leaves.pop())
-
-        if not maxnum:
-            raise Exception("BAD")
-
-
-#
-# Tests
-#
-
-
-def addbackend_harn(conn, name, beattrs=None):
-    """Create the suffix o=name and its backend."""
-    suffix = "o=%s" % name
-    e = Entry((suffix, {
-               'objectclass': ['top', 'organization'],
-               'o': [name]
-               }))
-
-    try:
-        ret = conn.addSuffix(suffix, bename=name, beattrs=beattrs)
-    except ldap.ALREADY_EXISTS:
-        raise
-    finally:
-        conn.added_backends.add(suffix)
-
-    conn.add(e)
-    conn.added_entries.append(e.dn)
-
-    return ret
-
-
-def setupBackend_ok_test():
-    "setupBackend_ok calls brooker.Backend.add"
-    try:
-        backendEntry, dummy = conn.backend.add('o=mockbe5',
-                                               benamebase='mockbe5')
-        assert backendEntry
-    except ldap.ALREADY_EXISTS:
-        raise
-    finally:
-        conn.backend.delete(benamebase='mockbe5')
-
-
-@raises(ldap.ALREADY_EXISTS)
-def setupBackend_double_test():
-    "setupBackend_double calls brooker.Backend.add"
-    backendEntry, dummy = conn.backend.add('o=mockbe3', benamebase='mockbe3')
-    backendEntry, dummy = conn.backend.add('o=mockbe3', benamebase='mockbe3')
-
-
-def addsuffix_test():
-    # identical to getMTEntry_present_test in dsadmin_basic_test
-    # addbackend_harn(conn, 'addressbook16')
-    # conn.added_backends.add('o=addressbook16')
-    pass
-
-
-def addreplica_write_test():
-    suffix = 'o=ab3'
-    backend = 'ab3'
-    user = {
-        'binddn': 'uid=rmanager,cn=config',
-        'bindpw': 'password'
-    }
-    replica = {
-        'suffix': suffix,
-        'type': lib389.MASTER_TYPE,
-        'id': 124
-    }
-    replica.update(user)
-
-    # create backend and suffix
-    backendEntry, dummy = conn.backend.add(suffix, benamebase=backend)
-    suffixEntry = conn.backend.setup_mt(suffix, backend)
-
-    ret = conn.replicaSetupAll(replica)
-
-    assert ret != -1, "Error in setup replica: %s" % ret
-
-
-def prepare_master_replica_test():
-    """prepare_master_replica -> Replica.changelog"""
-    user = {
-        'binddn': 'uid=rmanager,cn=config',
-        'bindpw': 'password'
-    }
-    conn.enableReplLogging()
-    e = conn.setupBindDN(**user)
-    conn.added_entries.append(e.dn)
-
-    # only for Writable
-    e = conn.replica.changelog()
-    conn.added_entries.append(e.dn)
-
-
-@with_setup(setup_backend)
-def setupAgreement_test():
-    consumer = MockDirSrv()
-    args = {
-        'suffix': "o=addressbook6",
-        # 'bename': "userRoot",
-        'binddn': "uid=rmanager,cn=config",
-        'bindpw': "password",
-        'rtype': lib389.MASTER_TYPE,
-        'rid': '1234'
-    }
-    conn.replica.add(**args)
-    conn.added_entries.append(args['binddn'])
-
-    dn_replica = conn.createAgreement(consumer, args)
-
-
-def stop_start_test():
-    # dunno why DirSrv.start|stop writes to dirsrv error-log
-    conn.errlog = "/tmp/dirsrv-errlog"
-    open(conn.errlog, "w").close()
-    DirSrvTools.stop(conn)
-    log.info("server stopped")
-    DirSrvTools.start(conn)
-    log.info("server start")
-    time.sleep(5)
-    # save and restore conn settings after restart
-    tmp = conn.added_backends, conn.added_entries
-    setup()
-    conn.added_backends, conn.added_entries = tmp
-    assert conn.search_s(
-        *utils.searches['NAMINGCONTEXTS']), "Missing namingcontexts"
-
-
-def setupSSL_test():
-    ssl_args = {
-        'dirsrv': conn,
-        'secport': 22636,
-        'sourcedir': None,
-        'secargs': {'nsSSLPersonalitySSL': 'localhost'},
-    }
-    cert_dir = conn.getDseAttr('nsslapd-certdir')
-    assert cert_dir, "Cannot retrieve cert dir"
-
-    log.info("Initialize the cert store with an empty password: %r", cert_dir)
-    fd_null = open('/dev/null', 'w')
-    open('%s/pin.txt' % cert_dir, 'w').close()
-    cmd_initialize = 'certutil -d %s -N -f %s/pin.txt' % (cert_dir, cert_dir)
-    Popen(cmd_initialize.split(), stderr=fd_null)
-
-    log.info("Creating a self-signed cert for the server in %r" % cert_dir)
-    cmd_mkcert = ('certutil -d %s -S -n localhost  -t CTu,Cu,Cu  '
-                  '-s cn=localhost -x' % cert_dir)
-    Popen(cmd_mkcert.split(), stdin=open("/dev/urandom"), stderr=fd_null)
-
-    log.info("Testing ssl configuration")
-    ssl_args.update({'dirsrv': conn})
-    DirSrvTools.setupSSL(**ssl_args)
diff --git a/tests/effective_rights_test.py b/tests/effective_rights_test.py
deleted file mode 100644
index 84a0418..0000000
--- a/tests/effective_rights_test.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-from lib389._constants import *
-from lib389 import DirSrv, Entry
-import pytest
-import logging
-
-logging.getLogger(__name__).setLevel(logging.DEBUG)
-log = logging.getLogger(__name__)
-
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'effectiverightsds'
-TEST_USER = 'uid=test,%s' % DEFAULT_SUFFIX
-TEST_GROUP = 'cn=testgroup,%s' % DEFAULT_SUFFIX
-
-
-class TopologyInstance(object):
-    def __init__(self, instance):
-        instance.open()
-        self.instance = instance
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    instance = DirSrv(verbose=False)
-    instance.log.debug("Instance allocated")
-    args = {SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT,
-            SER_SERVERID_PROP: INSTANCE_SERVERID}
-    instance.allocate(args)
-    if instance.exists():
-        instance.delete()
-    instance.create()
-    instance.open()
-
-    def fin():
-        if instance.exists():
-            instance.delete()
-    request.addfinalizer(fin)
-
-    return TopologyInstance(instance)
-
-
-@pytest.fixture(scope="module")
-def add_user(topology):
-    """Create a user entry"""
-
-    log.info('Create a user entry: %s' % TEST_USER)
-    uentry = Entry(TEST_USER)
-    uentry.setValues('objectclass', 'top', 'extensibleobject')
-    uentry.setValues('uid', 'test')
-    topology.instance.add_s(uentry)
-    # topology.instance.log.debug("Created user entry as:" ,uentry.dn)
-
-
-@pytest.fixture(scope="module")
-def add_group(topology):
-    """Create a group for the user to have some rights to"""
-
-    log.info('Create a group entry: %s' % TEST_GROUP)
-    gentry = Entry(TEST_GROUP)
-    gentry.setValues('objectclass', 'top', 'extensibleobject')
-    gentry.setValues('cn', 'testgroup')
-    topology.instance.add_s(gentry)
-
-
-def test_effective_rights(topology, add_user, add_group):
-    """Run an effective rights search
-    and compare actual results with expected
-    """
-
-    log.info('Search for effective rights with get_effective_rights() '
-             'function')
-    result = topology.instance.get_effective_rights(TEST_USER,
-                                                    filterstr='(cn=testgroup)',
-                                                    attrlist=['cn'])
-
-    rights = result[0]
-    log.info('Assert that "attributeLevelRights: cn:rsc" and '
-             '"entryLevelRights: v"')
-    assert rights.getValue('attributeLevelRights') == 'cn:rsc'
-    assert rights.getValue('entryLevelRights') == 'v'
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/tests/entry_test.py b/tests/entry_test.py
deleted file mode 100644
index 46fee29..0000000
--- a/tests/entry_test.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import os
-from lib389 import Entry
-import lib389
-import pytest
-
-import logging
-logging.basicConfig(level=logging.DEBUG)
-log = logging.getLogger(__name__)
-
-
-class TestEntry(object):
-    """A properly initialized Entry:
-        - accepts well-formed or empty dn and tuples;
-        - refuses empty dn
-    """
-    def test_init_empty(self):
-        e = Entry('')
-        assert not e.dn
-
-    def test_init_with_str(self):
-        e = Entry('o=pippo')
-        assert e.dn == 'o=pippo'
-
-    def test_init_badstr(self):
-        # This should not be allowed
-        with pytest.raises(ValueError):
-            e = Entry('no equal sign here')
-
-    def test_init_with_tuple(self):
-        expected = 'pippo'
-        given = 'o=pippo'
-        t = (given, {
-             'o': [expected],
-             'objectclass': ['organization', 'top']
-             })
-        e = Entry(t)
-        assert e.dn == given
-        assert expected in e.o
-
-    def test_update(self):
-        expected = 'pluto minnie'
-        given = {'cn': expected}
-        t = ('o=pippo', {
-             'o': ['pippo'],
-             'objectclass': ['organization', 'top']
-             })
-
-        e = Entry(t)
-        e.update(given)
-        assert e.cn == expected, "Bad cn: %s, expected: %s" % (e.cn, expected)
-
-    def test_update_complex(self):
-        # compare two entries created with different methods
-        nsuffix, replid, replicatype = ("dc=example,dc=com", 5,
-                                        lib389.REPLICA_RDWR_TYPE)
-        binddnlist, legacy = ['uid=pippo, cn=config'], 'off'
-        dn = "dc=example,dc=com"
-        entry = Entry(dn)
-        entry.setValues(
-            'objectclass', "top", "nsds5replica", "extensibleobject")
-        entry.setValues('cn', "replica")
-        entry.setValues('nsds5replicaroot', nsuffix)
-        entry.setValues('nsds5replicaid', str(replid))
-        entry.setValues('nsds5replicatype', str(replicatype))
-        entry.setValues('nsds5flags', "1")
-        entry.setValues('nsds5replicabinddn', binddnlist)
-        entry.setValues('nsds5replicalegacyconsumer', legacy)
-
-        uentry = Entry((
-            dn, {'objectclass': ["top", "nsds5replica", "extensibleobject"],
-                 'cn': ["replica"]})
-        )
-        log.debug("Entry created with dict:", uentry)
-        # Entry.update *replaces*, so be careful with multi-valued attrs
-        uentry.update({
-            'nsds5replicaroot': nsuffix,
-            'nsds5replicaid': str(replid),
-            'nsds5replicatype': str(replicatype),
-            'nsds5flags': '1',
-            'nsds5replicabinddn': binddnlist,
-            'nsds5replicalegacyconsumer': legacy
-        })
-        uentry_s, entry_s = list(map(str, (uentry, entry)))
-        assert uentry_s == entry_s, "Mismatching entries [%r] vs [%r]" % (
-            uentry, entry)
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/tests/krb5_create_test.py b/tests/krb5_create_test.py
deleted file mode 100644
index efdb298..0000000
--- a/tests/krb5_create_test.py
+++ /dev/null
@@ -1,99 +0,0 @@
-
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-from lib389._constants import *
-from lib389.mit_krb5 import MitKrb5, KrbClient
-from lib389 import DirSrv, Entry
-import pytest
-import logging
-
-import ldap
-import ldap.sasl
-
-logging.getLogger(__name__).setLevel(logging.DEBUG)
-log = logging.getLogger(__name__)
-
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'gssapi'
-REALM = "EXAMPLE.COM"
-TEST_USER = 'uid=test,%s' % DEFAULT_SUFFIX
-
-
-class TopologyInstance(object):
-    def __init__(self, instance):
-        instance.open()
-        self.instance = instance
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    # Create the realm
-    krb = MitKrb5(realm=REALM)
-    instance = DirSrv(verbose=False)
-    instance.log.debug("Instance allocated")
-    args = {SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT,
-            SER_REALM: REALM,
-            SER_SERVERID_PROP: INSTANCE_SERVERID}
-    instance.allocate(args)
-    if instance.exists():
-        instance.delete()
-    # Its likely our realm exists too
-    if krb.check_realm():
-        krb.destroy_realm()
-    # This will automatically create the krb entries
-    krb.create_realm()
-    instance.create()
-    instance.open()
-
-    def fin():
-        if instance.exists():
-            instance.delete()
-        if krb.check_realm():
-            krb.destroy_realm()
-    request.addfinalizer(fin)
-
-    return TopologyInstance(instance)
-
-
-@pytest.fixture(scope="module")
-def add_user(topology):
-    """
-    Create a user entry
-    """
-
-    log.info('Create a user entry: %s' % TEST_USER)
-    uentry = Entry(TEST_USER)
-    uentry.setValues('objectclass', 'top', 'extensibleobject')
-    uentry.setValues('uid', 'test')
-    topology.instance.add_s(uentry)
-    # This doesn't matter that we re-open the realm
-    krb = MitKrb5(realm=REALM)
-    krb.create_principal("test")
-    # We extract the kt so we can kinit from it
-    krb.create_keytab("test", "/tmp/test.keytab")
-
-
-def test_gssapi(topology, add_user):
-    """
-    Check that our bind completese with ldapwhoami correctly mapped from
-    the principal to our test user object.
-    """
-    # Init our local ccache
-    kclient = KrbClient("test@%s" % REALM, "/tmp/test.keytab")
-    # Probably need to change this to NOT be raw python ldap
-    conn = ldap.initialize("ldap://%s:%s" % (LOCALHOST, INSTANCE_PORT))
-    sasl = ldap.sasl.gssapi()
-    conn.sasl_interactive_bind_s('', sasl)
-    assert(conn.whoami_s() == "dn: uid=test,dc=example,dc=com")
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/tests/mappingTree_test.py b/tests/mappingTree_test.py
deleted file mode 100644
index b26e90d..0000000
--- a/tests/mappingTree_test.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import os
-import pytest
-import logging
-from lib389._constants import *
-from lib389.properties import *
-from lib389 import DirSrv, InvalidArgumentError
-
-logging.getLogger(__name__).setLevel(logging.DEBUG)
-log = logging.getLogger(__name__)
-
-TEST_REPL_DN = "uid=test,%s" % DEFAULT_SUFFIX
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'dirsrv'
-INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
-NEW_SUFFIX_1 = 'o=test_create'
-NEW_BACKEND_1 = 'test_createdb'
-NEW_CHILDSUFFIX_1 = 'o=child1,o=test_create'
-NEW_CHILDBACKEND_1 = 'test_createchilddb'
-NEW_SUFFIX_2 = 'o=test_bis_create'
-NEW_BACKEND_2 = 'test_bis_createdb'
-NEW_CHILDSUFFIX_2 = 'o=child2,o=test_bis_create'
-NEW_CHILDBACKEND_2 = 'test_bis_createchilddb'
-
-
-class TopologyInstance(object):
-    def __init__(self, instance):
-        instance.open()
-        self.instance = instance
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    instance = DirSrv(verbose=False)
-    instance.log.debug("Instance allocated")
-    args = {SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT,
-            SER_SERVERID_PROP: INSTANCE_SERVERID}
-    instance.allocate(args)
-    if instance.exists():
-        instance.delete()
-    instance.create()
-    instance.open()
-
-    def fin():
-        instance.delete()
-    request.addfinalizer(fin)
-
-    return TopologyInstance(instance)
-
-
-def test_list(topology):
-    """This test list with only no param, suffix,
-    bename, suffix+bename (also with invalid values)
-    """
-
-    ents = topology.instance.mappingtree.list()
-    for ent in ents:
-            log.info('test_list: %r' % ent)
-
-    log.info("get with a dedicated suffix")
-    ents = topology.instance.mappingtree.list(suffix=DEFAULT_SUFFIX)
-    assert len(ents) == 1
-    log.info('test_list(suffix): %r' % ent)
-
-    ents = topology.instance.mappingtree.list(suffix="dc=dummy")
-    assert len(ents) == 0
-
-    log.info("get with a dedicated backend name")
-    ents = topology.instance.mappingtree.list(bename=DEFAULT_BENAME)
-    assert len(ents) == 1
-    log.info('test_list(bename): %r' % ent)
-
-    ents = topology.instance.mappingtree.list(bename="dummy")
-    assert len(ents) == 0
-
-    log.info("check backend is taken first")
-    ents = topology.instance.mappingtree.list(suffix="dc=dummy",
-                                              bename=DEFAULT_BENAME)
-    assert len(ents) == 1
-    log.info('test_list(suffix, bename): %r' % ent)
-
-
-def test_create(topology):
-    """This test will create 2 backends/mapping trees,
-    then 2 childs backend/mapping tree
-    """
-
-    log.info("before creating mapping trees, the backends must exists")
-    backendEntry = topology.instance.backend.create(
-        NEW_SUFFIX_1, {BACKEND_NAME: NEW_BACKEND_1})
-    backendEntry = topology.instance.backend.create(
-        NEW_SUFFIX_2, {BACKEND_NAME: NEW_BACKEND_2})
-
-    ents = topology.instance.mappingtree.list()
-    nb_mappingtree = len(ents)
-
-    log.info("create a first additional mapping tree")
-    topology.instance.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree + 1)
-
-    log.info("create a second additional mapping tree")
-    topology.instance.mappingtree.create(NEW_SUFFIX_2, bename=NEW_BACKEND_2)
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree + 2)
-
-    log.info("Creating a mapping tree that already exists => "
-             "it just returns the existing MT")
-    topology.instance.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree + 2)
-
-    log.info("Creating a mapping tree that already exists => "
-             "it just returns the existing MT")
-    topology.instance.mappingtree.create(NEW_SUFFIX_2, bename=NEW_BACKEND_2)
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree + 2)
-
-    log.info("before creating mapping trees, the backends must exists")
-    backendEntry = topology.instance.backend.create(
-        NEW_CHILDSUFFIX_1, {BACKEND_NAME: NEW_CHILDBACKEND_1})
-    backendEntry = topology.instance.backend.create(
-        NEW_CHILDSUFFIX_2, {BACKEND_NAME: NEW_CHILDBACKEND_2})
-
-    log.info("create a third additional mapping tree, that is child "
-             "of NEW_SUFFIX_1")
-    topology.instance.mappingtree.create(
-        NEW_CHILDSUFFIX_1, bename=NEW_CHILDBACKEND_1, parent=NEW_SUFFIX_1)
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree + 3)
-
-    ents = topology.instance.mappingtree.list(suffix=NEW_CHILDSUFFIX_1)
-    assert len(ents) == 1
-    ent = ents[0]
-    assert ent.hasAttr(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX]) and \
-        (ent.getValue(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX]) ==
-         NEW_SUFFIX_1)
-
-    log.info("create a fourth additional mapping tree, that is child "
-             "of NEW_SUFFIX_2")
-    topology.instance.mappingtree.create(NEW_CHILDSUFFIX_2,
-                                         bename=NEW_CHILDBACKEND_2,
-                                         parent=NEW_SUFFIX_2)
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree + 4)
-
-    ents = topology.instance.mappingtree.list(suffix=NEW_CHILDSUFFIX_2)
-    assert len(ents) == 1
-    ent = ents[0]
-    assert ent.hasAttr(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX]) and \
-        (ent.getValue(MT_PROPNAME_TO_ATTRNAME[MT_PARENT_SUFFIX]) ==
-         NEW_SUFFIX_2)
-
-
-def test_delete(topology):
-    """Delete the mapping tree and check the remaining number.
-    Delete the sub-suffix first.
-    """
-
-    ents = topology.instance.mappingtree.list()
-    nb_mappingtree = len(ents)
-    deleted = 0
-
-    log.debug("delete MT for suffix " + NEW_CHILDSUFFIX_1)
-    topology.instance.mappingtree.delete(suffix=NEW_CHILDSUFFIX_1)
-    deleted += 1
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree - deleted)
-
-    log.debug("delete MT with backend " + NEW_CHILDBACKEND_2)
-    topology.instance.mappingtree.delete(bename=NEW_CHILDBACKEND_2)
-    deleted += 1
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree - deleted)
-
-    log.debug("delete MT for suffix %s and with backend %s" %
-              (NEW_SUFFIX_1, NEW_BACKEND_1))
-    topology.instance.mappingtree.delete(suffix=NEW_SUFFIX_1,
-                                         bename=NEW_BACKEND_1)
-    deleted += 1
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree - deleted)
-
-    ents = topology.instance.mappingtree.list(suffix=NEW_SUFFIX_2)
-    assert len(ents) == 1
-    log.debug("delete MT with DN %s (dummy suffix/backend)" % (ents[0].dn))
-    topology.instance.mappingtree.delete(suffix="o=dummy", bename="foo",
-                                         name=ents[0].dn)
-
-
-def test_getProperties(topology):
-    """Create one additional mapping tree
-    and try to get properties from it
-    """
-
-    ents = topology.instance.mappingtree.list()
-    nb_mappingtree = len(ents)
-
-    log.info("create a first additional mapping tree")
-    topology.instance.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
-    ents = topology.instance.mappingtree.list()
-    assert len(ents) == (nb_mappingtree + 1)
-
-    log.info("check we can get properties from suffix")
-    prop_ref = topology.instance.mappingtree.getProperties(suffix=NEW_SUFFIX_1)
-    log.info("properties [suffix] %s: %r" % (NEW_SUFFIX_1, prop_ref))
-
-    log.info("check we can get properties from backend name")
-    properties = topology.instance.mappingtree.getProperties(
-        bename=NEW_BACKEND_1)
-    for key in list(properties.keys()):
-        assert prop_ref[key] == properties[key]
-    log.info("properties [backend] %s: %r" % (NEW_SUFFIX_1, properties))
-
-    log.info("check we can get properties from suffix AND backend name")
-    properties = topology.instance.mappingtree.getProperties(
-        suffix=NEW_SUFFIX_1, bename=NEW_BACKEND_1)
-    for key in list(properties.keys()):
-        assert prop_ref[key] == properties[key]
-    log.info("properties [suffix+backend]%s: %r" % (NEW_SUFFIX_1, properties))
-
-    log.info("check we can get properties from MT entry")
-    ents = topology.instance.mappingtree.list(suffix=NEW_SUFFIX_1)
-    assert len(ents) == 1
-    ent = ents[0]
-    properties = topology.instance.mappingtree.getProperties(name=ent.dn)
-    for key in list(properties.keys()):
-        assert prop_ref[key] == properties[key]
-    log.info("properties [MT entry DN] %s: %r" % (NEW_SUFFIX_1, properties))
-
-    log.info("check we can get only one properties")
-    properties = topology.instance.mappingtree.getProperties(
-        name=ent.dn, properties=[MT_STATE])
-    assert len(properties) == 1
-    assert properties[MT_STATE] == prop_ref[MT_STATE]
-
-    with pytest.raises(KeyError):
-        properties = topology.instance.mappingtree.getProperties(
-            name=ent.dn, properties=['dummy'])
-
-
-def test_toSuffix(topology):
-    """Try to get suffix name from existing mapping tree"""
-
-    ents = topology.instance.mappingtree.list()
-    log.info("check we can get suffix from a mapping tree by entry")
-    suffix = topology.instance.mappingtree.toSuffix(entry=ents[0])
-    assert len(suffix) > 0
-    log.info("suffix (entry) is %s" % suffix[0])
-
-    log.info("check we can get suffix from a mapping tree by name")
-    suffix = topology.instance.mappingtree.toSuffix(name=ents[0].dn)
-    assert len(suffix) > 0
-    log.info("suffix (dn) is %s" % suffix[0])
-
-    log.info("check we can not get suffix from a mapping tree by nothing")
-    with pytest.raises(InvalidArgumentError):
-        suffix = topology.instance.mappingtree.toSuffix()
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/tests/replica_test.py b/tests/replica_test.py
deleted file mode 100644
index 9eb0078..0000000
--- a/tests/replica_test.py
+++ /dev/null
@@ -1,459 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import ldap
-import os
-import pytest
-import logging
-
-from lib389 import InvalidArgumentError
-from lib389._constants import *
-from lib389.properties import *
-from lib389 import DirSrv, Entry
-
-logging.getLogger(__name__).setLevel(logging.DEBUG)
-log = logging.getLogger(__name__)
-
-# Used for One master / One consumer topology
-HOST_MASTER = LOCALHOST
-PORT_MASTER = 40389
-SERVERID_MASTER = 'master'
-REPLICAID_MASTER = 1
-
-HOST_CONSUMER = LOCALHOST
-PORT_CONSUMER = 50389
-SERVERID_CONSUMER = 'consumer'
-
-TEST_REPL_DN = "uid=test,%s" % DEFAULT_SUFFIX
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'dirsrv'
-INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
-NEW_SUFFIX_1 = 'ou=test_master'
-NEW_BACKEND_1 = 'test_masterdb'
-NEW_RM_1 = "cn=replrepl,%s" % NEW_SUFFIX_1
-
-NEW_SUFFIX_2 = 'ou=test_consumer'
-NEW_BACKEND_2 = 'test_consumerdb'
-
-NEW_SUFFIX_3 = 'ou=test_enablereplication_1'
-NEW_BACKEND_3 = 'test_enablereplicationdb_1'
-
-NEW_SUFFIX_4 = 'ou=test_enablereplication_2'
-NEW_BACKEND_4 = 'test_enablereplicationdb_2'
-
-NEW_SUFFIX_5 = 'ou=test_enablereplication_3'
-NEW_BACKEND_5 = 'test_enablereplicationdb_3'
-
-
-class TopologyReplication(object):
-    def __init__(self, master, consumer):
-        master.open()
-        consumer.open()
-        self.master = master
-        self.consumer = consumer
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    # Create the master instance
-    master = DirSrv(verbose=False)
-    master.log.debug("Master allocated")
-    args = {SER_HOST: HOST_MASTER,
-            SER_PORT: PORT_MASTER,
-            SER_SERVERID_PROP: SERVERID_MASTER}
-    master.allocate(args)
-    if master.exists():
-        master.delete()
-    master.create()
-    master.open()
-
-    # Create the consumer instance
-    consumer = DirSrv(verbose=False)
-    consumer.log.debug("Consumer allocated")
-    args = {SER_HOST: HOST_CONSUMER,
-            SER_PORT: PORT_CONSUMER,
-            SER_SERVERID_PROP: SERVERID_CONSUMER}
-    consumer.allocate(args)
-    if consumer.exists():
-        consumer.delete()
-    consumer.create()
-    consumer.open()
-
-    # Delete each instance in the end
-    def fin():
-        master.delete()
-        consumer.delete()
-    request.addfinalizer(fin)
-
-    return TopologyReplication(master, consumer)
-
-
-def test_create(topology):
-    """This test creates
-         - suffix/backend (NEW_SUFFIX_[12], NEW_BACKEND_[12]) : Master
-         - suffix/backend (NEW_SUFFIX_[12], NEW_BACKEND_[12]) : Consumer
-         - replica NEW_SUFFIX_1 as MASTER : Master
-         - replica NEW_SUFFIX_2 as CONSUMER : Master
-    """
-
-    log.info("\n\n##########\n### CREATE\n############")
-    #
-    # MASTER (suffix/backend)
-    #
-    backendEntry = topology.master.backend.create(
-        suffix=NEW_SUFFIX_1, properties={BACKEND_NAME: NEW_BACKEND_1})
-    backendEntry = topology.master.backend.create(
-        suffix=NEW_SUFFIX_2, properties={BACKEND_NAME: NEW_BACKEND_2})
-
-    ents = topology.master.mappingtree.list()
-    master_nb_mappingtree = len(ents)
-
-    # create a first additional mapping tree
-    topology.master.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
-    ents = topology.master.mappingtree.list()
-    assert len(ents) == (master_nb_mappingtree + 1)
-    topology.master.add_s(Entry((NEW_SUFFIX_1,
-                          {'objectclass': "top organizationalunit".split(),
-                           'ou': NEW_SUFFIX_1.split('=', 1)[1]})))
-
-    # create a second additional mapping tree
-    topology.master.mappingtree.create(NEW_SUFFIX_2, bename=NEW_BACKEND_2)
-    ents = topology.master.mappingtree.list()
-    assert len(ents) == (master_nb_mappingtree + 2)
-    topology.master.add_s(Entry((NEW_SUFFIX_2,
-                          {'objectclass': "top organizationalunit".split(),
-                           'ou': NEW_SUFFIX_2.split('=', 1)[1]})))
-    log.info('Master it exists now %d suffix(es)' % len(ents))
-
-    #
-    # CONSUMER (suffix/backend)
-    #
-    backendEntry = topology.consumer.backend.create(
-        suffix=NEW_SUFFIX_1, properties={BACKEND_NAME: NEW_BACKEND_1})
-    backendEntry = topology.consumer.backend.create(
-        suffix=NEW_SUFFIX_2, properties={BACKEND_NAME: NEW_BACKEND_2})
-
-    ents = topology.consumer.mappingtree.list()
-    consumer_nb_mappingtree = len(ents)
-
-    # create a first additional mapping tree
-    topology.consumer.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
-    ents = topology.consumer.mappingtree.list()
-    assert len(ents) == (consumer_nb_mappingtree + 1)
-    topology.consumer.add_s(Entry((NEW_SUFFIX_1,
-                            {'objectclass': "top organizationalunit".split(),
-                             'ou': NEW_SUFFIX_1.split('=', 1)[1]})))
-
-    # create a second additional mapping tree
-    topology.consumer.mappingtree.create(NEW_SUFFIX_2, bename=NEW_BACKEND_2)
-    ents = topology.consumer.mappingtree.list()
-    assert len(ents) == (consumer_nb_mappingtree + 2)
-    topology.consumer.add_s(Entry((NEW_SUFFIX_2,
-                            {'objectclass': "top organizationalunit".split(),
-                             'ou': NEW_SUFFIX_2.split('=', 1)[1]})))
-    log.info('Consumer it exists now %d suffix(es)' % len(ents))
-
-    #
-    # Now create REPLICAS on master
-    #
-    # check it exists this entry to stores the changelogs
-    topology.master.changelog.create()
-
-    # create a master
-    topology.master.replica.create(suffix=NEW_SUFFIX_1,
-                                   role=REPLICAROLE_MASTER,
-                                   rid=1)
-    ents = topology.master.replica.list()
-    assert len(ents) == 1
-    log.info('Master replica %s' % ents[0].dn)
-
-    # create a consumer
-    topology.master.replica.create(suffix=NEW_SUFFIX_2,
-                                   role=REPLICAROLE_CONSUMER)
-    ents = topology.master.replica.list()
-    assert len(ents) == 2
-    ents = topology.master.replica.list(suffix=NEW_SUFFIX_2)
-    log.info('Consumer replica %s' % ents[0].dn)
-
-    #
-    # Now create REPLICAS on consumer
-    #
-    # create a master
-    topology.consumer.replica.create(suffix=NEW_SUFFIX_1,
-                                     role=REPLICAROLE_CONSUMER)
-    ents = topology.consumer.replica.list()
-    assert len(ents) == 1
-    log.info('Consumer replica %s' % ents[0].dn)
-
-    # create a consumer
-    topology.consumer.replica.create(suffix=NEW_SUFFIX_2,
-                                     role=REPLICAROLE_CONSUMER)
-    ents = topology.consumer.replica.list()
-    assert len(ents) == 2
-    ents = topology.consumer.replica.list(suffix=NEW_SUFFIX_2)
-    log.info('Consumer replica %s' % ents[0].dn)
-
-
-def test_list(topology):
-    """This test checks:
-         - existing replicas can be retrieved
-         - access to unknown replica does not fail
-
-    PRE-CONDITION:
-         It exists on MASTER two replicas NEW_SUFFIX_1 and NEW_SUFFIX_2
-         created by test_create()
-    """
-
-    log.info("\n\n############\n### LIST\n############")
-    ents = topology.master.replica.list()
-    assert len(ents) == 2
-
-    # Check we can retrieve a replica with its suffix
-    ents = topology.master.replica.list(suffix=NEW_SUFFIX_1)
-    assert len(ents) == 1
-    replica_dn_1 = ents[0].dn
-
-    # Check we can retrieve a replica with its suffix
-    ents = topology.master.replica.list(suffix=NEW_SUFFIX_2)
-    assert len(ents) == 1
-    replica_dn_2 = ents[0].dn
-
-    # Check we can retrieve a replica with its DN
-    ents = topology.master.replica.list(replica_dn=replica_dn_1)
-    assert len(ents) == 1
-    assert replica_dn_1 == ents[0].dn
-
-    # Check we can retrieve a replica if we provide DN and suffix
-    ents = topology.master.replica.list(suffix=NEW_SUFFIX_2,
-                                        replica_dn=replica_dn_2)
-    assert len(ents) == 1
-    assert replica_dn_2 == ents[0].dn
-
-    # Check DN is used before suffix name
-    ents = topology.master.replica.list(suffix=NEW_SUFFIX_2,
-                                        replica_dn=replica_dn_1)
-    assert len(ents) == 1
-    assert replica_dn_1 == ents[0].dn
-
-    # Check that invalid value does not break
-    ents = topology.master.replica.list(suffix="X")
-    for ent in ents:
-        log.critical("Unexpected replica: %s" % ent.dn)
-    assert len(ents) == 0
-
-
-def test_create_repl_manager(topology):
-    """The tests are
-         - create the default Replication manager/Password
-         - create a specific Replication manager/ default Password
-         - Check we can bind successfully
-         - create a specific Replication manager / specific Password
-         - Check we can bind successfully
-    """
-
-    log.info("\n\n###########\n### CREATE_REPL_MANAGER\n###########")
-    # First create the default replication manager
-    topology.consumer.replica.create_repl_manager()
-    ents = topology.consumer.search_s(defaultProperties[REPLICATION_BIND_DN],
-                                      ldap.SCOPE_BASE, "objectclass=*")
-    assert len(ents) == 1
-    assert ents[0].dn == defaultProperties[REPLICATION_BIND_DN]
-
-    # Second create a custom replication manager under NEW_SUFFIX_2
-    rm_dn = "cn=replrepl,%s" % NEW_SUFFIX_2
-    topology.consumer.replica.create_repl_manager(repl_manager_dn=rm_dn)
-    ents = topology.consumer.search_s(rm_dn, ldap.SCOPE_BASE, "objectclass=*")
-    assert len(ents) == 1
-    assert ents[0].dn == rm_dn
-
-    # Check we can bind
-    topology.consumer.simple_bind_s(rm_dn,
-                                    defaultProperties[REPLICATION_BIND_PW])
-
-    # Check we fail to bind
-    with pytest.raises(ldap.INVALID_CREDENTIALS) as excinfo:
-        topology.consumer.simple_bind_s(rm_dn, "dummy")
-    log.info("Exception: %s" % str(excinfo.value))
-
-    # now rebind
-    topology.consumer.simple_bind_s(topology.consumer.binddn,
-                                    topology.consumer.bindpw)
-
-    # Create a custom replication manager under NEW_SUFFIX_1
-    # with a specified password
-    rm_dn = NEW_RM_1
-    topology.consumer.replica.create_repl_manager(repl_manager_dn=rm_dn,
-                                                  repl_manager_pw="Secret123")
-    ents = topology.consumer.search_s(rm_dn, ldap.SCOPE_BASE, "objectclass=*")
-    assert len(ents) == 1
-    assert ents[0].dn == rm_dn
-
-    # Check we can bind
-    topology.consumer.simple_bind_s(rm_dn, "Secret123")
-
-    # Check we fail to bind
-    with pytest.raises(ldap.INVALID_CREDENTIALS) as excinfo:
-        topology.consumer.simple_bind_s(rm_dn, "dummy")
-    log.info("Exception: %s" % str(excinfo.value))
-    topology.consumer.simple_bind_s(topology.consumer.binddn,
-                                    topology.consumer.bindpw)
-
-
-def test_enableReplication(topology):
-    """It checks
-         - Ability to enable replication on a supplier
-         - Ability to enable replication on a consumer
-         - Failure to enable replication with wrong replicaID on supplier
-         - Failure to enable replication with wrong replicaID on consumer
-    """
-
-    log.info("\n\n############\n### ENABLEREPLICATION\n##########")
-    #
-    # MASTER (suffix/backend)
-    #
-    backendEntry = topology.master.backend.create(suffix=NEW_SUFFIX_3,
-                                                  properties={BACKEND_NAME:
-                                                              NEW_BACKEND_3})
-
-    ents = topology.master.mappingtree.list()
-    master_nb_mappingtree = len(ents)
-
-    # create a first additional mapping tree
-    topology.master.mappingtree.create(NEW_SUFFIX_3, bename=NEW_BACKEND_3)
-    ents = topology.master.mappingtree.list()
-    assert len(ents) == (master_nb_mappingtree + 1)
-    topology.master.add_s(Entry((NEW_SUFFIX_3,
-                          {'objectclass': "top organizationalunit".split(),
-                           'ou': NEW_SUFFIX_3.split('=', 1)[1]})))
-
-    # a supplier should have replicaId in [1..CONSUMER_REPLICAID[
-    with pytest.raises(ValueError) as excinfo:
-        topology.master.replica.enableReplication(suffix=NEW_SUFFIX_3,
-                                                  role=REPLICAROLE_MASTER,
-                                                  replicaId=CONSUMER_REPLICAID)
-    log.info("Exception (expected): %s" % str(excinfo.value))
-    topology.master.replica.enableReplication(suffix=NEW_SUFFIX_3,
-                                              role=REPLICAROLE_MASTER,
-                                              replicaId=1)
-
-    #
-    # MASTER (suffix/backend)
-    #
-    backendEntry = topology.master.backend.create(suffix=NEW_SUFFIX_4,
-                                                  properties={BACKEND_NAME:
-                                                              NEW_BACKEND_4})
-
-    ents = topology.master.mappingtree.list()
-    master_nb_mappingtree = len(ents)
-
-    # create a first additional mapping tree
-    topology.master.mappingtree.create(NEW_SUFFIX_4, bename=NEW_BACKEND_4)
-    ents = topology.master.mappingtree.list()
-    assert len(ents) == (master_nb_mappingtree + 1)
-    topology.master.add_s(Entry((NEW_SUFFIX_4,
-                          {'objectclass': "top organizationalunit".split(),
-                           'ou': NEW_SUFFIX_4.split('=', 1)[1]})))
-
-    # A consumer should have CONSUMER_REPLICAID not '1'
-    with pytest.raises(ValueError) as excinfo:
-        topology.master.replica.enableReplication(suffix=NEW_SUFFIX_4,
-                                                  role=REPLICAROLE_CONSUMER,
-                                                  replicaId=1)
-    log.info("Exception (expected): %s" % str(excinfo.value))
-    topology.master.replica.enableReplication(suffix=NEW_SUFFIX_4,
-                                              role=REPLICAROLE_CONSUMER)
-
-
-def test_disableReplication(topology):
-    """It checks
-         - Ability to disable replication on a supplier
-         - Ability to disable replication on a consumer
-         - Failure to disable replication with wrong suffix on supplier
-         - Failure to disable replication with wrong suffix on consumer
-    """
-
-    log.info("\n\n############\n### DISABLEREPLICATION\n##########")
-    topology.master.replica.disableReplication(suffix=NEW_SUFFIX_3)
-    with pytest.raises(ldap.LDAPError) as excinfo:
-        topology.master.replica.disableReplication(suffix=NEW_SUFFIX_3)
-    log.info("Exception (expected): %s" % str(excinfo.value))
-
-    topology.master.replica.disableReplication(suffix=NEW_SUFFIX_4)
-    with pytest.raises(ldap.LDAPError) as excinfo:
-        topology.master.replica.disableReplication(suffix=NEW_SUFFIX_4)
-    log.info("Exception (expected): %s" % str(excinfo.value))
-
-
-def test_setProperties(topology):
-    """Set some properties
-    Verified that valid properties are set
-    Verified that invalid properties raise an Exception
-
-    PRE-REQUISITE: it exists a replica for NEW_SUFFIX_1
-    """
-
-    log.info("\n\n##########\n### SETPROPERTIES\n############")
-    # set valid values to SUFFIX_1
-    properties = {REPLICA_LEGACY_CONS: 'off',
-                  REPLICA_BINDDN: NEW_RM_1,
-                  REPLICA_PURGE_INTERVAL: str(3600),
-                  REPLICA_PURGE_DELAY: str(5 * 24 * 3600),
-                  REPLICA_REFERRAL: "ldap://%s:1234/" % LOCALHOST}
-    topology.master.replica.setProperties(suffix=NEW_SUFFIX_1,
-                                          properties=properties)
-
-    # Check the values have been written
-    replicas = topology.master.replica.list(suffix=NEW_SUFFIX_1)
-    assert len(replicas) == 1
-    for prop in properties:
-        attr = REPLICA_PROPNAME_TO_ATTRNAME[prop]
-        val = replicas[0].getValue(attr)
-        log.info("Replica[%s] -> %s: %s" % (prop, attr, val))
-        assert val == properties[prop]
-
-    # Check invalid properties raise exception
-    with pytest.raises(ValueError) as excinfo:
-        properties = {"dummy": 'dummy'}
-        topology.master.replica.setProperties(suffix=NEW_SUFFIX_1,
-                                              properties=properties)
-    log.info("Exception (expected): %s" % str(excinfo.value))
-
-    # check call without suffix/dn/entry raise InvalidArgumentError
-    with pytest.raises(InvalidArgumentError) as excinfo:
-        properties = {REPLICA_LEGACY_CONS: 'off'}
-        topology.master.replica.setProperties(properties=properties)
-    log.info("Exception (expected): %s" % str(excinfo.value))
-
-    # check that if we do not provide a valid entry it raises ValueError
-    with pytest.raises(ValueError) as excinfo:
-        properties = {REPLICA_LEGACY_CONS: 'off'}
-        topology.master.replica.setProperties(replica_entry="dummy",
-                                              properties=properties)
-    log.info("Exception (expected): %s" % str(excinfo.value))
-
-    # check that with an invalid suffix or replica_dn it raise ValueError
-    with pytest.raises(ValueError) as excinfo:
-        properties = {REPLICA_LEGACY_CONS: 'off'}
-        topology.master.replica.setProperties(suffix="dummy",
-                                              properties=properties)
-    log.info("Exception (expected): %s" % str(excinfo.value))
-
-
-def test_getProperties(topology):
-    """Currently not implemented"""
-
-    log.info("\n\n############\n### GETPROPERTIES\n###########")
-    with pytest.raises(NotImplementedError) as excinfo:
-        properties = {REPLICA_LEGACY_CONS: 'off'}
-        topology.master.replica.getProperties(suffix=NEW_SUFFIX_1)
-    log.info("Exception (expected): %s" % str(excinfo.value))
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/tests/schema_test.py b/tests/schema_test.py
deleted file mode 100644
index 35b82bd..0000000
--- a/tests/schema_test.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import pytest
-from lib389._constants import *
-from lib389 import DirSrv
-
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'schemainspectds'
-
-
-class TopologyInstance(object):
-    def __init__(self, instance):
-        instance.open()
-        self.instance = instance
-
-
-@pytest.fixture(scope="module")
-def topology(request):
-    instance = DirSrv(verbose=False)
-    instance.log.debug("Instance allocated")
-    args = {SER_HOST: LOCALHOST,
-            SER_PORT: INSTANCE_PORT,
-            SER_SERVERID_PROP: INSTANCE_SERVERID}
-    instance.allocate(args)
-    if instance.exists():
-        instance.delete()
-    instance.create()
-    instance.open()
-
-    def fin():
-        instance.delete()
-    request.addfinalizer(fin)
-
-    return TopologyInstance(instance)
-
-
-def test_schema(topology):
-    must_expect = ['uidObject', 'account', 'posixAccount', 'shadowAccount']
-    may_expect = ['cosDefinition', 'inetOrgPerson', 'inetUser',
-                  'mailRecipient']
-    attrtype, must, may = topology.instance.schema.query_attributetype('uid')
-    assert attrtype.names == ('uid', 'userid')
-    for oc in must:
-        assert oc.names[0] in must_expect
-    for oc in may:
-        assert oc.names[0] in may_expect
-    assert topology.instance.schema.query_objectclass('account').names == \
-        ('account', )
-
-
-if __name__ == '__main__':
-    # Run isolated
-    # -s for DEBUG mode
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s %s" % CURRENT_FILE)
diff --git a/tests/suffix_test.py b/tests/suffix_test.py
deleted file mode 100644
index e3df10b..0000000
--- a/tests/suffix_test.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-
-import os
-from lib389._constants import *
-from lib389.properties import *
-from lib389 import DirSrv
-
-
-TEST_REPL_DN = "uid=test,%s" % DEFAULT_SUFFIX
-INSTANCE_PORT = 54321
-INSTANCE_SERVERID = 'dirsrv'
-# INSTANCE_PREFIX = os.environ.get('PREFIX', None)
-INSTANCE_PREFIX = None
-INSTANCE_BACKUP = os.environ.get('BACKUPDIR', DEFAULT_BACKUPDIR)
-NEW_SUFFIX_1 = 'o=test_create'
-NEW_BACKEND_1 = 'test_createdb'
-NEW_CHILDSUFFIX_1 = 'o=child1,o=test_create'
-NEW_CHILDBACKEND_1 = 'test_createchilddb'
-NEW_SUFFIX_2 = 'o=test_bis_create'
-NEW_BACKEND_2 = 'test_bis_createdb'
-NEW_CHILDSUFFIX_2 = 'o=child2,o=test_bis_create'
-NEW_CHILDBACKEND_2 = 'test_bis_createchilddb'
-
-
-class Test_suffix():
-    def setUp(self):
-        instance = DirSrv(verbose=False)
-        instance.log.debug("Instance allocated")
-        args = {SER_HOST: LOCALHOST,
-                SER_PORT: INSTANCE_PORT,
-                SER_DEPLOYED_DIR: INSTANCE_PREFIX,
-                SER_SERVERID_PROP: INSTANCE_SERVERID
-                }
-        instance.allocate(args)
-        if instance.exists():
-            instance.delete()
-        instance.create()
-        instance.open()
-        self.instance = instance
-
-    def tearDown(self):
-        if self.instance.exists():
-            self.instance.delete()
-
-    def test_list(self):
-        # before creating mapping trees, the backends must exists
-        backendEntry = self.instance.backend.create(
-            NEW_SUFFIX_1, {BACKEND_NAME: NEW_BACKEND_1})
-
-        ents = self.instance.mappingtree.list()
-        nb_mappingtree = len(ents)
-
-        # create a first additional mapping tree
-        self.instance.mappingtree.create(NEW_SUFFIX_1, bename=NEW_BACKEND_1)
-        ents = self.instance.mappingtree.list()
-        assert len(ents) == (nb_mappingtree + 1)
-
-        suffixes = self.instance.suffix.list()
-        assert len(suffixes) == 2
-        for suffix in suffixes:
-            self.instance.log.info("suffix is %s" % suffix)
-
-    def test_toBackend(self):
-        backends = self.instance.suffix.toBackend(suffix=NEW_SUFFIX_1)
-        assert len(backends) == 1
-        backend = backends[0]
-        self.instance.log.info("backend entry is %r" % backend)
-        assert backend.getValue(
-            BACKEND_PROPNAME_TO_ATTRNAME[BACKEND_SUFFIX]) == NEW_SUFFIX_1
-        assert backend.getValue(
-            BACKEND_PROPNAME_TO_ATTRNAME[BACKEND_NAME]) == NEW_BACKEND_1
-
-    def test_getParent(self):
-        parent = self.instance.suffix.getParent(suffix=NEW_SUFFIX_1)
-        assert parent is None
-
-        backendEntry = self.instance.backend.create(
-            NEW_CHILDSUFFIX_1, {BACKEND_NAME: NEW_CHILDBACKEND_1})
-        # create a third additional mapping tree, that is child of NEW_SUFFIX_1
-        self.instance.mappingtree.create(
-            NEW_CHILDSUFFIX_1, bename=NEW_CHILDBACKEND_1, parent=NEW_SUFFIX_1)
-        parent = self.instance.suffix.getParent(suffix=NEW_CHILDSUFFIX_1)
-        self.instance.log.info("Retrieved parent of %s:  %s" %
-                               (NEW_CHILDSUFFIX_1, parent))
-        assert parent == NEW_SUFFIX_1
-
-
-if __name__ == "__main__":
-    test = Test_suffix()
-    test.setUp()
-
-    test.test_list()
-    test.test_toBackend()
-    test.test_getParent()
-
-    test.tearDown()
diff --git a/tests/test_module_proxy.py b/tests/test_module_proxy.py
deleted file mode 100644
index 288b9ab..0000000
--- a/tests/test_module_proxy.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import pytest
-import os
-from lib389.ds_instance import DSModuleProxy
-
-
-def test_module_proxy_fun_with_no_arg(fake_ds_class, fake_ds_modules):
-    ds_inst = fake_ds_class()
-    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
-                                        os.path.basename(fake_ds_modules))
-    assert ds_inst.repl.with_no_arg() == ds_inst
-
-
-def test_module_proxy_fun_with_one_arg(fake_ds_class, fake_ds_modules):
-    ds_inst = fake_ds_class()
-    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
-                                        os.path.basename(fake_ds_modules))
-    assert ds_inst.repl.with_one_arg(1) == (ds_inst, 1)
-
-
-def test_module_proxy_plugin_fun_with_no_arg(fake_ds_class, fake_ds_modules):
-    ds_inst = fake_ds_class()
-    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
-                                        os.path.basename(fake_ds_modules))
-    assert ds_inst.plugin.automember.with_no_arg() == ds_inst
-
-
-def test_module_proxy_plugin_fun_with_one_arg(fake_ds_class, fake_ds_modules):
-    ds_inst = fake_ds_class()
-    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
-                                        os.path.basename(fake_ds_modules))
-    assert ds_inst.plugin.automember.with_one_arg(2) == (ds_inst, 2)
-
-
-def test_module_proxy_plugin_call_ds_method(fake_ds_class, fake_ds_modules):
-    ds_inst = fake_ds_class()
-    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
-                                        os.path.basename(fake_ds_modules))
-    assert ds_inst.plugin.automember.calling_ds_method(2) == (ds_inst, 1, 2)
-
-
-def test_module_proxy_plugin_call_another_module(fake_ds_class,
-                                                 fake_ds_modules):
-    ds_inst = fake_ds_class()
-    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
-                                        os.path.basename(fake_ds_modules))
-    assert ds_inst.plugin.automember.calling_repl(2, 3) == 6
-
-
-def test_module_proxy_plugin_call_another_module_kwarg(fake_ds_class,
-                                                       fake_ds_modules):
-    ds_inst = fake_ds_class()
-    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
-                                        os.path.basename
-                                        (fake_ds_modules))
-    assert ds_inst.plugin.automember.calling_repl_with_kwarg1() == 1
-    assert ds_inst.plugin.automember.calling_repl_with_kwarg2() == 2
-
-
-def test_module_proxy_plugin_call_with_all(fake_ds_class, fake_ds_modules):
-    ds_inst = fake_ds_class()
-    DSModuleProxy.populate_with_proxies(ds_inst, ds_inst,
-                                        os.path.basename
-                                        (fake_ds_modules))
-    assert ds_inst.plugin.automember.with_all(0, 3, 2, 1) == (1, 7, 5, 3)
-
-
-if __name__ == '__main__':
-    # Run isolated
-    # -s for DEBUG mo     de
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/tests/utils_test.py b/tests/utils_test.py
deleted file mode 100644
index d1af6aa..0000000
--- a/tests/utils_test.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2015 Red Hat, Inc
-# All rights reserved.
-#
-# License: GPL (version 3 or any later version).
-# See LICENSE for details.
-# --- END COPYRIGHT BLOCK ---
-#
-import pytest
-from lib389.utils import *
-
-
-def test_normalizeDN():
-    test = [
-        (r'dc=example,dc=com', r'dc=example,dc=com'),
-        (r'dc=example, dc=com', r'dc=example,dc=com'),
-        (r'cn="dc=example,dc=com",cn=config',
-         'cn=dc\\=example\\,dc\\=com,cn=config'),
-    ]
-    for k, v in test:
-        r = normalizeDN(k)
-        assert r == v, "Mismatch %r vs %r" % (r, v)
-
-
-def test_escapeDNValue():
-    test = [(r'"dc=example, dc=com"', r'\"dc\=example\,\ dc\=com\"')]
-    for k, v in test:
-        r = escapeDNValue(k)
-        assert r == v, "Mismatch %r vs %r" % (r, v)
-
-
-def test_escapeDNFiltValue():
-    test = [(r'"dc=example, dc=com"',
-             '\\22dc\\3dexample\\2c\\20dc\\3dcom\\22')]
-    for k, v in test:
-        r = escapeDNFiltValue(k)
-        assert r == v, "Mismatch %r vs %r" % (r, v)
-
-#
-# socket related functions
-#
-import socket
-
-
-def test_isLocalHost():
-    test = [
-        ('localhost', True),
-        ('localhost.localdomain', True),
-        (socket.gethostname(), True),
-        ('www.google.it', False)]
-    for k, v in test:
-        r = isLocalHost(k)
-        assert r == v, "Mismatch %r vs %r on %r" % (r, v, k)
-
-
-def test_update_jewhost_with_fqdn():
-    test = [
-        ({'hostname': 'localhost'}, ('localhost.localdomain', True)),
-        ({'hostname': 'remote'}, ('remote', False)),
-    ]
-    for k, v in test:
-        old = k.copy()
-        expected_host, expected_r = v
-        r = update_newhost_with_fqdn(k)
-        assert expected_r == r, "Mismatch %r vs %r for %r" % (
-            r, expected_r, old)
-        assert expected_host == k['hostname'], "Mismatch %r vs %r for %r" % (
-            k['hostname'], expected_host, old)
-
-
-def test_formatInfData():
-    ret = formatInfData({
-        'hostname': 'localhost.localdomain',
-        'user-id': 'dirsrv',
-        'group-id': 'dirsrv',
-        'ldap-port': 12345,
-        'root-dn': 'cn=directory manager',
-        'root-pw': 'password',
-        'server-id': 'dirsrv',
-        'suffix': 'o=base1',
-    })
-    log.info("content: %r" % ret)
-
-
-def test_formatInfData_withadmin():
-    instance_params = {
-        'hostname': 'localhost.localdomain',
-        'user-id': 'dirsrv',
-        'group-id': 'dirsrv',
-        'ldap-port': 12346,
-        'root-dn': 'cn=directory manager',
-        'root-pw': 'password',
-        'server-id': 'dirsrv',
-        'suffix': 'o=base1'}
-    admin_params = {
-        'have_admin': True,
-        'create_admin': True,
-        'admin_domain': 'example.com',
-        'cfgdshost': 'localhost',
-        'cfgdsport': 12346,
-        'cfgdsuser': 'admin',
-        'cfgdspwd': 'admin'}
-    instance_params.update(admin_params)
-    ret = formatInfData(instance_params)
-    log.info("content: %r" % ret)
-
-
-def test_formatInfData_withconfigserver():
-    instance_params = {
-        'hostname': 'localhost.localdomain',
-        'user-id': 'dirsrv',
-        'group-id': 'dirsrv',
-        'ldap-port': 12346,
-        'root-dn': 'cn=directory manager',
-        'root-pw': 'password',
-        'server-id': 'dirsrv',
-        'suffix': 'o=base1'}
-    admin_params = {
-        'have_admin': True,
-        'cfgdshost': 'localhost',
-        'cfgdsport': 12346,
-        'cfgdsuser': 'admin',
-        'cfgdspwd': 'admin',
-        'admin_domain': 'example.com'}
-    instance_params.update(admin_params)
-    ret = formatInfData(instance_params)
-    log.info("content: %r" % ret)
-
-
-if __name__ == "__main__":
-    CURRENT_FILE = os.path.realpath(__file__)
-    pytest.main("-s -v %s" % CURRENT_FILE)
-- 
2.4.3

