X-debugger shows unexpected changes when watching variables in a PHP server-side script - centos

I want to know if the X-debugger and/or Apache web-server could be the cause of a debugging issue that I just started seeing. I'm including the following code to show where the unexpected values occur.
Here is the script code:
// The value of $retrim is FALSE.
// The value of $lowValue is "Smokeymoke".
// The value of $highValue is "Te".
// The value of $k is 1 (ONE).
while( true ) { // The condition of the while loop isn't actually true, but is a detail
// that only adds complexity to this issue so isn't shown here.
$newLowValue = substr( $lowValue, 0, $k ); // When executed $newLowValue is
// "Smokeymoke", but should be "S"!
if( $retrim ) { // The value of $retrim is FALSE, so this if-then block of code
// isn't executed.
$newHighValue = substr( $highValue, 0, $k );
} // End of if( $retrim ) ...
if( $newLowValue !== $newHighValue ) { // However, the value of $newHightValue at
// this point doesn't show "Te", but rather
// "T" (!), but since the two aren't the same,
// even if wrong, causes the while-loop to
// exit.
break;
} // End of if( $newLowValue !== $newHighValue ) ...
++$k;
} // End of while( true ) ...
The while-loop, in the above code, exits with a break statement when $newLowValue is not same as $newHighValue. Otherwise, the loop continues executing.
However, with the values shown, the loop exits because $newLowValue and $newHighValue differ, even though the code didn't execute properly as per the comments in the code above, causing the values of these variables not to be correct.
The attachment shows the X-debugger output that I see when debugging the while-loop, above.
The server information from phpinfo.php -
OS version: Linux (CentOS) 3.10.0-514.16.1.el7.x86_64 #1
SMP Wed Apr 12 15:04:24 UTC 2017 x86_64
Apache version: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips PHP/5.6.30
X-Debugger version: 2.5.3
PHP version: 5.6.30
Symfony 2 version: 2.8.28 - app/dev/debug
The client is running -
PHP Storm version: PhpStorm 2016.3.3 Build #PS-163.13906.21, built on
March 8, 2017
Chrome Browser version: Version 75.0.3770.142 (Official Build) (64-bit)
Windows 10 Home version: 1803 OS build 17134.885

Thank you for your comments. Here is the problem that I found ...
It isn't clear from the data that I showed in my question, but the side-effect of using substr on multi-byte character strings was that sometimes the function returned the original un-truncated string, no matter the value of length parameter. Changing from substr to mb_substr stopped this from happening.
Additionally, the if( retrim ) tests, which were assigned true and false boolean values, would fail and the code block inside the if-then statements would execute even when they shouldn't. When I changed these to if( retrim === true ) along with changing to the mb_substr function, the side-effects stopped occurring.

Related

Within a gimp python-fu plug-in can one create/invoke a modal dialog (and/or register a procedure that is ONLY to be added as a temp procedure?)

I am trying to add a procedure to pop-up a modal dialog inside a plug-in.
Its purpose is to query a response at designated steps within the control-flow of the plug-in (not just acquire parameters at its start).
I have tried using gtk - I get a dialog but it is asynchronous - the plugin continues execution. It needs to operate as a synchronous function.
I have tried registering a plugin in order to take advantage of the gimpfu start-up dialogue for same. By itself, it works; it shows up in the procedural db when queried. But I never seem to be able to actually invoke it from within another plug-in - its either an execution error or wrong number of arguments no matter how many permutations I try.
[Reason behind all of this nonsense: I have written a lot of extension Python scripts for PaintShopPro. I have written a App package (with App.Do, App.Constants, Environment and the like that lets me begin to port those scripts to GIMP -- yes it is perverse, and yes sometimes the code just has to be rewritten, but for a lot of what I actual use in the PSP.API it is sufficient.
However, debugging and writing the module rhymes with witch. So. I am trying to add emulation of psp's "SetExecutionMode" (ie interactive). If
set, the intended behavior is that the App.Do() method will "pause" after/before it runs the applicable psp emulation code by popping up a simple message dialog.]
A simple modal dialogue within a gimp python-fu plug-in can be implemented via gtk's Dialog interface, specifically gtk.MessageDialog.
A generic dialog can be created via
queryDialogue = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT \
gtk.MESSAGE_QUESTION, \
gtk.BUTTONS_OK_CANCEL, "")
Once the dialog has been shown,
a synchronous response may be obtained from it
queryDialogue.show()
response = queryDialogue.run()
queryDialogue.hide()
The above assumes that the dialog is not created and thence destroyed after each use.
In the use case (mentioned in the question) of a modal dialog to manage single stepping through a pspScript in gimp via an App emulator package, the dialogue message contents need to be customized for each use. [Hence, the "" for the message argument in the Constructor. [more below]]
In addition, the emulator must be able to accept a [cancel] response to 'get out of Dodge' - ie quit the entire plug-in (gracefully). I could not find a gimpfu interface for the latter, (and do not want to kill the app entirely via gimp.exit()). Hence, this is accomplished by raising a custom Exception class [appTerminate] within the App pkg and catching the exception in the outer-most scope of the plugin. When caught, then, the plug-in returns (exits).[App.Do() can not return a value to indicate continue/exit/etc, because the pspScripts are to be included verbatim.]
The following is an abbreviated skeleton of the solution -
a plug-in incorporating (in part) a pspScript
the App.py pkg supplying the environment and App.Do() to support the pspScript
a Map.py pkg supporting how pspScripts use dot-notation for parameters
App.py demonstrates creation, customization and use of a modal dialog - App.doContinue() displays the dialogue illustrating how it can be customized on each use.
App._parse() parses the pspScript (excerpt showing how it determines to start/stop single-step via the dialogue)
App._exec() implements the pspScript commands (excerpt showing how it creates the dialogue, identifies the message widget for later customization, and starts/stops its use)
# App.py (abbreviated)
#
import gimp
import gtk
import Map # see https://stackoverflow.com/questions/2352181/how-to- use-a-dot-to-access-members-of-dictionary
from Map import *
pdb = gimp.pdb
isDialogueAvailable = False
queryDialogue = None
queryMessage = None
Environment = Map({'executionMode' : 1 })
_AutoActionMode = Map({'Match' : 0})
_ExecutionMode = Map({'Default' : 0}, Silent=1, Interactive=2)
Constants = Map({'AutoActionMode' : _AutoActionMode}, ExecutionMode=_ExecutionMode ) # etc...
class appTerminate(Exception): pass
def Do(eNvironment, procedureName, options = {}):
global appTerminate
img = gimp.image_list()[0]
lyr = pdb.gimp_image_get_active_layer(img)
parsed = _parse(img, lyr, procedureName, options)
if eNvironment.executionMode == Constants.ExecutionMode.Interactive:
resp = doContinue(procedureName, parsed.detail)
if resp == -5: # OK
print procedureName # log to stdout
if parsed.valid:
if parsed.isvalid:
_exec(img, lyr, procedureName, options, parsed, eNvironment)
else:
print "invalid args"
else:
print "invalid procedure"
elif resp == -6: # CANCEL
raise appTerminate, "script cancelled"
pass # terminate plugin
else:
print procedureName + " skipped"
pass # skip execution, continue
else:
_exec(img, lyr, procedureName, options, parsed, eNvironment)
return
def doContinue(procedureName, details):
global queryMessage, querySkip, queryDialogue
# - customize the dialog -
if details == "":
msg = "About to execute procedure \n "+procedureName+ "\n\nContinue?"
else:
msg = "About to execute procedure \n "+procedureName+ "\n\nDetails - \n" + details +"\n\nContinue?"
queryMessage.set_text(msg)
queryDialogue.show()
resp = queryDialogue.run() # get modal response
queryDialogue.hide()
return resp
def _parse(img, lyr, procedureName, options):
# validate and interpret App.Do options' semantics vz gimp
if procedureName == "Selection":
isValid=True
# ...
# parsed = Map({'valid' : True}, isvalid=True, start=Start, width=Width, height=Height, channelOP=ChannelOP ...
# /Selection
# ...
elif procedureName == "SetExecutionMode":
generalOptions = options['GeneralSettings']
newMode = generalOptions['ExecutionMode']
if newMode == Constants.ExecutionMode.Interactive:
msg = "set mode interactive/single-step"
else:
msg = "set mode silent/run"
parsed = Map({'valid' : True}, isvalid=True, detail=msg, mode=newMode)
# /SetExecutionMode
else:
parsed = Map({'valid' : False})
return parsed
def _exec(img, lyr, procedureName, options, o, eNvironment):
global isDialogueAvailable, queryMessage, queryDialogue
#
try:
# -------------------------------------------------------------------------------------------------------------------
if procedureName == "Selection":
# pdb.gimp_rect_select(img, o.start[0], o.start[1], o.width, o.height, o.channelOP, ...
# /Selection
# ...
elif procedureName == "SetExecutionMode":
generalOptions = options['GeneralSettings']
eNvironment.executionMode = generalOptions['ExecutionMode']
if eNvironment.executionMode == Constants.ExecutionMode.Interactive:
if isDialogueAvailable:
queryDialogue.destroy() # then clean-up and refresh
isDialogueAvailable = True
queryDialogue = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, "")
queryDialogue.set_title("psp/APP.Do Emulator")
queryDialogue.set_size_request(450, 180)
aqdContent = queryDialogue.children()[0]
aqdHeader = aqdContent.children()[0]
aqdMsgBox = aqdHeader.children()[1]
aqdMessage = aqdMsgBox.children()[0]
queryMessage = aqdMessage
else:
if isDialogueAvailable:
queryDialogue.destroy()
isDialogueAvailable = False
# /SetExecutionMode
else: # should not get here (should have been screened by parse)
raise AssertionError, "unimplemented PSP procedure: " + procedureName
except:
raise AssertionError, "App.Do("+procedureName+") generated an exception:\n" + sys.exc_info()
return
A skeleton of the plug-in itself. This illustrates incorporating a pspScript which includes a request for single-step/interactive execution mode, and thus the dialogues. It catches the terminate exception raised via the dialogue, and then terminates.
def generateWebImageSet(dasImage, dasLayer, title, mode):
try:
img = dasImage.duplicate()
# ...
bkg = img.layers[-1]
frameWidth = 52
start = bkg.offsets
end = (start[0]+bkg.width, start[1]+frameWidth)
# pspScript: (snippet included verbatim)
# SetExecutionMode / begin interactive single-step through pspScript
App.Do( Environment, 'SetExecutionMode', {
'GeneralSettings': {
'ExecutionMode': App.Constants.ExecutionMode.Interactive
}
})
# Selection
App.Do( Environment, 'Selection', {
'General' : {
'Mode' : 'Replace',
'Antialias' : False,
'Feather' : 0
},
'Start': start,
'End': end
})
# Promote
App.Do( Environment, 'SelectPromote' )
# und_so_weiter ...
except App.appTerminate:
raise AssertionError, "script cancelled"
# /generateWebImageSet
# _generateFloatingCanvasSetWeb.register -----------------------------------------
#
def generateFloatingCanvasSetWeb(dasImage, dasLayer, title):
mode="FCSW"
generateWebImageSet(dasImage, dasLayer, title, mode)
register(
"generateFloatingCanvasSetWeb",
"Generate Floating- Frame GW Canvas Image Set for Web Page",
"Generate Floating- Frame GW Canvas Image Set for Web Page",
"C G",
"C G",
"2019",
"<Image>/Image/Generate Web Imagesets/Floating-Frame Gallery-Wrapped Canvas Imageset...",
"*",
[
( PF_STRING, "title", "title", "")
],
[],
generateFloatingCanvasSetWeb)
main()
I realize that this may seem like a lot of work just to be able to include some pspScripts in a gimp plug-in, and to be able to single-step through the emulation. But we are talking about maybe 10K lines of scripts (and multiple scripts).
However, if any of this helps anyone else with dialogues inside plug-ins, etc., so much the better.

Eclipse console writes output only after the program has finished

I have the following D program:
void main( string[] args )
{
import core.thread, std.stdio;
for ( int i = 10; i > 0; --i )
{
writeln( i );
Thread.sleep(dur!"seconds"(1) );
}
writeln("Bang!");
}
It counts from 10 down to 1 and then outputs "Bang!". Between each output the program waits for the duration of one second. When I run this program in Eclipse (Eclipse Platform, Version: 3.8.1, Build id: debbuild) with the DDT plugin (Version: 0.8.1.v201309231) then the console output is as expected, but it apppears only until after the program has finished running.
When I start the same program from the console, then the program behaves as it should.
How can I fix that?
Put stdout.flush() before the sleep line. stdout is buffered, so flush ensures it actually gets out to the device instead of waiting in the buffer.

net-snmp perl subagent not being triggered by snmpget

I've been working on a custom SNMP Mib and I've come up against a wall while trying to get an agent to return the proper data.
MIB (validated by running smilint -l 6):
IDB-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32, enterprises
FROM SNMPv2-SMI
MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF;
idb MODULE-IDENTITY
LAST-UPDATED "201307300000Z" -- Midnight 30 July 2013
ORGANIZATION "*********"
CONTACT-INFO "email: *******"
DESCRIPTION "description"
REVISION "201307300000Z" -- Midnight 29 July 2013
DESCRIPTION "First Draft"
::= { enterprises 42134 }
iDBCompliance MODULE-COMPLIANCE
STATUS current
DESCRIPTION
"Compliance statement for iDB"
MODULE
GROUP testGroup
DESCRIPTION
"This group is a test group"
::= {idb 1}
test2 OBJECT-TYPE
SYNTAX Integer32
UNITS "tests"
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"A test object"
DEFVAL { 5 }
::= { idb 3 }
testGroup OBJECT-GROUP
OBJECTS {
test2
}
STATUS current
DESCRIPTION "all test objects"
::= { idb 2 }
END
Agent file:
#!/usr/bin/perl
use NetSNMP::OID(':all');
use NetSNMP::agent(':all');
use NetSNMP::ASN(':all');
sub myhandler {
my ($handler, $registration_info, $request_info, $requests) = #_;
print "Handling request\n";
for ($request = $requests; $request; $request = $request->next()) {
#
# Work through the list of varbinds
#
my $oid = $request->getOID();
print "Got request for oid $oi\n";
if ($request_info->getMode() == MODE_GET) {
if ($oid == new NetSNMP::OID($rootOID . ".3")) {
$request->setValue(ASN_INTEGER, 2);
}
}
}
}
{
$subagent = 0;
print "Running new agent\n";
my $rootOID = ".1.3.6.1.4.1.42134";
my $regoid = new NetSNMP::OID($rootOID);
if (!$agent) {
$agent = new NetSNMP::agent('Name'=>'my_agent_name','AgentX' => 1);
$subagent = 1;
print "Starting subagent\n";
}
print "Registering agent\n";
$agent->register("my_agent_name", $regoid, \&myhandler);
print "Agent registered\n";
if ($subagent) {
$SIG{'INT'} = \&shut_it_down;
$SIG{'QUIT'} = \&shut_it_down;
$running = 1;
while ($running) {
$agent->agent_check_and_process(1);
}
$agent->shutdown();
}
}
sub shut_it_down() {
$running = 0;
print "Shutting down agent\n";
}
When I run the agent I get the following:
Running new agent
Starting subagent!
Registering agent with oid idb
Agent registered
So I know that much is working. However when I run the following command:
snmpget -v 1 -c mycommunity localhost:161 test2.0
I get this error message:
Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: IDB-MIB::test2.0
I know from snmptranslate that the mib file is set correctly. I have even looked through the debug for snmpget (using -DALL) to make sure that the mib is being loaded and parsed correctly.
So my question is: Why is my subagent not being passed the request?
Update:
I've been told by #EhevuTov that my MIB file is not valid, however smilint does not report any issues and running snmpget -v 2c -c mycommunity localhost:161 .1.3.6.1.4.1.42134.3.0 does report the NAME of the object (IDB-MIB::test2.0) correctly, but does not find any data for it.
I am getting IDB-MIB::test2 = No Such Object available on this agent at this OID, which makes me think that my agent is not registering properly, however it's not throwing any errors.
Update 2:
I've been fiddling around with the agent code a bit. Based on the CPAN documentation (http://metacpan.org/pod/NetSNMP::agent), it looks like the $agent->register function call is supposed to return 0 if successful. So I checked the return code and got this:
Agent registered. Result: NetSNMP::agent::netsnmp_handler_registration=SCALAR(0x201e688)
Printing it out using Data::Dumper results in:
$VAR1 = bless( do{\(my $o = 34434624)}, 'NetSNMP::agent::netsnmp_handler_registration' );
I vaguely understand what bless does, but even so, I have no idea what this result is supposed to mean. So I'm starting to think that the agent is wrong somehow. Does anyone know how to debug these agents? Is there somewhere I can look to see if it's getting loaded properly into the master snmpd?
And I've solved the problem. It wasn't with the MIB, it was with the agent (which I had THOUGHT was working fine the whole time so I never bothered to check it).
I'd been running the agent stand-alone, because it seemed like it was working fine (never threw any errors when registering the handler). Apparently though, it needs to be run directly by snmpd.
I moved it to a directory that snmpd can access (because also apparently snmpd can't run scripts from /root, even though it's running as root), and added these lines in snmpd.conf:
perl print "\nRunning agents now\n";
perl do "/usr/share/snmp/agent.pl" || print "Problem running agent script: $!\n";
perl print "Agents run\n";
Note that these two lines were already present:
disablePerl false
perlInitFile /usr/share/snmp/snmp_perl.pl
I can now run the snmpget command and get the expected response.
> snmpget -v 2c -c mycommunity localhost:161 .1.3.6.1.4.1.42134.3
IDB-MIB::test2 = INTEGER: 2 tests

gmake: a target completes but $(realpath ...) doesn't find it

Environment stuff:
Solaris NFS file servers running NFS 3
Errors occur in Linux or Solaris environments
Using GNU Make 3.82
Using Sun Studio compilers, if that matters
This is a vastly simplified example of the build I'm looking at:
all: ${list of shared objects to build}
#do whatever
lib1.so: ${1s objects}
lib2.so: ${2s objects}
lib3.so: ${3s objects}
#...
%.so:
$(call CHECK_DEPENDENCIES_EXIST)
#${LD} ${LDFLAGS} ${^} -o ${#}
%.o : %.c
#do stuff
%.o : %.cc
#do stuff
define CHECK_DEPENDENCIES_EXIST =
$(if $(realpath ${^}),,$(warning No dependencies specified for ${#})false)
endef
The short & sweet: $(realpath x y z) (x/y/z get returned if they exist; returns an absolute path including no symlinks) is removing files from the list under some circumstances, and I think it has to do with NFS. It isn't predictable which target will fail. Sometimes a target will fail when it's succeeded the last 10 times. If I take #false out of the macro, the build continues without error -- that is, the linker does not complain about the supposedly missing file(s).
I'll spare you the drawn-out explanation; suffice it to say, the macro is helpful for debugging.
Turns out there's a bug in gmake. From the GNU Make 3.82 source, function.c, on or about line 2026:
while ((path = find_next_token (&p, &len)) != 0 ) {
/* ... */
if (
#ifdef HAVE_REALPATH
realpath (in, out)
#else
abspath (in, out) && stat (out, &st) == 0
#endif
)
{
/* ... */
}
}
}
/* ... */
Ocasionally, various calls to realpath would get interrupted (EINTR); nothing in this code checks errno, so it just silently fails.
So, it wasn't that the file didn't exist, it was that $(realpath ...) was being interrupted by a signal (presumably a child instance of gmake signaling its completion or something similar) and this function wasn't designed to recover from that sort of event.
To fix the problem:
while ((path = find_next_token (&p, &len)) != 0 ) {
... becomes:
while ( errno == EINTR || (path = find_next_token (&p, &len)) != 0 ) {
The || will shortcut & prevent it from marching on to the next token.

In Specman, why is my macro label for the code body returning garbage?

Similar to this post
http://feedproxy.google.com/~r/cadence/community/blogs/fv/~3/IvdCIla8_Es/extending-multiple-when-subtypes-simultaneously.aspx
I want to make a macro that does loop unrolling to get around some of the when-subtyping and inheritance issues Specman has.
I've started with:
-- macros.e
<'
define <FOREACH_UNROLL'action> "FOREACH_UNROLL (<UNROLLEES>\[<unrollee'name>,...\]) (<STATEMENTS>{<statement>;...})" as computed {
print <UNROLLEES>;
print str_split(<UNROLLEES>,"/ *, */");
for each in str_split(<UNROLLEES>,"/ *, */") {
out(it.as_a(string));
var statements := str_replace( <STATEMENTS>,"\"REPLACE_ME\"",it);
result =appendf("%s %s;",result,statements);
};
};
'>
-- main.e
<'
import macros.e
extend sys {
run() is also {
FOREACH_UNROLL [baz,foo,bar] {
out("REPLACE_ME");
out("part2","REPLACE_ME");
};
};
};
'>
When I run this, I get:
specman -c 'load $HOME/main; test'
Welcome to Specman Elite(64) (08.20.007-s) - Linked on Tue Dec 15 17:07:26
2009
Protected by U.S. Patents 6,141,630 ;6,182,258; 6,219,809; 6,347,388;
6,487,704; 6,499,132; 6,502,232; 6,519,727; 6,530,054; 6,675,138; 6,684,359;
6,687,662; 6,907,599; 6,918,076; 6,920,583; Other Patents Pending.
0 notifications were modified by command 'set notify -severity=WARNING
DEPR_START_TCM_ARG_BY_REF'
Checking license ... OK
Loading macros.e (imported by main.e) ...
read...parse...update...patch...h code...code...clean...
Loading /nfs/pdx/home/rbroger1/main.e ...
read...parse... <UNROLLEES> = "[35]"
str_split(<UNROLLEES>,"/ *, */") =
0. "[35]"
[35]
update...patch...h code...code...clean...
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
REPLACE_ME
part2REPLACE_ME
No actual running requested.
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.
If you look at the printout of <UNROLLEES>:
<UNROLLEES> = "[35]"
Why does <UNROLLEES> give me [35] instead of the body inside the curly braces? 35 is the ascii value for #, so I'm at a loss why I would get a 35...
P.S. I realize macros are from the devil, but I think code copying is worse. I have to do this because Specman isn't really polymorphic.
It turns out I needed to use the function str_expand_dots in my version of Specman (8.2).
Here is the modified macros.e:
define <FOREACH_UNROLL'action> "FOREACH_UNROLL (<UNROLLEES>\[<unrollee'name>,...\]) (<STATEMENTS>{<statement>;...})" as computed {
-- print str_expand_dots(<UNROLLEES>);
--print str_expand_dots(<STATEMENTS>);
-- print str_split(str_expand_dots(<UNROLLEES>),"/ *, */");
for each in str_split(str_expand_dots(<UNROLLEES>),"/ *, */") {
var unrollee := str_replace(it, "[","");
unrollee = str_replace(unrollee, "]","");
--out(unrollee);
var statements := str_replace( str_expand_dots(<STATEMENTS>),"\"REPLACE_ME\"",unrollee);
result =appendf("%s %s;",result,statements);
};
};
Modified main.e:
import macros;
extend sys {
run() is also {
FOREACH_UNROLL ["baz","foo","bar"] {
out("REPLACE_ME");
out("part2","REPLACE_ME");
if "REPLACE_ME" == "baz" {
out("found baz");
};
};
};
};
And the output:
Welcome to Specman Elite(64) (08.20.007-s) - Linked on Tue Dec 15 17:07:26
2009
Protected by U.S. Patents 6,141,630 ;6,182,258; 6,219,809; 6,347,388;
6,487,704; 6,499,132; 6,502,232; 6,519,727; 6,530,054; 6,675,138; 6,684,359;
6,687,662; 6,907,599; 6,918,076; 6,920,583; Other Patents Pending.
0 notifications were modified by command 'set notify -severity=WARNING
DEPR_START_TCM_ARG_BY_REF'
Checking license ... OK
Loading /nfs/pdx/home/rbroger1/macros.e (imported by main.e) ...
read...parse...update...patch...h code...code...clean...
Loading /nfs/pdx/home/rbroger1/main.e ...
read...parse...update...patch...h code...code...clean...
Doing setup ...
Generating the test using seed 1...
Starting the test ...
Running the test ...
baz
part2baz
found baz
foo
part2foo
bar
part2bar
No actual running requested.
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.