blob: 9a8003f3f5ee242dc296206df6796b0be551e55e [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2019 Ericsson Telecom AB //
// //
// All rights reserved. This program and the accompanying materials //
// are made available under the terms of the Eclipse Public License v2.0 //
// which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html //
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Module: EPTF_LGenBaseDemo_CallerFunctions
//
// Purpose:
// This module contains function used in the Caller component.
//
// Module Parameters:
// -
//
// Module depends on:
//
// Current Owner:
// ELSZSKU
//
// Last Review Date:
// 20 - -
//
// Detailed Comments:
//
///////////////////////////////////////////////////////////
module EPTF_LGenBaseDemo_CallerFunctions
{
import from EPTF_CLL_LGenBase_EventHandlingFunctions all;
import from TCCConversion_Functions all;
import from EPTF_CLL_Base_Functions all;
import from EPTF_CLL_LGenBase_TemplateFunctions all;
import from EPTF_LGenBaseDemo_CallerDefinitions all
import from EPTF_LGenBaseDemo_TransportDefinitions all
import from EPTF_LGenBaseDemo_TransportFunctions all
import from EPTF_LGenBaseDemo_TemplateFunctions all;
import from EPTF_CLL_LGenBase_Functions all
import from EPTF_CLL_LGenBase_ConfigDefinitions all
import from EPTF_CLL_LGenBase_ConfigFunctions all
import from EPTF_CLL_LGenBase_Definitions all
import from EPTF_CLL_LGenBase_TrafficFunctions all
import from EPTF_CLL_LGenBaseStats_Definitions all
import from EPTF_CLL_Variable_Definitions all
import from EPTF_CLL_Variable_Functions all
import from EPTF_CLL_Common_Definitions all
//The template describing the ReRegister messages is loaded programmatically
//This module parameter describes the file
modulepar charstring tsp_LGenBaseDemo_msgReRegisterExtTemplateFile := "../EPTF_LGenBaseDemo_msgReRegisterTemplate.txt"
///////////////////////////////////////////////////////////////////////////////
// This is the starter function of the Caller component
// There are samples how to retrieve identifiers of scenarios and traffic cases
///////////////////////////////////////////////////////////////////////////////
public function f_LGenBaseDemo_Caller_behavior(
in charstring pl_name,
in LGenBaseDemo_Transport_CT pl_connectTo)
runs on LGenBaseDemo_Caller_CT{
//Initialize the component
f_LGenBaseDemo_Caller_init(pl_name, pl_connectTo)
//Create the scenario
f_EPTF_LGenBase_createScenario2EntityGroup({c_LGenBaseDemo_Caller_entityGroupName,c_LGenBaseDemo_Caller_scenarioName},false)
//Store the identifier of the Register traffic case for later use
v_LGenBaseDemo_Caller_registerTcIdx := f_EPTF_LGenBase_trafficCaseId(
c_LGenBaseDemo_Caller_entityGroupName,
c_LGenBaseDemo_Caller_scenarioName,
c_LGenBaseDemo_Caller_tcRegisterName)
var integer vl_eGrpIdx, vl_scRelIdx
//Retrieve the identifiers of the scenario to be started, and...
f_EPTF_LGenBase_scenarioRelIdx(
f_EPTF_LGenBase_scenarioAbsIdxByName(c_LGenBaseDemo_Caller_entityGroupName, c_LGenBaseDemo_Caller_scenarioName),
vl_eGrpIdx,
vl_scRelIdx)
//start it
f_EPTF_LGenBase_enableScenarioOnEntityGroup(vl_eGrpIdx, vl_scRelIdx)
//Then come what may...
f_EPTF_Base_wait4Shutdown()
}
///////////////////////////////////////////////////////////////////////////////
// Initialization of the Caller component
///////////////////////////////////////////////////////////////////////////////
public function f_LGenBaseDemo_Caller_init(
in charstring pl_name,
in LGenBaseDemo_Transport_CT pl_connectTo)
runs on LGenBaseDemo_Caller_CT{
f_LGenBaseDemo_Transport_init(
pl_name, //the name of the component always must be passed to the extended component
refers(f_LGenBaseDemo_Caller_processResponses),
pl_connectTo)
f_EPTF_LGenBase_init(pl_name)
v_LGenBaseDemo_Caller_msgUserDataMarkLen := lengthof(c_LGenBaseDemo_Caller_msgUserDataMark)
v_LGenBaseDemo_Caller_msgUserDataSeparatorLen := lengthof(c_LGenBaseDemo_Caller_msgUserDataSeparator)
//Some template initialization functions. See the function itself.
f_LGenBaseDemo_Caller_templateDef()
f_EPTF_Base_registerCleanup(refers(f_LGenBaseDemo_Caller_cleanup))
//Declare a behavior type.
//This behavior type can be used for several purposes.
//The Caller component uses it only to identify events. See the f_EPTF_LGenBase_declareFsmEvent function calls.
//See also the initialization of the Responder component
v_LGenBaseDemo_Caller_myBehavId := f_EPTF_LGenBase_declareBehaviorType(c_LGenBaseDemo_Caller_BehaviorName, -1, null, null, null)
//These events used to notify the FSMs about the responses of the Responder component
f_EPTF_LGenBase_declareFsmEvent(c_LGenBaseDemo_Caller_BehaviorName, c_LGenBaseDemo_Caller_InputNameRespSuccess)
f_EPTF_LGenBase_declareFsmEvent(c_LGenBaseDemo_Caller_BehaviorName, c_LGenBaseDemo_Caller_InputNameRespFailed)
//At the end of the test a test report is generated. The following listener is called when the
//c_EPTF_LGenBase_inputIdx_testMgmt_testFinished is dispatched. See also the trafficFinishedActions
//parameter of the "Caller_TcDoMsg" traffic case.
f_EPTF_LGenBase_addGeneralEventListener(c_EPTF_LGenBase_bIdx, c_EPTF_LGenBase_inputIdx_testMgmt_testFinished, refers(f_LGenBaseDemo_Caller_testFinishedListener), {})
//We use only one combination of the behaviors (only the "Caller" behavior), therefore
//we use only one entity type
f_EPTF_LGenBase_declareEntityType(c_LGenBaseDemo_Caller_entityTypeName, {c_LGenBaseDemo_Caller_BehaviorName})
//Declare the functions to be used in the traffic cases
//The f_LGenBaseDemo_Caller_registerFinished function will be called when the traffic case "Register" finished
//See also the "trafficStartFinish" parameters of the Register traffic case.
f_EPTF_LGenBase_declareFunction(c_LGenBaseDemo_Caller_registerFinishedName, {customFinishFunction := refers(f_LGenBaseDemo_Caller_registerFinished)})
//The f_LGenBaseDemo_Caller_entityFinishedInRegister will be called each time an entity of the Register traffic case finished.
//See also the "entityFinishActions" parameter of the Register traffic case.
f_EPTF_LGenBase_declareFunction(c_LGenBaseDemo_Caller_entityFinishedName, {customFinishFunction := refers(f_LGenBaseDemo_Caller_entityFinishedInRegister)})
//All the test step functions must be declared before their first use
//See also the occurance of the c_LGenBaseDemo_Caller_StepName_sendMessage in the f_LGenBaseDemo_Caller_fsm
f_EPTF_LGenBase_declareStep(c_LGenBaseDemo_Caller_BehaviorName, {c_LGenBaseDemo_Caller_StepName_sendMessage,refers(f_LGenBaseDemo_Caller_sendMessage)})
//This case an entity represents a user. Therefore the size of the entity group
//must be equal to the count of the users to be simulated.
//See also the init function of the responder.
f_EPTF_LGenBase_createEntityGroup({c_LGenBaseDemo_Caller_entityGroupName, c_LGenBaseDemo_Caller_entityTypeName, tsp_LGenBaseDemo_userCount})
//Since the FSMs of all the traffic cases are almost the same (except the message to be sent to the responder)
//the FSMs can be produced by the same function.
f_EPTF_LGenBase_declareFSMTable(f_LGenBaseDemo_Caller_fsm(
c_LGenBaseDemo_Caller_fsmNameRegister,
c_LGenBaseDemo_Caller_MsgRegister))
f_EPTF_LGenBase_declareFSMTable(f_LGenBaseDemo_Caller_fsm(
c_LGenBaseDemo_Caller_fsmNameReRegister,
c_LGenBaseDemo_Caller_MsgReRegister))
f_EPTF_LGenBase_declareFSMTable(f_LGenBaseDemo_Caller_fsm(
c_LGenBaseDemo_Caller_fsmNameDoMsg,
c_LGenBaseDemo_Caller_MsgDoMsg))
//A traffic case type must be declared before the traffic case is declred for a scenario
//The traffic case type "Caller_TcRegister" uses the FSM "Caller_fsmRegister"
//We want to use the f_EPTF_LGenBase_successIfOnceSuccess function to decide the success
//of the entities. This must be declared. The default is f_EPTF_LGenBase_successSucNoFail.
f_EPTF_LGenBase_declareTrafficCaseType({
c_LGenBaseDemo_Caller_tcRegisterName,
c_LGenBaseDemo_Caller_fsmNameRegister,
c_LGenBaseDemo_Caller_entityTypeName,
{
{customEntitySucc := c_EPTF_LGenBase_EntitySucc_successIfOnceSuccessFnName}
}
})
f_EPTF_LGenBase_declareTrafficCaseType({
c_LGenBaseDemo_Caller_tcReRegisterName,
c_LGenBaseDemo_Caller_fsmNameReRegister,
c_LGenBaseDemo_Caller_entityTypeName,
{}
})
f_EPTF_LGenBase_declareTrafficCaseType({
c_LGenBaseDemo_Caller_tcDoMsgName,
c_LGenBaseDemo_Caller_fsmNameDoMsg,
c_LGenBaseDemo_Caller_entityTypeName,
{}
})
var float vl_targetCPSOfRegister := tsp_LGenBaseDemo_targetCPS/2.0
//The scenario contains 3 traffic cases.
f_EPTF_LGenBase_declareScenarioType3({
name := c_LGenBaseDemo_Caller_scenarioName,
tcList := {
{
tcName := c_LGenBaseDemo_Caller_tcRegisterName,
tcParamsList := {
//All the entities will be enabled in the traffic case at the start.
//The LGenBase starts each entity.
{enableEntitiesAtStart := true},
//The traffic case will be enabled at the start of the scenario, so it
//will be started too
{enabledAtStart := true},
//The entities will be selected in order
{entitySelection := round_robin},
{target := {cpsToReach := vl_targetCPSOfRegister} },
//The entities will be started until...
{entityFinishConditions := {
//the first successful registration
{nrOfSuccesses := 1},
//or maximum 3 failed registrations
{nrOfFails := 3}
}},
{entityFinishActions := {
{
//When an entity finished, it becomes enabled in the ReRegister traffic case
//if it had been registered succesfully
enableEntity4Tc := {
tcName := c_LGenBaseDemo_Caller_tcReRegisterName,
aMode := enableIfPreviousSuccess
}
},
//When an entity finished, a logger function is called to display the workflow.
//See also the f_EPTF_LGenBase_declareFunction calls in the initialization
{customFinishFunction := c_LGenBaseDemo_Caller_entityFinishedName}
}
},
//The traffic case will be finished..
{trafficStartFinish:={
//when all the available entities finished.
{availableEntitiesFinished := {{
//Then a logger function is called
//See also the f_EPTF_LGenBase_declareFunction calls in the initialization
{customFinishFunction := c_LGenBaseDemo_Caller_registerFinishedName},
//When there is no more entities to be registered, the ReRegister traffic case
//must be stopped too, and...
{disableTc := {c_LGenBaseDemo_Caller_tcReRegisterName}},
//the DoMsg message sending traffic case must be started
{enableTc := {c_LGenBaseDemo_Caller_tcDoMsgName,enableIfPreviousSuccess}}
}}}
}},
//The external templates used in a traffic case can be described
//with function calls, or in the traffic case declaration.
{templateSet :={
{
//The following 2 names must match the name pair used in
//the f_EPTF_LGenBase_declareTemplateType.
//See <f_LGenBaseDemo_Caller_templateDef>
c_LGenBaseDemo_Caller_BehaviorName,
c_LGenBaseDemo_Caller_msgRegisterTemplType,
//This value must match the name assigned to the external template file
//in the tsp_LGenBase_extTemplLoadList in the config file
//or in the f_EPTF_LGenBase_loadExtTempl function call.
c_LGenBaseDemo_Caller_msgRegisterExtTemplateName
}
}}
}
},
{
tcName := c_LGenBaseDemo_Caller_tcReRegisterName,
tcParamsList := {
{enableEntitiesAtStart := false},
{enabledAtStart := true},
{entitySelection := round_robin},
{target := {cpsToReach := tsp_LGenBaseDemo_targetCPS-vl_targetCPSOfRegister} }
}
},
{
tcName := c_LGenBaseDemo_Caller_tcDoMsgName,
tcParamsList := {
{enableEntitiesAtStart := false},
//This traffic case won't be started when the scenario started.
//See also the trafficStartFinish parameter of the Register traffic case
{enabledAtStart := false},
//In this tc the entities are selected randomly
{entitySelection := random},
{target := {cpsToReach := tsp_LGenBaseDemo_targetCPS} },
//The tc runs for 4 seconds, then stops
{trafficStartFinish:={
{execTime := {4.0, {}}}
}},
//Let's wait while the response for the last started message arrives, and then stop the test.
//See also the f_LGenBaseDemo_Caller_testFinishedListener
{trafficFinishedActions := {
{testFinished := {}}
}},
//The template set of the DoMsg traffic case is described similarly to the
//traffic case Register
{templateSet :={
{
c_LGenBaseDemo_Caller_BehaviorName,
c_LGenBaseDemo_Caller_msgDoMsgTemplType,
c_LGenBaseDemo_Caller_msgDoMsgExtTemplateName
}
}}
}
}
},
scParamsList := {}
})
}
///////////////////////////////////////////////////////////////////////////////
// The FSMs describe how the entities behave.
// This function demonstrates how to describe an FSM.
///////////////////////////////////////////////////////////////////////////////
private function f_LGenBaseDemo_Caller_fsm(
in charstring pl_fsmName, //The name of the FSM
in integer pl_msgType) //Which kind of message to be sent
return EPTF_LGenBase_FsmTableDeclarator{
return {
name := pl_fsmName,
fsmParams := {
{stateList := {"idle", "waiting4Reply"}},
{timerList := {
{name := "watchdog", startValue := c_LGenBaseDemo_Caller_Watchdog}
}},
{varList := {
//Temporary variable to handle latency measurement.
//The chronometers of each FSM set the content of this variable.
//The min/max statistics calculate their values based on this variable.
{name := "tcLatency", initValue := {floatVal := 0.0}, scope := TC},
//The "max" statistics store its value in this variable
{name := "tcMaxLatency", initValue := {floatVal := 0.0}, scope := TC}
}},
{statMeasWithParamsList := {
{ name := "chronoLatency",
providerVarName := "",
targetVarName := "tcLatency",
statMeasParams := {statType := chrono},
scope := FSM
},
{
//Calculates the minimal value of the
//FSM variable called "tcLatency"
//and stores it in a temporary variable
name := "minLatency",
providerVarName := "tcLatency",
targetVarName := "",
statMeasParams := {statType := min},
scope := TC
},
{
//Calculates the maximal value of the
//FSM variable called "tcLatency",
//and stores it in the variable "tcMaxLatency"
name := "maxLatency",
providerVarName := "tcLatency",
targetVarName := "tcMaxLatency",
statMeasParams := {statType := max},
scope := TC
}
}
}
},
table := {
extendedTable := {
{
//Listens to the start event
events2Listen := { events := {{ singleEvent := {
c_EPTF_LGenBase_behavior,c_EPTF_LGenBase_inputName_testMgmt_startTC,fsm
}}}},
cellRow := { statedCellRow := {
{ inState := { state := "idle"},
cell := {
actionList := {
// Calls a function which creates and sends the appropriate message to the responder
{c_LGenBaseDemo_Caller_StepName_sendMessage, {stepContextArgs := {pl_msgType}}},
// Starts the chronometer
{c_EPTF_LGenBase_stepName_fsmStartChrono,{statMeasName := "chronoLatency"}},
// Then starts the watchdog timer
{c_EPTF_LGenBase_stepName_timerStart,{timerName := "watchdog"}}
},
nextStateCalculation := omit,
// At the end it puts the FSM to the "waiting4Reply" state
nextState := "waiting4Reply"
}}
}}
},
{
//Listens to the RespSuccess event
{ events := {{ singleEvent := {
c_LGenBaseDemo_Caller_BehaviorName,
c_LGenBaseDemo_Caller_InputNameRespSuccess,
fsm
}}}},
{ statedCellRow := {
{{state := "waiting4Reply"},
{{
// Stop the chronometer
{c_EPTF_LGenBase_stepName_fsmStopChrono,{statMeasName := "chronoLatency"}},
// Stop the watchdog timer
{c_EPTF_LGenBase_stepName_timerCancel,{timerName := "watchdog"}},
// and report successful finish
{c_EPTF_LGenBase_stepName_trafficSuccess,omit}
},
//Then put back to "idle" state
omit,"idle"
}}
//In any other state we don't take care of it.
//Probably a timed out response
}}
},
{
//Listens to the RespFailed event
{ events := {{ singleEvent := {
c_LGenBaseDemo_Caller_BehaviorName,
c_LGenBaseDemo_Caller_InputNameRespFailed,
fsm
}}}},
{ statedCellRow := {
{{state := "waiting4Reply"},
{{
// Stop the chronometer
{c_EPTF_LGenBase_stepName_fsmStopChrono,{statMeasName := "chronoLatency"}},
// Stop the watchdog timer
{c_EPTF_LGenBase_stepName_timerCancel,{timerName := "watchdog"}},
// and report finish with failure
{c_EPTF_LGenBase_stepName_trafficFailed,omit}
},
//Then put back to "idle" state
omit,"idle"
}}
//In any other state we don't take care of it.
//Probably a timed out response
}}
},
{
//Listenes to the watchdog timeout
{ events := {{ singleEvent := { c_EPTF_LGenBase_specialBName_timerTimeout,"watchdog",fsm }}}},
{ statedCellRow := {
{{state := "waiting4Reply"},
{{
//Reports finish with timeout
{c_EPTF_LGenBase_stepName_trafficTimeout,omit}
},
//Then put back to "idle" state
omit,"idle"
}},
//In any other state it's a programming fault.
{{anyUndefinedState := {}},
{{
{c_EPTF_LGenBase_stepName_cancelAllTimers, omit},
{c_EPTF_LGenBase_stepName_trafficError,omit}
},omit,"idle"
}}
}}
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
// The cleanup of the component does nothing.
// This case the function does not have to be described and registered.
///////////////////////////////////////////////////////////////////////////////
private function f_LGenBaseDemo_Caller_cleanup()
runs on LGenBaseDemo_Caller_CT{
}
///////////////////////////////////////////////////////////////////////////////
// This function demonstrates how does a custom step function have to look like,
// and how can data described in an FSM can be retrieved in the step function.
///////////////////////////////////////////////////////////////////////////////
private function f_LGenBaseDemo_Caller_sendMessage(in EPTF_LGenBase_TestStepArgs pl_args)
runs on LGenBaseDemo_Caller_CT{
var LGenBaseDemo_Transport_MessageData vl_msgData := c_LGenBaseDemo_Transport_emptyMessageData
vl_msgData.entityIdx := pl_args.eIdx
vl_msgData.fsmCtxIdx := pl_args.refContext.fCtxIdx
select( pl_args.stepArgs[0] ){
case ( c_LGenBaseDemo_Caller_MsgRegister ){
//We describe the template set content for the Register message through config
//This case the template set ID can be retrieved from the test step arguments
var charstring vl_msg := f_LGenBaseDemo_Caller_encodeRegister(pl_args,vl_msgData)
f_LGenBaseDemo_Transport_sendRegister(vl_msg)
}
case ( c_LGenBaseDemo_Caller_MsgReRegister ){
//We describe the template set content for the ReRegister message with function call
//This case the template set ID can be stored in component variable,
//and not from test step arguments
var charstring vl_msg := f_LGenBaseDemo_Caller_encodeReRegister(vl_msgData)
f_LGenBaseDemo_Transport_sendReRegister(vl_msg)
}
case ( c_LGenBaseDemo_Caller_MsgDoMsg ){
//We describe the template set content for the DoMsg message through config
//This case the template set ID can be retrieved from the test step arguments,
//just like in case of Register message
var charstring vl_msg := f_LGenBaseDemo_Caller_encodeDoMsg(pl_args,vl_msgData)
f_LGenBaseDemo_Transport_sendDoMsg(vl_msg)
}
case else{
//TODO error
}
}
}
///////////////////////////////////////////////////////////////////////////////
// Custom finish function is called when the Register traffic case finished.
// See the trafficStartFinish parameter of the tc "Register" in the initialization.
// This function demonstrates how to retrieve
// - the ID of the entity group associated to a traffic case
// - the entity count of an entity group
// - statistics about a traffic case
///////////////////////////////////////////////////////////////////////////////
private function f_LGenBaseDemo_Caller_registerFinished(in integer pl_tcIdx)
runs on LGenBaseDemo_Caller_CT{
action(%definitionId,": The traffic case register finished.")
var integer vl_eGrpIdx := f_EPTF_LGenBase_getEGrpIdxOfTc(pl_tcIdx)
var integer vl_eGrpCount := f_EPTF_LGenBase_getEGrpECount(vl_eGrpIdx)
//var integer vl_eGrpOffset := f_EPTF_LGenBase_getEGrpBaseOffset(vl_eGrpIdx)
for ( var integer vl_i := 0; vl_i < vl_eGrpCount ; vl_i := vl_i+1 ){
log("entity#"&int2str(vl_i)&" Started: ",f_EPTF_LGenBase_getEntityStarts(vl_i, pl_tcIdx),
" Success: ",f_EPTF_LGenBase_getEntitySuccesses(vl_i, pl_tcIdx),
" Fail: ",f_EPTF_LGenBase_getEntityFails(vl_i, pl_tcIdx))
}
}
///////////////////////////////////////////////////////////////////////////////
// Custom finish function is called when an entity of the Register traffic case finished.
// See the entityFinishActions parameter of the tc "Register" in the initialization.
// This function demonstrates also how to retrieve
// - the relative index of the entity in the entity group associated to a traffic case
// - statistics about an entity
///////////////////////////////////////////////////////////////////////////////
private function f_LGenBaseDemo_Caller_entityFinishedInRegister(in integer pl_eIdx)
runs on LGenBaseDemo_Caller_CT{
var integer vl_eIdxOfTc := f_EPTF_LGenBase_getERelIdx(pl_eIdx)
action("entity#",pl_eIdx," finished. Success: ",
f_EPTF_LGenBase_getEntitySuccesses(pl_eIdx, v_LGenBaseDemo_Caller_registerTcIdx)," Fail: ",
f_EPTF_LGenBase_getEntityFails(pl_eIdx, v_LGenBaseDemo_Caller_registerTcIdx))
}
///////////////////////////////////////////////////////////////////////////////
// This function demonstrates how to reach LGenBase statistics using variables
// and function calls
///////////////////////////////////////////////////////////////////////////////
private function f_LGenBaseDemo_Caller_createStats()
runs on LGenBaseDemo_Caller_CT{
var charstring vl_log := "\n"
//--------------
// Get the nr. of successfully registered entities using variable
//--------------
// The variables containing the tc statistics have special names.
var charstring vl_succRegVarName :=
f_EPTF_LGenBase_getNamePrefix(
c_LGenBaseDemo_Caller_entityGroupName,
c_LGenBaseDemo_Caller_scenarioName,
c_LGenBaseDemo_Caller_tcRegisterName)&
c_EPTF_LGenBaseStats_nameOfTcNrOfSuccesses
var integer vl_varId := f_EPTF_Var_getId(vl_succRegVarName)
var EPTF_Var_DirectContent vl_content
f_EPTF_Var_getContent(vl_varId, vl_content)
//First get the absolute index of the traffic cases
var integer vl_tcRegIdx := f_EPTF_LGenBase_trafficCaseId(
c_LGenBaseDemo_Caller_entityGroupName,
c_LGenBaseDemo_Caller_scenarioName,
c_LGenBaseDemo_Caller_tcRegisterName)
var integer vl_tcReRegIdx := f_EPTF_LGenBase_trafficCaseId(
c_LGenBaseDemo_Caller_entityGroupName,
c_LGenBaseDemo_Caller_scenarioName,
c_LGenBaseDemo_Caller_tcReRegisterName)
var integer vl_tcDoMsgIdx := f_EPTF_LGenBase_trafficCaseId(
c_LGenBaseDemo_Caller_entityGroupName,
c_LGenBaseDemo_Caller_scenarioName,
c_LGenBaseDemo_Caller_tcDoMsgName)
//Select an entity randomly from the successfully registered (so free) entities from the DoMsg tc.
//(The entitySelection of the tc had been set to random.
//See the f_EPTF_LGenBase_declareScenarioType3 call in the <f_LGenBaseDemo_Caller_init>.)
var integer vl_entityRelIdx := f_EPTF_LGenBase_getNextFreeEntity(vl_tcDoMsgIdx)
var integer vl_eAbsIdx := f_EPTF_LGenBase_getEAbsIdxOfTC(vl_entityRelIdx, vl_tcDoMsgIdx)
var charstring vl_maxLatencyVarName :=
f_EPTF_LGenBase_varNameOfTCVar(v_LGenBaseDemo_Caller_registerTcIdx, "tcMaxLatency")
vl_varId := f_EPTF_Var_getId(vl_maxLatencyVarName)
var EPTF_Var_DirectContent vl_contentLatency
f_EPTF_Var_getContent(vl_varId, vl_contentLatency)
action(%definitionId,"\nNr. of registered users: ",int2str(vl_content.intVal),
//--------------
//Get the nr. of register calls using function call
//--------------
"\nNr. of successful Register calls: ",int2str(f_EPTF_LGenBase_getTcSuccesses(vl_tcRegIdx)),
//--------------
//Get the nr. of reRegister calls using function call
//--------------
"\nNr. of ReRegister calls: ",int2str(f_EPTF_LGenBase_getTcStarts(vl_tcReRegIdx)),
//--------------
//Get the nr. of doMsg calls of a successfully registered entity
//--------------
"\nNr. of DoMsg calls of entity# ",int2str(vl_eAbsIdx),": ",
int2str(f_EPTF_LGenBase_getEntityStarts(vl_entityRelIdx, vl_tcDoMsgIdx)),
"\nMax latency of the Register traffic case:",float2str(vl_contentLatency.floatVal)
)
}
///////////////////////////////////////////////////////////////////////////////
// This function demonstrates how does a listener function have to look like
// This listener will be called when the associated event is dispatched.
// The listener can be registered by the f_EPTF_LGenBase_addxxxListener functions,
// where the xxx describes the event type.
// See <f_LGenBaseDemo_Caller_init>
///////////////////////////////////////////////////////////////////////////////
private function f_LGenBaseDemo_Caller_testFinishedListener(
EPTF_LGenBase_ReportedEventDescriptor pl_event,
EPTF_IntegerList pl_listenerArgs)
runs on LGenBaseDemo_Caller_CT{
//Create final statistics
f_LGenBaseDemo_Caller_createStats()
//Stops the test execution.
//When you use ExecCtrl to manage the test execution, you don't have to
//add such a listener, because the ExecCtrl component
//automatically registers one.
f_EPTF_Base_stopAll(pass)
}
///////////////////////////////////////////////////////////////////////////////
// There are two ways to use external templates:
// - automatically through the configuration
// - programmatically
//
// The external template of the Register and DoMsg messages are handled
// automatically, since it's declared in the config file.
// However, there is no external template file for the message DoMsg.
//
// The external template of the ReRegister message is handled
// programmatically
///////////////////////////////////////////////////////////////////////////////
private function f_LGenBaseDemo_Caller_templateDef()
runs on LGenBaseDemo_Caller_CT{
//This statement loads the external template of the ReRegister message
v_LGenBaseDemo_Caller_msgReRegisterTemplIdx := f_EPTF_LGenBase_loadExtTempl(
tsp_LGenBaseDemo_msgReRegisterExtTemplateFile,
c_LGenBaseDemo_Caller_msgReRegisterExtTemplateName,
true)
//Since the templates are always filled programmatically, it must be declared
//what kind of fields are used in all message types.
//The following block assignes a name pair to a set of arguments
//for each message type.
v_LGenBaseDemo_Caller_msgRegisterTemplTypeIdx := f_EPTF_LGenBase_declareTemplateType(
{c_LGenBaseDemo_Caller_BehaviorName, c_LGenBaseDemo_Caller_msgRegisterTemplType},
{"phonePrefix", "fromNr", "phonePrefixTo", "toNr", "eIdx", "fIdx"},
{});
v_LGenBaseDemo_Caller_msgReRegisterTemplTypeIdx := f_EPTF_LGenBase_declareTemplateType(
{c_LGenBaseDemo_Caller_BehaviorName, c_LGenBaseDemo_Caller_msgReRegisterTemplType},
{"phonePrefix", "fromNr", "eIdx", "fIdx"},
{"phonePrefixTo", "toNr"});
v_LGenBaseDemo_Caller_msgDoMsgTemplTypeIdx := f_EPTF_LGenBase_declareTemplateType(
{c_LGenBaseDemo_Caller_BehaviorName, c_LGenBaseDemo_Caller_msgDoMsgTemplType},
{"phonePrefix", "fromNr", "eIdx", "fIdx"},
{"phonePrefixTo", "toNr"});
}
///////////////////////////////////////////////////////////////////////////////
// The function is called by the Common component when a message arrived.
// Demonstrates how to dispatch an event
///////////////////////////////////////////////////////////////////////////////
private function f_LGenBaseDemo_Caller_processResponses(in LGenBaseDemo_Msg pl_msg)
runs on LGenBaseDemo_Caller_CT{
var boolean vl_resp := false
var LGenBaseDemo_Transport_MessageData vl_msgData := c_LGenBaseDemo_Transport_emptyMessageData
log(%definitionId&": Response message received: ",pl_msg)
//var integer vl_msgInput
var integer vl_msgId
if ( ischosen(pl_msg.registerResp) ){
vl_resp := pl_msg.registerResp.resp
f_LGenBaseDemo_Caller_decodeUserData(pl_msg.registerResp.msgUserData, vl_msgData)
vl_msgId := pl_msg.registerResp.msgId
}
else if ( ischosen(pl_msg.reRegisterResp) ){
vl_resp := pl_msg.reRegisterResp.resp
f_LGenBaseDemo_Caller_decodeUserData(pl_msg.reRegisterResp.msgUserData, vl_msgData)
vl_msgId := pl_msg.reRegisterResp.msgId
}
else if ( ischosen(pl_msg.doMsgResp) ){
vl_resp := pl_msg.doMsgResp.resp
f_LGenBaseDemo_Caller_decodeUserData(pl_msg.doMsgResp.msgUserData, vl_msgData)
vl_msgId := pl_msg.doMsgResp.msgId
} else {
//TODO error
}
//Send ack
f_LGenBaseDemo_Transport_sendMsgAck(vl_msgId, true)
//Notify the entity about the reception
//First fill in an entity
var EPTF_LGenBase_ReportedEventDescriptor vl_event := c_EPTF_LGenBase_emptyReportedEventDescriptor
vl_event.event.bIdx := v_LGenBaseDemo_Caller_myBehavId
vl_event.event.target.eIdx := vl_msgData.entityIdx
vl_event.event.target.fsmCtxIdx := vl_msgData.fsmCtxIdx
if(vl_resp){
vl_event.event.iIdx := c_LGenBaseDemo_Caller_InputIdxRespSuccess
}else{
vl_event.event.iIdx := c_LGenBaseDemo_Caller_InputIdxRespFailed
}
log(%definitionId&": Dispatching input "&f_EPTF_LGenBase_iIdx2Str(v_LGenBaseDemo_Caller_myBehavId,vl_event.event.iIdx)&
" to the entity#"&int2str(vl_event.event.target.eIdx))
f_EPTF_LGenBase_dispatchEvent(vl_event)
}
///////////////////////////////////////////////////////////////////////////////
// Some data are encoded into the messages sent to the Responder, and are
// sent back.
// There is no demo content
///////////////////////////////////////////////////////////////////////////////
public function f_LGenBaseDemo_Caller_decodeUserData(
in charstring pl_msg,
out LGenBaseDemo_Transport_MessageData pl_msgData){
pl_msgData := c_LGenBaseDemo_Transport_emptyMessageData
var charstring vl_msgChar := f_LGenBaseDemo_Caller_getUserData(pl_msg)
log(%definitionId&": UserData: "&vl_msgChar)
var integer vl_sepPos := f_strstr(vl_msgChar, c_LGenBaseDemo_Caller_msgUserDataSeparator, lengthof(c_LGenBaseDemo_Caller_msgUserDataMark))
pl_msgData.entityIdx := str2int(substr(vl_msgChar,lengthof(c_LGenBaseDemo_Caller_msgUserDataMark), vl_sepPos-lengthof(c_LGenBaseDemo_Caller_msgUserDataMark)))
var integer vl_userDataTermPos := f_strstr(vl_msgChar, c_LGenBaseDemo_Caller_msgUserDataTerm,vl_sepPos)
pl_msgData.fsmCtxIdx := str2int(substr(vl_msgChar,vl_sepPos+lengthof(c_LGenBaseDemo_Caller_msgUserDataSeparator),
vl_userDataTermPos-vl_sepPos-lengthof(c_LGenBaseDemo_Caller_msgUserDataSeparator)))
log(%definitionId&": MsgData: "&log2str(pl_msgData))
}
///////////////////////////////////////////////////////////////////////////////
// Some data are encoded into the messages sent to the Responder, and are
// sent back.
// There is no demo content
///////////////////////////////////////////////////////////////////////////////
public function f_LGenBaseDemo_Caller_getUserData(in charstring pl_msg)
return charstring
{
var integer vl_userDataPos := f_strstr(pl_msg, c_LGenBaseDemo_Caller_msgUserDataMark, 0)//+
//lengthof(c_LGenBaseDemo_Caller_msgUserDataMark)
//TODO check validity
return substr(pl_msg,vl_userDataPos,lengthof(pl_msg)-vl_userDataPos)
}
} // end of module