OpenTTCN/Developer corner/Running test cases and obtaining results/ControlPartLib.ttcn
From OpenTTCN
Home | Developer's corner | Knowledge base | Working documents | Documentation | OpenTTCN IDE | Tutorials | Training | How do I | Frequently asked questions | Technical support |
Source code of ControlPartLib.ttcn
/**
* Copyright (c) 2010 OpenTTCN Oy
* All rights reserved
*
* OPENTTCN OY
* Web: http://www.openttcn.com Email: info@openttcn.fi
* P.O.BOX 6, FIN-53851 LAPPEENRANTA, FINLAND
*/
module ControlPartLib
{
type record of verdicttype VerdictList;
type record of float DurationList; // in seconds
type record CaseExecInfoItem
{
charstring tcName, // testcase name
VerdictList verdicts,
DurationList durations
}
type record of CaseExecInfoItem CaseExecInfoItems;
type record TestCampaignReport
{
CaseExecInfoItems caseExecInfo
}
type record of charstring ROC_Type;
function createTestCampaignReport() return TestCampaignReport
{
return { caseExecInfo := { } };
}
function createCaseExecInfoItem() return CaseExecInfoItem
{
return { tcName := "", verdicts := { }, durations := { } };
}
function appendVerdict(inout VerdictList dst, verdicttype src)
{
dst[lengthof(dst)] := src;
}
function appendDuration(inout DurationList dst, float src)
{
dst[lengthof(dst)] := src;
}
function appendCaseExecInfoItem(inout CaseExecInfoItems dst, CaseExecInfoItem src)
{
dst[lengthof(dst)] := src;
}
function split(charstring val, char separator) return ROC_Type
{
var ROC_Type result := { };
var integer size := lengthof(val);
var charstring buffer := val;
if (size == 0) { return result; }
var charstring line := "";
var char ch;
var integer index := 0;
while (index < size)
{
ch := buffer[index];
if (ch == separator)
{
if (line != "") { result[lengthof(result)] := line; }
line := "";
}
else { line := line & ch; }
index := index + 1;
}
if (line != "") { result[lengthof(result)] := line; }
return result;
}
/**
* Executes campaign of all test cases defined in the session that have names
* starting with tcNamePrefix using basic heuristic rules. Empty tcNamePrefix
* is the default and it means all test cases.
*
* Each test case is run repeatedly until pass verdict is produced, but at most
* maxRuns times and at least minRuns times in a row.
*
* Each test case duration is limited by maxCaseExecTime seconds.
*/
function heuristicExecute(
charstring tcNamePrefix := "",
float pauseBetweenCases := 0.0,
integer maxRuns := 5,
integer minRuns := 1,
float maxCaseExecTime := 20.0)
return TestCampaignReport
{
var integer i, len, j, jlen;
var boolean makePause := false;
var ROC_Type tcNames := testcasenamelist();
var integer tcNamePrefixLen := lengthof(tcNamePrefix);
var TestCampaignReport report := createTestCampaignReport();
len := lengthof(tcNames);
for (i := 0; i < len; i := i + 1)
{
var charstring tcName := tcNames[i];
var ROC_Type tcNameItems := split(tcName, ".");
var charstring shortTcName := tcNameItems[lengthof(tcNameItems) - 1];
if (lengthof(shortTcName) < tcNamePrefixLen)
{
continue;
}
if (substr(shortTcName, 0, tcNamePrefixLen) != tcNamePrefix)
{
continue;
}
var CaseExecInfoItem vinfoItem := createCaseExecInfoItem();
vinfoItem.tcName := tcName;
var boolean hasPassVerdict := false;
jlen := maxRuns;
for (j := 0; j < jlen; j := j + 1)
{
if (makePause and (pauseBetweenCases > 0.0))
{
timer T_pause := pauseBetweenCases;
T_pause.start;
T_pause.timeout;
}
timer T_measure := 1E10;
T_measure.start;
var verdicttype verdict := execute(tcName, maxCaseExecTime);
var float duration := T_measure.read;
appendVerdict(vinfoItem.verdicts, verdict);
appendDuration(vinfoItem.durations, duration);
makePause := true;
if (verdict == pass) { hasPassVerdict := true; }
if (hasPassVerdict and ((j + 1) >= minRuns)) { break; }
}
appendCaseExecInfoItem(report.caseExecInfo, vinfoItem);
}
return report;
}
function floatToStr(float val, integer precision := -1) return charstring
{
var charstring result := "";
if (val < 0.0)
{
result := "-";
val := -val;
}
result := result & int2str(float2int(val)) & ".";
val := val - int2float(float2int(val));
var float counter := val * 1E1;
if (val == 0.0) { return result & "0"; }
var charstring fraction := "";
while (counter < 1.0)
{
fraction := fraction & "0";
counter := counter * 1E1;
}
fraction := fraction & int2str(float2int(val * 1E9));
if (precision > 0)
{
fraction := substr(fraction, 0, precision);
}
result := result & fraction;
return result;
}
function getChars(integer num, char ch := " ") return charstring
{
if (num <= 0) { return ""; }
var charstring result := "";
for (var integer i := 0; i < num; i := i + 1)
{
result := result & ch;
}
return result;
}
function appendLineToResult(inout charstring result, inout charstring line)
{
result := result & line;
line := "";
}
/**
* Prepares pretty-printed textual test campaign report and returns it as
* charstring
*/
function printCampaignReport(
TestCampaignReport tcr,
boolean printDetails := false,
integer tcNameColWidth := 50)
return charstring
{
var integer i, len, j, jlen;
// %d10; ASCII LF, line feed, '\n'
const charstring LF := oct2char('0A'O);
var charstring result := "";
//////////////////////////////////////////////////////////////////////////
// Summary
result := result & LF;
result := result & getChars(tcNameColWidth - 50 + 34 + 72 + 1, "*");
result := result & LF;
result := result & "*** TEST CAMPAIGN REPORT SUMMARY";
result := result & " - Timestamp: " & int2str(otGetUnixTime()) & LF;
var charstring line := "";
line := line & getChars(tcNameColWidth, "-");
line := line & "+----------+---------+------------------------+----------" & LF;
appendLineToResult(result, line);
line := line & "Testcase";
line := line & getChars(tcNameColWidth - lengthof(line));
line := line & "| Wr.Cs.V* | Bt.Cs.V | Totals | Avg.Dur." & LF;
appendLineToResult(result, line);
line := line & getChars(tcNameColWidth, "-");
line := line & "+----------+---------+------------------------+----------" & LF;
appendLineToResult(result, line);
len := lengthof(tcr.caseExecInfo);
for (i := 0; i < len; i := i + 1)
{
var CaseExecInfoItem item := tcr.caseExecInfo[i];
line := line & item.tcName;
line := line & getChars(tcNameColWidth - lengthof(line));
line := line & "|";
var integer passNum := 0, inconcNum := 0, failNum := 0, errorNum := 0, noneNum := 0;
var float avgDuration := 0.0;
jlen := lengthof(item.verdicts);
for (j := 0; j < jlen; j := j + 1)
{
var verdicttype verdict := item.verdicts[j];
if (verdict == pass) { passNum := passNum + 1; }
else if (verdict == inconc) { inconcNum := inconcNum + 1; }
else if (verdict == fail) { failNum := failNum + 1; }
else if (verdict == error) { errorNum := errorNum + 1; }
else if (verdict == none) { noneNum := noneNum + 1; }
avgDuration := avgDuration + item.durations[j];
}
if (j != 0) { avgDuration := avgDuration / int2float(jlen); }
var charstring wcv := "none";
if (errorNum != 0) { wcv := "error"; }
else if (failNum != 0) { wcv := "fail"; }
else if (inconcNum != 0) { wcv := "inconc"; }
else if (passNum != 0) { wcv := "pass"; }
var charstring bcv := "none";
if (passNum != 0) { bcv := "pass"; }
else if (inconcNum != 0) { bcv := "inconc"; }
else if (failNum != 0) { bcv := "fail"; }
else if (errorNum != 0) { bcv := "error"; }
var charstring totals :=
int2str(passNum) & "p " &
int2str(inconcNum) & "i " &
int2str(failNum) & "f " &
int2str(errorNum) & "e " &
int2str(noneNum) & "n";
var charstring avgDurationStr := floatToStr(avgDuration, 4);
line := line & " " &
wcv & getChars(8 - lengthof(wcv)) & " | "
& bcv & getChars(7 - lengthof(bcv)) & " | "
& totals & getChars(22 - lengthof(totals)) & " | "
& avgDurationStr & LF;
appendLineToResult(result, line);
}
line := line & getChars(tcNameColWidth, "-");
line := line & "+----------+---------+------------------------+----------" & LF;
line := line &
"* Wr.Cs.V = Worst case verdict; Bt.Cs.V = Best case verdict; Avg.Dur. = Average duration in secs" & LF;
appendLineToResult(result, line);
line := line & getChars(tcNameColWidth, "-");
line := line & "---------------------------------------------------------" & LF;
appendLineToResult(result, line);
if (not printDetails) { return result; }
//////////////////////////////////////////////////////////////////////////
// Details
result := result & getChars(tcNameColWidth - 50 + 34 + 72 + 1, "*");
result := result & LF;
result := result & "*** TEST CAMPAIGN REPORT DETAILS";
result := result & " - Timestamp: " & int2str(otGetUnixTime()) & LF;
line := line & getChars(tcNameColWidth, "-");
line := line & "+-------+---------+----------" & LF;
appendLineToResult(result, line);
line := line & "Testcase";
line := line & getChars(tcNameColWidth - lengthof(line));
line := line & "| Run | Verdict | Duration" & LF;
appendLineToResult(result, line);
line := line & getChars(tcNameColWidth, "-");
line := line & "+-------+---------+----------" & LF;
appendLineToResult(result, line);
len := lengthof(tcr.caseExecInfo);
for (i := 0; i < len; i := i + 1)
{
var CaseExecInfoItem item := tcr.caseExecInfo[i];
jlen := lengthof(item.verdicts);
for (j := 0; j < jlen; j := j + 1)
{
if (j == 0) { line := line & item.tcName; }
line := line & getChars(tcNameColWidth - lengthof(line));
line := line & "|";
var charstring runNoStr := int2str(j + 1);
runNoStr := getChars(5 - lengthof(runNoStr), "0") & runNoStr;
var verdicttype verdict := item.verdicts[j];
var charstring verdictStr := "?";
if (verdict == pass) { verdictStr := "pass"; }
else if (verdict == inconc) { verdictStr := "inconc"; }
else if (verdict == fail) { verdictStr := "fail"; }
else if (verdict == error) { verdictStr := "error"; }
else if (verdict == none) { verdictStr := "none"; }
var float duration := item.durations[j];
var charstring durationStr := floatToStr(duration, 4);
line := line & " " &
runNoStr & getChars(5 - lengthof(runNoStr)) & " | "
& verdictStr & getChars(7 - lengthof(verdictStr)) & " | "
& durationStr & LF;
appendLineToResult(result, line);
}
line := line & getChars(tcNameColWidth, "-");
line := line & "+-------+---------+----------" & LF;
appendLineToResult(result, line);
}
return result;
}
}
