| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // 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_CLL_CSAdmin_Functions |
| // |
| // Purpose: |
| // This TTCN-3 module contains generic function definitions and altsteps |
| // for EPTF central scheduling admin. |
| // |
| // Module paramters: |
| // - tsp_debug_EPTF_CS_Admin_Functions - *boolean* |
| // - tsp_EPTF_CLL_CS_Admin_LGenStatusGuard - *float* |
| // - tsp_EPTF_CLL_CS_Admin_LGenCreationDelay - *float* |
| // |
| // Module depens on: |
| // <EPTF_CLL_Common_Definitions> |
| // <EPTF_CLL_CS_Definitions> |
| // <EPTF_CLL_CSLB_Functions> |
| // <EPTF_CLL_Base_Definitions> |
| // <EPTF_CLL_Base_Functions> |
| // <EPTF_CLL_LGenBase_Definitions> |
| // <EPTF_CLL_LGenBaseStats_Functions> |
| // <EPTF_CLL_LGenBase_ConfigFunctions> |
| // <EPTF_CLL_LGenBase_TrafficFunctions> |
| // <EPTF_CLL_LGenBase_StepFunctions> |
| // <EPTF_CLL_LGenBase_EventHandlingFunctions> |
| // <EPTF_CLL_ExecCtrl_Definitions> |
| // <EPTF_CLL_ExecCtrlClient_Functions> |
| // <EPTF_CLL_FBQ_Functions> |
| // <EPTF_CLL_FBQ_Definitions> |
| // <EPTF_CLL_Variable_Functions> |
| // <EPTF_CLL_Logging_Definitions> |
| // <EPTF_CLL_Logging_Functions> |
| // |
| // Current Owner: |
| // Gabor Tatarka (egbotat) |
| // |
| // Last review date: |
| // 2008-02-09 |
| //////////////////////////////////////////////////// |
| module EPTF_CLL_CSAdmin_Functions |
| { |
| |
| import from EPTF_CLL_Common_Definitions all; |
| import from EPTF_CLL_CS_Definitions all; |
| import from EPTF_CLL_CSLB_Functions all; |
| import from EPTF_CLL_Base_Definitions all; |
| import from EPTF_CLL_Base_Functions all; |
| import from EPTF_CLL_LGenBase_Definitions all; |
| import from EPTF_CLL_LGenBaseStats_Functions all; |
| import from EPTF_CLL_LGenBase_ConfigFunctions all; |
| import from EPTF_CLL_LGenBase_TrafficFunctions all; |
| import from EPTF_CLL_LGenBase_StepFunctions all; |
| import from EPTF_CLL_LGenBase_EventHandlingFunctions all; |
| import from EPTF_CLL_ExecCtrl_Definitions all; |
| import from EPTF_CLL_ExecCtrlClient_Functions all; |
| import from EPTF_CLL_FBQ_Functions all; |
| import from EPTF_CLL_FBQ_Definitions all; |
| import from EPTF_CLL_Variable_Functions all; |
| import from EPTF_CLL_Logging_Definitions all; |
| import from EPTF_CLL_Logging_Functions all; |
| |
| import from EPTF_CLL_DataSource_Definitions all; |
| import from EPTF_CLL_DataSourceClient_Functions all; |
| import from EPTF_CLL_CS_DSFunctions all; |
| |
| friend module EPTF_CLL_CSUIHandler_Functions; |
| friend module EPTF_CLL_CS_DSFunctions; |
| |
| modulepar boolean tsp_debug_EPTF_CS_Admin_Functions := false; |
| modulepar float tsp_EPTF_CLL_CS_Admin_LGenStatusGuard := 10.0; |
| modulepar float tsp_EPTF_CLL_CS_Admin_LGenCreationDelay := 0.1; |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_AvgLGenUsage |
| // |
| //Purpose: |
| // EPTF_Var post-proc function for the average LGen usage stat. |
| // |
| //Parameters: |
| // - pl_idx - *in* *integer* - variable index |
| // - pl_argList - *in* <EPTF_IntegerList> - arguments list |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_AvgLGenUsage( |
| in integer pl_idx, |
| in EPTF_IntegerList pl_argList) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(f_EPTF_CS_Admin_isScenarioPaused() and |
| f_EPTF_CS_getSelectionAttempts() == 0) { |
| f_EPTF_Var_setContent(pl_idx, |
| { |
| floatVal := 100.0 |
| } |
| ); |
| } else { |
| var float vl_total := int2float(f_EPTF_CS_getNumberOfLoadgens()); |
| if(f_EPTF_CS_getSelectionAttempts() == 0 or vl_total == 0.0) { |
| return; |
| } |
| var float vl_busy := int2float(f_EPTF_CS_getAvgLGenUsageCounter()) / int2float(f_EPTF_CS_getSelectionAttempts()); |
| f_EPTF_Var_setContent(pl_idx, |
| { |
| floatVal := (100.0*vl_busy)/vl_total |
| } |
| ); |
| f_EPTF_CS_resetSelectionAttempts(); |
| f_EPTF_CS_resetAvgLGenUsageCounter(); |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_MaxLGenUsage |
| // |
| //Purpose: |
| // EPTF_Var post-proc function for the maximum LGen usage stat. |
| // |
| //Parameters: |
| // - pl_idx - *in* *integer* - variable index |
| // - pl_argList - *in* <EPTF_IntegerList> - arguments list |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_MaxLGenUsage( |
| in integer pl_idx, |
| in EPTF_IntegerList pl_argList) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(f_EPTF_CS_Admin_isScenarioPaused() and |
| f_EPTF_CS_getSelectionAttempts() == 0) { |
| f_EPTF_Var_setContent(pl_idx, |
| { |
| floatVal := 100.0 |
| } |
| ); |
| } else { |
| var float vl_busy := int2float(f_EPTF_CS_getMaxLGenUsageCounter()); |
| var float vl_total := int2float(f_EPTF_CS_getNumberOfLoadgens()); |
| if(vl_total == 0.0) { |
| return; |
| } |
| f_EPTF_Var_setContent(pl_idx, |
| { |
| floatVal := (100.0*vl_busy)/vl_total |
| } |
| ); |
| f_EPTF_CS_resetMaxLGenUsageCounter(); |
| } |
| } |
| |
| |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_init_CT |
| // |
| //Purpose: |
| // Function for initializing CS_ApplAdminBase component. |
| // |
| //Parameters: |
| // - pl_selfName - *in* *charstring* - EPTF self-name |
| // - pl_adminIdx - *in* *integer* - admin index |
| // - pl_ExecCtrlRef - *in* <EPTF_ExecCtrl_CT> - Execution Control component reference |
| // - pl_EPTF_CS_AdminInit - *in* <EPTF_CS_AdminInit_FT> - user defined init function reference |
| // - pl_loadBalancingAvailable - *in* *boolean* - true if load balancing is to be used |
| // - pl_dataSource_compRef - <EPTF_DataSource_CT> - datasource component reference |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_Admin_init_CT( |
| in charstring pl_selfName, |
| in integer pl_adminIdx, |
| in EPTF_ExecCtrl_CT pl_ExecCtrlRef, |
| in EPTF_CS_AdminInit_FT pl_EPTF_CS_AdminInit, |
| in boolean pl_loadBalancingAvailable := false, |
| in EPTF_DataSource_CT pl_dataSource_compRef := null) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| f_EPTF_Logging_init_CT(pl_selfName); |
| v_CS_ApplAdminBase_loggingMaskId := f_EPTF_Logging_registerComponentMasks( |
| tsp_EPTF_CS_ApplAdminBase_loggingComponentMask, |
| c_EPTF_CS_loggingEventClasses, |
| EPTF_Logging_CLL); |
| if(tsp_debug_EPTF_CS_Admin_Functions) { |
| f_EPTF_Logging_enableLocalMask(v_CS_ApplAdminBase_loggingMaskId, c_EPTF_CS_loggingClassIdx_Debug); |
| } else { |
| f_EPTF_Logging_disableLocalMask(v_CS_ApplAdminBase_loggingMaskId, c_EPTF_CS_loggingClassIdx_Debug); |
| } |
| |
| if(v_EPTF_CS_initialized) { |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": already initialized")); |
| return; |
| } |
| |
| f_EPTF_FBQ_init_CT(pl_selfName); |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": initializing " & f_EPTF_Base_selfName())); |
| |
| f_EPTF_LGenBaseStats_init(f_EPTF_Base_selfName(), "Entity#"); |
| |
| if(pl_loadBalancingAvailable) { |
| f_EPTF_LB_init(f_EPTF_Base_selfName()); |
| } |
| |
| f_EPTF_ExecCtrlClient_init_CT(f_EPTF_Base_selfName(), pl_ExecCtrlRef, false); |
| |
| v_EPTF_CS_scenarioCreated_hookIdx := f_EPTF_LGenBase_addScenarioCreatedCallback(refers(f_EPTF_CS_Admin_scenarioCreated)); |
| f_EPTF_ExecCtrlClient_registerEndOfConfigCallback(refers(f_EPTF_CS_Admin_endOfConfig)); |
| |
| |
| v_EPTF_CS_db_LGens := {{}, c_EPTF_emptyFreeBusyQueue}; |
| f_EPTF_FBQ_initFreeBusyQueue(v_EPTF_CS_db_LGens.queue); |
| |
| if(pl_EPTF_CS_AdminInit != null) { pl_EPTF_CS_AdminInit.apply(f_EPTF_Base_selfName(), pl_adminIdx); } |
| |
| f_EPTF_CS_Admin_sanityCheck(); |
| |
| f_EPTF_CS_Admin_initFSM(); |
| |
| f_EPTF_Base_registerCleanup(refers(f_EPTF_CS_Admin_cleanup_CT)); |
| |
| f_EPTF_Var_newInt(f_EPTF_Base_selfName() & "." & c_EPTF_CS_varName_intVerdict, |
| c_EPTF_CS_intVerdict_none, v_EPTF_CS_Admin_intVerdict_k); |
| f_EPTF_Var_addPostProcFn(v_EPTF_CS_Admin_intVerdict_k, |
| { refers(f_EPTF_CS_Admin_verdictPostProc), {}} ); |
| |
| //Create variables and adding postproc |
| var integer vl_key |
| f_EPTF_Var_newFloat( |
| f_EPTF_CS_Admin_varName4AvgLGenUsage(), 0.0, vl_key); |
| f_EPTF_Var_addPostProcFn( |
| vl_key, { refers(f_EPTF_CS_Admin_AvgLGenUsage), {}} ) |
| f_EPTF_Var_addSyncCallBackFn(refers(f_EPTF_CS_Admin_AvgLGenUsage_Synccallback), {vl_key}) |
| |
| f_EPTF_Var_newFloat( |
| f_EPTF_CS_Admin_varName4MaxLGenUsage(), 0.0, vl_key); |
| f_EPTF_Var_addPostProcFn( |
| vl_key, { refers(f_EPTF_CS_Admin_MaxLGenUsage), {}} ) |
| f_EPTF_Var_addSyncCallBackFn(refers(f_EPTF_CS_Admin_MaxLGenUsage_Synccallback), {vl_key}) |
| |
| if(pl_dataSource_compRef != null){ |
| f_EPTF_DataSourceClient_init_CT(f_EPTF_Base_selfName(), pl_dataSource_compRef); |
| f_EPTF_DataSourceClient_registerData(c_EPTF_CS_DataSource_sourceId, f_EPTF_Base_selfName(), refers(f_EPTF_CS_DSProcessData), pl_dataSource_compRef); |
| //f_EPTF_CS_DSCreateIteratorVars(); |
| f_EPTF_DataSourceClient_sendReady(c_EPTF_CS_DataSource_sourceId, f_EPTF_Base_selfName()); |
| } |
| |
| v_EPTF_CS_initialized := true; |
| |
| f_EPTF_ExecCtrlClient_readyToStart(); |
| |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": initialization finished for " & f_EPTF_Base_selfName())); |
| } |
| |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_varName4AvgLGenUsage |
| // |
| //Purpose: |
| // Function is creating the variable name of average LGen usage |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| friend function f_EPTF_CS_Admin_varName4AvgLGenUsage() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return charstring |
| { |
| return f_EPTF_Base_selfName() & ".AvgLGenUsage"; |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_varName4MaxLGenUsage |
| // |
| //Purpose: |
| // Function is creating the variable name of max LGen usage |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| friend function f_EPTF_CS_Admin_varName4MaxLGenUsage() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return charstring |
| { |
| return f_EPTF_Base_selfName() & ".MaxLGenUsage"; |
| } |
| |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_AvgLGenUsage_Synccallback |
| // |
| //Purpose: |
| // Function is responsible for refreshing the AvgLGenUsage variable in the gui |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_AvgLGenUsage_Synccallback(in EPTF_IntegerList pl_argList) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| var integer vl_idx := pl_argList[0]; |
| f_EPTF_Var_refreshContent(vl_idx); |
| } |
| |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_MaxLGenUsage_Synccallback |
| // |
| //Purpose: |
| // Function is responsible for refreshing the MaxLGenUsage variable in the gui |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_MaxLGenUsage_Synccallback(in EPTF_IntegerList pl_argList) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| var integer vl_idx := pl_argList[0]; |
| f_EPTF_Var_refreshContent(vl_idx); |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_LGenBase_init_CT |
| // |
| //Purpose: |
| // Function for initializing CS_LGenBase component. |
| // |
| //Parameters: |
| // - pl_selfName - *in* *charstring* - EPTF self-name |
| // - pl_adminIdx - *in* *integer* - admin index |
| // - pl_ExecCtrlRef - *in* <EPTF_ExecCtrl_CT> - Execution Control component reference |
| // - pl_EPTF_CS_AdminInit - *in* <EPTF_CS_AdminInit_FT> - user defined init function reference |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_LGenBase_init_CT( |
| in charstring pl_selfName) |
| runs on EPTF_CS_LGenBase_CT |
| { |
| if(v_CS_LGenBase_initialized) { |
| log(%definitionId& ": already initialized"); |
| return; |
| } |
| f_EPTF_Base_init_CT(pl_selfName); |
| v_CS_LGenBase_initialized := true |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_setEntityNameSuffix |
| // |
| //Purpose: |
| // Function for setting the entity name suffix. |
| // |
| //Parameters: |
| // - pl_suffix - *in* *charstring* - the suffix string |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // The entity name suffix should be unique for each different types of |
| // central scheduling admins. It should be set from the user init function. |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_Admin_setEntityNameSuffix(in charstring pl_suffix) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| v_EPTF_CS_EntityName_Suffix := pl_suffix; |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_declareTrafficCase |
| // |
| //Purpose: |
| // Function for declaring a traffic case by name supported by the LGens, |
| // and assigning a traffic case selector to it. |
| // |
| //Parameters: |
| // - pl_tcName - *in* *charstring* - name of the traffic case |
| // - pl_tcSelector - *in* *integer* - traffic case selector |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_Admin_declareTrafficCase( |
| in charstring pl_tcName, |
| in integer pl_tcSelector) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(sizeof(v_EPTF_CS_tcTypeIdx2tcSelector) == 0) { |
| for(var integer i := 0; i < sizeof(v_EPTF_CS_tcName2tcSelector); i := i + 1) { |
| if(v_EPTF_CS_tcName2tcSelector[i].tcName == pl_tcName) { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": redeclaration of traffic case ", pl_tcName)); |
| //f_EPTF_Base_stop(); |
| } |
| if(v_EPTF_CS_tcName2tcSelector[i].tcSelector == pl_tcSelector) { |
| f_EPTF_CS_ApplAdminBase_warning(log2str(%definitionId& " WARNING: traffic case selector ", pl_tcSelector, |
| " assigned to traffic case ", pl_tcName, " is already used by ", |
| v_EPTF_CS_tcName2tcSelector[i].tcName)); |
| } |
| } |
| v_EPTF_CS_tcName2tcSelector[sizeof(v_EPTF_CS_tcName2tcSelector)] := { |
| tcName := pl_tcName, |
| tcSelector := pl_tcSelector |
| } |
| } else { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": Traffic cases should be declared in user defined init function.")); |
| //f_EPTF_Base_stop(); |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_sanityCheck |
| // |
| //Purpose: |
| // Function for checking if mandatory function references have been initialized. |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_sanityCheck() runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(v_EPTF_CS_addExecBurstElem == null) { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": missing initialisation of mandatory function reference 'v_EPTF_CS_addExecBurstElem'")); |
| //f_EPTF_Base_stop(); |
| } |
| |
| if(v_EPTF_CS_sendExecBurst == null) { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": missing initialisation of mandatory function reference 'v_EPTF_CS_sendExecBurst'")); |
| //f_EPTF_Base_stop(); |
| } |
| |
| if(v_EPTF_CS_LGenCreate == null) { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": missing initialisation of mandatory function reference 'v_EPTF_CS_LGenCreate'")); |
| //f_EPTF_Base_stop(); |
| } |
| |
| if(sizeof(v_EPTF_CS_tcName2tcSelector) == 0) { |
| f_EPTF_CS_ApplAdminBase_warning(log2str(%definitionId& " WARNING: no traffic case was declared. Traffic case "& |
| "selectors will be auto-assigned.")); |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_cleanup_CT |
| // |
| //Purpose: |
| // CS_ApplAdminBase component cleanup function. |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // Calls the user defined cleanup function reference if not *null*. |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_cleanup_CT() runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(not v_EPTF_CS_initialized) { |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": not yet initialized")); |
| return; |
| } |
| f_EPTF_CS_Admin_pauseScenario(); |
| log(%definitionId& ": Admin verdict: ", v_EPTF_CS_Admin_verdict); |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": performing cleanup")); |
| if(v_EPTF_CS_AdminCleanup != null) { v_EPTF_CS_AdminCleanup.apply(); } |
| v_EPTF_CS_initialized := false; |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_initFSM |
| // |
| //Purpose: |
| // Function for FSM related initialization. |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_initFSM() runs on EPTF_CS_ApplAdminBase_CT |
| { |
| v_EPTF_CS_myBIdx := f_EPTF_LGenBase_declareBehaviorType(c_EPTF_CS_BehaviorName & v_EPTF_CS_EntityName_Suffix, -1, |
| null, null, null); |
| v_EPTF_CS_myBIdx_LGen := f_EPTF_LGenBase_declareBehaviorType(c_EPTF_CS_BehaviorName_LGen & v_EPTF_CS_EntityName_Suffix, -1, |
| null, null, null); |
| |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": myBIdx: ", v_EPTF_CS_myBIdx)); |
| |
| f_EPTF_LGenBase_declareEntityType(c_EPTF_CS_EntityName_Tc & v_EPTF_CS_EntityName_Suffix, {c_EPTF_CS_BehaviorName & v_EPTF_CS_EntityName_Suffix}); |
| f_EPTF_LGenBase_declareEntityType(c_EPTF_CS_EntityName_LGen & v_EPTF_CS_EntityName_Suffix, {c_EPTF_CS_BehaviorName_LGen & v_EPTF_CS_EntityName_Suffix}); |
| |
| if(c_EPTF_CS_eventIdx_receivedResultSuccess_Tc != f_EPTF_LGenBase_declareFsmEvent(c_EPTF_CS_BehaviorName & v_EPTF_CS_EntityName_Suffix, c_EPTF_CS_eventName_receivedResultSuccess_Tc) or |
| c_EPTF_CS_eventIdx_receivedResultFail_Tc != f_EPTF_LGenBase_declareFsmEvent(c_EPTF_CS_BehaviorName & v_EPTF_CS_EntityName_Suffix, c_EPTF_CS_eventName_receivedResultFail_Tc)) { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": Error while declaring FSM events")); |
| //f_EPTF_Base_stop(); |
| } |
| |
| f_EPTF_LGenBase_declareCompactFsmTable(f_EPTF_CS_Admin_getFSM_Tc()); |
| |
| f_EPTF_LGenBase_addBurstGeneratedCallBack(refers(f_EPTF_CS_Admin_burstPostCalc)); |
| //v_EPTF_CS_burstPostCalc_hook := v_LGenBase_burstPostCalc; |
| //v_LGenBase_burstPostCalc := refers(f_EPTF_CS_Admin_burstPostCalc); |
| |
| // entityGroups, TcTypes and scenario created by ExecCtrl |
| // scenario started by ExecCtrl |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_getFSM_Tc |
| // |
| //Purpose: |
| // Function that returns the FSM used for traffic cases. |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_getFSM_Tc() runs on EPTF_CS_ApplAdminBase_CT |
| return EPTF_LGenBase_CompactFsmTable |
| { |
| return |
| { |
| name := c_EPTF_CS_FsmName_Tc, |
| stateList := { c_EPTF_CS_stateName_idle, c_EPTF_CS_stateName_busy }, |
| timerList := {}, |
| table := { |
| { eventToListen := {c_EPTF_LGenBase_bIdx, c_EPTF_LGenBase_inputIdx_testMgmt_startTC, fsm}, |
| cellRow := { |
| { // state = idle |
| actionList := { |
| {refers(f_EPTF_CS_startTc_Tc), {}} |
| }, |
| nextStateCalculation := omit, |
| nextState := c_EPTF_CS_stateIdx_busy |
| }, |
| { // state = busy |
| actionList := omit, |
| nextStateCalculation := omit, |
| nextState := omit |
| } |
| } |
| }, |
| { eventToListen := {v_EPTF_CS_myBIdx, c_EPTF_CS_eventIdx_receivedResultSuccess_Tc, fsm}, |
| cellRow := { |
| { // state = idle |
| actionList := omit, |
| nextStateCalculation := omit, |
| nextState := omit |
| }, |
| { // state = busy |
| actionList := { |
| {refers(f_EPTF_LGenBase_step_trafficSuccess), {}} |
| }, |
| nextStateCalculation := omit, |
| nextState := c_EPTF_CS_stateIdx_idle |
| } |
| } |
| }, |
| { eventToListen := {v_EPTF_CS_myBIdx, c_EPTF_CS_eventIdx_receivedResultFail_Tc, fsm}, |
| cellRow := { |
| { // state = idle |
| actionList := omit, |
| nextStateCalculation := omit, |
| nextState := omit |
| }, |
| { // state = busy |
| actionList := { |
| {refers(f_EPTF_LGenBase_step_trafficFailed), {}} |
| }, |
| nextStateCalculation := omit, |
| nextState := c_EPTF_CS_stateIdx_idle |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_startTc_Tc |
| // |
| //Purpose: |
| // 'startTc' event handler for traffic case FSM |
| // |
| //Parameters: |
| // - pl_ptr - *in* <EPTF_LGenBase_TestStepArgs> - FSM step parameters |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_startTc_Tc(in EPTF_LGenBase_TestStepArgs pl_ptr) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| // f_EPTF_Base_assert(%definitionId& ": refContext or fCtxIdx not present in TestStepArgs", |
| // ispresent(pl_ptr.refContext) and ispresent(pl_ptr.refContext.fCtxIdx)); |
| if(tsp_debug_EPTF_CS_Admin_Functions) { log(%definitionId& ": pl_ptr := ", pl_ptr); } |
| |
| var integer vl_tcSelector := f_EPTF_LGenBase_getTypeIdxOfTc(pl_ptr.stepArgs[0]); |
| vl_tcSelector := v_EPTF_CS_tcTypeIdx2tcSelector[vl_tcSelector]; |
| |
| var EPTF_IntegerList vl_rangeItems := {}; |
| for(var integer i := 1; i < sizeof(pl_ptr.stepArgs); i := i + 1) { |
| vl_rangeItems[i-1] := pl_ptr.stepArgs[i]; |
| } |
| |
| v_EPTF_CS_addExecBurstElem.apply(vl_tcSelector, vl_rangeItems); |
| |
| v_bufferedTCs[sizeof(v_bufferedTCs)] := { |
| eIdx := pl_ptr.eIdx, |
| fCtxIdx := pl_ptr.refContext.fCtxIdx |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_SelectAndTriggenLGen |
| // |
| //Purpose: |
| // Function for selecting a free LGen and sending the buffered execBurst_msg to |
| // it by calling the user defined callback function v_EPTF_CS_sendExecBurst |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_SelectAndTriggenLGen() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return boolean |
| { |
| if(sizeof(v_bufferedTCs) == 0) { |
| f_EPTF_CS_ApplAdminBase_warning(log2str("WARNING " & %definitionId& ": no trigger message is buffered.")); |
| return false; |
| } |
| |
| if(f_EPTF_FBQ_getLengthOfFreeChain(v_EPTF_CS_db_LGens.queue) > 0) { // this 'if' removes the "no more free slots" log... |
| if(f_EPTF_LB_getInitialized()) { |
| v_EPTF_CS_selectedLGen := f_EPTF_LB_selectLoadGen(); |
| } else { |
| v_EPTF_CS_selectedLGen := f_EPTF_FBQ_getFreeSlot(v_EPTF_CS_db_LGens.queue); |
| } |
| } else { |
| v_EPTF_CS_selectedLGen := -1; |
| } |
| |
| v_EPTF_CS_SelectionAttempts := v_EPTF_CS_SelectionAttempts + 1; |
| |
| if (v_EPTF_CS_selectedLGen<0) { |
| f_EPTF_CS_ApplAdminBase_warning(log2str("WARNING: "& %definitionId& ":no free LGen: saturation!!!")); |
| f_EPTF_CS_Admin_pauseScenario(); |
| return false; |
| } else { |
| // Set busy status |
| f_EPTF_FBQ_moveFromFreeToBusyTail(v_EPTF_CS_selectedLGen, v_EPTF_CS_db_LGens.queue); |
| } |
| |
| var integer vl_numBusy := f_EPTF_FBQ_getLengthOfBusyChain(v_EPTF_CS_db_LGens.queue); |
| if(v_EPTF_CS_MaxLGenUsageCounter < vl_numBusy) { |
| v_EPTF_CS_MaxLGenUsageCounter := vl_numBusy; |
| } |
| v_EPTF_CS_AvgLGenUsageCounter := v_EPTF_CS_AvgLGenUsageCounter + vl_numBusy; |
| |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": selected LGen: ", v_EPTF_CS_selectedLGen)); |
| |
| v_EPTF_CS_sendExecBurst.apply(); |
| return true; |
| } |
| |
| friend function f_EPTF_CS_getSelectionAttempts() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return integer |
| { |
| return v_EPTF_CS_SelectionAttempts; |
| } |
| |
| friend function f_EPTF_CS_resetSelectionAttempts() |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| v_EPTF_CS_SelectionAttempts := 0; |
| } |
| |
| friend function f_EPTF_CS_getAvgLGenUsageCounter() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return integer |
| { |
| return v_EPTF_CS_AvgLGenUsageCounter; |
| } |
| |
| friend function f_EPTF_CS_resetAvgLGenUsageCounter() |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| v_EPTF_CS_AvgLGenUsageCounter := 0; |
| } |
| |
| friend function f_EPTF_CS_getMaxLGenUsageCounter() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return integer |
| { |
| return v_EPTF_CS_AvgLGenUsageCounter; |
| } |
| |
| friend function f_EPTF_CS_resetMaxLGenUsageCounter() |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| v_EPTF_CS_AvgLGenUsageCounter := 0; |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_handleExecResult |
| // |
| //Purpose: |
| // Function for handling a singe execution result. |
| // |
| //Parameters: |
| // - pl_execResult - *in* *verdicttype* - execution result for a single traffic case |
| // - pl_indexInBurst - *in* *integer* - iteration through result message |
| // - pl_LGenIdx - *in* *integer* - index of the LGen |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // Call f_EPTF_CS_lookupBySenderAddress with the sender component as parameter |
| // to get the LGen index (pl_LGenIdx). |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_handleExecResult( |
| in verdicttype pl_execResult, // result message should contain this |
| in integer pl_indexInBurst, // iteration through result message |
| in integer pl_LGenIdx) // call f_EPTF_CS_lookupBySenderAddress(sender-of-result-message) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| var integer eIdx := v_EPTF_CS_db_LGens.loadgens[pl_LGenIdx].runningTCs[pl_indexInBurst].eIdx; |
| var integer fCtxIdx := v_EPTF_CS_db_LGens.loadgens[pl_LGenIdx].runningTCs[pl_indexInBurst].fCtxIdx; |
| if(pl_execResult == pass /*or pl_execResult == none*/) { |
| f_EPTF_LGenBase_dispatchEvent({ |
| event := { |
| bIdx := v_EPTF_CS_myBIdx, |
| iIdx := c_EPTF_CS_eventIdx_receivedResultSuccess_Tc, |
| target := { |
| eIdx := eIdx, |
| fsmCtxIdx := fCtxIdx |
| }, |
| source := omit |
| }, |
| reportedArgs := {} |
| }); |
| } else { |
| f_EPTF_LGenBase_dispatchEvent({ |
| event := { |
| bIdx := v_EPTF_CS_myBIdx, |
| iIdx := c_EPTF_CS_eventIdx_receivedResultFail_Tc, |
| target := { |
| eIdx := eIdx, |
| fsmCtxIdx := fCtxIdx |
| }, |
| source := omit |
| }, |
| reportedArgs := {} |
| }); |
| } |
| |
| var integer tcIdx := f_EPTF_LGenBase_tcIdxOfFSM(eIdx,fCtxIdx), |
| eGrpIdx := f_EPTF_LGenBase_getEGrpIdxOfTc(tcIdx), |
| eScIdx := f_EPTF_LGenBase_getScIdxOfTc(tcIdx) |
| |
| f_EPTF_CS_setScenarioVerdict(f_EPTF_LGenBase_scenarioName(eGrpIdx, eScIdx), pl_execResult); |
| f_EPTF_CS_summarizeVerdicts(pl_execResult); |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_LGenBurstFinished |
| // |
| //Purpose: |
| // Function for freeing a LGen after processing all its result messages, |
| // to make it available for new execution burst. |
| // |
| //Parameters: |
| // - pl_LGenIdx - *in* *integer* - LGen index |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // Call this function after calling f_EPTF_CS_handleExecResult |
| // for all result message elements. |
| // Call f_EPTF_CS_lookupBySenderAddress with the sender component as parameter |
| // to get the LGen index (pl_LGenIdx). |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_LGenBurstFinished( |
| in integer pl_LGenIdx) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(v_EPTF_CS_scenarioPaused) { |
| if(sizeof(v_bufferedTCs) > 0) { |
| v_EPTF_CS_selectedLGen := pl_LGenIdx; |
| v_EPTF_CS_sendExecBurst.apply(); |
| v_EPTF_CS_db_LGens.loadgens[v_EPTF_CS_selectedLGen].runningTCs := v_bufferedTCs; |
| v_bufferedTCs := {} |
| return; |
| } else { |
| f_EPTF_CS_Admin_unpauseScenario(); |
| } |
| } |
| |
| // make LGen available for new execBurst |
| if(f_EPTF_FBQ_itemIsBusy(pl_LGenIdx, v_EPTF_CS_db_LGens.queue)) { |
| f_EPTF_FBQ_moveFromBusyToFreeTail(pl_LGenIdx, v_EPTF_CS_db_LGens.queue); |
| } else { |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": LGen ", pl_LGenIdx, " is not in busy queue")); |
| } |
| v_EPTF_CS_db_LGens.loadgens[pl_LGenIdx].runningTCs := {}; |
| } |
| |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_handleLGenStatusMsg |
| // |
| //Purpose: |
| // Function for handling LGen status message. |
| // |
| //Parameters: |
| // - pl_enabled - *inout* *boolean* - status message |
| // - pl_compRef - *inout* <EPTF_CS_LGenBase_CT> - sender of the message |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_handleLGenStatusMsg( |
| inout boolean pl_enabled, |
| inout EPTF_CS_LGenBase_CT pl_compRef) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(v_EPTF_CS_nofCreatedLGens == v_EPTF_CS_nofLGens) { |
| var integer vl_LGenIdx := f_EPTF_CS_lookupBySenderAddress(pl_compRef); |
| |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": LGen index: ", vl_LGenIdx, " enabled: ", pl_enabled)); |
| |
| if(pl_enabled) { |
| if(f_EPTF_FBQ_itemIsBusy(vl_LGenIdx, v_EPTF_CS_db_LGens.queue)) { |
| if(v_EPTF_CS_scenarioPaused) { |
| f_EPTF_CS_Admin_unpauseScenario(); |
| } |
| f_EPTF_FBQ_moveFromBusyToFreeTail(vl_LGenIdx, v_EPTF_CS_db_LGens.queue); |
| } |
| } else { |
| if(f_EPTF_FBQ_itemIsFree(vl_LGenIdx, v_EPTF_CS_db_LGens.queue)) { |
| f_EPTF_FBQ_moveFromFreeToBusyTail(vl_LGenIdx, v_EPTF_CS_db_LGens.queue); |
| if(v_EPTF_CS_MaxLGenUsageCounter < f_EPTF_FBQ_getLengthOfBusyChain(v_EPTF_CS_db_LGens.queue)) { |
| v_EPTF_CS_MaxLGenUsageCounter := f_EPTF_FBQ_getLengthOfBusyChain(v_EPTF_CS_db_LGens.queue); |
| } |
| if(f_EPTF_FBQ_getLengthOfFreeChain(v_EPTF_CS_db_LGens.queue) == 0) { |
| f_EPTF_CS_Admin_pauseScenario(); |
| } |
| } |
| } |
| } else { |
| if(not pl_enabled) { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": problem reported by LGen during initialization")); |
| //f_EPTF_Base_stop(); |
| } |
| v_EPTF_CS_nofCreatedLGens := v_EPTF_CS_nofCreatedLGens + 1; |
| } |
| } |
| |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_lookupBySenderAddress |
| // |
| //Purpose: |
| // Function to look up the LGen index by sender component reference. |
| // |
| //Parameters: |
| // - pl_compRef - *inout* <EPTF_CS_LGenBase_CT> - |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_lookupBySenderAddress( |
| inout EPTF_CS_LGenBase_CT pl_compRef) |
| runs on EPTF_CS_ApplAdminBase_CT |
| return integer |
| { |
| for(var integer i := 0; i < sizeof(v_EPTF_CS_db_LGens.loadgens); i := i + 1) { |
| if(v_EPTF_CS_db_LGens.loadgens[i].compRef == pl_compRef) { return i; } |
| } |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": component reference ", pl_compRef, |
| " not found in LGen database: ", v_EPTF_CS_db_LGens.loadgens)); |
| //f_EPTF_Base_stop(); |
| return -1; |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_summarizeVerdicts |
| // |
| //Purpose: |
| // Function for summarizing traffic case verdicts. |
| // |
| //Parameters: |
| // - pl_verdict - *in* *verdicttype* - verdict of the traffic case |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_summarizeVerdicts(in verdicttype pl_verdict) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| var integer pl_iv := f_EPTF_CS_verdict2int(pl_verdict); |
| |
| var integer pl_sum := f_EPTF_CS_summarizeIntVerdicts( |
| f_EPTF_Var_getIntValue(v_EPTF_CS_Admin_intVerdict_k), pl_iv); |
| |
| f_EPTF_Var_adjustContent(v_EPTF_CS_Admin_intVerdict_k, {intVal:=pl_sum}); |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_burstPostCalc |
| // |
| //Purpose: |
| // CPS event burst post-processing function, used for selecting a LGen and |
| // sending the execution burst message |
| // |
| //Parameters: |
| // - pl_schData - *inout* <EPTF_LGenBase_SchedulerData> - scheduler data |
| // - pl_maxSend - *in* *integer* - burst size for this scheduler interval |
| // - pl_sent - *in* *integer* - actual burst generated |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_burstPostCalc( |
| inout EPTF_LGenBase_SchedulerData pl_schData, |
| in integer pl_maxSend, |
| in integer pl_sent) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(pl_sent > 0) { |
| if(f_EPTF_CS_SelectAndTriggenLGen()) { |
| v_EPTF_CS_db_LGens.loadgens[v_EPTF_CS_selectedLGen].runningTCs := v_bufferedTCs; |
| v_bufferedTCs := {} |
| } |
| } |
| |
| if(v_EPTF_CS_burstPostCalc_hook != null) { |
| v_EPTF_CS_burstPostCalc_hook.apply(pl_schData, pl_maxSend, pl_sent); |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_pauseScenario |
| // |
| //Purpose: |
| // Function for pausing the scenario. |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_pauseScenario() |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(not v_EPTF_CS_scenarioPaused) { |
| v_EPTF_CS_scenarioPaused := true; |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": pausing scenario")); |
| /* for(var integer i := 0; i < sizeof(v_LGenBase_trafficCases); i := i + 1) { |
| f_EPTF_LGenBase_pauseTrafficCaseByIdx(i); |
| }*/ |
| for(var integer egIdx := 0; egIdx < f_EPTF_LGenBase_getEGrpCount(); egIdx := egIdx + 1) { |
| for(var integer scIdx := 0; |
| scIdx < f_EPTF_LGenBase_getScCountOfEGrp(egIdx); |
| scIdx := scIdx + 1) { |
| if(f_EPTF_LGenBase_getScState(egIdx,scIdx) == c_EPTF_LGenBase_tcStateRunning) { |
| if(f_EPTF_LGenBase_isWeightedScenario(egIdx, scIdx)) { |
| f_EPTF_LGenBase_pauseWeightedScenario(egIdx, scIdx); |
| } else { |
| f_EPTF_LGenBase_pauseScenario(egIdx, scIdx); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_unpauseScenario |
| // |
| //Purpose: |
| // Function for unpausing the scenario. |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_unpauseScenario() |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(v_EPTF_CS_scenarioPaused) { |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": unpausing scenario")); |
| v_EPTF_CS_scenarioPaused := false; |
| // un-pause scenario |
| /* for(var integer i := 0; i < sizeof(v_LGenBase_trafficCases); i := i + 1) { |
| f_EPTF_LGenBase_startLaunchTC(i); |
| }*/ |
| for(var integer egIdx := 0; egIdx < f_EPTF_LGenBase_getEGrpCount(); egIdx := egIdx + 1) { |
| for(var integer scIdx := 0; |
| scIdx < f_EPTF_LGenBase_getScCountOfEGrp(egIdx); |
| scIdx := scIdx + 1) { |
| if(f_EPTF_LGenBase_getScState(egIdx,scIdx) == c_EPTF_LGenBase_tcStatePaused) { |
| if(f_EPTF_LGenBase_isWeightedScenario(egIdx, scIdx)) { |
| f_EPTF_LGenBase_startLaunchWeightedScenario(egIdx, scIdx); |
| } else { |
| f_EPTF_LGenBase_enableScenarioOnEntityGroup(egIdx, scIdx); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| friend function f_EPTF_CS_Admin_isScenarioPaused() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return boolean |
| { |
| return v_EPTF_CS_scenarioPaused; |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_buildTcTypeIdx2tcSelector |
| // |
| //Purpose: |
| // Function to build the lookup table used for retrieving traffic case selector |
| // by traffic case type index (which is dependent on definition order in config file). |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_buildTcTypeIdx2tcSelector() |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(sizeof(v_EPTF_CS_tcName2tcSelector) > 0) { |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": assigning TC selectors based on declared traffic cases")); |
| for(var integer i := 0; i < f_EPTF_LGenBase_getTcTypeCount(); i := i + 1) { |
| if(f_EPTF_LGenBase_getETypeNameOfTcType(i) == |
| c_EPTF_CS_EntityName_Tc & v_EPTF_CS_EntityName_Suffix) { |
| var integer vl_tcSelector := -1; |
| for(var integer j := 0; j < sizeof(v_EPTF_CS_tcName2tcSelector); j := j + 1) { |
| if(v_EPTF_CS_tcName2tcSelector[j].tcName == f_EPTF_LGenBase_getTcTypeName(i)) { |
| vl_tcSelector := v_EPTF_CS_tcName2tcSelector[j].tcSelector; |
| j := sizeof(v_EPTF_CS_tcName2tcSelector); |
| } |
| } |
| if(vl_tcSelector < 0) { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": undefined traffic case ", |
| f_EPTF_LGenBase_getTcTypeName(i), " for entity type ", |
| c_EPTF_CS_EntityName_Tc & v_EPTF_CS_EntityName_Suffix)); |
| //f_EPTF_Base_stop(); |
| } |
| v_EPTF_CS_tcTypeIdx2tcSelector[i] := vl_tcSelector; |
| } |
| } |
| } else { |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": auto-assigning TC selectors")); |
| for(var integer i := 0; i < f_EPTF_LGenBase_getTcTypeCount(); i := i + 1) { |
| v_EPTF_CS_tcTypeIdx2tcSelector[i] := i; |
| } |
| } |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId&": v_EPTF_CS_tcName2tcSelector: ", v_EPTF_CS_tcName2tcSelector)); |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId&": v_EPTF_CS_tcTypeIdx2tcSelector: ", v_EPTF_CS_tcTypeIdx2tcSelector)); |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_scenarioCreated |
| // |
| //Purpose: |
| // Callback function that is called by the LGenBase when the scenario is created. |
| // Used for creating the load generator PTCs. |
| // |
| //Parameters: |
| // - pl_eGrpIdx - *in* *integer* - |
| // - pl_scIdx - *in* *integer* - |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_scenarioCreated( |
| in integer pl_eGrpIdx, |
| in integer pl_scIdx) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(f_EPTF_LGenBase_entityTypeNameOfEG(pl_eGrpIdx) == c_EPTF_CS_EntityName_LGen & v_EPTF_CS_EntityName_Suffix) { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": No scenario should be started on LGen entities.")); |
| //f_EPTF_Base_stop(); |
| } |
| |
| var integer scNameIdx := -1; |
| var charstring scName := f_EPTF_LGenBase_scNameInEG(pl_eGrpIdx, pl_scIdx); |
| for(var integer i := 0; i < sizeof(v_EPTF_CS_scenarioNames) and scNameIdx < 0; i := i + 1) { |
| if(v_EPTF_CS_scenarioNames[i] == scName) { |
| scNameIdx := i; |
| } |
| } |
| |
| if(scNameIdx < 0) { |
| scNameIdx := sizeof(v_EPTF_CS_scenarioNames); |
| v_EPTF_CS_scenarioNames[scNameIdx] := scName; |
| |
| v_EPTF_CS_scenarioIntVerdict_keys[scNameIdx] := -1; |
| |
| f_EPTF_Var_newInt(f_EPTF_Base_selfName() & "." & scName & "." & c_EPTF_CS_varName_intVerdict, |
| c_EPTF_CS_intVerdict_none, v_EPTF_CS_scenarioIntVerdict_keys[scNameIdx]); |
| } |
| |
| // if(v_EPTF_CS_scenarioCreated_hook != null) { |
| // if(tsp_debug_EPTF_CS_Admin_Functions) { |
| // log(%definitionId& ": calling ", v_EPTF_CS_scenarioCreated_hook); |
| // } |
| // v_EPTF_CS_scenarioCreated_hook.apply(pl_eGrpIdx, pl_scIdx); |
| // } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_endOfConfig |
| // |
| //Purpose: |
| // Callback function for end-of-config event of ExecCtrlClient. |
| // |
| //Parameters: |
| // - |
| // |
| //Errors: |
| // - |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_endOfConfig() |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(v_EPTF_CS_nofLGens < 0) { |
| // get size of group with LGen entity type into v_EPTF_CS_nofLGens |
| var integer pl_lgenEGrpIdx := -1; |
| for(var integer i := 0; i < f_EPTF_LGenBase_getEGrpCount(); i := i + 1) { |
| if(f_EPTF_LGenBase_entityTypeNameOfEG(i) == c_EPTF_CS_EntityName_LGen & v_EPTF_CS_EntityName_Suffix) { |
| pl_lgenEGrpIdx := i; |
| i := f_EPTF_LGenBase_getEGrpCount(); |
| } |
| } |
| |
| if(pl_lgenEGrpIdx < 0) { |
| f_EPTF_CS_ApplAdminBase_error(%definitionId&": could not find entity group " & |
| c_EPTF_CS_EntityName_LGen & v_EPTF_CS_EntityName_Suffix); |
| } |
| |
| v_EPTF_CS_nofLGens := f_EPTF_LGenBase_getEGrpECount(pl_lgenEGrpIdx); |
| |
| f_EPTF_CS_Admin_buildTcTypeIdx2tcSelector(); |
| |
| f_EPTF_CS_Admin_createLGens(); |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_createLGens |
| // |
| //Purpose: |
| // Function for creating load generator PTCs by calling the user defined callback |
| // function v_EPTF_CS_LGenCreate. The init function of the extending component |
| // must activate an altstep that receives the LGenStatus message and calls |
| // f_EPTF_CS_handleLGenStatusMsg. |
| // |
| //Parameters: |
| // - |
| // |
| //Errors: |
| // If a LGen does not send LGenStatus in the time interval tsp_EPTF_CLL_CS_Admin_LGenCreationDelay. |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_createLGens() runs on EPTF_CS_ApplAdminBase_CT |
| { |
| timer T_EPTF_LGenCreationDelay := tsp_EPTF_CLL_CS_Admin_LGenCreationDelay; |
| f_EPTF_FBQ_createFreeSlots(v_EPTF_CS_nofLGens, v_EPTF_CS_db_LGens.queue); |
| for(var integer i := 0; i < v_EPTF_CS_nofLGens; i := i + 1) { |
| var charstring vl_LGenName := f_EPTF_Base_selfName() & ".LGen." & int2str(i); |
| |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": creating LGen[", i, "] with name " & vl_LGenName)); |
| |
| if(sizeof(tsp_EPTF_CS_LGenHostnameList) != 0) { |
| v_EPTF_CS_db_LGens.loadgens[i].hostIdx := i mod sizeof(tsp_EPTF_CS_LGenHostnameList); |
| v_EPTF_CS_db_LGens.loadgens[i].compRef := |
| v_EPTF_CS_LGenCreate.apply(i,vl_LGenName, tsp_EPTF_CS_LGenHostnameList[v_EPTF_CS_db_LGens.loadgens[i].hostIdx]); |
| } else { |
| v_EPTF_CS_db_LGens.loadgens[i].hostIdx := -1; |
| v_EPTF_CS_db_LGens.loadgens[i].compRef := |
| v_EPTF_CS_LGenCreate.apply(i,vl_LGenName, ""); |
| } |
| |
| timer T_LGenStatusGuard := tsp_EPTF_CLL_CS_Admin_LGenStatusGuard; |
| T_LGenStatusGuard.start; |
| T_EPTF_LGenCreationDelay.start; |
| // note: user-init function should activate an altstep receiving the |
| // LGenStatus and call f_EPTF_CS_handleLGenStatusMsg() from that altstep |
| alt { |
| [v_EPTF_CS_nofCreatedLGens == i+1]T_EPTF_LGenCreationDelay.timeout { } |
| []T_LGenStatusGuard.timeout |
| { |
| f_EPTF_CS_ApplAdminBase_error(log2str(%definitionId& ": timeout when waiting for LGen status message")); |
| //f_EPTF_Base_stop(); |
| } |
| } |
| if(T_LGenStatusGuard.running) { T_LGenStatusGuard.stop; } |
| if(T_EPTF_LGenCreationDelay.running) { T_EPTF_LGenCreationDelay.stop; } |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_behavior |
| // |
| //Purpose: |
| // Behavior function for the Cenral Scheduling Admin. The function reference parameters |
| // with *runs on self* make it necessary to start a user defined function on the admin |
| // and call this function from within that function. |
| // |
| //Parameters: |
| // - pl_selfName - *in* *charstring* - EPTF self-name |
| // - pl_adminIdx - *in* *integer* - admin index |
| // - pl_ExecCtrlRef - *in* <EPTF_ExecCtrl_CT> - Execution Control component reference |
| // - pl_EPTF_CS_AdminInit - *in* <EPTF_CS_AdminInit_FT> - user defined init function reference |
| // - pl_loadBalancingAvailable - *in* *boolean* - true if load balancing is to be used |
| // - pl_dataSource_Ref - *in* <EPTF_DataSource_CT> - datasource component reference |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_Admin_behavior( |
| in charstring pl_selfName, |
| in integer pl_adminIdx, |
| in EPTF_ExecCtrl_CT pl_ExecCtrlRef, |
| in EPTF_CS_AdminInit_FT pl_EPTF_CS_AdminInit, |
| in boolean pl_loadBalancingAvailable, |
| in EPTF_DataSource_CT pl_dataSource_Ref := null) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| if(sizeof(tsp_EPTF_CS_LGenHostnameList) < 2) { |
| pl_loadBalancingAvailable := false; |
| } |
| f_EPTF_CS_Admin_init_CT(pl_selfName, pl_adminIdx, pl_ExecCtrlRef, pl_EPTF_CS_AdminInit, pl_loadBalancingAvailable, pl_dataSource_Ref); |
| |
| f_EPTF_CS_ApplAdminBase_debug(log2str(%definitionId& ": entering main alt loop")); |
| f_EPTF_Base_wait4Shutdown(); |
| if(tsp_debug_EPTF_CS_Admin_Functions) { log(%definitionId& ": exited main alt loop"); } |
| |
| if(tsp_debug_EPTF_CS_Admin_Functions) { |
| for(var integer i := 0; i < sizeof(v_EPTF_CS_db_LGens.loadgens); i := i + 1) { |
| if(v_EPTF_CS_db_LGens.loadgens[i].compRef.running == false) { |
| f_EPTF_CS_ApplAdminBase_debug(log2str("LGen[", i, "] stopped operation. Component reference: ", v_EPTF_CS_db_LGens.loadgens[i].compRef)); |
| } else { |
| f_EPTF_CS_ApplAdminBase_debug(log2str("LGen[", i, "] still running. Component reference: ", v_EPTF_CS_db_LGens.loadgens[i].compRef)); |
| } |
| } |
| } |
| f_EPTF_Base_cleanup_CT(); |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_getCompRefOfSelectedLGen |
| // |
| //Purpose: |
| // Query function to obtain the comp.ref of the selected LGen to be used on "send to" statements. |
| // |
| //Parameters: |
| // - |
| // |
| //Return: |
| // <EPTF_Base_CT> |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| public function f_EPTF_CS_Admin_getCompRefOfSelectedLGen() |
| runs on EPTF_CS_ApplAdminBase_CT return EPTF_Base_CT{ |
| return v_EPTF_CS_db_LGens.loadgens[v_EPTF_CS_selectedLGen].compRef |
| } |
| |
| friend function f_EPTF_CS_getNumberOfLoadgens() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return integer |
| { |
| return sizeof(v_EPTF_CS_db_LGens.loadgens); |
| } |
| |
| friend function f_EPTF_CS_getCompRefOfLGen(in integer pl_lgenIdx) |
| runs on EPTF_CS_ApplAdminBase_CT |
| return EPTF_Base_CT |
| { |
| return v_EPTF_CS_db_LGens.loadgens[pl_lgenIdx].compRef; |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_Admin_verdictPostProc |
| // |
| //Purpose: |
| // Post-proc function for variable v_EPTF_CS_Admin_intVerdict_k. |
| // |
| //Parameters: |
| // - pl_v - *in* *verdicttype* - value to convert |
| // |
| //Return: |
| // *integer* |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // Converts the value of variable v_EPTF_CS_Admin_intVerdict_k to verdict and |
| // assigns it to v_EPTF_CS_Admin_verdict. |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_Admin_verdictPostProc( |
| in integer pl_idx, |
| in EPTF_IntegerList pl_argList) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| v_EPTF_CS_Admin_verdict := f_EPTF_CS_int2verdict(f_EPTF_Var_getIntValue(pl_idx)); |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_verdict2int |
| // |
| //Purpose: |
| // Function for converting variables of verdicttype to integer. |
| // |
| //Parameters: |
| // - pl_v - *in* *verdicttype* - value to convert |
| // |
| //Return: |
| // *integer* |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_verdict2int(in verdicttype pl_v) return integer |
| { |
| select(pl_v) { |
| case(none) { return c_EPTF_CS_intVerdict_none; } |
| case(pass) { return c_EPTF_CS_intVerdict_pass; } |
| case(inconc) { return c_EPTF_CS_intVerdict_inconc; } |
| case(fail) { return c_EPTF_CS_intVerdict_fail; } |
| case else { return c_EPTF_CS_intVerdict_error; } |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_int2verdict |
| // |
| //Purpose: |
| // Function for converting variables of integer to verdicttype. |
| // |
| //Parameters: |
| // - pl_i - *in* *integer* - value to convert |
| // |
| //Return: |
| // *verdicttype* |
| // |
| //Errors: |
| // Only values 0..4 are valid. Other values will result in `error' verdict being returned. |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_int2verdict(in integer pl_i) return verdicttype |
| { |
| select(pl_i) { |
| case(c_EPTF_CS_intVerdict_none) { return none; } |
| case(c_EPTF_CS_intVerdict_pass) { return pass; } |
| case(c_EPTF_CS_intVerdict_inconc) { return inconc; } |
| case(c_EPTF_CS_intVerdict_fail) { return fail; } |
| case(c_EPTF_CS_intVerdict_error) { return error; } |
| case else { |
| log("WARNING: "&%definitionId&": cannot convert number "&int2str(pl_i)&" to verdicttype. Returning `error'."); |
| return error; |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_summarizeIntVerdicts |
| // |
| //Purpose: |
| // Function for summarizing integers representing verdicts. |
| // |
| //Parameters: |
| // - pl_v1 - *in* *integer* - int-verdict 1 |
| // - pl_v2 - *in* *integer* - int-verdict 2 |
| // |
| //Return: |
| // *integer* - the summarized int-verdict |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_summarizeIntVerdicts(in integer pl_v1, in integer pl_v2) return integer |
| { |
| if(pl_v1 > pl_v2) { return pl_v1; } |
| else { return pl_v2; } |
| } |
| |
| //////////////////////////////////////////////////// |
| //Function: f_EPTF_CS_setScenarioVerdict |
| // |
| //Purpose: |
| // Function for setting the verdict of a scenario. |
| // |
| //Parameters: |
| // - pl_scName - *in* *charstring* - name of the scenario |
| // - pl_verdict - *in* *verdicttype* - verdict to set |
| // |
| //Return: |
| // - |
| // |
| //Errors: |
| // |
| //Detailed comments: |
| // |
| //////////////////////////////////////////////////// |
| private function f_EPTF_CS_setScenarioVerdict(in charstring pl_scName, in verdicttype pl_verdict) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| for(var integer i := 0; i < sizeof(v_EPTF_CS_scenarioNames); i := i + 1) { |
| if(pl_scName == v_EPTF_CS_scenarioNames[i]) { |
| var integer vl_v0 := f_EPTF_Var_getIntValue(v_EPTF_CS_scenarioIntVerdict_keys[i]); |
| var integer vl_iv := f_EPTF_CS_verdict2int(pl_verdict); |
| |
| var integer vl_sum := f_EPTF_CS_summarizeIntVerdicts(vl_v0, vl_iv); |
| |
| if(vl_sum != vl_v0) { |
| f_EPTF_Var_adjustContent(v_EPTF_CS_scenarioIntVerdict_keys[i], {intVal:=vl_sum}); |
| } |
| } |
| } |
| } |
| |
| friend function f_EPTF_CS_initialized() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return boolean |
| { |
| return v_EPTF_CS_initialized; |
| } |
| |
| group Logging { |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_CS_ApplAdminBase_error |
| // |
| // Purpose: |
| // Function to log an error from ApplAdminBase feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_CS_ApplAdminBase_error(in charstring pl_message) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| f_EPTF_Logging_error(true, tsp_EPTF_CS_ApplAdminBase_loggingComponentMask&": "&pl_message); |
| f_EPTF_Base_stopAll(); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_CS_ApplAdminBase_warning |
| // |
| // Purpose: |
| // Function to log a warning from CS_ApplAdminBase feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_CS_ApplAdminBase_warning(in @lazy charstring pl_message) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| f_EPTF_Logging_warningV2(pl_message, v_CS_ApplAdminBase_loggingMaskId, {c_EPTF_CS_loggingClassIdx_Warning}); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_CS_ApplAdminBase_debug |
| // |
| // Purpose: |
| // Function to log a debug message from ApplAdminBase feature. |
| // |
| // Parameters: |
| // - pl_message - *in* *charstring* - the message to log |
| // |
| // Return Value: |
| // - |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_CS_ApplAdminBase_debug(in @lazy charstring pl_message) |
| runs on EPTF_CS_ApplAdminBase_CT |
| { |
| f_EPTF_Logging_debugV2(pl_message, v_CS_ApplAdminBase_loggingMaskId, {c_EPTF_CS_loggingClassIdx_Debug}); |
| } |
| |
| /////////////////////////////////////////////////////////// |
| // Function: f_EPTF_CS_ApplAdminBase_debugEnabled |
| // |
| // Purpose: |
| // Function to check if debug is enabled for CS_ApplAdminBase |
| // |
| // Parameters: |
| // - |
| // |
| // Return Value: |
| // *boolean* - true if debug enalbed |
| // |
| // Errors & assertions: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| // |
| /////////////////////////////////////////////////////////// |
| private function f_EPTF_CS_ApplAdminBase_debugEnabled() |
| runs on EPTF_CS_ApplAdminBase_CT |
| return boolean |
| { |
| return f_EPTF_Logging_isEnabled(v_CS_ApplAdminBase_loggingMaskId, c_EPTF_CS_loggingClassIdx_Debug); |
| } |
| } // group Logging |
| |
| } // end of module |