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