Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add test timeout #181

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions TcUnit/TcUnit/GVLs/GVL_TcUnit.TcGVL
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
{attribute 'qualified_only'}
VAR_GLOBAL
TcUnitRunner : FB_TcUnitRunner;
TimeoutWatcher : FB_TimeoutWatcher;

(* Indication of whether the last instantiated test suite has an assert instance created *)
TestSuiteIsRegistered : BOOL;

(* Pointer to current test suite being called *)
CurrentTestSuiteBeingCalled : POINTER TO FB_TestSuite;

(* Reference to current test being called *)
CurrentTestBeingCalled : REFERENCE TO FB_Test;

(* Current name of test being called *)
CurrentTestNameBeingCalled : Tc2_System.T_MaxString;
Expand Down
21 changes: 21 additions & 0 deletions TcUnit/TcUnit/POUs/FB_Test.TcPOU
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ VAR
TestIsFailed : BOOL; // Indication of whether this test has at least one failed assert
AssertionMessage : Tc2_System.T_MaxString; // Assertion message for the first assertion in this test
AssertionType : E_AssertionType; // Assertion type for the first assertion in this test
{attribute 'hide'}
_timeStampOfStart : ULINT;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
Expand Down Expand Up @@ -144,5 +146,24 @@ END_VAR]]></Declaration>
<ST><![CDATA[TestOrderNumber := OrderNumber;]]></ST>
</Implementation>
</Method>
<Property Name="TimeStampOfStart" Id="{98ea485f-23b3-4302-94fb-ef3c3eb87cc8}">
<Declaration><![CDATA[PROPERTY INTERNAL TimeStampOfStart : ULINT]]></Declaration>
<Get Name="Get" Id="{03131e4c-df2c-42c2-aec0-011820c2afa8}">
<Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[TimeStampOfStart := _timeStampOfStart;]]></ST>
</Implementation>
</Get>
<Set Name="Set" Id="{2c57d63e-1f5c-4ef2-9b2c-cd2f1802432c}">
<Declaration><![CDATA[VAR
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_timeStampOfStart := TimeStampOfStart;]]></ST>
</Implementation>
</Set>
</Property>
</POU>
</TcPlcObject>
29 changes: 28 additions & 1 deletion TcUnit/TcUnit/POUs/FB_TestSuite.TcPOU
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ VAR

(* Number of ordered tests (created by TEST_ORDERED()) that this test suite contains *)
NumberOfOrderedTests : UINT(0..GVL_Param_TcUnit.MaxNumberOfTestsForEachTestSuite);

Utility : FB_Utility;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
<Method Name="AddTest" Id="{d383011f-6bea-4b05-9018-ea4782ad2837}">
<Declaration><![CDATA[METHOD INTERNAL AddTest
<Declaration><![CDATA[METHOD INTERNAL AddTest : REFERENCE TO FB_Test
VAR_INPUT
TestName : Tc2_System.T_MaxString;
IsTestOrdered : BOOL;
Expand Down Expand Up @@ -128,6 +130,11 @@ IF NOT TestWithThisNameAlreadyExists THEN
END_IF
END_IF

AddTest REF= GetTestByName(TrimmedTestName);
IF AddTest.TimeStampOfStart=0 THEN
AddTest.TimeStampOfStart := Utility.GetCpuCounterAsULINT();
END_IF

(* Check if this test should be disabled *)
IF IgnoreCurrentTestCase THEN
GVL_TcUnit.IgnoreCurrentTest := TRUE;
Expand Down Expand Up @@ -3717,6 +3724,26 @@ GetNumberOfSkippedTests := SkippedTestsCount;]]></ST>
<ST><![CDATA[GetNumberOfTestsToAnalyse := MIN(GetNumberOfTests(), GVL_Param_TcUnit.MaxNumberOfTestsForEachTestSuite);]]></ST>
</Implementation>
</Method>
<Method Name="GetTestByName" Id="{7503ce60-ab36-477f-93a9-d6b044348b26}">
<Declaration><![CDATA[METHOD INTERNAL GetTestByName : REFERENCE TO FB_Test
VAR_INPUT
TestName : Tc2_System.T_MaxString;
END_VAR
VAR
IteratorCounter : UINT;
NumberOfTestsToAnalyse : UINT(1..GVL_Param_TcUnit.MaxNumberOfTestSuites);
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[NumberOfTestsToAnalyse := GetNumberOfTestsToAnalyse();
FOR IteratorCounter := 1 TO NumberOfTestsToAnalyse BY 1 DO
IF Tests[IteratorCounter].GetName() = TestName THEN
GetTestByName REF= Tests[IteratorCounter];
RETURN;
END_IF
END_FOR]]></ST>
</Implementation>
</Method>
<Method Name="GetTestByPosition" Id="{3795ba6c-bb70-4d36-8d46-fa6431157992}">
<Declaration><![CDATA[(* This method returns the test at the n'th position, ranging from 1.. NumberOfTests *)
METHOD INTERNAL GetTestByPosition : FB_Test
Expand Down
55 changes: 55 additions & 0 deletions TcUnit/TcUnit/POUs/FB_TimeoutWatcher.TcPOU
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4022.18">
<POU Name="FB_TimeoutWatcher" Id="{c00583a8-41fa-4f83-8876-8a6f8a49c4ec}" SpecialFunc="None">
<Declaration><![CDATA[{attribute 'hide_all_locals'}
FUNCTION_BLOCK INTERNAL FB_TimeoutWatcher
VAR_INPUT
Time_out : TIME := T#0S;
END_VAR
VAR
IndexOfTaskThatContainsTestSuites : BYTE := 255;
AdsPort : UINT := TwinCAT_SystemInfoVarList._AppInfo.AdsPort;
StopCmd : BOOL := FALSE;
PlcStop : PLC_Stop;
TimeoutAsULINT : ULINT;
CpuCounterULINT : ULINT;
Utility : FB_Utility;
TestSuiteInstancePath : Tc2_System.T_MaxString;
TestName : Tc2_System.T_MaxString;
ReportMessage : Tc2_System.T_MaxString;
AdsLogStringMessageFifoQueue : FB_AdsLogStringMessageFifoQueue;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[IF Time_out=T#0S OR NOT __ISVALIDREF(GVL_TcUnit.CurrentTestBeingCalled)
OR_ELSE GVL_TcUnit.CurrentTestBeingCalled.TimeStampOfStart=0
OR_ELSE GVL_TcUnit.CurrentTestBeingCalled.TestIsFinished THEN
RETURN;
END_IF

CpuCounterULINT := Utility.GetCpuCounterAsULINT();
TimeOutAsULINT := TIME_TO_ULINT(Time_out) * 10000;

IF IndexOfTaskThatContainsTestSuites = 255 THEN
IndexOfTaskThatContainsTestSuites := GVL_TcUnit.TestSuiteAddresses[1]^.GetCurrentTaskIndex.index;
END_IF
IF IndexOfTaskThatContainsTestSuites <> 255 THEN
IF CpuCounterULINT >= GVL_TcUnit.CurrentTestBeingCalled.TimeStampOfStart + TimeoutAsULINT THEN

// generate report message
TestSuiteInstancePath := GVL_TcUnit.CurrentTestSuiteBeingCalled^.InstancePath;
TestName := GVL_TcUnit.CurrentTestNameBeingCalled;
ReportMessage := CONCAT('| Timeout Reached. TestSuite Path=',TestSuiteInstancePath);
ReportMessage := CONCAT(ReportMessage,', Test Name=%s');
// add report to FifoQueue for pipelines
AdsLogStringMessageFifoQueue.WriteLog(MsgCtrlMask:=ADSLOG_MSGTYPE_ERROR,MsgFmtStr:=ReportMessage,StrArg:=TestName);
// print report in error list for developers
ADSLOGSTR(MsgCtrlMask:=ADSLOG_MSGTYPE_ERROR,MsgFmtStr:=ReportMessage,StrArg:=TestName);

StopCmd := TRUE;
END_IF
END_IF
PlcStop(NETID:='',PORT:=AdsPort,STOP:=stopCmd);
StopCmd := FALSE;]]></ST>
</Implementation>
</POU>
</TcPlcObject>
27 changes: 27 additions & 0 deletions TcUnit/TcUnit/POUs/FB_Utility.TcPOU
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4022.18">
<POU Name="FB_Utility" Id="{eb7474a6-4c38-44a6-a596-17f52c47b8c1}" SpecialFunc="None">
<Declaration><![CDATA[{attribute 'hide_all_locals'}
FUNCTION_BLOCK PUBLIC FB_Utility
VAR
CpuCounter : GETCPUCOUNTER;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
<Method Name="GetCpuCounterAsULINT" Id="{422b728e-cf37-4fcb-b889-112b7adf5522}">
<Declaration><![CDATA[METHOD PUBLIC GetCpuCounterAsULINT : ULINT
VAR
TempResult : ULINT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[CpuCounter();
TempResult := CpuCounter.cpuCntHiDW;
TempResult := SHL(TempResult,32);
GetCpuCounterAsULINT := TempResult + CpuCounter.cpuCntLoDW;]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>
2 changes: 1 addition & 1 deletion TcUnit/TcUnit/POUs/Functions/TEST.TcPOU
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ GVL_TcUnit.CurrentTestNameBeingCalled := TestName;
FOR CounterTestSuiteAddress := 1 TO GVL_TcUnit.NumberOfInitializedTestSuites BY 1 DO
(* Look for the test suite by comparing to the one that is currently running *)
IF GVL_TcUnit.TestSuiteAddresses[CounterTestSuiteAddress] = GVL_TcUnit.CurrentTestSuiteBeingCalled THEN
GVL_TcUnit.TestSuiteAddresses[CounterTestSuiteAddress]^.AddTest(TestName := TestName, IsTestOrdered := FALSE);
GVL_TcUnit.CurrentTestBeingCalled REF= GVL_TcUnit.TestSuiteAddresses[CounterTestSuiteAddress]^.AddTest(TestName := TestName, IsTestOrdered := FALSE);
GVL_TcUnit.CurrentTestIsFinished := GVL_TcUnit.TestSuiteAddresses[CounterTestSuiteAddress]^.IsTestFinished(TestName := TestName);
RETURN;
END_IF
Expand Down
2 changes: 1 addition & 1 deletion TcUnit/TcUnit/POUs/Functions/TEST_ORDERED.TcPOU
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ FOR CounterTestSuiteAddress := 1 TO GVL_TcUnit.NumberOfInitializedTestSuites BY

(* Look for the test suite by comparing to the one that is currently running *)
IF GVL_TcUnit.TestSuiteAddresses[CounterTestSuiteAddress] = GVL_TcUnit.CurrentTestSuiteBeingCalled THEN
GVL_TcUnit.TestSuiteAddresses[CounterTestSuiteAddress]^.AddTest(TestName := TestName, IsTestOrdered := TRUE);
GVL_TcUnit.CurrentTestBeingCalled REF= GVL_TcUnit.TestSuiteAddresses[CounterTestSuiteAddress]^.AddTest(TestName := TestName, IsTestOrdered := TRUE);
GVL_TcUnit.CurrentTestIsFinished := GVL_TcUnit.TestSuiteAddresses[CounterTestSuiteAddress]^.IsTestFinished(TestName := TestName);

(* Check that no previous code has set the currently running test to ignored (for example by setting the test to DISABLED *)
Expand Down
20 changes: 20 additions & 0 deletions TcUnit/TcUnit/POUs/Functions/TIMEOUT_FOR_EACH_TEST.TcPOU
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4022.18">
<POU Name="TIMEOUT_FOR_EACH_TEST" Id="{f4fb1591-6c45-4819-b7fb-69124cd2e3ab}" SpecialFunc="None">
<Declaration><![CDATA[(* this function sets a timeout for each test and if a test doesn't finish during this timeout PLC will STOP
- to use this function make another TASK in PLC with lower number of priority
- make a PROGRAM and assign it to the newly created TASK
- call this FUNCTION in it with desired Timeout
- Zero (T#0S) disables this function *)
FUNCTION TIMEOUT_FOR_EACH_TEST
VAR_INPUT
Timeout : TIME;
END_VAR
VAR
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[GVL_TcUnit.TimeoutWatcher(Time_out:=Timeout);]]></ST>
</Implementation>
</POU>
</TcPlcObject>
11 changes: 10 additions & 1 deletion TcUnit/TcUnit/TcUnit.plcproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Documentation and examples are available at www.tcunit.org</Description>
</SelectedLibraryCategories>
<Company>www.tcunit.org</Company>
<Author>Jakob Sagatowski and contributors</Author>
<ProjectVersion>1.2.1.0</ProjectVersion>
<ProjectVersion>1.2.2.0</ProjectVersion>
<!-- <OutputType>Exe</OutputType>
<RootNamespace>MyApplication</RootNamespace>
<AssemblyName>MyApplication</AssemblyName>-->
Expand Down Expand Up @@ -112,6 +112,12 @@ Documentation and examples are available at www.tcunit.org</Description>
<Compile Include="POUs\FB_StreamBuffer.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="POUs\FB_TimeoutWatcher.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="POUs\FB_Utility.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="POUs\FB_xUnitXmlPublisher.TcPOU">
<SubType>Code</SubType>
</Compile>
Expand Down Expand Up @@ -181,6 +187,9 @@ Documentation and examples are available at www.tcunit.org</Description>
<Compile Include="POUs\Functions\TEST_ORDERED.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="POUs\Functions\TIMEOUT_FOR_EACH_TEST.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="POUs\Functions\WRITE_PROTECTED_\WRITE_PROTECTED_BOOL.TcPOU">
<SubType>Code</SubType>
</Compile>
Expand Down
2 changes: 1 addition & 1 deletion TcUnit/TcUnit/Version/Global_Version.TcGVL
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// This function has been automatically generated from the project information.
VAR_GLOBAL CONSTANT
{attribute 'const_non_replaced'}
stLibVersion_TcUnit : ST_LibVersion := (iMajor := 1, iMinor := 2, iBuild := 1, iRevision := 0, sVersion := '1.2.1.0');
stLibVersion_TcUnit : ST_LibVersion := (iMajor := 1, iMinor := 2, iBuild := 2, iRevision := 0, sVersion := '1.2.2.0');
END_VAR
]]></Declaration>
</GVL>
Expand Down