<?
xml version="1.0" encoding="UTF-8" standalone="no"?>
! 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 ! You can obtain a copy of the license at ! 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 ! 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] ! Copyright 2007-2010 Sun Microsystems, Inc. ! Portions Copyright 2011 ForgeRock AS. <
function name="checkRC">
This function checks a return code against an expected return code
<
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 name="result" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="integer"/>
<
function-
arg-
def name="expected" type="optional" default="0">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="integer"/>
<
if expr="expected == 'noCheck'">
<
if expr="returncode == expected">
'RC=%s, Result=Ok' % (returncode)
'RC=%s, Result=%s' % (returncode,result)
<
message log="1" level="'Error'">
'RC=%s, Expected %s, Result=%s' % (returncode,expected,result)
<
function name="checktestRC">
This function checks the return code against an expected return code for a testcase
<
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 name="result" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="integer"/>
<
function-
arg-
def name="expected" type="optional" default="0">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="integer"/>
<
function-
arg-
def name="issue" type="optional" default="None">
<
function-
arg-
description>
Issue id. Corresponds to an issue number.
</
function-
arg-
description>
<
if expr="expected == 'noCheck'">
<
if expr="returncode == expected">
<
if expr="STAXCurrentTestcase != None">
<
tcstatus result="'pass'"/>
<
if expr="VERBOSE_MODE == 'true'">
'SUCCESS: RC=%s, Expected %s, Result=%s' % (returncode,expected,result)
'SUCCESS: RC=%s, Expected %s' % (returncode,expected)
<
if expr="STAXCurrentTestcase != None">
<
if expr="issue == None">
<
tcstatus result="'fail'"/>
<
call function="'setKnownIssue'">
<
message log="1" level="'Error'">
'ERROR : RC=%s, Expected %s, Result=%s' % (returncode,expected,result)
<
function name="setKnownIssue">
This function set the known issue flag and maintains list of known issues
<
function-
arg-
def name="issueId" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
call function="'GetVar'">
'location' : STAF_REMOTE_HOSTNAME,
'variable' : 'issuesList'
issuesList=eval(STAFResult)
if issueId.__class__ is PyList:
if int(issue) not in issuesList:
if int(issueId) not in issuesList:
print 'Issues list undefined. Unable to add issue %s' % issueId
<
message log="1" level="'Error'">
'ERROR: HIT **** Known Issue (%s) ****' % issueId
<
tcstatus result="'fail'">
'KnownIssue: %s' % issuesList
<
call function="'SetVar'">
'location' : STAF_REMOTE_HOSTNAME,
'variable' : 'issuesList=%s' % issuesList
<!-- Set the test status to PASS --> <
function name="testPassed">
This function set the status of the tests: PASS
<
message>'Set test status to PASS'</
message>
<
tcstatus result="'pass'"/>
<!-- Set the test status to FAIL --> <
function name="testFailed">
This function set the status of the tests: FAIL
<
message>'Set test status to FAIL'</
message>
<
tcstatus result="'fail'"/>
<
function name="searchString" scope="local">
This function search for a string in the return string of a testcase
Return 0 if the string is found, 1 otherwise
<
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 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 name="searchType" <
function-
arg-
description>
the type of the search: substring, exact-case-insensitive or
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
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 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"/>
<!-- Check that returnString is really a string or unicode --> <
if expr='returnString.__class__ is not PyString and returnString.__class__ is not PyUnicode'>
<
message log="1" level="'Error'">
'Invalid returnString type (%s), requires str or unicode.' \
'The returnString is ("%s")' % returnString
myReason = 'Python error'
<
tcstatus result="'fail'"/>
<
return>[myRC, myReason]</
return>
if searchType == 'substring':
searchResult = (
re.search(searchre, returnString) != None)
elif searchType == 'exact-case-sensitive':
searchResult = (expectedString == returnString)
elif searchType == 'exact-case-insensitive':
<!-- Search for the expectedString --> 'Search type: %s Found substring, %s, in the return string' \
% (searchType, expectedString)
myReason = 'String found'
'Search type: %s Did not find substring, %s, in the return \
string, %s' % (searchType, expectedString, returnString)
myReason = 'String not found'
<!-- Manage expectedRC and knownIssue --> <
if expr="expectedRC != 'noCheck'">
<
if expr="myRC == expectedRC">
'SUCCESS: searchString successful'
<
tcstatus result="'pass'"/>
<
message log="1" level="'Error'">
'ERROR: searchString fail'
<
if expr="knownIssue == None">
<
tcstatus result="'fail'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : knownIssue }
<
return>[myRC, myReason]</
return>
<!-- DEPRECATED, use searchString function --> <
function name="checktestString">
This function checks the return string against an expected return substring for a testcase
<
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 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 name="issue" type="optional" default="None">
<
function-
arg-
description>
Known issue. Corresponds to an issue number.
</
function-
arg-
description>
<!-- Check that returnString is really a string --> <
if expr='returnString.__class__ is not PyString and returnString.__class__ is not PyUnicode'>
<
message log="1" level="'Error'">
'ERROR : Invalid returnString type (%s), requires str or unicode.' \
<
tcstatus result="'fail'"/>
<
if expr='re.search(searchre, returnString) != None'>
<
tcstatus result="'pass'"/>
'SUCCESS : Found substring, %s, in the return string' % (expectedString)
<
if expr="issue == None">
<
tcstatus result="'fail'"/>
<
call function="'setKnownIssue'">
<
message log="1" level="'Error'">
'ERROR : Did not find substring, %s, in the return string, %s' % (expectedString, returnString)
<!-- DEPRECATED, use searchString function --> <
function name="checktestStringNotPresent">
This function checks the return string against an expected return substring that should not be present for a testcase
<
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 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 name="issue" type="optional" default="None">
<
function-
arg-
description>
Known issue. Corresponds to an issue number.
</
function-
arg-
description>
<
if expr='re.search(searchre, returnString) == None'>
<
tcstatus result="'pass'"/>
'Did Not Find substring, %s, in the return string' % (testString)
<
if expr="issue == None">
<
tcstatus result="'fail'"/>
<
call function="'setKnownIssue'">
<
message log="1" level="'Error'">
'Found substring, %s, in the return string, %s' % (testString, returnString)
<!-- DEPRECATED, use searchString function --> <
function name="searchStringForSubstring">
This function simply searches a string for a substring
<
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 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 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"/>
<!-- Until all the test cases are refactored to use the expectedResult param, we need this if-else conditional. --> <
if expr="expectedResult == '2'">
<
if expr='re.search(searchre, returnString) == None'>
<
script>returnCode='0'</
script>
'Did Not Find substring, %s, in the return string' % (testString)
<
script>returnCode='1'</
script>
'Found substring, %s, in the return string' % (testString)
<
return>returnCode</
return>
<
if expr='re.search(searchre, returnString) == None'>
<
script>returnCode='0'</
script>
<
if expr="expectedResult == '0'">
<
tcstatus result="'pass'"/>
'SUCCESS : Did Not Find substring, %s, in the return string' % (testString)
<
tcstatus result="'fail'"/>
<
message log="1" level="'Error'">
'ERROR : Did Not Find substring, %s, in the return string' % (testString)
<
script>returnCode='1'</
script>
<
if expr="expectedResult == '1'">
<
tcstatus result="'pass'"/>
'SUCCESS : Found substring, %s, in the return string' % (testString)
<
tcstatus result="'fail'"/>
<
message log="1" level="'Error'">
'ERROR : Found substring, %s, in the return string' % (testString)
<
return>returnCode</
return>
<
function name="isAlive" scope="local">
Checks that the ldap server is running
<
function-
arg-
def name="location" type="optional" default="STAF_REMOTE_HOSTNAME">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
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 name="noOfLoops" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="integer"/>
<
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 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 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 name="dsInstanceDn" type="optional" default="DIRECTORY_INSTANCE_DN">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="DN"/>
<
function-
arg-
def name="dsInstancePswd" type="optional" default="DIRECTORY_INSTANCE_PSWD">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
loop from="1" to="noOfLoops" while="ldapRC != 0">
<
call function="'SearchObject'">
{ 'location' : mylocation,
'dsInstanceHost' : myhost ,
'dsInstancePort' : myport ,
'dsInstancePswd' : mypswd ,
'dsBaseDN' : 'cn=config' ,
'dsFilter' : 'objectclass=*' ,
'LOOP %s => RC=%s' % (myLoop, ldapRC)
<
call function="'Sleep'">
{ 'sleepForMilliSeconds' : noOfMilliSeconds }
<
call function="'checktestRC'">
{ 'returncode' : ldapRC ,
'result' : 'Check is alive' }
<
function name="isStopped" scope="local">
Checks that the ldap server is stopped
<
function-
arg-
def name="location" default="STAF_REMOTE_HOSTNAME">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="dsPath" 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 name="noOfLoops" <
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="integer"/>
<
function-
arg-
def name="noOfMilliSeconds" <
function-
arg-
description>
Number of seconds to wait between iterations
</
function-
arg-
description>
<
function-
arg-
property name="type" value="seconds"/>
<
script>checkRC=9999</
script>
<
loop from="1" to="noOfLoops" var="loop" while="checkRC != 48">
<
call function="'GetEntry'">
<
message>'LOOP %s => RC %s' % (loop,checkRC)</
message>
<
message>'Sleep for %sms' % noOfMilliSeconds</
message>
<
call function="'Sleep'">
{ 'sleepForMilliSeconds' : noOfMilliSeconds }
<
if expr="checkRC != 48">
'Server is not stopped after %sms \
% (noOfLoops*noOfMilliSeconds,dsPath,location)
Sleep for number of milliseconds
<
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"/>
<
stafcmd name="'STAF Command: Delay'">
<
location>STAXServiceMachine</
location>
<
service>'delay'</
service>
'delay %i' % int(sleepForMilliSeconds)
<
call function="'checkRC'">
<
function name="getOSvariables">
<
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"/>
<
stafcmd name="'STAF Command: Get OS Name'">
<
location>'%s' % hostname</
location>
'OS Name= %s' % STAFResult
<
return>STAFResult</
return>
<
function name="testCase_StartBanner">
Pretty prints a banner at the start of a test.
<
message level="'start'">'testcase: %s' % STAXCurrentTestcase</
message>
<
message>'****************************************************'</
message>
<
message>'*** STARTING TEST CASE %s.' % STAXCurrentTestcase</
message>
<
function name="testCase_EndBanner">
Pretty prints a banner at the end of a test.
<
message>'*** ENDING TEST CASE %s.' % STAXCurrentTestcase</
message>
<
message>'****************************************************'</
message>
<
message level="'stop'">'testcase: %s' % STAXCurrentTestcase</
message>
<
function name="testCase_Preamble">
Performs all the preoperations for a test case
testcaseStartTime=strftime("%Y%m%d-%H:%M:%S",localtime())
for logType in ['errors','access']:
logfile=open('%s/%
s/
logs/%s' % (DIRECTORY_INSTANCE_DIR,OPENDSNAME,logType),'a')
<
call function="'SetVar'">
'location' : STAF_REMOTE_HOSTNAME,
'variable' : 'issuesList=[]'
<
call function="'testCase_StartBanner'" />
<
function name="testCase_Postamble">
Performs all the post operations for a test suite
<!-- Check the SignalRaised flag --> 'A signal (%s) was raised during this test case' % SignalRaised
<
tcstatus result="'fail'"/>
<!-- Reset the SignalRaised flag --> <
call function="'GetVar'">
'location' : STAF_REMOTE_HOSTNAME,
'variable' : 'issuesList'
issuesList=eval(STAFResult)
<!-- Query the test case results --> <
call function="'queryTestcase'" />
numPass=int(STAFResult['numPasses'])
numFail=int(STAFResult['numFails'])
startTimestamp=STAFResult['startedTimestamp']
information=STAFResult['information']
_status='KNOWN ISSUES %s' % str(issuesList)
for issueID in issuesList:
if issueID not in allbugs:
<
message level="'status'">
'## Test Verdict: %s ##' % _status
<
call function="'testCase_EndBanner'" />
testcaseEndTime = strftime("%Y%m%d-%H:%M:%S",localtime())
testcaseDuration=testcaseStop-testcaseStart
shortName=get_test_name(STAXCurrentTestcase)
for issueID in issuesList:
<
call function="'queryLogs'">
{ 'location' : STAXServiceMachine,
'logname' : 'STAX_Job_%s_User' % STAXJobID,
'startfrom' : testcaseStartTime,
'endat' : testcaseEndTime }
percentage = (nbDone - nbFail - nbKnown) * 100 / nbDone
if TESTS_TYPE == 'functional-tests':
<
function name="testSuite_Preamble">
Performs all the pre operations for a test suite
<!-- Take the values from the current test path --> CurrentTestPath['group']='unknown-group'
CurrentTestPath['suite']='unknown-suite'
ThisGroupName=CurrentTestPath['group']
ThisSuiteName=CurrentTestPath['suite']
#Create testsuite element
<!-- Start time of test suite --> TestSuiteStartTime=strftime("%Y%m%d-%H:%M:%S",localtime())
'#### %s/%s suite preamble ####' % (ThisGroupName,ThisSuiteName)
<
function name="testSuite_Postamble">
Performs all the post operations for a test suite
<!-- Take the values from the current test path --> ThisSuiteName=CurrentTestPath['suite']
ThisSuiteName='unknown-suite'
ThisGroupName=CurrentTestPath['group']
ThisGroupName='unknown-group'
'#### %s/%s suite postamble ####' % (ThisGroupName,ThisSuiteName)
<!-- Start time of test suite --> TestSuiteEndTime=strftime("%Y%m%d-%H:%M:%S",localtime())
<!-- Format the test group and suite names to create folder --> FormattedTestcase=format_testcase()
TestLogDir= '%s/%s' % (
logs.tests,FormattedTestgroup)
TestLogFile='%s/%s' % (TestLogDir,FormattedTestsuite)
<
call function="'WriteLogsForTestCase'">
{ 'starttime' : TestSuiteStartTime,
'endtime' : TestSuiteEndTime,
'logFile' : TestLogFile }
del CurrentTestPath['suite']
<
function name="testGroup_Preamble">
Performs all the pre operations for a test group
<!-- Take the values from the current test path --> CurrentTestPath['group']='unknown-group'
ThisGroupName=CurrentTestPath['group']
# tempres element already exits
#Create testgroup element
<
message>'##### %s group preamble #####' % ThisGroupName</
message>
<
function name="testGroup_Postamble">
Performs all the post operations for a test group
ThisGroupName=CurrentTestPath['group']
ThisGroupName='unknown-group'
<
message>'##### %s group postamble #####' % ThisGroupName</
message>
emmaJar='%s/%
s/
lib/
emma.jar' % (DIRECTORY_INSTANCE_DIR,OPENDSNAME)
<
call function="'GetEntry'">
'location' : STAF_REMOTE_HOSTNAME ,
ecPath=
os.path.join(remoteCoveragePath,CurrentTestPath['group'])
<
call function="'listFolderByExtension'" >
'location' : STAF_REMOTE_HOSTNAME,
coverageFiles=','.join(STAXResult)
srcArgs = " -sp ".join(srcPaths)
<
call function="'runCommand'">
{ 'location' : STAF_REMOTE_HOSTNAME,
'name' : 'Generate coverage html report for test group %s' % CurrentTestPath['group'],
'arguments' : '-Xms64M -Xmx1G -cp %s emma report -r html -in %s,%s
-Dreport.html.out.file=%s -sp %s' % (emmaJar, coverageEm, coverageFiles, coverageHtml, srcArgs),
del CurrentTestPath['group']
<
function name="WriteLogsForTestCase" scope="local">
Queries the staf logs for the test case and write to file as text
<
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 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 name="logFile" type="required">
<
function-
arg-
description>
name of file to write the logs
</
function-
arg-
description>
<
function-
arg-
property name="type" value="filepath"/>
<!-- Query STAF to obtain the logs for the test case --> <
call function="'queryLogs'">
{ 'location' : STAXServiceMachine,
'logname' : 'STAX_Job_%s_User' % STAXJobID,
<!-- Write out the logs into an XML file --> <
call function="'WriteXmlLogs'">
{ 'queryresult' : STAFResult,
<!-- Transform the XML file into an HTML file --> <
call function="'WriteHtmlLogs'">
<!-- Delete the XML file --> <
call function="'deleteFile'">
{ 'location' : STAXServiceMachine,
<
function name="WriteXmlLogs" scope="local">
Process staf log query results and write them to a file
<
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 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"/>
<
message>'Creating XML log file %s' % logFile</
message>
<
call function="'createFolder'">
{ 'location' : STAXServiceMachine,
'foldername' : NewLogDir }
# Create the qa base element
# Create the base element
# Try to pass only the pretty print of the test suite name
suite=CurrentTestPath['suite'].split('.')[2].strip()
formattedTestcase = format_testcase()
<
if expr="queryresult == '[]'">
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)
<
call function="'checktestRC'">
<
iterate var="element" in="queryresult">
message=element['message']
timestamp=element['timestamp']
_message='Generated XML test case report.'
testlogfh=open('%s' % logFile,'w')
except AttributeError,details:
_message='Unable to generate XML test case report %s.' % details
_message='Unable to generate XML test case report !!!'
testlogfh=open('%s' % logFile,'r')
testlogfh=open('%s' % logFile,'w')
<
message>_message</
message>
<
function name="WriteHtmlLogs" scope="local">
Process XML file and transform that to an HTML log file
<
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 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 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"/>
<
message>'Inputting XML file %s' % xmlFile</
message>
<
message>'Transform XSL file %s' % xslFile</
message>
<
message>'Creating HTML file %s' % htmlFile</
message>
_message='Generated test case logs.'
testCaseLogs=report_generation()
_message='Unable to generate test case logs %s.' % details
_message='Unable to generate test case logs %s.' % details
_message='Unable to generate test case logs !!!'
<
message>'%s' % _message</
message>
<
function name="CheckMatches">
check the number of matching sub-string in a string
<
function-
arg-
def name="string2find" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
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 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 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 name="issue" type="optional" default="None">
<
function-
arg-
description>
Issue id. Corresponds to an issue number.
</
function-
arg-
description>
caseSensitiveInfo = '[case sensitive mode]'
if caseSensitive == False:
caseSensitiveInfo = '[case insensitive mode]'
if nbFound == nbExpected:
myMessage = 'SUCCESS : %s matches %s time(s) (expected %s) %s' % (string2find,nbFound,nbExpected,caseSensitiveInfo)
myMessage = 'ERROR : %s matches %s time(s) (expected %s) in "%s" %s' % (string2find,nbFound,nbExpected,mainString,caseSensitiveInfo)
<
tcstatus result="'pass'"/>
<
if expr="issue == None">
<
tcstatus result="'fail'"/>
<
call function="'setKnownIssue'">
<
message log="1" level="'Error'">
<
return>myRC,myMessage</
return>
<
function name="runFunction" scope="local">
<
function-
arg-
def name="functionName" type="required">
<
function-
arg-
description>
Name of the function to run
</
function-
arg-
description>
<
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' ,
. for a list, pass the arguments like this:
[ 'argumentAvalue, 1, ... ]
</
function-
arg-
description>
<
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 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 name="functionMessage" type="optional">
<
function-
arg-
description>
An optional message to display before running the function
</
function-
arg-
description>
<
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 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 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 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 name="functionCallBackArguments" type="optional">
<
function-
arg-
description>
This allows to specify arguments for the call back function
</
function-
arg-
description>
<!-- 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 _expectedRC=int(expectedRC)
<
message log="1" level="'info'" if="_displayMessage == True">
<
message log="1" level="'debug'">
'runFunction: %s: called with parameters [%s]' % (functionName,functionArguments)
<
call function="functionName">functionArguments</
call>
_functionResult = STAXResult
<!-- this section handles the optional case when we need to set the <
if expr="_doSetTCStatus == True">
<
if expr="_functionRC == _expectedRC">
<
script>_tcStatus='pass'</
script>
<
tcstatus result="_tcStatus" />
<!-- 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" />
<!-- 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'" />
<!-- 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>
<
function name="runCommand" >
A general wrapper to run a command without having to write a dedicated
<
function-
arg-
def name="command" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
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 name="arguments" type="optional" default="''">
<
function-
arg-
description>
the path where the command is to be found
</
function-
arg-
description>
<
function-
arg-
def name="envCmd" <
function-
arg-
description>
the environment variables to set. The default set here should just
</
function-
arg-
description>
<
function-
arg-
def name="location" default="STAXServiceMachine">
<
function-
arg-
description>
Which machine should the command be executed on
</
function-
arg-
description>
<
function-
arg-
def name="name" default="'Running %s' % command" <
function-
arg-
description>
The name to give the process (only matters in the STAX Monitor really)
</
function-
arg-
description>
<
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-
def name="timerDuration" <
function-
arg-
description>
The duration that the process is allowed to run
</
function-
arg-
description>
<
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 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 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 name="knownIssue" type="optional" default="None">
<
function-
arg-
description>
Known issue. Corresponds to an issue number.
</
function-
arg-
description>
<
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"/>
_id = '%s#%d' % (strftime('%Y-%m-%d %H:%M:%S',localtime()),
random.randint(0,999))
if is_windows_platform(location):
env.append('PATH=%s\\bin;C:\\Windows;C:\\Windows\\system32;%s' % (REMOTE_STAF_ROOT,path))
arguments = arguments + ' & set PROCESSRC=%ERRORLEVEL% & exit %PROCESSRC%'
if TESTS_TYPE == 'functional-tests':
'%s: Running command:\n %s %s\nlocation: %s\nenv: %s\nworkdir: %s' % (_id,command,arguments,location,env,path)
<
timer duration="timerDuration">
<!-- If 'logStderr' is True then redirect sdterr to sdtout --> <
if expr="logStderr == True">
<
location>location</
location>
<
command>command</
command>
<
stdout if="outputFile != 'None'" mode="'replace'">'%s' % outputFile</
stdout>
<
stderr mode="'stdout'"/>
<
elseif expr="inputFile != 'None'">
<
location>location</
location>
<
command>command</
command>
<
stdin>'%s' % inputFile</
stdin>
<
location>location</
location>
<
command>command</
command>
<
stdout if="outputFile != 'None'" mode="'replace'">'%s' % outputFile</
stdout>
<!-- The problem here is that STAXResult can either be a string, list or a map object --> cmdOutput=STAXResult[0][1]
if var.__class__==[].__class__:
for i in range(len(var)):
if var.__class__==''.__class__:
return 'could not evaluate the following component: %s' % var
<
if expr="expectedRC != 'noCheck'">
<
call function="'checktestRC'">
cmdResult=[[1,'Timeout']]
<
message log="1" level="'Error'">
'ERROR: COMMAND HANGING, not completed after %s' % timerDuration
<
if expr="knownIssue == None">
<
tcstatus result="'fail'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : knownIssue }
<
script>RC = cmdRC</
script>
<
function-
arg-
def name="location" default="STAF_REMOTE_HOSTNAME">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="dsPath" % (DIRECTORY_INSTANCE_DIR,OPENDSNAME)">
<
function-
arg-
description>
Pathname to installation root
</
function-
arg-
description>
<
function-
arg-
property name="type" value="pathname"/>
'Kill server running on %s at %s' % (location, dsPath)
<
call function="'runSTAFCommand'">
{ 'name' : 'Read server pid file',
if is_windows_platform(location):
<
call function="'runCommand'">
{ 'name' : 'Kill DS server',
<
message>'skip the killing of process when running with coverage to avoid data corruption'</
message>
<
return>STAXResult</
return>
<
function name="runSTAFCommand" >
A general wrapper to run a STAF command without having to write a
dedicated function for it
<
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 name="name" type="required">
<
function-
arg-
description>
The name to give the process
</
function-
arg-
description>
<
function-
arg-
def name="service" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
def name="request" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
def name="arguments" type="optional" default="''">
<
function-
arg-
description>
the arguments for the service request
</
function-
arg-
description>
_id = '%s#%d' % (strftime('%Y-%m-%d %H:%M:%S',localtime()),
random.randint(0,99999))
'%s: Running STAF command:\n %s %s %s\nlocation: %s\n' % (_id,service,request,arguments,location)
<
block name="'%s:Wrapper for %s' % (_id,name)">
<
stafcmd name="'STAF Command: %s' % name">
<
location>'%s' % location</
location>
<
service>service</
service>
'%s %s' % (request,arguments)
'%s: STAF Command returned:\n%s' % (_id,STAFResult)
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-
arg-
def name="location" default="STAF_REMOTE_HOSTNAME">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="filename" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="pathname"/>
<
function-
arg-
def name="testString" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
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>
'Search for string \"%s\" in file %s on host %s' % \
(testString, filename, location)
<
call function="'getFile'">
# getFile returns: STAXResult = [cmdRC, cmdResult]
filecontent = STAXResult[1]
if (expectedRC == 'noCheck'):
# don't care about expected result
# expect testString to be present in filecontent
# expect testString not to be present in filecontent
<
call function="'searchStringForSubstring'">
'testString' : testString,
'returnString' : filecontent,
'expectedResult' : myExpectedResult
<
return>STAXResult</
return>
<
function name="compareFile">
This function compares two files.
Print the differences if the comparison failed.
<
function-
arg-
def name="location" default="STAXServiceMachine">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="remotehost" default="STAF_REMOTE_HOSTNAME">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="dsPath" 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 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 name="outputPath" type="optional">
<
function-
arg-
description>
path containing outputFile
</
function-
arg-
description>
<
function-
arg-
property name="type" value="filepath"/>
<
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 name="refPath" type="optional">
<
function-
arg-
description>
reference path containing refFile
</
function-
arg-
description>
<
function-
arg-
property name="type" value="filepath"/>
<
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 name="diffPath" type="optional">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="filepath"/>
<
function-
arg-
def name="knownIssue" type="optional" default="None">
<
function-
arg-
description>
Known issue. Corresponds to an issue number.
</
function-
arg-
description>
ThisGroupName = CurrentTestPath['group']
ThisGroupName = 'unknown-group'
FormattedTestcase = format_testcase()
outputPath = '%s/..' % (dsPath)
tmpName =
re.sub(regexp, '', outputFile)
refFile = '%
s.ref' % tmpName
refPath = '%s/%s' % (
local.data,FormattedTestgroup)
tmpName =
re.sub(regexp, '', outputFile)
diffFile = '%
s.diff' % tmpName
diffPath = '%
s/
diffs' % (diffPath)
<!-- Check if 'diffPath' is already created --> <
call function="'GetEntry'">
<!-- If 'diffPath' is not already created then create it --> 'Create folder %s' % diffPath
<
call function="'createFolder'">
'location' : cflocation ,
'Copy file %s/%s (on %s) to %s/%s (on %s)' % \
(outputPath, outputFile, cfremotehost, diffPath, outputFile, cflocation)
<
call function="'copyFile'">
'location' : cfremotehost ,
'srcfile' : '%s/%s' % (outputPath, outputFile) ,
'destfile' : '%s/%s' % (diffPath, outputFile) ,
'remotehost' : cflocation
'Copy file %s/%s (on %s) to %s/%s (on %s)' % \
(refPath, refFile, cflocation, diffPath, refFile, cflocation)
<
call function="'copyFile'">
'location' : cflocation ,
'srcfile' : '%s/%s' % (refPath, refFile) ,
'destfile' : '%s/%s' % (diffPath, refFile) ,
'remotehost' : cflocation
<!-- If the copy of 'outputFile' and 'refFile' succeed then compare these files --> <
if expr="outputRC == 0 and refRC == 0">
'Compare file %s/%s to %s/%s on %s' % \
(diffPath, outputFile, diffPath, refFile, cflocation)
CompareFile = compare_file('%s/%s' % (diffPath, outputFile),
'%s/%s' % (diffPath, refFile),
'%s/%s' % (diffPath, diffFile))
<
tcstatus result="'pass'"/>
'SUCCESS : No differences were found between %s and %s' % \
<
if expr="knownIssue == None">
<
tcstatus result="'fail'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : knownIssue }
'ERROR : Differences were found between %s and %s\n%s' % \
(outputFile, refFile, diff)
'ERROR : Diff file is here: %s/%s' % (diffPath, diffFile)
<
tcstatus result="'fail'"/>
'ERROR : Error during file comparision'
<
function name="compileJava" scope="local">
This function compile java files.
<
function-
arg-
def name="location" default="STAXServiceMachine">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
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 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 name="classpath" type="optional">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
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>
<!-- Build the command --> if is_windows_platform(location):
cp = 'CLASSPATH=%s%s.' % (classpath, separator)
if location == STAXServiceMachine:
env = ['JAVA_HOME=%s' % JAVA_HOME, '%s' % cp]
cmdOptions = '-d %s' % destfolder
<
call function="'listFolderByExtension'" >
'foldername' : foldername ,
<
if expr="cmdResult != 'Folder does not exist.'">
<
call function="'runCommand'" >
'name' : 'Compile Java files' ,
'arguments' : '-target 1.6 %s %s' % (cmdOptions,list) ,
'expectedRC' : expectedRC
<
tcstatus result="'fail'"></
tcstatus>
<
function name="createJar" scope="local">
This function create a jar file.
<
function-
arg-
def name="location" default="STAXServiceMachine">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
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 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 name="pathfolder" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="filepath"/>
<
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 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>
<!-- Build the command --> if location == STAXServiceMachine:
cmd = '%
s/
bin/
jar' % LOCAL_JAVA_HOME
cmdOptions = 'cmf %s' % manifestpath
<!-- Check if the classfolder exists --> <
call function="'GetEntry'">
'entry' : '%s/%s' % (pathfolder,entrypoint) ,
<
call function="'runCommand'" >
'name' : 'Create Jar file' ,
'arguments' : '%s %s %s' % (cmdOptions,jarname,entrypoint) ,
'expectedRC' : expectedRC
<
tcstatus result="'fail'"></
tcstatus>
<
function name="getFreePort" scope="local">
Returns the first free TCP port greater or equal to given number
<
function-
arg-
def name="host" default="STAXServiceMachine">
<
function-
arg-
description>
Which machine to look for the free port
</
function-
arg-
description>
<
function-
arg-
def name="port" type="required">
<
function-
arg-
description>
The minimal port number to be returned
</
function-
arg-
description>
# returns first free port in [port; port+5]
# if no free port in this interval, return -1
s = Socket(hostAddr, port)
<
function name="checkFileExists" scope="local">
Set testcase result to FAIL if file (as param) does not exist
<
function-
arg-
def name="location" default="STAXServiceMachine">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="file" type="required">
<
function-
arg-
description>
The file to check existence
</
function-
arg-
description>
<
call function="'GetEntry'">
'location' : STAF_REMOTE_HOSTNAME ,
<
tcstatus result="'fail'"/>
<
message log="1" level="'Error'">
'ERROR : File %s does not exist' % file
<
function name="checkFileNotExists" scope="local">
Set testcase result to FAIL if file (as param) exists
<
function-
arg-
def name="location" default="STAXServiceMachine">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="file" type="required">
<
function-
arg-
description>
The file to check absence
</
function-
arg-
description>
<
call function="'GetEntry'">
'location' : STAF_REMOTE_HOSTNAME ,
<
tcstatus result="'fail'"/>
<
message log="1" level="'Error'">
'ERROR : File %s does not exist' % file
This function execute the ldclt tools.
<
function-
arg-
def name="location" default="STAF_CLIENT_HOSTNAME">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="dsInstanceHost" 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 name="dsInstancePort" 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 name="dsInstanceDn" default="DIRECTORY_INSTANCE_DN">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="DN"/>
<
function-
arg-
def name="dsInstancePswd" default="DIRECTORY_INSTANCE_PSWD">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="dsBaseDn" 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 name="ldcltOptions" <
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="dn"/>
<
function-
arg-
def name="outputFile" <
function-
arg-
description>
File containing output from the command
</
function-
arg-
description>
<
function-
arg-
property name="type" value="file"/>
<
function-
arg-
def name="outputPath" <
function-
arg-
description>
Path containing outputFile
</
function-
arg-
description>
<
function-
arg-
property name="type" value="filepath"/>
<
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 name="knownIssue" <
function-
arg-
description>
Known issue. Corresponds to an issue number.
</
function-
arg-
description>
STAFCmdParams=' '.join(STAFCmdParamsList)
<
call function="'runCommand'" >
'name' : 'LDCLT Script' ,
'arguments' : STAFCmdParams ,
'outputFile' : '%s/%s' % (outputPath, outputFile) ,
'expectedRC' : expectedRC ,
'knownIssue' : knownIssue
<!-- This function uses make ldif to generate LDIF data files --> <
function name="MakeALdcltTemplate">
This function makes a ldclt template file
<
function-
arg-
def name="templateFile" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="filename"/>
<
function-
arg-
def name="templateLocation" default="STAF_CLIENT_HOSTNAME">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="filename"/>
<
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"/>
<!-- Build the import task configuration object --> 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('telephoneNumber: 0[RNDN(1;5;1)] [RNDN(0;99;2)] [RNDN(0;99;2)] [RNDN(0;99;2)] [RNDN(0;99;2)]')
<!-- Write out the make-ldif template file --> outfile = open(tmpTemplateFile,"w")
<
if expr="STAXCode != 0">
<
message level="'error'">
'creation of a ldclt template failed (Code=%s,Reason=%s).' % (STAXCode,STAXReason)
<
call function="'checktestRC'">
{ 'returncode' : STAXCode ,
<
call function="'copyFile'">
{ 'location' : STAXServiceMachine,
'srcfile' : tmpTemplateFile,
'destfile' : templateFile,
'remotehost' : templateLocation }
<
call function="'checktestRC'">
<
return>[RC, STAXResult]</
return>
<!-- This function parses an ldif entry --> <
function name="parseLdifEntry">
This function parses an ldif entry and returns a dictionary,
e.g.:
{'dn':['o=example'],'objectclass':['top','organization'],'o':['example']}
<
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"/>
# line corresponds to an attr:val
if attr == 'objectclass':
# This is the first occurrence of this attr
parsedEntry[attr] = [val]
# There is already some value for this attr
parsedEntry[attr].append(val)
# line corresponds to a trailing value
parsedEntry[prevAttr].remove(prevVal)
parsedEntry[prevAttr].append(val)
<
return> parsedEntry </
return>
<!-- This function parses several ldif entries --> <
function name="parseLdifEntries">
This function parses several ldif entries and returns a list of
dictionaries such as those produced by parseLdifEntry
<
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"/>
if len(ldifEntryLines) != 0:
ldifEntry = '\n'.join(ldifEntryLines)
if len(ldifEntryLines) != 0:
ldifEntry = '\n'.join(ldifEntryLines)
<
if expr="len(ldifEntryList) != 0">
<
iterate var="entryToParse" in="ldifEntryList">
<
call function="'parseLdifEntry'">
{ 'ldifEntry' : entryToParse }
<
return> parsedEntryList </
return>
<!-- This function parses an ldif change --> <
function name="parseLdifChange">
This function parses an ldif change and returns a list,
e.g.:
[ ['replace','l','London'], ['add','description','This is a test'] ]
<
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"/>
# line corresponds to an attr:val
if attr == 'objectclass':
# attr represents indeed an attribute type, so we may assume the
# mod already has [mod_type,attr_type]
# attr represents the mod_type, and val the attr_type
# line corresponds to a trailing value
# line is empty or line starts with '-'; this means that
# the mod is complete, so we can add it to the parsedChange list
# add the trailing mod to the parsedChange list
<
return> parsedChange </
return>
<!-- This function checks the content of an external changelog entry --> <
function name="checkChangelogEntry">
This function checks the content of an external changelog entry
<
function-
arg-
def name="location" default="STAF_REMOTE_HOSTNAME">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="dsPath" 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 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 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 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 name="changeTime" <
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="changeNumber" <
function-
arg-
description>
Changenumber (only for changelog draft-compatible mode)
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="replicationCSN" <
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="targetEntryUUID" <
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="replicaIdentifier" <
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="newRDN" <
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="deleteOldRDN" <
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="newSuperior" <
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="changes" <
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 name="includeAttrs" <
function-
arg-
description>
Map containing the attributes configured as include-attributes along
{ 'description':['desc1', desc2'], 'telephonenumber':['11-22-33']}
</
function-
arg-
description>
<
function-
arg-
property name="type" value="map"/>
<
function-
arg-
def name="expectMissingIncAttrs" <
function-
arg-
description>
List of the attributes in includeAttrs expected NOT TO BE FOUND in the
</
function-
arg-
description>
<
function-
arg-
property name="type" value="list"/>
<
function-
arg-
def name="knownIssue" type="optional" default="None">
<
function-
arg-
description>
Known issue. Corresponds to an issue number.
</
function-
arg-
description>
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]
ecl_replicationCSN = None
ecl_replicaIdentifier = None
ecl_targetEntryUUID = None
ecl_includedAttributes = None
ecl_replicationCSN = changelogEntry['replicationcsn'][0]
ecl_replicaIdentifier = changelogEntry['replicaidentifier'][0]
ecl_targetEntryUUID = changelogEntry['targetentryuuid'][0]
ecl_newRDN = changelogEntry['newrdn'][0]
ecl_deleteOldRDN = changelogEntry['deleteoldrdn'][0]
ecl_newSuperior = changelogEntry['newsuperior'][0]
ecl_changes = changelogEntry['changes'][0]
ecl_includedAttributes = changelogEntry['includedattributes'][0]
'checkChangelogEntry: Checking changelog entry %s against expected \
'checkChangelogEntry: Checking targetDN'
<
call function="'searchString'">
{ 'returnString' : ecl_targetDN,
'expectedString' : targetDN,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
'checkChangelogEntry: Checking changeType'
<
call function="'searchString'">
{ 'returnString' : ecl_changeType,
'expectedString' : changeType,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
'checkChangelogEntry: Checking changeTime'
<
call function="'searchString'">
{ 'returnString' : ecl_changeTime,
'expectedString' : changeTime,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
'checkChangelogEntry: Checking changeNumber'
<
call function="'searchString'">
{ 'returnString' : ecl_changeNumber,
'expectedString' : changeNumber,
'searchType' : 'exact-case-sensitive',
'knownIssue' : myKnownIssue
<
if expr="replicationCSN">
<
if expr="ecl_replicationCSN">
'checkChangelogEntry: Checking replicationCSN'
<
call function="'searchString'">
{ 'returnString' : ecl_replicationCSN,
'expectedString' : replicationCSN,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
<
message log="1" level="'Error'">
'No replicationCSN could be found in the changelog entry'
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
if expr="replicaIdentifier">
<
if expr="ecl_replicaIdentifier">
'checkChangelogEntry: Checking replicaIdentifier'
<
call function="'searchString'">
{ 'returnString' : ecl_replicaIdentifier,
'expectedString' : replicaIdentifier,
'searchType' : 'exact-case-sensitive',
'knownIssue' : myKnownIssue
<
message log="1" level="'Error'">
'No replicaIdentifier could be found in the changelog entry'
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
if expr="targetEntryUUID">
<
if expr="ecl_targetEntryUUID">
'checkChangelogEntry: Checking targetEntryUUID'
<
call function="'searchString'">
{ 'returnString' : ecl_targetEntryUUID,
'expectedString' : targetEntryUUID,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
<
message log="1" level="'Error'">
'No targetEntryUUID could be found in the changelog entry'
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
'checkChangelogEntry: Checking newRDN'
<
call function="'searchString'">
{ 'returnString' : ecl_newRDN,
'expectedString' : newRDN,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
<
message log="1" level="'Error'">
'No newRDN could be found in the changelog entry'
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
if expr="ecl_deleteOldRDN">
'checkChangelogEntry: Checking deleteOldRDN'
<
call function="'searchString'">
{ 'returnString' : ecl_deleteOldRDN,
'expectedString' : deleteOldRDN,
'searchType' : 'exact-case-sensitive',
'knownIssue' : myKnownIssue
<
message log="1" level="'Error'">
'No deleteOldRDN could be found in the changelog entry'
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
if expr="ecl_newSuperior">
'checkChangelogEntry: Checking newSuperior'
<
call function="'searchString'">
{ 'returnString' : ecl_newSuperior,
'expectedString' : newSuperior,
'searchType' : 'exact-case-insensitive',
'knownIssue' : myKnownIssue
<
message log="1" level="'Error'">
'No newSuperior could be found in the changelog entry'
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<!-- Decode the changes that are encoded in base64 --> 'checkChangelogEntry: Decode external changelog entry changes'
<
call function="'Base64WithScript'">
{ 'location' : myLocation,
'encodedData' : ecl_changes
<!-- STAXResult is not always a list--> decodeRC, decodedChanges = STAXResult[0]
except AttributeError, details:
decodedChanges = 'AttributeError: can not parse STAXResult %s' \
'checkChangelogEntry: Decoded changes:\n%s' % decodedChanges
'checkChangelogEntry: Checking changes'
<
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 --> <
call function="'parseLdifEntry'">
{ 'ldifEntry' : decodedChanges }
ecl_changesMap = STAXResult
'Parsed changelog entry changes: \n%s' % ecl_changesMap
valueList = changes[attr]
ecl_valueList = ecl_changesMap[attr]
<
if expr="ecl_valueList != None">
'checkChangelogEntry: Checking changes: %s' % attr
<
if expr="valueList == ecl_valueList">
'Found expected values in changes: %s' % valueList
<
message log="1" level="'Error'">
'Expected values %s could not be found in %s' \
% (valueList, ecl_valueList)
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
message log="1" level="'Error'">
'No %s could be found in the changes' % attr
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
elseif expr="decodeRC == 0">
<!-- If changetype:modify, the changes look like a sequence of ! so we need to treat them differently --> <
call function="'parseLdifChange'">
{ 'ldifChange' : decodedChanges }
ecl_changesList = STAXResult
'Parsed changelog entry changes: \n%s' % ecl_changesList
<
iterate var="mod" in="changes">
'checkChangelogEntry: Checking changes: %s' % mod
<
if expr="mod in ecl_changesList">
'Found expected change:\n %s: %s\n %s: %s\n' \
% (mod_type, mod_attr, mod_attr, mod_val)
<
message log="1" level="'Error'">
'Expected change %s could not be found in %s'\
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
message log="1" level="'Error'">
'No changes could be found in the changelog entry'
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
if expr="ecl_includedAttributes">
<!-- Decode the changes that are encoded in base64 --> 'checkChangelogEntry: Decode external changelog included attributes'
<
call function="'Base64WithScript'">
{ 'location' : myLocation,
'encodedData' : ecl_includedAttributes
<!-- STAXResult is not always a list--> decodeRC, decodedChanges = STAXResult[0]
except AttributeError, details:
decodedChanges = 'AttributeError: can not parse STAXResult %s' \
'checkChangelogEntry: Decoded changes:\n%s' % decodedChanges
<
if expr="decodeRC == 0">
<
call function="'parseLdifEntry'">
{ 'ldifEntry' : decodedChanges }
ecl_includeAttrsMap = STAXResult
'Parsed changelog entry changes: \n%s' % ecl_includeAttrsMap
<
message>'Matching included attribute %s.' % attr</
message>
valueList = includeAttrs[attr]
ecl_valueList = ecl_includeAttrsMap[targetAttr]
<
if expr="ecl_valueList != None">
<!-- Some value found for (include-attribute) targetAttr --> <
if expr="attr in expectMissingIncAttrs">
<
message log="1" level="'Error'">
'Found values %s for %s while NONE expected.' \
% (valueList, targetAttr)
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
if expr="valueList == ecl_valueList">
'Found expected values for include attribute in %s: \
%s' % (targetAttr, valueList)
<
message log="1" level="'Error'">
'Expected values %s could not be found in %s: %s' \
% (valueList, targetAttr, ecl_valueList)
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<!-- No (include-attribute) targetAttr found --> <
if expr="attr in expectMissingIncAttrs">
'No %s could be found in the changelog entry, AS EXPECTED' \
<
message log="1" level="'Error'">
'No %s could be found in the changelog entry' % targetAttr
<
if expr="myKnownIssue == None">
<
call function="'testFailed'"/>
<
call function="'setKnownIssue'">
{ 'issueId' : myKnownIssue }
<
function name="psearch" scope="local">
This function performs a psearch request
<
function-
arg-
def name="location" default="STAF_REMOTE_HOSTNAME">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="hostname"/>
<
function-
arg-
def name="dsInstanceHost" 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 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 name="dsInstanceDn" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
function-
arg-
def name="dsInstancePswd" type="required">
<
function-
arg-
description>
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
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 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 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 name="operation" type="optional">
<
function-
arg-
description>
Specify the opeation type
</
function-
arg-
description>
<
function-
arg-
property name="type" value="string"/>
<
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 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 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"/>
if is_windows_platform(location):
jstaf_jarfile='%s\\bin\\
JSTAF.jar' % REMOTE_STAF_ROOT
<!-- Build the command --> STAFCmdParams=' '.join(STAFCmdParamsList)
if is_windows_platform(location):
cp = 'CLASSPATH=%s%s%s%s.' \
% (ldapjdk_jarfile,separator,jstaf_jarfile,separator)
'%s %s' % (STAFCmd, STAFCmdParams)
<
call function="'runCommand'" >
'arguments' : '%s %s' % (STAFCmd, STAFCmdParams) ,
'expectedRC' : expectedRC
<
function name="testStep">
This function print out a test step.
<
function-
arg-
def name="stepMessage" type="required">
<
function-
arg-
description>
test step message to display
</
function-
arg-
description>
<
message>'*** Step%s: %s' % (stepNumber,stepMessage)</
message>