Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief State Machine tests
0003  *
0004  * @file test_nstd_sm.c
0005  */
0006 /* -----------------------------------------------------------------------------
0007  * Enduro/X Middleware Platform for Distributed Transaction Processing
0008  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0009  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
0019  *
0020  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0021  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0022  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 
0035 /*---------------------------Includes-----------------------------------*/
0036 #include <exsm.h>
0037 #include <cgreen/cgreen.h>
0038 #include <ndebug.h>
0039 /*---------------------------Externs------------------------------------*/
0040 /*---------------------------Macros-------------------------------------*/
0041 #define NR_TRANS    5
0042 /*---------------------------Enums--------------------------------------*/
0043 enum
0044 {
0045     st_entry
0046     , st_say_hello
0047     , st_go_home
0048     , st_go_work
0049     , st_count /* used for state index counting..., not functional */
0050 };
0051 
0052 enum
0053 {
0054     ev_ok
0055     , ev_err
0056     , ev_timeout
0057     , ev_fatal
0058     , ev_normal
0059 };
0060 
0061 /*---------------------------Typedefs-----------------------------------*/
0062 NDRX_SM_T(ndrx_sm_test_t, NR_TRANS);
0063 /*---------------------------Globals------------------------------------*/
0064 /*---------------------------Statics------------------------------------*/
0065 exprivate int M_entry_called;
0066 exprivate int M_say_hello_called;
0067 exprivate int M_go_home_called;
0068 exprivate int M_go_work_called;
0069 /*---------------------------Prototypes---------------------------------*/
0070 
0071 exprivate int entry(void *data);
0072 exprivate int say_hello(void *data);
0073 exprivate int go_home(void *data);
0074 exprivate int go_work(void *data);
0075 
0076 ndrx_sm_test_t M_sm1[st_count] = {
0077 
0078     NDRX_SM_STATE( st_entry, entry,
0079           NDRX_SM_TRAN      (ev_ok,         st_say_hello)
0080         , NDRX_SM_TRAN      (ev_err,        st_go_home)
0081         , NDRX_SM_TRAN      (ev_timeout,    st_go_work)
0082         , NDRX_SM_TRAN      (ev_normal,     NDRX_SM_ST_RETURN0)
0083         , NDRX_SM_TRAN_END
0084         )
0085     , NDRX_SM_STATE(st_say_hello, say_hello,
0086           NDRX_SM_TRAN      (ev_ok,         st_go_home)
0087         , NDRX_SM_TRAN      (ev_err,        st_go_work)
0088         , NDRX_SM_TRAN      (ev_timeout,    st_go_work)
0089         , NDRX_SM_TRAN_END
0090         )
0091     , NDRX_SM_STATE(st_go_home, go_home,
0092           NDRX_SM_TRAN      (ev_ok,         st_go_work)
0093         , NDRX_SM_TRAN      (ev_err,        st_go_work)
0094         , NDRX_SM_TRAN      (ev_timeout,    st_go_work)
0095         , NDRX_SM_TRAN_END
0096         )
0097     , NDRX_SM_STATE(st_go_work, go_work,
0098           NDRX_SM_TRAN      (ev_ok,         NDRX_SM_ST_RETURN)
0099         , NDRX_SM_TRAN      (ev_err,        NDRX_SM_ST_RETURN)
0100         , NDRX_SM_TRAN_END
0101         )
0102 };
0103 
0104 /**
0105  * last state is st_go_home and not st_go_work
0106  */
0107 ndrx_sm_test_t M_sm2[st_count] = {
0108 
0109     NDRX_SM_STATE( st_entry, entry,
0110           NDRX_SM_TRAN      (ev_ok,          st_go_home)
0111         , NDRX_SM_TRAN      (ev_err,        st_go_home)
0112         , NDRX_SM_TRAN      (ev_timeout,    st_go_work)
0113         , NDRX_SM_TRAN      (ev_normal,     NDRX_SM_ST_RETURN0)
0114         , NDRX_SM_TRAN_END
0115         )
0116     , NDRX_SM_STATE(st_go_home, go_home,
0117           NDRX_SM_TRAN      (ev_ok,         st_go_work)
0118         , NDRX_SM_TRAN      (ev_err,        st_go_work)
0119         , NDRX_SM_TRAN      (ev_timeout,    st_go_work)
0120         , NDRX_SM_TRAN_END
0121         )
0122 };
0123 
0124 /* have strange event codes, use scanning*/
0125 ndrx_sm_test_t M_sm3[st_count] = {
0126 
0127     NDRX_SM_STATE( st_entry, entry,
0128           NDRX_SM_TRAN      (-500,          st_go_home)
0129         , NDRX_SM_TRAN      (511,           st_go_home)
0130         , NDRX_SM_TRAN_END
0131         )
0132     , NDRX_SM_STATE(st_go_home, go_home,
0133           NDRX_SM_TRAN      (ev_ok,         st_go_work)
0134         , NDRX_SM_TRAN_END
0135         )
0136     , NDRX_SM_STATE(st_go_work, go_work,
0137           NDRX_SM_TRAN      (-500,         NDRX_SM_ST_RETURN)
0138         , NDRX_SM_TRAN      (511,         NDRX_SM_ST_RETURN)
0139         , NDRX_SM_TRAN_END
0140         )
0141 };
0142 
0143 
0144 /* missing state (out of range) */
0145 ndrx_sm_test_t M_sm4[st_count] = {
0146 
0147     NDRX_SM_STATE( st_entry, entry,
0148           NDRX_SM_TRAN      (-500,          st_go_home)
0149         , NDRX_SM_TRAN      (511,           777)
0150         , NDRX_SM_TRAN_END
0151         )
0152     , NDRX_SM_STATE(st_go_home, go_home,
0153           NDRX_SM_TRAN      (ev_ok,         st_go_work)
0154         , NDRX_SM_TRAN_END
0155         )
0156 };
0157 
0158 
0159 exprivate void reset_counters(void)
0160 {
0161     M_entry_called = 0;
0162     M_say_hello_called = 0;
0163     M_go_home_called = 0;
0164     M_go_work_called = 0;
0165 }
0166 
0167 exprivate int entry(void *data)
0168 {
0169     M_entry_called++;
0170     int *case_no = (int *)data;
0171     return *case_no;
0172 }
0173 
0174 exprivate int say_hello(void *data)
0175 {
0176     M_say_hello_called++;
0177     NDRX_LOG(log_info, "HELLO");
0178     return ev_timeout;
0179 }
0180 
0181 exprivate int go_home(void *data)
0182 {
0183     M_go_home_called++;
0184     return ev_ok;
0185 }
0186 
0187 exprivate int go_work(void *data)
0188 {
0189     M_go_work_called++;
0190     int *case_no =(int *)data;
0191     return *case_no;
0192 }
0193 
0194 Ensure(test_nstd_sm_test1)
0195 {
0196     int data=ev_ok;
0197     reset_counters();
0198 
0199     /* compile the SM: */
0200     assert_equal(ndrx_sm_comp((void *)M_sm1, st_count, NR_TRANS, st_go_work), EXSUCCEED);
0201 
0202     assert_equal(ndrx_sm_run((void *)M_sm1, NR_TRANS, st_entry, (void *)&data, LOG_FACILITY_NDRX), ev_ok);
0203     assert_equal(M_entry_called, 1);
0204     assert_equal(M_say_hello_called, 1);
0205     assert_equal(M_go_home_called, 0);
0206     assert_equal(M_go_work_called, 1);
0207 
0208     reset_counters();
0209     data=ev_err;
0210     assert_equal(ndrx_sm_run((void *)M_sm1, NR_TRANS, st_entry, (void *)&data, LOG_FACILITY_NDRX), ev_err);
0211     assert_equal(M_entry_called, 1);
0212     assert_equal(M_say_hello_called, 0);
0213     assert_equal(M_go_home_called, 1);
0214     assert_equal(M_go_work_called, 1);
0215 
0216     /* transition not found: */
0217     reset_counters();
0218     data = ev_fatal;
0219     assert_equal(ndrx_sm_run((void *)M_sm1, NR_TRANS, st_entry, (void *)&data, LOG_FACILITY_NDRX), EXFAIL);
0220     assert_equal(M_entry_called, 1);
0221     assert_equal(M_say_hello_called, 0);
0222     assert_equal(M_go_home_called, 0);
0223     assert_equal(M_go_work_called, 0);
0224 
0225     /* try different entry state */
0226     data=ev_ok;
0227     reset_counters();
0228     assert_equal(ndrx_sm_run((void *)M_sm1, NR_TRANS, st_go_home, (void *)&data, LOG_FACILITY_NDRX), ev_ok);
0229     assert_equal(M_entry_called, 0);
0230     assert_equal(M_say_hello_called, 0);
0231     assert_equal(M_go_home_called, 1);
0232     assert_equal(M_go_work_called, 1);
0233 
0234     /* exit code 0 forced (not from event code) */
0235     data=ev_normal;
0236     reset_counters();
0237     assert_equal(ndrx_sm_run((void *)M_sm1, NR_TRANS, st_entry, (void *)&data, LOG_FACILITY_NDRX), 0);
0238     assert_equal(M_entry_called, 1);
0239     assert_equal(M_say_hello_called, 0);
0240     assert_equal(M_go_home_called, 0);
0241     assert_equal(M_go_work_called, 0);
0242 }
0243 
0244 /**
0245  * Check SM validations
0246  */
0247 Ensure(test_nstd_sm_validate)
0248 {
0249     assert_equal(ndrx_sm_comp((void *)M_sm1, st_count, NR_TRANS, st_go_work), EXSUCCEED);
0250     /* missing state: */
0251     assert_equal(ndrx_sm_comp((void *)M_sm4, st_count, NR_TRANS, st_go_home), EXFAIL);
0252     /* missing EOF in transitions: */
0253     assert_equal(ndrx_sm_comp((void *)M_sm2, st_count, NR_TRANS, st_go_home), EXFAIL);
0254 }
0255 
0256 /**
0257  * Ensure non index events works
0258  */
0259 Ensure(test_nstd_sm_scan_evs)
0260 {
0261     int data;
0262     assert_equal(ndrx_sm_comp((void *)M_sm3, st_count, NR_TRANS, st_go_work), EXSUCCEED);
0263 
0264     data=-500;
0265     reset_counters();
0266     assert_equal(ndrx_sm_run((void *)M_sm3, NR_TRANS, st_entry, (void *)&data, LOG_FACILITY_NDRX), -500);
0267 
0268     data=511;
0269     reset_counters();
0270     assert_equal(ndrx_sm_run((void *)M_sm3, NR_TRANS, st_entry, (void *)&data, LOG_FACILITY_NDRX), 511);
0271 }
0272 
0273 
0274 /**
0275  * Standard library tests
0276  * @return
0277  */
0278 TestSuite *ubf_nstd_sm(void)
0279 {
0280     TestSuite *suite = create_test_suite();
0281 
0282     add_test(suite, test_nstd_sm_test1);
0283     add_test(suite, test_nstd_sm_validate);
0284     add_test(suite, test_nstd_sm_scan_evs);
0285     
0286     return suite;
0287 }
0288 
0289 /* vim: set ts=4 sw=4 et smartindent: */