| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // 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_LoadRegulator_demo |
| // |
| // Purpose: |
| // This module contains function definitions for testing EPTF Load Regulator |
| // |
| // Module Parameters: |
| // tsp_demoInterval - *float* - interval of testing, default: 30.0 |
| // tsp_demoLoadGenerationPeriod - *float* - load generation period, default: 0.1 |
| // tsp_demoSutLoadUpdatePeriod - *float* - update period for load measurement, default: 2.0 |
| // tsp_demoLoadToReach - *float* |
| // tsp_demoCpsToReach - *float* |
| // tsp_NetInterfaceName - *charstring* |
| // tsp_bandwidthToReach - *float* |
| // Module depends on: |
| // <EPTF_CLL_Base_Definitions> |
| // <EPTF_CLL_Base_Functions> |
| // <EPTF_CLL_LoadRegulator_Definitions> |
| // <EPTF_CLL_LoadRegulator_Functions> |
| // <EPTF_CLL_HostAdmin_BaseDefinitions> |
| // <EPTF_CLL_HostAdmin_BaseFunctions> |
| // <EPTF_CLL_Scheduler_Definitions> |
| // <EPTF_CLL_RBTScheduler_Definitions> |
| // <EPTF_CLL_RBTScheduler_Functions> |
| // <LOADMEASasp_Types> |
| // <LOADMEASasp_PortType> |
| // |
| // Current Owner: |
| // Gabor Tatarka (egbotat) |
| // |
| // Last Review Date: |
| // - |
| // |
| // Detailed Comments: |
| // - |
| /////////////////////////////////////////////////////////// |
| |
| module EPTF_LoadRegulator_demo |
| { |
| |
| import from EPTF_CLL_Base_Functions all; |
| |
| import from EPTF_CLL_LoadRegulator_Definitions all; |
| import from EPTF_CLL_LoadRegulator_Functions all; |
| |
| import from EPTF_CLL_HostAdmin_BaseDefinitions all; |
| import from EPTF_CLL_HostAdmin_BaseFunctions all; |
| |
| import from EPTF_CLL_Scheduler_Definitions all; |
| import from EPTF_CLL_RBTScheduler_Definitions all; |
| import from EPTF_CLL_RBTScheduler_Functions all; |
| |
| |
| import from LOADMEASasp_Types all; |
| import from LOADMEASasp_PortType all; |
| |
| |
| modulepar float tsp_demoInterval := 300.0; |
| modulepar float tsp_demoLoadGenerationPeriod := 0.1; |
| modulepar float tsp_demoSutLoadUpdatePeriod := 2.0; |
| modulepar float tsp_demoLoadToReach := 25.0; |
| modulepar float tsp_demoCpsToReach := 10.0; |
| modulepar charstring tsp_NetInterfaceName := "eth0"; |
| modulepar float tsp_bandwidthToReach := 150.0; // kB/s |
| |
| |
| type record WeightedCpsElem { |
| float cps, |
| float weight, |
| boolean lockCps |
| } |
| |
| type record of WeightedCpsElem WeightedCpsList; |
| |
| type port Demo_PT message |
| { |
| inout charstring; |
| } with { extension "internal" } |
| |
| type component LoadRegulatorDemo_CT |
| extends EPTF_HostAdmin_Base_CT, EPTF_Scheduler_CT, EPTF_LoadRegulator_CT |
| { |
| var EPTF_Scheduler_ActionHandler v_myEventHandler; |
| port Demo_PT demo_PCO; |
| |
| // for weighted CPS: |
| var WeightedCpsList v_weightedCpsList := {} |
| |
| // for bandwidth limited traffic control: |
| port LOADMEASasp_PT loadMeas_PCO; |
| } |
| |
| type component Repeater_CT |
| { |
| port Demo_PT demo_PCO; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////// |
| // scheduling and event handling |
| |
| const integer c_actionId_generateLoad := 0; |
| const integer c_actionId_updateSutLoad := 1; |
| |
| function f_myEventHandler(in EPTF_ScheduledAction pl_action, in integer pl_eventIndex) |
| runs on LoadRegulatorDemo_CT return boolean |
| { |
| if (pl_action.actionId[0] == c_actionId_generateLoad) { |
| f_handleEvent_generateLoad(pl_action.when); |
| return true; |
| } |
| if (pl_action.actionId[0] == c_actionId_updateSutLoad) { |
| f_handleEvent_updateSutLoad(pl_action.when); |
| return true; |
| } |
| return false; |
| } |
| |
| function f_scheduleEvent_generateLoad(in float pl_when) |
| runs on LoadRegulatorDemo_CT |
| { |
| var integer eventIdx := 0; |
| if(not f_EPTF_SchedulerComp_scheduleAction( |
| pl_when + tsp_demoLoadGenerationPeriod,v_myEventHandler,{c_actionId_generateLoad}, |
| eventIdx |
| )) { |
| setverdict(fail, "f_EPTF_SchedulerComp_scheduleAction failed."); |
| stop; |
| } |
| } |
| |
| function f_scheduleEvent_updateSutLoad(in float pl_when) |
| runs on LoadRegulatorDemo_CT |
| { |
| var integer eventIdx := 0; |
| if(not f_EPTF_SchedulerComp_scheduleAction( |
| pl_when + tsp_demoSutLoadUpdatePeriod,v_myEventHandler,{c_actionId_updateSutLoad}, |
| eventIdx |
| )) { |
| setverdict(fail, "f_EPTF_SchedulerComp_scheduleAction failed."); |
| stop; |
| } |
| } |
| |
| type octetstring SDP_Message; |
| |
| function f_SDP_enc_Message(in SDP_Message pl_msg) return charstring { |
| return oct2char(pl_msg); |
| } |
| |
| function f_SDP_dec_Message(in charstring pl_msg) return SDP_Message { |
| return char2oct(pl_msg); |
| } |
| |
| function f_handleEvent_generateLoad(in float pl_when) |
| runs on LoadRegulatorDemo_CT |
| { |
| var SDP_Message vl_SDP_Message := '000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F'O; |
| |
| // Note: this is not an accurate way of generating load. |
| var integer calls := float2int(f_EPTF_LoadRegulator_getCpsToReach() * tsp_demoLoadGenerationPeriod); |
| for(var integer i := 0; i < calls; i := i + 1) { |
| var charstring msg := f_SDP_enc_Message(vl_SDP_Message); |
| demo_PCO.send(msg); |
| } |
| |
| f_scheduleEvent_generateLoad(pl_when); |
| } |
| |
| function f_handleEvent_updateSutLoad(in float pl_when) |
| runs on LoadRegulatorDemo_CT |
| { |
| // log("f_handleEvent_updateSutLoad() called"); |
| f_EPTF_HostAdmin_Base_update(); |
| log("Tester host load: ", v_EPTF_HostAdmin_testerHostLoad); |
| |
| f_scheduleEvent_updateSutLoad(pl_when); |
| } |
| |
| // end of scheduling and event handling |
| //////////////////////////////////////////////////////////////////////////////////// |
| |
| function f_getSUTLoad() runs on LoadRegulatorDemo_CT return float |
| { |
| return v_EPTF_HostAdmin_testerHostLoad; |
| } |
| |
| function f_repeater() runs on Repeater_CT |
| { |
| var charstring msg; |
| var SDP_Message SDP_msg; |
| |
| alt { |
| [] demo_PCO.receive(charstring:?) -> value msg { |
| SDP_msg := f_SDP_dec_Message(msg); |
| msg := f_SDP_enc_Message(SDP_msg); |
| demo_PCO.send(msg); |
| repeat; |
| } |
| } |
| } |
| |
| |
| |
| testcase tc_LoadRegulator_demo() runs on LoadRegulatorDemo_CT |
| { |
| timer T_interval := tsp_demoInterval; |
| |
| log("**** creating repeater component"); |
| |
| var Repeater_CT rep := Repeater_CT.create; |
| connect(self:demo_PCO, rep:demo_PCO); |
| rep.start(f_repeater()); |
| |
| log("**** initializing HostAdmin_Base"); |
| |
| f_EPTF_HostAdmin_Base_init_CT("LoadRegulator"); |
| |
| log("**** initializing LoadRegulator"); |
| |
| f_EPTF_LoadRegulator_setLoadToReach(tsp_demoLoadToReach); |
| //v_EPTF_LoadRegulator_cpsToReach := tsp_demoCpsToReach; |
| f_EPTF_LoadRegulator_init_CT("LoadRegulator", refers(f_getSUTLoad)); |
| |
| log("**** initializing Scheduler"); |
| |
| f_EPTF_Scheduler_init_CT(f_EPTF_Base_selfName()); |
| v_myEventHandler := refers(f_myEventHandler); |
| f_EPTF_SchedulerComp_refreshSnapshotTime(); |
| f_scheduleEvent_generateLoad(f_EPTF_SchedulerComp_snapshotTime()); |
| f_scheduleEvent_updateSutLoad(f_EPTF_SchedulerComp_snapshotTime()); |
| |
| log("**** entering main loop"); |
| |
| T_interval.start; |
| var charstring msg; |
| alt { |
| [] T_interval.timeout |
| { |
| setverdict(pass); |
| } |
| []demo_PCO.receive(charstring:?) -> value msg |
| { |
| var SDP_Message SDP_msg := f_SDP_dec_Message(msg); |
| repeat; |
| } |
| } |
| |
| log("**** performing cleanup"); |
| |
| rep.stop; |
| disconnect(self:demo_PCO, rep:demo_PCO); |
| |
| f_EPTF_Base_cleanup_CT(); |
| } |
| |
| // Post-calculate function for weighted CPS calculation. |
| function f_calcWeightedCpsList() |
| runs on LoadRegulatorDemo_CT |
| { |
| log(%definitionId&" called"); |
| |
| if(sizeof(v_weightedCpsList) == 0) { return; } |
| var float weightSum := 0.0; |
| var float cpsSum := f_EPTF_LoadRegulator_getCpsToReach(); |
| for(var integer i := 0; i < sizeof(v_weightedCpsList); i := i + 1) { |
| if(not v_weightedCpsList[i].lockCps) { |
| weightSum := weightSum + v_weightedCpsList[i].weight; |
| } else { |
| cpsSum := cpsSum - v_weightedCpsList[i].cps; |
| } |
| } |
| if(weightSum == 0.0) { |
| log("WARNING " & %definitionId & ": all CPS values are locked or the "& |
| "unlocked CPS values have a weight of 0.0."); |
| return; |
| } |
| if(cpsSum < 0.0) { |
| log("WARNING " & %definitionId & ": sum of locked CPS values already "& |
| "greater than CPS-to-reach."); |
| for(var integer i := 0; i < sizeof(v_weightedCpsList); i := i + 1) { |
| if(not v_weightedCpsList[i].lockCps) { |
| v_weightedCpsList[i].cps := 0.0; |
| } |
| } |
| return; |
| } |
| for(var integer i := 0; i < sizeof(v_weightedCpsList); i := i + 1) { |
| if(not v_weightedCpsList[i].lockCps) { |
| v_weightedCpsList[i].cps := |
| (v_weightedCpsList[i].weight * cpsSum) / weightSum; |
| } |
| } |
| |
| log(%definitionId&" finished. Weighted CPS list: ", v_weightedCpsList); |
| } |
| |
| testcase tc_LoadRegulator_weightedCPS_demo() runs on LoadRegulatorDemo_CT |
| { |
| timer T_interval := tsp_demoInterval; |
| |
| log("**** creating repeater component"); |
| |
| var Repeater_CT rep := Repeater_CT.create; |
| connect(self:demo_PCO, rep:demo_PCO); |
| rep.start(f_repeater()); |
| |
| log("**** initializing HostAdmin_Base"); |
| |
| f_EPTF_HostAdmin_Base_init_CT("LoadRegulator"); |
| |
| log("**** initializing LoadRegulator"); |
| |
| f_EPTF_LoadRegulator_setLoadToReach(tsp_demoLoadToReach); |
| //v_EPTF_LoadRegulator_cpsToReach := tsp_demoCpsToReach; |
| v_weightedCpsList := { |
| { |
| cps := 10.0, |
| weight := 19.0, |
| lockCps := true |
| }, |
| { |
| cps := 10.0, |
| weight := 1.0, |
| lockCps := false |
| }, |
| { |
| cps := 10.0, |
| weight := 2.0, |
| lockCps := false |
| }, |
| { |
| cps := 10.0, |
| weight := 3.0, |
| lockCps := false |
| } |
| } |
| f_EPTF_LoadRegulator_init_CT("LoadRegulator",refers(f_getSUTLoad), null, refers(f_calcWeightedCpsList)); |
| |
| log("**** initializing Scheduler"); |
| |
| f_EPTF_Scheduler_init_CT(f_EPTF_Base_selfName()); |
| v_myEventHandler := refers(f_myEventHandler); |
| f_EPTF_SchedulerComp_refreshSnapshotTime(); |
| f_scheduleEvent_generateLoad(f_EPTF_SchedulerComp_snapshotTime()); |
| f_scheduleEvent_updateSutLoad(f_EPTF_SchedulerComp_snapshotTime()); |
| |
| log("**** entering main loop"); |
| |
| T_interval.start; |
| var charstring msg; |
| alt { |
| [] T_interval.timeout |
| { |
| setverdict(pass); |
| } |
| []demo_PCO.receive(charstring:?) -> value msg |
| { |
| var SDP_Message SDP_msg := f_SDP_dec_Message(msg); |
| repeat; |
| } |
| } |
| |
| log("**** performing cleanup"); |
| |
| rep.stop; |
| disconnect(self:demo_PCO, rep:demo_PCO); |
| |
| f_EPTF_Base_cleanup_CT(); |
| } |
| |
| function f_initNetMeas() runs on LoadRegulatorDemo_CT |
| { |
| map(self:loadMeas_PCO, system:loadMeas_PCO); |
| |
| var ASP_LOADMEAS vl_ASP_LOADMEAS; |
| |
| vl_ASP_LOADMEAS.loadType := NETWORK; |
| vl_ASP_LOADMEAS.msg := { setPeriod := { periodTime := tsp_EPTF_loadRegulator_updateTimeout/2.0 } }; |
| loadMeas_PCO.send(vl_ASP_LOADMEAS); |
| |
| vl_ASP_LOADMEAS := { loadType := NETWORK, msg := { setInterface:= { interface := tsp_NetInterfaceName } } }; |
| loadMeas_PCO.send(vl_ASP_LOADMEAS); |
| |
| vl_ASP_LOADMEAS.msg := { startMeas := {} }; |
| loadMeas_PCO.send(vl_ASP_LOADMEAS); |
| } |
| |
| function f_getBandwidthUsage() runs on LoadRegulatorDemo_CT return float |
| { |
| // var float upRate := getNetworkUploadSpeed(loadMeas_PCO); |
| var float downRate := getNetworkDownloadSpeed(loadMeas_PCO); |
| // return downRate + upRate; |
| return downRate; |
| } |
| |
| function f_cleanupNetMeas() runs on LoadRegulatorDemo_CT |
| { |
| unmap(self:loadMeas_PCO, system:loadMeas_PCO); |
| } |
| |
| /*function f_calcNextCps_BW( |
| in float loadToReach, |
| in float oldCps) |
| runs on LoadRegulatorDemo_CT |
| return float |
| { |
| if (loadToReach == 0.0) { return 0.0 } |
| |
| var integer measWindowSize := sizeof(vc_loadRegMeasWindow); |
| var float loadNew := 0.0; |
| var float loadOld := 0.0; |
| |
| //calculate last two load values |
| if(vc_measWinIdx == 0) { |
| loadNew := vc_loadRegMeasWindow[measWindowSize-1]; |
| loadOld := vc_loadRegMeasWindow[measWindowSize-2]; |
| } |
| else if(vc_measWinIdx == 1) { |
| loadNew := vc_loadRegMeasWindow[0]; |
| loadOld := vc_loadRegMeasWindow[measWindowSize-1]; |
| } |
| else { |
| loadNew := vc_loadRegMeasWindow[vc_measWinIdx-1]; |
| loadOld := vc_loadRegMeasWindow[vc_measWinIdx-2]; |
| } |
| |
| var float cpsDelta := (1.0 - ((2.0*loadNew+loadOld)/(loadToReach*3.0))) * tsp_EPTF_loadregulator_cpsDelta; |
| |
| if(cpsDelta > tsp_EPTF_loadregulator_cpsDelta) { |
| cpsDelta := tsp_EPTF_loadregulator_cpsDelta; |
| } else if(cpsDelta < -tsp_EPTF_loadregulator_cpsDelta) { |
| cpsDelta := -tsp_EPTF_loadregulator_cpsDelta; |
| } |
| |
| var float newCps := oldCps + cpsDelta |
| if(newCps < 0.0) { newCps := 0.0; } |
| |
| log(%definitionId&": Old cps: ", oldCps); |
| log(%definitionId&": LoadToReach: ", loadToReach); |
| log(%definitionId&": Load: ", loadNew); |
| log(%definitionId&": Cps delta: ", cpsDelta); |
| log(%definitionId&": New cps: ", newCps); |
| |
| return newCps; |
| }*/ |
| |
| // note: this demo needs that the repeater and the demo component are running on different hosts! |
| // For this, start two host controllers on two hosts connecting to the same main controller. |
| // The first HC started will run the demo component and will regulate the load. |
| testcase tc_BandwidthLimitedTrafficControl_demo() runs on LoadRegulatorDemo_CT |
| { |
| timer T_interval := tsp_demoInterval; |
| |
| timer T_startup := 2.0; |
| T_startup.start; |
| T_startup.timeout; |
| |
| log("**** creating repeater component"); |
| |
| var Repeater_CT rep := Repeater_CT.create; |
| connect(self:demo_PCO, rep:demo_PCO); |
| rep.start(f_repeater()); |
| |
| log("**** initializing NET measure interface"); |
| |
| f_initNetMeas(); |
| f_EPTF_Base_registerCleanup(refers(f_cleanupNetMeas)); |
| |
| log("**** initializing LoadRegulator"); |
| |
| f_EPTF_LoadRegulator_setLoadToReach(tsp_bandwidthToReach); |
| //v_EPTF_LoadRegulator_cpsToReach := tsp_demoCpsToReach; |
| // f_EPTF_LoadRegulator_init_CT(refers(f_getBandwidthUsage), refers(f_calcNextCps_BW)); |
| f_EPTF_LoadRegulator_init_CT("LoadRegulator",refers(f_getBandwidthUsage)); |
| |
| log("**** initializing Scheduler"); |
| |
| f_EPTF_Scheduler_init_CT(f_EPTF_Base_selfName()); |
| v_myEventHandler := refers(f_myEventHandler); |
| f_EPTF_SchedulerComp_refreshSnapshotTime(); |
| f_scheduleEvent_generateLoad(f_EPTF_SchedulerComp_snapshotTime()); |
| // f_scheduleEvent_updateSutLoad(f_EPTF_SchedulerComp_snapshotTime()); |
| |
| log("**** entering main loop"); |
| |
| T_interval.start; |
| var charstring msg; |
| alt { |
| [] T_interval.timeout |
| { |
| setverdict(pass); |
| } |
| []demo_PCO.receive(charstring:?) -> value msg |
| { |
| var SDP_Message SDP_msg := f_SDP_dec_Message(msg); |
| repeat; |
| } |
| } |
| |
| log("**** performing cleanup"); |
| |
| rep.stop; |
| disconnect(self:demo_PCO, rep:demo_PCO); |
| |
| f_EPTF_Base_cleanup_CT(); |
| } |
| |
| } // module |
| |