From 0fe5268ec1a2d87441edcfee52e09d4f01f36edf Mon Sep 17 00:00:00 2001 From: Juergen Haug Date: Fri, 23 Jun 2017 15:32:12 +0200 Subject: modellib and runtime.c updates for testing Change-Id: Id4c29fa47b0f3c931f66e8521c1647ea9d113bbb --- .../org.eclipse.etrice.modellib.c/model/Tests.room | 182 +++++---------------- .../model/Tests.room | 9 +- .../model/Tests.room | 167 +------------------ .../src/common/etUnit/etUnit.c | 23 +++ .../src/common/etUnit/etUnit.h | 25 +++ 5 files changed, 93 insertions(+), 313 deletions(-) (limited to 'runtime') diff --git a/runtime/org.eclipse.etrice.modellib.c/model/Tests.room b/runtime/org.eclipse.etrice.modellib.c/model/Tests.room index 387b3b477..d39ab3f3f 100644 --- a/runtime/org.eclipse.etrice.modellib.c/model/Tests.room +++ b/runtime/org.eclipse.etrice.modellib.c/model/Tests.room @@ -1,4 +1,4 @@ -RoomModel room.basic.etunit { +RoomModel room.basic.test { import room.basic.service.timing.* from "TimingService.room" import room.basic.types.* from "Types.room" @@ -14,169 +14,65 @@ RoomModel room.basic.etunit { target = { SubSystemClass, ActorClass } } - /** - * Creates an etUnit test suite. Test cases can be added by creating added ActorRefs of type TestSuiteActor. - */ - abstract ActorClass TestSuiteActor { + ActorClass SequentialTestExecutor { Interface { - SPP timer : PTimer - SPP tcLifecycle : PTestLifecycle + conjugated Port control[*]: PTestControl + } Structure { - LayerConnection relay_sap timer satisfied_by timingService.timer - LayerConnection relay_sap tcLifecycle satisfied_by lifecycleActor.fct - ActorRef timingService: ATimingService - ActorRef lifecycleActor : TestLifecycleActor - } - Behavior { - ctor { - "etUnit_open(\"log/testlog\", getTestSuiteName());" - "etUnit_openTestSuite(getTestSuiteName());" - } - dtor { - "etUnit_closeTestSuite();" - "etUnit_close();" - } - Operation getTestSuiteName() : string { - "return \"unnamedTestSuite\";" + usercode3 { + "#include \"etUnit/etUnit.h\"" } - } - } - - abstract async ActorClass TestCaseActor { - Structure { - Attribute tcTimeoutIgnore : boolean - Attribute tcCaseId : int32 - SAP tcLifecycle : PTestLifecycle - SAP tcTimer : PTimer + external Port control + Attribute next : int16 } Behavior { - Operation getTestCaseName() : string { - "return \"unnamedTestCase\";" - } - Operation startTimeout(timeMs: uint32){ - "tcTimeoutIgnore = ET_FALSE;" - "tcTimer.startTimeout(timeMs);" - } - Operation invalidateTimeout(){ - "tcTimeoutIgnore = ET_TRUE;" - } StateMachine { - Transition init: initial -> wait4Start { - action { - "invalidateTimeout();" + State execute { + entry + + { + "if(next < self->constData->control.size){" + "\tcontrol[next++].start();" + "} else {" + "\tetUnit_testFinished(0);" + "}" } } - Transition trFinish: tpFinish of testing -> finish - Transition trTimeout: testing -> timeout { - triggers { - - } - action { - "invalidateTimeout();" + Transition init0: initial -> execute + { } - } - Transition tr0: wait4Start -> testing { + Transition tr0: execute -> execute { triggers { - - } - } - State testing { - subgraph { - ExitPoint tpFinish - } - } - State timeout { - entry { - "EXPECT_FALSE(tcCaseId, \"timeout\", ET_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\", self->constData->instName, self->constData->fct.size);" - "if(self->constData->fct.size == 0)" - "\tetUnit_testFinished(-1);" - "else" - "\ttimer.startTimeout(entireTestTimeout);" - "" - "if(!sequentialExecution)" - "\tfct.startTestCase();" - } - } - Transition tr1: idle -> cp cp0 { - triggers { - - } - action { - "tcCurrentIdx++;" - } - } - Transition tr2: idle -> terminate { - triggers { - - } - } - Transition tr3: cp cp0 -> idle - Transition tr4: cp cp0 -> terminate { - cond { - "tcCurrentIdx >= self->constData->fct.size" - } - } - ChoicePoint cp0 - State idle { - entry { - "if(sequentialExecution)" - "\tfct[tcCurrentIdx].startTestCase();" - } - } - State terminate { - entry { - "etUnit_testFinished(-1);" - } - } - } - } - } - - ProtocolClass PTestLifecycle { + ProtocolClass PTestControl { incoming { - Message finishedTestCase() + /** + * Start test execution. + */ + Message start() + + /** + * Abort test execution. + */ + Message abort() } outgoing { - Message startTestCase() + /** + * Test execution finished or aborted. + */ + Message done(success : boolean) } +// semantics { +// in:start -> out:done +// in:abort -> out:done +// } } } \ No newline at end of file diff --git a/runtime/org.eclipse.etrice.modellib.cpp/model/Tests.room b/runtime/org.eclipse.etrice.modellib.cpp/model/Tests.room index 48e49e03d..097b72e5e 100644 --- a/runtime/org.eclipse.etrice.modellib.cpp/model/Tests.room +++ b/runtime/org.eclipse.etrice.modellib.cpp/model/Tests.room @@ -1,10 +1,11 @@ -RoomModel room.basic.etunit { - - import room.basic.types.* from "Types.room" +RoomModel room.basic.test { + + 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.
- * During generation the necessary instantiation (LogicalSystem, SubSystemRef etc.) and mapping will be created. + * During generation the necessary instantiation (LogicalSystem, SubSystemRef etc.) and mapping will be created. *

* Must not have LogicalThreads. Globally only once allowed. Runtime execution on DefaultThread of given PhysicalSystem. *

diff --git a/runtime/org.eclipse.etrice.modellib.java/model/Tests.room b/runtime/org.eclipse.etrice.modellib.java/model/Tests.room index cb2097af7..097b72e5e 100644 --- a/runtime/org.eclipse.etrice.modellib.java/model/Tests.room +++ b/runtime/org.eclipse.etrice.modellib.java/model/Tests.room @@ -1,4 +1,4 @@ -RoomModel room.basic.etunit { +RoomModel room.basic.test { import room.basic.service.timing.* from "TimingService.room" import room.basic.types.* from "Types.room" @@ -14,169 +14,4 @@ RoomModel room.basic.etunit { target = { SubSystemClass, ActorClass } } - /** - * Creates an etUnit test suite. Test cases can be added by creating instances of ActorClass TestSuiteActor. - */ - 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 { - - } - action { - "invalidateTimeout();" - } - } - Transition tr0: wait4Start -> testing { - triggers { - - } - } - 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 { - - } - action { - "tcCurrentIdx++;" - } - } - Transition tr2: idle -> terminate { - triggers { - - } - } - 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() - } - } - } \ No newline at end of file diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/etUnit/etUnit.c b/runtime/org.eclipse.etrice.runtime.c/src/common/etUnit/etUnit.c index b90ac2af4..2dd752a55 100644 --- a/runtime/org.eclipse.etrice.runtime.c/src/common/etUnit/etUnit.c +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/etUnit/etUnit.c @@ -21,6 +21,8 @@ /*** member variables */ +static etInt16 etUnit_failedSuites = 0; + /* file handling */ static FILE* etUnit_reportfile = NULL; @@ -131,6 +133,8 @@ void etUnit_close(void) { else etLogger_logErrorF("Error Counter: %ld", etUnit_errorCounter); etLogger_logInfoF("************* TEST END **************"); + + etUnit_errorCounter = 0; } void etUnit_openTestSuite(const char* testSuiteName) { @@ -140,6 +144,7 @@ void etUnit_openTestSuite(const char* testSuiteName) { } void etUnit_closeTestSuite(void) { + etUnit_failedSuites += (etUnit_isSuccessSuite()) ? 0 : 1; } etInt16 etUnit_openTestCase(const char* testCaseName) { @@ -250,6 +255,16 @@ void expect_equal_void_ptr(etInt16 id, const char* message, const void* expected } } +void expectEqualStr(etInt16 id, const char* message, const char* expected, const char* actual, const char* file, int line) { + if (!(expected || actual || strcmp(expected, actual) == 0)) { + char testresult[ETUNIT_FAILURE_TEXT_LEN]; + sprintf(testresult, "%s: expected=%s, actual=%s", message, expected, actual); + etUnit_handleExpect(id, ET_FALSE, testresult, expected, actual, file, line); + } else { + etUnit_handleExpect(id, ET_TRUE, "", NULL, NULL, file, line); + } +} + #ifdef ET_FLOAT32 void expectEqualFloat32(etInt16 id, const char* message, etFloat32 expected, etFloat32 actual, etFloat32 precision, const char* file, int line) { expect_equal_float(id, message, expected, actual, precision, file, line); @@ -321,6 +336,14 @@ etBool etUnit_isSuccess(etInt16 id) { return etUnit_testcaseSuccess[id]; } +etBool etUnit_isSuccessSuite() { + return etUnit_errorCounter == 0; +} + +etBool etUnit_isSuccessAll() { + return etUnit_failedSuites == 0; +} + /* private functions */ static void expect_equal_int(etInt16 id, const char* message, etInt32 expected, etInt32 actual, const char* file, int line) { diff --git a/runtime/org.eclipse.etrice.runtime.c/src/common/etUnit/etUnit.h b/runtime/org.eclipse.etrice.runtime.c/src/common/etUnit/etUnit.h index f891c37a5..b29080445 100644 --- a/runtime/org.eclipse.etrice.runtime.c/src/common/etUnit/etUnit.h +++ b/runtime/org.eclipse.etrice.runtime.c/src/common/etUnit/etUnit.h @@ -71,6 +71,14 @@ void etUnit_closeTestCase(etInt16 id); * \param id the test case id */ etBool etUnit_isSuccess(etInt16 id); +/** + * indicate success of current test suite + */ +etBool etUnit_isSuccessSuite(); +/** + * indicate success of all test suites + */ +etBool etUnit_isSuccessAll(); /** * releases the \ref etRuntime_getTerminateSemaphore() and thus makes the program terminate * @@ -153,6 +161,10 @@ void etUnit_closeAll(etInt16 id); #define EXPECT_EQUAL_PTR(id, msg, expected, actual) \ expect_equal_void_ptr(id, msg, (const void*) expected, (const void*) actual, __FILE__, __LINE__) +/* + * Strings + */ +#define EXPECT_EQUAL_STR(id, msg, expected, actual) expectEqualStr(id, msg, expected, actual, __FILE__, __LINE__) /* * more specialized functions @@ -358,6 +370,19 @@ void expectRangeFloat64(etInt16 id, const char* message, etFloat64 min, etFloat6 * \param line the line */ void expect_equal_void_ptr(etInt16 id, const char* msg, const void* expected, const void* actual, const char* file, int line); + +/** + * reports an error if two strings aren't equal + * + * \param id the test case id + * \param msg the result message + * \param expected the expected value + * \param actual the actual value + * \param file the file name with the test case + * \param line the line + */ +void expectEqualStr(etInt16 id, const char* msg, const char* expected, const char* actual, const char* file, int line); + /** * start of a comparison of an expected order. Initially with this method * a list of integers is passed. Later calls of \ref expectOrder(etInt16, const char* msg, etInt16, const char* int) -- cgit v1.2.3