Last Updated: August 20, 2015
2.0 Supported Platforms and Perl Versions
5.0 Package STAFMon
STAF Perl support must be installed in order to submit requests to STAF via a Perl program.
Note: All of STAF's Perl APIs are provided in the STAF namespace.
STAF Perl support is only provided in the STAF installer files for the platforms listed below. STAF Perl support is not provided in the STAF installer files for other operating systems.
The version of Perl used to build the STAF Perl libraries is usually the only Perl version that will work with those STAF Perl libraries. STAF currently provides STAF Perl support on the following platforms:
Section 2.0 provides details about the STAF Perl support by platform.
If you want to use a different version of Perl or if you want STAF Perl support for a different operating system, you can either:
If you build STAF Perl support for a different operating system and/or different Perl version, please contribute it to the STAF project. To contribute it, browse the STAF Support Requests to see if someone else has already provided STAF Perl support for this operating system and Perl version combination. If not, open a STAF Support Request with the "Summary" containing "STAF V3 Support for Perl x.x.x (Platform)", replacing x.x.x with the Perl version and replacing Platform with the operating system on which you built the support. Attach the necessary files to the Support Request.
Supported Perl Version | Built with | PLSTAF library | Perl Services |
---|---|---|---|
5.6.x | 5.6.1 (ActiveState) | bin/perl56/PLSTAF.dll | Not supported |
5.8.x (default) | 5.8.3 (ActiveState) | bin/perl58/PLSTAF.dll | Supported |
5.10.x | 5.10.0 (ActiveState) | bin/perl510/PLSTAF.dll | Supported |
5.12.x | 5.12.4 (ActiveState) | bin/perl512/PLSTAF.dll | Supported |
5.14.x | 5.14.2 (ActiveState) | bin/perl514/PLSTAF.dll | Supported |
Supported Perl Version | Built with | PLSTAF library | Perl Services |
---|---|---|---|
5.8.x (default) | 5.8.8 (ActiveState) | bin/perl58/PLSTAF.dll | Supported |
5.10.x | 5.10.0 (ActiveState) | bin/perl510/PLSTAF.dll | Supported |
5.12.x | 5.12.4 (ActiveState) | bin/perl512/PLSTAF.dll | Supported |
5.14.x | 5.14.2 (ActiveState) | bin/perl514/PLSTAF.dll | Supported |
Supported Perl Version | Built with | PLSTAF library | Perl Services |
---|---|---|---|
5.6.x | 5.6.1 (ActiveState) | lib/perl56/libPLSTAF.so | Not supported |
5.8.x (default) | 5.8.7 (ActiveState) | lib/perl58/libPLSTAF.so | Supported |
5.10.x | 5.10.0 (ActiveState) | lib/perl510/libPLSTAF.so | Supported |
5.12.x | 5.12.4 (ActiveState) | lib/perl512/libPLSTAF.so | Supported |
5.14.x | 5.14.2 (ActiveState) | lib/perl514/libPLSTAF.so | Supported |
5.18.x | 5.18.4 (ActiveState) | lib/perl518/libPLSTAF.so | Supported |
Notes:
|
Supported Perl Version | Built with | PLSTAF library | Perl Services |
---|---|---|---|
5.8.x (default) | 5.8.8 (ActiveState) | lib/perl58/libPLSTAF.so | Supported |
5.10.x | 5.10.0 (ActiveState) | lib/perl510/libPLSTAF.so | Supported |
5.12.x | 5.12.4 (ActiveState) | lib/perl512/libPLSTAF.so | Supported |
5.14.x | 5.14.2 (ActiveState) | lib/perl514/libPLSTAF.so | Supported |
5.18.x | 5.18.4 (ActiveState) | lib/perl518/libPLSTAF.so | Supported |
Notes:
|
Supported Perl Version | Built with | PLSTAF library | Perl Services |
---|---|---|---|
5.8.x (default) | 5.8.8 (ActiveState) | lib/perl58/libPLSTAF.so | Not supported |
5.10.x | 5.10.0 (ActiveState) | lib/perl510/libPLSTAF.so | Not supported |
Notes:
|
Supported Perl Version | Built with | PLSTAF library | Perl Services |
---|---|---|---|
5.8.x (default) | 5.8.8 (ActiveState) | lib/perl58/libPLSTAF.so | Supported |
5.10.x | 5.10.0 (ActiveState) | lib/perl510/libPLSTAF.so | Supported |
Notes:
|
Supported Perl Version | Built with | PLSTAF library | Perl Services |
---|---|---|---|
5.8.x (default) | 5.8.8 (ActiveState) | lib/perl58/libPLSTAF.so | Supported |
5.10.x | 5.10.0 (ActiveState) | lib/perl510/libPLSTAF.so | Supported |
Notes:
|
Supported Perl Version | Built with | PLSTAF library | Perl Services |
---|---|---|---|
5.18.x (default) | 5.18.2 | lib/perl518/libPLSTAF.dylib | Supported |
5.16.x | 5.16.3 | lib/perl516/libPLSTAF.dylib | Supported |
Once STAF Perl support is installed, verify that the following STAF Perl files exist:
{STAF/Config/STAFRoot}/bin/PLSTAF.pm {STAF/Config/STAFRoot}/bin/STAF.pl {STAF/Config/STAFRoot}/bin/STAF2.pl {STAF/Config/STAFRoot}/bin/STAFMon.pm {STAF/Config/STAFRoot}/bin/STAFLog.pm {STAF/Config/STAFRoot}/docs/STAFPerl.htm {STAF/Config/STAFRoot}/bin/perl56/PLSTAF.dll (On Windows Intel 32-bit) {STAF/Config/STAFRoot}/bin/perl58/PLSTAF.dll {STAF/Config/STAFRoot}/bin/perl510/PLSTAF.dll {STAF/Config/STAFRoot}/bin/perl512/PLSTAF.dll {STAF/Config/STAFRoot}/bin/perl514/PLSTAF.dll
{STAF/Config/STAFRoot}/bin/PLSTAF.pm {STAF/Config/STAFRoot}/bin/STAF.pl {STAF/Config/STAFRoot}/bin/STAF2.pl {STAF/Config/STAFRoot}/bin/STAFMon.pm {STAF/Config/STAFRoot}/bin/STAFLog.pm {STAF/Config/STAFRoot}/docs/STAFPerl.htm {STAF/Config/STAFRoot}/lib/perl56/libPLSTAF.so (Only provided if build Perl 5.6, which pre-built Linux 32-bit does) {STAF/Config/STAFRoot}/lib/perl58/libPLSTAF.so (On Linux and other Unix platforms that use .so extension) {STAF/Config/STAFRoot}/lib/perl510/libPLSTAF.so (On Linux and other Unix platforms that use .so extension) {STAF/Config/STAFRoot}/lib/perl512/libPLSTAF.so (On Linux and other Unix platforms that use .so extension) {STAF/Config/STAFRoot}/lib/perl514/libPLSTAF.so (On Linux and other Unix platforms that use .so extension) {STAF/Config/STAFRoot}/lib/perl518/libPLSTAF.so (On Linux AMD64) {STAF/Config/STAFRoot}/lib/perl516/libPLSTAF.dylib (On Mac OS X which uses .dylib extension) {STAF/Config/STAFRoot}/lib/perl518/libPLSTAF.dylib (On Mac OS X which uses .dylib extension)
The library file for the version of Perl that was selected as the default Perl version during the STAF installation (when using the Installshield installer) will either have a link in {STAF/Config/STAFRoot}/lib (on Linux) or a copy in {STAF/Config/STAFRoot}/bin on Windows.
On Windows (if using Perl 5.10): set PERLLIB=C:\STAF\bin;C:\STAF\bin\perl510 On Unix (if using Perl 5.8): export PERLLIB=/usr/local/staf/bin:/usr/local/staf/lib/perl58
use PLSTAF;Note that use loads modules at compile time whereas require loads modules at run time.
The procedural style of communicating with STAF uses the following methods:
The object-oriented style of communicating with STAF uses the following class:
Other STAF Perl classes that it externalizes are:
Other STAF Perl functions that it externalizes are:
where,
PROCESSNAME is the name by which your Perl program will be known
if ($rc != $STAF::kOk) {
print "Error registering with STAF, RC: $STAF::RC\n";
exit $rc;
}
print "My STAF handle: $STAF::Handle\n";
where,
LOCATION is the system to which the request should be submitted. "Local" may be used to represent the local system, i.e., the system on which the Perl program is running.
SERVICE is the name of the service to which the request should be submitted.
REQUEST is the actual request string itself.
$rc = STAF::Submit("local", "ping", "ping"); if ($rc != $STAF::kOk) { print "Error submitting ping request, RC: $STAF::RC\n"; if (length($STAF::Result) != 0) { print "Additional info: $STAF::Result\n"; } exit $rc; } print "STAF Ping result: $STAF::Result\n";
my $fileName = '{STAF/Config/STAFRoot}/bin/STAFProc.exe'; my $request = "QUERY ENTRY $fileName"; print "STAF local FS $request\n\n"; my $rc = STAF::Submit("local", "FS", $request); if ($rc != $STAF::kOk) { print "Request failed: STAF local FS $request\n"; print "RC=$STAF::RC Result=$STAF::Result\n"; exit $rc; } my $mc = STAF::STAFUnmarshall($STAF::Result); my $entryMap = $mc->getRootObject(); if ($entryMap->{type} eq 'F') { print "File Name : $fileName\n"; print "File Size : $entryMap->{lowerSize}\n"; print "Last Modified: $entryMap->{lastModifiedTimestamp}\n"; } else { print "$fileName is not a file. Type=$entryMap->{type}\n"; }
# Set $dir to a directory name whose contents will be listed my $dir = "C:/tmp"; my $request = "LIST DIRECTORY $dir"; print "STAF local FS $request\n\n"; my $rc = STAF::Submit("local", "FS", $request); if ($rc != $STAF::kOk) { print "Error on STAF local FS request\n"; print "Expected RC: $STAF::kOk\n"; print "Received RC: $rc, Result: $STAF::Result\n"; exit $rc; } my $mc = STAF::STAFUnmarshall($STAF::Result); # Get a "reference" to an array (which is the root object) my $rootObject = $mc->getRootObject(); # Each item in the array is a "reference" to a string which # contains the name of an entry in the directory for my $item (@{$rootObject}) { print "$item\n"; }
This example could print the following when run:
STAF local FS LIST DIRECTORY C:/tmp test1 AutoFVT.bsh tmp2 testA.exe test temp2 test2 openssl myfile.txt
where,
SYNCOPTION can be any of the following:
LOCATION is the system to which the request should be submitted. "Local" may be used to represent the local system, i.e., the system on which the Perl program is running.
SERVICE is the name of the service to which the request should be submitted.
REQUEST is the actual request string itself.
if ($rc != $STAF::kOk) {
print "Error submitting ping request, RC: $STAF::RC\n";
if (length($STAF::Result) != 0) {
print "Additional info:
$STAF::Result\n";
}
exit $rc;
}
print "STAF Ping result: $STAF::Result\n";
if ($rc != $STAF::kOk) {
print "Error unregistering with STAF, RC: $STAF::RC\n";
exit $rc;
}
There are two ways to create a STAF::STAFHandle object:
Once you have a valid STAFHandle object, you can begin submitting requests to STAF services. To do this, you use the STAFHandle's submit() or submit2() method.
STAFHandle defines the following member variables. They are initialized by the constructor, and should not be modified directly.
where,
HANDLENAMEORNUMBER is a required argument that specifies a handle name or number. If you specify a standard handle type (the default), this argument must be a string containing a name for the STAF handle to be created. If you specify a static handle type for the second argument, this argument must be an integer containing the handle number for an existing static STAF handle.
HANDLETYPE is an optional argument that specifies the type of handle. The valid handle types are:
The HANDLETYPE argument was added in STAF V3.3.3.
use PLSTAF; $handle = STAF::STAFHandle->new("My program"); if ($handle->{rc} != $STAF::kOk) { print "Error registering with STAF, RC: $handle->{rc}\n"; exit $handle->{rc}; } print "My STAF handle: $handle->{handle}\n"; $result = $handle->submit("local", "ping", "ping"); if (($result->{rc} != $STAF::kOk) or ($result->{result} != "PONG")) { print "Error on ping request.\n"; print "Expected RC: 0, Result: PONG\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } print "\nUnregistering handle $handle->{handle}\n"; $rc = $handle->unRegister(); if ($rc != $STAF::kOk) { print "Error unregistering with STAF, RC: $STAF::RC\n"; exit $rc; }
# First, need to obtain an existing static handle number from somewhere. # This example assumes that the Perl script containing this code will be # run by submitting a START request to the STAF PROCESS service using the # STATICHANDLENAME option. This allows it to obtain the STAF static handle # number from environment variable STAF_STATIC_HANDLE. # # Note: Another way a static handle could have been obtained is if it # is passed to the Perl program as an argument. The static handle # could have been created by another program (which submitted a CREATE # HANDLE request to the HANDLE service). Or, the Perl program could have # created a non-static handle and used it to submit a CREATE HANDLE request # to the HANDLE service to create a static handle. use PLSTAF; $staticHandleNumber = $ENV{'STAF_STATIC_HANDLE'}; if ($staticHandleNumber == undef) { print "STAF_STATIC_HANDLE is undefined"; exit 1; } print "Using STAF static handle $staticHandleNumber\n"; # Register with STAF using a static handle that already exists $handle = STAF::STAFHandle->new($staticHandleNumber, $STAF::STAFHandle::kStatic); print "Static STAF handle: $handle->{handle}\n"; $result = $handle->submit("local", "ping", "ping"); if (($result->{rc} != $STAF::kOk) or ($result->{result} != "PONG")) { print "Error on ping request.\n"; print "Expected RC: 0, Result: PONG\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; }
where,
LOCATION is the system to which the request should be submitted. "Local" may be used to represent the local system, i.e., the system on which the Perl program is running.
SERVICE is the name of the service to which the request should be submitted.
REQUEST is the actual request string itself.
In addition, if auto-unmarshalling is enabled for the handle that called the submit() method (e.g. if the handle's doUnmarshallResult field is set to 1), the STAF::STAFResult object also contains the marshalling context for the result (e.g. the unmarshalled result) and the result object (e.g. the root object of the marshalling context) so that you don't have to call the handle's unmarshall method to unmarshall results. Otherwise, if auto-unmarshalling is disabled, the resultContext and resultObj fields in the STAF::STAFResult object will be set to undef.
$result = $handle->submit("local", "ping", "ping"); if ($result->{rc} != $STAF::kOk) { print "Error submitting ping request, RC: $result->{rc}\n"; if (length($result->{result}) != 0) { print "Additional info: $result->{result}\n"; } exit $result->{rc}; } print "STAF Ping result: $result->{result}\n";
$result = $handle->submit("local", "misc", "whoami"); if ($result->{rc} != $STAF::kOk) { print "Error submitting MISC WHOAMI request, RC: $result->{rc}\n"; if (length($result->{result}) != 0) { print "Additional info: $result->{result}\n"; } exit $result->{rc}; } print "MISC WHOAMI result: $result->{resultContext}\n"; print "UUID: $result->{resultObj}->{instanceUUID}\n";
# Submit a PROCESS START request and wait for it to complete my $command = 'dir {STAF/Config/STAFRoot}'; my $request = "START SHELL COMMAND ".STAF::WrapData($command). " RETURNSTDOUT STDERRTOSTDOUT WAIT"; print "\nSTAF local PROCESS $request\n"; my $result = $handle->submit("local", "PROCESS", $request); if ($result->{rc} != $STAF::kOk) { print "Error on STAF local PROCESS $request\n"; print "Expected RC: 0\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } # The result is a marshalling context whose root object is a # map containing keys 'rc', and 'fileList'. The value for # 'fileList' is a list of the returned files. Each entry in the # list consists of a map that contains keys 'rc' and 'data'. # In our PROCESS START request, we returned one file, stdout (and # returned stderr to this same file). # Get process RC my $processRC = $result->{resultObj}->{rc}; # Verify that the rc is 0 for returning data for the Stdout file my $stdoutRC = $result->{resultObj}->{fileList}[0]{rc}; if ($stdoutRC != $STAF::kOk) { print "Error on retrieving process's stdout data.\n"; print "Expected RC: 0\n"; print "Received RC: $stdoutRC\n"; exit $stdoutRC; } # Print the data in the stdout file created by the process my $stdoutData = $result->{resultObj}->{fileList}[0]{data}; print "\nProcess Stdout File Contains:\n"; print "$stdoutData\n"; # Verify that the process rc is 0 if ($processRC != $STAF::kOk) { print "Process RC: $processRC\n"; print "Expected Process RC: 0\n"; exit $processRC; }
This example could print the following when run:
STAF local PROCESS START SHELL COMMAND :26:dir {STAF/Config/STAFRoot} RETURNSTDOUT STDERRTOSTDOUT WAIT Process Stdout File Contains: Volume in drive C has no label. Volume Serial Number is B0B7-F95A Directory of C:\STAF 01/26/2006 02:56p <DIR> . 01/26/2006 02:56p <DIR> .. 01/26/2006 02:56p <DIR> lib 01/26/2006 02:56p <DIR> codepage 01/26/2006 02:56p <DIR> samples 01/26/2006 02:57p <DIR> include 01/26/2006 02:57p <DIR> bin 02/25/2008 01:30p 17,029 LICENSE.htm 01/26/2006 03:04p <DIR> docs 01/26/2006 03:11p <DIR> data 02/12/2008 05:05p 25 STAFReg.inf 06/05/2008 10:17a 8,729 NOTICES.htm 06/24/2008 04:34p 77 install.properties 4 File(s) 72,601 bytes 9 Dir(s) 8,199,012,352 bytes free
This example shows the use of the STAFResult class when submitting a request to a STAF service using a handle that has auto-unmarshalling results enabled.
# Set $dir to a directory name whose contents will be listed my $dir = "C:/tmp"; my $request = "LIST DIRECTORY $dir LONG"; print "STAF local FS $request\n\n"; my $result = $handle->submit("local", "FS", $request); if ($result->{rc} != $STAF::kOk) { print "Error on STAF local FS $request\n"; print "Expected RC: 0\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } # The result is a marshalling context whose root object is a "reference" # to an array. Each item in the array is a "reference" to a hash/map. for my $itemMap (@{$result->{resultObj}) { print "Type: $itemMap->{type} Size: $itemMap->{size} Name: $itemMap->{name}\n"; }
This example could print the following when run:
STAF local FS LIST DIRECTORY C:/tmp LONG Type: D Size: 0 Name: test1 Type: F Size: 44 Name: AutoFVT.bsh Type: D Size: 0 Name: tmp2 Type: F Size: 12505 Name: testA.exe Type: D Size: 0 Name: test Type: D Size: 0 Name: temp2 Type: D Size: 0 Name: test2 Type: D Size: 0 Name: openssl Type: F Size: 36 Name: myfile.txt
where,
SYNCOPTION can be any of the following:
LOCATION is the system to which the request should be submitted. "Local" may be used to represent the local system, i.e., the system on which the Perl program is running.
SERVICE is the name of the service to which the request should be submitted.
REQUEST is the actual request string itself.
In addition, if auto-unmarshalling is enabled for the handle that called the submit() method (e.g. if the handle's doUnmarshallResult field is set to 1), the STAF::STAFResult object also contains the marshalling context for the result (e.g. the unmarshalled result) and the result object (e.g. the root object of the marshalling context) so that you don't have to call the handle's unmarshall method to unmarshall results. Otherwise, if auto-unmarshalling is disabled, the resultContext and resultObj fields in the STAF::STAFResult object will be set to undef.
$result = $handle->submit2( $STAF::STAFHandle::kReqQueue, "local", "PING", "PING"); if ($result->{rc} != $STAF::kOk) { print "Error submitting ping request, RC: $result->{rc}\n"; if (length($result->{result}) != 0) { print "Additional info: $result->{result}\n"; } exit $result->{rc}; } print "Request Number: $result->{result}\n";
if ($rc != $STAF::kOk) {
print "Error unregistering with STAF, RC: $rc\n";
exit $rc;
}
where,
doUnmarshallResult should be 0 to disable auto-unmarshalling results or 1 to enabling auto-unmarshalling results when the handle submits a STAF service request.
Since: STAF V3.3.1
$handle->setDoUnmarshallResult(0);
Since: STAF V3.3.1
$doUnmarshallResultFlag = $handle->getDoUnmarshallResult();
Class STAF::STAFResult defines the following methods:
The required argument rc specifies the numeric return code
of the service request.
The required argument result specifies a string result buffer
returned from the service request.
The optional argument doUnmarshallResult specifies whether
auto-unmarshalling results should be performed. It should be 0 or 1.
Note: The doUnmarshallResult argument was added in STAF V3.3.1.
Class STAF::STAFResult defines the following member variables. They are initialized by the constructor, and should not be modified directly.
my $result = STAF::STAFResult->new(0, 'Successful'); print "RC: $result->{rc}, Result: $result->{result}\n";
The following example shows the use of the STAFResult class in calling a STAF service that returns a simple string result.
# The variable "handle" is an instance of the STAFHandle class that was # previously instantiated $result = $handle->submit("local", "ping", "ping"); print "Ping request RC: $handle->{rc}\n"; print "Ping request result buffer: $result->{result}\n";
The following example shows the use of the STAFResult class in calling a STAF service that returns a marshalled map result.
# The variable "handle" is an instance of the STAFHandle class that was # previously instantiated $result = $handle->submit("local", "misc", "whoami"); print "MISC WHOAMI request RC: $handle->{rc}\n"; print "MISC WHOAMI request result buffer: $result->{resultContext}\n"; print "UUID: $result->{resultObj}->{instanceUUID}\n";
Note that STAF::STAFUtil::WrapData is an alias for the STAF::wrapData function and can be used instead to call this function.
my $message = "Hello World"; $result = $handle->submit( "local", "monitor", "log message ".STAF::WrapData($message)); if ($result->{rc} == $STAF::kOk) { print "Error logging message to Monitor,". " RC: $result->{rc} Result: $result->{result}\n"; exit $result->{rc}; }
These APIs allow you to define, manipulate, and (un)marshall data structures, and print marshalled data in human-readable ("pretty" print) format.
STAF supports the automatic marshalling and unmarshalling of structured data. The act of marshalling takes a data structure and converts it into a string-based representation. The act of unmarshalling reverses this and converts the string-based representation back into a data structure. See Section 6.1, "Marshalling Structured Data" in the STAF User's Guide for more information.
Class STAF::STAFMapClassDefinition defines the following methods:
The optional keyword argument name specifies the name of the STAF map class definition. The default is an empty string.
Since: STAF V3.2.4
The required keyword argument keyName specifies the name of a key.
The optional keyword argument displayName specifies a string to use when displaying the key. The default is None which indicates to use the actual key name when displaying the key.
The required keyword argument keyName specifies the name of a key for which this property is being set.
The required keyword argument property specifies the name of the property being set. The only property name currently recognized isropery name currently recognized is 'display-short-name'.
The required keyword argument value specifies the value for the property being set.
my $myMapClassDef = STAF::STAFMapClassDefinition->new('Test/MyMap'); $myMapClassDef->addKey('name', 'Name'); $myMapClassDef->addKey('exec', "Executable"); $myMapClassDef->addKey('testType', 'Test Type'); $myMapClassDef->setKeyProperty('testType', 'display-short-name', 'Test'); $myMapClassDef->addKey('outputList', 'Outputs'); my $myMapClassName = $myMapClassDef->name(); print "The keys in map class definition '$myMapClassName' are:\n"; my @classDefKeys = $myMapClassDef->keys(); my $classDefKeys_ref = \@classDefKeys; print STAF::STAFFormatObject($classDefKeys_ref), "\n";
The keys in map class definition 'Test/MyMap' are: [ { display-name: Name key : name } { display-name: Executable key : exec } { display-short-name: Test display-name : Test Type key : testType } { display-name: Outputs key : outputList } ]
In order to use a map class when marshalling data, you must add the map class definition to the marshalling context, set the root object of the marshalling context to the object you want to marshall, and then marshall the marshalling context itself. When you unmarshall a data structure, you will always receive a marshalling context. Any map class definitions referenced by map classes within the data structure will be present in the marshalling context.
The primary use of this class is to represent multi-valued results that consist of a data structure (e.g. results from a QUERY/LIST service request, etc.) as a string that can also be converted back into the data structure. This string can be assigned to the string result buffer returned from the service request.
Class STAFMarshallingContext defines the following methods:
The optional keyword argument obj specifies the root object to be marshalled. The default is an empty string.
Since: STAF V3.2.4
Since: STAF V3.2.4
Since: STAF V3.2.4
# Create a map class definition my $myMapClassDef = STAF::STAFMapClassDefinition->new('Test/MyMap'); $myMapClassDef->addKey('name', 'Name'); $myMapClassDef->addKey('exec', 'Executable'); # Create an array (aka list) of hashes (aka maps) my @testList = ( {name => 'TestA', exec => '/tests/TestA.py'}, {name => 'TestB', exec => '/tests/TestB.sh'}, {name => 'TestC', exec => '/tests/TestC.cmd'} ); # Create a reference to the array (aka list) my $testList_ref = \@testList; # Create a marshalling context with one map class definition my $mc = STAF::STAFMarshallingContext->new(); $mc->setMapClassDefinition($myMapClassDef); # Create an array (aka list) of map class map data my @myTestList; foreach my $test (@$testList_ref) { my $testMap = $myMapClassDef->createInstance(); $testMap->{'name'} = $test->{'name'}; $testMap->{'exec'} = $test->{'exec'}; push @myTestList, $testMap; } # Assign a reference to the array (aka list) as the root object # for the marshalling context $mc->setRootObject(\@myTestList); print "Test List:\n", $mc->formatObject(), "\n"; # Create a string from the marshalling context # This string could be a message that you log or send to a queue, etc. my $stringResult = $mc->marshall(); # Convert the marshalled string representation back into an array (aka list) my $mc2 = STAF::STAFUnmarshall($stringResult); my $theTestList = $mc2->getRootObject();
Test List: [ { Name : TestA Executable: /tests/TestA.py } { Name : TestB Executable: /tests/TestB.sh } { Name : TestC Executable: /tests/TestC.cmd } ]
if (STAF::STAFIsMarshalledData($result->{result})) { my $mc = STAF::STAFUnmarshall($result->{result}); }
The default for optional keyword argument context is None.
Note, normally you would use a STAFMarshallingContext object's marshall() method instead of this function.
Since: STAF V3.2.4
my $myTestMap = { 'name' => 'TestA', 'exec' => '/tests/TestA.py', 'testType' => 'FVT', 'outputs' => [ 'TestA.out', 'TestA.err' ] }; my $message = STAF::STAFMarshall($myTestMap); my $rc = STAF::Submit('local', 'QUEUE', "QUEUE MESSAGE $message"); if ($rc != $STAF::kOk) { print "QUEUE MESSAGE failed with RC=$STAF::RC Result=$STAF::Result\n"; exit $rc; } # Another process could obtain the message from the queue and unmarshall # it to get the original hash (map) object my $rc = STAF::Submit('local', 'QUEUE', 'GET'); if ($rc == $STAF::kOk) { my $mc = STAF::STAFUnmarshall($STAF::Result); my $yourTestMap = $mc->getRootObject(); print "Received following message:\n", $mc->formatObject(), "\n"; } else { print "QUEUE GET failed with RC=$STAF::RC Result=$STAF::Result\n"; exit $rc; }
Received following message: { Priority : 5 Date-Time : 20071022-14:42:15 Machine : local://local Handle Name: Lang/Perl/Test/Basic Handle : 126 User : none://anonymous Type :Message : { testType: FVT outputs : [ TestA.out TestA.err ] name : TestA exec : /tests/TestA.py } }
# Create a map class definition my $myMapClassDef = STAF::STAFMapClassDefinition->new('Test/MyMap'); $myMapClassDef->addKey('name', 'Name'); $myMapClassDef->addKey('exec', 'Executable'); # Create a Perl array (aka list) where each entry is a hash (aka map) my @testList = ( {name => 'TestA', exec => '/tests/TestA.py'}, {name => 'TestB', exec => '/tests/TestB.sh'}, {name => 'TestC', exec => '/tests/TestC.cmd'} ); # Create a marshalling context with testList and one map class definition my $mc = STAF::STAFMarshallingContext->new(); $mc->setMapClassDefinition($myMapClassDef); my @myTestList; my $testList_ref = \@testList; foreach my $test (@$testList_ref) { my $testMap = $myMapClassDef->createInstance(); $testMap->{'name'} = $test->{'name'}; $testMap->{'exec'} = $test->{'exec'}; push @myTestList, $testMap; } # Assign a reference to the array (aka list) my $myTestList_ref = \@myTestList; print "Test List:\n" print STAF::STAFFormatObject($myTestList_ref, $mc), "\n"; my $marshalledString = STAF::STAFMarshall($myTestList_ref, $mc);
The required keyword argument data is a string to be unmarshalled.
The optional keyword argument context specifies the STAF::STAFMarshallingContext object that should be used when generating when unmarshalling the string. The default is None.
The optional keyword argument flags can be used to control how to unmarshall the string. When a string is unmarshalled into a data structure, it is possible that one of the string objects that is unmarshalled is itself the string form of another marshalled data structure. The default when no flags are specified is to recursively unmarshall these nested objects. To disable this additional processing, specify IGNORE_INDIRECT_OBJECTS=>1 for the flags argument.
my $rc = STAF::Submit('local', 'QUEUE', 'GET'); if ($rc == $STAF::kOk) { my $mc = STAF::STAFUnmarshall($STAF::Result); my $yourTestMap = $mc->getRootObject(); print "Received following message:\n", $mc->formatObject(), "\n"; } else { print "QUEUE GET failed with RC=$STAF::RC Result=$STAF::Result\n"; exit $rc; }
The required keyword argument obj specifies the object to be formatted in a verbose, more readable format.
The optional keyword argument context specifies the STAF::STAFMarshallingContext object that should be used when generating the "pretty print" output. The default is None.
Since: STAF V3.2.4
my $myTestMap = { 'name' => 'TestA', 'exec' => '/tests/TestA.py', 'testType' => 'FVT', 'outputs' => [ 'TestA.out', 'TestA.err' ] }; print STAF::STAFFormatObject($myTestMap);
{ testType: FVT outputs : [ TestA.out TestA.err ] name : TestA exec : /tests/TestA.py }
my $fileName = '{STAF/Config/ConfigFile}'; my $request = "QUERY ENTRY $fileName"; my $result = $handle->submit('local', 'FS', $request); if ($result->{rc} != $STAF::kOk) { print "Request failed: STAF local FS $request\n"; print "RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } my $mc = STAF::STAFUnmarshall($result->{result}); print "Formatted output:\n" print STAF::STAFFormatObject($result->{resultObject}, $result->{resultContext});
Formatted output: { Name : c:\staf\bin\STAF.cfg Type : F Upper 32-bit Size : 0 Lower 32-bit Size : 243 Modified Date-Time: 20071011-13:16:36 }
print "Formatted output:\n", $result->{resultContext}, "\n";
These APIs allow you to handle private data. See Section 7.3, "Private Data" in the STAF User's Guide for more information about handling private data.
This method should be used by anyone who wants to protect private data specified in a STAF command option that supports handling private data.
Required argument data is a String that contains data you want to protect.
Since: STAF V3.1.0
Examples:
my $password = "passw0rd"; $result = $handle->submit( "local", "PROCESS", "START SHELL COMMAND C:/tests/TestA USERNAME Test1 PASSWORD".STAF::AddPrivacyDelimiters($password));
my $password = "secret"; my $command = "C:/tests/admin -password ".STAF::AddPrivacyDelimiters($password); my $request = "START SHELL COMMAND ".STAF::WrapData($command); $result = $handle->submit("local", "PROCESS", request);
This method should be used before calling the addPrivacyDelimiters method for data that needs to be protected but may contain substrings !!@ and/or @!! that should not be mistaken for privacy delimiters .
Required argument data is a String.
Since: STAF V3.1.0
For example, if the data is "passw@!!d", this method would return "passw^@!!d".
my $password = "passw@!!d"; my $request = "START SHELL COMMAND C:/tests/TestA USERNAME Test1 PASSWORD".STAF::AddPrivacyDelimiters(STAF::EscapePrivacyDelimiters($password)); $result = $handle->submit("local", "PROCESS", request);
Required argument data is a String that may contain privacy delimiters (e.g. !!@, @!!).
Optional argument numLevels in an int that specifies the number of levels of privacy data to remove. The default is 0 which indicates to remove all levels of privacy data. Note that, generally, you'll want to remove all levels of privacy delimiters.
Since: STAF V3.1.0
Examples:
my $protectedPw = "!!@secret@!!"; my $password = STAF::RemovePrivacyDelimiters($protectedPw);
Required argument data is a String that may contain privacy delimiters (e.g. !!@, @!!).
Since: STAF V3.1.0
Examples:
my $password = "passw0rd"; my $request = "START COMMAND C:/tests/TestA.exe USERNAME Test1 PASSWORD".STAF::AddPrivacyDelimiters($password); print " STAF::MaskPrivateData($request)";
The following variables are defined which represent the handle types that can be specified for the STAF::STAFHandle->new() function. These variables were added in STAF V3.3.3.
The following variables affect the behavior of the STAFMon package. These variable values may be changed to alter the behavior of the STAFMon package.
STAF::Monitor::SystemName - The system name to which Monitor service requests should be sent (default = local) STAF::Monitor::ServiceName - The service name to which Monitor service requests should be sent (default = monitor)
where,
MESSAGE is the message to log.
OPTIONS are any additional options that should be passed on the LOG request, e.g., RESOLVEMESSAGE. The default is "".
if ($rc != $STAF::kOk) {
print "Error logging message to
Monitor, RC: $rc\n";
exit $rc;
}
where,
HANDLE is a STAF::STAFHandle object obtained at registration time.
SYSTEMNAME is the name of the system where the Monitor service is installed. The default is "LOCAL".
SERVICENAME is the name by which the Monitor service is identified. The default is "MONITOR".
where,
MESSAGE is the message to log.
OPTIONS are any additional options that should be passed on the LOG request, e.g., RESOLVEMESSAGE. The default is "".
if ($result->{rc} != $STAF::kOk) {
print "Error logging message to
Monitor, RC: $result->{rc}\n";
exit $result->{rc};
}
For a complete description of these return codes and their meaning, please see the STAF User's Guide.STAF::Log::kInvalidLevel STAF::Log::kInvalidLogFileFormat STAF::Log::kPurgeFailure
The following variables affect the behavior of the STAFLog package. These variable values may be changed to alter the behavior of the STAFLog package.
STAF::Log::SystemName - The system name to which Log service requests should be sent (default = local) STAF::Log::ServiceName - The service name to which Log service requests should be sent (default = log)
where,
LOGNAME is the name of the log.
LOGTYPE is the type of log to be created, "GLOBAL", "MACHINE", or "HANDLE". The default is "MACHINE".
MONITORMASK is the set of logging levels which will also be sent to the Monitor service. The default is "FATAL ERROR WARNING INFO STATUS".
where,
LEVEL is the level of the message to log, e.g., "WARNING" or "DEBUG".
MESSAGE is the message to log.
OPTIONS are any additional options that should be passed on the LOG request, e.g., "RESOLVEMESSAGE". The default is "".
if ($rc != $STAF::kOk) {
print "Error logging message to
Log, RC: $rc\n";
exit $rc;
}
where,
HANDLE is a STAF::STAFHandle object obtained at registration time.
LOGNAME is the name of the log.
LOGTYPE is the type of log to be created, "GLOBAL", "MACHINE", or "HANDLE". The default is "MACHINE".
MONITORMASK is the set of logging levels which will also be sent to the Monitor service. The default is "FATAL ERROR WARNING INFO STATUS".
SYSTEMNAME is the name of the system where the Log service is installed. The default is "LOCAL".
SERVICENAME is the name by which the Log service is identified. The default is "LOG".
where,
LEVEL is the level of the message to log, e.g., "WARNING" or "DEBUG".
MESSAGE is the message to log.
OPTIONS are any additional options that should be passed on the LOG request, e.g., "RESOLVEMESSAGE". The default is "".
if ($result->{rc} != $STAF::kOk) {
print "Error logging message to
Log, RC: $result->{rc}\n";
exit $result->{rc};
}
This example demonstrates using the procedural-style APIs to register with STAF, submit requests to STAF, and unregister with STAF. This example submits several different requests to the DIAG service and demonstrates how to use the STAF::wrapData API to "wrap" an option value that may contain spaces, etc. This example also shows how to unmarshall the data in the result returned by a DIAG LIST request. The result buffer for a DIAG LIST request contains a marshalled <Map:STAF/Service/Diag/AllDiagInfo> representing all of the unique trigger/source combinations. The comboList field in this map contains a marshalled <List> of <Map:STAF/Service/Diag> and this example shows how to iterate through this list of trigger/source combinations. The STAF User's Guide defines the results for each request submitted to an internal STAF service, including definitions of maps returned in a result.
The source code for this program is provided in the STAF source code directory tree at src/staf/lang/perl/TestDiagList.pl. See section "Obtaining the STAF Source Code" in the STAF Developer's Guide for instructions on how to download STAF source code.
use PLSTAF; $rc = STAF::Register("My program"); if ($rc != $STAF::kOk) { print "Error registering with STAF, RC: $STAF::RC\n"; exit $rc; } my $machine = "local"; my $service = "DIAG"; my $request = "RESET FORCE"; my $stafCmd = "STAF $machine $service $request"; print "$stafCmd\n"; $rc = STAF::Submit($machine, $service, $request); if ($rc != $STAF::kOk) { print "Error on $stafCmd\nRC: $rc, Result: $STAF::Result\n"; } my $request = "ENABLE"; my $stafCmd = "STAF $machine $service $request"; print "$stafCmd\n"; $rc = STAF::Submit($machine, $service, $request); if ($rc != $STAF::kOk) { print "Error on $stafCmd\nRC: $rc, Result: $STAF::Result\n"; STAF::UnRegister(); exit $rc; } my $trigger = "PROCESS QUERY"; my $source = "My program;client1.company.com"; my $request = "RECORD TRIGGER ".STAF::WrapData($trigger)." SOURCE ".STAF::WrapData($source); my $stafCmd = "STAF $machine $service $request"; print "$stafCmd\n"; $rc = STAF::Submit($machine, $service, $request); if ($rc != $STAF::kOk) { print "Error on $stafCmd\nRC: $rc, Result: $STAF::Result\n"; } my $trigger = "PROCESS LIST"; my $request = "RECORD TRIGGER ".STAF::WrapData($trigger)." SOURCE ".STAF::WrapData($source); my $stafCmd = "STAF $machine $service $request"; print "$stafCmd\n"; $rc = STAF::Submit($machine, $service, $request); if ($rc != $STAF::kOk) { print "Error on $stafCmd\nRC: $rc, Result: $STAF::Result\n"; } my $request = "LIST"; my $stafCmd = "STAF $machine $service $request"; print "$stafCmd\n"; $rc = STAF::Submit($machine, $service, $request); if ($rc != $STAF::kOk) { print "Error on $stafCmd\nRC: $rc, Result: $STAF::Result\n"; } my $mc = STAF::STAFUnmarshall($STAF::Result); my $rootObject = $mc->getRootObject(); print "\nFormatted Output:\n", $mc->formatObject(), "\n"; print "\nOutput obtained from fields in rootObject:\n"; print " From Date-Time : $rootObject->{fromTimestamp}\n"; print " To Date-Time : $rootObject->{toTimestamp}\n"; print " Elapsed Time : $rootObject->{elapsedTime}\n"; print " Number of Triggers: $rootObject->{numberOfTriggers}\n"; print " Number of Sources : $rootObject->{numberOfSources}\n"; print " Trigger/Source Combinations List:\n"; # Each item in the array is a "reference" to a hash/map for $itemMap (@{$rootObject->{comboList}}) { print "\n Trigger: $itemMap->{trigger}\n"; print " Source : $itemMap->{source}\n"; print " Count : $itemMap->{count}\n"; } print "\n"; my $request = "DISABLE"; my $stafCmd = "STAF $machine $service $request"; print "$stafCmd\n"; $rc = STAF::Submit($machine, $service, $request); if ($rc != $STAF::kOk) { print "Error on $stafCmd\nRC: $rc, Result: $STAF::Result\n"; } STAF::UnRegister();
This example could print the following when run:
STAF local DIAG RESET FORCE STAF local DIAG ENABLE STAF local DIAG RECORD TRIGGER :13:PROCESS QUERY SOURCE :30:My program;client1.c ompany.com STAF local DIAG RECORD TRIGGER :12:PROCESS LIST SOURCE :30:My program;client1.co mpany.com STAF local DIAG LIST Formatted Output: { From Date-Time : 20071023-15:07:11 To Date-Time : 20071023-15:07:11 Elapsed Time : 00:00:00 Number of Triggers : 2 Number of Sources : 1 Trigger/Source Combinations: [ { Trigger: PROCESS LIST Source : My program;client1.company.com Count : 1 } { Trigger: PROCESS QUERY Source : My program;client1.company.com Count : 1 } ] } Output obtained from fields in rootObject: From Date-Time : 20071023-15:07:11 To Date-Time : 20071023-15:07:11 Elapsed Time : 00:00:00 Number of Triggers: 2 Number of Sources : 1 Trigger/Source Combinations List: Trigger: PROCESS LIST Source : My program;client1.company.com Count : 1 Trigger: PROCESS QUERY Source : My program;client1.company.com Count : 1 STAF local DIAG DISABLE
This example shows a Perl program that tests most of the STAF Perl APIs.
The source code for this program is provided in the STAF source code directory tree at src/staf/lang/perl/TestPerl.pl. See section "Obtaining the STAF Source Code" in the STAF Developer's Guide for instructions on how to download STAF source code.
############################################################################# # Software Testing Automation Framework (STAF) # # (C) Copyright IBM Corp. 2002 # # # # This software is licensed under the Eclipse Public License (EPL) V1.0. # ############################################################################# use PLSTAF; use STAFMon; use STAFLog; # Register with STAF and get a STAF handle $handle = STAF::STAFHandle->new("Lang/Perl/Test/Basic"); if ($handle->{rc} != $STAF::kOk) { print "Error registering with STAF, RC: $handle->{rc}\n"; exit $handle->{rc}; } print "Using handle: $handle->{handle}\n"; print "\nTesting Class STAFHandle Methods...\n"; # Test the STAFHandle->submit API $result = $handle->submit("local", "ping", "ping"); if (($result->{rc} != $STAF::kOk) or ($result->{result} != "PONG")) { print "Error on ping request.\n"; print "Expected RC: 0, Result: PONG\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } $result = $handle->submit("local", "var", "resolve string {STAF/Config/Machine}"); if ($result->{rc} != $STAF::kOk) { print "Error resolving machine, RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } print " Verify that auto-unmarshalling result is turned on by default\n"; # Test the STAFHandle->getDoUnmarshallResult API if ($handle->getDoUnmarshallResult() != 1) { print "ERROR: handle->getDoUnmarshallResult() != 1\n"; print "Found: ", $handle->getDoUnmarshallResult(), "\n"; exit 1; } $result = $handle->submit("local", "MISC", "WHOAMI"); if ($result->{rc} != $STAF::kOk) { print "Error on MISC WHOAMI request, RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } # Make sure that the resultContext and resultObj variables in the # STAFResult class were set correctly since auto-unmarshalling result is on my $mc = STAF::STAFUnmarshall($result->{result}); my $entryMap = $mc->getRootObject(); if ($result->{resultContext} == undef) { print "ERROR: result->{resultContext} is undef\n"; exit 1; } elsif ($result->{resultContext}->getRootObject()->{instanceUUID} != $entryMap->{instanceUUID}) { print "STAFResult resultContext variable is not set correctly.\n"; print "Expected: $mc\n"; print "Found: $result->{resultContext}\n"; exit 1; } if ($result->{resultObj} == undef) { print "ERROR: result->{resultObj} is undef\n"; exit 1; } elsif ($result->{resultObj}->{instanceUUID} != $entryMap->{instanceUUID}) { print "STAFResult resultObj variable is not set correctly.\n"; print "Expected: $entryMap\n"; print "Found: $result->{resultObj}\n"; exit 1; } # Make sure that if turn off auto-unmarshalling result that the # resultContext and resultObj variables are set to None since # auto-unmarshalling result is off # Test the STAFHandle.setDoUnmarshallResult API print " Turn off auto-unmarshalling result"; $handle->setDoUnmarshallResult(0); if ($handle->getDoUnmarshallResult() != 0) { print "ERROR: handle->getDoUnmarshallResult() != 0\n"; print "Found: ", $handle->getDoUnmarshallResult(), "\n"; exit 1; } $result = $handle->submit("local", "MISC", "WHOAMI"); if ($result->{rc} != $STAF::kOk) { print "Error on MISC WHOAMI request, RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } if ($result->{resultContext} != undef) { print "ERROR: result->{resultContext} != undef\n"; print "Found: $result->{resultContext}\n"; exit 1; } if ($result->{resultObj} != undef) { print "ERROR: result->{resultObj} != undef\n"; print "Found: $result->{resultObj}\n"; exit 1; } # Make sure that if turn on auto-unmarshalling result that the # resultContext and resultObj variables are set correctly since # auto-unmarshalling result is on print " Turn on auto-unmarshalling result"; $handle->setDoUnmarshallResult(1); if ($handle->getDoUnmarshallResult() != 1) { print "ERROR: handle->getDoUnmarshallResult() != 1\n"; print "Found: ", $handle->getDoUnmarshallResult(), "\n"; exit 1; } $result = $handle->submit("local", "MISC", "WHOAMI"); if ($result->{rc} != $STAF::kOk) { print "Error on MISC WHOAMI request, RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } # Make sure that the resultContext and resultObj variables in the # STAFResult class were set correctly since auto-unmarshalling result is on my $mc = STAF::STAFUnmarshall($result->{result}); my $entryMap = $mc->getRootObject(); if ($result->{resultContext} == undef) { print "ERROR: result->{resultContext} is undef\n"; exit 1; } elsif ($result->{resultContext}->getRootObject()->{instanceUUID} != $entryMap->{instanceUUID}) { print "STAFResult resultContext variable is not set correctly.\n"; print "Expected: $mc\n"; print "Found: $result->{resultContext}\n"; exit 1; } if ($result->{resultObj} == undef) { print "ERROR: result->{resultObj} is undef\n"; exit 1; } elsif ($result->{resultObj}->{instanceUUID} != $entryMap->{instanceUUID}) { print "STAFResult resultObj variable is not set correctly.\n"; print "Expected: $entryMap\n"; print "Found: $result->{resultObj}\n"; exit 1; } # Test the STAF::Submit2 API print "\nTesting STAF::Submit2 API with \"local PING PING\"\n"; print "\nTesting \$STAF::STAFHandle::kReqSync\n"; $rc = STAF::Submit2($STAF::STAFHandle::kReqSync, "local", "PING", "PING"); if (($rc != $STAF::kOk) or ($STAF::Result ne "PONG")) { print " Error submitting \"local PING PING\", expected PONG\n"; print " Received RC: $STAF::RC, Result: $STAF::Result\n"; exit $rc; } print " Result: $STAF::Result\n"; print "\nTesting \$STAF::STAFHandle::kReqFireAndForget\n"; $rc = STAF::Submit2($STAF::STAFHandle::kReqFireAndForget, "local", "PING", "PING"); if (($rc != $STAF::kOk) or ($STAF::Result eq "PONG")) { print " Error submitting \"local PING PING\", expected Request Number\n"; print " Received RC: $STAF::RC, Result: $STAF::Result\n"; exit $rc; } print " Result: $STAF::Result\n"; print "\nTesting \$STAF::STAFHandle::kReqQueue\n"; $rc = STAF::Submit2($STAF::STAFHandle::kReqQueue, "local", "PING", "PING"); if (($rc != $STAF::kOk) or ($STAF::Result eq "PONG")) { print " Error submitting \"local PING PING\", expected Request Number\n"; print " Received RC: $STAF::RC, Result: $STAF::Result\n"; exit $rc; } print " Result: $STAF::Result\n"; print "\nTesting \$STAF::STAFHandle::kReqRetain\n"; $rc = STAF::Submit2($STAF::STAFHandle::kReqRetain, "local", "PING", "PING"); if (($rc != $STAF::kOk) or ($STAF::Result eq "PONG")) { print " Error submitting \"local PING PING\", expected Request Number\n"; print " Received RC: $STAF::RC, Result: $STAF::Result\n"; exit $rc; } print " Result: $STAF::Result\n"; print "\nTesting \$STAF::STAFHandle::kReqQueueRetain\n"; $rc = STAF::Submit2($STAF::STAFHandle::kReqQueueRetain, "local", "PING", "PING"); if (($rc != $STAF::kOk) or ($STAF::Result eq "PONG")) { print " Error submitting \"local PING PING\", expected Request Number\n"; print " Received RC: $STAF::RC, Result: $STAF::Result\n"; exit $rc; } print " Result: $STAF::Result\n"; # Test the STAFHandle->submit2 API print "\nTesting STAFHandle->submit2 API with \"local PING PING\"\n"; print "\nTesting \$STAF::STAFHandle::kReqSync\n"; $result = $handle->submit2($STAF::STAFHandle::kReqSync, "local", "PING", "PING"); if (($result->{rc} != $STAF::kOk) or ($result->{result} ne "PONG")) { print " Error submitting \"local PING PING\", expected PONG\n"; print " Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } print " Result: $result->{result}\n"; print "\nTesting \$STAF::STAFHandle::kReqFireAndForget\n"; $result = $handle->submit2($STAF::STAFHandle::kReqFireAndForget, "local", "PING", "PING"); if (($result->{rc} != $STAF::kOk) or ($result->{result} eq "PONG")) { print " Error submitting \"local PING PING\", expected Request Number\n"; print " Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } print " Result: $result->{result}\n"; print "\nTesting \$STAF::STAFHandle::kReqQueue\n"; $result = $handle->submit2($STAF::STAFHandle::kReqQueue, "local", "PING", "PING"); if (($result->{rc} != $STAF::kOk) or ($result->{result} eq "PONG")) { print " Error submitting \"local PING PING\", expected Request Number\n"; print " Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } print " Result: $result->{result}\n"; print "\nTesting \$STAF::STAFHandle::kReqRetain\n"; $result = $handle->submit2($STAF::STAFHandle::kReqRetain, "local", "PING", "PING"); if (($result->{rc} != $STAF::kOk) or ($result->{result} eq "PONG")) { print " Error submitting \"local PING PING\", expected Request Number\n"; print " Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } print " Result: $result->{result}\n"; print "\nTesting \$STAF::STAFHandle::kReqQueueRetain\n"; $result = $handle->submit2($STAF::STAFHandle::kReqQueueRetain, "local", "PING", "PING"); if (($result->{rc} != $STAF::kOk) or ($result->{result} eq "PONG")) { print " Error submitting \"local PING PING\", expected Request Number\n"; print " Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } print " Result: $result->{result}\n"; # Test the privacy APIs print "\nTesting Privacy APIs...\n"; my $pw = "secret"; my $pwWithPD = STAF::AddPrivacyDelimiters($pw); my $expectedResult = "!!@secret@!!"; print " STAF::AddPrivacyDelimiters($pw): $pwWithPD\n"; if ($pwWithPD != $expectedResult) { print "Error: STAF::AddPrivacyDelimiters($pw): $pwWithPD\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::EscapePrivacyDelimiters($pwWithPD); my $expectedResult = "^!!@secret^@!!"; print " STAF::EscapePrivacyDelimiters($pwWithPD): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::EscapePrivacyDelimiters($pwWithPD): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::MaskPrivateData($pwWithPD); my $expectedResult = "************"; print " STAF::MaskPrivateData($pwWithPD): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::MaskPrivateData($pwWithPD): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::RemovePrivacyDelimiters($pwWithPD); my $expectedResult = "secret"; print " STAF::RemovePrivacyDelimiters($pwWithPD): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($pwWithPD): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $dataWith3LevelsPD = '!!@Msg: ^!!@Pw is ^^^!!@secret^^^@!!.^@!!@!!'; my $outString = STAF::RemovePrivacyDelimiters($dataWith3LevelsPD); my $expectedResult = "Msg: Pw is !!@secret!!@"; print " STAF::RemovePrivacyDelimiters($dataWith3LevelsPD): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($dataWith3LevelsPD): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 0); print " STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 0): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 0): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 3); print " STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 3): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 3): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $expectedResult = 'Msg: !!@Pw is ^^!!@secret^^@!!.@!!'; my $outString = STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 1); print " STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 1): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $expectedResult = 'Msg: Pw is !!@secret@!!.'; my $outString = STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 2); print " STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 2): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 2): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $expectedResult = 'Msg: !!@Pw is ^^!!@secret^^@!!.@!!'; my $outString = STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 1); print " STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($dataWith3LevelsPD, 1): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $expectedResult = 'Msg: Pw is !!@secret@!!.'; my $outString = STAF::RemovePrivacyDelimiters($outString, 1); print " STAF::RemovePrivacyDelimiters($outString, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($outString, 1): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } # Test private methods passing in an empty string my $data = ''; my $expectedResult = ''; my $outString = STAF::AddPrivacyDelimiters($data); print " STAF::AddPrivacyDelimiters($data, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::AddPrivacyDelimiters($data): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::EscapePrivacyDelimiters($data); print " STAF::EscapePrivacyDelimiters($data, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::EscapePrivacyDelimiters($data): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::MaskPrivateData($data); print " STAF::MaskPrivateData($data, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::MaskPrivateData($data): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::RemovePrivacyDelimiters($data); print " STAF::RemovePrivacyDelimiters($data, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($data): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } # Test private methods passing in non-English data my $data = "‰¥"; my $expectedResult = "!!@‰¥@!!"; my $outString = STAF::AddPrivacyDelimiters($data); print " STAF::AddPrivacyDelimiters($data, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::AddPrivacyDelimiters($data): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $data = "!!@‰¥@!!"; my $expectedResult = "^!!@‰¥!@!!"; my $outString = STAF::EscapePrivacyDelimiters($data); print " STAF::EscapePrivacyDelimiters($data, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::EscapePrivacyDelimiters($data): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::MaskPrivateData($data); my $expectedResult = "********"; print " STAF::MaskPrivateData($data, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::MaskPrivateData($data): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } my $outString = STAF::RemovePrivacyDelimiters($data); my $expectedResult = "‰¥"; print " STAF::RemovePrivacyDelimiters($data, 1): $outString\n"; if ($outString != $expectedResult) { print "Error: STAF::RemovePrivacyDelimiters($data): $outString\n"; print " Should return the following instead: $expectedResult"; exit 1; } # Test the Monitor wrapper APIs print "\nTesting Monitor Service Wrapper...\n"; my $machine = $result->{result}; print " STAF/Config/Machine=$machine\n"; print " Log a message to the monitor service\n"; $rc = STAF::Monitor::Log("Hello World"); if ($rc != $STAF::kOk) { print "Error logging message to Monitor, RC: $rc\n"; exit $rc; } $mon = STAF::STAFMonitor->new($handle); $result = $mon->log("Hello World Again"); if ($result->{rc} != $STAF::kOk) { print "Error logging message to Monitor, RC: $result->{rc}\n"; exit $rc; } print "\nTesting Log Service Wrapper...\n"; print " Init Log\n"; $rc = STAF::Log::Init("TestCase1", "GLOBAL", "FATAL ERROR"); print " Log a message\n"; $rc = STAF::Log::Log("WARNING", "Unable to find specified file"); if ($rc != $STAF::kOk) { print "Error logging message to Log, RC: $rc\n"; exit $rc; } print " Init TestCase2 log\n"; $log = STAF::STAFLog->new($handle, "TestCase2", "GLOBAL", "FATAL ERROR"); $result = $log->log("WARNING", "Unable to find specified file"); if ($result->{rc} != $STAF::kOk) { print "Error logging message to Log, RC: $result->{rc}\n"; exit $result->{rc}; } $logtype = $log->getLogType(); print " Log Type: $logtype\n"; $logmask = $log->getMonitorMask(); print " Log's Monitor Mask: $logmask\n"; $system = $log->getSystemName(); print " Log Service System Name: $system\n"; $service = $log->getServiceName(); print " Log Service Name: $service\n"; print "\nTesting Class STAFMapClassDefinition's methods...\n"; print " Testing STAFMapClassDefinition new() method...\n"; my $myMapClassDef = STAF::STAFMapClassDefinition->new('Test/MyMap'); print " Testing STAFMapClassDefinition addKey() method...\n"; $myMapClassDef->addKey('name', 'Name'); $myMapClassDef->addKey('exec', "Executable"); $myMapClassDef->addKey('testType', 'Test Type'); print " Testing STAFMapClassDefinition setKeyProperty() method...\n"; $myMapClassDef->setKeyProperty('testType', 'display-short-name', 'Test'); $myMapClassDef->addKey('outputs', 'Outputs'); print " Testing STAFMapClassDefinition name() method...\n"; my $myMapClassName = $myMapClassDef->name(); my $foundKeys = 0; print " Testing STAFMapClassDefinition keys() method...\n"; for my $key ($myMapClassDef->keys()) { if ($key->{'key'} eq "name") { $foundKeys = $foundKeys + 1; } elsif ($key->{'key'} eq "exec") { $foundKeys = $foundKeys + 1; } elsif (($key->{'key'} eq "testType") && ($key->{'display-short-name'} eq "Test")) { $foundKeys = $foundKeys + 1; print " key=$key->{'key'} display-name=$key->{'display-name'}". " display-short-name=$key->{'display-short-name'}\n"; } elsif ($key->{'key'} eq "outputs") { $foundKeys = $foundKeys + 1; } } if ($foundKeys != 4) { print "ERROR: Map Class Definition does not contain the correct 4 keys.\n". "Contains $foundKeys keys.\n"; exit 1; } print " Testing STAFMapClassDefinition createInstance() method...\n"; my $myMapClass = $myMapClassDef->createInstance(); # Create a marshalling context and assign a map class definition to it print "\nTesting Class STAFMarshallingContext Methods...\n"; print " Testing STAFMarshallingContext new() method...\n"; my $mc = STAF::STAFMarshallingContext->new(); print " Testing STAFMarshallingContext setMapClassDefinition() method...\n"; $mc->setMapClassDefinition($myMapClassDef); print " Testing STAFMarshallingContext hasMapClassDefinition() method...\n"; if (!$mc->hasMapClassDefinition('Test/MyMap')) { print "Oops, map class 'Test/MyMap' doesn't exist\n"; exit 1; } # Get the map class definition from the marshalling context print " Testing STAFMarshallingContext getMapClassDefinition() method...\n"; my $mapClassDef = $mc->getMapClassDefinition('Test/MyMap'); # Set the root object for a marshalling context to be a string # and get the root object. $data = "This is a string"; $mc->setRootObject($data); my $rootObj = $mc->getRootObject(); # Set the root object for a marshalling context to be a hash (aka map) print " Testing STAFMarshallingContext getRootObject() method...\n"; my $myTestMap = { 'name' => 'TestA', 'exec' => '/tests/TestA.py', 'testType' => 'FVT', 'outputs' => [ 'TestA.out', 'TestA.err' ] }; $mc->setRootObject($myTestMap); my $rootObj = $mc->getRootObject(); print " Testing STAFMarshallingContext getPrimaryObject() method...\n"; my $priObj = $mc->getPrimaryObject(); if (!($priObj eq $mc)) { print 'Error: $mc->getPrimaryObject() != $mc', "\n"; print "mc->getPrimaryObject()=$priObj\n"; print "mc-$mc\n"; exit 1; } print " Testing STAFMarshallingContext formatObject() method...\n"; my $formattedOutput1 = $mc->formatObject(); my $formattedOutput2 = STAF::STAFFormatObject($mc->getRootObject(), $mc); if (!($formattedOutput1 eq $formattedOutput2)) { print "Error in mc->formatObject() or STAF::STAFFormatObject function\n"; print "formattedOutput1:\n$formattedOutput1\n"; print "formattedOutput2:\n$formattedOutput2\n"; exit 1; } print " Testing STAFMarshallingContext marshall() method...\n"; # Test the marshall function using a MapClassDefinition my $expectedResult2 = '@SDT/*:558:@SDT/{:398::13:map-class-map@SDT/{:370::10:Test/MyMap' . '@SDT/{:345::4:keys@SDT/[4:298:@SDT/{:50::12:display-name' . '@SDT/$S:4:Name:3:key@SDT/$S:4:name@SDT/{:57::12:display-name' . '@SDT/$S:10:Executable:3:key@SDT/$S:4:exec@SDT/{:95::12:display-name' . '@SDT/$S:9:Test Type:3:key@SDT/$S:8:testType:18:display-short-name' . '@SDT/$S:4:test@SDT/{:56::12:display-name@SDT/$S:7:Outputs:3:key' . '@SDT/$S:7:outputs:4:name@SDT/$S:10:Test/MyMap@SDT/{:138::7:outputs' . '@SDT/[2:38:@SDT/$S:9:TestA.out@SDT/$S:9:TestA.err:8:testType' . '@SDT/$S:3:FVT:4:name@SDT/$S:5:TestA:4:exec@SDT/$S:15:/tests/TestA.py'; my $marshalledResult2 = STAF::STAFMarshall($mc, $mc); if (length($marshalledResult2) != length($expectedResult2)) { print "Error: Wrong output for marshall function\n"; print "Expected to find:\n$expectedResult2\n"; print "Found:\n$marshalledResult2\n"; exit 1; } my $marshalledResult3 = $mc->marshall(); if (length($marshalledResult3) != length($expectedResult2)) { print "Error: Wrong output for marshall function\n"; print "Expected to find:\n$expectedResult2\n"; print "Found:\n$marshalledResult3\n"; exit 1; } # Create a map class definition without a name my $myDef = STAF::STAFMapClassDefinition->new(); $myDef->addKey('key1', 'Key 1'); my $myDefName = $myDef->name(); ############################################ # Next, test the STAFUnmarshall function # ############################################ print "\nTesting STAFUnmarshall()...\n"; # Submit a FS QUERY ENTRY request and unmarshall it's result (a map) print "\n STAF local FS QUERY ENTRY {STAF/Config/ConfigFile}\n\n"; $result = $handle->submit("local", "FS", "QUERY ENTRY {STAF/Config/ConfigFile}"); if ($result->{rc} != $STAF::kOk) { print "Error on FS QUERY ENTRY request.\n"; print "Expected RC: 0\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } if (!STAF::STAFIsMarshalledData($result->{result})) { print "ERROR: Not marshalled data: Result: $result->{result}\n"; } my $mc = STAF::STAFUnmarshall($result->{result}); my $entryMap = $mc->getRootObject(); if ($entryMap->{type} eq "F") { print " File Name : $entryMap->{name}\n"; print " Size : $entryMap->{lowerSize}\n"; print " Date Last Modified: $entryMap->{lastModifiedTimestamp}\n"; } else { print "Error on FS QUERY ENTRY result.\n"; print "$fileName is not a file. Type=$entryMap->{type}\n"; exit 1; } # Determine if running test on a Windows or Unix machine my $request = "RESOLVE STRING {STAF/Config/OS/Name}"; print "\n STAF local VAR $request\n"; $result = $handle->submit("local", "VAR", $request); if ($result->{rc} != $STAF::kOk) { print "Error on STAF local VAR $request\n"; print "Expected RC: 0\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } my $osName = $result->{result}; print "\n STAF/Config/OS/Name: $osName\n"; # Use command "dir" if on Windows or use "ls" if on Unix my $command = "dir {STAF/Config/STAFRoot}"; if (($osName eq "Linux") || ($osName eq "HP-UX") || ($osName eq "AIX") || ($osName eq "SunOS") || ($osName eq "OS/400") || ($osName eq "OS/390") || ($osName eq "FreeBSD") || ($osName eq "Darwin")) { $command = "ls {STAF/Config/STAFRoot}"; } # Submit a PROCESS START request without a WAIT option my $request = "START SHELL COMMAND ".STAF::WrapData($command). " RETURNSTDOUT STDERRTOSTDOUT"; print "\n STAF local PROCESS $request\n"; $result = $handle->submit("local", "PROCESS", $request); if ($result->{rc} != $STAF::kOk) { print "Error on STAF local PROCESS $request\n"; print "Expected RC: 0\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } print "\n Process Handle: $result->{result}\n"; # Submit a PROCESS START request and wait for it to complete my $request = "START SHELL COMMAND ".STAF::WrapData($command). " RETURNSTDOUT STDERRTOSTDOUT WAIT"; print "\n STAF local PROCESS $request\n"; $result = $handle->submit("local", "PROCESS", $request); if ($result->{rc} != $STAF::kOk) { print "Error on STAF local PROCESS $request\n"; print "Expected RC: 0\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } # Unmarshall the result which is a marshalling context whose # root object is a map containing keys 'rc', and 'fileList'. # The value for 'fileList' is a list of the returned files. # Each entry in the list consists of a map that contains keys # 'rc' and 'data'. In our PROCESS START request, we returned # one file, stdout (and returned stderr to this same file). my $mc = STAF::STAFUnmarshall($result->{result}); my $mcRootObject = $mc->getRootObject(); # Verify that the process rc is 0 my $processRC = $mcRootObject->{rc}; if ($processRC != $STAF::kOk) { print " Process RC: $processRC\n"; exit $processRC; } # Verify that the rc is 0 for returning data for the Stdout file my $stdoutRC = $mcRootObject->{fileList}[0]{rc}; if ($stdoutRC != $STAF::kOk) { print "Error on retrieving process's stdout data.\n"; print "Expected RC: 0\n"; print "Received RC: $stdoutRC\n"; exit $stdoutRC; } # Print the data in the stdout file created by the process my $stdoutData = $mcRootObject->{fileList}[0]{data}; print "\n Process Stdout File Contains:\n"; print "$stdoutData\n"; # Test unmarshalling data that contains indirect marshalled data print "Test unmarshalling data that contains indirect marshalled data\n\n"; # Create an array (aka list) of hashes (aka maps) my @testList = ( {name => 'TestA', exec => '/tests/TestA.py'}, {name => 'TestB', exec => '/tests/TestB.sh'}, {name => 'TestC', exec => '/tests/TestC.cmd'} ); $result = $handle->submit("local", "FS", "QUERY ENTRY {STAF/Config/ConfigFile}"); if ($result->{rc} != $STAF::kOk) { print "Error on FS QUERY ENTRY request.\n"; print "Expected RC: 0\n"; print "Received RC: $result->{rc}, Result: $result->{result}\n"; exit $result->{rc}; } # Add some marshalled data as an entry to the list push @testList, $result->{result}; my $mcWithIndirectObjects = $mc; $mcWithIndirectObjects->setRootObject(\@testList); my $marshalledData = $mcWithIndirectObjects->marshall(); print "Unmarshall using IGNORE_INDIRECT_OBJECTS=>0 flag\n"; my $mc2 = STAF::STAFUnmarshall($marshalledData, IGNORE_INDIRECT_OBJECTS=>0); my $formattedData2 = STAF::STAFFormatObject($mc2->getRootObject(), $mc2); print $formattedData2, "\n"; print "Unmarshall using IGNORE_INDIRECT_OBJECTS=>1 flag\n"; my $mc3 = STAF::STAFUnmarshall($marshalledData, $mc2, IGNORE_INDIRECT_OBJECTS=>1); my $formattedData3 = STAF::STAFFormatObject($mc3->getRootObject(), $mc3); print $formattedData3, "\n"; if ($formattedData2 eq $formattedData3) { print "formattedData2 eq formattedData3\n"; } if (!($formattedData2 eq $formattedData3) && (index($formattedData2, '@SDT/*') == -1) && (index($formattedData3, '@SDT/*') > 0)) { # Success } else { print "Error using IGNORE_INDIRECT_OBJECTS flag on unmarshall\n"; print "\nFormatted output using IGNORE_INDIRECT_OBJECTS=>0 flag:\n"; print $formattedData2, "\n"; print "\nFormatted output using IGNORE_INDIRECT_OBJECTS=>1 flag:\n"; print $formattedData3, "\n"; exit 1; } ############################################ # Next, test the STAFMarshall function # ############################################ print "\nTesting STAFMarshall()...\n\n"; # Test marshalling a scalar (e.g. a string) my $marshalledResult = STAF::STAFMarshall("This is a string"); print "Marshalled result from marshalling a string:\n$marshalledResult\n\n"; my $expectedLength = 27; if (length($marshalledResult) != $expectedLength) { print "ERROR: Incorrect marshalled data. Length is ", length($marshalledResult), " but should be $expectedLength\n\n"; } # Test marshalling a None scalar my $data = undef; my $marshalledResult = STAF::STAFMarshall($data); print "Marshalled result from marshalling a None scalar:\n$marshalledResult\n\n"; if (!($marshalledResult eq '@SDT/$0:0:')) { print 'ERROR: Incorrect marshalled data. Expected: @SDT/$0:0:', "\n\n"; } my $mc = STAF::STAFUnmarshall($marshalledResult); if (!($mc->formatObject() eq "<None>")) { print "ERROR: FormatObject for a None scalar isn't <None>\n"; print " Result: $mc->formatObject()\n\n"; } # Test marshalling a hash my $myTestMap = { 'name' => 'TestA', 'exec' => '/tests/TestA.py', 'testType' => 'FVT', 'outputs' => [ 'TestA.out', 'TestA.err' ] }; my $marshalledResult = STAF::STAFMarshall($myTestMap); print "Marshalled result from marshalling a hash:\n$marshalledResult\n\n"; my $expectedLength = 149; if (length($marshalledResult) != $expectedLength) { print "ERROR: Incorrect marshalled data. Length is ", length($marshalledResult), " but should be $expectedLength\n\n"; } # Test marshalling an array my @testList = ( {name => 'TestA', exec => '/tests/TestA.py'}, {name => 'TestB', exec => '/tests/TestB.sh'}, {name => 'TestC', exec => '/tests/TestC.cmd'} ); my $marshalledResult = STAF::STAFMarshall(\@testList); print "Marshalled result from marshalling an array:\n$marshalledResult\n\n"; my $expectedLength = 208; if (length($marshalledResult) != $expectedLength) { print "ERROR: Incorrect marshalled data. Length is ", length($marshalledResult), " but should be $expectedLength\n\n"; } # Test marshalling data using a marshalling context # Create a marshalling context and marshall it, and unmarshall it # Create a map class definition my $myMapClassDef = STAF::STAFMapClassDefinition->new('Test/MyMap'); $myMapClassDef->addKey('name', 'Name'); $myMapClassDef->addKey('exec', 'Executable'); # Create an array (aka list) of hashes (aka maps) my @testList = ( {name => 'TestA', exec => '/tests/TestA.py'}, {name => 'TestB', exec => '/tests/TestB.sh'}, {name => 'TestC', exec => '/tests/TestC.cmd'} ); # Create a reference to the array (aka list) my $testList_ref = \@testList; # Create a marshalling context with one map class definition my $mc = STAF::STAFMarshallingContext->new(); $mc->setMapClassDefinition($myMapClassDef); # Create an array (aka list) of map class map data my @myTestList; foreach my $test (@$testList_ref) { my $testMap = $myMapClassDef->createInstance(); $testMap->{'name'} = $test->{'name'}; $testMap->{'exec'} = $test->{'exec'}; push @myTestList, $testMap; } # Assign a reference to the array (aka list) as the root object # for the marshalling context $mc->setRootObject(\@myTestList); # Create a string from the marshalling context # This string could be a message that you log or send to a queue, etc. my $marshalledResult = $mc->marshall(); print "Marshalled result from marshalling a marshalling context:\n$marshalledResult\n\n"; my $expectedLength = 457; if (length($marshalledResult) != $expectedLength) { print "ERROR: Incorrect marshalled data. Length is ", length($marshalledResult), " but should be $expectedLength\n\n"; } # Convert the marshalled string representation back into an array (aka list) my $mc2 = STAF::STAFUnmarshall($marshalledResult); my $message2 = $mc2->marshall(); my $theTestList = $mc2->getRootObject(); if (length($marshalledResult) != length($message2)) { print 'Error: length($marshalledResult) != length($message2)', "\n"; print "Message:\n$marshalledResult\n"; print "Message2:\n$message2\n"; exit 1; } ############################################ # Next, test the STAFFormatObject function # ############################################ print "Testing STAFFormatObject()..."; print "\n\nPrinting formatted output for a scalar (e.g. a string):\n"; print STAF::STAFFormatObject("This is a string"); print "\n\nPrinting formatted output for None scalar (e.g. undef):\n"; print STAF::STAFFormatObject(undef); if (!(STAF::STAFFormatObject(undef) eq '<None>')) { print "ERROR: Wrong FormatObject for a None scalar\n"; print " Result: ", STAF::STAFFormatObject(undef), "\n\n"; } print "\n\nPrinting formatted output for an array:\n"; my @testList = ( {name => 'TestA', exec => '/tests/TestA.py'}, {name => 'TestB', exec => '/tests/TestB.sh'}, {name => 'TestC', exec => '/tests/TestC.cmd'} ); print STAF::STAFFormatObject(\@testList); print "\n\nPrinting formatted output for a hash:\n"; print STAF::STAFFormatObject($myTestMap); my $fileName = '{STAF/Config/ConfigFile}'; my $result = $handle->submit('local', 'FS', "QUERY ENTRY $fileName"); if (result->{rc} != STAFResult.Ok) { print "FS QUERY ENTRY $fileName failed"; print "RC=$result->{rc}, Result=$result->{result}"; exit 1; } my $mc = STAF::STAFUnmarshall($result->{result}); print "\n\nPrinting formatted output for FS QUERY ENTRY using STAFFormatObject\n"; print STAF::STAFFormatObject($mc->getRootObject(), $mc); print "\n\nPrinting formatted output for FS QUERY ENTRY using formatObject\n"; print $mc->formatObject(); # Test STAFResult->new print "\n\nTesting STAFResult->new()...\n"; my $result = STAF::STAFResult->new(0, 'Successful'); if (($result->{rc} != $STAF::kOk) or (!$result->{result} eq 'Successful')) { print "ERROR: Wrong STAFResult.". "RC: $result->{rc} Result: $result->{result}\n"; exit $result->{rc}; } # Test STAF::WrapData function print "\nTesting STAF::WrapData()...\n"; my $message = "Hello World"; $result = $handle->submit( "local", "monitor", "log message ".STAF::WrapData($message)); if ($result->{rc} != $STAF::kOk) { print "Error logging message to Monitor,". " RC: $result->{rc} Result: $result->{result}\n"; exit $result->{rc}; } # Unregister the handle print "\nUnregistering handle $handle->{handle}\n"; $rc = $handle->unRegister(); if ($rc != $STAF::kOk) { print "Error unregistering with STAF, RC: $STAF::RC\n"; exit $rc; } print "\n *** All tests successful ***\n";
This example could print the following when run:
Using handle: 31 Testing Class STAFHandle Methods... Verify that auto-unmarshalling result is turned on by default Turn off auto-unmarshalling result Turn on auto-unmarshalling result Testing STAF::Submit2 API with "local PING PING" Testing $STAF::STAFHandle::kReqSync Result: PONG Testing $STAF::STAFHandle::kReqFireAndForget Result: 211 Testing $STAF::STAFHandle::kReqQueue Result: 212 Testing $STAF::STAFHandle::kReqRetain Result: 213 Testing $STAF::STAFHandle::kReqQueueRetain Result: 214 Testing STAFHandle->submit2 API with "local PING PING" Testing $STAF::STAFHandle::kReqSync Result: PONG Testing $STAF::STAFHandle::kReqFireAndForget Result: 217 Testing $STAF::STAFHandle::kReqQueue Result: 219 Testing $STAF::STAFHandle::kReqRetain Result: 220 Testing $STAF::STAFHandle::kReqQueueRetain Result: 221 Testing Privacy APIs... STAF::AddPrivacyDelimiters(secret): !!@secret@!! STAF::EscapePrivacyDelimiters(!!@secret@!!): ^!!@secret^@!! STAF::MaskPrivateData(!!@secret@!!): ************ STAF::RemovePrivacyDelimiters(!!@secret@!!): secret STAF::RemovePrivacyDelimiters(!!@Msg: ^!!@Pw is ^^^!!@secret^^^@!!.^@!!@!!): Msg: Pw is !!@secret@!!. STAF::RemovePrivacyDelimiters(!!@Msg: ^!!@Pw is ^^^!!@secret^^^@!!.^@!!@!!, 0): Msg: Pw is !!@secret@!!. STAF::RemovePrivacyDelimiters(!!@Msg: ^!!@Pw is ^^^!!@secret^^^@!!.^@!!@!!, 3): Msg: Pw is !!@secret@!!. STAF::RemovePrivacyDelimiters(!!@Msg: ^!!@Pw is ^^^!!@secret^^^@!!.^@!!@!!, 1): Msg: !!@Pw is ^^!!@secret^^@!!.@!! STAF::RemovePrivacyDelimiters(!!@Msg: ^!!@Pw is ^^^!!@secret^^^@!!.^@!!@!!, 2): Msg: Pw is !!@secret@!!. STAF::RemovePrivacyDelimiters(!!@Msg: ^!!@Pw is ^^^!!@secret^^^@!!.^@!!@!!, 1): Msg: !!@Pw is ^^!!@secret^^@!!.@!! STAF::RemovePrivacyDelimiters(Msg: Pw is !!@secret@!!., 1): Msg: Pw is !!@secret@!!. STAF::AddPrivacyDelimiters(, 1): STAF::EscapePrivacyDelimiters(, 1): STAF::MaskPrivateData(, 1): STAF::RemovePrivacyDelimiters(, 1): STAF::AddPrivacyDelimiters(‰¥, 1): !!@‰¥@!! STAF::EscapePrivacyDelimiters(!!@‰¥@!!, 1): ^!!@‰¥^@!! STAF::MaskPrivateData(!!@‰¥@!!, 1): ********** STAF::RemovePrivacyDelimiters(!!@‰¥@!!, 1): ‰¥ Testing Monitor Service Wrapper... STAF/Config/Machine=221 Log a message to the monitor service Testing Log Service Wrapper... Init Log Log a message Init TestCase2 log Log Type: GLOBAL Log's Monitor Mask: FATAL ERROR Log Service System Name: LOCAL Log Service Name: LOG Testing Class STAFMapClassDefinition's methods... Testing STAFMapClassDefinition new() method... Testing STAFMapClassDefinition addKey() method... Testing STAFMapClassDefinition setKeyProperty() method... Testing STAFMapClassDefinition name() method... Testing STAFMapClassDefinition keys() method... key=testType display-name=Test Type display-short-name=Test Testing STAFMapClassDefinition createInstance() method... Testing Class STAFMarshallingContext Methods... Testing STAFMarshallingContext new() method... Testing STAFMarshallingContext setMapClassDefinition() method... Testing STAFMarshallingContext hasMapClassDefinition() method... Testing STAFMarshallingContext getMapClassDefinition() method... Testing STAFMarshallingContext getRootObject() method... Testing STAFMarshallingContext getPrimaryObject() method... Testing STAFMarshallingContext formatObject() method... Testing STAFMarshallingContext marshall() method... Testing STAFUnmarshall()... STAF local FS QUERY ENTRY {STAF/Config/ConfigFile} File Name : c:\staf\bin\staf3x.cfg Size : 8845 Date Last Modified: 20080721-17:33:22 STAF local VAR RESOLVE STRING {STAF/Config/OS/Name} STAF/Config/OS/Name: Win2000 STAF local PROCESS START SHELL COMMAND :26:dir {STAF/Config/STAFRoot} RETURNSTDOUT STDERRTOSTDOUT Process Handle: 32 STAF local PROCESS START SHELL COMMAND :26:dir {STAF/Config/STAFRoot} RETURNSTDOUT STDERRTOSTDOUT WAIT Process Stdout File Contains: Volume in drive C has no label. Volume Serial Number is B0B7-F95A Directory of c:\dev\sf\rel\win32\staf\retail 01/26/2006 02:56p <DIR> . 01/26/2006 02:56p <DIR> .. 01/26/2006 02:56p <DIR> lib 01/26/2006 02:56p <DIR> codepage 08/13/2008 05:24p 38,938 STAFInst 08/01/2008 01:21p 7,276 STAFInst.mfs 01/26/2006 02:56p <DIR> samples 01/26/2006 02:57p <DIR> include 01/26/2006 02:57p <DIR> bin 02/25/2008 01:30p 17,029 LICENSE.htm 01/26/2006 03:04p <DIR> docs 01/26/2006 03:11p <DIR> data 01/26/2006 03:15p <DIR> services 02/12/2008 05:05p 25 STAFReg.inf 06/05/2008 10:17a 8,729 NOTICES.htm 06/24/2008 04:34p 77 install.properties 6 File(s) 72,074 bytes 10 Dir(s) 8,451,129,344 bytes free Test unmarshalling data that contains indirect marshalled data Unmarshall using IGNORE_INDIRECT_OBJECTS=>0 flag [ { name: TestA exec: /tests/TestA.py } { name: TestB exec: /tests/TestB.sh } { name: TestC exec: /tests/TestC.cmd } { Name : c:\staf\bin\staf3x.cfg Type : F Upper 32-bit Size : 0 Lower 32-bit Size : 8845 Modified Date-Time: 20080721-17:33:22 } ] Unmarshall using IGNORE_INDIRECT_OBJECTS=>1 flag [ { name: TestA exec: /tests/TestA.py } { name: TestB exec: /tests/TestB.sh } { name: TestC exec: /tests/TestC.cmd } @SDT/*:649:@SDT/{:501::13:map-class-map@SDT/{:473::25:STAF/Service/FS/QueryInfo@SDT/{:433::4:keys@SDT/[5:371:@SDT/{:50::12:display-name@SDT/$S:4:Name:3:key@SDT/$S:4:name@SDT/{:50::12:display-name@SDT/$S:4:Type:3:key@SDT/$S:4:type@SDT/{:69::12:display-name@SDT/$S:17:Upper 32-bit Size:3:key@SDT/$S:9:upperSize@SDT/{:69::12:display-name@SDT/$S:17:Lower 32-bit Size:3:key@SDT/$S:9:lowerSize@SDT/{:83::12:display-name@SDT/$S:18:Modified Date-Time:3:key@SDT/$S:21:lastModifiedTimestamp:4:name@SDT/$S:25:STAF/Service/FS/QueryInfo@SDT/%:126::25:STAF/Service/FS/QueryInfo@SDT/$S:22:c:\staf\bin\staf3x.cfg@SDT/$S:1:F@SDT/$S:1:0@SDT/$S:4:8845@SDT/$S:17:20080721-17:33:22 ] Testing STAFMarshall()... Marshalled result from marshalling a string: @SDT/$S:16:This is a string Marshalled result from marshalling a None scalar: @SDT/$0:0: Marshalled result from marshalling a hash: @SDT/{:138::8:testType@SDT/$S:3:FVT:7:outputs@SDT/[2:38:@SDT/$S:9:TestA.out@SDT/$S:9:TestA.err:4:name@SDT/$S:5:TestA:4:exec@SDT/$S:15:/tests/TestA.py Marshalled result from marshalling an array: @SDT/[3:196:@SDT/{:55::4:name@SDT/$S:5:TestA:4:exec@SDT/$S:15:/tests/TestA.py@SDT/{:55::4:name@SDT/$S:5:TestB:4:exec@SDT/$S:15:/tests/TestB.sh@SDT/{:56::4:name@SDT/$S:5:TestC:4:exec@SDT/$S:16:/tests/TestC.cmd Marshalled result from marshalling a marshalling context: @SDT/*:446:@SDT/{:227::13:map-class-map@SDT/{:199::10:Test/MyMap@SDT/{:174::4:keys@SDT/[2:127:@SDT/{:50::12:display-name@SDT/$S:4:Name:3:key@SDT/$S:4:name@SDT/{:57::12:display-name@SDT/$S:10:Executable:3:key@SDT/$S:4:exec:4:name@SDT/$S:10:Test/MyMap@SDT/[3:196:@SDT/%:55::10:Test/MyMap@SDT/$S:5:TestA@SDT/$S:15:/tests/TestA.py@SDT/%:55::10:Test/MyMap@SDT/$S:5:TestB@SDT/$S:15:/tests/TestB.sh@SDT/%:56::10:Test/MyMap@SDT/$S:5:TestC@SDT/$S:16:/tests/TestC.cmd Testing STAFFormatObject()... Printing formatted output for a scalar (e.g. a string): This is a string Printing formatted output for None scalar (e.g. undef): <None> Printing formatted output for an array: [ { name: TestA exec: /tests/TestA.py } { name: TestB exec: /tests/TestB.sh } { name: TestC exec: /tests/TestC.cmd } ] Printing formatted output for a hash: { testType: FVT outputs : [ TestA.out TestA.err ] name : TestA exec : /tests/TestA.py } Printing formatted output for FS QUERY ENTRY using STAFFormatObject { Name : c:\staf\bin\staf3x.cfg Type : F Upper 32-bit Size : 0 Lower 32-bit Size : 8845 Modified Date-Time: 20080721-17:33:22 } Printing formatted output for FS QUERY ENTRY using formatObject { Name : c:\staf\bin\staf3x.cfg Type : F Upper 32-bit Size : 0 Lower 32-bit Size : 8845 Modified Date-Time: 20080721-17:33:22 } Testing STAFResult->new()... Testing STAF::WrapData()... Unregistering handle 31 *** All tests successful ***
*** End of Document ***