mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

ugaston
22.56.2008 b641be47ccf7eb5261be4f44abbf016dfa0e9ddd
New Replication Changelog testsuite
1 files added
5 files modified
1686 ■■■■■ changed files
opends/tests/functional-tests/testcases/replication/changelog/changelog.xml 1350 ●●●●● patch | view | raw | blame | history
opends/tests/functional-tests/testcases/replication/replication.xml 5 ●●●●● patch | view | raw | blame | history
opends/tests/functional-tests/testcases/replication/replication_setup.xml 106 ●●●● patch | view | raw | blame | history
opends/tests/shared/functions/dsadm.xml 61 ●●●● patch | view | raw | blame | history
opends/tests/shared/functions/topology.xml 80 ●●●● patch | view | raw | blame | history
opends/tests/shared/functions/utils.xml 84 ●●●●● patch | view | raw | blame | history
opends/tests/functional-tests/testcases/replication/changelog/changelog.xml
New file
@@ -0,0 +1,1350 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "../../../../shared/stax.dtd">
<!--
 ! CDDL HEADER START
 !
 ! The contents of this file are subject to the terms of the
 ! Common Development and Distribution License, Version 1.0 only
 ! (the "License").  You may not use this file except in compliance
 ! with the License.
 !
 ! You can obtain a copy of the license at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
 ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 ! See the License for the specific language governing permissions
 ! and limitations under the License.
 !
 ! When distributing Covered Code, include this CDDL HEADER in each
 ! file and include the License file at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 ! add the following below this CDDL HEADER, with the fields enclosed
 ! by brackets "[]" replaced with your own identifying information:
 !      Portions Copyright [yyyy] [name of copyright owner]
 !
 ! CDDL HEADER END
 !
 !      Copyright 2008 Sun Microsystems, Inc.
 ! -->
<stax>
  <defaultcall function="replication_changelog"/>
  <function name="replication_changelog">
    <sequence>
      <block name="'changelog'">
        <sequence>
          <script>
            if not CurrentTestPath.has_key('group'):
              CurrentTestPath['group']='replication'
            CurrentTestPath['suite']=STAXCurrentBlock
          </script>
          <call function="'testSuite_Preamble'"/>
          <!--- Test Suite information
          #@TestSuiteName       Replication Changelog Tests
          #@TestSuitePurpose    Test the accessibility of the changelog through
                                search, export, backup and restore operations.
                                Also, test other replication features using
                                changelog properties.
          #@TestSuiteID         Changelog Tests
          #@TestSuiteGroup      Changelog
          #@TestGroup           Replication
          #@TestScript          replication_changelog.xml
          #@TestHTMLLink        http://opends.dev.java.net/
          -->
          <import machine="STAF_LOCAL_HOSTNAME"
                  file="'%s/testcases/replication/replication_setup.xml'
                        % (TESTS_DIR)"/>
          <call function="'replication_setup'">
            { 'dataFile' : 'Example.ldif' }
          </call>
          <!--- Test Case information
          #@TestMarker          Replication Changelog Tests
          #@TestName            Replication: Changelog: Search
          #@TestID              Search
          #@TestPurpose         Check replication changelog can be searched and
                                look up changes
          #@TestPreamble
          #@TestSteps           Add entry to server A
          #@TestSteps           Modify entry on server A
          #@TestSteps           Search changelogs and check for made changes
          #@TestPostamble
          #@TestResult          Success if the corresponding changes can be
                                found in the changelog
          -->
          <testcase name="getTestCaseName('Search')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Changelog: Search. \
                Check replication changelog can be searched and look up changes'
              </message>
              <!-- Add entry to "master" server -->
              <script>
                userDn = 'uid=iabizen.0, ou=People, %s' % synchroSuffix
                listAttr = []
                listAttr.append('objectclass:top')
                listAttr.append('objectclass:organizationalperson')
                listAttr.append('objectclass:inetorgperson')
                listAttr.append('objectclass:person')
                listAttr.append('givenname:Izen.0')
                listAttr.append('sn:Abizen.0')
                listAttr.append('cn:Izen Abizen.0')
                listAttr.append('l:ICNC')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : masterHost,
                  'dsPath'         : masterPath,
                  'dsInstanceHost' : masterHost,
                  'dsInstancePort' : master.getPort(),
                  'dsInstanceDn'   : master.getRootDn(),
                  'dsInstancePswd' : master.getRootPwd(),
                  'DNToAdd'        : userDn,
                  'listAttributes' : listAttr,
                  'expectedRC'     : 0
                }
              </call>
              <!-- Modify entry on one of the servers -->
              <call function="'modifyAnAttribute'">
                { 'location'          : masterHost,
                  'dsPath'            : masterPath,
                  'dsInstanceHost'    : masterHost,
                  'dsInstancePort'    : master.getPort(),
                  'dsInstanceDn'      : master.getRootDn(),
                  'dsInstancePswd'    : master.getRootPwd(),
                  'DNToModify'        : userDn,
                  'attributeName'     : 'l',
                  'newAttributeValue' : 'GEC',
                  'changetype'        : 'replace',
                  'expectedRC'        : 0
                }
              </call>
              <!-- Let some time for the change to propagate -->
              <call function="'Sleep'">
                { 'location'             :  masterHost,
                  'sleepForMilliSeconds' :  2000
                }
              </call>
              <!-- Search changelog in the various replication servers -->
              <paralleliterate var="server"
                               in="_topologyServerList">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                  </script>
                  <!-- Search for entry add -->
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges',
                      'dsFilter'         : 'uid=iabizen.0',
                      'dsAttributes'     : 'dn'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <!-- expect entry returned => len(searchResult) > 0
                    =====> resultLength = 1 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : 1
                    }
                  </call>
                  <!-- Search for entry modify -->
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges',
                      'dsFilter'         : 'l=GEC',
                      'dsAttributes'     : 'dn'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <!-- expect entry returned => len(searchResult) > 0
                    =====> resultLength = 1 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : 1
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, master, consumerList, synchroSuffix ]
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker          Replication Changelog Tests
          #@TestName            Replication: Changelog: Export (on-line)
          #@TestID              Export (on-line)
          #@TestPurpose         Check replication changelog can be exported
                                on-line and look up changes
          #@TestPreamble
          #@TestSteps           Add entry to server A
          #@TestSteps           Export every changelog to ldif file
          #@TestSteps           Check for added entry in each exported changelog
                                file
          #@TestPostamble
          #@TestResult          Success if the corresponding change can be found
                                in the exported changelog files
          -->
          <testcase name="getTestCaseName('Export (on-line)')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Changelog: Export (on-line). \
                Check replication changelog can be exported on-line and look \
                up changes'
              </message>
              <!-- Add entry to "master" server -->
              <script>
                userDn = 'uid=iabizen.2, ou=People, %s' % synchroSuffix
                listAttr = []
                listAttr.append('objectclass:top')
                listAttr.append('objectclass:organizationalperson')
                listAttr.append('objectclass:inetorgperson')
                listAttr.append('objectclass:person')
                listAttr.append('givenname:Izen.2')
                listAttr.append('sn:Abizen.2')
                listAttr.append('cn:Izen Abizen.2')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : masterHost,
                  'dsPath'         : masterPath,
                  'dsInstanceHost' : masterHost,
                  'dsInstancePort' : master.getPort(),
                  'dsInstanceDn'   : master.getRootDn(),
                  'dsInstancePswd' : master.getRootPwd(),
                  'DNToAdd'        : userDn,
                  'listAttributes' : listAttr,
                  'expectedRC'     : 0
                }
              </call>
              <!-- Let some time for the change to propagate -->
              <call function="'Sleep'">
                { 'location'             :  masterHost,
                  'sleepForMilliSeconds' :  2000
                }
              </call>
              <!-- Export changelog in the various replication servers, then
                check for added entry in the exported files -->
              <paralleliterate var="server"
                               in="_topologyServerList">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                    serverDataDir = '%s/%s' % (server.getDir(),relativeDataDir)
                    exportedChangelog = \
                      '%s/replication/changelog_export_online.ldif' \
                      % serverDataDir
                  </script>
                  <!-- Export changelog data from server -->
                  <call function="'exportLdifTask'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : serverPath,
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'taskID'         : 'changelog export task',
                      'ldifFile'       : exportedChangelog,
                      'backEnd'        : 'replicationChanges'
                    }
                  </call>
                  <!-- Check for the added entry inside the exported file -->
                  <call function="'grep'">
                    {
                      'location'   : server.getHostname(),
                      'filename'   : exportedChangelog,
                      'testString' : 'uid=iabizen.2'
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, master, consumerList, synchroSuffix ]
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker          Replication Changelog Tests
          #@TestName            Replication: Changelog:
                                Backup-restore (off-line)
          #@TestID              Backup-restore (off-line)
          #@TestPurpose         Check replication changelog can be backuped and
                                restored off-line
          #@TestPreamble        Backup server suffix (done at the beginning of
                                the test suite)
          #@TestSteps           Add entry A to server
          #@TestSteps           Stop servers
          #@TestSteps           Backup every changelog
          #@TestSteps           Start servers
          #@TestSteps           Add entry B to server
          #@TestSteps           Stop servers
          #@TestSteps           Restore server suffix (without entries A and B)
          #@TestSteps           Restore every changelog
          #@TestSteps           Start servers
          #@TestSteps           Check for added entry A in changelog and server
          #@TestSteps           Check for added entry B in changelog and server
          #@TestPostamble
          #@TestResult          Success if the search for entry A succeeds and
                                the search for entry B fails
          -->
          <testcase name="getTestCaseName('Backup-restore (off-line)')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Changelog: Backup-restore (off-line). \
                Check replication changelog can be backuped and restored \
                off-line'
              </message>
              <!-- Add entry A to "master" server -->
              <script>
                userDnA = 'uid=iabizen.A, ou=People, %s' % synchroSuffix
                listAttr = []
                listAttr.append('objectclass:top')
                listAttr.append('objectclass:organizationalperson')
                listAttr.append('objectclass:inetorgperson')
                listAttr.append('objectclass:person')
                listAttr.append('givenname:Izen.A')
                listAttr.append('sn:Abizen.A')
                listAttr.append('cn:Izen Abizen.A')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : masterHost,
                  'dsPath'         : masterPath,
                  'dsInstanceHost' : masterHost,
                  'dsInstancePort' : master.getPort(),
                  'dsInstanceDn'   : master.getRootDn(),
                  'dsInstancePswd' : master.getRootPwd(),
                  'DNToAdd'        : userDnA,
                  'listAttributes' : listAttr,
                  'expectedRC'     : 0
                }
              </call>
              <!-- Let some time for the change to propagate -->
              <call function="'Sleep'">
                { 'location'             :  masterHost,
                  'sleepForMilliSeconds' :  2000
                }
              </call>
              <!-- Stop the servers in the topology -->
              <call function="'stopServers'">
                [_topologyServerList]
              </call>
              <!-- Backup changelog in the various replication servers -->
              <paralleliterate var="server"
                               in="_topologyServerList">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                    serverDataDir = '%s/%s' % (server.getDir(),relativeDataDir)
                    changelogBackupDir = '%s/replication/changelog_backup' \
                                         % serverDataDir
                  </script>
                  <call function="'backup'">
                    { 'location'  : server.getHostname(),
                      'dsPath'    : serverPath,
                      'backupDir' : changelogBackupDir,
                      'backEnd'   : 'replicationChanges'
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Start the servers in the topology -->
              <call function="'startServers'">
                [_topologyServerList]
              </call>
              <!-- Add entry B to "master" server -->
              <script>
                userDnB = 'uid=iabizen.B, ou=People, %s' % synchroSuffix
                listAttr = []
                listAttr.append('objectclass:top')
                listAttr.append('objectclass:organizationalperson')
                listAttr.append('objectclass:inetorgperson')
                listAttr.append('objectclass:person')
                listAttr.append('givenname:Izen.B')
                listAttr.append('sn:Abizen.B')
                listAttr.append('cn:Izen Abizen.B')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : masterHost,
                  'dsPath'         : masterPath,
                  'dsInstanceHost' : masterHost,
                  'dsInstancePort' : master.getPort(),
                  'dsInstanceDn'   : master.getRootDn(),
                  'dsInstancePswd' : master.getRootPwd(),
                  'DNToAdd'        : userDnB,
                  'listAttributes' : listAttr,
                  'expectedRC'     : 0
                }
              </call>
              <!-- Let some time for the change to propagate -->
              <call function="'Sleep'">
                { 'location'             :  masterHost,
                  'sleepForMilliSeconds' :  2000
                }
              </call>
              <!-- Stop the servers in the topology -->
              <call function="'stopServers'">
                [_topologyServerList]
              </call>
              <!-- Restore master_backup in every server, then restore
                changelog_backup in the various replication servers -->
              <paralleliterate var="server"
                               in="_topologyServerList"
                               indexvar="i">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                    serverDataDir = '%s/%s' % (server.getDir(),relativeDataDir)
                    changelogBackupDir = '%s/replication/changelog_backup' \
                                         % serverDataDir
                  </script>
                  <!-- Restore master_backup -->
                  <if expr="i != 0">
                    <!-- _topologyServerList[0] corresponds to "master", so
                      no need to copy the files for that case -->
                    <sequence>
                      <if expr="os.path.exists
                                ('%s/config/schematokens.dat' % dsPath)" >
                        <call function="'copyFile'">
                          { 'location'   : masterHost,
                            'remotehost' : server.getHostname(),
                            'srcfile'    : '%s/config/schematokens.dat' \
                                           % masterPath,
                            'destfile'   : '%s/config/schematokens.dat' \
                                           % serverPath
                          }
                        </call>
                      </if>
                      <call function="'CopyFolderByExtension'">
                        { 'location'   : masterHost,
                          'remotehost' : server.getHostname(),
                          'srcfolder'  : masterBackupDir,
                          'destfolder' : '%s/replication/master_backup' \
                                         % serverDataDir,
                          'extension'  : '*'
                        }
                      </call>
                    </sequence>
                  </if>
                  <call function="'restore'">
                    { 'location'  : server.getHostname(),
                      'dsPath'    : serverPath,
                      'backupDir' : '%s/replication/master_backup' \
                                    % serverDataDir
                    }
                  </call>
                  <!-- Restore changelog_backup -->
                  <call function="'restore'">
                    { 'location'  : server.getHostname(),
                      'dsPath'    : serverPath,
                      'backupDir' : changelogBackupDir
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Start the servers in the topology -->
              <call function="'startServers'">
                [_topologyServerList]
              </call>
              <!-- Search synchroSuffix and changelog in the various servers,
                looking for entries A (should be there) and B (shouldn't be) -->
              <paralleliterate var="server"
                               in="_topologyServerList">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                  </script>
                  <!-- Search for entry A (should be there) -->
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : userDnA,
                      'dsFilter'         : 'objectclass=*',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 0
                    }
                  </call>
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges',
                      'dsFilter'         : 'uid=iabizen.A',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 0
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <!-- expect entry returned => len(searchResult) > 0
                    =====> resultLength = 1 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : 1
                    }
                  </call>
                  <!-- Search for entry B (should NOT be there) -->
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : userDnB,
                      'dsFilter'         : 'objectclass=*',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 32
                    }
                  </call>
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges',
                      'dsFilter'         : 'uid=iabizen.B',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 0
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <!-- expect NO entry returned => len(searchResult) = 0
                    =====> resultLength = 0 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : 0
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, master, consumerList, synchroSuffix ]
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker          Replication Changelog Tests
          #@TestName            Replication: Changelog: Backup-restore (on-line)
          #@TestID              Backup-restore (on-line)
          #@TestPurpose         Check replication changelog can be backuped and
                                restored on-line
          #@TestPreamble        Backup server suffix (done at the beginning of
                                the test suite)
          #@TestSteps           Add entry AA to server
          #@TestSteps           Backup every changelog
          #@TestSteps           Add entry BB to server
          #@TestSteps           Restore every changelog
          #@TestSteps           Restore server suffix (without entries AA & BB)
          #@TestSteps           Check for added entry AA in changelog and server
          #@TestSteps           Check for added entry BB in changelog and server
          #@TestPostamble
          #@TestResult          Success if the search for entry AA succeeds and
                                the search for entry BB fails
          -->
          <testcase name="getTestCaseName('Backup-restore (on-line)')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Changelog: Backup-restore (on-line). \
                Check replication changelog can be backuped and restored \
                on-line'
              </message>
              <!-- Add entry AA to "master" server -->
              <script>
                userDnAA = 'uid=iabizen.AA, ou=People, %s' % synchroSuffix
                listAttr = []
                listAttr.append('objectclass:top')
                listAttr.append('objectclass:organizationalperson')
                listAttr.append('objectclass:inetorgperson')
                listAttr.append('objectclass:person')
                listAttr.append('givenname:Izen.AA')
                listAttr.append('sn:Abizen.AA')
                listAttr.append('cn:Izen Abizen.AA')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : masterHost,
                  'dsPath'         : masterPath,
                  'dsInstanceHost' : masterHost,
                  'dsInstancePort' : master.getPort(),
                  'dsInstanceDn'   : master.getRootDn(),
                  'dsInstancePswd' : master.getRootPwd(),
                  'DNToAdd'        : userDnAA,
                  'listAttributes' : listAttr,
                  'expectedRC'     : 0
                }
              </call>
              <!-- Let some time for the change to propagate -->
              <call function="'Sleep'">
                { 'location'             :  masterHost,
                  'sleepForMilliSeconds' :  2000
                }
              </call>
              <!-- Backup changelog in the various replication servers -->
              <paralleliterate var="server"
                               in="_topologyServerList">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                    serverDataDir = '%s/%s' % (server.getDir(),relativeDataDir)
                    changelogBackupDir = \
                      '%s/replication/changelog_backup_online' % serverDataDir
                  </script>
                  <call function="'backupTask'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : serverPath,
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'taskID'         : 'changelog backup task',
                      'backupDir'      : changelogBackupDir,
                      'backEnd'        : 'replicationChanges'
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Add entry BB to "master" server -->
              <script>
                userDnBB = 'uid=iabizen.BB, ou=People, %s' % synchroSuffix
                listAttr = []
                listAttr.append('objectclass:top')
                listAttr.append('objectclass:organizationalperson')
                listAttr.append('objectclass:inetorgperson')
                listAttr.append('objectclass:person')
                listAttr.append('givenname:Izen.BB')
                listAttr.append('sn:Abizen.BB')
                listAttr.append('cn:Izen Abizen.BB')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : masterHost,
                  'dsPath'         : masterPath,
                  'dsInstanceHost' : masterHost,
                  'dsInstancePort' : master.getPort(),
                  'dsInstanceDn'   : master.getRootDn(),
                  'dsInstancePswd' : master.getRootPwd(),
                  'DNToAdd'        : userDnBB,
                  'listAttributes' : listAttr,
                  'expectedRC'     : 0
                }
              </call>
              <!-- Let some time for the change to propagate -->
              <call function="'Sleep'">
                { 'location'             :  masterHost,
                  'sleepForMilliSeconds' :  2000
                }
              </call>
              <!-- Restore changelog_backup_online in the various replication
                servers, then restore master_backup in every server -->
              <paralleliterate var="server"
                               in="_topologyServerList"
                               indexvar="i">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                    serverDataDir = '%s/%s' % (server.getDir(),relativeDataDir)
                    changelogBackupDir = \
                      '%s/replication/changelog_backup_online' % serverDataDir
                  </script>
                  <!-- Restore changelog_backup -->
                  <call function="'restoreTask'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : serverPath,
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'taskID'         : 'changelog restore task',
                      'backupDir'      : changelogBackupDir
                    }
                  </call>
                  <!-- Restore master_backup -->
                  <if expr="i != 0">
                    <!-- _topologyServerList[0] corresponds to "master", so
                      no need to copy the files for that case -->
                    <sequence>
                      <if expr="os.path.exists
                                ('%s/config/schematokens.dat' % dsPath)" >
                        <call function="'copyFile'">
                          { 'location'   : masterHost,
                            'remotehost' : server.getHostname(),
                            'srcfile'    : '%s/config/schematokens.dat' \
                                           % masterPath,
                            'destfile'   : '%s/config/schematokens.dat' \
                                           % serverPath
                          }
                        </call>
                      </if>
                      <call function="'CopyFolderByExtension'">
                        { 'location'   : masterHost,
                          'remotehost' : server.getHostname(),
                          'srcfolder'  : masterBackupDir,
                          'destfolder' : '%s/replication/master_backup' \
                                         % serverDataDir,
                          'extension'  : '*'
                        }
                      </call>
                    </sequence>
                  </if>
                  <call function="'restoreTask'">
                    { 'location'       : server.getHostname(),
                      'dsPath'         : serverPath,
                      'dsInstanceHost' : server.getHostname(),
                      'dsInstancePort' : server.getPort(),
                      'dsInstanceDn'   : server.getRootDn(),
                      'dsInstancePswd' : server.getRootPwd(),
                      'taskID'         : 'restore task',
                      'backupDir'      : '%s/replication/master_backup' \
                                         % serverDataDir
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Search synchroSuffix and changelog in the various servers,
                looking for entries AA (should be there) and BB (shouldn't be)
                -->
              <paralleliterate var="server"
                               in="_topologyServerList">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                  </script>
                  <!-- Search for entry AA (should be there) -->
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : userDnAA,
                      'dsFilter'         : 'objectclass=*',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 0
                    }
                  </call>
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges',
                      'dsFilter'         : 'uid=iabizen.AA',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 0
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <!-- expect entry returned => len(searchResult) > 0
                    =====> resultLength = 1 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : 1
                    }
                  </call>
                  <!-- Search for entry BB (should NOT be there) -->
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : userDnBB,
                      'dsFilter'         : 'objectclass=*',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 32
                    }
                  </call>
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges',
                      'dsFilter'         : 'uid=iabizen.BB',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 0
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <!-- expect NO entry returned => len(searchResult) = 0
                    =====> resultLength = 0 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : 0
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, master, consumerList, synchroSuffix ]
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker          Replication Changelog Tests
          #@TestName            Replication: Changelog: Changelog Reset
          #@TestID              Changelog Reset
          #@TestPurpose         Check replication changelog is reset by
                                dsreplication pre/post-external-initialize
          #@TestPreamble
          #@TestSteps           Add entry to server A
          #@TestSteps           Search changelogs and check for made change
          #@TestSteps           Reset changelog (call pre/post-external init)
          #@TestSteps           Search changelogs and check for made change
          #@TestPostamble
          #@TestResult          Success if the corresponding change can be found
                                in the changelog prior to the reset but not any
                                more after the reset
          -->
          <testcase name="getTestCaseName('Changelog Reset')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Changelog: Changelog Reset. \
                Check replication changelog is reset by \
                dsreplication pre/post-external-initialize'
              </message>
              <!-- Add entry to "master" server -->
              <script>
                userDn = 'uid=iabizen.3, ou=People, %s' % synchroSuffix
                listAttr = []
                listAttr.append('objectclass:top')
                listAttr.append('objectclass:organizationalperson')
                listAttr.append('objectclass:inetorgperson')
                listAttr.append('objectclass:person')
                listAttr.append('givenname:Izen.3')
                listAttr.append('sn:Abizen.3')
                listAttr.append('cn:Izen Abizen.3')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : masterHost,
                  'dsPath'         : masterPath,
                  'dsInstanceHost' : masterHost,
                  'dsInstancePort' : master.getPort(),
                  'dsInstanceDn'   : master.getRootDn(),
                  'dsInstancePswd' : master.getRootPwd(),
                  'DNToAdd'        : userDn,
                  'listAttributes' : listAttr,
                  'expectedRC'     : 0
                }
              </call>
              <!-- Let some time for the change to propagate -->
              <call function="'Sleep'">
                { 'location'             :  masterHost,
                  'sleepForMilliSeconds' :  2000
                }
              </call>
              <!-- Search changelog in the various replication servers -->
              <paralleliterate var="server"
                               in="_topologyServerList">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                  </script>
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges' ,
                      'dsFilter'         : 'uid=iabizen.3',
                      'dsAttributes'     : 'dn'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <!-- expect entry returned => len(searchResult) > 0
                    =====> resultLength = 1 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : 1
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Reset the changelog (call pre/post-external-init) -->
              <call function="'resetReplicationData'">
                { 'location'           : clientHost,
                  'dsPath'             : clientPath,
                  'sourceInstanceHost' : masterHost,
                  'sourceInstancePort' : master.getPort(),
                  'sourceInstanceDn'   : master.getRootDn(),
                  'sourceInstancePswd' : master.getRootPwd(),
                  'backupDir'          : masterBackupDir,
                  'suffixDn'           : synchroSuffix
                }
              </call>
              <!-- Search changelog in the various replication servers -->
              <paralleliterate var="server"
                               in="_topologyServerList">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                  </script>
                  <!-- Search for entry in the suffix (should NOT be there) -->
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : userDn,
                      'dsFilter'         : 'objectclass=*',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 32
                    }
                  </call>
                  <!-- Search for corresponding change in the changelog
                    (should NOT be there) -->
                  <call function="'ldapSearchWithScript'">
                    { 'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges',
                      'dsFilter'         : 'uid=iabizen.3',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 0
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <!-- expect NO entry returned => len(searchResult) = 0
                    =====> resultLength = 0 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : 0
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, master, consumerList, synchroSuffix ]
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <!--- Test Case information
          #@TestMarker          Replication Changelog Tests
          #@TestName            Replication: Changelog: Changelog Purge
          #@TestID              Changelog Purge
          #@TestPurpose         Check replication changelog is purged after the
                                purge delay specified in the conf expires
          #@TestPreamble
          #@TestSteps           Set purge delay to 20 seconds on server A
          #@TestSteps           Add entry X to server A
          #@TestSteps           Add entry Y to server A
          #@TestSteps           Search changelogs and check for made change
          #@TestSteps           Let purge delay expire (sleep for 30 seconds)
          #@TestSteps           Search changelogs and check for made change
          #@TestPostamble
          #@TestResult          Success if the corresponding change for entry X
                                can be found in every changelog before the purge
                                delay expires but not any more on server A's
                                after the delay expires (entry Y will still be
                                there though since the last change is always
                                kept)
          -->
          <testcase name="getTestCaseName('Changelog Purge')">
            <sequence>
              <call function="'testCase_Preamble'"/>
              <message>
                'Replication: Changelog: Changelog Purge. \
                Check replication changelog is purged after the purge delay \
                specified in the conf expires'
              </message>
              <message>
                'Set purge delay to 20 seconds on server %s:%s' \
                % (masterHost, master.getPort())
              </message>
              <!-- Set purge delay to 20s on "master" server -->
              <call function="'dsconfigSet'">
                { 'location'         : masterHost,
                  'dsPath'           : masterPath,
                  'dsInstanceHost'   : masterHost,
                  'dsInstancePort'   : master.getPort(),
                  'dsInstanceDn'     : master.getRootDn(),
                  'dsInstancePswd'   : master.getRootPwd(),
                  'objectName'       : 'replication-server' ,
                  'propertyType'     : 'provider',
                  'propertyName'     : 'Multimaster Synchronization',
                  'attributeName'    : 'replication-purge-delay' ,
                  'attributeValue'   : '20s'
                }
              </call>
              <!-- Add entry X to "master" server -->
              <script>
                userDnX = 'uid=iabizen.X, ou=People, %s' % synchroSuffix
                listAttr = []
                listAttr.append('objectclass:top')
                listAttr.append('objectclass:organizationalperson')
                listAttr.append('objectclass:inetorgperson')
                listAttr.append('objectclass:person')
                listAttr.append('givenname:Izen.X')
                listAttr.append('sn:Abizen.X')
                listAttr.append('cn:Izen Abizen.X')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : masterHost,
                  'dsPath'         : masterPath,
                  'dsInstanceHost' : masterHost,
                  'dsInstancePort' : master.getPort(),
                  'dsInstanceDn'   : master.getRootDn(),
                  'dsInstancePswd' : master.getRootPwd(),
                  'DNToAdd'        : userDnX,
                  'listAttributes' : listAttr,
                  'expectedRC'     : 0
                }
              </call>
              <!-- Add entry Y to "master" server -->
              <script>
                userDnY = 'uid=iabizen.Y, ou=People, %s' % synchroSuffix
                listAttr = []
                listAttr.append('objectclass:top')
                listAttr.append('objectclass:organizationalperson')
                listAttr.append('objectclass:inetorgperson')
                listAttr.append('objectclass:person')
                listAttr.append('givenname:Izen.Y')
                listAttr.append('sn:Abizen.Y')
                listAttr.append('cn:Izen Abizen.Y')
              </script>
              <call function="'addAnEntry'">
                { 'location'       : masterHost,
                  'dsPath'         : masterPath,
                  'dsInstanceHost' : masterHost,
                  'dsInstancePort' : master.getPort(),
                  'dsInstanceDn'   : master.getRootDn(),
                  'dsInstancePswd' : master.getRootPwd(),
                  'DNToAdd'        : userDnY,
                  'listAttributes' : listAttr,
                  'expectedRC'     : 0
                }
              </call>
              <!-- Let some time for the changes to propagate -->
              <call function="'Sleep'">
                { 'location'             :  masterHost,
                  'sleepForMilliSeconds' :  2000
                }
              </call>
              <!-- Search changelog in the various replication servers -->
              <paralleliterate var="server"
                               in="_topologyServerList">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                  </script>
                  <call function="'ldapSearchWithScript'">
                    {
                      'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges' ,
                      'dsFilter'         : 'uid=iabizen.X',
                      'dsAttributes'     : 'dn'
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                  </script>
                  <!-- expect entry returned => len(searchResult) > 0
                    =====> resultLength = 1 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : 1
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Let the purge delay expire: sleep for 60s -->
              <call function="'Sleep'">
                { 'location'             :  masterHost,
                  'sleepForMilliSeconds' :  60000
                }
              </call>
              <!-- Search changelog in the various replication servers -->
              <paralleliterate var="server"
                               in="_topologyServerList"
                               indexvar="i">
                <sequence>
                  <script>
                    serverPath = '%s/%s' % (server.getDir(), OPENDSNAME)
                  </script>
                  <call function="'ldapSearchWithScript'">
                    {
                      'location'         : server.getHostname(),
                      'dsPath'           : serverPath,
                      'dsInstanceHost'   : server.getHostname(),
                      'dsInstancePort'   : server.getPort(),
                      'dsInstanceDn'     : server.getRootDn(),
                      'dsInstancePswd'   : server.getRootPwd(),
                      'dsBaseDN'         : 'dc=replicationChanges',
                      'dsFilter'         : 'uid=iabizen.X',
                      'dsAttributes'     : 'dn',
                      'expectedRC'       : 0
                    }
                  </call>
                  <script>
                    searchRC = STAXResult[0][0]
                    searchResult = STAXResult[0][1]
                    resultLength = len(searchResult) > 0
                    if i == 0:
                      # index [0] corresponds to "master" server
                      # => purge delay expired => changelog purged
                      # => expect NO entry returned
                      # => len(searchResult) = 0 => resultLength = 0
                      myExpectedRC = 0
                    else:
                      # purge delay not expired (default purge delay: 1 day)
                      # => expect entry returned
                      # => len(searchResult) > 0 => resultLength = 1
                      myExpectedRC = 1
                  </script>
                  <!-- expect NO entry returned => len(searchResult) = 0
                    =====> resultLength = 0 -->
                  <call function="'checktestRC'">
                    { 'returncode' : resultLength ,
                      'result'     : searchResult ,
                      'expected'   : myExpectedRC
                    }
                  </call>
                </sequence>
              </paralleliterate>
              <!-- Verify the synchronization of the trees among the servers in
                the topology -->
              <call function="'verifyTrees'">
                [ clientHost, clientPath, master, consumerList, synchroSuffix ]
              </call>
              <call function="'testCase_Postamble'"/>
            </sequence>
          </testcase>
          <import machine="STAF_LOCAL_HOSTNAME"
                  file="'%s/testcases/replication/replication_cleanup.xml'
                        % (TESTS_DIR)"/>
          <call function="'replication_cleanup'" />
          <call function="'testSuite_Postamble'"/>
        </sequence>
      </block>
    </sequence>
  </function>
</stax>
opends/tests/functional-tests/testcases/replication/replication.xml
@@ -38,8 +38,9 @@
          </script>
          <call function="'testGroup_Preamble'"/>            
          <iterate  var="_test" 
                    in="['totalupdate','binarycopy','ldifimport','resynchronization',
                         'basic','schema','failover','encryption']">
                    in="['totalupdate','binarycopy','ldifimport',
                         'resynchronization','basic','schema','failover',
                         'encryption','changelog']">
            <sequence>
              <import machine="STAF_LOCAL_HOSTNAME"
                      file="'%s/testcases/replication/%s/%s.xml' % 
opends/tests/functional-tests/testcases/replication/replication_setup.xml
@@ -48,6 +48,18 @@
        </function-arg-description>
        <function-arg-property name="type" value="boolean"/>          
      </function-arg-def>
      <function-arg-def name="dataFile"
                        type="optional"
                        default="None">
        <function-arg-description>
          Name of the data file within shared/data/replication/ for suffix
          initialisation.
          If no filename provided (default), the topology won't be initialised.
          If a filename provided, after initialisation the suffix will be
          backuped under masterBackupDir.
        </function-arg-description>
        <function-arg-property name="type" value="filename"/>
      </function-arg-def>
    </function-map-args>    
    
    <sequence>
@@ -93,9 +105,42 @@
            masterReplicationServer = master.getChangelogServer()
            masterPath = '%s/%s' % (master.getDir(),OPENDSNAME)
            masterDataDir = '%s/%s' % (master.getDir(),relativeDataDir)
            synchroSuffix = master.getSynchronizedSuffixList()[0].getSuffixDn()
            masterBackupDir = '%s/replication/master_backup' % masterDataDir
            consumerList = _topologyServerList[1:]              
          </script>
          </script>
          <if expr="dataFile">
            <sequence>
              <script>
                importDataFile = '%s/replication/%s' % (masterDataDir, dataFile)
              </script>
              <message>
                'Import data from %s into server %s:%s' \
                % (importDataFile, masterHost, master.getPort())
              </message>
              <!-- Import data into "master" Directory Server -->
              <call function="'ImportLdifWithScript'">
                { 'location'     : masterHost,
                  'dsPath'       : masterPath,
                  'dsBackEnd'    : 'userRoot',
                  'dsLdifFile'   : importDataFile
                }
              </call>
              <!-- Backup "master" server -->
              <call function="'backup'">
                { 'location'  : masterHost,
                  'dsPath'    : masterPath,
                  'backupDir' : masterBackupDir
                }
              </call>
            </sequence>
          </if>
                          
          <!-- Start the servers in the topology -->        
          <call function="'startServers'">
@@ -131,29 +176,50 @@
                  </message>
                                        
                  <call function="'enableReplication'">
                    { 'location'  :  clientHost,
                      'dsPath'  :  clientPath,
                      'dsInstanceHost'  :  server.getHostname(),
                      'dsInstancePort'  :  server.getPort(),
                      'dsInstanceDn'  :  server.getRootDn(),
                      'dsInstancePswd'  :  server.getRootPwd(),
                      'dsReplicationPort'  :  replicationServer.getPort(),
                      'dsSecureReplication'  :  secureReplication,
                      'refInstanceHost'  :  masterHost,
                      'refInstancePort'  :  master.getPort(),
                      'refInstanceDn'  :  master.getRootDn(),
                      'refInstancePswd'  :  master.getRootPwd(),
                      'refReplicationPort'  :  masterReplicationServer.getPort(),
                      'refSecureReplication'  :  secureReplication,
                      'replicationDnList'  :  replicatedDnList,
                      'useSecondServerAsSchemaSource'  :  True }
                    { 'location'             : clientHost,
                      'dsPath'               : clientPath,
                      'dsInstanceHost'       : server.getHostname(),
                      'dsInstancePort'       : server.getPort(),
                      'dsInstanceDn'         : server.getRootDn(),
                      'dsInstancePswd'       : server.getRootPwd(),
                      'dsReplicationPort'    : replicationServer.getPort(),
                      'dsSecureReplication'  : secureReplication,
                      'refInstanceHost'      : masterHost,
                      'refInstancePort'      : master.getPort(),
                      'refInstanceDn'        : master.getRootDn(),
                      'refInstancePswd'      : master.getRootPwd(),
                      'refReplicationPort'  : masterReplicationServer.getPort(),
                      'refSecureReplication' : secureReplication,
                      'replicationDnList'    : replicatedDnList,
                      'useSecondServerAsSchemaSource'  :  True
                    }
                  </call>
                </sequence>
              </if>                
                
            </sequence>              
          </iterate>
          </iterate>
          <if expr="dataFile">
            <sequence>
              <message>
                'Initialise topology from %s:%s' \
                % (masterHost, master.getPort())
              </message>
              <!-- Initialise the servers in the topology -->
              <call function="'initializeReplication'">
                { 'location'           : clientHost,
                  'dsPath'             : clientPath,
                  'sourceInstanceHost' : masterHost,
                  'sourceInstancePort' : master.getPort(),
                  'replicationDnList'  : [synchroSuffix]
                }
              </call>
            </sequence>
          </if>
        </sequence>
      </block>
opends/tests/shared/functions/dsadm.xml
@@ -1202,7 +1202,7 @@
      <!-- Start the task using ldap task interface -->
      <call function="'StartLdapTask'">
        { 'location'   : myLocation,
          'dsPath'     :  myPath,
          'dsPath'     : myPath,
          'taskLabel'  : 'Online Import Task',
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
@@ -1210,7 +1210,11 @@
          'dsBindPswd' : dsInstancePswd,
          'dsTaskLdif' : taskLdif }
      </call>
      <script>
        STAFCmdRC=STAXResult[0]
      </script>
      <!-- Check that the ldap task is completed -->
      <if expr="STAFCmdRC == 0">
        <sequence>
@@ -1668,6 +1672,7 @@
      <!-- Local variables -->
      <script>
        myLocation=location
        myPath=dsPath
        taskLdifFile='export-task.ldif'
        taskLdif='%s/../%s/%s' % (dsPath,relativeDataDir,taskLdifFile)
        tmpTaskLdif='%s/%s' % (logsTempDir,taskLdifFile)
@@ -1733,7 +1738,7 @@
      <!-- Start the task using ldap task interface -->
      <call function="'StartLdapTask'">
        { 'location'   : myLocation,
          'dsPath'  :  myPath,
          'dsPath'     : myPath,
          'taskLabel'  : 'Online Export Task',
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
@@ -1741,13 +1746,17 @@
          'dsBindPswd' : dsInstancePswd,
          'dsTaskLdif' : taskLdif }
      </call>
      <script>
        STAFCmdRC=STAXResult[0]
      </script>
      <!-- Check that the task is completed -->
      <if expr="STAFCmdRC == 0">
        <sequence>
            <call function="'CheckLdapTask'">
            { 'location'   : myLocation,
              'dsPath'  :  myPath,
              'dsPath'     : myPath,
              'dsTaskDn'   : taskDN,
              'dsHost'     : dsInstanceHost,
              'dsPort'     : dsInstancePort,
@@ -2046,7 +2055,7 @@
      <!-- Start the task using ldap task interface -->
      <call function="'StartLdapTask'">
        { 'location'   : myLocation,
          'dsPath'  :  myPath,
          'dsPath'     : myPath,
          'taskLabel'  : 'Online Backup Task',
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
@@ -2054,13 +2063,17 @@
          'dsBindPswd' : dsInstancePswd,
          'dsTaskLdif' : taskLdif }
      </call>
      <script>
        STAFCmdRC=STAXResult[0]
      </script>
      <!-- Check that the ldap task is completed -->
      <if expr="STAFCmdRC == 0">
        <sequence>
            <call function="'CheckLdapTask'">
            { 'location'   : myLocation,
              'dsPath'  :  myPath,
              'dsPath'     : myPath,
              'dsTaskDn'   : taskDN,
              'dsHost'     : dsInstanceHost,
              'dsPort'     : dsInstancePort,
@@ -2306,7 +2319,7 @@
      <!-- Start the task using ldap task interface -->
      <call function="'StartLdapTask'">
        { 'location'   : myLocation,
          'dsPath'  :  myPath,
          'dsPath'     : myPath,
          'taskLabel'  : 'Online Restore Task',
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
@@ -2314,13 +2327,17 @@
          'dsBindPswd' : dsInstancePswd,
          'dsTaskLdif' : taskLdif }
      </call>
      <script>
        STAFCmdRC=STAXResult[0]
      </script>
      <!-- Check that the ldap task is completed -->
      <if expr="STAFCmdRC == 0">
        <sequence>
            <call function="'CheckLdapTask'">
            { 'location'   : myLocation,
              'dsPath'  :  myPath,
              'dsPath'     : myPath,
              'dsTaskDn'   : taskDN,
              'dsHost'     : dsInstanceHost,
              'dsPort'     : dsInstancePort,
@@ -2429,7 +2446,7 @@
      <!-- Start the task using ldap task interface -->
      <call function="'StartLdapTask'">
        { 'location'   : myLocation,
          'dsPath'  :  myPath,
          'dsPath'     : myPath,
          'taskLabel'  : 'Online Export Task',
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
@@ -2437,7 +2454,11 @@
          'dsBindPswd' : dsInstancePswd,
          'dsTaskLdif' : taskLdif }
      </call>
      <script>
        STAFCmdRC=STAXResult[0]
      </script>
      <return>STAFCmdRC</return>
      
    </sequence>
@@ -2539,7 +2560,7 @@
      <!-- Start the task using ldap task interface -->
      <call function="'StartLdapTask'">
        { 'location'   : myLocation,
          'dsPath'  :  myPath,
          'dsPath'     : myPath,
          'taskLabel'  : 'Online Export Task',
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
@@ -2548,6 +2569,10 @@
          'dsTaskLdif' : taskLdif }
      </call>
      
      <script>
        STAFCmdRC=STAXResult[0]
      </script>
      <!--- Check that DS started -->
      <if expr="STAFCmdRC == 0">
        <sequence>
@@ -2676,7 +2701,7 @@
      <!-- Start the task using ldap task interface -->
      <call function="'StartLdapTask'">
        { 'location'   : myLocation,
          'dsPath'  :  myPath,
          'dsPath'     : myPath,
          'taskLabel'  : 'Online Schema Task',
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
@@ -2688,7 +2713,7 @@
      <!-- Check that the ldap task is completed -->
      <call function="'CheckLdapTask'">
        { 'location'   : myLocation,
          'dsPath'  :  myPath,
          'dsPath'     : myPath,
          'dsTaskDn'   : taskDN,
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
@@ -2804,7 +2829,7 @@
      <!-- Start the task using ldap task interface -->
      <call function="'StartLdapTask'">
        { 'location'   : myLocation,
          'dsPath'  :  myPath,
          'dsPath'     : myPath,
          'taskLabel'  : 'Online Schema Task',
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
@@ -2816,7 +2841,7 @@
      <!-- Check that the ldap task is completed -->
      <call function="'CheckLdapTask'">
        { 'location'   : myLocation,
          'dsPath'  :  myPath,
          'dsPath'     : myPath,
          'dsTaskDn'   : taskDN,
          'dsHost'     : dsInstanceHost,
          'dsPort'     : dsInstancePort,
opends/tests/shared/functions/topology.xml
@@ -85,45 +85,45 @@
            </sequence>
          </if>
        </sequence>
        <else>
          <!-- MULTIPLE instance deployment: read parameters from
            topologyDescFile -->
          <sequence>
            <message>
              'MULTIPLE instance deployment: read parameters from %s' \
              % topologyDescFile
            </message>
            <!-- Parse the topology description file and set
              _topologyServerList -->
            <call function="'readTopology'">
              { 'file' : topologyDescFile }
            </call>
            <message>
              'Number of server instances required by the deployment: %s' \
              % len(_topologyServerList)
            </message>
            <iterate var="server" in="_topologyServerList">
              <sequence>
                <!-- Create the instance-->
                <call function="'createInstance'">
                  { 'dsHost'    : server.getHostname(),
                    'dsDir'     : server.getDir(),
                    'dsPort'    : server.getPort(),
                    'dsSslPort' : server.getSslPort(),
                    'dsJmxPort' : server.getJmxPort(),
                    'dsBindDN'  : server.getRootDn(),
                    'dsBindPwd' : server.getRootPwd(),
                    'dsBaseDN'  : server.getBaseDn()
                  }
                </call>
              </sequence>
            </iterate>
          </sequence>
        </else>
      <else>
        <!-- MULTIPLE instance deployment: read parameters from
          topologyDescFile -->
        <sequence>
          <message>
            'MULTIPLE instance deployment: read parameters from %s' \
            % topologyDescFile
          </message>
          <!-- Parse the topology description file and set
            _topologyServerList -->
          <call function="'readTopology'">
            { 'file' : topologyDescFile }
          </call>
          <message>
            'Number of server instances required by the deployment: %s' \
            % len(_topologyServerList)
          </message>
          <iterate var="server" in="_topologyServerList">
            <sequence>
              <!-- Create the instance-->
              <call function="'createInstance'">
                { 'dsHost'    : server.getHostname(),
                  'dsDir'     : server.getDir(),
                  'dsPort'    : server.getPort(),
                  'dsSslPort' : server.getSslPort(),
                  'dsJmxPort' : server.getJmxPort(),
                  'dsBindDN'  : server.getRootDn(),
                  'dsBindPwd' : server.getRootPwd(),
                  'dsBaseDN'  : server.getBaseDn()
                }
              </call>
            </sequence>
          </iterate>
        </sequence>
      </else>
      </if>
    </sequence>
  </function>
@@ -1917,7 +1917,7 @@
          'dsPath'            : dsPath,
          'dsInstanceHost'    : sourceInstanceHost,
          'dsInstancePort'    : sourceInstancePort,
          'localOnly'         : True,
          'localOnly'         : False,
          'replicationDnList' : [suffixDn],
          'adminUID'          : adminUID,
          'adminPswd'         : adminPswd
opends/tests/shared/functions/utils.xml
@@ -1533,8 +1533,8 @@
                        default="STAF_REMOTE_HOSTNAME">
        <function-arg-description>
          Location of target host
      </function-arg-description>
      <function-arg-property name="type" value="hostname"/>
        </function-arg-description>
        <function-arg-property name="type" value="hostname"/>
      </function-arg-def>
      <function-arg-def name="dsPath" 
                        type="optional" 
@@ -1649,5 +1649,83 @@
      </return>
    </sequence>
  </function>
  <function name="grep">
    <function-prolog>
      This function search for a given string in a given file.
      BEWARE! of potential performance degradation when grepping big files due
      to the use of getFile, which loads the whole file content into a variable.
    </function-prolog>
    <function-map-args>
      <function-arg-def name="location"
                        type="optional"
                        default="STAF_REMOTE_HOSTNAME">
        <function-arg-description>
          Location of target host
        </function-arg-description>
        <function-arg-property name="type" value="hostname"/>
      </function-arg-def>
      <function-arg-def name="filename" type="required">
        <function-arg-description>
          File path
        </function-arg-description>
        <function-arg-property name="type" value="pathname"/>
      </function-arg-def>
      <function-arg-def name="testString" type="required">
        <function-arg-description>
          String searched
        </function-arg-description>
        <function-arg-property name="type" value="string"/>
      </function-arg-def>
      <function-arg-def name="expectedRC" type="optional" default="0">
        <function-arg-description>
          Expected return code value.
          0 for successful grep, 1 for unsuccessful grep. Default value is 0.
          Wildcard 'noCheck' to not check the RC
        </function-arg-description>
      </function-arg-def>
    </function-map-args>
    <sequence>
      <message>
        'Search for string \"%s\" in file %s on host %s' % \
        (testString, filename, location)
      </message>
      <call function="'getFile'">
        {
          'location' : location,
          'filename' : filename
        }
      </call>
      <script>
        # getFile returns: STAXResult = [cmdRC, cmdResult]
        filecontent = STAXResult[1]
        if (expectedRC == 'noCheck'):
          # don't care about expected result
          myExpectedResult = '2'
        elif (expectedRC == 0):
          # expect testString to be present in filecontent
          myExpectedResult = '1'
        else:
          # expect testString not to be present in filecontent
          myExpectedResult = '0'
      </script>
      <call function="'searchStringForSubstring'">
        {
          'testString'     : testString,
          'returnString'   : filecontent,
          'expectedResult' : myExpectedResult
        }
      </call>
      <return>STAXResult</return>
    </sequence>
  </function>
</stax>