| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /*
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2023-06-03 tyx first implementation
- */
- #include <stdio.h>
- #include <string.h>
- #include <gtest/gtest.h>
- #include "cb_hsm.h"
- typedef struct sm_test_actor
- {
- cb_hsm_actor_t super;
- int foo;
- char buff[256];
- char *ptr;
- char* end;
- }sm_actor;
- enum QHsmTstSignals {
- A_SIG = CB_HSM_TOPIC_USER,
- B_SIG,
- C_SIG,
- D_SIG,
- E_SIG,
- F_SIG,
- G_SIG,
- H_SIG,
- I_SIG,
- TERMINATE_SIG,
- MAX_SIG
- };
- static sm_actor test_actor;
- cb_hsm_ret_t QHsmTst_initial(sm_actor *me, const cb_hsm_event_t * const e);
- cb_hsm_ret_t QHsmTst_s2(sm_actor *me, const cb_hsm_event_t * const e);
- cb_hsm_ret_t QHsmTst_s11(sm_actor *me, const cb_hsm_event_t * const e);
- cb_hsm_ret_t QHsmTst_s211(sm_actor *me, const cb_hsm_event_t * const e);
- const char* QHsmTst_ctor(void) {
- sm_actor *me = &test_actor;
- cb_hsm_init(&me->super);
- CB_HSM_START(&me->super, &QHsmTst_initial);
- return test_actor.buff;
- }
- cb_hsm_ret_t QHsmTst_initial(sm_actor *me, const cb_hsm_event_t * const e)
- {
- (void)e; /* suppress "e not used" compiler warning */
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "top-INIT;");
- me->foo = 0; /* initialize extended state variable */
- return CB_HSM_TRAN(me, &QHsmTst_s2);
- }
- cb_hsm_ret_t QHsmTst_s(sm_actor *me, const cb_hsm_event_t * const e) {
- switch (e->topic) {
- case CB_HSM_TOPIC_ENTER: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s-ENTRY;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_EXIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s-EXIT;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_INIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s-INIT;");
- return CB_HSM_TRAN(me, &QHsmTst_s11);
- }
- case E_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s-E;");
- return CB_HSM_TRAN(me, &QHsmTst_s11);
- }
- case I_SIG: { /* internal transition with a guard */
- if (me->foo) {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s-I;");
- me->foo = 0;
- return CB_HSM_HANDLED(me);
- }
- break;
- }
- case TERMINATE_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "exit\n\n;");
- return CB_HSM_HANDLED(me);
- }
- }
- return CB_HSM_SUPER(me, &cb_hsm_state_top);
- }
- cb_hsm_ret_t QHsmTst_s1(sm_actor *me, const cb_hsm_event_t * const e) {
- switch (e->topic) {
- case CB_HSM_TOPIC_ENTER: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s1-ENTRY;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_EXIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s1-EXIT;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_INIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s1-INIT;");
- return CB_HSM_TRAN(me, &QHsmTst_s11);
- }
- case A_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s1-A;");
- return CB_HSM_TRAN(me, &QHsmTst_s1);
- }
- case B_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s1-B;");
- return CB_HSM_TRAN(me, &QHsmTst_s11);
- }
- case C_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s1-C;");
- return CB_HSM_TRAN(me, &QHsmTst_s2);
- }
- case D_SIG: { /* transition with a gurad */
- if (!me->foo) {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s1-D;");
- me->foo = 1;
- return CB_HSM_TRAN(me, &QHsmTst_s);
- }
- break;
- }
- case F_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s1-F;");
- return CB_HSM_TRAN(me, &QHsmTst_s211);
- }
- case I_SIG: { /* internal transition */
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s1-I;");
- return CB_HSM_HANDLED(me);
- }
- }
- return CB_HSM_SUPER(me, &QHsmTst_s);
- }
- /*..........................................................................*/
- cb_hsm_ret_t QHsmTst_s11(sm_actor *me, const cb_hsm_event_t * const e) {
- switch (e->topic) {
- case CB_HSM_TOPIC_ENTER: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s11-ENTRY;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_EXIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s11-EXIT;");
- return CB_HSM_HANDLED(me);
- }
- case D_SIG: { /* transition with a gurad */
- if (me->foo) {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s11-D;");
- me->foo = 0;
- return CB_HSM_TRAN(me, &QHsmTst_s1);
- }
- break;
- }
- case G_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s11-G;");
- return CB_HSM_TRAN(me, &QHsmTst_s211);
- }
- case H_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s11-H;");
- return CB_HSM_TRAN(me, &QHsmTst_s);
- }
- }
- return CB_HSM_SUPER(me, &QHsmTst_s1);
- }
- /*..........................................................................*/
- cb_hsm_ret_t QHsmTst_s2(sm_actor *me, const cb_hsm_event_t * const e) {
- switch (e->topic) {
- case CB_HSM_TOPIC_ENTER: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s2-ENTRY;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_EXIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s2-EXIT;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_INIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s2-INIT;");
- return CB_HSM_TRAN(me, &QHsmTst_s211);
- }
- case C_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s2-C;");
- return CB_HSM_TRAN(me, &QHsmTst_s1);
- }
- case F_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s2-F;");
- return CB_HSM_TRAN(me, &QHsmTst_s11);
- }
- case I_SIG: { /* internal transition with a guard */
- if (!me->foo) {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s2-I;");
- me->foo = 1;
- return CB_HSM_HANDLED(me);
- }
- break;
- }
- }
- return CB_HSM_SUPER(me, &QHsmTst_s);
- }
- /*..........................................................................*/
- cb_hsm_ret_t QHsmTst_s21(sm_actor *me, const cb_hsm_event_t * const e) {
- switch (e->topic) {
- case CB_HSM_TOPIC_ENTER: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s21-ENTRY;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_EXIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s21-EXIT;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_INIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s21-INIT;");
- return CB_HSM_TRAN(me, &QHsmTst_s211);
- }
- case A_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s21-A;");
- return CB_HSM_TRAN(me, &QHsmTst_s21);
- }
- case B_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s21-B;");
- return CB_HSM_TRAN(me, &QHsmTst_s211);
- }
- case G_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s21-G;");
- return CB_HSM_TRAN(me, &QHsmTst_s1);
- }
- }
- return CB_HSM_SUPER(me, &QHsmTst_s2);
- }
- /*..........................................................................*/
- cb_hsm_ret_t QHsmTst_s211(sm_actor *me, const cb_hsm_event_t * const e) {
- switch (e->topic) {
- case CB_HSM_TOPIC_ENTER: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s211-ENTRY;");
- return CB_HSM_HANDLED(me);
- }
- case CB_HSM_TOPIC_EXIT: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s211-EXIT;");
- return CB_HSM_HANDLED(me);
- }
- case D_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s211-D;");
- return CB_HSM_TRAN(me, &QHsmTst_s21);
- }
- case H_SIG: {
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "s211-H;");
- return CB_HSM_TRAN(me, &QHsmTst_s);
- }
- }
- return CB_HSM_SUPER(me, &QHsmTst_s21);
- }
- static void result_clean(void)
- {
- memset(test_actor.buff, 0, sizeof(test_actor.buff));
- test_actor.ptr = test_actor.buff;
- test_actor.end = &test_actor.buff[sizeof(test_actor.buff) / sizeof(test_actor.buff[0])];
- }
- static const char *dispatch(enum QHsmTstSignals sig) {
- cb_hsm_event_t e;
- result_clean();
- e.topic = sig & 0xFFFF;
- test_actor.ptr += snprintf(test_actor.ptr, test_actor.end - test_actor.ptr, "%c:", 'A' + sig - A_SIG);
- cb_hsm_event_handle(&test_actor.super, &e); /* dispatch the event */
- return test_actor.buff;
- }
- TEST(testCase, cb_hsm_test01)
- {
- result_clean();
- EXPECT_STREQ(QHsmTst_ctor(), "top-INIT;s-ENTRY;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;");
- EXPECT_STREQ(dispatch(G_SIG), "G:s21-G;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;");
- EXPECT_STREQ(dispatch(I_SIG), "I:s1-I;");
- EXPECT_STREQ(dispatch(A_SIG), "A:s1-A;s11-EXIT;s1-EXIT;s1-ENTRY;s1-INIT;s11-ENTRY;");
- EXPECT_STREQ(dispatch(D_SIG), "D:s1-D;s11-EXIT;s1-EXIT;s-INIT;s1-ENTRY;s11-ENTRY;");
- EXPECT_STREQ(dispatch(D_SIG), "D:s11-D;s11-EXIT;s1-INIT;s11-ENTRY;");
- EXPECT_STREQ(dispatch(C_SIG), "C:s1-C;s11-EXIT;s1-EXIT;s2-ENTRY;s2-INIT;s21-ENTRY;s211-ENTRY;");
- EXPECT_STREQ(dispatch(E_SIG), "E:s-E;s211-EXIT;s21-EXIT;s2-EXIT;s1-ENTRY;s11-ENTRY;");
- EXPECT_STREQ(dispatch(E_SIG), "E:s-E;s11-EXIT;s1-EXIT;s1-ENTRY;s11-ENTRY;");
- EXPECT_STREQ(dispatch(G_SIG), "G:s11-G;s11-EXIT;s1-EXIT;s2-ENTRY;s21-ENTRY;s211-ENTRY;");
- EXPECT_STREQ(dispatch(I_SIG), "I:s2-I;");
- EXPECT_STREQ(dispatch(I_SIG), "I:s-I;");
- }
|