blob: cb2097af7471e827cb017b6c41ea063209521b50 [file] [log] [blame]
RoomModel room.basic.etunit {
import room.basic.service.timing.* from "TimingService.room"
import room.basic.types.* from "Types.room"
/**
* A SubSystemClass or ActorClass having this annotation is construed as an instance.<br>
* During generation the necessary instantiation (LogicalSystem, SubSystemRef etc.) and mapping will be created.
* <p>
* Must not have LogicalThreads. Globally only once allowed. Runtime execution on DefaultThread of given PhysicalSystem.
* </p>
*/
AnnotationType TestInstance {
target = { SubSystemClass, ActorClass }
}
/**
* Creates an etUnit test suite. Test cases can be added by creating instances of ActorClass <i>TestSuiteActor</i>.
*/
abstract ActorClass TestSuiteActor {
Interface {
SPP timer : PTimer
SPP tcLifecycle : PTestLifecycle
}
Structure {
LayerConnection relay_sap timer satisfied_by timingService.timer
LayerConnection relay_sap tcLifecycle satisfied_by lifecycleActor.fct
ActorRef timingService: ATimingService
ActorRef lifecycleActor : TestLifecycleActor
}
Behavior {
Operation getTestSuiteName() : string {
"return getName();"
}
ctor {
"etUnit_open(\"log/testlog\", getTestSuiteName());"
"etUnit_openTestSuite(getTestSuiteName());"
}
dtor {
"etUnit_closeTestSuite();"
"etUnit_close();"
}
}
}
abstract async ActorClass TestCaseActor {
Structure {
Attribute tcTimeoutIgnore : boolean
Attribute tcCaseId : int32
SAP tcLifecycle : PTestLifecycle
SAP tcTimer : PTimer
}
Behavior {
Operation getTestCaseName() : string {
"return getName();"
}
Operation startTimeout(timeMs: int32){
"tcTimeoutIgnore = false;"
"tcTimer.startTimeout(timeMs);"
}
Operation invalidateTimeout(){
"tcTimeoutIgnore = true;"
}
StateMachine {
Transition init: initial -> wait4Start {
action {
"invalidateTimeout();"
}
}
Transition trFinish: tpFinish of testing -> finish
Transition trTimeout: testing -> timeout {
triggers {
<timeout: tcTimer guard {
"!tcTimeoutIgnore"
}>
}
action {
"invalidateTimeout();"
}
}
Transition tr0: wait4Start -> testing {
triggers {
<startTestCase: tcLifecycle>
}
}
State testing {
subgraph {
ExitPoint tpFinish
}
}
State timeout {
entry {
"EXPECT_FALSE(tcCaseId, \"timeout\", true);"
"etUnit_closeTestCase(tcCaseId);"
"tcLifecycle.finishedTestCase();"
}
}
State finish {
entry {
"etUnit_closeTestCase(tcCaseId);"
"tcLifecycle.finishedTestCase();"
}
}
State wait4Start {
exit {
"tcCaseId = etUnit_openTestCase(getTestCaseName());"
}
}
}
}
}
ActorClass TestLifecycleActor {
Interface {
SPP fct: PTestLifecycle
}
Structure {
ServiceImplementation of fct
Attribute entireTestTimeout : int32 = "5000"
Attribute sequentialExecution : boolean = "true"
Attribute tcCurrentIdx : int32 = "0"
SAP timer : PTimer
}
Behavior {
StateMachine {
Transition init: initial -> idle {
action {
"//printf(\"TestLifecycleActor (%s) starting with %d test cases\\n\", getName(), fct.getReplication());"
"if(fct.getReplication() == 0)"
"\tetUnit_testFinished(-1);"
"else"
"\ttimer.startTimeout(entireTestTimeout);"
""
"if(!sequentialExecution)"
"\tfct.startTestCase();"
}
}
Transition tr1: idle -> cp cp0 {
triggers {
<finishedTestCase: fct>
}
action {
"tcCurrentIdx++;"
}
}
Transition tr2: idle -> terminate {
triggers {
<timeout: timer>
}
}
Transition tr3: cp cp0 -> idle
Transition tr4: cp cp0 -> terminate {
cond {
"tcCurrentIdx >= fct.getReplication()"
}
}
ChoicePoint cp0
State idle {
entry {
"if(sequentialExecution)"
"\tfct[tcCurrentIdx].startTestCase();"
}
}
State terminate {
entry {
"etUnit_testFinished(-1);"
}
}
}
}
}
ProtocolClass PTestLifecycle {
incoming {
Message finishedTestCase()
}
outgoing {
Message startTestCase()
}
}
}