From b641be47ccf7eb5261be4f44abbf016dfa0e9ddd Mon Sep 17 00:00:00 2001
From: ugaston <ugaston@localhost>
Date: Fri, 22 Feb 2008 17:56:27 +0000
Subject: [PATCH] New Replication Changelog testsuite

---
 opends/tests/functional-tests/testcases/replication/replication.xml         |    5 
 opends/tests/functional-tests/testcases/replication/changelog/changelog.xml | 1350 ++++++++++++++++++++++++++++++++++++++++++++++
 opends/tests/functional-tests/testcases/replication/replication_setup.xml   |  106 ++
 opends/tests/shared/functions/dsadm.xml                                     |   61 +
 opends/tests/shared/functions/topology.xml                                  |   80 +-
 opends/tests/shared/functions/utils.xml                                     |   84 ++
 6 files changed, 1,603 insertions(+), 83 deletions(-)

diff --git a/opends/tests/functional-tests/testcases/replication/changelog/changelog.xml b/opends/tests/functional-tests/testcases/replication/changelog/changelog.xml
new file mode 100644
index 0000000..41cf2ec
--- /dev/null
+++ b/opends/tests/functional-tests/testcases/replication/changelog/changelog.xml
@@ -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>
diff --git a/opends/tests/functional-tests/testcases/replication/replication.xml b/opends/tests/functional-tests/testcases/replication/replication.xml
index 5a375f5..bb8840d 100644
--- a/opends/tests/functional-tests/testcases/replication/replication.xml
+++ b/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' % 
diff --git a/opends/tests/functional-tests/testcases/replication/replication_setup.xml b/opends/tests/functional-tests/testcases/replication/replication_setup.xml
index 95ca89c..5b8051c 100644
--- a/opends/tests/functional-tests/testcases/replication/replication_setup.xml
+++ b/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>
diff --git a/opends/tests/shared/functions/dsadm.xml b/opends/tests/shared/functions/dsadm.xml
index 3d2e606..5f9de1c 100755
--- a/opends/tests/shared/functions/dsadm.xml
+++ b/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,
diff --git a/opends/tests/shared/functions/topology.xml b/opends/tests/shared/functions/topology.xml
index cf95f0b..99ca602 100755
--- a/opends/tests/shared/functions/topology.xml
+++ b/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
diff --git a/opends/tests/shared/functions/utils.xml b/opends/tests/shared/functions/utils.xml
index 060eefe..ac77407 100755
--- a/opends/tests/shared/functions/utils.xml
+++ b/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>

--
Gitblit v1.10.0