This is where you should look if you have a question about STAF V3, STAX V3, or an external STAF V3 service.
For questions about STAF V2, STAX V1, or an external STAF V2 service,. see the STAF V2 FAQ
1. General Information | |||
| |||
| 1.1. | What is STAF? | ||
STAF stands for "Software Testing Automation Framework. As its name indicates, STAF is an automation framework. It is intended to make it easier to create and manage automated testcases and test environments. STAF externalizes its capabilities through services. A service provides a focused set of functionality, such as, Logging, Process Invocation, etc. STAFProc is the process that runs on a machine, called a STAF Client, which accepts requests and routes them to the appropriate service. These requests may come from the local machine or from another STAF Client. Thus, STAF works in a peer environment, where machines may make requests of services on other machines. STAF was designed with the following points in mind:
| |||
| 1.2. | What operating systems are supported by STAF? | ||
STAF 3.2.4+ is supported on the following operating systems:
If you need support for another operating system, open a feature request on the STAF SourceForge web site.
If you can't wait, port STAF to your favorite operating system yourself since STAF is open source.
| |||
| 1.3. | Where can I get STAF? | ||
STAF software, information, documentation, etc. can be found at the STAF SourceForge web site. | |||
| 1.4. | Is STAF Open Source? | ||
Yes! STAF is open source. STAF Version 3.2.5 and later is licensed under the EPL (Eclipse Public License) V1.0. STAF Versions 2.6.8 through 3.2.4 were licensed under the Common Public License (CPL) V1.0. STAF Versions prior to 2.6.8 were licensed under the GNU Lesser General Public License (LGPL) V2.1. | |||
| 1.5. | What documentation exists for STAF V3? | ||
The following documents (and more) can be found at the STAF/STAX V3 Documentation web site:
| |||
| 1.6. | How do I get on/off STAF mailing lists? | ||
Go to the STAF Mailing Lists web page and click on Subscribe or Unsubscribe for the STAF mailing list that you want to be added to or removed from. | |||
| 1.7. | How do I get help? | ||
You can submit questions using the STAF Mailing Lists and the STAF Discussion Forums on SourceForge. If you are an IBMer, you may use the following IBM Forum to submit questions for STAF, STAX, and its services:
You can also get help about a STAF service's request syntax by using the following command: STAF local service HELP This will return the available options for the <service>
You can find out more information about STAF error codes by using the following command: STAF local HELP ERROR 7 This will return detailed information about error code 7.
| |||
| 1.8. | How do I request a feature for STAF? | ||
To request a feature (or browse a list of requested features), click here. | |||
| 1.9. | Why isn't STAF written in Java? | ||
| |||
| 1.10. | What is the performance overhead of running STAF? | ||
As a general rule, STAF takes up very little system resources. A typical STAF installation is about 10-30 MB (depending on whether you use the installer with the integrated JVM). STAF's in-memory size (without any additional external services) is about 2.5-5 MB (depending on the platform). On an idle STAF system (i.e., one in which there are no requests currently being handled by STAF) STAF consumes 0% CPU on a Windows system and a VERY limited amount on unix systems. On unix, we have a thread which wakes up once a second to see if any STAF processes have completed. STAF was designed to consume as little system resources as possible, as we know that people want their test systems as close to clean-room conditions as possible. | |||
| 1.11. | How do I interact with STAF? | ||
You can interact with STAF from many languages (Java, C, C++, Python, Perl, Tcl, Rexx) and from the command line/shell prompt. See the "API Reference" and "Commands" sections in the STAF User's Guide for more information. If you need support for another language, open a feature request on the STAF SourceForge web site. If you can't wait, provide support for your favorite language yourself since STAF is open sourced. | |||
2. How-to Questions | |||
| |||
2.1. Installation/Configuration | |||
| 2.1.1. | How do I install STAF? | ||
STAF provides its own installation program which uses InstallAnywhere for supported platforms. On Unix platforms, we also provide a shell script-based installation mechanism. See the STAF Installation Guide for detailed instructions on how to install STAF. | |||
| 2.1.2. | How do I install STAF in silent mode? | ||
Here are the commands to install STAF in silent mode (these examples are for Win32): If using the InstallAnywhere executable:
C:\temp>STAF330-setup-win32 -i silent -DACCEPT_LICENSE=1
To override the default location where STAF is installed during a silent installation, you can specify the following option:
C:\temp>STAF330-setup-win32 -i silent -DACCEPT_LICENSE=1 -DUSER_INSTALL_DIR=C:\tools\staf
| |||
| 2.1.3. | How do I configure STAF? | ||
STAF is configured through a text file called the STAF Configuration File. This file may have any name you desire, but the default is STAF.cfg. The STAF configuration File is read and processed line by line. The various configuration options are described in the Configuration section in the STAF User's Guide. | |||
| 2.1.4. | How can I determine which version/architecture of STAF is installed? After the STAF install is complete, an install.properties file will be created in the root STAF install directory. The file will contain key/value pairs that provide information about the version of STAF that has been installed. The install.properties file will contain the following information:
Here is a sample install.properties file from a Windows system (using the IA installer): version=3.3.0 platform=win32 architecture=32-bit installer=IA file=STAF330-setup-win32.exe osname=Windows osversion=* osarch=x86 Here is a sample install.properties file from a Mac OS X i386 system (using the STAFInst installer): version=3.3.0 platform=macosx-i386 architecture=32-bit installer=STAFInst file=STAF330-macosx-i386.tar osname=Mac OS X osversion=10.4+ osarch=i386 | ||
| |||
2.2. Starting STAF | |||
| |||
| 2.2.1. | How do I make STAF start automatically during reboot on Unix platforms? | ||
Each Unix platform has a different method to start executables automatically during reboot. On Linux platforms, perform the following steps (substituting your specific locations where STAF and Java are installed):
Don't worry if you get the following error message: STAFProcess::processMonitorThread: error opening /dev/tty, errno: 6 STAFProc does start despite this message, and accepts requests. | |||
| 2.2.2. | How do I start STAF as a service on Solaris? | ||
Procedure 1. Running STAFProc as a service on Solaris
| |||
| 2.2.3. | How do I load STAFEnv.sh automatically for each terminal window I open on Unix? | ||
Note: Be aware of all the leading dots ('.') and dot spaces (". ") in the following steps. They are crucial and are functionally distinct.
| |||
| 2.2.4. | How do I start STAF as a Windows service? | ||
On Windows, when the machine fails and/or is rebooted, STAF is unavailable for remote commands until a user logs in and starts it. As an solution, you can configure the STAF process as a Windows service that will run automatically when the machine boots. Procedure 3. Starting STAF as a Windows Service These instructions assume you have copied INSTSRV.EXE and SVRANY.EXE (available from the Windows Resource Kit) into C:\WINNT\SYSTEM32 and you have users connecting through Remote Desktop Client. These instructions are for Windows 2000 and later.
Problems and Solutions when Starting STAF as a Service: Problem: If a user logs on before the STAF process (STAFproc) has initialized, it is possible that they still receive the error 'Error registering with STAF, RC: 21' even after the service has started.
Solution: Stop and restart the service with due care as others might already be using it. net stop staf net start staf
Problem: STAF should not be started or shutdown with the commands on the start menu when STAF is configured as a service.
Solution: The service can be restarted by suitably authorized user from the command line with: net stop staf net start staf
The service can be restarted from the services panel of the management console by right clicking and selecting stop and then right clicking and selecting start.
Problem: STAF is still started (and fails) when the user who installed it logs in.
Solution: Delete STAF from Start > Programs > Startup folder
| |||
| 2.2.5. | How do I start STAF as a scheduled task on Windows during reboot? | ||
On Windows, when a machine is booted up, STAF is unavailable until a user logs in and starts it. To have STAF start automatically when a Windows machine is booted up without a user having to login to the machine, you can start STAFProc as a scheduled task. This works for Windows 2000 or later. This is an alternative to configuring STAFProc as a Windows service (as described above). This is especially good for Windows 2003 64-bit machines which do not support srvany.exe in the Windows Toolkit (used when starting STAF as a Windows service). Note that when starting STAFProc as a scheduled task, it does not display any dialog. Procedure 4. Starting STAF as a Scheduled Task on Windows These instructions are for Windows 2003.
| |||
2.3. PROCESS Service | |||
| |||
| 2.3.1. | How do I redirect output from a process started by STAF? | ||
You can't use the command line redirection symbols, such as '>', with STAF. They won't work. However, STAF's PROCESS service provides several redirection options, namely STDIN, STDOUT, STDOUTAPPEND, STDERR, and STDERRAPPEND, depending on what (and how) you want to redirect. For example, to start shell script tc3.sh and redirect its standard output to /tmp/tc3.out: STAF local PROCESS START COMMAND tc3.sh STDOUT /tmp/tc3.out | |||
| 2.3.2. | How do I run a complex command that I can type at a shell (command) prompt via STAF? | ||
The PROCESS service has a SHELL parameter which specifies that COMMAND should be executed as though you were at a shell prompt. This allows complex commands involving pipelines to be readily executed. Note, if COMMAND and PARMS are both specified they will be concatenated with a space between them, and the resulting string is what will be executed.
| |||
| 2.3.3. | How do I quote options that contain white space (e.g. pathnames containing spaces, etc.) via STAF? | ||
You must specify quotes around pathnames that contain white space and you need to specify double quotes around the entire option value. To have double quotes contained within double quotes, you need to escape them with a backslash, e.g. \". Here are some examples of how to quote options that contain white space in PROCESS START requests:
| |||
| 2.3.4. | How do I use a static handle to have multiple programs access variables and log data? | ||
If you have a program (PROG-A) that creates a static handle, and you want to start another program (PROG-B) using the STAF start command, such that PROG-B can create variables and a log using that same handle. The problem is that each program has to know the number of the static handle in order to use it. You can do this via an environment variable. So, from PROG-A, you could do something like: request = 'start command cmd.exe parms "/c PROG-B" env STAFHANDLE='staticHandle call STAFSubmit 'local', 'process', request
Then, PROG-B can pull the static handle from the environment variable. | |||
2.4. LOG Service | |||
| 2.4.1. | How do I make each application have its own STAF log file? | ||
Use HANDLE logs instead of GLOBAL logs. With HANDLE logs each application will get a physically separate log file. HANDLE logs keep separate logs for each process even if the processes are using the same log names. The downside to HANDLE logs is you need to remember the handles you were using, so that you can query them. For example if you log data to a handle log, like so:
STAF local log LOG HANDLE LOGNAME testit LEVEL info MESSAGE hello
then you can query it like so:
STAF local log QUERY MACHINE m1 HANDLE h1 LOGNAME testit
In this request you need to know m1 (which should be your machines name) and h1 which you won't know until your program is executed.
To facilitate HANDLE based logs, it is probably a good idea for programs using them to write their name and handle to a GLOBAL log so that you can determine which HANDLE logs you need to query.
| |||
| 2.4.2. | How do I view a STAF log as it appears to be in some weird format? | ||
This is the expected format for STAF logs (they are binary files, not text files). As a general rule you should use the LOG service itself to look at the logs. For example:
STAF local log query global logname stresstst
You can redirect that to another file, which will be in text format, if you want. You can also use the FmtLog utility (shipped with STAF) which will read a log file and format and write the data to an output file in a readable format. | |||
2.5. HTTP Service | |||
| 2.5.1. | Does the HTTP Service retain session information across multiple requests? | ||
Yes. Version 2.0 (and later) of the HTTP service provides the ability to group requests to the HTTP service together in a session. Performing requests in a session provides the ability simulate a browsing experience. Since a session provides memory about the last request it is possible to manipulate cookies, login into secure web sites, and interact with form and link html elements that are returned from requests. | |||
2.6. STAX Service | |||
| |||
| 2.6.1. | How do I access system date and time in a STAX job? | ||
You can either use the python libraries or the java libraries. Here is a STAX job which shows both approaches: Example 1. Accessing system date and time via Python libraries and Java libraries
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">
<stax>
<defaultcall function="test"/>
<function name="test">
<sequence>
<!-- get the python date -->
<script>
from time import localtime, strftime
currenttime = strftime("%a, %d %b %Y %H:%M:%S", localtime())
</script>
<message>'Python time: %s' % currenttime</message>
<!-- get the java date -->
<script>
from java.util import Calendar, Date
from java.text import SimpleDateFormat
formatter = SimpleDateFormat("yyyy.MM.dd G 'at' hh:mm:ss a zzz")
currentTimestamp = Date()
dateString = formatter.format(currentTimestamp)
</script>
<message>'Java time: %s' % dateString<</message>
</sequence>
</function>
</stax>
| |||
| 2.6.2. | How do I search for multiple strings in testcase output files in STAX? | ||
You can use the Python re library to search for multiple strings in testcase output files. For example, if you have a testcase output file c:/temp/test.txt: Example 2. Contents of testcase output file c:/temp/test.txt
********************************* Top of Data **********************************
---------+---------+---------+---------+---------+---------+---------+---------+
SET CURRENT SQLID='DBTIFAHC';
---------+---------+---------+---------+---------+---------+---------+---------+
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 0
---------+---------+---------+---------+---------+---------+---------+---------+
SELECT * FROM SPA_FI_REGISTRY;
---------+---------+---------+---------+---------+---------+---------+---------+
FI_ID AVLBLTY_STATUS UPDATE_USER_ID
UPDATE_TMSTP
---------+---------+---------+---------+---------+---------+---------+---------+
IBANKA S
STCCICS 2003-07-11-08.38.37.638163
DSNE610I NUMBER OF ROWS DISPLAYED IS 1
DSNE616I STATEMENT EXECUTION WAS SUCCESSFUL, SQLCODE IS 100
---------+---------+---------+---------+---------+---------+---------+---------+
-- INSERT INTO IFS_SESSN_ACTIVE
-- (USR_ID, FI_ID,SERV_ID,SESSN_NBR,IP_ADDR,SESSN_STRT_TMSTP,
-- SESSN_END_TMSTP,SESSN_ST_CODE, SESSN_MQ_QUALIFIER,CHK_DUPL_TXN,
-- SERV_INST_NBR)
F1=Help F2=Split F3=Exit F5=Rfind F7=Up F8=Down F9=Swap
F10=Left F11=Right F12=Cancel
SPUFI SSID: DB71
===>
Enter the input data set name: (Can be sequential or partitioned)
1 DATA SET NAME ... ===> 'MONICA1.IFSSCCAH.SPUFI.CNTL(SELECT)'
2 VOLUME SERIAL ... ===> (Enter if not cataloged)
3 DATA SET PASSWORD ===> (Enter if password protected)
* DSNE361I SPUFI PROCESSING COMPLETE *
Here's a sample STAX job that searches for 3 sets of strings in the test.txt file. Notice that when you specify the string text, you need to escape, with a backslash, any non-alphanumeric characters (such as spaces, dots, comma, equals, greater/less than, parenthesis...). You can find a Howto on Regular Expressions at http://www.amk.ca/python/howto/regex/. Example 3. Using Python re (regular expression) module to do string matches
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">
<stax>
<defaultcall function="test"/>
<function name="test">
<sequence>
<stafcmd>
<location>'local'</location>
<service>'fs'</service>
<request>'get file c:/temp/test.txt'</request>
</stafcmd>
<script>
import re
result = STAFResult
searchre = r"""(?mx)
^.*
^.*?IBANKA.*?
^.*
^.*?1\ \ DATA\ SET\ NAME\ \.\.\.\ \=\=\=\>\ \'MONICA1\.IFSSCCAH\.SPUFI\.CNTL\(SELECT\)\'.*?
^.*
^.*?DSNE361I\ SPUFI\ PROCESSING\ COMPLETE.*?
^.*"""
</script>
<if expr='re.match(searchre, result) != None'>
<message>'Pass'</message>
<else>
<message>'Fail'</message>
</else>
</if>
</sequence>
</function>
</stax>
| |||
| 2.6.3. | How do I access STAF system variable values via a STAX job? | ||
The STAF variables have to be resolved using either the VAR service through a <stafcmd> or using the STAXUtilImportSTAFVars function from the STAXUtil.xml file (provided with the STAX download in the library subdirectory of the STAX installroot). Example 4. Using <stafcmd> to call the var service
<stafcmd>
<location>'local'</location>
<service>'var'</service>
<request>'resolve string {STAF/Config/STAFRoot}'</request>
</stafcmd>
<script>stafRoot=STAFResult</script>
Example 5. Using the STAXUtilImportSTAFVars function
<call function="'STAXUtilImportSTAFVars'">
[
{'STAF/Env/STAFDir': 'mySTAFDir', 'STAF/Version': 'mySTAFVersion'},
'machA'
]
</call>
and the resulting STAX variables could be: mySTAFDir = 'C:\STAF' mySTAFVersion = '3.2.0' See STAXUtil.html for full details. | |||
| 2.6.4. | How do I use the <stopusing> element in a STAX job that runs on both Windows and Unix? | ||
You can first determine whether the machine is Windows or non-Windows, set a variable to the STOPUSING option that you want to use on that operating system, and then use that variable in the <stopusing> element. Here is a sample STAX job: Example 6. Setting the <stopusing> value based on the operating system
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">
<stax>
<defaultcall function="test"/>
<function name="test">
<sequence>
<stafcmd>
<location>'local'</location>
<service>'var'</service>
<request>'resolve string {STAF/Config/OS/Name}'</request>
</stafcmd>
<script>
import re
osname = STAFResult
</script>
<if expr='re.search("^win", osname.lower()) != None'>
<script>stopusing = 'WM_CLOSE'</script>
<else>
<script>stopusing = 'SIGKILLALL'</script>
</else>
</if>
<process>
<location>'local'</location>
<command>'java'</command>
<stopusing>stopusing</stopusing>
</process>
</sequence>
</function>
</stax>
| |||
| 2.6.5. | Does a STAX process element use the workdir element as the path to the command? | ||
No. The STAF User's Guide, section 8.10.2 (PROCESS START) says: COMMAND specifies the actual command that you want to start. If the path to the command is not specified, the system PATH will be searched for the command. So, if the path to the command is not specified in the <command> element, the system PATH is searched. Just specifying the <workdir> will not make it use the workdir as the path and you'll get RC 10 (Base operating system error) because it couldn't find the command executable. The following <process> element specifies the path (assigned to variable testdir) to the test1.exe executable since it's not in the system PATH: Example 7. Specifying the path to the executable in the <command>
<script>
clientname = 'machineA.austin.ibm.com'
testdir = 'C:/test'
</script>
<process>
<location>clientname</location>
<command>'%s/test1.exe' % (testdir)</command>
<workdir>testdir</workdir>
</process>
| |||
| 2.6.6. | How do I use STAF and STAX to boot and shutdown VMWare images on my test machines? | ||
You can use STAF/STAX to boot VMWare images and then execute tests on the VMWare images. Below is a example that demonstrates how to do this. The "startvmware" function boots a VMWare image. Note that it's <function-prolog> has important information on how to configure your VMWare image to work correctly with STAF/STAX. The "stopvmware" function shuts down and powers off a VMWare image. The "main" function shows how you call the vmware functions. In your main function, after the VMWare image has booted (you would need to wait for an appropriate amount of time and do a STAF PING to the machine to determine that it's up and running), you would begin running your tests on the VMWare image. Example 8. Using STAF/STAX to boot VMWare images and then execute tests
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">
<stax>
<defaultcall function="main"/>
<function name="main" scope="local">
<parallel>
<block name="'Boot up VMWare image'">
<call function="'startvmware'">
{ 'image': 'c:/vmware/winxp/Windows-XP-Professional.vmx',
'timeout' : '5m', 'imagehostname' : 'abcdef',
'imagename' : 'Windows XP Professional'
}
</call>
</block>
<block name="'Release this block to shutdown the VMWare image'">
<sequence>
<hold/>
<call function="'stopvmware'">
{ 'imagehostname' : 'abcdef', 'shutdown' : 'shutdown -s -f -t 0' }
</call>
</sequence>
</block>
</parallel>
</function>
<function name="startvmware" scope="local">
<function-prolog>
Starts a VMWare image, and attempts to do a STAF PING to the VMWare image.
Your VMWare image needs to be configured so that there are no popups
displayed when the VMWare image starts (for example, messages about Disk
Drive warnings, etc), and that the image is set up to automatically log
in. Also, the machine must be configured to start STAF automatically.
Also, you must have the following 2 lines in your VMWare image's .vmx file:
gui.exitOnCLIHLT = "TRUE"
gui.exitAtPowerOff = "TRUE"
Note that you should avoid terminating any blocks that are running a VMWare
image, as that will kill the VMWare image without it being shutdown. Instead,
you should manually shutdown and power off the VMWare image, or call the
"terminatevmware" [not yet implemented] function.
You should use Bridged network connections for VMWare images to work
correctly with this function.
</function-prolog>
<function-map-args>
<function-optional-arg name="machine" default="'local'">
The machine on which the VMWare image is to be started. The default is 'local'.
</function-optional-arg>
<function-optional-arg name="vmwarebin" default="'c:/Program Files/Vmware/VMware Workstation/vmware.exe'">
The VMWare executable file. If the VMWare executable is not in the
VMWare system's PATH, then the file must be fully qualified.
The default is 'c:/Program Files/Vmware/VMware Workstation/vmware.exe'.
</function-optional-arg>
<function-required-arg name="image">
The fully qualified VMWare .vmx file for the VMWare image. Note that
the VMWare executable does not permit spaces in the file name of the
vmx file.
</function-required-arg>
<function-required-arg name="imagehostname">
The hostname for the VMWare image.
</function-required-arg>
<function-optional-arg name="timeout" default="'10m'">
The timeout value for when the function should stop attempting to
STAF PING the VMWare image. The default is 10 minutes. The STAF PING
to the VMWare image will be attempted every 30 seconds, up to the
timeout value.
</function-optional-arg>
<function-optional-arg name="imagename" default='image'>
The name of the VMWare image. The default is the argument specified
for image.
</function-optional-arg>
</function-map-args>
<parallel>
<process name="'VMWare Image %s ' % imagename">
<location>machine</location>
<command>vmwarebin</command>
<parms>'-x -q %s' % image</parms> <!-- -x powers on automatically, -q exits at power off -->
<stdout>'out.txt'</stdout>
<stderr mode="'stdout'"/>
<returnstdout/>
</process>
<sequence>
<script>contacted = 0</script>
<timer duration='timeout'>
<loop while="contacted == 0">
<sequence>
<stafcmd name="'Delaying for 30 seconds'">
<location>'local'</location>
<service>'delay'</service>
<request>'delay 30000'</request>
</stafcmd>
<stafcmd name = "'Attempt to ping %s' % imagehostname">
<location>imagehostname</location>
<service>'ping'</service>
<request>'ping'</request>
</stafcmd>
<if expr="RC == 0">
<sequence>
<script>contacted = 1</script>
<message>'Machine %s is up and running with VMWare image %s' % (imagehostname, imagename)</message>
<log>'Machine %s is up and running with VMWare image %s' % (imagehostname, imagename)</log>
</sequence>
</if>
</sequence>
</loop>
</timer>
<if expr="RC != 0">
<sequence>
<message>'Machine %s with VMWare image %s was not successfully started RC: %s' % (imagehostname, imagename, RC)</message>
<log>'Machine %s with VMWare image %s was not successfully started RC: %s' % (imagehostname, imagename, RC)</log>
</sequence>
</if>
</sequence>
</parallel>
</function>
<function name="stopvmware" scope="local">
<function-prolog>
Stops a VMWare image
</function-prolog>
<function-map-args>
<function-required-arg name="imagehostname">
The hostname for the VMWare image.
</function-required-arg>
<function-required-arg name="shutdown">
The command used to shut down the OS.
</function-required-arg>
</function-map-args>
<sequence>
<script>
from com.ibm.staf import STAFUtil
</script>
<stafcmd>
<location>imagehostname</location>
<service>'process'</service>
<request>'start async shell command %s' % STAFUtil.wrapData(shutdown)</request>
</stafcmd>
</sequence>
</function>
</stax>
| |||
| 2.6.7. | How can I parse an XML file from a STAX job? | ||
A STAX job can parse an XML file using an XML Parser of your choice. Below is a example that demonstrates how to do this using an XML Parser provided with java. This example parses an XML file whose name you specify and also validates the xml file. In this example, it's parsing a STAX xml file so it's using the STAX DTD but you could specify another DTD). This example also provides xml parsing error information, including the line number and xml parsing error message. Example 9. Parsing an XML File from a STAX job
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE stax SYSTEM "stax.dtd">
<stax>
<defaultcall function="Main"/>
<function name="Main">
<sequence>
<!-- Assign the file name of a STAX xml document you want to parse -->
<call function="'parseXML'">'c:/dev/src/stax/leTest.xml'</call>
<script>
document = STAXResult
# Change code here to parse the document as you desire.
# The code shown here is just an example for parsing a STAX xml document
root = document.getDocumentElement()
children = root.getChildNodes()
msg = ''
for i in range(children.getLength()):
thisChild = children.item(i);
if (thisChild.getNodeType() == Node.ELEMENT_NODE and
thisChild.getNodeName() == 'defaultcall'):
msg = '%s\nFound defaultcall element' % (msg)
elif thisChild.getNodeType() == Node.COMMENT_NODE:
# Do nothing
continue
elif thisChild.getNodeType() == Node.ELEMENT_NODE:
msg = '%s\nFound %s element' % (msg, thisChild.getNodeName())
</script>
<message>'Some parsed data: %s' % (msg)</message>
<log>'Some parsed data: %s' % (msg)</log>
</sequence>
</function>
<!-- ******************************************************************* -->
<!-- Following function is used to parse an XML file and return the DOM -->
<!-- document object -->
<!-- ******************************************************************* -->
<function name="parseXML" scope="local">
<function-list-args>
<function-required-arg name="xmlFileName">
Name of file containing XML to be parsed
</function-required-arg>
</function-list-args>
<sequence>
<!-- Parse the XML -->
<script>
factory = DocumentBuilderFactory.newInstance();
factory.setValidating(1)
factory.setIgnoringElementContentWhitespace(0)
try:
parseError = 0
builder = factory.newDocumentBuilder()
resolver = ParserResolver()
builder.setEntityResolver(resolver)
builder.setErrorHandler(resolver)
document = builder.parse(xmlFileName)
except SAXParseException, spe:
parseError = 1
</script>
<!-- Quit if there is any parsing error -->
<if expr="parseError">
<sequence>
<script>
errmsg = 'Error occurred parsing file %s\n line: %s\n msg: %s' % (
xmlFileName, spe.getLineNumber(), spe.getMessage())
</script>
<log>errmsg</log>
<message>errmsg</message>
<terminate/>
</sequence>
</if>
<return>document</return>
</sequence>
</function>
<script>
# These imports only need to be done once per job, no matter
# how many xml documents are parsed
from java.io import File
from java.io import StringReader
from org.xml.sax import InputSource
from org.xml.sax import SAXParseException
from org.xml.sax.helpers import DefaultHandler
from javax.xml.parsers import DocumentBuilderFactory
from javax.xml.parsers import DocumentBuilder
from org.w3c.dom import Document
from org.w3c.dom import Element
from org.w3c.dom import Node
from org.w3c.dom import NodeList
# Name of file containing STAX DTD (or whatever DTD you want used) to
# when validating/parsing an xml file
dtdFileName = 'C:/stax.dtd'
# ************************************************************************ #
# Following are the private Python classes #
# ************************************************************************ #
# This class handles XML Parsing exceptions
class ParserException(Exception):
pass
# This class handles the exception raised by XML parser
class ParserResolver(DefaultHandler):
def resolveEntity (self, publicId, systemId):
return InputSource(dtdFileName)
def error (self, e):
raise 'error', e
def warning (self, e):
raise 'warning', e
def fatalError (self, e):
raise 'fatal', e
</script>
</stax>
| |||
2.7. Globalization | |||
| 2.7.1. | How do I use STAF/STAX in environments where machines running STAF have different locales? | ||
In general, you don't have to do anything special. The requests submitted to STAF and the results received from STAF are all strings. These strings may contain any arbitrary set of characters, including the NULL (i.e., 0) character. When working in an environment with a heterogeneous set of codepages, STAF will translate the request and result strings from and to the necessary codepages. This ensures that the request and result strings are not misinterpreted by the receiver. In general, when using STAF services, there shouldn't be any round trip problems. "Round trip" in this context means when all requests are originating from the same system, even if the requests are sent to, and the data is stored on, a system with a different codepage. However, if you send, for example, a request to log data containing Japanese codepage specific characters to any system and then query the log from a system using a US English codepage, you won't get the "correct" data, as that is not a valid "round trip". Note: All STAF generated strings are composed of only ASCII-7 characters and will safely survive the translation from/to different codepages. CautionIf you use a STAF service that is written in REXX, it can have round trip codepage translation problems. All of STAF services currently provided are written in C++/Java so they do not have this problem. | |||
| 2.7.2. | How do I specify non-ASCII characters in a STAF request or STAX job? | ||
If you're specifying a STAF request from the command line, then you can just specify the appropriate characters. Example 10. Specifying a French character in a STAF request submitted via the command line
STAF frenchMach PROCESS START COMMAND c:/test/TestA PARMS "-server français"
If you want to specify non-ASCII characters in a STAX job, then you need to specify them in Unicode. Example 11. Specifying a French character in Unicode in a STAX job
<process>
<location>'frenchMach'</location>
<command>'c:/test/TestA'</command>
<parms>'-server fran' + u'\u00E7' + 'ais'</parms>
</process>
Example 12. Specifying Chinese characters in Unicode in a STAX job
<script>dirName = '/tmp/Sun2_' + u'\u4F3A\u670D\u5668'</script>
<stafcmd>
<location>'chineseMach'</location>
<service>'FS'</service>
<request>'CREATE DIRECTORY %s' % (dirName)</request>
</stafcmd>
If you want to specify non-ASCII characters in a STAF request submitted via a Java program, then you need to specify them in Unicode. Example 13. Specifying Chinese characters in Unicode in a PROCESS START request via a Java program
String machine = "chineseMach";
String service = "PROCESS";
String serverName = "\u4F3A\u670D\u5668_HP";
String request = "START COMMAND " + STAFUtil.wrapData("/test/startServer.sh") +
" PARMS " + STAFUtil.wrapData(serverName) + " WAIT";
STAFResult submitResult = handle.submit2(machine, service, request);
If you need to specify non-ASCII characters in a request, then you need to be aware of some anomalies if your target system is a Windows system that isn't using an English codepage and whose ANSI codepage (ACP) identifier is different from the OEM codepage (OEMCP) identifier. The system locale determines which codepages are defaults for the Windows system. However, some European locales such as French and German set different values for the ACP and OEMCP. See section "2.7.1 Windows Codepage Translation Anomalies" in the STAF User's Guide for more information on these Windows codepage translation anomalies. | |||
| 2.7.3. | How do I know what codepage STAF is using on my machine? | ||
To see the codepage that STAF is using, check the value of STAF variable STAF/Config/CodePage. For example:
STAF testmach1 VAR RESOLVE STRING {STAF/Config/CodePage}
| |||
3. Debugging STAF | |||
| |||
3.1. General Questions | |||
| |||
| 3.1.1. | What should I do if I'm having a problem with STAF or one of its services? | ||
If you are having a problem with STAF or one of its services, follow these steps to resolve the problem:
| |||
| 3.1.2. | What information should I include when asking questions or reporting bugs? | ||
When you are posting to the Help forum or submitting a new bug, the STAF development team will be better able to quickly resolve your problem if you supply the following information:
| |||
| 3.1.3. | Explain RC 16 when attempting to send a STAF request to a remote machine | ||
Return code of 16 means "No Path To Endpoint". This means that STAF could not talk to the target system, with likely causes being:
| |||
| 3.1.4. | Why can't my STAF machines communicate? | ||
If you are having problems getting two STAF machines to communicate, try the following steps on each machine:
Procedure 5. Changing the DNS settings on Windows 2000
Procedure 6. Changing the DNS settings on Windows XP
The following paragraph only applies to IBM users of STAF/STAX. If you are running a Windows e-business client, and other machines can't ping the e-business client, it is likely that the e-business client is running "Net Firewall", which disables the ability of other machines to ping the e-business client (which also means that STAFProc on other machines will not be able to communicate with the e-business client). To determine if the machine is running Net Firewall, open the Network Connection the machine is using, and click on "Properties". If "Net Firewall" is listed as a component, and it is checked, then the e-business client will experience this problem. If you uncheck "Net Firewall" and click on OK, other machines will be able to ping the e-business client, and STAFProc on other machines will be able to communicate with the e-business client. CautionDO NOT UNINSTALL NET FIREWALL! The AT&T Net Client will not run without Net Firewall, and if Net Firewall is uninstalled, you must completely reinstall the AT&T Net Client. Procedure 7. Changing the DNS settings on Linux
Procedure 8. Changing the DNS settings on HP-UX
Certain versions of Linux set up a high level of security access for incoming requests on specific ports (including STAF requests, which, by default, come in through port 6500). From a Linux machine, if you are able to successfully send a staf ping to another machine, but the other machine cannot do a staf ping to the Linux machine (and you have verified that the DNS information is set up correctly on both machines), try the following (note that you may need to customize these commands depending on the Linux distribution):
| |||
| 3.1.5. | Why aren't my entries in /etc/hosts being used for STAF communication (particularly on Linux SLES)? | ||
On Linux, if you are using /etc/hosts to specify hostnames/IPs, and a regular "ping" to the hostname works, but a STAF ping fails with RC 16, it is likely that your /etc/hosts file is not being used. Ensure that your /etc/host.conf file looks contains order hosts, bind Also verify that the /etc/nsswitch.conf file contains: hosts: files dns If your /etc/host.conf file contains the following line: multi on Verify that you are using STAF V3.1.5 or later (which contains a fix for handling 'multi on'). If you are using an earlier version of STAF, you can workaround this problem by commenting out the 'multi on' line, and then restarting STAFProc. | |||
| 3.1.6. | Why can't I use the HELP service when STAF is not running? | ||
staf local help error error-number doesn't work if STAF is not running on your workstation. Users can access help messages offline (when STAF isn't running) by viewing the STAF documentation. STAF documentation is installed on the local system (if a typical install was done). The "STAF API Return Code Reference" contains a quick reference to the STAF return codes and is available at staf/docs/STAFRC.htm or you can view it on the STAF SourceForge website at http://staf.sourceforge.net/current/STAFRC.htm. | |||
| 3.1.7. | Why are there are more STAF processes on Linux? | ||
If you issue the following command
ps -ef | grep -i staf,
you will see more STAFProc processes (typically 10 or more) on Linux than on other platforms (which there's only one). This is because the Linux base operating system doesn't really have threads. Threads are simulated on Linux using processes, so each thread shows up as a process. | |||
| 3.1.8. | Why am I having problems (such as an RC 6) submitting a request to a Java service? | ||
If you are having a problem accessing a Java service, such as getting an RC 6 for any request you make to a Java service, the Java service's JVM may have encountered an error or may have been killed. Check the Java service's JVM log to see if any errors were logged. The JVM logs are stored in the {STAF/DataDir}/lang/java/jvm/<JVMName> directory on the system where the Java service is registered. The current JVM log is named JVMLog.1. If the JVM log contains an OutOfMemory error, any Java services using this JVM will have to be removed and added (registered) in order to start accepting requests. You may want to look at increasing the JVM's maximum heap size as the Java service(s) using this JVM may require more memory than can be allocated. Refer to the STAF User's Guide, section "4.4.3 JSTAF service proxy library", for more information on how to do this. Make sure you are using STAF V3.1.5 or later which contains a significant memory leak fix for STAF Java support. If the JVM was killed, there won't be errors regarding this in the JVM log, but the following error is written to the STAFProc window when a request is made to a Java service whose java executable has died: In JSTAF.STAFServiceAcceptRequest: Caught STAFException Name : STAFConnectionConnectException Location : d:\dev\sf\src\staf\stafif\win32\STAFLocalConnection.cpp(162) Text : OpenProcess2 Error code: 87
If the JVM was killed, any Java services using this JVM will have to be removed and added (registered) in order to start accepting requests. | |||
| 3.1.9. | Why is STAFProc terminating on some Unix platforms (such as Solaris) when the STAFProc terminal is exited? | ||
For example, if you have a script such as: PATH=/usr/local/staf/bin:/usr/local/java/bin:$PATH export PATH CLASSPATH=/usr/local/staf/lib:/usr/local/staf/lib/JSTAF.jar:$CLASSPATH export CLASSPATH STAFCONVDIR=/usr/local/staf/codepage export STAFCONVDIR LD_LIBRARY_PATH=/usr/local/staf/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH /usr/local/staf/bin/STAFProc &
STAF will start fine if you log in and exec this script, but when you log out, STAF terminates. To resolve this you should change the last line in the script to: nohup /usr/local/staf/bin/STAFProc >/tmp/STAFProc.out 2>&1 &
You should redirect STAFProc's stdout and stderr to a file, as shown above, because STAFProc's output is very important when investigating a STAF problem.
# man nohup
NAME
nohup - run a command immune to hangups
SYNOPSIS
/usr/bin/nohup command [ argument ...]
/usr/xpg4/bin/nohup command [ argument ...]
DESCRIPTION
The nohup utility invokes the named command with argu-
ments supplied. When the command is invoked, nohup arranges
for the SIGHUP signal to be ignored by the process.
The nohup utility can be used when it is known that command
will take a long time to run and the user wants to logout of
the terminal; when a shell exits, the system sends its chil-
dren SIGHUP signals, which by default cause them to be
killed. All stopped, running, and background jobs will
ignore SIGHUP and continue running, f their invocation is
preceded by the nohup command or if the process programmati-
cally has chosen to ignore SIGHUP.
| |||
| 3.1.10. | Why don't I see any Java service output in the STAFProc console anymore? | ||
The console output was redirected because in STAF 2.4.4 we changed the way JVMs for STAF Java services (such as STAX) output all of their stdout/stderr data (including the output of <script>print...</script> since that is being written to the JVM's stdout). All of the output that was formerly in the console output should now be in the JVMLog file. The file is located at:
{STAF/DataDir}/lang/java/jvm/JVM Name/JVMLog.x
where x is a number and JVM Name is STAFJVM1 by default unless you used the JVMName OPTION when configuring the Java service and set it to another name. If you look at your {STAF/DataDir}/lang/java/jvm/STAFJVM1/JVMLog.1 file, you should see something like: ****************************************************************************** *** 20030418-14:40:33 - Start of Log for JVMName: STAFJVM1 *** JVM Executable: java *** JVM Options : none ******************************************************************************
| |||
| 3.1.11. | When using Sun Java 1.4.2, why are the -Xmx settings for my Java STAF service not being used? | ||
This appears to be a bug in Sun Java 1.4.2 where it is not using the -Xmx heap settings. This means that if you are running Java STAF services with Sun 1.4.2, and specifying the OPTION J2=-Xmx option, the option will not be used and your service JVM will run out of memory at a much lower heap size (the actual limit seems to vary by OS). IBM Java 1.4.2 works correctly (http://www-106.ibm.com/developerworks/java/jdk/index.html) | |||
| 3.1.12. | Explain RC 21 when running staf local ping ping on Unix paltforms. | ||
When executing STAFEnv.sh during system startup on Unix platforms, it is possible to inadvertently pass "start" as the parameter to STAFEnv.sh (and so STAFProc is using that as the instance name when it starts). In this scenario, if you run staf <unix-machine> var list from another machine and examine the value of STAF/Config/InstanceName, the value will be set to "start". So, even though "echo $STAF_INSTANCE_NAME" is set to "STAF" as expected when you run "staf local ping ping", the value that STAFProc is using does not match, and so you get an RC 21. If this is the case, you can resolve the problem by adding a "shift" command to the start section of the STAF startup script just before STAFEnv.sh is called. That way, the parameters are decremented from 1 to 0. So you would have something like:
'start')
if [ -f /etc/rc.config.d/staf ]; then
. /etc/rc.config.d/staf
fi
if [ $STAF -eq 1 ]; then
shift
. /usr/local/staf/STAFEnv.sh
/bin/nohup STAFProc 2>error &
fi
;;
| |||
| 3.1.13. | Explain "Error accepting on server socket,socket RC: 24" | ||
This error can occur when your system has run out of file descriptors because too many files have been opened and you've exceeded the maximum number of open files allowed by your system. Anytime a file is opened, a file descriptor must be used to allow the program to access the data. When the STAF connection provider calls accept() to accept a connection on a socket and it's failing to open the socket and setting errno to 24 (this is the error code on Unix systems). In /usr/include/asm/errno.h on Linux systems, errno 24 is defined as: #define EMFILE 24 /* Too many open files */ EMFILE The per-process limit of open file descriptors has been reached. To see what files are open on Unix machines, use the lsof command. It lists the names of the open files and the pids of the processes that opened them. You can list the open files for a process by getting it's pid and then run lsof -p <pid>command>. If you you are using the STAX service on this machine, it's possible that a STAX job could be responsible for opening files and not closing them. Refer to Explain "RC 21 submitting a STAX EXECUTE request" for more information on this. | |||
3.2. STAF Install Questions | |||
| |||
| 3.2.1. | If the InstallAnywhere installer fails, how do I get debug information? | ||
The STAF IA installers will create a log file called STAFInstall.log in the root i | |||