blob: 5c72ab123d2fd65ec2907ca86608f803914a43dd [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_HostAdmin_Test_Functions
//
// Purpose:
// This module contains function definitions for testing EPTF Base.
//
// Module Parameters:
// tsp_demoHost - *charstring* - remote-measurement hostname or IP address, default: 127.0.0.1
//
// Module depends on:
// <EPTF_HostAdmin_Test_Definitions>
// <EPTF_CLL_Variable_Functions>
// <EPTF_CLL_HostAdmin_BaseDefinitions>
// <EPTF_CLL_HostAdmin_Definitions>
// <EPTF_CLL_Common_Definitions>
//
// Current Owner:
// Balazs Barcsik (ebalbar)
//
// Last Review Date:
// -
//
// Detailed Comments:
// -
///////////////////////////////////////////////////////////
module EPTF_HostAdmin_Test_Functions {
//=========================================================================
// Import Part
//=========================================================================
import from EPTF_HostAdmin_Test_Definitions all;
import from EPTF_CLL_Variable_Functions all;
import from EPTF_CLL_HostAdmin_Definitions all;
import from EPTF_CLL_HostAdminServer_Definitions all;
import from EPTF_CLL_HostAdminServer_Functions all;
import from EPTF_CLL_Common_Definitions all;
import from EPTF_CLL_RBTScheduler_Definitions all;
import from EPTF_CLL_RBTScheduler_Functions all;
import from EPTF_CLL_Scheduler_Definitions all;
import from EPTF_CLL_DataSource_Definitions all;
import from EPTF_CLL_DataSourceClient_Functions all;
import from EPTF_CLL_DataSource_Functions all;
import from EPTF_CLL_Base_Functions all;
//=========================================================================
// Module Parameters
//=========================================================================
modulepar charstring tsp_demoHost := "127.0.0.1";
//=========================================================================
// Functions
//=========================================================================
function f_demo_subscribe() runs on EPTF_HostAdmin_Test_CT
{
// create subscriber variables
var charstring prefix := c_hostAdmin_name & ".";
f_EPTF_Var_subscribeRemote(hostAdm, prefix & c_EPTF_HostAdmin_testerHostLoad_name, realtime, v_testerHostLoad_k);
f_EPTF_Var_subscribeRemote(hostAdm, prefix & c_EPTF_HostAdmin_numCPUs_name, realtime, v_numCPUs_k);
for(var integer i:=0; i<f_EPTF_Var_getIntValue(v_numCPUs_k); i:=i+1) {
v_CPULoads_k[i] := -1;
f_EPTF_Var_subscribeRemote(hostAdm, prefix & c_EPTF_HostAdmin_CPULoads_name & "." & int2str(i),
realtime, v_CPULoads_k[i]);
f_EPTF_Var_addPostProcFn(v_CPULoads_k[i], {refers(f_postproc_CPULoads), {i}});
}
f_EPTF_Var_subscribeRemote(hostAdm, prefix & c_EPTF_HostAdmin_physicalMemory_name, realtime, v_physicalMemory_k);
f_EPTF_Var_subscribeRemote(hostAdm, prefix & c_EPTF_HostAdmin_freeMemory_name, realtime, v_freeMemory_k);
f_EPTF_Var_addPostProcFn(v_testerHostLoad_k, {refers(f_postproc_testerHostLoad), {}});
f_EPTF_Var_addPostProcFn(v_freeMemory_k, {refers(f_postproc_freeMemory), {}});
log("***** Number of CPUs on host ", tsp_demoHost, ": ", f_EPTF_Var_getIntValue(v_numCPUs_k));
log("***** Physical memory: ", f_EPTF_Var_getIntValue(v_physicalMemory_k));
}
function f_postproc_testerHostLoad(in integer pl_idx, in EPTF_IntegerList pl_argList) runs on EPTF_HostAdmin_Test_CT
{
var float vl_value := f_EPTF_Var_getFloatValue(v_testerHostLoad_k);
if (vl_value >= 0.0) {
setverdict(pass);
} else {
log("Error: wrong host load value: ", vl_value, ", expected: >=0.0");
setverdict(fail);
}
v_hostLoadCalled := v_hostLoadCalled + 1;
}
function f_postproc_CPULoads(in integer pl_idx, in EPTF_IntegerList pl_argList) runs on EPTF_HostAdmin_Test_CT
{
var float vl_value := f_EPTF_Var_getFloatValue(v_CPULoads_k[pl_argList[0]]);
if (vl_value >= 0.0) {
setverdict(pass);
} else {
log("Error: wrong Load of CPU:", pl_argList[0], ": ", vl_value, ", expected: >=0.0");
setverdict(fail);
}
v_CPUloadCalled := v_CPUloadCalled + 1;
}
function f_postproc_freeMemory(in integer pl_idx, in EPTF_IntegerList pl_argList) runs on EPTF_HostAdmin_Test_CT
{
var integer vl_value := f_EPTF_Var_getIntValue(v_freeMemory_k);
if (vl_value >= 0) {
setverdict(pass);
} else {
log("Error: wrong free memory value: ", vl_value, ", expected: >=0");
setverdict(fail);
}
v_freeMemoryCalled := v_freeMemoryCalled + 1;
}
group OverloadDetection {
type component BurnCPU_CT {
private timer t_clock;
private timer t_cpu;
private var float lastEventTime := 0.0;
private var float deltaT := 0.02;
private var integer loadCyclesFor10Percent := 40000;
private var integer loadCycles := 0;
private var float targetLoad := 0.5;
private var default v_default := null
}
type component EPTF_Scheduler_OverloadTest_CT extends EPTF_DataSourceClient_CT, EPTF_Scheduler_CT, BurnCPU_CT {
var float v_readLoadPeriod := 10.0;
var float v_overloadThreshold := 0.99;
}
function f_EPTF_HostAdmin_overloadDetection_test_dataSourceHandlerLGen(
out charstring pl_dataVarName,
in charstring pl_source,
in charstring pl_ptcName,
in charstring pl_element,
in EPTF_DataSource_Params pl_params
) runs on EPTF_Scheduler_OverloadTest_CT return integer {
pl_dataVarName := pl_element;
return 0;
}
function f_EPTF_HostAdmin_overloadDetection_test_setTargetLoadPostProc(in integer pl_idx, in EPTF_IntegerList pl_argList) runs on EPTF_Scheduler_OverloadTest_CT {
f_BurnCPU_setTargetLoad(f_EPTF_Var_getFloatValue(pl_idx));
};
function f_EPTF_HostAdmin_overloadDetection_test_setOverLoadThresholdPostProc(in integer pl_idx, in EPTF_IntegerList pl_argList) runs on EPTF_Scheduler_OverloadTest_CT {
v_overloadThreshold := f_EPTF_Var_getFloatValue(pl_idx)/100.0;
f_EPTF_Scheduler_setMaxLoadThreshold(v_overloadThreshold);
};
public function f_EPTF_Scheduler_OverloadTest_init(in charstring pl_selfname, in integer pl_loadCyclesFor10Percent := 40000) runs on EPTF_Scheduler_OverloadTest_CT {
f_EPTF_Scheduler_init_CT(pl_selfname);
//f_EPTF_Scheduler_enableLoadMeasurement(true);
f_BurnCPU_init_CT(pl_loadCyclesFor10Percent := pl_loadCyclesFor10Percent);
var integer vl_eventId;
f_EPTF_SchedulerComp_scheduleAction(
pl_when := f_EPTF_SchedulerComp_snapshotTime() + 1.0,
pl_actionHandler := refers(f_EPTF_Scheduler_generateOverloadHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
f_EPTF_SchedulerComp_scheduleAction(
pl_when := f_EPTF_SchedulerComp_snapshotTime() + 1.0,
pl_actionHandler := refers(f_EPTF_Scheduler_generateBackgroundEventsHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
f_EPTF_SchedulerComp_scheduleAction(
pl_when := f_EPTF_SchedulerComp_snapshotTime() + 1.0,
pl_actionHandler := refers(f_EPTF_Scheduler_readLoadHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
f_EPTF_DataSourceClient_init_CT(f_EPTF_Base_selfName(),mtc);
var integer vl_idx;
f_EPTF_Var_newFloat("LoadInScheduler",0.0,vl_idx);
f_EPTF_Var_setSubsCanAdjust(vl_idx,false);
f_EPTF_DataSourceClient_registerData("LoadGen",f_EPTF_Base_selfName(),refers(f_EPTF_HostAdmin_overloadDetection_test_dataSourceHandlerLGen),mtc);
f_EPTF_Var_newFloat("targetLoad",0.0,vl_idx);
f_EPTF_Var_addPostProcFn(
vl_idx,
{
funcRef := refers(f_EPTF_HostAdmin_overloadDetection_test_setTargetLoadPostProc),
argList := {}
}
);
f_EPTF_Var_newFloat("overloadThreshold",v_overloadThreshold*100.0,vl_idx);
f_EPTF_Var_addPostProcFn(
vl_idx,
{
funcRef := refers(f_EPTF_HostAdmin_overloadDetection_test_setOverLoadThresholdPostProc),
argList := {}
}
);
f_EPTF_Var_newStatusLED("overloadLED",{led_green, "ok"},vl_idx);
}
private altstep as_BurnCPU_generateLoad() runs on BurnCPU_CT {
var float currentTime;
var float nextTime;
[] t_cpu.timeout {
// calculate next event time:
currentTime := t_clock.read;
nextTime := lastEventTime+deltaT;
lastEventTime := nextTime;
var float vl_interval := nextTime-currentTime;
if (vl_interval<0.0) {
vl_interval := 0.0;
}
t_cpu.start(vl_interval);
// generate load:
f_BurnCPU_generateLoad();
repeat;
}
}
private function f_BurnCPU_generateLoad() runs on BurnCPU_CT {
// generate load:
var float vl_var;
for(var integer i:=0; i<loadCycles; i:=i+1) {
vl_var := 12.34;
vl_var := vl_var*vl_var; // just do something to generate CPU load
}
}
private function f_BurnCPU_getDeltaT() runs on BurnCPU_CT return float {
return deltaT;
}
private function f_EPTF_Scheduler_generateOverloadHandler(
in EPTF_ScheduledAction pl_action,
in integer pl_eventIndex
) runs on EPTF_Scheduler_OverloadTest_CT return boolean {
f_BurnCPU_generateLoad();
var integer vl_eventId;
f_EPTF_SchedulerComp_scheduleAction(
pl_when := pl_action.when + f_BurnCPU_getDeltaT(),
pl_actionHandler := refers(f_EPTF_Scheduler_generateOverloadHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
return true;
}
private function f_EPTF_Scheduler_generateBackgroundEventsHandler(
in EPTF_ScheduledAction pl_action,
in integer pl_eventIndex
) runs on EPTF_Scheduler_OverloadTest_CT return boolean {
var integer vl_eventId;
f_EPTF_SchedulerComp_scheduleAction(
pl_when := pl_action.when + 0.01,
pl_actionHandler := refers(f_EPTF_Scheduler_generateBackgroundEventsHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
return true;
}
private function f_EPTF_Scheduler_readLoadHandler(
in EPTF_ScheduledAction pl_action,
in integer pl_eventIndex
) runs on EPTF_Scheduler_OverloadTest_CT return boolean {
f_EPTF_Var_adjustContent(f_EPTF_Var_getId("LoadInScheduler"),{floatVal := 100.0*f_EPTF_Scheduler_getLoad()});
var EPTF_StatusLED vl_led := {led_green, "ok"};
if (f_EPTF_Scheduler_getLoad()>v_overloadThreshold) {
//overload:
vl_led := {led_red, "OVERLOAD!"};
}
f_EPTF_Var_adjustContent(f_EPTF_Var_getId("overloadLED"),{statusLEDVal := vl_led});
//action("load: ", f_EPTF_Scheduler_getLoad(), " period: ", f_EPTF_Scheduler_getLoadMeasurementInterval());
var integer vl_eventId;
f_EPTF_SchedulerComp_scheduleAction(
pl_when := pl_action.when + v_readLoadPeriod,
pl_actionHandler := refers(f_EPTF_Scheduler_readLoadHandler),
pl_action := {},
pl_eventIndex := vl_eventId
);
return true;
}
public function f_BurnCPU_init_CT(
in float pl_deltaT := 0.02,
in integer pl_loadCyclesFor10Percent := 40000,
in float pl_targetLoad := 0.5,
in float pl_startDelay := 1.0
) runs on BurnCPU_CT {
deltaT := pl_deltaT;
loadCyclesFor10Percent := pl_loadCyclesFor10Percent;
targetLoad := pl_targetLoad;
loadCycles := float2int(int2float(loadCyclesFor10Percent)*targetLoad*10.0);
lastEventTime := pl_startDelay;
t_clock.start(1000.0);
t_cpu.start(lastEventTime);
// v_default := activate(as_BurnCPU_generateLoad());
}
// changes deltaT so that load remains the same
public function f_BurnCPU_setDeltaT(
in float pl_deltaT := 0.1
) runs on BurnCPU_CT {
loadCyclesFor10Percent := float2int(int2float(loadCyclesFor10Percent)*pl_deltaT/deltaT);
deltaT := pl_deltaT;
f_BurnCPU_setTargetLoad(targetLoad);
}
// changes load so that deltaT remains the same
public function f_BurnCPU_setTargetLoad(
in float pl_targetLoad
) runs on BurnCPU_CT {
targetLoad := pl_targetLoad;
loadCycles := float2int(int2float(loadCyclesFor10Percent)*targetLoad*10.0);
}
public function f_EPTF_Scheduler_Test_overloadDetection_behaviour(in charstring pl_selfName, in float pl_desiredLoad, in integer pl_loadCyclesFor10Percent := 40000) runs on EPTF_Scheduler_OverloadTest_CT {
f_EPTF_Scheduler_OverloadTest_init(pl_selfName, pl_loadCyclesFor10Percent);
f_BurnCPU_setTargetLoad(pl_desiredLoad);
f_BurnCPU_setDeltaT(0.05);
v_overloadThreshold := 0.95;
f_EPTF_Scheduler_setMaxLoadThreshold(v_overloadThreshold);
f_EPTF_Scheduler_setLoadMeasurementPeriod(1.0);
v_readLoadPeriod := f_EPTF_Scheduler_getLoadMeasurementInterval();
if (v_readLoadPeriod<0.0) {
v_readLoadPeriod := 1.0;
}
f_EPTF_Var_adjustContent(f_EPTF_Var_getId("targetLoad"), {floatVal := pl_desiredLoad});
f_EPTF_Base_wait4Shutdown();
// activate the overload generator altstep
}
} // group OverloadDetection
type component EPTF_HostAdmin_Test_Process_CPULoad_CT extends EPTF_Scheduler_OverloadTest_CT
{
}
type component EPTF_HostAdmin_Test_Process_CPULoad_Server_CT extends EPTF_HostAdminServer_CT, EPTF_DataSource_CT{
var boolean v_dsHostAdminReady := false;
}
function f_EPTF_HostAdmin_Test_Process_CPULoad_Server_init_CT(
in charstring pl_selfName
) runs on EPTF_HostAdmin_Test_Process_CPULoad_Server_CT {
f_EPTF_DataSource_init_CT(pl_selfName);
f_EPTF_DataSource_registerReadyCallback(refers(f_EPTF_HostAdmin_Test_Process_CPULoad_dataSourceReadyCallback));
v_dsHostAdminReady := false;
f_EPTF_HostAdminServer_init_CT(pl_selfName, self);
}
external function f_EPTF_HostAdmin_Test_Process_CPULoad_startThreads(
in integer pl_nofThread,
in float pl_desiredLoad
);
function f_EPTF_HostAdmin_Test_Process_CPULoad_proc_behavior(
in charstring pl_selfName,
in float pl_desiredLoad,
in integer pl_loadCyclesFor10Percent := 40000
) runs on EPTF_HostAdmin_Test_Process_CPULoad_CT {
action("*** PROC NAME *** ", pl_selfName&int2str(float2int(pl_desiredLoad)));
var float vl_singleThreadLoad := pl_desiredLoad;
var integer vl_nofThread := (float2int(pl_desiredLoad) / 100);
if (pl_desiredLoad > 100.0) {
vl_singleThreadLoad := vl_singleThreadLoad / int2float(vl_nofThread);
}
action("*** NOF THREAD *** ", vl_nofThread);
if (vl_nofThread > 1) {
f_EPTF_HostAdmin_Test_Process_CPULoad_startThreads(vl_nofThread-1, vl_singleThreadLoad);
}
f_EPTF_Scheduler_Test_overloadDetection_behaviour(pl_selfName&int2str(float2int(pl_desiredLoad)), vl_singleThreadLoad/100.0, pl_loadCyclesFor10Percent);
}
function f_EPTF_HostAdmin_Test_Process_CPULoad_dataSourceReadyCallback(
in charstring pl_source,
in charstring pl_ptcName
) runs on EPTF_HostAdmin_Test_Process_CPULoad_Server_CT {
action("*** READY RECV FOR *** ", pl_source);
if (pl_source == c_HostAdminServer_DataSource_sourceId) {
action("*** true *** ", pl_source);
v_dsHostAdminReady := true;
}
}
}