Home » Eclipse Projects » Eclipse Titan » test component sends messages to already disconnected component on shutdown(test component sends messages to already disconnected component on shutdown causing testcase error)
|
Re: test component sends messages to already disconnected component on shutdown [message #1782765 is a reply to message #1782716] |
Thu, 01 March 2018 07:56 |
|
Hi Philipp,
yes, it's a known problem and there's no simple solution to it.
The spawned PTC's are acting asynchronously and one needs to implement a logic for controlled shutdown.
A common mistake is to rely on timers and delays , which builds a number of implicit assumptions into the code;
eventually the architecture will fall apart displaying mysterious symptoms.
If your shutdown function has no side effects, it's just as good as any.
I personally prefer a graceful shutdown implemented with internal synchronization ports;
these ports carry bidirectionally simple synchronization messages (strings or integers) and connect every PTC to the MTC , where the test case executes.
The functions started on the PTC's, when they are about to terminate , send a request to the MTC and wait to be acknowledged.
When acknowledged, the function terminates and the component becomes done.
something like this :
testcase tc_TS002_cancel_nonExisting_action() runs on MTC_CT
{
ConfigurationBuild();
v_RequestorMapping_CT.start(f_ScanClientPorts(tsp_AuthType_requestor,"titan0","titan0",tsp_localPortRequestor));
alt { []Ctlrm_PCO.receive("ready") {}; }
v_TranslatorR_CT.start(f_ScanTranslatorPorts());
v_Requestor_CT.start(f_TS002_cancel_nonExisting_action());
Twait.start(60.0);
alt
{
[]Ctlr_PCO.receive("halt")
{
Ctlrt_PCO.send("halt");
Ctlrm_PCO.send("halt");
};
[]Twait.timeout {};
}//endalt
all component.done;
ConfigurationKill();
}
//-----------------------------------------------------------------------------
function f_ScanServerPorts() runs on ServerMapping_CT
//-----------------------------------------------------------------------------
{//startfunction
:
vl_result :=f_IPL4_listen( TCP_PCO, "", tsp_ServerListenerPort, {tcp:={}}, {} )
if (ispresent(vl_result.connId))
{
Ctl_PCO.send("ready");
}
:
//function body here
:
:
alt {
[] Ctl_PCO.receive("halt") {
}//endalt
}//endfunction
//*************************************************************************
function f_ScanTranslatorPorts() runs on Translator_CT
//*************************************************************************
{//startfunction f_ScanTranslatorPorts
alt
{//startalt
:
//function body here
:
[] Ctl_PCO.receive("halt") {
}//endalt
}//endfunction ScanTranslatorPorts
where
ConfigurationByuild/ConfigurationKill contain all create/connect/map and
unmap/disconnect/kill commands respectively:
//-----------------------------------------------------------------------------
function ConfigurationBuild() runs on MTC_CT
//-----------------------------------------------------------------------------
{//startfunction
v_ServerMapping_CT:=ServerMapping_CT.create;
v_TranslatorS_CT:=Translator_CT.create;
v_Server_CT:=Server_CT.create;
connect(v_ServerMapping_CT:Ctl_PCO,self:Ctlsm_PCO);
connect(v_Server_CT:Ctl_PCO,self:Ctls_PCO);
connect(v_TranslatorS_CT:Ctl_PCO,self:Ctlst_PCO);
connect(v_ServerMapping_CT:Comm_PCO,v_Server_CT:Comm_PCO);
connect(v_ServerMapping_CT:CommTrans_PCO,v_TranslatorS_CT:CommTrans_PCO);
connect(v_Server_CT:InComm_PCO,v_TranslatorS_CT:InComm_PCO);
map(v_ServerMapping_CT:TCP_PCO, system:TCPs_PCO);
}//endfunction
//-----------------------------------------------------------------------------
function ConfigurationKill() runs on MTC_CT
//-----------------------------------------------------------------------------
{//startfunction
unmap(v_ServerMapping_CT:TCP_PCO, system:TCPs_PCO);
disconnect(v_ServerMapping_CT:Comm_PCO,v_Server_CT:Comm_PCO);
disconnect(v_ServerMapping_CT:CommTrans_PCO,v_TranslatorS_CT:CommTrans_PCO);
disconnect(v_Server_CT:InComm_PCO,v_TranslatorS_CT:InComm_PCO);
disconnect(v_Server_CT:Ctl_PCO,self:Ctls_PCO);
disconnect(v_ServerMapping_CT:Ctl_PCO,self:Ctlsm_PCO);
disconnect(v_TranslatorS_CT:Ctl_PCO,self:Ctlst_PCO);
all component.kill;
}//endfunction
So what happens is that the test case starts one component , waits until it announces itself to be ready ( the transport layer has to stabilize end-to-end, all alarms silent , whatnot) and only then starts the other components.
When the component of interest terminates , it announces itself finished to the MTC, which only then gives permission to the other components to leave; they might have terminated already and are likely waiting in the final alt for permission.
Finally , when all components are done, the configuration is dismantled.
Now I'm not saying that everyone should do the same; for simple configurations this might be overkill; it definitely adds an overhead;
However with this such a mechanism arbitrarily large architectures can be
started/terminated in a controlled manner.
Again, if you are happy with your shutdown, use it.
I hope this helps somewhat
Best regards
Elemer
[Updated on: Sat, 03 March 2018 08:44] Report message to a moderator
|
|
| | |
Goto Forum:
Current Time: Wed Sep 25 01:02:13 GMT 2024
Powered by FUDForum. Page generated in 0.04441 seconds
|