summaryrefslogtreecommitdiff
path: root/cesar/cp/eoc/fsm/test/utest
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/cp/eoc/fsm/test/utest')
-rw-r--r--cesar/cp/eoc/fsm/test/utest/Config3
-rw-r--r--cesar/cp/eoc/fsm/test/utest/Makefile14
-rw-r--r--cesar/cp/eoc/fsm/test/utest/inc/scenario_defs.h135
-rw-r--r--cesar/cp/eoc/fsm/test/utest/override/cp/inc/context.h35
-rw-r--r--cesar/cp/eoc/fsm/test/utest/override/cp/sta/core/core.h26
-rw-r--r--cesar/cp/eoc/fsm/test/utest/src/actions.c97
-rw-r--r--cesar/cp/eoc/fsm/test/utest/src/fsm_stub.c263
-rw-r--r--cesar/cp/eoc/fsm/test/utest/src/test_fsm.c477
-rw-r--r--cesar/cp/eoc/fsm/test/utest/src/utest.fsm86
9 files changed, 1136 insertions, 0 deletions
diff --git a/cesar/cp/eoc/fsm/test/utest/Config b/cesar/cp/eoc/fsm/test/utest/Config
new file mode 100644
index 0000000000..7378106168
--- /dev/null
+++ b/cesar/cp/eoc/fsm/test/utest/Config
@@ -0,0 +1,3 @@
+CONFIG_CP_EOC = y
+CONFIG_DEBUG_FATAL_CATCH = y
+CONFIG_CP_FSM_DEF = "cp/eoc/fsm/test/utest/src/utest.fsm"
diff --git a/cesar/cp/eoc/fsm/test/utest/Makefile b/cesar/cp/eoc/fsm/test/utest/Makefile
new file mode 100644
index 0000000000..7cf4406e65
--- /dev/null
+++ b/cesar/cp/eoc/fsm/test/utest/Makefile
@@ -0,0 +1,14 @@
+BASE = ../../../../..
+
+INCLUDES = cp/eoc/fsm/test/utest cp/eoc/fsm/test/utest/override
+
+HOST_PROGRAMS = test_fsm
+test_fsm_SOURCES = test_fsm.c fsm_stub.c actions.c
+test_fsm_MODULES = lib lib/scenario cp/eoc/fsm
+test_fsm_CONFIG_MODULES = cp/eoc mac/common
+cp_eoc_fsm_MODULE_SOURCES :=
+
+cp_MODULE_MODULES =
+cp_MODULE_SOURCES = $(if $(filter y,$(CONFIG_TRACE)),trace.c,)
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/cp/eoc/fsm/test/utest/inc/scenario_defs.h b/cesar/cp/eoc/fsm/test/utest/inc/scenario_defs.h
new file mode 100644
index 0000000000..a91c3fe4d8
--- /dev/null
+++ b/cesar/cp/eoc/fsm/test/utest/inc/scenario_defs.h
@@ -0,0 +1,135 @@
+#ifndef inc_scenario_defs_h
+#define inc_scenario_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/scenario_defs.h
+ * \brief Scenario definitions.
+ * \ingroup test
+ */
+
+#include "cp/types.h"
+#include "cp/mme.h"
+#include "cp/fsm/fsm.h"
+
+/* Scenario globals. */
+#define SCENARIO_DEFS_GLOBALS \
+ cp_t *cp;
+
+/* Scenario actions. */
+#define SCENARIO_DEFS_ACTIONS \
+ post_and_process, \
+ post, \
+ trigger, \
+ post_urgent, \
+ process, \
+ process_urgent
+
+typedef struct
+{
+ cp_fsm_event_type_t type;
+ cp_mme_rx_t *mme;
+ bsu_beacon_t *beacon;
+ cp_net_t *net;
+ cp_sta_t *sta;
+} scenario_action_event_param_t;
+
+typedef scenario_action_event_param_t scenario_action_post_and_process_t;
+typedef scenario_action_event_param_t scenario_action_post_t;
+typedef scenario_action_event_param_t scenario_action_trigger_t;
+typedef scenario_action_event_param_t scenario_action_post_urgent_t;
+typedef scenario_empty_t scenario_action_process_t;
+typedef scenario_empty_t scenario_action_process_urgent_t;
+
+void
+scenario_action_post_and_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_post_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_trigger_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_post_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+void
+scenario_action_process_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params);
+
+/* Scenario events. */
+#define SCENARIO_DEFS_EVENTS \
+ cp_fsm__STATE1__event1, \
+ cp_fsm__STATE1__event2, \
+ cp_fsm__STATE1__event_mme, \
+ cp_fsm__STATE1__event_sta, \
+ cp_fsm__STATE1__event_beacon, \
+ cp_fsm__STATE1__eventb, \
+ cp_fsm__STATE1__long_event, \
+ cp_fsm__STATE1__urgent_event, \
+ cp_fsm__STATE2__event3, \
+ cp_fsm__STATE3__event1, \
+ cp_fsm__STATE3__event2, \
+ cp_fsm__STATE3__urgent_event, \
+ cp_fsm__STATE4__event1, \
+ cp_fsm__STATE5__enter, \
+ cp_fsm__STATE5__leave, \
+ cp_fsm__STATE6__enter, \
+ cp_fsm__STATE6__leave, \
+ cp_fsm__STATEA__eventb, \
+ cp_fsm__STATEB__eventa
+
+typedef struct
+{
+ cp_fsm_branch_t branch;
+} scenario_event_transition_with_branch_t;
+
+typedef scenario_empty_t scenario_event_cp_fsm__STATE1__event1_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE1__event2_t;
+typedef struct
+{
+ cp_mme_rx_t *mme;
+} scenario_event_cp_fsm__STATE1__event_mme_t;
+typedef struct
+{
+ cp_net_t *net;
+ cp_sta_t *sta;
+} scenario_event_cp_fsm__STATE1__event_sta_t;
+typedef struct
+{
+ bsu_beacon_t *beacon;
+ cp_net_t *net;
+ cp_sta_t *sta;
+} scenario_event_cp_fsm__STATE1__event_beacon_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE1__eventb_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE1__long_event_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE1__urgent_event_t;
+typedef scenario_event_transition_with_branch_t
+scenario_event_cp_fsm__STATE2__event3_t;
+typedef scenario_event_transition_with_branch_t
+scenario_event_cp_fsm__STATE3__event1_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE3__event2_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE3__urgent_event_t;
+typedef scenario_event_transition_with_branch_t
+scenario_event_cp_fsm__STATE4__event1_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE5__enter_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE5__leave_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE6__enter_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATE6__leave_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATEA__eventb_t;
+typedef scenario_empty_t scenario_event_cp_fsm__STATEB__eventa_t;
+
+#endif /* inc_scenario_defs_h */
diff --git a/cesar/cp/eoc/fsm/test/utest/override/cp/inc/context.h b/cesar/cp/eoc/fsm/test/utest/override/cp/inc/context.h
new file mode 100644
index 0000000000..edc1fde804
--- /dev/null
+++ b/cesar/cp/eoc/fsm/test/utest/override/cp/inc/context.h
@@ -0,0 +1,35 @@
+#ifndef override_cp_inc_context_h
+#define override_cp_inc_context_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cp/inc/context.h
+ * \brief Control plane context override.
+ * \ingroup test
+ */
+
+#include "cp/fsm/fsm.h"
+#include "cp/fsm/inc/context.h"
+#include "cp/inc/trace.h"
+
+struct cp_t
+{
+#if CONFIG_TRACE
+ /** Trace context. */
+ trace_buffer_t trace;
+#endif /* CONFIG_TRACE */
+
+ /** FSM context. */
+ cp_fsm_t fsm;
+ /** STA core flag. */
+ bool sta_core_flag;
+ /** STA core urgent flag. */
+ bool sta_core_urgent_flag;
+};
+
+#endif /* override_cp_inc_context_h */
diff --git a/cesar/cp/eoc/fsm/test/utest/override/cp/sta/core/core.h b/cesar/cp/eoc/fsm/test/utest/override/cp/sta/core/core.h
new file mode 100644
index 0000000000..352368b45b
--- /dev/null
+++ b/cesar/cp/eoc/fsm/test/utest/override/cp/sta/core/core.h
@@ -0,0 +1,26 @@
+#ifndef override_cp_sta_core_core_h
+#define override_cp_sta_core_core_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/cp/sta/core/core.h
+ * \brief STA Core override.
+ * \ingroup test
+ */
+
+BEGIN_DECLS
+
+void
+cp_sta_core_signal_fsm_event (cp_t *ctx);
+
+void
+cp_sta_core_signal_fsm_urgent_event (cp_t *ctx);
+
+END_DECLS
+
+#endif /* override_cp_sta_core_core_h */
diff --git a/cesar/cp/eoc/fsm/test/utest/src/actions.c b/cesar/cp/eoc/fsm/test/utest/src/actions.c
new file mode 100644
index 0000000000..b8d344a32f
--- /dev/null
+++ b/cesar/cp/eoc/fsm/test/utest/src/actions.c
@@ -0,0 +1,97 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/actions.c
+ * \brief Scenario actions.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "cp/inc/context.h"
+
+cp_fsm_event_t *
+scenario_action_make_event (cp_t *cp, scenario_action_event_param_t *ep)
+{
+ cp_fsm_event_t *event;
+ if (ep->mme)
+ event = cp_fsm_event_mme_new (cp, ep->type, ep->mme);
+ else if (ep->beacon)
+ event = cp_fsm_event_beacon_new (cp, ep->type, ep->beacon, ep->net,
+ ep->sta);
+ else if (ep->sta)
+ event = cp_fsm_event_sta_new (cp, ep->type, ep->net, ep->sta);
+ else
+ event = cp_fsm_event_bare_new (cp, ep->type);
+ return event;
+}
+
+void
+scenario_action_post_and_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ scenario_action_post_and_process_t *p = &params->action_post_and_process;
+ cp_fsm_post (globals->cp, scenario_action_make_event (globals->cp, p));
+ test_fail_unless (globals->cp->sta_core_flag);
+ globals->cp->sta_core_flag = false;
+ cp_fsm_process (globals->cp);
+}
+
+void
+scenario_action_post_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ scenario_action_post_t *p = &params->action_post;
+ cp_fsm_post (globals->cp, scenario_action_make_event (globals->cp, p));
+ test_fail_unless (globals->cp->sta_core_flag);
+}
+
+void
+scenario_action_trigger_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ scenario_action_trigger_t *p = &params->action_trigger;
+ cp_fsm_trigger (globals->cp, scenario_action_make_event (globals->cp, p));
+ test_fail_unless (globals->cp->sta_core_flag);
+}
+
+void
+scenario_action_post_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ scenario_action_post_urgent_t *p = &params->action_post_urgent;
+ cp_fsm_post_urgent (globals->cp,
+ scenario_action_make_event (globals->cp, p));
+ test_fail_unless (globals->cp->sta_core_urgent_flag);
+}
+
+void
+scenario_action_process_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ test_fail_unless (globals->cp->sta_core_flag);
+ globals->cp->sta_core_flag = false;
+ cp_fsm_process (globals->cp);
+}
+
+void
+scenario_action_process_urgent_cb (scenario_globals_t *globals,
+ scenario_params_t *params)
+{
+ test_within (scenario.t);
+ test_fail_unless (globals->cp->sta_core_urgent_flag);
+ globals->cp->sta_core_urgent_flag = false;
+ cp_fsm_process_urgent (globals->cp);
+}
+
diff --git a/cesar/cp/eoc/fsm/test/utest/src/fsm_stub.c b/cesar/cp/eoc/fsm/test/utest/src/fsm_stub.c
new file mode 100644
index 0000000000..ee8c8bea9e
--- /dev/null
+++ b/cesar/cp/eoc/fsm/test/utest/src/fsm_stub.c
@@ -0,0 +1,263 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/fsm_stub.c
+ * \brief Override FSM tables.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/scenario/scenario.h"
+
+#include "cp/fsm/fsm.h"
+#include "cp/fsm/inc/tables.h"
+
+int cp_fsm__STATE1__enter_nb;
+int cp_fsm__STATE2__enter_nb;
+
+void
+cp_fsm__STATE1__enter (cp_t *ctx);
+
+void
+cp_fsm__STATE1__event1 (cp_t *ctx);
+
+void
+cp_fsm__STATE1__event2 (cp_t *ctx);
+
+void
+cp_fsm__STATE1__error_event_no_branch (cp_t *ctx);
+
+void
+cp_fsm__STATE1__error_event_bad_branch (cp_t *ctx);
+
+void
+cp_fsm__STATE1__error_event_dup_branch (cp_t *ctx);
+
+void
+cp_fsm__STATE1__error_urgent_event_branch (cp_t *ctx);
+
+void
+cp_fsm__STATE1__event_mme (cp_t *ctx, cp_mme_rx_t *mme);
+
+void
+cp_fsm__STATE1__event_sta (cp_t *ctx, cp_net_t *net, cp_sta_t *sta);
+
+void
+cp_fsm__STATE1__event_beacon (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta);
+
+void
+cp_fsm__STATE1__eventb (cp_t *ctx);
+
+void
+cp_fsm__STATE1__long_event (cp_t *ctx);
+
+void
+cp_fsm__STATE1__urgent_event (cp_t *ctx);
+
+void
+cp_fsm__STATE2__enter (cp_t *ctx);
+
+void
+cp_fsm__STATE2__event3 (cp_t *ctx);
+
+void
+cp_fsm__STATE3__event1 (cp_t *ctx);
+
+void
+cp_fsm__STATE3__event2 (cp_t *ctx);
+
+void
+cp_fsm__STATE3__urgent_event (cp_t *ctx);
+
+void
+cp_fsm__STATE4__event1 (cp_t *ctx);
+
+void
+cp_fsm__STATE5__enter (cp_t *ctx);
+
+void
+cp_fsm__STATE5__leave (cp_t *ctx);
+
+void
+cp_fsm__STATE6__enter (cp_t *ctx);
+
+void
+cp_fsm__STATE6__leave (cp_t *ctx);
+
+void
+cp_fsm__STATEA__eventb (cp_t *ctx);
+
+void
+cp_fsm__STATEB__eventa (cp_t *ctx);
+
+/* Include generated tables. */
+#include "cp_fsm_tables.h"
+
+void
+cp_fsm__STATE1__enter (cp_t *ctx)
+{
+ cp_fsm__STATE1__enter_nb++;
+}
+
+void
+cp_fsm__STATE1__event1 (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE1__event1);
+}
+
+void
+cp_fsm__STATE1__event2 (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE1__event2);
+}
+
+void
+cp_fsm__STATE1__error_event_no_branch (cp_t *ctx)
+{
+ /* Do not choose branch. */
+}
+
+void
+cp_fsm__STATE1__error_event_bad_branch (cp_t *ctx)
+{
+ cp_fsm_branch (ctx, STATE2, event3, branch1);
+}
+
+void
+cp_fsm__STATE1__error_event_dup_branch (cp_t *ctx)
+{
+ cp_fsm_branch (ctx, STATE1, error_event_dup_branch, branch1);
+ cp_fsm_branch (ctx, STATE1, error_event_dup_branch, branch2);
+}
+
+void
+cp_fsm__STATE1__error_urgent_event_branch (cp_t *ctx)
+{
+ cp_fsm_branch (ctx, STATE1, error_urgent_event_branch, branch1);
+}
+
+void
+cp_fsm__STATE1__event_mme (cp_t *ctx, cp_mme_rx_t *mme)
+{
+ scenario_event (cp_fsm__STATE1__event_mme, param);
+ test_fail_unless (mme == param->mme);
+}
+
+void
+cp_fsm__STATE1__event_sta (cp_t *ctx, cp_net_t *net, cp_sta_t *sta)
+{
+ scenario_event (cp_fsm__STATE1__event_sta, param);
+ test_fail_unless (net == param->net);
+ test_fail_unless (sta == param->sta);
+}
+
+void
+cp_fsm__STATE1__event_beacon (cp_t *ctx, bsu_beacon_t *beacon,
+ cp_net_t *net, cp_sta_t *sta)
+{
+ scenario_event (cp_fsm__STATE1__event_beacon, param);
+ test_fail_unless (beacon == param->beacon);
+ test_fail_unless (net == param->net);
+ test_fail_unless (sta == param->sta);
+}
+
+void
+cp_fsm__STATE1__eventb (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE1__eventb);
+}
+
+void
+cp_fsm__STATE1__long_event (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE1__long_event);
+ cp_fsm_process_urgent (ctx);
+}
+
+void
+cp_fsm__STATE1__urgent_event (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE1__urgent_event);
+}
+
+void
+cp_fsm__STATE2__enter (cp_t *ctx)
+{
+ cp_fsm__STATE2__enter_nb++;
+}
+
+void
+cp_fsm__STATE2__event3 (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE2__event3, param);
+ cp_fsm_branch_ (ctx, param->branch);
+}
+
+void
+cp_fsm__STATE3__event1 (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE3__event1, param);
+ cp_fsm_branch_ (ctx, param->branch);
+}
+
+void
+cp_fsm__STATE3__event2 (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE3__event2);
+}
+
+void
+cp_fsm__STATE3__urgent_event (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE3__urgent_event);
+}
+
+void
+cp_fsm__STATE4__event1 (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE4__event1, param);
+ cp_fsm_branch_ (ctx, param->branch);
+}
+
+void
+cp_fsm__STATE5__enter (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE5__enter);
+}
+
+void
+cp_fsm__STATE5__leave (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE5__leave);
+}
+
+void
+cp_fsm__STATE6__enter (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE6__enter);
+}
+
+void
+cp_fsm__STATE6__leave (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATE6__leave);
+}
+
+void
+cp_fsm__STATEA__eventb (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATEA__eventb);
+}
+
+void
+cp_fsm__STATEB__eventa (cp_t *ctx)
+{
+ scenario_event (cp_fsm__STATEB__eventa);
+}
+
diff --git a/cesar/cp/eoc/fsm/test/utest/src/test_fsm.c b/cesar/cp/eoc/fsm/test/utest/src/test_fsm.c
new file mode 100644
index 0000000000..54a17abc6d
--- /dev/null
+++ b/cesar/cp/eoc/fsm/test/utest/src/test_fsm.c
@@ -0,0 +1,477 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_fsm.c
+ * \brief Test FSM module.
+ * \ingroup test
+ */
+#include "common/std.h"
+
+#include "lib/blk.h"
+#include "lib/test.h"
+#include "lib/scenario/scenario.h"
+
+#include "cp/fsm/fsm.h"
+
+#include "cp/inc/context.h"
+
+#include "cp/sta/core/core.h"
+
+extern int cp_fsm__STATE1__enter_nb;
+extern int cp_fsm__STATE2__enter_nb;
+
+void
+test_fsm_basic_test_case (test_t t)
+{
+ test_case_begin (t, "basic");
+ cp_t cp;
+ cp.sta_core_urgent_flag = false;
+ cp_trace_init (&cp);
+ slab_cache_t cache;
+ slab_cache_init (&cache, "dummy", 1, NULL);
+ cp_mme_rx_t *mme = slab_alloc (&cache);
+ cp_sta_t *sta = slab_alloc (&cache);
+ cp_net_t *net = (void *) 0x9abcdef0;
+ bsu_beacon_t *beacon = blk_alloc ();
+ test_begin (t, "bare")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STATE1 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_fsm__STATE1__event1),
+ /* STATE1 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event2),
+ SCENARIO_EVENT (cp_fsm__STATE1__event2),
+ /* STATE2 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event3),
+ SCENARIO_EVENT (cp_fsm__STATE2__event3,
+ .branch = CP_FSM_BRANCH (STATE2, event3, branch1)),
+ /* STATE3 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_fsm__STATE3__event1,
+ .branch = CP_FSM_BRANCH (STATE3, event1, branch2)),
+ /* STATE3 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event2),
+ SCENARIO_EVENT (cp_fsm__STATE3__event2),
+ /* STATE2 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event3),
+ SCENARIO_EVENT (cp_fsm__STATE2__event3,
+ .branch = CP_FSM_BRANCH (STATE2, event3, branch2)),
+ /* STATE4 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_fsm__STATE4__event1,
+ .branch = CP_FSM_BRANCH (STATE4, event1, branch2)),
+ /* STATE4 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_fsm__STATE4__event1,
+ .branch = CP_FSM_BRANCH (STATE4, event1, branch1)),
+ /* STATE1 */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ cp_fsm_uninit (&cp);
+ } test_end;
+ test_begin (t, "mme")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event_mme, .mme = mme),
+ SCENARIO_EVENT (cp_fsm__STATE1__event_mme, .mme = mme),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ cp_fsm_uninit (&cp);
+ } test_end;
+ test_begin (t, "sta")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event_sta,
+ .net = net, .sta = sta),
+ SCENARIO_EVENT (cp_fsm__STATE1__event_sta,
+ .net = net, .sta = sta),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ cp_fsm_uninit (&cp);
+ } test_end;
+ test_begin (t, "beacon")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event_beacon,
+ .beacon = beacon, .net = net, .sta = sta),
+ SCENARIO_EVENT (cp_fsm__STATE1__event_beacon,
+ .beacon = beacon, .net = net, .sta = sta),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ cp_fsm_uninit (&cp);
+ } test_end;
+ test_begin (t, "dual")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STATE1, STATEA */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_eventb),
+ SCENARIO_EVENT (cp_fsm__STATE1__eventb),
+ SCENARIO_EVENT (cp_fsm__STATEA__eventb),
+ /* STATE3, STATEB */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_eventa),
+ SCENARIO_EVENT (cp_fsm__STATEB__eventa),
+ /* STATE3, STATEA */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_fsm__STATE3__event1,
+ .branch = CP_FSM_BRANCH (STATE3, event1, branch1)),
+ /* STATE1, STATEA */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ test_fail_unless (cp.fsm.active_states[1] == CP_FSM_STATE_STATEA);
+ cp_fsm_uninit (&cp);
+ } test_end;
+ test_begin (t, "no action")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STATE1 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event_no_action),
+ /* STATE3 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_fsm__STATE3__event1,
+ .branch = CP_FSM_BRANCH (STATE3, event1, branch1)),
+ /* STATE1 */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ cp_fsm_uninit (&cp);
+ } test_end;
+ test_begin (t, "enter leave")
+ {
+ cp_fsm__STATE1__enter_nb = 0;
+ cp_fsm__STATE2__enter_nb = 0;
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STATE1 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event5),
+ SCENARIO_EVENT (cp_fsm__STATE5__enter),
+ /* STATE5 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event5),
+ /* No enter/leave here. */
+ /* STATE5 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event6),
+ SCENARIO_EVENT (cp_fsm__STATE5__leave),
+ SCENARIO_EVENT (cp_fsm__STATE6__enter),
+ /* STATE6 */
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_fsm__STATE6__leave),
+ /* STATE1 */
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ test_fail_unless (cp_fsm__STATE1__enter_nb == 2);
+ test_fail_unless (cp_fsm__STATE2__enter_nb == 0);
+ cp_fsm_uninit (&cp);
+ } test_end;
+ test_begin (t, "trigger")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STATE1 */
+ SCENARIO_ACTION (post, .type = CP_FSM_EVENT_TYPE_event3),
+ SCENARIO_ACTION (trigger, .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_ACTION (trigger, .type = CP_FSM_EVENT_TYPE_event2),
+ SCENARIO_ACTION (process),
+ SCENARIO_EVENT (cp_fsm__STATE1__event1),
+ SCENARIO_ACTION (process),
+ SCENARIO_EVENT (cp_fsm__STATE1__event2),
+ /* STATE2 */
+ SCENARIO_ACTION (process),
+ SCENARIO_EVENT (cp_fsm__STATE2__event3,
+ .branch = CP_FSM_BRANCH (STATE2, event3, branch1)),
+ /* STATE3 */
+ SCENARIO_ACTION (trigger, .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_ACTION (process),
+ SCENARIO_EVENT (cp_fsm__STATE3__event1,
+ .branch = CP_FSM_BRANCH (STATE3, event1, branch1)),
+ /* STATE1 */
+ /* Now, test some insertion corner cases. */
+ SCENARIO_ACTION (trigger, .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_ACTION (trigger, .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_ACTION (post, .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ cp_fsm_uninit (&cp);
+ } test_end;
+ test_begin (t, "urgent")
+ {
+ cp_fsm_init (&cp);
+ cp.sta_core_flag = false;
+ scenario_entry_t entries[] = {
+ /* STATE1 */
+ SCENARIO_ACTION (post, .type = CP_FSM_EVENT_TYPE_long_event),
+ SCENARIO_ACTION (post_urgent,
+ .type = CP_FSM_EVENT_TYPE_urgent_event),
+ SCENARIO_ACTION (process),
+ SCENARIO_EVENT (cp_fsm__STATE1__long_event),
+ SCENARIO_EVENT (cp_fsm__STATE1__urgent_event),
+ /* STATE3 */
+ SCENARIO_ACTION (post_urgent,
+ .type = CP_FSM_EVENT_TYPE_urgent_event),
+ SCENARIO_ACTION (post_urgent,
+ .type = CP_FSM_EVENT_TYPE_urgent_event),
+ SCENARIO_ACTION (process_urgent),
+ SCENARIO_EVENT (cp_fsm__STATE3__urgent_event),
+ SCENARIO_ACTION (process_urgent),
+ SCENARIO_EVENT (cp_fsm__STATE3__urgent_event),
+ SCENARIO_ACTION (post_and_process,
+ .type = CP_FSM_EVENT_TYPE_event1),
+ SCENARIO_EVENT (cp_fsm__STATE3__event1,
+ .branch = CP_FSM_BRANCH (STATE3, event1, branch1)),
+ SCENARIO_END
+ };
+ scenario_globals_t globals = {
+ .cp = &cp,
+ };
+ scenario_run (t, entries, &globals);
+ test_fail_unless (cp.fsm.active_states[0] == CP_FSM_STATE_STATE1);
+ cp_fsm_uninit (&cp);
+ } test_end;
+ slab_release (mme);
+ slab_release (sta);
+ slab_cache_uninit (&cache);
+ blk_release (beacon);
+#if CONFIG_TRACE
+ trace_buffer_dbg_dump (&cp.trace);
+#endif /* CONFIG_TRACE */
+ cp_trace_uninit (&cp);
+}
+
+void
+test_fsm_error_test_case (test_t t)
+{
+ test_case_begin (t, "error");
+ cp_t cp;
+ cp_trace_init (&cp);
+ test_begin (t, "no branch")
+ {
+ cp_fsm_init (&cp);
+ cp_fsm_event_t *event = cp_fsm_event_bare_new (
+ &cp, CP_FSM_EVENT_TYPE_error_event_no_branch);
+ cp_fsm_post (&cp, event);
+ const char *asserted = NULL;
+ dbg_fatal_try_begin
+ {
+ cp_fsm_process (&cp);
+ }
+ dbg_fatal_try_catch (const char *msg)
+ {
+ slab_release (event); /* Was not release due to assert. */
+ asserted = msg;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (asserted);
+ } test_end;
+ test_begin (t, "bad branch")
+ {
+ cp_fsm_init (&cp);
+ cp_fsm_event_t *event = cp_fsm_event_bare_new (
+ &cp, CP_FSM_EVENT_TYPE_error_event_bad_branch);
+ cp_fsm_post (&cp, event);
+ const char *asserted = NULL;
+ dbg_fatal_try_begin
+ {
+ cp_fsm_process (&cp);
+ }
+ dbg_fatal_try_catch (const char *msg)
+ {
+ slab_release (event); /* Was not release due to assert. */
+ asserted = msg;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (asserted);
+ } test_end;
+ test_begin (t, "dup branch")
+ {
+ cp_fsm_init (&cp);
+ cp_fsm_event_t *event = cp_fsm_event_bare_new (
+ &cp, CP_FSM_EVENT_TYPE_error_event_dup_branch);
+ cp_fsm_post (&cp, event);
+ const char *asserted = NULL;
+ dbg_fatal_try_begin
+ {
+ cp_fsm_process (&cp);
+ }
+ dbg_fatal_try_catch (const char *msg)
+ {
+ slab_release (event); /* Was not release due to assert. */
+ asserted = msg;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (asserted);
+ } test_end;
+ test_begin (t, "not in transition")
+ {
+ cp_fsm_init (&cp);
+ const char *asserted = NULL;
+ dbg_fatal_try_begin
+ {
+ cp_fsm_branch (&cp, STATE1, error_event_no_branch, branch1);
+ }
+ dbg_fatal_try_catch (const char *msg)
+ {
+ asserted = msg;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (asserted);
+ } test_end;
+ test_begin (t, "transition for urgent event")
+ {
+ cp_fsm_init (&cp);
+ cp_fsm_event_t *event = cp_fsm_event_bare_new (
+ &cp, CP_FSM_EVENT_TYPE_error_urgent_event_transition);
+ cp_fsm_post_urgent (&cp, event);
+ const char *asserted = NULL;
+ dbg_fatal_try_begin
+ {
+ cp_fsm_process_urgent (&cp);
+ }
+ dbg_fatal_try_catch (const char *msg)
+ {
+ slab_release (event); /* Was not release due to assert. */
+ asserted = msg;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (asserted);
+ } test_end;
+ test_begin (t, "branch for urgent event")
+ {
+ cp_fsm_init (&cp);
+ cp_fsm_event_t *event = cp_fsm_event_bare_new (
+ &cp, CP_FSM_EVENT_TYPE_error_urgent_event_branch);
+ cp_fsm_post_urgent (&cp, event);
+ const char *asserted = NULL;
+ dbg_fatal_try_begin
+ {
+ cp_fsm_process_urgent (&cp);
+ }
+ dbg_fatal_try_catch (const char *msg)
+ {
+ slab_release (event); /* Was not release due to assert. */
+ asserted = msg;
+ }
+ dbg_fatal_try_end;
+ test_fail_unless (asserted);
+ } test_end;
+#if CONFIG_TRACE
+ trace_buffer_dbg_dump (&cp.trace);
+#endif /* CONFIG_TRACE */
+ cp_trace_uninit (&cp);
+}
+
+void
+test_fsm_test_suite (test_t t)
+{
+ test_suite_begin (t, "fsm");
+ test_fsm_basic_test_case (t);
+ test_fsm_error_test_case (t);
+ test_case_begin (t, "memory");
+ test_begin (t, "memory")
+ {
+ test_fail_unless (blk_check_memory ());
+ } test_end;
+}
+
+void
+cp_sta_core_signal_fsm_event (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ ctx->sta_core_flag = true;
+}
+
+void
+cp_sta_core_signal_fsm_urgent_event (cp_t *ctx)
+{
+ dbg_assert (ctx);
+ ctx->sta_core_urgent_flag = true;
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ trace_init ();
+ test_init (t, argc, argv);
+ test_fsm_test_suite (t);
+ trace_uninit ();
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
+
diff --git a/cesar/cp/eoc/fsm/test/utest/src/utest.fsm b/cesar/cp/eoc/fsm/test/utest/src/utest.fsm
new file mode 100644
index 0000000000..f251cb6708
--- /dev/null
+++ b/cesar/cp/eoc/fsm/test/utest/src/utest.fsm
@@ -0,0 +1,86 @@
+Test Control Plane FSM
+ Test FSM for engine test.
+
+States:
+ STATE1 [enter=cp_fsm__STATE1__enter]
+ STATE2 [enter=cp_fsm__STATE2__enter]
+ STATE3
+ STATE4
+ STATE5 [enter=cp_fsm__STATE5__enter leave=cp_fsm__STATE5__leave]
+ STATE6 [enter=cp_fsm__STATE6__enter leave=cp_fsm__STATE6__leave]
+ *STATEA
+ STATEB
+
+Events:
+ event1
+ event2
+ event3
+ event4
+ event5
+ event6
+ error_event_no_branch
+ test error conditions: no branch selected
+ error_event_bad_branch
+ test error conditions: branch not for this event
+ error_event_dup_branch
+ test error conditions: branch selected two times
+ error_urgent_event_transition
+ test error conditions: urgent event with transition
+ error_urgent_event_branch
+ test error conditions: urgent event with branch
+ event_mme
+ event_sta
+ event_beacon
+ event_no_action
+ eventa
+ eventb
+ long_event
+ long event handling triggering a urgent process
+ urgent_event
+
+STATE1:
+ event1 -> .
+ event2 -> STATE2
+ event5 -> STATE5 [NULL]
+ error_event_no_branch: branch1 -> .
+ error_event_no_branch: branch2 -> .
+ error_event_bad_branch: branch1 -> .
+ error_event_bad_branch: branch2 -> .
+ error_event_dup_branch: branch1 -> .
+ error_event_dup_branch: branch2 -> .
+ error_urgent_event_transition -> STATE2 [NULL]
+ error_urgent_event_branch: branch1 -> .
+ error_urgent_event_branch: branch2 -> .
+ event_mme -> .
+ event_sta -> .
+ event_beacon -> .
+ event_no_action -> STATE3 [NULL]
+ eventb -> STATE3
+ long_event -> STATE3
+ urgent_event -> .
+
+STATE2:
+ event3: branch1 -> STATE3
+ event3: branch2 -> STATE4
+
+STATE3:
+ event2 -> STATE2
+ urgent_event -> .
+
+STATE3, STATE4:
+ event1: branch1 -> STATE1
+ event1: branch2 -> .
+
+STATE5:
+ event5 -> . [NULL]
+ event6 -> STATE6 [NULL]
+
+STATE6:
+ event1 -> STATE1 [NULL]
+
+STATEA:
+ eventb -> STATEB
+
+STATEB:
+ eventa -> STATEA
+