# HCVEexec.ctl: Executes HCVE Tests
# $Id: HCVEexec.ctl,v 1.14 2015/11/13 12:40:48 RDA Exp $
# ARCS: $Header: /home/cvs/cvs/RDA_8/src/scripting/lib/collect/TOOL/HCVEexec.ctl,v 1.14 2015/11/13 12:40:48 RDA Exp $
#
# Change History
# 20151113 MSC Add rule link in the failure summary.
=head1 NAME
TOOL:HCVEexec - Executes Health Check/Validation Engine Rules.
=head1 DESCRIPTION
This test module applies HCVE rules to the current context. It removes all
previous reports for that rule set.
Produces the documentation of the specified rules set as a report.
=cut
use Buffer,Collect,Env,Hcve,Message,Report,Rda,Target,Xml
var $TOC = '%TOC%'
var $TOP = '[[#Top][Back to top]]'
keep $TOC,$TOP
# -----------------------------------------------------------------------------
# Initialize the rule set treatment
# -----------------------------------------------------------------------------
section begin
var $req = $arg[0]
global $[set] = $arg[1]
var ($ret,$ttl,%grp,%rpt) = (0,$[set]->{'ttl'})
echo tput('bold'),'Performing HCVE checks ...',tput('off')
# -----------------------------------------------------------------------------
# Rule related macros
# -----------------------------------------------------------------------------
# Evaluate a HCVE condition
macro eval_hcve_condition
{var ($rul,$rid) = @arg
import %res
keep %res
# Detect circular references
$val = $res{$rid,'res'}
if compare('eq',$val,'LOOP')
return (false,undef,\
err => 'LOOP',\
msg => concat('Rule: Circular dependencies found in ',$rid))
# Check if a condition is specified
if !?$rul->get_value('condition')
return (true)
# Evaluate the condition
var $flg = false
var $tbl{'tst'} = $tst = $rul->get_value('condition','')
if compare('eq',$tst,'IS')
{var $tbl{'min'} = $min = rpl_hcve_ref($rul->get_value('minimum'))
var $flg = match($val,$min)
}
else
{var $val = nvl($res{$rid,'val'},'')
if compare('eq',$tst,'=~')
{var $tbl{'min'} = $min = rpl_hcve_ref($rul->get_value('minimum'))
var $flg = match($val,$min)
}
elsif compare('eq',$tst,'!~')
{var $tbl{'min'} = $min = rpl_hcve_ref($rul->get_value('minimum'))
var $flg = not(match($val,$min))
}
elsif match($tst,'^([=!]=|[<>]=?)$')
{var $tbl{'min'} = $min = rpl_hcve_ref($rul->get_value('minimum'))
var $flg = cond(and(isNumber($val),isNumber($min)),\
expr($tst,$val,$min),\
compare($tst,$val,$min))
}
elsif match($tst,'^B',true)
{var $tbl{'min'} = $min = rpl_hcve_ref($rul->get_value('minimum'))
var $tbl{'max'} = $max = rpl_hcve_ref($rul->get_value('maximum'))
var $flg = cond(and(isNumber($val),isNumber($min),isNumber($max)),\
and(expr('>=',$val,$min),expr('<=',$val,$max)),\
and(compare('ge',$val,$min),compare('le',$val,$max)))
}
elsif match($tst,'^N',true)
var $flg = isNumber($val)
elsif match($tst,'^O',true)
{var $tbl{'min'} = $min = rpl_hcve_ref($rul->get_value('minimum'))
var $tbl{'max'} = $max = rpl_hcve_ref($rul->get_value('maximum'))
var $flg = cond(and(isNumber($val),isNumber($min),isNumber($max)),\
or(expr('<',$val,$min),expr('>',$val,$max)),\
or(compare('lt',$val,$min),compare('gt',$val,$max)))
}
elsif match($tst,'^V[\-\+=!<>]$')
{var $tbl{'min'} = $min = rpl_hcve_ref($rul->get_value('minimum'))
var $flg = cond(compare($tst,$val,$min))
}
elsif match($tst,'^VB',true)
{var $tbl{'min'} = $min = rpl_hcve_ref($rul->get_value('minimum'))
var $tbl{'max'} = $max = rpl_hcve_ref($rul->get_value('maximum'))
var $flg = and(compare('V+',$val,$min),compare('V-',$val,$max))
}
elsif match($tst,'^VO',true)
{var $tbl{'min'} = $min = rpl_hcve_ref($rul->get_value('minimum'))
var $tbl{'max'} = $max = rpl_hcve_ref($rul->get_value('maximum'))
var $flg = or(compare('V<',$val,$min),compare('V>',$val,$max))
}
}
return ($flg, $val, %tbl)
}
# Execute a rule
macro exec_hcve_rule
{var ($rid,@lid) = @arg
import $tgt,@res,%err,%grp,%msg,%rul,%res,%stk
keep $tgt,@res,%err,%grp,%msg,%rul,%res,%stk
var $rul = $rul{$rid}
var $uid = join('_',$rid,@lid)
var $res{$uid} = {\
dsc => $rul->find('sdp_description')->get_data,\
lid => [@lid],\
mod => $mod = uc($rul->get_value('mode','?')),\
nam => $nam = $rul->get_value('name',$rid),\
res => 'LOOP',\
rid => $rid,\
val => ''}
# Check the dependencies
loop $dep ($rul->find('sdp_dependencies/sdp_dependency'))
{var $did = $dep->get_value('id','')
# Resolve the dependency
if ?find_did($did,@lid)
var $did = last
else
{if missing($rul{$did})
{debug sprintf('Executing Rule: [%-6s] %-20.20s - missing.',$did,'')
var $err{$did} = 'Rule: Missing rule'
var $res{$did} = {nam => '???',\
res => 'ERROR',\
val => 'NA'}
call push(@res,$did)
}
elsif ?exec_hcve_rule($did,cond($dep->get_value('local'),@lid,list()))
return last
}
# Check the condition
var ($flg,$val,%tbl) = eval_hcve_condition($dep,$did)
next $flg
debug sprintf('Executing Rule: [%-6s] %-20.20s - dependency failure.',\
$rid,$nam)
var $res{$uid,'dep'} = $did
if exists($tbl{'err'})
{var $res{$uid,'res'} = $tbl{'err'}
var $err{$uid} = $tbl{'msg'}
}
else
{var $res{$uid,'prv'} = $val
var $res{$uid,'res'} = $dep->get_value('result','FAILED')
var $res{$uid,'syn'} = $dep->get_value('syntax','text')
var $res{$uid,'val'} = $dep->get_value('value','NA')
call get_text($res{$uid},$dep)
loop $key (keys(%tbl))
var $res{$uid,$key} = $tbl{$key}
if $dep->get_value('error')
var $err{$uid} = last
}
call push(@res,$uid)
return undef
}
# Get the value
call push(@res,$uid)
call $[HCVE]->set_rule($rid)
var ($msg,$val) = ()
loop $itm ($rul->find('sdp_command'))
{if $itm->get_value('exec')
next skip_command(last)
var $typ = uc($itm->get_value('type','?'))
var $cmd = rpl_hcve_ref($itm->get_data)
if !$cmd
var $msg = 'Command: Missing command'
elsif compare('eq',$typ,'ATTACH')
{if ?testFile('rf',$cmd)
{var $val = basename($cmd)
var $rpt = $[OUT]->add_report('D',concat('fil_',$[set]->{'set'},'_',$val))
if $rpt->write_data($cmd)
var $val = join('|',$rpt->get_file,$cmd)
else
var $msg = join("\012",'Command:',\
'',\
$cmd,\
'',\
'Result: Copy failed')
call $[OUT]->end_report($rpt)
}
else
var $msg = join("\012",'Command:',\
'',\
$cmd,\
'',\
'Result: Cannot find or read the file')
var $res{$uid,'mod'} = $mod = 'ATTACH'
}
elsif compare('eq',$typ,'GROUP')
{if missing($grp{$cmd})
var $msg = concat("Missing group ",$cmd)
elsif exists($stk{$cmd})
var $msg = concat("Recursive call to group ",$cmd)
elsif !$grp{$cmd,'exe'}
{var $stk{$cmd} = true
loop $det (@{$grp{$cmd,'rul'}})
break ?exec_hcve_rule($det,@lid)
delete $stk{$cmd}
}
}
elsif compare('eq',$typ,'LOOP')
{if missing($grp{$cmd})
var $msg = concat("Missing group ",$cmd)
elsif exists($stk{$cmd})
var $msg = concat("Recursive call to group ",$cmd)
elsif !?$var = $itm->get_value('variable')
var $msg = concat('Missing variable')
elsif !?$inp = $itm->get_value('input')
var $msg = concat('Missing value list')
elsif !$grp{$cmd,'exe'}
{var ($stk{$cmd},@val) = (true)
loop $key (split(',',$inp))
{var $key = check(uc($key),\
'^HCVE/((\w+\.)+[A-Z]_[A-Z]\w*)$',concat('COL/TOOL.HCVE.',matches->[0]),\
'^((COL|RUN)/(\w+\.)+[A-Z]_[A-Z]\w*)$',matches->[0],\
'^((\w+\.)+[A-Z]_[A-Z]\w*)$',concat('SET.',matches->[0]))
next ${<$key>/M}
var @val = @{<$key>}
break
}
var $cnt = @val
var $fmt = cond(expr('>=',$cnt,100),'%03d',\
expr('>=',$cnt,10), '%02d',\
'%d')
var $cnt = 0
loop $val (@val)
{var $lid = sprintf($fmt,incr($cnt))
call $[HCVE]->define_variable($var,$val)
loop $det (@{$grp{$cmd,'rul'}})
break ?exec_hcve_rule($det,@lid,$lid)
}
delete $stk{$cmd}
}
}
elsif compare('eq',$typ,'PROMPT')
{var ${RUN.REQUEST.W_HCVE_INFO} = 'prompt'
var ${RUN.REQUEST.T_HCVE_PROMPT} = $cmd
var $dft = undef
if ?$itm->get_value('input')
{loop $key (split(',',last))
break ?$dft = check(uc($key),\
'^HCVE/((\w+\.)+[A-Z]_[A-Z]\w*)$',${<'COL/TOOL.HCVE',matches->[0]>},\
'^((COL|RUN)/(\w+\.)+[A-Z]_[A-Z]\w*)$',${[0]>},\
'^((\w+\.)+[A-Z]_[A-Z]\w*)$',${<'SET',matches->[0]>})
}
var ${RUN.REQUEST.T_HCVE_DEFAULT} = nvl($dft,\
determine(rpl_hcve_ref($itm->get_value('default'))))
call $[COL]->request('TOOL:HCVEexec')
var $val = $[ENV]->resolve(${RUN.REQUEST.T_HCVE_VALUE})
}
elsif compare('eq',$typ,'SQL')
{var ($val,$msg,@err) = $[HCVE]->eval_command($typ, $cmd)
if $msg
{var $msg = join("\012",'Command:',\
'',\
$cmd,\
'',\
concat('Result: ',$msg),\
'Value:',\
'',\
$val,\
'')
if @err
var $msg = join("\012",$msg,\
'Return code: ',\
'',\
@err,\
'')
}
}
else
{var ($val,$msg,@err) = $[HCVE]->eval_command($typ, $cmd)
if $msg
var $msg = join("\012",'Command:',\
'',\
$cmd,\
'',\
join('%BR%',concat('Result: ',$msg),\
concat('Value: ',nvl($val,'NA')),\
@err))
}
# Treat the error
if $msg
{debug sprintf('Executing Rule: [%-6s] %-20.20s - error encountered.',\
$uid,$nam)
var $res{$uid,'res'} = 'ERROR'
var $res{$uid,'val'} = 'NA'
var $err{$uid} = $msg
return cond(compare('eq',$mod,'VERIFY_ABORT'),$rid,undef)
}
# Define parameter and variable
var $key = $itm->get_value('parameter')
if match($key,'^((\w+\.)+\w+)$')
call $[HCVE]->set_parameter($key,$val)
if match($itm->get_value('variable'),'^(\$\w+)$')
call $[HCVE]->define_variable(last,$val)
}
# Perform the validation
debug sprintf('Executing Rule: [%-6s] %-20.20s - completed.',$rid,$nam)
var $res{$rid,'val'} = \
$res{$uid,'val'} = $[HCVE]->set_result($val)
if compare('eq',$mod,'ATTACH')
var $res{$uid,'res'} = 'ATTACH'
elsif compare('eq',$mod,'LOG')
var $res{$uid,'res'} = 'LOGGED'
elsif compare('eq',$mod,'RECORD')
var $res{$uid,'res'} = 'RECORD'
elsif compare('eq',$mod,'SECTION')
{var $res{$uid,'act'} = $prv = []
var $res{$uid,'res'} = 'PASSED'
var $res{$uid,'txt'} = $nam
# Identify the action
loop $act ($rul->find('sdp_actions/sdp_action'))
{# Check the action condition
var ($flg,undef,%tbl) = eval_hcve_condition($act,$rid)
# Apply the action
if $flg
{var $res{$uid,'res'} = $act->get_value('result','PASSED')
var $res{$uid,'txt'} = get_title($act)
loop $key (keys(%tbl))
var $res{$uid,$key} = $tbl{$key}
if $act->get_value('error')
var $err{$uid} = last
# Store the variable when requested
if match($act->get_value('variable'),'^(\$\w+)$')
call $[HCVE]->define_variable(last,$val)
break
}
call push($prv,{%tbl})
}
if and(defined($mid = $rul->get_value('message')),exists($msg{$mid}))
var $res{$uid,'nam'} = rpl_hcve_ref($msg{$mid})
}
elsif match($mod,'VERIFY(_ABORT)?')
{var $res{$uid,'act'} = $prv = []
var $res{$uid,'res'} = 'FAILED'
# Identify the action
loop $act ($rul->find('sdp_actions/sdp_action'))
{# Check the action condition
var ($flg,undef,%tbl) = eval_hcve_condition($act,$rid)
# Apply the action
if $flg
{var $res{$uid,'res'} = $act->get_value('result','FAILED')
var $res{$uid,'syn'} = $act->get_value('syntax','text')
call get_text($res{$uid},$act)
loop $key (keys(%tbl))
var $res{$uid,$key} = $tbl{$key}
if $act->get_value('error')
var $err{$uid} = last
# Store the variable when requested
if match($act->get_value('variable'),'^(\$\w+)$')
call $[HCVE]->define_variable(last,$val)
# Check if the rule execution must be aborted
if compare('eq',$mod,'VERIFY_ABORT')
{if match($res,'(FAILED|ERROR)')
return $rid
}
break
}
call push($prv,{%tbl})
}
}
# Continue the rule evaluation
return undef
}
# -----------------------------------------------------------------------------
# Internal routines
# -----------------------------------------------------------------------------
# Determine whether a dependency has been already resolved
macro find_did
{var ($did, @lid) = @arg
import %res
keep %res
while
{var $uid = join('_',$did,@lid)
if exists($res{$uid,'res'})
return $uid
if !?pop(@lid)
return undef
}
}
# Get the associated text
macro get_text
{var ($rec,$obj) = @arg
import %msg
keep %msg
# Get the text blocks
var (@lin,@txt) = ()
if ?$obj->get_value('message')
{loop $mid (split(',',rpl_hcve_ref(last)))
{if exists($msg{$mid})
call push(@lin,split('\n',rpl_hcve_ref($msg{$mid})))
}
}
else
call push(@lin,split('\n',rpl_hcve_ref($obj->get_data)))
# Format the text blocks
if compare('eq',$rec->{'syn'},'wiki')
{var ($val,%val) = ($rec->{'val'})
if isNumber($val)
var $val{$rec->{'nam'}} = 0
loop $str (split('[\|\012]',$val))
var $val{replace($str,'\[.*?\]','...',true)} = 1
loop $lin (@lin)
{if match($lin,'^\s*\|([^\|]+)\|([^\|]+\|)?(.*)\|\s*$')
{var ($str,undef,$act) = (last)
if exists($val{trim($str)})
call push(@txt,$[HCVE]->get_values($act))
}
elsif !match($lin,'^\s*\|.*\|\s*$')
call push(@txt,$[HCVE]->get_values($lin))
}
}
else
{loop $lin (@lin)
call push(@txt,fmt_hcve_str($[HCVE]->get_values($lin)))
}
if @txt
var $rec->{'txt'} = join('%BR%',@txt)
}
# Get the associated title
macro get_title
{var ($obj) = @arg
import %msg
keep %msg
# Get the text blocks
var @lin = ()
if ?$obj->get_value('message')
{loop $mid (split(',',rpl_hcve_ref(last)))
{if exists($msg{$mid})
call push(@lin,split('\n',rpl_hcve_ref($msg{$mid})))
}
}
else
call push(@lin,split('\n',rpl_hcve_ref($obj->get_data)))
return join('',@lin)
}
# Define a macro to remove references
macro rpl_hcve_ref
{var ($str) = @arg
import %res
keep %res
# Reject missing or empty string
if !$str
return $str
# Replace the references
var $chr = "\224"
while match($str,'(%+(.*?)%+)')
{var ($ref,$rid) = (last)
var $val = cond(match($rid,'\.'),$[HCVE]->get_fact($rid),$res{$rid,'val'})
if match($val,'^NA')
return 'NA:'
if ?$val
var $str = replace($str,concat('%+',$rid,'%+'),$val,true)
else
{# Escape when not a reference
var $ref = replace($ref,'%\!','%')
var $ref = replace($ref,'\!%','%')
var $ref = replace($ref,'%',$chr,true)
var $str = replace($str,concat('%+',$rid,'%+'),$ref,true)
}
}
return replace($str,$chr,'%',true)
}
# Format a result value
macro fmt_hcve_res
return concat('``',replace(encode($arg[0]),"\012",'%BR%',true),'``')
# Format a string
macro fmt_hcve_str
{var ($str,$flg) = @arg
var $str = encode($str,$flg)
var $str = replace($str,'\|','|',true)
var $str = replace($str,'\*','*',true)
var $str = replace($str,"\012",'%BR%',true)
return $str
}
# Check if a command must be skipped
macro skip_command
{loop $nam (split('\|',@arg))
{if $[HCVE]->get_fact($nam)
return false
}
return true
}
# -----------------------------------------------------------------------------
# Load the rule set
# -----------------------------------------------------------------------------
section Load
var ($rid,$tgt,@grp,%err,%grp,%msg,%res,%rul,%stk) = ()
keep $rid,$tgt,@grp,%err,%grp,%msg,%res,%rul,%stk
# Load the fact collectors
var $prv = undef
loop $fct ($[set]->{'xml'}->find('sdp_facts/sdp_fact'))
{var $uid = $fct->get_value('id','')
if !match($uid,'^\w+$')
die 'Missing or invalid fact identifier ',\
cond($prv,concat('after fact ',$prv),'at first row')
call $[HCVE]->set_fact($uid,$fct)
}
# Load the messages
var $prv = undef
loop $msg ($[set]->{'xml'}->find('sdp_messages/sdp_message'))
{var $uid = $msg->get_value('id','')
if !match($uid,'^\w+$')
die 'Missing or invalid message identifier ',\
cond($prv,concat('after message ',$prv),'at first row')
var $msg{$prv = $uid} = $msg->get_data
if $msg->get_value('prefix')
call $[HCVE]->set_parameter(concat(last,'.',$uid),$msg{$uid})
}
# Get the list of opted-out rules
var ($uid,%out) = ($[set]->{'xml'}->get_value('id'))
if ?$uid
{loop $rul (@{COL.TOOL.HCVE.SKIP.W_${VAR.uid}:@{ENV.${VAR.uid}/C}})
{if match($rul,'^\w+$')
$out{$rul} = 1
}
}
# Load the rules
loop $grp ($[set]->{'xml'}->find('sdp_group'))
{# Define the group record
var $rec = {\
exe => $grp->get_value('exec',1),\
gid => $grp->get_value('id'),\
rul => $det = [],\
ttl => $grp->get_value('title')}
var $out = $grp->get_value('opt_out')
# Load the rules
var $prv = undef
loop $rul ($grp->find('sdp_rule'))
{# Validate the rule identifier
var $uid = $rul->get_value('id','')
if !match($uid,'^\w+$')
die 'Missing or invalid rule identifier ',\
cond($prv,concat('after rule ',$prv),'at first row')
var $rul{$prv = $uid} = $rul
# Validate the dependency identifiers
loop $dep ($rul->find('sdp_dependencies/sdp_dependency'))
{if !match($dep->get_value('id',''),'^\w+$')
die 'Missing or invalid dependency identifier in rule ',$uid
}
# Add the rule to the group
if !and($rul->get_value('opt_out',$out),exists($out{$uid}))
call push($det,$uid)
}
call push(@grp,$rec)
if $rec->{'gid'}
var $grp{last} = $rec
}
# -----------------------------------------------------------------------------
# Perform the HCVE tests
# -----------------------------------------------------------------------------
section Execute
var ($hlt,@res) = (0)
keep $hlt,@res
debug 'Executing the ',$ttl,' validation rules'
if $[HCVE]->set_context(nvl($[set]->{'ini'},'TOOL:HCVEinit'))
die [$[HCVE]->purge_errors]
loop $grp (@grp)
{next !$grp->{'exe'}
loop $rid (@{$grp->{'rul'}})
break ?$hlt = exec_hcve_rule($rid)
}
# -----------------------------------------------------------------------------
# Display a result summary
# -----------------------------------------------------------------------------
section Summary
# Display the page header
if $dsp = ${SET.TOOL.HCVE.B_SUMMARY:true}
{var $fmt = "%-6s %-20.20s %-7.7s %s"
var $sct = "%-6s -- %.64s --"
dump "\012Test \042",$ttl,"\042 executed at ",${RDA.T_LOCALTIME}
dump "\012Test Results\012~~~~~~~~~~~~\012"
dump sprintf($fmt,"ID","NAME","RESULT","VALUE")
dump "====== ==================== ======= ====================================\
======"
}
# Display a rule overview
loop $uid (@res)
{var $mod = $res{$uid,'mod'}
var $nam = $res{$uid,'nam'}
var $res = $res{$uid,'res'}
var $rid = $res{$uid,'rid'}
# Determine the value contribution and display the rule result
if $dsp
{if and(compare('eq',$mod,'LOG'),\
compare('ne',$res,'ERROR'),\
compare('ne',$res,'LOOP'))
dump sprintf($fmt,$rid,$nam,$res,'See Log')
elsif compare('eq',$mod,'SECTION')
{if compare('ne',$res,'SKIPPED')
dump sprintf($sct,$rid,$res{$uid,'txt'})
}
elsif ?$res{$uid,'val'}
{var $val = replace(last,"\012",' ',true)
if expr('>',length($val),40)
var $val = concat(substr($val,0,37),'...')
dump sprintf($fmt,$rid,$nam,$res,nvl($val,''))
}
else
dump sprintf($fmt,$rid,$nam,$res,'')
}
# Check when if abort occurred
if compare('eq',$rid,$hlt)
{echo ${RDA.T_LINE}
if compare('eq',$res,'ERROR')
echo "(ABORT) Execution of rule \042",$nam,"\042 completed with errors."
else
echo "(ABORT) Execution of rule \042",$nam,"\042 was FAILED."
echo 'To be able to continue with remaing tests, this test has to be PASSED.'
echo ${RDA.T_LINE}
break
}
}
# Report execution errors
if scalar(keys(%err))
echo "\012Execution of ",last," rule(s) completed with errors."
# -----------------------------------------------------------------------------
# Produce a complete report
# -----------------------------------------------------------------------------
section Report
# Purge old reports
call setAbbr(nvl($[set]->{'abr'},'RDA_HCVE_'))
call setPrefix(concat($[set]->{'cls'},'_',$[set]->{'set'}))
call purge('C','(res|err)',0)
# Produce the result report
report res
write '---+!! Health Check/Validation for "',$ttl,'"'
write 'Tests "',$ttl,'" executed at ',${RDA.T_GMTIME},' UTC'
write
write $TOC
# Report the test results
write '---+ Test Results'
write '|*Rule*|*Name*|*Result*|*Value*|'
var $det = $arg[2]
loop $rid (@res)
{# Determine the value contribution
var $rec = $res{$rid}
var $mod = $rec->{'mod'}
var $nam = $rec->{'nam'}
var $res = $rec->{'res'}
if and(compare('eq',$mod,'ATTACH'),\
compare('ne',$res,'ERROR'),\
compare('ne',$res,'LOOP'))
{var @tbl = ()
loop $itm (split("\012",$rec->{'val'}))
{var ($lnk,$rpt) = split("\|",$itm,2)
if length($lnk)
call push(@tbl,concat('[[',$lnk,'][_blank][',nvl($rpt,$lnk),']]'))
}
var $val = join("\012",@tbl)
}
elsif and(compare('eq',$mod,'LOG'),\
compare('ne',$res,'ERROR'),\
compare('ne',$res,'LOOP'))
var $val = 'See Log'
else
var $val = $rec->{'val'}
# Display the rule result
if compare('ne',$mod,'SECTION')
{if and($det,match($res,'(FAILED|LOGGED|PASSED|SKIPPED|WARNING)'))
var $res = concat('[[#Rule',$rid,'][',$res,']]')
write '|',$rid,' |',fmt_hcve_str($nam),' |',$res,' |',fmt_hcve_res($val),' |'
}
elsif compare('ne',$res,'SKIPPED')
write '|',$rid,' | **',fmt_hcve_str($rec->{'txt'}),'** |||'
# Check when if abort occurred
if compare('eq',$rid,$hlt)
{write '---'
if compare('eq',$res,'ERROR')
write '(ABORT) Execution of rule "',$nam,'" completed with errors.'
else
write '(ABORT) Execution of rule "',$nam,'" was FAILED.'
write 'To be able to continue with remaing tests, this test has to be \
PASSED.'
write '---'
break
}
}
if scalar(keys(%err))
write 'Execution of ',last,' rule(s) completed with errors.%BR%'
write $TOP
# List Failures
prefix
{write '---+ Failure Summary'
write '|*Rule*|*Description*|*Result*|*Action*|'
}
loop $rid (keys(%res))
{var $rec = $res{$rid}
if compare('eq',$rec->{'res'},'FAILED')
write '|[[#Rule',$rid,'][',$rid,']]|',\
fmt_hcve_str($rec->{'dsc'},true),' |',\
fmt_hcve_res(replace($rec->{'val'},'[\[\]]','',true)),' |',\
$rec->{'txt'},' |'
}
if hasOutput(true)
{write $TOP
incr $ret,1
}
# Report detailed results
if $det
{var $TTL = '---+ Detailed Results'
loop $rid (keys(%res))
{var $rec = $res{$rid}
var $rul = $rul{$rid}
# Print the actions
prefix
{write $TTL
var $TTL = '---'
write '#Rule',$rid,' ---## Rule ',$rid,': ',fmt_hcve_str($res{$rid,'nam'})
write '---### Description'
write fmt_hcve_str($rec->{'dsc'},true)
}
if exists($rec->{'dep'})
{var $did = $rec->{'dep'}
write '---### Dependency Failures'
write ' * Dependency: ',$did,' - ',$res{$did,'nam'}
write ' * Result: **',$rec->{'res'},'**'
write ' * Condition: ``',\
fmt_hcve_str(join(' ',$rec->{'prv'},\
$rec->{'tst'},\
$rec->{'min'},\
$rec->{'max'})),'``'
if ?$rec->{'txt'}
write last
write
}
elsif exists($rec->{'act'})
{if @{$rec->{'act'}}
{write '---### Unmatched Actions'
loop $act (@{$rec->{'act'}})
write ' * ',\
fmt_hcve_res($rec->{'val'}),'`` ',\
fmt_hcve_str(join(' ',$act->{'tst'},\
$act->{'min'},\
$act->{'max'})),'``'
}
if ?$rec->{'tst'}
{write '---### Action'
write ' * Result: **',$rec->{'res'},'**'
write ' * Condition: ',\
fmt_hcve_res($rec->{'val'}),'`` ',\
fmt_hcve_str(join(' ',$rec->{'tst'},\
$rec->{'min'},\
$rec->{'max'})),'``'
}
else
{write '---### Default Action'
write ' * Result: **',$rec->{'res'},'**'
write ' * Value: ',fmt_hcve_res($rec->{'val'})
}
if ?$rec->{'txt'}
write last
write
}
if hasOutput(true)
write $TOP
}
# Report logged results
prefix
write '---+ Logged Results'
loop $rid (keys(%res))
{var $rec = $res{$rid}
next !compare('eq',$rec->{'res'},'LOGGED')
write '#Rule',$rid,' ---## Rule ',$rid,': ',fmt_hcve_str($rec->{'nam'})
write ''
write $rec->{'val'}
write ''
}
if hasOutput(true)
write $TOP
}
if isCreated(true)
var $rpt{'results'} = renderFile()
# Produce the error report
report err
prefix
{write '---+!! Health Check/Validation Errors for "',$ttl,'"'
write 'Tests "',$ttl,'" executed at ',${RDA.T_GMTIME},' UTC'
}
loop $rid (keys(%err))
{write '---'
write '(Error) Execution of rule ',$rid,' failed.'
write '---'
write $err{$rid}
}
if isCreated(true)
{var $rpt{'errors'} = renderReport()
incr $ret,2
}
# Indicate the results
return new($req,'OK.Exec',exit=>$ret,title=>$ttl,%rpt)
=head1 SEE ALSO
L,
L
=begin credits
=over 10
=item RDA 4.3: Joerg Doerris, Bill Loi, John Peeken, Wes Root.
=back
=end credits
=head1 COPYRIGHT NOTICE
Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
=head1 TRADEMARK NOTICE
Oracle and Java are registered trademarks of Oracle and/or its
affiliates. Other names may be trademarks of their respective owners.
=cut