<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "/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 legal-notices/CDDLv1_0.txt
! or http://forgerock.org/license/CDDLv1.0.html.
! 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 legal-notices/CDDLv1_0.txt.
! 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 2007-2010 Sun Microsystems, Inc.
! Portions Copyright 2011-2013 ForgeRock AS.
! -->
<stax>
<function name="checkRC">
<function-prolog>
This function checks a return code against an expected return code
</function-prolog>
<function-map-args>
<function-arg-def name="returncode" type="required">
<function-arg-description>
return code received from command
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="result" type="required">
<function-arg-description>
the output of the result
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="expected" type="optional" default="0">
<function-arg-description>
the expected return code
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
</function-map-args>
<sequence>
<if expr="expected == 'noCheck'">
<return/>
</if>
<if expr="returncode == expected">
<sequence>
<if expr="result == ''">
<message log="1">
'RC=%s, Result=Ok' % (returncode)
</message>
<else>
<message log="1">
'RC=%s, Result=%s' % (returncode,result)
</message>
</else>
</if>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'RC=%s, Expected %s, Result=%s' % (returncode,expected,result)
</message>
</sequence>
</else>
</if>
<return>RC</return>
</sequence>
</function>
<function name="checktestRC">
<function-prolog>
This function checks the return code against an expected return code for a testcase
</function-prolog>
<function-map-args>
<function-arg-def name="returncode" type="required">
<function-arg-description>
return code received from command
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="result" type="required">
<function-arg-description>
the output of the result
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="expected" type="optional" default="0">
<function-arg-description>
the expected return code
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="issue" type="optional" default="None">
<function-arg-description>
Issue id. Corresponds to an issue number.
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<if expr="expected == 'noCheck'">
<return/>
</if>
<if expr="returncode == expected">
<sequence>
<if expr="STAXCurrentTestcase != None">
<sequence>
<tcstatus result="'pass'"/>
</sequence>
</if>
<if expr="VERBOSE_MODE == 'true'">
<message log="1">
'SUCCESS: RC=%s, Expected %s, Result=%s' % (returncode,expected,result)
</message>
<else>
<message log="1">
'SUCCESS: RC=%s, Expected %s' % (returncode,expected)
</message>
</else>
</if>
<script>
RC=0
</script>
</sequence>
<else>
<sequence>
<if expr="STAXCurrentTestcase != None">
<sequence>
<if expr="issue == None">
<tcstatus result="'fail'"/>
<else>
<sequence>
<call function="'setKnownIssue'">
{ 'issueId' : issue }
</call>
</sequence>
</else>
</if>
</sequence>
</if>
<message log="1" level="'Error'">
'ERROR : RC=%s, Expected %s, Result=%s' % (returncode,expected,result)
</message>
</sequence>
</else>
</if>
</sequence>
</function>
<!-- Set Known Issue -->
<function name="setKnownIssue">
<function-prolog>
This function set the known issue flag and maintains list of known issues
</function-prolog>
<function-map-args>
<function-arg-def name="issueId" type="required">
<function-arg-description>
Issue ID
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<call function="'GetVar'">
{
'location' : STAF_REMOTE_HOSTNAME,
'type' : 'shared',
'variable' : 'issuesList'
}
</call>
<script>
issuesList=eval(STAFResult)
</script>
<script>
try:
from org.python.core import PyList
if issueId.__class__ is PyList:
for issue in issueId:
if issue not in issuesList:
issuesList.append(issue)
else:
if issueId not in issuesList:
issuesList.append(issueId)
except Exception,e:
print 'Issues list undefined. Unable to add issue %s. Reason=%s' % (issueId,e)
</script>
<message log="1" level="'Error'">
'ERROR: HIT **** Known Issue (%s) ****' % issueId
</message>
<tcstatus result="'fail'">
'KnownIssue: %s' % issuesList
</tcstatus>
<call function="'SetVar'">
{
'location' : STAF_REMOTE_HOSTNAME,
'type' : 'shared',
'variable' : 'issuesList=%s' % issuesList
}
</call>
</sequence>
</function>
<!-- testPassed -->
<!-- Set the test status to PASS -->
<function name="testPassed">
<function-prolog>
This function set the status of the tests: PASS
</function-prolog>
<sequence>
<message>'Set test status to PASS'</message>
<tcstatus result="'pass'"/>
</sequence>
</function>
<!-- testFailed -->
<!-- Set the test status to FAIL -->
<function name="testFailed">
<function-prolog>
This function set the status of the tests: FAIL
</function-prolog>
<sequence>
<message>'Set test status to FAIL'</message>
<tcstatus result="'fail'"/>
</sequence>
</function>
<!-- Search string -->
<function name="searchString" scope="local">
<function-prolog>
This function search for a string in the return string of a testcase
Return 0 if the string is found, 1 otherwise
</function-prolog>
<function-map-args>
<function-arg-def name="expectedString" type="required">
<function-arg-description>
the substring expected from the command
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="returnString" type="required">
<function-arg-description>
the return string received from command
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="searchType"
type="optional"
default="'substring'">
<function-arg-description>
the type of the search: substring, exact-case-insensitive or
exact-case-sensitive
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="knownIssue" type="optional" default="None">
<function-arg-description>
Known issue. Corresponds to an issue number.
</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. Default value is 0.
Wildcard 'noCheck' to not check the RC
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<sequence>
<script>
searchre = re.compile('%s' % expectedString)
myRC = 0
myReason = 'None'
</script>
<!-- Check that returnString is really a string or unicode -->
<if expr='value_not_string(returnString)'>
<sequence>
<message log="1" level="'Error'">
'Invalid returnString type (%s), requires str or unicode.' \
% returnString.__class__
</message>
<message>
'The returnString is ("%s")' % returnString
</message>
<script>
myRC = 1
myReason = 'Python error'
</script>
<tcstatus result="'fail'"/>
<return>[myRC, myReason]</return>
</sequence>
</if>
<script>
if searchType == 'substring':
searchResult = (re.search(searchre, returnString) != None)
elif searchType == 'exact-case-sensitive':
searchResult = (expectedString == returnString)
elif searchType == 'exact-case-insensitive':
searchResult = (expectedString.lower() == returnString.lower())
</script>
<!-- Search for the expectedString -->
<if expr='searchResult'>
<sequence>
<message log="1">
'Search type: %s Found substring, %s, in the return string' \
% (searchType, expectedString)
</message>
<script>
myRC = 0
myReason = 'String found'
</script>
</sequence>
<else>
<sequence>
<if expr="expectedRC == 1">
<sequence>
<!-- The string is not found as expected so don't display the output -->
<message log="1">
'Search type: %s Did not find substring, %s, in the return \
string' % (searchType, expectedString)
</message>
</sequence>
<else>
<sequence>
<message log="1">
'Search type: %s Did not find substring, %s, in the return \
string, %s' % (searchType, expectedString, returnString)
</message>
</sequence>
</else>
</if>
<script>
myRC = 1
myReason = 'String not found'
</script>
</sequence>
</else>
</if>
<!-- Manage expectedRC and knownIssue -->
<if expr="expectedRC != 'noCheck'">
<if expr="myRC == expectedRC">
<sequence>
<message log="1">
'SUCCESS: searchString successful'
</message>
<tcstatus result="'pass'"/>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'ERROR: searchString fail'
</message>
<if expr="knownIssue == None">
<tcstatus result="'fail'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : knownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</if>
<return>[myRC, myReason]</return>
</sequence>
</function>
<!-- DEPRECATED, use searchString function -->
<function name="checktestString">
<function-prolog>
This function checks the return string against an expected return substring for a testcase
</function-prolog>
<function-map-args>
<function-arg-def name="expectedString" type="required">
<function-arg-description>
the substring expected from the command
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="returnString" type="required">
<function-arg-description>
the return string received from command
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="issue" type="optional" default="None">
<function-arg-description>
Known issue. Corresponds to an issue number.
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
searchre = re.compile('%s' % expectedString)
</script>
<!-- Check that returnString is really a string -->
<if expr='value_not_string(returnString)'>
<sequence>
<message log="1" level="'Error'">
'ERROR : Invalid returnString type (%s), requires str or unicode.' \
% returnString.__class__
</message>
<tcstatus result="'fail'"/>
</sequence>
</if>
<if expr='re.search(searchre, returnString) != None'>
<sequence>
<tcstatus result="'pass'"/>
<message log="1">
'SUCCESS : Found substring, %s, in the return string' % (expectedString)
</message>
</sequence>
<else>
<sequence>
<if expr="issue == None">
<tcstatus result="'fail'"/>
<else>
<sequence>
<call function="'setKnownIssue'">
{ 'issueId' : issue }
</call>
</sequence>
</else>
</if>
<message log="1" level="'Error'">
'ERROR : Did not find substring, %s, in the return string, %s' % (expectedString, returnString)
</message>
</sequence>
</else>
</if>
</sequence>
</function>
<!-- DEPRECATED, use searchString function -->
<function name="checktestStringNotPresent">
<function-prolog>
This function checks the return string against an expected return substring that should not be present for a testcase
</function-prolog>
<function-map-args>
<function-arg-def name="testString" type="required">
<function-arg-description>
the substring being tested from the command
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="returnString" type="required">
<function-arg-description>
the return string received from command
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="issue" type="optional" default="None">
<function-arg-description>
Known issue. Corresponds to an issue number.
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
searchre = re.compile('%s' % testString)
</script>
<if expr='re.search(searchre, returnString) == None'>
<sequence>
<tcstatus result="'pass'"/>
<message log="1">
'Did Not Find substring, %s, in the return string' % (testString)
</message>
</sequence>
<else>
<sequence>
<if expr="issue == None">
<tcstatus result="'fail'"/>
<else>
<sequence>
<call function="'setKnownIssue'">
{ 'issueId' : issue }
</call>
</sequence>
</else>
</if>
<message log="1" level="'Error'">
'Found substring, %s, in the return string, %s' % (testString, returnString)
</message>
</sequence>
</else>
</if>
</sequence>
</function>
<!-- DEPRECATED, use searchString function -->
<function name="searchStringForSubstring">
<function-prolog>
This function simply searches a string for a substring
</function-prolog>
<function-map-args>
<function-arg-def name="testString" type="required">
<function-arg-description>
the substring being tested from the command
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="returnString" type="required">
<function-arg-description>
the return string received from command
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="expectedResult" type="optional" default="'2'">
<function-arg-description>
the expected result, 0 for false (not present), 1 for true (present), 2 for old behavior
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<!-- Until all the test cases are refactored to use the expectedResult param,
we need this if-else conditional. -->
<sequence>
<if expr="expectedResult == '2'">
<sequence>
<script>
searchre = re.compile(testString)
</script>
<if expr='re.search(searchre, returnString) == None'>
<sequence>
<script>returnCode='0'</script>
<message log="1">
'Did Not Find substring, %s, in the return string' % (testString)
</message>
</sequence>
<else>
<sequence>
<script>returnCode='1'</script>
<message log="1">
'Found substring, %s, in the return string' % (testString)
</message>
</sequence>
</else>
</if>
<return>returnCode</return>
</sequence>
<else>
<sequence>
<script>
searchre = re.compile(testString)
</script>
<if expr='re.search(searchre, returnString) == None'>
<sequence>
<script>returnCode='0'</script>
<if expr="expectedResult == '0'">
<sequence>
<tcstatus result="'pass'"/>
<message log="1">
'SUCCESS : Did Not Find substring, %s, in the return string' % (testString)
</message>
</sequence>
<else>
<sequence>
<tcstatus result="'fail'"/>
<message log="1" level="'Error'">
'ERROR : Did Not Find substring, %s, in the return string' % (testString)
</message>
</sequence>
</else>
</if>
</sequence>
<else>
<sequence>
<script>returnCode='1'</script>
<if expr="expectedResult == '1'">
<sequence>
<tcstatus result="'pass'"/>
<message log="1">
'SUCCESS : Found substring, %s, in the return string' % (testString)
</message>
</sequence>
<else>
<sequence>
<tcstatus result="'fail'"/>
<message log="1" level="'Error'">
'ERROR : Found substring, %s, in the return string' % (testString)
</message>
</sequence>
</else>
</if>
</sequence>
</else>
</if>
<return>returnCode</return>
</sequence>
</else>
</if>
</sequence>
</function>
<function name="isAlive" scope="local">
<function-prolog>
Checks that the ldap server is running
</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="dsPath" type="optional" default="'%s/%s' % (DIRECTORY_INSTANCE_BIN,OPENDSNAME)">
<function-arg-description>
Pathname to installation root
</function-arg-description>
<function-arg-property name="type" value="pathname"/>
</function-arg-def>
<function-arg-def name="noOfLoops" type="required">
<function-arg-description>
Number of iterations
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="noOfMilliSeconds" type="required">
<function-arg-description>
Number of seconds to wait between iterations
</function-arg-description>
<function-arg-property name="type" value="seconds"/>
</function-arg-def>
<function-arg-def name="dsInstanceHost" type="optional" default="DIRECTORY_INSTANCE_HOST">
<function-arg-description>
Directory server hostname or IP address
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
<function-arg-def name="dsInstancePort" type="optional" default="DIRECTORY_INSTANCE_PORT">
<function-arg-description>
Directory server port number
</function-arg-description>
<function-arg-property name="type" value="Port number"/>
</function-arg-def>
<function-arg-def name="dsInstanceDn" type="optional" default="DIRECTORY_INSTANCE_DN">
<function-arg-description>
Bind DN
</function-arg-description>
<function-arg-property name="type" value="DN"/>
</function-arg-def>
<function-arg-def name="dsInstancePswd" type="optional" default="DIRECTORY_INSTANCE_PSWD">
<function-arg-description>
Bind password
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<sequence>
<!-- Local variables -->
<script>
mylocation=location
mypath=dsPath
myhost=dsInstanceHost
myport=dsInstancePort
mydn=dsInstanceDn
mypswd=dsInstancePswd
</script>
<script>
myLoop=0
ldapRC=9999
</script>
<loop from="1" to="noOfLoops" while="ldapRC != 0">
<sequence>
<script>
myLoop=myLoop+1
</script>
<call function="'SearchObject'">
{ 'location' : mylocation,
'dsPath' : mypath,
'dsInstanceHost' : myhost ,
'dsInstancePort' : myport ,
'dsInstanceDn' : mydn ,
'dsInstancePswd' : mypswd ,
'dsScope' : 'base' ,
'dsBaseDN' : 'cn=config' ,
'dsFilter' : 'objectclass=*' ,
'attributes' : 'dn',
'expectedRC' : 'noCheck'
}
</call>
<script>
ldapRC=RC
</script>
<message>
'LOOP %s => RC=%s' % (myLoop, ldapRC)
</message>
<call function="'Sleep'">
{ 'sleepForMilliSeconds' : noOfMilliSeconds }
</call>
</sequence>
</loop>
<call function="'checktestRC'">
{ 'returncode' : ldapRC ,
'result' : 'Check is alive' }
</call>
</sequence>
</function>
<function name="isStopped" scope="local">
<function-prolog>
Checks that the ldap server is stopped
</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="dsPath"
type="optional"
default="'%s/%s' % (DIRECTORY_INSTANCE_DIR,OPENDSNAME)">
<function-arg-description>
Pathname to installation root
</function-arg-description>
<function-arg-property name="type" value="pathname"/>
</function-arg-def>
<function-arg-def name="noOfLoops"
type="optional"
default="10">
<function-arg-description>
Number of iterations
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="noOfMilliSeconds"
type="optional"
default="2000">
<function-arg-description>
Number of seconds to wait between iterations
</function-arg-description>
<function-arg-property name="type" value="seconds"/>
</function-arg-def>
</function-map-args>
<sequence>
<script>checkRC=9999</script>
<loop from="1" to="100" var="loop" while="checkRC != 48">
<sequence>
<message>
'Check if %s/logs/server.pid still exists on host %s' \
% (dsPath,location)
</message>
<call function="'GetEntry'">
{ 'location' : location,
'entry' : '%s/logs/server.pid' % dsPath,
'attribute' : 'TYPE'
}
</call>
<script>
checkRC = RC
</script>
<message>'LOOP %s => RC %s' % (loop,checkRC)</message>
<message>'Sleep for %sms' % noOfMilliSeconds</message>
<call function="'Sleep'">
{ 'sleepForMilliSeconds' : noOfMilliSeconds }
</call>
</sequence>
</loop>
<if expr="checkRC != 48">
<sequence>
<message log="1" level="'Error'">
'Server is not stopped after %sms \
(%s/logs/server.pid still exists on %s)' \
% (noOfLoops*noOfMilliSeconds,dsPath,location)
</message>
<tcstatus result="'fail'"/>
<!-- Kill the server to avoid impact on the other testcases -->
<call function="'killDs'">
{ 'location' : location,
'dsPath' : dsPath
}
</call>
</sequence>
</if>
</sequence>
</function>
<function name="Sleep">
<function-prolog>
Sleep for number of milliseconds
</function-prolog>
<function-map-args>
<function-arg-def name="sleepForMilliSeconds" type="required">
<function-arg-description>
Number of milliseconds to sleep
</function-arg-description>
<function-arg-property name="type" value="seconds"/>
</function-arg-def>
</function-map-args>
<sequence>
<stafcmd name="'STAF Command: Delay'">
<location>STAXServiceMachine</location>
<service>'delay'</service>
<request>
'delay %i' % int(sleepForMilliSeconds)
</request>
</stafcmd>
<call function="'checkRC'">
{ 'returncode' : RC ,
'result' : STAFResult }
</call>
</sequence>
</function>
<function name="getOSvariables">
<function-prolog>
Get OS related variables
</function-prolog>
<function-map-args>
<function-arg-def name="hostname" type="required">
<function-arg-description>
Name of host on which to retrieve variables
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
</function-map-args>
<sequence>
<stafcmd name="'STAF Command: Get OS Name'">
<location>'%s' % hostname</location>
<service>'var'</service>
<request>
'get system var STAF/Config/OS/Name'
</request>
</stafcmd>
<message>
'OS Name= %s' % STAFResult
</message>
<return>STAFResult</return>
</sequence>
</function>
<function name="testCase_StartBanner" scope="local">
<function-prolog>
Pretty prints a banner at the start of a test.
</function-prolog>
<function-no-args />
<sequence>
<message level="'start'">'testcase: %s' % STAXCurrentTestcase</message>
<message>'****************************************************'</message>
<message>'*** STARTING TEST CASE %s.' % STAXCurrentTestcase</message>
<message>'***'</message>
</sequence>
</function>
<function name="testCase_EndBanner" scope="local">
<function-prolog>
Pretty prints a banner at the end of a test.
</function-prolog>
<function-no-args />
<sequence>
<message>'***'</message>
<message>'*** ENDING TEST CASE %s.' % STAXCurrentTestcase</message>
<message>'****************************************************'</message>
<message level="'stop'">'testcase: %s' % STAXCurrentTestcase</message>
</sequence>
</function>
<function name="testCase_Preamble">
<function-prolog>
Performs all the preoperations for a test case
</function-prolog>
<function-no-args />
<sequence>
<script>
import time
testcaseStart=int(time.time())
testcaseStartTime=strftime("%Y%m%d-%H:%M:%S",localtime())
stepNumber=1
</script>
<call function="'SetVar'">
{
'location' : STAF_REMOTE_HOSTNAME,
'type' : 'shared',
'variable' : 'issuesList=[]'
}
</call>
<call function="'testCase_StartBanner'" />
</sequence>
</function>
<function name="testCase_Postamble" scope="local">
<function-prolog>
Performs all the post operations for a test suite
</function-prolog>
<function-no-args />
<sequence>
<!-- Check the SignalRaised flag -->
<if expr="SignalRaised">
<sequence>
<message>
'A signal (%s) was raised during this test case' % SignalRaised
</message>
<tcstatus result="'fail'"/>
</sequence>
</if>
<!-- Reset the SignalRaised flag -->
<script>
SignalRaised=''
</script>
<call function="'GetVar'">
{
'location' : STAF_REMOTE_HOSTNAME,
'type' : 'shared',
'variable' : 'issuesList'
}
</call>
<script>
issuesList=eval(STAFResult)
</script>
<!-- Query the test case results -->
<call function="'queryTestcase'" />
<script>
if STAFResult.has_key('numPasses'):
numPass=int(STAFResult['numPasses'])
else:
numPass=int(0)
if STAFResult.has_key('numFails'):
numFail=int(STAFResult['numFails'])
else:
numFail=int(0)
if STAFResult.has_key('startedTimestamp'):
startTimestamp=STAFResult['startedTimestamp']
else:
startTimestamp=int(0)
if STAFResult.has_key('information'):
information=STAFResult['information']
else:
information=''
xml=xmldoc_service()
repdoc = xml.parseXMLfile("%s/results_tmp.xml" % logs.reports)
qa = repdoc.getDocumentElement()
ft = qa.getChildNodes().item(1)
results = ft.getChildNodes().item(3)
xml.tempres = results.getChildNodes().item(1)
fail = xml.tempres.getChildNodes().item(1)
known = xml.tempres.getChildNodes().item(3)
done = xml.tempres.getChildNodes().item(5)
bugs = xml.tempres.getChildNodes().item(7)
nvDone = 0
nbFail = 0
nbKnown = 0
allbugs = eval(bugs.getTextContent())
if numFail == 0:
if numPass == 0:
_status='INCONCLUSIVE'
_result='unknown'
nbFail = int(fail.getTextContent()) + 1
fail.setTextContent('%s' % nbFail)
nbDone = int(done.getTextContent()) + 1
done.setTextContent('%s' % nbDone)
else:
_status='PASS'
_result='pass'
nbDone = int(done.getTextContent()) + 1
done.setTextContent('%s' % nbDone)
else:
if len(issuesList)==0:
_status='FAIL'
_result='fail'
nbFail = int(fail.getTextContent()) + 1
fail.setTextContent('%s' % nbFail)
nbDone = int(done.getTextContent()) + 1
done.setTextContent('%s' % nbDone)
else:
_status='KNOWN ISSUES %s' % str(issuesList)
_result='fail'
nbKnown = int(known.getTextContent()) + 1
known.setTextContent('%s' % nbKnown)
nbDone = int(done.getTextContent()) + 1
done.setTextContent('%s' % nbDone)
for issueID in issuesList:
if issueID not in allbugs:
allbugs.append(issueID)
bugs.setTextContent('%s' % allbugs)
</script>
<message level="'status'">
'## Test Verdict: %s ##' % _status
</message>
<call function="'testCase_EndBanner'" />
<script>
ThisGroupName=CurrentTestPath['group']
ThisSuiteName=CurrentTestPath['suite']
testcaseEndTime = strftime("%Y%m%d-%H:%M:%S",localtime())
testcaseStop=int(time.time())
testcaseDuration=testcaseStop-testcaseStart
shortName=get_test_name(STAXCurrentTestcase)
testsuite = xml.getElementByAttributeName(qa,'testsuite',ThisSuiteName,'name')
xml.testcase = repdoc.createElement("testcase")
xml.createAttr(repdoc,xml.testcase,"name",STAXCurrentTestcase)
xml.createAttr(repdoc,xml.testcase,"duration",testcaseDuration)
xml.createAttr(repdoc,xml.testcase,"group",ThisGroupName)
xml.createAttr(repdoc,xml.testcase,"result",_result)
xml.createAttr(repdoc,xml.testcase,"shortname",shortName.lower())
xml.createAttr(repdoc,xml.testcase,"start",startTimestamp)
xml.createAttr(repdoc,xml.testcase,"stop",testcaseEndTime)
xml.createAttr(repdoc,xml.testcase,"suite",ThisSuiteName)
xml.createAttr(repdoc,xml.testcase,"info",information)
testsuite.appendChild(xml.testcase)
if len(issuesList)!=0:
xml.issues = repdoc.createElement("issues")
xml.testcase.appendChild(xml.issues)
for issueID in issuesList:
xml.issue = repdoc.createElement("issue")
xml.createAttr(repdoc,xml.issue,"id",issueID)
xml.issues.appendChild(xml.issue)
xml.writeXMLfile(repdoc,"%s/results_tmp.xml" % logs.reports)
</script>
<call function="'queryLogs'">
{ 'location' : STAXServiceMachine,
'logname' : 'STAX_Job_%s_User' % STAXJobID,
'startfrom' : testcaseStartTime,
'endat' : testcaseEndTime }
</call>
<script>
# Update the report.cfg file
nbDone = int(done.getTextContent())
nbFail = int(fail.getTextContent())
nbKnown = int(known.getTextContent())
percentage = (nbDone - nbFail - nbKnown) * 100 / nbDone
starttime = time.strftime("%Y/%m/%d %H:%M:%S", time.gmtime(TESTS_TIMESTAMP))
duration = time.strftime("%H:%M:%S", time.gmtime(time.time() - TESTS_TIMESTAMP))
reportCfg = open('%s/logs/report.cfg' % LOGS_ROOT, 'w')
reportCfg.write('[Main]\n')
reportCfg.write('product = Directory\n')
if TESTS_TYPE == 'functional-tests':
reportCfg.write('category = Functional\n')
else:
reportCfg.write('category = Stress\n')
reportCfg.write('dsconfignumber = -1\n')
reportCfg.write('hostname = %s\n' % STAF_REMOTE_HOSTNAME)
reportCfg.write('testcasesfail = %s\n' % nbFail)
reportCfg.write('testcasesdone = %s\n' % nbDone)
reportCfg.write('testcasestotal = 2851\n')
reportCfg.write('starttime = %s\n' % starttime)
reportCfg.write('duration = %s\n' % duration)
reportCfg.write('dsconfigduration = 0\n')
reportCfg.write('percentage = %s\n' % percentage)
reportCfg.write('allbugs = %s\n' % allbugs)
reportCfg.write('os = %s\n' % TEST_OS_STRING)
reportCfg.write('report = reports/results_tmp.xml\n')
reportCfg.write('istemporary = True\n')
reportCfg.close()
</script>
</sequence>
</function>
<function name="testSuite_Preamble" scope="local">
<function-prolog>
Performs all the pre operations for a test suite
</function-prolog>
<function-no-args />
<sequence>
<!-- Take the values from the current test path -->
<script>
if not CurrentTestPath.has_key('group'):
CurrentTestPath['group']='unknown-group'
if not CurrentTestPath.has_key('suite'):
CurrentTestPath['suite']='unknown-suite'
ThisGroupName=CurrentTestPath['group']
ThisSuiteName=CurrentTestPath['suite']
xml=xmldoc_service()
repdoc = xml.parseXMLfile("%s/results_tmp.xml" % logs.reports)
qa = repdoc.getDocumentElement()
testgroup = xml.getElementByAttributeName(qa,'testgroup',ThisGroupName,'name')
#Create testsuite element
xml.testsuite = repdoc.createElement("testsuite")
xml.createAttr(repdoc,xml.testsuite,"name",ThisSuiteName)
xml.createAttr(repdoc,xml.testsuite,"shortname",ThisSuiteName)
testgroup.appendChild(xml.testsuite)
xml.writeXMLfile(repdoc,"%s/results_tmp.xml" % logs.reports)
</script>
<!-- Start time of test suite -->
<script>
TestSuiteStartTime.set(strftime("%Y%m%d-%H:%M:%S",localtime()))
</script>
<message>
'#### %s/%s suite preamble ####' % (ThisGroupName,ThisSuiteName)
</message>
</sequence>
</function>
<function name="testSuite_Postamble" scope="local">
<function-prolog>
Performs all the post operations for a test suite
</function-prolog>
<function-no-args />
<sequence>
<!-- Take the values from the current test path -->
<script>
if CurrentTestPath.has_key('suite'):
ThisSuiteName=CurrentTestPath['suite']
else:
ThisSuiteName='unknown-suite'
if CurrentTestPath.has_key('group'):
ThisGroupName=CurrentTestPath['group']
else:
ThisGroupName='unknown-group'
</script>
<message>
'#### %s/%s suite postamble ####' % (ThisGroupName,ThisSuiteName)
</message>
<!-- Start time of test suite -->
<script>
TestSuiteEndTime=strftime("%Y%m%d-%H:%M:%S",localtime())
</script>
<!-- Format the test group and suite names to create folder -->
<script>
FormattedTestcase=format_testcase()
FormattedTestgroup=FormattedTestcase.group(ThisGroupName)
FormattedTestsuite=FormattedTestcase.suite(ThisSuiteName)
TestLogDir= '%s/%s' % (logs.tests,FormattedTestgroup)
TestLogFile='%s/%s' % (TestLogDir,FormattedTestsuite)
</script>
<call function="'WriteLogsForTestCase'">
{ 'starttime' : TestSuiteStartTime.get(),
'endtime' : TestSuiteEndTime,
'logFile' : TestLogFile }
</call>
<script>
if CurrentTestPath.has_key('suite'):
del CurrentTestPath['suite']
</script>
</sequence>
</function>
<function name="testGroup_Preamble" scope="local">
<function-prolog>
Performs all the pre operations for a test group
</function-prolog>
<function-no-args />
<sequence>
<!-- Take the values from the current test path -->
<script>
if not CurrentTestPath.has_key('group'):
CurrentTestPath['group']='unknown-group'
ThisGroupName=CurrentTestPath['group']
xml=xmldoc_service()
repdoc = xml.parseXMLfile("%s/results_tmp.xml" % logs.reports)
qa = repdoc.getDocumentElement()
ft = qa.getChildNodes().item(1)
results = ft.getChildNodes().item(3)
if results.getChildNodes().item(1):
# tempres element already exits
xml.tempres = results.getChildNodes().item(1)
fail = xml.tempres.getChildNodes().item(1)
known = xml.tempres.getChildNodes().item(3)
done = xml.tempres.getChildNodes().item(5)
bugs = xml.tempres.getChildNodes().item(7)
else:
# Create tempres element
xml.tempres = repdoc.createElement("tempres")
results.appendChild(xml.tempres)
fail = repdoc.createElement('fail')
xml.tempres.appendChild(fail)
fail.appendChild(repdoc.createTextNode('0'))
known = repdoc.createElement('known')
xml.tempres.appendChild(known)
known.appendChild(repdoc.createTextNode('0'))
done = repdoc.createElement('done')
xml.tempres.appendChild(done)
done.appendChild(repdoc.createTextNode('0'))
bugs = repdoc.createElement('bugs')
xml.tempres.appendChild(bugs)
bugs.appendChild(repdoc.createTextNode('[]'))
#Create testgroup element
xml.testgroup = repdoc.createElement("testgroup")
xml.createAttr(repdoc,xml.testgroup,"name",ThisGroupName)
results.appendChild(xml.testgroup)
xml.writeXMLfile(repdoc,"%s/results_tmp.xml" % logs.reports)
</script>
<message>'##### %s group preamble #####' % ThisGroupName</message>
</sequence>
</function>
<function name="testGroup_Postamble">
<function-prolog>
Performs all the post operations for a test group
</function-prolog>
<function-no-args />
<sequence>
<script>
if CurrentTestPath.has_key('group'):
ThisGroupName=CurrentTestPath['group']
else:
ThisGroupName='unknown-group'
coverage='N/A'
</script>
<message>'##### %s group postamble #####' % ThisGroupName</message>
<script>
emmaJar='%s/%s/lib/emma.jar' % (DIRECTORY_INSTANCE_DIR,OPENDSNAME)
</script>
<!-- Check if 'emma.jar' exists -->
<call function="'GetEntry'">
{
'location' : STAF_REMOTE_HOSTNAME ,
'entry' : emmaJar ,
'attribute' : 'TYPE'
}
</call>
<if expr="RC != 48">
<!-- 'emma.jar' exists -->
<sequence>
<script>
remoteCoveragePath=os.path.join(remote.temp,'coverage')
coverageEm=os.path.join(remoteCoveragePath,'coverage.em')
ecPath=os.path.join(remoteCoveragePath,CurrentTestPath['group'])
</script>
<call function="'listFolderByExtension'" >
{
'location' : STAF_REMOTE_HOSTNAME,
'foldername' : ecPath,
'extension' : 'ec'
}
</call>
<script>
coverageFiles=','.join(STAXResult)
coverageHtml=os.path.join(remoteCoveragePath,CurrentTestPath['group'],'coverage.html')
srcPathPrefix = os.path.join(TESTS_ROOT,"..","..","src")
srcPaths = [ os.path.join(srcPathPrefix,"server"),
os.path.join(srcPathPrefix,"ads"),
os.path.join(srcPathPrefix,"server","org"),
os.path.join(srcPathPrefix,"admin","defn","org"),
os.path.join(srcPathPrefix,"snmp","src","org"),
os.path.join(srcPathPrefix,"ads","org"),
os.path.join(srcPathPrefix,"dsml","org"),
os.path.join(srcPathPrefix,"messages","src","org")
]
srcArgs = " -sp ".join(srcPaths)
</script>
<call function="'runCommand'">
{ 'location' : STAF_REMOTE_HOSTNAME,
'name' : 'Generate coverage html report for test group %s' % CurrentTestPath['group'],
'command' : 'java',
'arguments' : '-Xms64M -Xmx1G -cp %s emma report -r html -in %s,%s -Dreport.html.out.file=%s -sp %s' % (emmaJar, coverageEm, coverageFiles, coverageHtml, srcArgs),
'path' : ecPath
}
</call>
</sequence>
</if>
<script>
if CurrentTestPath.has_key('group'):
del CurrentTestPath['group']
</script>
</sequence>
</function>
<function name="WriteLogsForTestCase" scope="local">
<function-prolog>
Queries the staf logs for the test case and write to file as text
</function-prolog>
<function-map-args>
<function-arg-def name="starttime" type="required">
<function-arg-description>
timestamp to start logging from
</function-arg-description>
<function-arg-property name="type" value="timestamp"/>
</function-arg-def>
<function-arg-def name="endtime" type="required">
<function-arg-description>
timestamp to start logging to
</function-arg-description>
<function-arg-property name="type" value="timestamp"/>
</function-arg-def>
<function-arg-def name="logFile" type="required">
<function-arg-description>
name of file to write the logs
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
</function-map-args>
<sequence>
<script>
xmlFile = '%s-log.xml' % logFile
htmlFile = '%s-log.html' % logFile
xslFile = '%s/gen-logs.xsl' % TESTS_XSL_DIR
</script>
<!-- Query STAF to obtain the logs for the test case -->
<call function="'queryLogs'">
{ 'location' : STAXServiceMachine,
'logname' : 'STAX_Job_%s_User' % STAXJobID,
'startfrom' : starttime,
'endat' : endtime }
</call>
<!-- Write out the logs into an XML file -->
<call function="'WriteXmlLogs'">
{ 'queryresult' : STAFResult,
'output' : xmlFile }
</call>
<!-- Transform the XML file into an HTML file -->
<call function="'WriteHtmlLogs'">
{ 'input' : xmlFile,
'stylesheet' : xslFile,
'output' : htmlFile }
</call>
<!-- Delete the XML file
<call function="'deleteFile'">
{ 'location' : STAXServiceMachine,
'filename' : xmlFile }
</call>
-->
</sequence>
</function>
<function name="WriteXmlLogs" scope="local">
<function-prolog>
Process staf log query results and write them to a file
</function-prolog>
<function-map-args>
<function-arg-def name="queryresult" type="required">
<function-arg-description>
result of the staf log query
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="output" type="required">
<function-arg-description>
name of the XML file to where results are written
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<sequence>
<script>
logFile=output
NewLogDir=os.path.dirname(logFile)
</script>
<message>'Creating XML log file %s' % logFile</message>
<call function="'createFolder'">
{ 'location' : STAXServiceMachine,
'foldername' : NewLogDir }
</call>
<script>
from xml.dom.minidom import Document
logsdoc = Document()
# Create the qa base element
qa = logsdoc.createElement("qa")
logsdoc.appendChild(qa)
# Create the base element
logs = logsdoc.createElement("logs")
qa.appendChild(logs)
# Try to pass only the pretty print of the test suite name
try:
suite=CurrentTestPath['suite'].split('.')[2].strip()
except:
formattedTestcase = format_testcase()
suite = formattedTestcase.suite(CurrentTestPath['suite'])
# Create the log element
log = logsdoc.createElement("log")
log.setAttribute("group", "%s" % CurrentTestPath['group'])
log.setAttribute("suite", "%s" % suite)
log.setAttribute("jobid", "%s" % STAXJobID)
log.setAttribute("parent", "%s" % STAXParentID)
logs.appendChild(log)
</script>
<if expr="queryresult == '[]'">
<sequence>
<script>
output1 = 'queryresult is empty'
output2 = 'check the date between the OS, the logs'
output3 = 'and the local time zone'
output = '%s %s %s' % (output1,output2,output3)
</script>
<call function="'checktestRC'">
{ 'returncode' : '1' ,
'result' : output,
'expected' : '0' }
</call>
</sequence>
<else>
<iterate var="element" in="queryresult">
<script>
level=element['level']
message=element['message']
timestamp=element['timestamp']
line = logsdoc.createElement("line")
line.setAttribute("timestamp", "%s" % timestamp)
line.setAttribute("level", "%s" % level)
line.setAttribute("message", "%s" % message)
if level == 'Start':
tag=get_test_name(message.replace('testcase: ',''))
line.setAttribute("tag", "%s" % tag.lower())
log.appendChild(line)
</script>
</iterate>
</else>
</if>
<script>
_message='Generated XML test case report.'
testlogfh=open('%s' % logFile,'w')
try:
testlogfh.writelines(logsdoc.toprettyxml(indent=" "))
except AttributeError,details:
_message='Unable to generate XML test case report %s.' % details
except:
_message='Unable to generate XML test case report !!!'
testlogfh.close()
firstline=0
newlines=[]
testlogfh=open('%s' % logFile,'r')
lines=testlogfh.readlines()
for l in lines:
if firstline==0:
newlines.append('&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;\n')
firstline=1
else:
newlines.append(l)
testlogfh.close()
testlogfh=open('%s' % logFile,'w')
testlogfh.writelines(newlines)
testlogfh.close()
</script>
<message>_message</message>
</sequence>
</function>
<function name="WriteHtmlLogs" scope="local">
<function-prolog>
Process XML file and transform that to an HTML log file
</function-prolog>
<function-map-args>
<function-arg-def name="input" type="required">
<function-arg-description>
name of the XML file to where results are obtained
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="output" type="required">
<function-arg-description>
name of the HTML file to where results are written
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="stylesheet" type="required">
<function-arg-description>
name of the XSL stylesheet used to transform results
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<sequence>
<script>
xmlFile=input
htmlFile=output
xslFile=stylesheet
</script>
<message>'Inputting XML file %s' % xmlFile</message>
<message>'Transform XSL file %s' % xslFile</message>
<message>'Creating HTML file %s' % htmlFile</message>
<script>
_message='Generated test case logs.'
testCaseLogs=report_generation()
stringParamsDict={}
try:
testCaseLogs.transformReport(xslFile,xmlFile,htmlFile,stringParamsDict)
except java.io.FileNotFoundException,details:
_message='Unable to generate test case logs %s.' % details
except IOError,details:
_message='Unable to generate test case logs %s.' % details
except:
_message='Unable to generate test case logs !!!'
</script>
<message>'%s' % _message</message>
</sequence>
</function>
<function name="CheckMatches">
<function-prolog>
check the number of matching sub-string in a string
</function-prolog>
<function-map-args>
<function-arg-def name="string2find" type="required">
<function-arg-description>
the sub-string to check
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="mainString" type="required">
<function-arg-description>
the main string where the search is done
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="caseSensitive" type="optional" default="True">
<function-arg-description>
comparison using case sensitive, or not value is : True/False
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="nbExpected" type="optional" default="1">
<function-arg-description>
number of expected sub-string that must be in the main string
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="issue" type="optional" default="None">
<function-arg-description>
Issue id. Corresponds to an issue number.
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
caseSensitiveInfo = '[case sensitive mode]'
if caseSensitive == False:
string2find = string2find.lower()
mainString = mainString.lower()
caseSensitiveInfo = '[case insensitive mode]'
nbFound = mainString.count(string2find)
if nbFound == nbExpected:
myMessage = 'SUCCESS : %s matches %s time(s) (expected %s) %s' % (string2find,nbFound,nbExpected,caseSensitiveInfo)
myRC=0
else:
myMessage = 'ERROR : %s matches %s time(s) (expected %s) in "%s" %s' % (string2find,nbFound,nbExpected,mainString,caseSensitiveInfo)
myRC=1
</script>
<if expr="myRC == 0">
<sequence>
<tcstatus result="'pass'"/>
<message log="1">
'%s' % myMessage
</message>
</sequence>
<else>
<sequence>
<if expr="issue == None">
<tcstatus result="'fail'"/>
<else>
<sequence>
<call function="'setKnownIssue'">
{ 'issueId' : issue }
</call>
</sequence>
</else>
</if>
<message log="1" level="'Error'">
'%s' % myMessage
</message>
</sequence>
</else>
</if>
<return>myRC,myMessage</return>
</sequence>
</function>
<function name="runFunction" scope="local">
<function-map-args>
<function-arg-def name="functionName" type="required">
<function-arg-description>
Name of the function to run
</function-arg-description>
</function-arg-def>
<function-arg-def name="functionArguments" type="optional">
<function-arg-description>
Arguments to be passed on to the called function.
This can be a map or a list of arguments, whatever the called function
expects will be carried on here.
. for a map, pass the arguments like this:
{ 'argumentA' : 'argumentAvalue' ,
'argumentB' : 1 ,
...
}
. for a list, pass the arguments like this:
[ 'argumentAvalue, 1, ... ]
</function-arg-description>
</function-arg-def>
<function-arg-def name="expectedRC" type="optional" default="0">
<function-arg-description>
The expected return code of the function to run.
This is then passed onto the checkRC function.
It is also used to throw an exception if the argument
functionException is provided and set the test case status if the
argument functionSetsTCStatus is provided
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="functionException" type="optional">
<function-arg-description>
The exception to throw if the return code differs from the expected
RC. The exception is appended to STAXException.
</function-arg-description>
</function-arg-def>
<function-arg-def name="functionMessage" type="optional">
<function-arg-description>
An optional message to display before running the function
</function-arg-description>
</function-arg-def>
<function-arg-def name="functionSetsTCStatus" type="optional">
<function-arg-description>
Whether the function to run sets the testcase status or not.
If this is set, the test case status is set according to whether
or not the function meets the expected return code.
True or False should be used for this argument.
</function-arg-description>
</function-arg-def>
<function-arg-def name="functionFailureTC" type="optional">
<function-arg-description>
If this argument is provided, a testcase will be created with
this argument's value for name and set to fail only upon failure
</function-arg-description>
</function-arg-def>
<function-arg-def name="functionSignal" type="optional">
<function-arg-description>
If this argument is provided, a signal will be raised upon unsuccesful
execution of the function to run
</function-arg-description>
</function-arg-def>
<function-arg-def name="functionCallBack" type="optional">
<function-arg-description>
If this argument is provided then functionCallBack will be called
after the execution of function name.
</function-arg-description>
</function-arg-def>
<function-arg-def name="functionCallBackArguments" type="optional">
<function-arg-description>
This allows to specify arguments for the call back function
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
<!-- defining the booleans here should temporary while I find a nicer
solution. We have a chicken and egg problem between the
loadGlobalEnvironment and loadSharedLibraries functions in
environment.xml at the moment.
-->
if not False:
False=0
if not True:
True=1
_expectedRC=int(expectedRC)
_throwException=False
if functionException:
_throwException=True
_displayMessage=False
if functionMessage:
_displayMessage=True
_tcStatus='fail'
_doSetTCStatus=False
if functionSetsTCStatus:
_doSetTCStatus=True
_createFailureTC=False
if functionFailureTC:
_createFailureTC=True
</script>
<message log="1" level="'info'" if="_displayMessage == True">
'%s' % functionMessage
</message>
<message log="1" level="'debug'">
'runFunction: %s: called with parameters [%s]' % (functionName,functionArguments)
</message>
<call function="functionName">functionArguments</call>
<script>
_functionRC = int(RC)
_functionResult = STAXResult
</script>
<!-- this section handles the optional case when we need to set the
test case status
-->
<if expr="_doSetTCStatus == True">
<sequence>
<if expr="_functionRC == _expectedRC">
<script>_tcStatus='pass'</script>
</if>
<tcstatus result="_tcStatus" />
</sequence>
</if>
<!-- this section handles the optional case when we need to throw an
exception upon unexpected function return code
-->
<if expr="_throwException == True" >
<if expr="_functionRC != _expectedRC" >
<throw exception="'STAXException.%s' % functionException" />
</if>
</if>
<!-- this section handles the optional case when we need to set a
test case status to fail to reflect the failure in the test report.
-->
<if expr="_createFailureTC == True" >
<if expr="_functionRC != _expectedRC" >
<testcase name="'!!! %s [%s]' % (functionFailureTC,functionName)">
<tcstatus result="'fail'" />
</testcase>
</if>
</if>
<!-- TODO: implement the signal raising mechanism -->
<!-- TODO: implement the call back function mechanism -->
<!-- bubble the function return code and result up one level -->
<return>[_functionRC,_functionResult]</return>
</sequence>
</function>
<function name="runCommand" >
<function-description>
A general wrapper to run a command without having to write a dedicated
function for it
</function-description>
<function-map-args>
<function-arg-def name="command" type="required">
<function-arg-description>
the command to run
</function-arg-description>
</function-arg-def>
<function-arg-def name="path" type="optional" default="dsBinPath">
<function-arg-description>
the path where the command is to be run from
</function-arg-description>
</function-arg-def>
<function-arg-def name="arguments" type="optional" default="''">
<function-arg-description>
the path where the command is to be found
</function-arg-description>
</function-arg-def>
<function-arg-def name="envCmd"
type="optional"
default="''">
<function-arg-description>
the environment variables to set. The default set here should just
work for OpenDS commands
</function-arg-description>
</function-arg-def>
<function-arg-def name="location"
type="optional"
default="STAXServiceMachine">
<function-arg-description>
Which machine should the command be executed on
</function-arg-description>
</function-arg-def>
<function-arg-def name="name"
default="'Running %s' % command"
type="optional">
<function-arg-description>
The name to give the process (only matters in the STAX Monitor really)
</function-arg-description>
</function-arg-def>
<function-arg-def name="stripOutput" default="True" type="optional">
<function-arg-description>
A boolean (use True or False here, case matters) to enable disable
stripping the output of a command
TODO: consider allowing passing a function name to enable custom
output manipulation (overkill?)
</function-arg-description>
<function-arg-property name="type" value="enum">
<function-arg-property-description>
This argument can only have boolean values
</function-arg-property-description>
<function-arg-property-data type="choice" value="True"/>
<function-arg-property-data type="choice" value="False"/>
</function-arg-property>
</function-arg-def>
<function-arg-def name="timerDuration"
type="optional"
default="'5m'">
<function-arg-description>
The duration that the process is allowed to run
</function-arg-description>
</function-arg-def>
<function-arg-def name="inputFile" type="optional" default="'None'">
<function-arg-description>
input file containing the command input
</function-arg-description>
<function-arg-property name="type" value="file"/>
</function-arg-def>
<function-arg-def name="outputFile" type="optional" default="'None'">
<function-arg-description>
Output file containing the command output
</function-arg-description>
<function-arg-property name="type" value="file"/>
</function-arg-def>
<function-arg-def name="expectedRC" type="optional" default="0">
<function-arg-description>
Expected return code value. Default value is 0.
Wildcard 'noCheck' to not check the RC
</function-arg-description>
</function-arg-def>
<function-arg-def name="expectedString" type="optional" default="None">
<function-arg-description>
Expected return string value.
</function-arg-description>
</function-arg-def>
<function-arg-def name="knownIssue" type="optional" default="None">
<function-arg-description>
Known issue. Corresponds to an issue number.
</function-arg-description>
</function-arg-def>
<function-arg-def name="logStderr" type="optional" default="True">
<function-arg-description>
If true, stderr for the command is redirect to stdout.
</function-arg-description>
<function-arg-property name="type" value="enum">
<function-arg-property-description>
This argument can only have boolean values
</function-arg-property-description>
<function-arg-property-data type="choice" value="True"/>
<function-arg-property-data type="choice" value="False"/>
</function-arg-property>
</function-arg-def>
</function-map-args>
<sequence>
<script>
import random
import java.util.Date
random.seed(java.util.Date().getTime())
_id = '%s#%d' % (strftime('%Y-%m-%d %H:%M:%S',localtime()),random.randint(0,999))
env=[]
for item in envCmd:
env.append('%s' % item)
if is_windows_platform(location):
env.append('PATH=%s\\bin;C:\\Windows;C:\\Windows\\system32;%s' % (REMOTE_STAF_ROOT,path))
env.append('JAVA_HOME=%s' % JAVA_HOME)
else:
env.append('PATH=/bin:/usr/bin:%s' % path)
env.append('JAVA_HOME=%s' % JAVA_HOME)
if command.endswith('setup.bat') or command.endswith('uninstall.bat'):
arguments = arguments + ' &amp; set PROCESSRC=%ERRORLEVEL% &amp; exit %PROCESSRC%'
if TESTS_TYPE == 'functional-tests':
timerDuration = '10m'
else:
timerDuration = '10h'
</script>
<message>
'%s: Running command:\n %s %s\nlocation: %s\nenv: %s\nworkdir: %s' % (_id,command,arguments,location,env,path)
</message>
<timer duration="timerDuration">
<sequence>
<!-- If 'logStderr' is True then redirect sdterr to sdtout -->
<if expr="logStderr == True">
<process name="name">
<location>location</location>
<command>command</command>
<parms>arguments</parms>
<workdir>path</workdir>
<envs>env</envs>
<console use="'same'"/>
<stdout if="outputFile != 'None'" mode="'replace'">'%s' % outputFile</stdout>
<stderr mode="'stdout'"/>
<returnstdout/>
</process>
<elseif expr="inputFile != 'None'">
<process name="name">
<location>location</location>
<command>command</command>
<parms>arguments</parms>
<workdir>path</workdir>
<envs>env</envs>
<console use="'same'"/>
<stdin>'%s' % inputFile</stdin>
<returnstdout/>
</process>
</elseif>
<else>
<process name="name">
<location>location</location>
<command>command</command>
<parms>arguments</parms>
<workdir>path</workdir>
<envs>env</envs>
<console use="'same'"/>
<stdout if="outputFile != 'None'" mode="'replace'">'%s' % outputFile</stdout>
<returnstdout/>
</process>
</else>
</if>
<!-- The problem here is that STAXResult can either be a
string, list or a map object -->
<script>
try:
cmdOutput=STAXResult[0][1]
cmdRC = RC
except:
cmdOutput=STAXResult
cmdRC = RC
cmdResult=STAXResult
</script>
<script>
def dig(var):
try:
if var.__class__==[].__class__:
for i in range(len(var)):
var[i]=dig(var[i])
return var
else:
if var.__class__==''.__class__:
return re.compile(r'EMMA:.*\n').sub('',var)
else:
return var
except TypeError:
return 'could not evaluate the following component: %s' % var
if stripOutput == True:
cmdResult=dig(cmdResult)
</script>
<if expr="expectedRC != 'noCheck'">
<call function="'checktestRC'">
{ 'returncode' : cmdRC,
'result' : cmdResult,
'expected' : expectedRC,
'issue' : knownIssue
}
</call>
</if>
<if expr="expectedString">
<call function="'checktestString'">
{ 'returnString' : cmdOutput ,
'expectedString' : expectedString }
</call>
</if>
<!-- If output contains "There are no tasks defined", add known issue -->
<script>
import re
setIssue = False
if re.search('.*There are no tasks defined with ID.*', cmdOutput) is not None:
setIssue = True
</script>
<if expr="setIssue == True and expectedRC == 0">
<sequence>
<call function="'setKnownIssue'">
{ 'issueId' : 'OPENDJ-1071' }
</call>
</sequence>
</if>
</sequence>
</timer>
<if expr="RC == 1">
<sequence>
<script>
cmdResult=[[1,'Timeout']]
</script>
<message log="1" level="'Error'">
'ERROR: COMMAND HANGING, not completed after %s' % timerDuration
</message>
<if expr="knownIssue == None">
<tcstatus result="'fail'"/>
<else>
<sequence>
<call function="'setKnownIssue'">
{ 'issueId' : knownIssue }
</call>
</sequence>
</else>
</if>
</sequence>
<else>
<script>RC = cmdRC</script>
</else>
</if>
<return>
cmdResult
</return>
</sequence>
</function>
<function name="killDs">
<function-prolog>
Kill the ldap server
</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="dsPath"
type="optional"
default="'%s/%s'
% (DIRECTORY_INSTANCE_DIR,OPENDSNAME)">
<function-arg-description>
Pathname to installation root
</function-arg-description>
<function-arg-property name="type" value="pathname"/>
</function-arg-def>
</function-map-args>
<sequence>
<message>
'Kill server running on %s at %s' % (location, dsPath)
</message>
<script>
pidPath = '%s/logs/server.pid' % dsPath
_args = '%s' % pidPath
</script>
<call function="'runSTAFCommand'">
{ 'name' : 'Read server pid file',
'location' : location,
'service' : 'FS',
'request' : 'GET FILE',
'arguments' : _args
}
</call>
<script>
pidSTAXResult = STAXResult
pid = STAXResult[:-1]
cmd = '%s/bin/jstack' % JAVA_HOME
env = ['JAVA_HOME=%s' % JAVA_HOME]
if is_windows_platform(location):
cmdOptions = '-l %s' % pidSTAXResult
else:
cmdOptions = '-l %s' % pid
outputPath = '%s/..' % (dsPath)
</script>
<call function="'runCommand'" >
{
'name' : 'Run jstack' ,
'command' : cmd ,
'arguments' : cmdOptions ,
'location' : location ,
'outputFile' : '%s/jstack.txt' % outputPath ,
'envCmd' : env
}
</call>
<script>
if is_windows_platform(location):
_cmd = 'tskill'
_args = pidSTAXResult
else:
_cmd = '/bin/kill'
_args = '-9 %s' % pid
</script>
<if expr="os.path.exists(os.path.join(dsPath,'lib','emma.jar')) == False">
<call function="'runCommand'">
{ 'name' : 'Kill DS server',
'location' : location,
'command' : _cmd,
'arguments' : _args
}
</call>
<else>
<message>'skip the killing of process when running with coverage to avoid data corruption'</message>
</else>
</if>
<return>STAXResult</return>
</sequence>
</function>
<function name="runSTAFCommand" >
<function-description>
A general wrapper to run a STAF command without having to write a
dedicated function for it
</function-description>
<function-map-args>
<function-arg-def name="location" type="optional" default="STAXServiceMachine">
<function-arg-description>
Which machine should the command be executed on
</function-arg-description>
</function-arg-def>
<function-arg-def name="name" type="required">
<function-arg-description>
The name to give the process
</function-arg-description>
</function-arg-def>
<function-arg-def name="service" type="required">
<function-arg-description>
the command to run
</function-arg-description>
</function-arg-def>
<function-arg-def name="request" type="required">
<function-arg-description>
the command to run
</function-arg-description>
</function-arg-def>
<function-arg-def name="arguments" type="optional" default="''">
<function-arg-description>
the arguments for the service request
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
import random
import java.util.Date
random.seed(java.util.Date().getTime())
_id = '%s#%d' % (strftime('%Y-%m-%d %H:%M:%S',localtime()),random.randint(0,99999))
</script>
<message>
'%s: Running STAF command:\n %s %s %s\nlocation: %s\n' % (_id,service,request,arguments,location)
</message>
<block name="'%s:Wrapper for %s' % (_id,name)">
<stafcmd name="'STAF Command: %s' % name">
<location>'%s' % location</location>
<service>service</service>
<request>
'%s %s' % (request,arguments)
</request>
</stafcmd>
</block>
<message level="'info'">
'%s: STAF Command returned:\n%s' % (_id,STAFResult)
</message>
<return>
STAFResult
</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>
<if expr="VERBOSE_MODE == 'true'">
<message>
'File content %s' % filecontent
</message>
</if>
<call function="'searchStringForSubstring'">
{
'testString' : testString,
'returnString' : filecontent,
'expectedResult' : myExpectedResult
}
</call>
<return>STAXResult</return>
</sequence>
</function>
<function name="compareFile">
<function-prolog>
This function compares two files.
Print the differences if the comparison failed.
</function-prolog>
<function-map-args>
<function-arg-def name="location"
type="optional"
default="STAXServiceMachine">
<function-arg-description>
Location of target host
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
<function-arg-def name="remotehost"
type="optional"
default="STAF_REMOTE_HOSTNAME">
<function-arg-description>
The name of remote host
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
<function-arg-def name="dsPath"
type="optional"
default="'%s/%s' % (DIRECTORY_INSTANCE_BIN,OPENDSNAME)">
<function-arg-description>
Pathname to installation root
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
<function-arg-def name="outputFile" type="required">
<function-arg-description>
file containing output from the command
</function-arg-description>
<function-arg-property name="type" value="file"/>
</function-arg-def>
<function-arg-def name="outputPath" type="optional">
<function-arg-description>
path containing outputFile
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="refFile" type="optional">
<function-arg-description>
reference file containing expected output
</function-arg-description>
<function-arg-property name="type" value="file"/>
</function-arg-def>
<function-arg-def name="refPath" type="optional">
<function-arg-description>
reference path containing refFile
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="diffFile" type="optional">
<function-arg-description>
file containing diff output
</function-arg-description>
<function-arg-property name="type" value="file"/>
</function-arg-def>
<function-arg-def name="diffPath" type="optional">
<function-arg-description>
file containing diffFile
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="sortFile" type="optional" default="False">
<function-arg-description>
sort files before diff
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="knownIssue" type="optional" default="None">
<function-arg-description>
Known issue. Corresponds to an issue number.
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
if CurrentTestPath.has_key('group'):
ThisGroupName = CurrentTestPath['group']
else:
ThisGroupName = 'unknown-group'
FormattedTestcase = format_testcase()
FormattedTestgroup = FormattedTestcase.group(ThisGroupName)
if not outputPath:
outputPath = '%s/..' % (dsPath)
if not refFile:
regexp = re.compile('\..*$')
tmpName = re.sub(regexp, '', outputFile)
refFile = '%s.ref' % tmpName
if not refPath:
refPath = '%s/%s' % (local.data,FormattedTestgroup)
if not diffFile:
regexp = re.compile('\..*$')
tmpName = re.sub(regexp, '', outputFile)
diffFile = '%s.diff' % tmpName
if not diffPath:
diffPath = '%s/%s/diffs' % (logs.tests,FormattedTestgroup)
else:
diffPath = '%s/diffs' % (diffPath)
cflocation=location
cfremotehost=remotehost
</script>
<!-- Check if 'diffPath' is already created -->
<call function="'GetEntry'">
{
'location' : cflocation,
'entry' : diffPath,
'attribute' : 'TYPE'
}
</call>
<!-- If 'diffPath' is not already created then create it -->
<if expr="RC == 48">
<sequence>
<message>
'Create folder %s' % diffPath
</message>
<call function="'createFolder'">
{
'location' : cflocation ,
'foldername' : diffPath
}
</call>
</sequence>
</if>
<message>
'Copy file %s/%s (on %s) to %s/%s (on %s)' % \
(outputPath, outputFile, cfremotehost, diffPath, outputFile, cflocation)
</message>
<call function="'copyFile'">
{
'location' : cfremotehost ,
'srcfile' : '%s/%s' % (outputPath, outputFile) ,
'destfile' : '%s/%s' % (diffPath, outputFile) ,
'remotehost' : cflocation
}
</call>
<script>
outputRC=RC
</script>
<message>
'Copy file %s/%s (on %s) to %s/%s (on %s)' % \
(refPath, refFile, cflocation, diffPath, refFile, cflocation)
</message>
<call function="'copyFile'">
{
'location' : cflocation ,
'srcfile' : '%s/%s' % (refPath, refFile) ,
'destfile' : '%s/%s' % (diffPath, refFile) ,
'remotehost' : cflocation
}
</call>
<script>
refRC=RC
</script>
<!-- Sort files before diff -->
<if expr="sortFile == True" >
<sequence>
<script>
outputFileSorted = '%s_sorted' % outputFile
refFileSorted = '%s_sorted' % refFile
# Output file
sourceFile = open('%s/%s' % (diffPath, outputFile), "r")
sortFile = open('%s/%s' % (diffPath, outputFileSorted), "w")
lines = sourceFile.readlines()
lines.sort()
sortFile.writelines(lines)
sourceFile.close()
sortFile.close()
# Reference file
sourceFile = open('%s/%s' % (refPath, refFile), "r")
sortFile = open('%s/%s' % (diffPath, refFileSorted), "w")
lines = sourceFile.readlines()
lines.sort()
sortFile.writelines(lines)
sourceFile.close()
sortFile.close()
outputFile = outputFileSorted
refFile = refFileSorted
</script>
</sequence>
</if>
<!-- If the copy of 'outputFile' and 'refFile' succeed
then compare these files -->
<if expr="outputRC == 0 and refRC == 0">
<sequence>
<message>
'Compare file %s/%s to %s/%s on %s' % \
(diffPath, outputFile, diffPath, refFile, cflocation)
</message>
<script>
CompareFile = compare_file('%s/%s' % (diffPath, outputFile),
'%s/%s' % (diffPath, refFile),
'%s/%s' % (diffPath, diffFile))
diff = CompareFile.genDiff()
</script>
<if expr="diff == ''">
<sequence>
<tcstatus result="'pass'"/>
<message log="1">
'SUCCESS : No differences were found between %s and %s' % \
(outputFile, refFile)
</message>
</sequence>
<else>
<sequence>
<if expr="knownIssue == None">
<tcstatus result="'fail'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : knownIssue }
</call>
</else>
</if>
<message log="1">
'ERROR : Differences were found between %s and %s\n%s' % \
(outputFile, refFile, diff)
</message>
<message log="1">
'ERROR : Diff file is here: %s/%s' % (diffPath, diffFile)
</message>
</sequence>
</else>
</if>
</sequence>
<else>
<sequence>
<tcstatus result="'fail'"/>
<message log="1">
'ERROR : Error during file comparision'
</message>
</sequence>
</else>
</if>
</sequence>
</function>
<function name="compileJava" scope="local">
<function-prolog>
This function compile java files.
</function-prolog>
<function-map-args>
<function-arg-def name="location"
type="optional"
default="STAXServiceMachine">
<function-arg-description>
Location of remote host
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
<function-arg-def name="foldername" type="optional">
<function-arg-description>
Path containing java files to compile
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="destfolder" type="optional">
<function-arg-description>
Path where to place generated class files
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="classpath" type="optional">
<function-arg-description>
Additional classpath
</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. Default value is 0.
Wildcard 'noCheck' to not check the RC
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<!-- Build the command -->
<script>
cmdOptions = ''
if is_windows_platform(location):
separator=';'
else:
separator=':'
if classpath:
cp = 'CLASSPATH=%s%s.' % (classpath, separator)
else:
cp = 'CLASSPATH=.'
if location == STAXServiceMachine:
cmd = '%s/bin/javac' % LOCAL_JAVA_HOME
env = ['%s' % cp]
else:
cmd = '%s/bin/javac' % JAVA_HOME
env = ['JAVA_HOME=%s' % JAVA_HOME, '%s' % cp]
if destfolder:
cmdOptions = '-d %s' % destfolder
</script>
<call function="'listFolderByExtension'" >
{
'location' : location ,
'foldername' : foldername ,
'extension' : 'java'
}
</call>
<script>
cmdResult = STAXResult
</script>
<if expr="cmdResult != 'Folder does not exist.'">
<sequence>
<script>
list = ""
for file in cmdResult:
list = list + " " + file
</script>
<call function="'runCommand'" >
{
'name' : 'Compile Java files' ,
'command' : cmd ,
'arguments' : '%s %s' % (cmdOptions,list) ,
'location' : location ,
'path' : foldername ,
'envCmd' : env ,
'expectedRC' : expectedRC
}
</call>
</sequence>
<else>
<tcstatus result="'fail'"></tcstatus>
</else>
</if>
<return>
STAXResult
</return>
</sequence>
</function>
<function name="createJar" scope="local">
<function-prolog>
This function create a jar file.
</function-prolog>
<function-map-args>
<function-arg-def name="location"
type="optional"
default="STAXServiceMachine">
<function-arg-description>
Location of remote host
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
<function-arg-def name="jarname" type="required">
<function-arg-description>
Name of the jar file to create
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="entrypoint" type="required">
<function-arg-description>
Path where to find generated class files
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="pathfolder" type="required">
<function-arg-description>
Execution path
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="manifestpath" type="optional">
<function-arg-description>
Path to the manifest file
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="expectedRC" type="optional" default="0">
<function-arg-description>
Expected return code value. Default value is 0.
Wildcard 'noCheck' to not check the RC
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<!-- Build the command -->
<script>
if location == STAXServiceMachine:
cmd = '%s/bin/jar' % LOCAL_JAVA_HOME
else:
cmd = '%s/bin/jar' % JAVA_HOME
if manifestpath:
cmdOptions = 'cmf %s' % manifestpath
else:
cmdOptions = 'cf'
</script>
<!-- Check if the classfolder exists -->
<call function="'GetEntry'">
{
'location' : location ,
'entry' : '%s/%s' % (pathfolder,entrypoint) ,
'attribute' : 'TYPE'
}
</call>
<if expr="RC != 48">
<sequence>
<call function="'runCommand'" >
{
'name' : 'Create Jar file' ,
'command' : cmd ,
'arguments' : '%s %s %s' % (cmdOptions,jarname,entrypoint) ,
'location' : location ,
'path' : pathfolder ,
'expectedRC' : expectedRC
}
</call>
</sequence>
<else>
<tcstatus result="'fail'"></tcstatus>
</else>
</if>
<return>
STAXResult
</return>
</sequence>
</function>
<function name="getFreePort" scope="local">
<function-description>
Returns the first free TCP port greater or equal to given number
</function-description>
<function-map-args>
<function-arg-def name="host"
type="optional"
default="STAXServiceMachine">
<function-arg-description>
Which machine to look for the free port
</function-arg-description>
</function-arg-def>
<function-arg-def name="port" type="required">
<function-arg-description>
The minimal port number to be returned
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
# returns first free port in [port; port+5]
# if no free port in this interval, return -1
from java.net import Socket
from java.net import InetAddress
from java.io import IOException
hostAddr = InetAddress.getByName(host)
i = 0
while 1:
i = i + 1
if i > 5:
port = -1
break
try:
s = Socket(hostAddr, port)
s.close()
port = port + 1
except IOException, ioe:
break
</script>
<return>port</return>
</sequence>
</function>
<function name="checkFileExists" scope="local">
<function-description>
Set testcase result to FAIL if file (as param) does not exist
</function-description>
<function-map-args>
<function-arg-def name="location"
type="optional"
default="STAXServiceMachine">
<function-arg-description>
Location of target host
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
<function-arg-def name="file" type="required">
<function-arg-description>
The file to check existence
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<call function="'GetEntry'">
{
'location' : STAF_REMOTE_HOSTNAME ,
'entry' : file ,
'attribute' : 'TYPE'
}
</call>
<if expr="RC == 48">
<sequence>
<tcstatus result="'fail'"/>
<message log="1" level="'Error'">
'ERROR : File %s does not exist' % file
</message>
</sequence>
</if>
</sequence>
</function>
<function name="checkFileNotExists" scope="local">
<function-description>
Set testcase result to FAIL if file (as param) exists
</function-description>
<function-map-args>
<function-arg-def name="location"
type="optional"
default="STAXServiceMachine">
<function-arg-description>
Location of target host
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
<function-arg-def name="file" type="required">
<function-arg-description>
The file to check absence
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<call function="'GetEntry'">
{
'location' : STAF_REMOTE_HOSTNAME ,
'entry' : file ,
'attribute' : 'TYPE'
}
</call>
<if expr="RC != 48">
<sequence>
<tcstatus result="'fail'"/>
<message log="1" level="'Error'">
'ERROR : File %s does not exist' % file
</message>
</sequence>
</if>
</sequence>
</function>
<function name="ldclt">
<function-prolog>
This function execute the ldclt tools.
</function-prolog>
<function-map-args>
<function-arg-def name="location"
type="optional"
default="STAF_CLIENT_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="dsInstanceHost"
type="optional"
default="DIRECTORY_INSTANCE_HOST">
<function-arg-description>
Directory server hostname or IP address
</function-arg-description>
<function-arg-property name="type" value="hostname"/>
</function-arg-def>
<function-arg-def name="dsInstancePort"
type="optional"
default="DIRECTORY_INSTANCE_PORT">
<function-arg-description>
Directory server port number
</function-arg-description>
<function-arg-property name="type" value="Port number"/>
</function-arg-def>
<function-arg-def name="dsInstanceDn"
type="optional"
default="DIRECTORY_INSTANCE_DN">
<function-arg-description>
Bind DN
</function-arg-description>
<function-arg-property name="type" value="DN"/>
</function-arg-def>
<function-arg-def name="dsInstancePswd"
type="optional"
default="DIRECTORY_INSTANCE_PSWD">
<function-arg-description>
Bind password
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="dsBaseDn"
type="optional"
default="DIRECTORY_INSTANCE_SFX">
<function-arg-description>
The baseDN for the LDAP operation
</function-arg-description>
<function-arg-property name="type" value="dn"/>
</function-arg-def>
<function-arg-def name="ldcltOptions"
type="required">
<function-arg-description>
The ldclt options
</function-arg-description>
<function-arg-property name="type" value="dn"/>
</function-arg-def>
<function-arg-def name="outputFile"
type="required">
<function-arg-description>
File containing output from the command
</function-arg-description>
<function-arg-property name="type" value="file"/>
</function-arg-def>
<function-arg-def name="outputPath"
type="optional"
default="remote.temp">
<function-arg-description>
Path containing outputFile
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="expectedRC" type="optional" default="0">
<function-arg-description>
Expected return code value. Default value is 0
Wildcard 'noCheck' to not check the RC
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
<function-arg-def name="knownIssue"
type="optional"
default="None">
<function-arg-description>
Known issue. Corresponds to an issue number.
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
STAFCmdParamsList=[]
STAFCmdParams=''
STAFCmd='%s/bin/ldclt' % LDCLT_DIR
if dsInstanceHost:
STAFCmdParamsList.append('-h %s' % dsInstanceHost)
if dsInstanceHost:
STAFCmdParamsList.append('-p %s' % dsInstancePort)
if dsInstanceDn:
STAFCmdParamsList.append('-D "%s"' % dsInstanceDn)
if dsInstancePswd:
STAFCmdParamsList.append('-w %s' % dsInstancePswd)
if dsBaseDn:
STAFCmdParamsList.append('-b "%s"' % dsBaseDn)
STAFCmdParamsList.append(ldcltOptions)
STAFCmdParams=' '.join(STAFCmdParamsList)
ld = 'LD_LIBRARY_PATH='
env = ['%s' % ld]
</script>
<call function="'runCommand'" >
{
'name' : 'LDCLT Script' ,
'command' : STAFCmd ,
'arguments' : STAFCmdParams ,
'location' : location ,
'path' : LDCLT_DIR ,
'envCmd' : env ,
'outputFile' : '%s/%s' % (outputPath, outputFile) ,
'expectedRC' : expectedRC ,
'logStderr' : True ,
'knownIssue' : knownIssue
}
</call>
<return>
STAXResult
</return>
</sequence>
</function>
<!-- This function uses make ldif to generate LDIF data files -->
<function name="MakeALdcltTemplate">
<function-prolog>
This function makes a ldclt template file
</function-prolog>
<function-map-args>
<function-arg-def name="templateFile" type="required">
<function-arg-description>
Template file name
</function-arg-description>
<function-arg-property name="type" value="filename"/>
</function-arg-def>
<function-arg-def name="templateLocation"
type="optional"
default="STAF_CLIENT_HOSTNAME">
<function-arg-description>
Template file location
</function-arg-description>
<function-arg-property name="type" value="filename"/>
</function-arg-def>
<function-arg-def name="extraLine" type="optional">
<function-arg-description>
Extra line to add to the mkae-ldif template
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<sequence>
<!-- Build the import task configuration object -->
<script>
ldifLines=[]
ldifLines.append('objectClass: top')
ldifLines.append('objectClass: person')
ldifLines.append('objectClass: organizationalPerson')
ldifLines.append('objectClass: inetOrgPerson')
ldifLines.append('givenName: [A=RNDFROMFILE(%s/ldap/lib/names/Firstname.txt)]' % LDCLT_DIR)
ldifLines.append('sn: [B=RNDFROMFILE(%s/ldap/lib/names/Lastname.txt)]' % LDCLT_DIR)
ldifLines.append('employeeNumber: [C]')
ldifLines.append('cn: [A] [B] [C]')
ldifLines.append('mail: user.[C]@example.com')
ldifLines.append('initials: [A][B]')
ldifLines.append('homePhone: 0[RNDN(1;5;1)] [RNDN(0;99;2)] [RNDN(0;99;2)] [RNDN(0;99;2)] [RNDN(0;99;2)]')
ldifLines.append('mobile: 06 [RNDN(0;99;2)] [RNDN(0;99;2)] [RNDN(0;99;2)] [RNDN(0;99;2)]')
ldifLines.append('street: [D=RNDFROMFILE(%s/ldap/lib/names/Firstname.txt)]' % LDCLT_DIR)
ldifLines.append('l: [E=RNDFROMFILE(%s/ldap/lib/names/Lastname.txt)]' % LDCLT_DIR)
ldifLines.append('st: [F=RNDFROMFILE(%s/ldap/lib/names/Firstname.txt)]' % LDCLT_DIR)
ldifLines.append('postalCode: [G=RNDN(0;80000;5)]')
ldifLines.append('postalAddress: [A] [B] [C][D][E], [F] [G]')
ldifLines.append('telephoneNumber: 0[RNDN(1;5;1)] [RNDN(0;99;2)] [RNDN(0;99;2)] [RNDN(0;99;2)] [RNDN(0;99;2)]')
ldifLines.append('description: This is the description for user.[C].')
</script>
<!-- Write out the make-ldif template file -->
<script>
tmpTemplateFile = '%s/tempLdcltTemplateFile' % local.temp
outfile = open(tmpTemplateFile,"w")
for line in ldifLines:
outfile.write("%s\n" % line)
outfile.close()
</script>
<script>
STAXCode=RC
STAXReason=STAXResult
</script>
<if expr="STAXCode != 0">
<sequence>
<message level="'error'">
'creation of a ldclt template failed (Code=%s,Reason=%s).' % (STAXCode,STAXReason)
</message>
</sequence>
</if>
<call function="'checktestRC'">
{ 'returncode' : STAXCode ,
'result' : STAXReason }
</call>
<call function="'copyFile'">
{ 'location' : STAXServiceMachine,
'srcfile' : tmpTemplateFile,
'destfile' : templateFile,
'remotehost' : templateLocation }
</call>
<call function="'checktestRC'">
{
'returncode' : RC ,
'result' : STAXResult
}
</call>
<return>[RC, STAXResult]</return>
</sequence>
</function>
<!-- This function parses an ldif entry -->
<function name="parseLdifEntry">
<function-prolog>
This function parses an ldif entry and returns a dictionary, e.g.:
{'dn':['o=example'],'objectclass':['top','organization'],'o':['example']}
</function-prolog>
<function-map-args>
<function-arg-def name="ldifEntry" type="required">
<function-arg-description>
Ldif entry to parse (single string).
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<sequence>
<script>
parsedEntry = {}
prevAttr = None
prevVal = None
for line in ldifEntry.splitlines():
notBlank = (len(line.strip()) != 0)
if notBlank and (not line.startswith(' ')):
# line corresponds to an attr:val
attr = line[:line.find(':')].strip().lower()
val = line[line.find(':') + 1:].lstrip()
if val.startswith(':'):
val = val[1:].lstrip()
if attr == 'objectclass':
val = val.lower()
if not (attr in parsedEntry.keys()):
# This is the first occurrence of this attr
parsedEntry[attr] = [val]
else:
# There is already some value for this attr
parsedEntry[attr].append(val)
prevAttr = attr
prevVal = val
elif notBlank:
# line corresponds to a trailing value
parsedEntry[prevAttr].remove(prevVal)
val = prevVal + line.lstrip()
parsedEntry[prevAttr].append(val)
prevVal = val
</script>
<return> parsedEntry </return>
</sequence>
</function>
<!-- This function parses several ldif entries -->
<function name="parseLdifEntries">
<function-prolog>
This function parses several ldif entries and returns a list of
dictionaries such as those produced by parseLdifEntry
</function-prolog>
<function-map-args>
<function-arg-def name="ldifEntries" type="required">
<function-arg-description>
Ldif entries to parse (single string).
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<sequence>
<script>
parsedEntryList = []
ldifEntryList = []
ldifEntryLines = []
ldifEntry = None
for line in ldifEntries.splitlines():
notBlank = (len(line.strip()) != 0)
if notBlank:
ldifEntryLines.append(line)
else:
if len(ldifEntryLines) != 0:
ldifEntry = '\n'.join(ldifEntryLines)
ldifEntryList.append(ldifEntry)
ldifEntryLines = []
if len(ldifEntryLines) != 0:
ldifEntry = '\n'.join(ldifEntryLines)
ldifEntryList.append(ldifEntry)
ldifEntryLines = []
</script>
<if expr="len(ldifEntryList) != 0">
<iterate var="entryToParse" in="ldifEntryList">
<sequence>
<call function="'parseLdifEntry'">
{ 'ldifEntry' : entryToParse }
</call>
<script>
parsedEntryList.append(STAXResult)
</script>
</sequence>
</iterate>
</if>
<return> parsedEntryList </return>
</sequence>
</function>
<!-- This function parses an ldif change -->
<function name="parseLdifChange">
<function-prolog>
This function parses an ldif change and returns a list, e.g.:
[ ['replace','l','London'], ['add','description','This is a test'] ]
</function-prolog>
<function-map-args>
<function-arg-def name="ldifChange" type="required">
<function-arg-description>
Ldif change to parse (single string).
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<sequence>
<script>
parsedChange = []
mod = []
prevAttr = None
prevVal = None
for line in ldifChange.splitlines():
notBlank = (len(line.strip()) != 0)
if notBlank and (not line.startswith(' ')) and (not line.startswith('-')):
# line corresponds to an attr:val
attr = line[:line.find(':')].strip().lower()
val = line[line.find(':') + 1:].lstrip()
if val.startswith(':'):
val = val[1:].lstrip()
if attr == 'objectclass':
val = val.lower()
if (prevVal != None) and (attr == prevVal.lower()):
# attr represents indeed an attribute type, so we may assume the
# mod already has [mod_type,attr_type]
mod.append(val)
else:
# attr represents the mod_type, and val the attr_type
mod.append(attr)
mod.append(val.lower())
prevAttr = attr
prevVal = val
elif notBlank and line.startswith(' '):
# line corresponds to a trailing value
mod.remove(prevVal)
val = prevVal + line.lstrip()
mod.append(val)
prevVal = val
else:
# line is empty or line starts with '-'; this means that
# the mod is complete, so we can add it to the parsedChange list
parsedChange.append(mod)
mod = []
if len(mod) != 0:
# add the trailing mod to the parsedChange list
parsedChange.append(mod)
</script>
<return> parsedChange </return>
</sequence>
</function>
<!-- This function checks the content of an external changelog entry -->
<function name="checkChangelogEntry">
<function-prolog>
This function checks the content of an external changelog entry
</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="dsPath"
type="optional"
default="'%s/%s' % (DIRECTORY_INSTANCE_BIN,OPENDSNAME)">
<function-arg-description>
Pathname to installation root
</function-arg-description>
<function-arg-property name="type" value="filepath"/>
</function-arg-def>
<function-arg-def name="changelogEntry" type="required">
<function-arg-description>
External changelog entry (as an output of parseLdifEntry)
</function-arg-description>
<function-arg-property name="type" value="dictionary"/>
</function-arg-def>
<function-arg-def name="targetDN" type="required">
<function-arg-description>
DN of the target entry for the change
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="changeType" type="required">
<function-arg-description>
Change type (e.g. add, delete, modify)
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="changeTime"
type="optional"
default="None">
<function-arg-description>
Change time
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="changeNumber"
type="optional"
default="None">
<function-arg-description>
Changenumber (only for changelog draft-compatible mode)
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="replicationCSN"
type="optional"
default="None">
<function-arg-description>
Replication CSN
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="targetEntryUUID"
type="optional"
default="None">
<function-arg-description>
Target entry uuid
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="replicaIdentifier"
type="optional"
default="None">
<function-arg-description>
Replica Identifier
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="newRDN"
type="optional"
default="None">
<function-arg-description>
NewRDN
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="deleteOldRDN"
type="optional"
default="None">
<function-arg-description>
DeleteOldRDN
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="newSuperior"
type="optional"
default="None">
<function-arg-description>
NewSuperior
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="changes"
type="optional"
default="None">
<function-arg-description>
Changes. If changetype == add, changes should be a map, e.g.:
{'dn':['o=example'],'objectclass':['top','organization'],'o':['example']}
If changetype == modify, changes should be a list, e.g.:
[ ['replace','l','London'], ['add','description','This is a test'] ]
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="includeAttrs"
type="optional"
default="None">
<function-arg-description>
Map containing the attributes configured as include-attributes along
with their values, e.g.:
{ 'description':['desc1', desc2'], 'telephonenumber':['11-22-33']}
</function-arg-description>
<function-arg-property name="type" value="map"/>
</function-arg-def>
<function-arg-def name="expectMissingIncAttrs"
type="optional"
default="[]">
<function-arg-description>
List of the attributes in includeAttrs expected NOT TO BE FOUND in the
changelog entry.
</function-arg-description>
<function-arg-property name="type" value="list"/>
</function-arg-def>
<function-arg-def name="knownIssue" type="optional" default="None">
<function-arg-description>
Known issue. Corresponds to an issue number.
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
myLocation = location
myPath = dsPath
myKnownIssue = knownIssue
# Mandatory attributes in a changeLogEntry
ecl_DN = changelogEntry['dn'][0]
ecl_targetDN = changelogEntry['targetdn'][0]
ecl_changeType = changelogEntry['changetype'][0]
ecl_changeTime = changelogEntry['changetime'][0]
ecl_changeNumber = changelogEntry['changenumber'][0]
# Optional attributes
ecl_replicationCSN = None
ecl_replicaIdentifier = None
ecl_targetEntryUUID = None
ecl_newRDN = None
ecl_deleteOldRDN = None
ecl_newSuperior = None
ecl_changes = None
ecl_includedAttributes = None
if 'replicationcsn' in changelogEntry.keys():
ecl_replicationCSN = changelogEntry['replicationcsn'][0]
if 'replicaidentifier' in changelogEntry.keys():
ecl_replicaIdentifier = changelogEntry['replicaidentifier'][0]
if 'targetentryuuid' in changelogEntry.keys():
ecl_targetEntryUUID = changelogEntry['targetentryuuid'][0]
if 'newrdn' in changelogEntry.keys():
ecl_newRDN = changelogEntry['newrdn'][0]
if 'deleteoldrdn' in changelogEntry.keys():
ecl_deleteOldRDN = changelogEntry['deleteoldrdn'][0]
if 'newsuperior' in changelogEntry.keys():
ecl_newSuperior = changelogEntry['newsuperior'][0]
if 'changes' in changelogEntry.keys():
ecl_changes = changelogEntry['changes'][0]
if 'includedattributes' in changelogEntry.keys():
ecl_includedAttributes = changelogEntry['includedattributes'][0]
</script>
<message>
'checkChangelogEntry: Checking changelog entry %s against expected \
values' % ecl_DN
</message>
<message>
'checkChangelogEntry: Checking targetDN'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_targetDN,
'expectedString' : targetDN,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
}
</call>
<message>
'checkChangelogEntry: Checking changeType'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_changeType,
'expectedString' : changeType,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
}
</call>
<if expr="changeTime">
<sequence>
<message>
'checkChangelogEntry: Checking changeTime'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_changeTime,
'expectedString' : changeTime,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
}
</call>
</sequence>
</if>
<if expr="changeNumber">
<sequence>
<message>
'checkChangelogEntry: Checking changeNumber'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_changeNumber,
'expectedString' : changeNumber,
'searchType' : 'exact-case-sensitive',
'knownIssue' : myKnownIssue
}
</call>
</sequence>
</if>
<if expr="replicationCSN">
<if expr="ecl_replicationCSN">
<sequence>
<message>
'checkChangelogEntry: Checking replicationCSN'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_replicationCSN,
'expectedString' : replicationCSN,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
}
</call>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'No replicationCSN could be found in the changelog entry'
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</if>
<if expr="replicaIdentifier">
<if expr="ecl_replicaIdentifier">
<sequence>
<message>
'checkChangelogEntry: Checking replicaIdentifier'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_replicaIdentifier,
'expectedString' : replicaIdentifier,
'searchType' : 'exact-case-sensitive',
'knownIssue' : myKnownIssue
}
</call>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'No replicaIdentifier could be found in the changelog entry'
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</if>
<if expr="targetEntryUUID">
<if expr="ecl_targetEntryUUID">
<sequence>
<message>
'checkChangelogEntry: Checking targetEntryUUID'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_targetEntryUUID,
'expectedString' : targetEntryUUID,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
}
</call>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'No targetEntryUUID could be found in the changelog entry'
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</if>
<if expr="newRDN">
<if expr="ecl_newRDN">
<sequence>
<message>
'checkChangelogEntry: Checking newRDN'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_newRDN,
'expectedString' : newRDN,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
}
</call>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'No newRDN could be found in the changelog entry'
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</if>
<if expr="deleteOldRDN">
<if expr="ecl_deleteOldRDN">
<sequence>
<message>
'checkChangelogEntry: Checking deleteOldRDN'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_deleteOldRDN,
'expectedString' : deleteOldRDN,
'searchType' : 'exact-case-sensitive',
'knownIssue' : myKnownIssue
}
</call>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'No deleteOldRDN could be found in the changelog entry'
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</if>
<if expr="newSuperior">
<if expr="ecl_newSuperior">
<sequence>
<message>
'checkChangelogEntry: Checking newSuperior'
</message>
<call function="'searchString'">
{ 'returnString' : ecl_newSuperior,
'expectedString' : newSuperior,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
}
</call>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'No newSuperior could be found in the changelog entry'
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</if>
<if expr="changes">
<if expr="ecl_changes">
<sequence>
<!-- Decode the changes that are encoded in base64 -->
<message>
'checkChangelogEntry: Decode external changelog entry changes'
</message>
<call function="'Base64WithScript'">
{ 'location' : myLocation,
'dsPath' : myPath,
'subcommand' : 'decode',
'encodedData' : ecl_changes
}
</call>
<!-- STAXResult is not always a list-->
<script>
try:
decodeRC, decodedChanges = STAXResult[0]
except AttributeError, details:
decodedChanges = 'AttributeError: can not parse STAXResult %s' \
% details
decodeRC = '1'
</script>
<message>
'checkChangelogEntry: Decoded changes:\n%s' % decodedChanges
</message>
<message>
'checkChangelogEntry: Checking changes'
</message>
<if expr="decodeRC == 0 and changeType == 'add'">
<!-- If changetype:add, the changes look like a sequence of
! attribute:value, so we may parse them as an ldif entry -->
<sequence>
<call function="'parseLdifEntry'">
{ 'ldifEntry' : decodedChanges }
</call>
<script>
ecl_changesMap = STAXResult
</script>
<message>
'Parsed changelog entry changes: \n%s' % ecl_changesMap
</message>
<iterate var="attr" in="changes.keys()">
<sequence>
<script>
valueList = changes[attr]
ecl_valueList = None
if attr in ecl_changesMap.keys():
ecl_valueList = ecl_changesMap[attr]
ecl_valueList.sort()
valueList.sort()
</script>
<if expr="ecl_valueList != None">
<sequence>
<message>
'checkChangelogEntry: Checking changes: %s' % attr
</message>
<if expr="valueList == ecl_valueList">
<message>
'Found expected values in changes: %s' % valueList
</message>
<else>
<sequence>
<message log="1" level="'Error'">
'Expected values %s could not be found in %s' \
% (valueList, ecl_valueList)
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'No %s could be found in the changes' % attr
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</sequence>
</iterate>
</sequence>
<elseif expr="decodeRC == 0">
<!-- If changetype:modify, the changes look like a sequence of
! mod_type:attribute
! attribute:value
! so we need to treat them differently -->
<sequence>
<call function="'parseLdifChange'">
{ 'ldifChange' : decodedChanges }
</call>
<script>
ecl_changesList = STAXResult
</script>
<message>
'Parsed changelog entry changes: \n%s' % ecl_changesList
</message>
<iterate var="mod" in="changes">
<sequence>
<script>
mod_type = mod[0]
mod_attr = mod[1]
mod_val = None
if len(mod) == 3:
mod_val = mod[2]
</script>
<message>
'checkChangelogEntry: Checking changes: %s' % mod
</message>
<if expr="mod in ecl_changesList">
<message>
'Found expected change:\n %s: %s\n %s: %s\n' \
% (mod_type, mod_attr, mod_attr, mod_val)
</message>
<else>
<sequence>
<message log="1" level="'Error'">
'Expected change %s could not be found in %s'\
% (mod, ecl_changesList)
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</sequence>
</iterate>
</sequence>
</elseif>
</if>
</sequence>
<else>
<sequence>
<message log="1" level="'Error'">
'No changes could be found in the changelog entry'
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</if>
<if expr="includeAttrs">
<if expr="ecl_includedAttributes">
<sequence>
<!-- Decode the changes that are encoded in base64 -->
<message>
'checkChangelogEntry: Decode external changelog included attributes'
</message>
<call function="'Base64WithScript'">
{ 'location' : myLocation,
'dsPath' : myPath,
'subcommand' : 'decode',
'encodedData' : ecl_includedAttributes
}
</call>
<!-- STAXResult is not always a list-->
<script>
try:
decodeRC, decodedChanges = STAXResult[0]
except AttributeError, details:
decodedChanges = 'AttributeError: can not parse STAXResult %s' \
% details
decodeRC = '1'
</script>
<message>
'checkChangelogEntry: Decoded changes:\n%s' % decodedChanges
</message>
<if expr="decodeRC == 0">
<sequence>
<call function="'parseLdifEntry'">
{ 'ldifEntry' : decodedChanges }
</call>
<script>
ecl_includeAttrsMap = STAXResult
</script>
<message>
'Parsed changelog entry changes: \n%s' % ecl_includeAttrsMap
</message>
</sequence>
</if>
<iterate var="attr" in="includeAttrs.keys()">
<sequence>
<message>'Matching included attribute %s.' % attr</message>
<script>
targetAttr = attr
valueList = includeAttrs[attr]
ecl_valueList = None
if targetAttr in ecl_includeAttrsMap.keys():
ecl_valueList = ecl_includeAttrsMap[targetAttr]
ecl_valueList.sort()
valueList.sort()
</script>
<if expr="ecl_valueList != None">
<!-- Some value found for (include-attribute) targetAttr -->
<if expr="attr in expectMissingIncAttrs">
<sequence>
<message log="1" level="'Error'">
'Found values %s for %s while NONE expected.' \
% (valueList, targetAttr)
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
<else>
<if expr="valueList == ecl_valueList">
<message>
'Found expected values for include attribute in %s: \
%s' % (targetAttr, valueList)
</message>
<else>
<sequence>
<message log="1" level="'Error'">
'Expected values %s could not be found in %s: %s' \
% (valueList, targetAttr, ecl_valueList)
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</else>
</if>
<else>
<!-- No (include-attribute) targetAttr found -->
<if expr="attr in expectMissingIncAttrs">
<message>
'No %s could be found in the changelog entry, AS EXPECTED' \
% targetAttr
</message>
<else>
<sequence>
<message log="1" level="'Error'">
'No %s could be found in the changelog entry' % targetAttr
</message>
<if expr="myKnownIssue == None">
<call function="'testFailed'"/>
<else>
<call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
</call>
</else>
</if>
</sequence>
</else>
</if>
</else>
</if>
</sequence>
</iterate>
</sequence>
</if>
</if>
</sequence>
</function>
<!-- PSEARCH -->
<function name="psearch" scope="local">
<function-prolog>
This function performs a psearch request
</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="dsInstanceHost"
type="optional"
default="STAF_REMOTE_HOSTNAME">
<function-arg-description>
Target directory server hostname or IP address
</function-arg-description>
<function-arg-property name="type" value="hostname" />
</function-arg-def>
<function-arg-def name="dsInstancePort" type="required">
<function-arg-description>
Directory server port number
</function-arg-description>
<function-arg-property name="type" value="Port number"/>
</function-arg-def>
<function-arg-def name="dsInstanceDn" type="required">
<function-arg-description>
Directory server dn
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="dsInstancePswd" type="required">
<function-arg-description>
Bind password
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="dsBaseDn" type="required">
<function-arg-description>
Specify the base DN for which to perform the verification
</function-arg-description>
<function-arg-property name="type" value="dn"/>
</function-arg-def>
<function-arg-def name="nbrOfThread" type="optional" default="1">
<function-arg-description>
Specify the number of threads to use
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="outputFile" type="optional">
<function-arg-description>
Specify the output file path
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="operation" type="optional">
<function-arg-description>
Specify the opeation type
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
<function-arg-def name="display" type="optional">
<function-arg-description>
Optional do not perform any display in terminal
</function-arg-description>
<function-arg-property name="type" value="boolean"/>
</function-arg-def>
<function-arg-def name="ldif" type="optional">
<function-arg-description>
Optional output file in ldif format
</function-arg-description>
<function-arg-property name="type" value="boolean"/>
</function-arg-def>
<function-arg-def name="expectedRC" type="optional" default="0">
<function-arg-description>
Expected return code value. Default value is 0
Wildcard 'noCheck' to not check the RC
</function-arg-description>
<function-arg-property name="type" value="integer"/>
</function-arg-def>
</function-map-args>
<sequence>
<script>
if is_windows_platform(location):
jstaf_jarfile='%s\\bin\\JSTAF.jar' % REMOTE_STAF_ROOT
else:
jstaf_jarfile='%s/lib/JSTAF.jar' % REMOTE_STAF_ROOT
</script>
<!-- Build the command -->
<script>
foldersToCreate = []
STAFCmdParamsList=[]
STAFCmdParams=''
if dsInstanceHost:
STAFCmdParamsList.append('-h %s' % dsInstanceHost)
if dsInstancePort:
STAFCmdParamsList.append('-p %s' % dsInstancePort)
if dsInstanceDn:
STAFCmdParamsList.append('-D "%s"' % dsInstanceDn)
if dsBaseDn:
STAFCmdParamsList.append('-b "%s"' % dsBaseDn)
if dsInstancePswd:
STAFCmdParamsList.append('-w "%s"' % dsInstancePswd)
if display:
STAFCmdParamsList.append('-s')
if ldif:
STAFCmdParamsList.append('-l')
if outputFile:
foldersToCreate.append(os.path.dirname(outputFile))
STAFCmdParamsList.append('-f %s' % outputFile)
if nbrOfThread:
STAFCmdParamsList.append('-n %s' % nbrOfThread)
if operation:
STAFCmdParamsList.append('-o %s' % operation)
STAFCmdParams=' '.join(STAFCmdParamsList)
STAFCmd='PSearch'
if is_windows_platform(location):
separator=';'
else:
separator=':'
ldapjdkPath='%s/ldapjdk' % remote.java
ldapjdk_jarfile='%s/ldapjdk.jar' % ldapjdkPath
cp = 'CLASSPATH=%s%s%s%s.' \
% (ldapjdk_jarfile,separator,jstaf_jarfile,separator)
env = ['%s' % cp]
</script>
<call function="'createMultiFolders'">
{ 'location' : location,
'folderslist' : foldersToCreate
}
</call>
<message>
'%s %s' % (STAFCmd, STAFCmdParams)
</message>
<call function="'runCommand'" >
{
'name' : 'PSearch' ,
'command' : '%s/bin/java' % JAVA_HOME ,
'arguments' : '%s %s' % (STAFCmd, STAFCmdParams) ,
'location' : location ,
'path' : '%s/ldapjdk' % remote.java ,
'envCmd' : env ,
'expectedRC' : expectedRC
}
</call>
<return>
STAXResult
</return>
</sequence>
</function>
<!-- TestStep -->
<function name="testStep">
<function-prolog>
This function print out a test step.
</function-prolog>
<function-map-args>
<function-arg-def name="stepMessage" type="required">
<function-arg-description>
test step message to display
</function-arg-description>
</function-arg-def>
</function-map-args>
<sequence>
<script>
try:
stepNumber=stepNumber
except NameError:
stepNumber=1
</script>
<message>'*** Step%s: %s' % (stepNumber,stepMessage)</message>
<script>
stepNumber += 1
</script>
</sequence>
</function>
<!-- Run the test suites -->
<function name="testSuite_Run">
<function-prolog>
This function runs the test suites
</function-prolog>
<function-map-args>
<function-arg-def name="suites" type="required">
<function-arg-description>
List of test suites to run
</function-arg-description>
<function-arg-property name="type" value="list"/>
</function-arg-def>
<function-arg-def name="group" type="required">
<function-arg-description>
Name of test group
</function-arg-description>
<function-arg-property name="type" value="string"/>
</function-arg-def>
</function-map-args>
<sequence>
<iterate var="_suite" in="suites" >
<try>
<sequence>
<import machine="STAF_LOCAL_HOSTNAME"
file="'%s/testcases/%s/%s/%s.xml' %
(TESTS_DIR,group,_suite,_suite)"/>
<call function="'%s_%s'% (group,_suite)" />
</sequence>
<catch exception="'STAFException.TestSuite.SetupException'">
<message log="1" level="'fatal'">
'Setup of test suite %s failed.' % _suite
</message>
</catch>
<catch exception="'STAFException.TestSuite.MainException'">
<message log="1" level="'fatal'">
'Main part of test suite %s failed.' % _suite
</message>
</catch>
<catch exception="'STAFException.TestSuite.CleanupException'">
<message log="1" level="'fatal'">
'Cleanup of test suite %s failed.' % _suite
</message>
</catch>
</try>
</iterate>
</sequence>
</function>
</stax>