blob: 960042c77bbe5e9a6b73abf77bebd3b5c8f79fc8 [file] [log] [blame]
Harald Welte136e7372016-05-29 10:53:17 +09001#include <stdlib.h>
2#include <stdio.h>
3#include <stdarg.h>
4#include <unistd.h>
5#include <string.h>
Neels Hofmeyr975ee6b2018-04-09 00:42:12 +02006#include <errno.h>
Harald Welte136e7372016-05-29 10:53:17 +09007
8#include <osmocom/core/utils.h>
9#include <osmocom/core/select.h>
10#include <osmocom/core/logging.h>
11#include <osmocom/core/fsm.h>
Harald Welte31c0fef2017-04-16 17:26:30 +020012#include <osmocom/ctrl/control_if.h>
Harald Welte136e7372016-05-29 10:53:17 +090013
14enum {
15 DMAIN,
16};
17
18static void *g_ctx;
19
Neels Hofmeyr975ee6b2018-04-09 00:42:12 +020020static int safe_strcmp(const char *a, const char *b)
21{
22 if (!a || !b)
23 return a == b ? 0 : 1;
24 return strcmp(a, b);
25}
Harald Welte136e7372016-05-29 10:53:17 +090026
27enum test_fsm_states {
28 ST_NULL = 0,
29 ST_ONE,
30 ST_TWO,
31};
32
33enum test_fsm_evt {
34 EV_A,
35 EV_B,
36};
37
Stefan Sperling888dc7d2018-02-26 19:17:02 +010038static const struct value_string test_fsm_event_names[] = {
39 OSMO_VALUE_STRING(EV_A),
40 OSMO_VALUE_STRING(EV_B),
41 { 0, NULL }
42};
43
Harald Welte136e7372016-05-29 10:53:17 +090044static void test_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data)
45{
46 switch (event) {
47 case EV_A:
48 OSMO_ASSERT(data == (void *) 23);
49 osmo_fsm_inst_state_chg(fi, ST_ONE, 0, 0);
50 break;
51 default:
52 OSMO_ASSERT(0);
53 break;
54 }
55}
56
57static void test_fsm_one(struct osmo_fsm_inst *fi, uint32_t event, void *data)
58{
59 switch (event) {
60 case EV_B:
61 OSMO_ASSERT(data == (void *) 42);
62 osmo_fsm_inst_state_chg(fi,ST_TWO, 1, 2342);
63 break;
64 default:
65 OSMO_ASSERT(0);
66 break;
67 }
68}
69
Neels Hofmeyrd8f175c2018-04-09 00:42:22 +020070static bool main_loop_run = true;
71
Neels Hofmeyrcba8eb92016-12-23 04:32:09 +010072static int test_fsm_tmr_cb(struct osmo_fsm_inst *fi)
Harald Welte136e7372016-05-29 10:53:17 +090073{
74 OSMO_ASSERT(fi->T == 2342);
75 OSMO_ASSERT(fi->state == ST_TWO);
76 LOGP(DMAIN, LOGL_INFO, "Timer\n");
77
Neels Hofmeyrd8f175c2018-04-09 00:42:22 +020078 main_loop_run = false;
79
80 return 0;
Harald Welte136e7372016-05-29 10:53:17 +090081}
82
83static struct osmo_fsm_state test_fsm_states[] = {
84 [ST_NULL] = {
85 .in_event_mask = (1 << EV_A),
86 .out_state_mask = (1 << ST_ONE),
87 .name = "NULL",
88 .action = test_fsm_null,
89 },
90 [ST_ONE]= {
91 .in_event_mask = (1 << EV_B),
92 .out_state_mask = (1 << ST_TWO),
93 .name = "ONE",
94 .action= test_fsm_one,
95 },
96 [ST_TWO]= {
97 .in_event_mask = 0,
98 .name = "TWO",
99 .action = NULL,
100 },
101};
102
103static struct osmo_fsm fsm = {
Harald Welte31c0fef2017-04-16 17:26:30 +0200104 .name = "Test_FSM",
Harald Welte136e7372016-05-29 10:53:17 +0900105 .states = test_fsm_states,
106 .num_states = ARRAY_SIZE(test_fsm_states),
107 .log_subsys = DMAIN,
Stefan Sperling888dc7d2018-02-26 19:17:02 +0100108 .event_names = test_fsm_event_names,
Harald Welte136e7372016-05-29 10:53:17 +0900109};
110
Harald Welte31c0fef2017-04-16 17:26:30 +0200111static struct ctrl_handle *g_ctrl;
112
113static struct ctrl_cmd *exec_ctrl_cmd(const char *cmdstr)
114{
115 struct ctrl_cmd *cmd;
Vadim Yanitskiy35b54d12017-05-14 20:38:44 +0300116
117 cmd = ctrl_cmd_exec_from_string(g_ctrl, cmdstr);
Harald Welte31c0fef2017-04-16 17:26:30 +0200118 OSMO_ASSERT(cmd);
Vadim Yanitskiy35b54d12017-05-14 20:38:44 +0300119
Harald Welte31c0fef2017-04-16 17:26:30 +0200120 return cmd;
121}
122
123static void assert_cmd_reply(const char *cmdstr, const char *expres)
124{
125 struct ctrl_cmd *cmd;
126
127 cmd = exec_ctrl_cmd(cmdstr);
Neels Hofmeyr975ee6b2018-04-09 00:42:12 +0200128 if (safe_strcmp(cmd->reply, expres)) {
Harald Welte31c0fef2017-04-16 17:26:30 +0200129 fprintf(stderr, "Reply '%s' doesn't match expected '%s'\n", cmd->reply, expres);
130 OSMO_ASSERT(0);
131 }
132 talloc_free(cmd);
133}
134
Max3de97e12016-11-02 10:37:58 +0100135static struct osmo_fsm_inst *foo(void)
Harald Welte136e7372016-05-29 10:53:17 +0900136{
137 struct osmo_fsm_inst *fi;
Harald Welte31c0fef2017-04-16 17:26:30 +0200138 struct ctrl_cmd *cmd;
Harald Welte136e7372016-05-29 10:53:17 +0900139
140 LOGP(DMAIN, LOGL_INFO, "Checking FSM allocation\n");
Harald Welte4585e672017-04-16 17:23:56 +0200141 fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, "my_id");
Harald Welte136e7372016-05-29 10:53:17 +0900142 OSMO_ASSERT(fi);
143 OSMO_ASSERT(fi->fsm == &fsm);
144 OSMO_ASSERT(!strncmp(osmo_fsm_inst_name(fi), fsm.name, strlen(fsm.name)));
145 OSMO_ASSERT(fi->state == ST_NULL);
146 OSMO_ASSERT(fi->log_level == LOGL_DEBUG);
Harald Welte31c0fef2017-04-16 17:26:30 +0200147 assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL");
148 assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.timer", "0,0,0");
Harald Welte136e7372016-05-29 10:53:17 +0900149
150 /* Try invalid state transition */
151 osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42);
152 OSMO_ASSERT(fi->state == ST_NULL);
Harald Welte31c0fef2017-04-16 17:26:30 +0200153 assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "NULL");
154
Harald Welte136e7372016-05-29 10:53:17 +0900155
156 /* Legitimate state transition */
157 osmo_fsm_inst_dispatch(fi, EV_A, (void *) 23);
158 OSMO_ASSERT(fi->state == ST_ONE);
Harald Welte31c0fef2017-04-16 17:26:30 +0200159 assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "ONE");
Harald Welte136e7372016-05-29 10:53:17 +0900160
161 /* Legitimate transition with timer */
162 fsm.timer_cb = test_fsm_tmr_cb;
163 osmo_fsm_inst_dispatch(fi, EV_B, (void *) 42);
164 OSMO_ASSERT(fi->state == ST_TWO);
Harald Welte31c0fef2017-04-16 17:26:30 +0200165 assert_cmd_reply("GET 1 fsm.Test_FSM.id.my_id.state", "TWO");
Harald Welte136e7372016-05-29 10:53:17 +0900166
Harald Welte31c0fef2017-04-16 17:26:30 +0200167 cmd = exec_ctrl_cmd("GET 2 fsm.Test_FSM.id.my_id.dump");
168 const char *exp = "'Test_FSM(my_id)','my_id','DEBUG','TWO',2342,timeout_sec=";
169 OSMO_ASSERT(!strncmp(cmd->reply, exp, strlen(exp)));
170 talloc_free(cmd);
Harald Welte136e7372016-05-29 10:53:17 +0900171
Max3de97e12016-11-02 10:37:58 +0100172 return fi;
Harald Welte136e7372016-05-29 10:53:17 +0900173}
174
Harald Weltee61d4592022-11-03 11:05:58 +0100175static void test_id_api(void)
Neels Hofmeyr975ee6b2018-04-09 00:42:12 +0200176{
177 struct osmo_fsm_inst *fi;
178
179 fprintf(stderr, "\n--- %s()\n", __func__);
180
181/* Assert the instance has this name and can be looked up by it */
182#define assert_name(expected_name) \
183do { \
184 const char *name = osmo_fsm_inst_name(fi); \
185 fprintf(stderr, " osmo_fsm_inst_name() == %s\n", osmo_quote_str(name, -1)); \
186 if (safe_strcmp(name, expected_name)) { \
187 fprintf(stderr, " ERROR: expected %s\n", osmo_quote_str(expected_name, -1)); \
188 OSMO_ASSERT(false); \
189 } \
190 OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, expected_name) == fi); \
191 fprintf(stderr, " osmo_fsm_inst_find_by_name(%s) == fi\n", osmo_quote_str(expected_name, -1)); \
192} while(0)
193
194/* Assert the instance can be looked up by this id string */
195#define assert_id(expected_id) \
196do { \
197 OSMO_ASSERT(osmo_fsm_inst_find_by_id(&fsm, expected_id) == fi); \
198 fprintf(stderr, " osmo_fsm_inst_find_by_id(%s) == fi\n", osmo_quote_str(expected_id, -1)); \
199} while(0)
200
201/* Update the id, assert the proper rc, and expect a resulting fsm inst name + lookup */
202#define test_id(new_id, expect_rc, expect_name_suffix) do { \
203 int rc; \
204 fprintf(stderr, "osmo_fsm_inst_update_id(%s)\n", osmo_quote_str(new_id, -1)); \
205 rc = osmo_fsm_inst_update_id(fi, new_id); \
206 fprintf(stderr, " rc == %d", rc); \
207 if (rc == (expect_rc)) \
208 fprintf(stderr, ", ok\n"); \
209 else { \
210 fprintf(stderr, ", ERROR: expected rc == %d\n", expect_rc); \
211 OSMO_ASSERT(rc == expect_rc); \
212 } \
213 assert_name("Test_FSM" expect_name_suffix); \
214 }while (0)
215
216/* Successfully set a new id, along with name and id lookup assertions */
217#define change_id(new_id) \
218 test_id(new_id, 0, "(" new_id ")"); \
219 assert_id(new_id)
220
221 /* allocate FSM instance without id, there should be a name without id */
222 fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
223 OSMO_ASSERT(fi);
Neels Hofmeyr975ee6b2018-04-09 00:42:12 +0200224 assert_name("Test_FSM");
Neels Hofmeyr975ee6b2018-04-09 00:42:12 +0200225
226 change_id("my_id");
227 change_id("another_id");
228
229 test_id(NULL, 0, "");
230 /* clear already cleared id */
231 test_id(NULL, 0, "");
232
233 change_id("arbitrary_id");
234
235 /* clear id by empty string doesn't work */
236 test_id("", -EINVAL, "(arbitrary_id)");
237
238 test_id("invalid.id", -EINVAL, "(arbitrary_id)");
239
Neels Hofmeyra64c45a2018-03-31 16:34:49 +0200240 fprintf(stderr, "--- id format tests...\n");
241/* Update the id, assert the proper rc, and expect a resulting fsm inst name + lookup */
242#define test_id_f(expect_rc, expect_name_suffix, new_id_fmt, args...) do { \
243 int rc; \
244 fprintf(stderr, "osmo_fsm_inst_update_id_f(%s, " #args ")\n", \
245 osmo_quote_str(new_id_fmt, -1)); \
246 rc = osmo_fsm_inst_update_id_f(fi, new_id_fmt, ## args); \
247 fprintf(stderr, " rc == %d", rc); \
248 if (rc == (expect_rc)) \
249 fprintf(stderr, ", ok\n"); \
250 else { \
251 fprintf(stderr, ", ERROR: expected rc == %d\n", expect_rc); \
252 OSMO_ASSERT(rc == expect_rc); \
253 } \
254 assert_name("Test_FSM" expect_name_suffix); \
255 }while (0)
256
257 test_id_f(-EINVAL, "(arbitrary_id)", "format%cid", '.');
258 test_id_f(-EINVAL, "(arbitrary_id)", "%s", "");
259 test_id_f(0, "(format23id42)", "format%xid%d", 0x23, 42);
260 test_id_f(0, "", NULL);
261 test_id_f(0, "", NULL);
262 test_id_f(0, "(arbitrary_id)", "%s%c%s", "arbitrary", '_', "id");
263
Neels Hofmeyr975ee6b2018-04-09 00:42:12 +0200264 fprintf(stderr, "\n--- %s() done\n\n", __func__);
265
266 osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
267}
268
Neels Hofmeyr407df022018-05-25 18:20:06 +0200269const struct timeval fake_time_start_time = { 123, 456 };
270
271#define fake_time_passes(secs, usecs) do \
272{ \
273 struct timeval diff; \
274 osmo_gettimeofday_override_add(secs, usecs); \
275 osmo_clock_override_add(CLOCK_MONOTONIC, secs, usecs * 1000); \
276 timersub(&osmo_gettimeofday_override_time, &fake_time_start_time, &diff); \
277 fprintf(stderr, "Total time passed: %d.%06d s\n", \
278 (int)diff.tv_sec, (int)diff.tv_usec); \
279 osmo_timers_prepare(); \
280 osmo_timers_update(); \
281} while (0)
282
Harald Weltee61d4592022-11-03 11:05:58 +0100283void fake_time_start(void)
Neels Hofmeyr407df022018-05-25 18:20:06 +0200284{
285 struct timespec *clock_override;
286
287 osmo_gettimeofday_override_time = fake_time_start_time;
288 osmo_gettimeofday_override = true;
289 clock_override = osmo_clock_override_gettimespec(CLOCK_MONOTONIC);
290 OSMO_ASSERT(clock_override);
291 clock_override->tv_sec = fake_time_start_time.tv_sec;
292 clock_override->tv_nsec = fake_time_start_time.tv_usec * 1000;
293 osmo_clock_override_enable(CLOCK_MONOTONIC, true);
294 fake_time_passes(0, 0);
295}
296
297static int timeout_fired = 0;
298static int timer_cb(struct osmo_fsm_inst *fi)
299{
300 timeout_fired = fi->T;
301 return 0;
302}
303
Harald Weltee61d4592022-11-03 11:05:58 +0100304static void test_state_chg_keep_timer(void)
Neels Hofmeyr407df022018-05-25 18:20:06 +0200305{
306 struct osmo_fsm_inst *fi;
307
308 fprintf(stderr, "\n--- %s()\n", __func__);
309
310 fsm.timer_cb = timer_cb;
311
312 /* Test that no timer remains no timer */
313 fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
314 OSMO_ASSERT(fi);
315
316 osmo_fsm_inst_state_chg(fi, ST_ONE, 0, 0);
317 timeout_fired = -1;
318
319 osmo_fsm_inst_state_chg_keep_timer(fi, ST_TWO);
320
321 OSMO_ASSERT(timeout_fired == -1);
322 OSMO_ASSERT(fi->T == 0);
323
324 osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
325
326 /* Test that a set time continues with exact precision */
327 fake_time_start();
328 fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
329 OSMO_ASSERT(fi);
330
331 osmo_fsm_inst_state_chg(fi, ST_ONE, 10, 10);
332
333 timeout_fired = -1;
334
335 fake_time_passes(2, 342);
336 osmo_fsm_inst_state_chg_keep_timer(fi, ST_TWO);
337
338 fake_time_passes(0, 0);
339 OSMO_ASSERT(timeout_fired == -1);
340
341 fake_time_passes(7, 1000000 - 342 - 1);
342 OSMO_ASSERT(timeout_fired == -1);
343
344 fake_time_passes(0, 1);
345 OSMO_ASSERT(timeout_fired == 10);
346
347 osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
348
349 fprintf(stderr, "--- %s() done\n", __func__);
350}
351
Harald Weltee61d4592022-11-03 11:05:58 +0100352static void test_state_chg_T(void)
Neels Hofmeyrbd5a1dc2019-01-28 15:38:09 +0100353{
354 struct osmo_fsm_inst *fi;
355
356 fprintf(stderr, "\n--- %s()\n", __func__);
357
358 fsm.timer_cb = NULL;
359
360 /* Test setting to timeout_secs = 0, T = 0 */
361 fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
362 OSMO_ASSERT(fi);
363
364 osmo_fsm_inst_state_chg(fi, ST_ONE, 23, 42);
365 printf("T = %d\n", fi->T);
366 OSMO_ASSERT(fi->T == 42);
367 osmo_fsm_inst_state_chg(fi, ST_TWO, 0, 0);
368 printf("T = %d\n", fi->T);
369 OSMO_ASSERT(fi->T == 0);
370
371 osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
372
373 /* Test setting to timeout_secs = 0, T != 0 */
374 fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
375 OSMO_ASSERT(fi);
376
377 osmo_fsm_inst_state_chg(fi, ST_ONE, 23, 42);
378 printf("T = %d\n", fi->T);
379 OSMO_ASSERT(fi->T == 42);
380 osmo_fsm_inst_state_chg(fi, ST_TWO, 0, 11);
381 printf("T = %d\n", fi->T);
382 OSMO_ASSERT(fi->T == 11);
383
384 osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
385
386 fprintf(stderr, "--- %s() done\n", __func__);
387}
388
Vadim Yanitskiyd2964a92022-07-19 06:08:42 +0700389/* Test setting a state timeout with second granularity */
390static void test_state_chg_Ts(void)
391{
392 struct osmo_fsm_inst *fi;
393
394 fprintf(stderr, "\n--- %s()\n", __func__);
395
396 fsm.timer_cb = &timer_cb;
397 timeout_fired = -1;
398 fake_time_start();
399
400 fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
401 OSMO_ASSERT(fi);
402
403 osmo_fsm_inst_state_chg(fi, ST_ONE, 8, 4242);
404 OSMO_ASSERT(timeout_fired == -1);
405
406 fake_time_passes(3, 0); /* +3s */
407 OSMO_ASSERT(timeout_fired == -1);
408
409 fake_time_passes(2, 500000); /* +2.5s */
410 OSMO_ASSERT(timeout_fired == -1);
411
412 fake_time_passes(2, 500000); /* +2.5s */
413 OSMO_ASSERT(timeout_fired == 4242);
414
415 osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
416
417 fprintf(stderr, "--- %s() done\n", __func__);
418}
419
420/* Test setting a state timeout with millisecond granularity */
421static void test_state_chg_Tms(void)
422{
423 struct osmo_fsm_inst *fi;
424
425 fprintf(stderr, "\n--- %s()\n", __func__);
426
427 fsm.timer_cb = &timer_cb;
428 timeout_fired = -1;
429 fake_time_start();
430
431 fi = osmo_fsm_inst_alloc(&fsm, g_ctx, NULL, LOGL_DEBUG, NULL);
432 OSMO_ASSERT(fi);
433
434 osmo_fsm_inst_state_chg_ms(fi, ST_ONE, 1337, 4242); /* 1s 337ms */
435 OSMO_ASSERT(timeout_fired == -1);
436
437 fake_time_passes(0, 500000); /* +500ms, 500ms total */
438 OSMO_ASSERT(timeout_fired == -1);
439
440 fake_time_passes(0, 250000); /* +250ms, 750ms total */
441 OSMO_ASSERT(timeout_fired == -1);
442
443 fake_time_passes(0, 350000); /* +350ms, 1s 100ms total */
Vadim Yanitskiy76bdbd42022-07-19 06:20:55 +0700444 OSMO_ASSERT(timeout_fired == -1);
Vadim Yanitskiyd2964a92022-07-19 06:08:42 +0700445
446 fake_time_passes(0, 200000); /* +200ms, 1s 300ms total */
Vadim Yanitskiy76bdbd42022-07-19 06:20:55 +0700447 OSMO_ASSERT(timeout_fired == -1);
Vadim Yanitskiyd2964a92022-07-19 06:08:42 +0700448
449 fake_time_passes(0, 37000); /* +37ms, 1s 337ms total */
Vadim Yanitskiy76bdbd42022-07-19 06:20:55 +0700450 OSMO_ASSERT(timeout_fired == 4242);
Vadim Yanitskiyd2964a92022-07-19 06:08:42 +0700451
452 osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REQUEST, NULL);
453
454 fprintf(stderr, "--- %s() done\n", __func__);
455}
456
Harald Welte136e7372016-05-29 10:53:17 +0900457static const struct log_info_cat default_categories[] = {
458 [DMAIN] = {
459 .name = "DMAIN",
460 .description = "Main",
461 .enabled = 1, .loglevel = LOGL_DEBUG,
462 },
463};
464
465static const struct log_info log_info = {
466 .cat = default_categories,
467 .num_cat = ARRAY_SIZE(default_categories),
468};
469
470int main(int argc, char **argv)
471{
472 struct log_target *stderr_target;
Max3de97e12016-11-02 10:37:58 +0100473 struct osmo_fsm_inst *finst;
Harald Welte136e7372016-05-29 10:53:17 +0900474
475 osmo_fsm_log_addr(false);
476
Neels Hofmeyr050f2d32018-05-31 15:30:15 +0200477 /* Using fake time to get deterministic timeout logging */
478 osmo_fsm_log_timeouts(true);
479
Harald Welte136e7372016-05-29 10:53:17 +0900480 log_init(&log_info, NULL);
481 stderr_target = log_target_create_stderr();
482 log_add_target(stderr_target);
Pau Espin Pedrol01e0d3e2021-02-18 19:25:44 +0100483 log_set_print_filename2(stderr_target, LOG_FILENAME_NONE);
Pau Espin Pedroleb028fa2020-07-20 16:46:54 +0200484 log_set_use_color(stderr_target, 0);
Pau Espin Pedrol690b6612021-02-18 19:10:28 +0100485 log_set_print_category(stderr_target, 0);
486 log_set_print_category_hex(stderr_target, 0);
Harald Welte31c0fef2017-04-16 17:26:30 +0200487 g_ctrl = ctrl_handle_alloc(NULL, NULL, NULL);
Harald Welte136e7372016-05-29 10:53:17 +0900488
Harald Welte4585e672017-04-16 17:23:56 +0200489 g_ctx = NULL;
490 OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == NULL);
Harald Welteae5016f2019-12-01 13:38:20 +0100491 OSMO_ASSERT(osmo_fsm_register(&fsm) == 0);
Harald Welte4585e672017-04-16 17:23:56 +0200492 OSMO_ASSERT(osmo_fsm_find_by_name(fsm.name) == &fsm);
493
494 OSMO_ASSERT(osmo_fsm_inst_find_by_name(&fsm, "my_id") == NULL);
Max3de97e12016-11-02 10:37:58 +0100495 finst = foo();
Harald Welte136e7372016-05-29 10:53:17 +0900496
Neels Hofmeyrd8f175c2018-04-09 00:42:22 +0200497 while (main_loop_run) {
Harald Welte136e7372016-05-29 10:53:17 +0900498 osmo_select_main(0);
499 }
Max3de97e12016-11-02 10:37:58 +0100500 osmo_fsm_inst_free(finst);
Neels Hofmeyr975ee6b2018-04-09 00:42:12 +0200501
502 test_id_api();
Neels Hofmeyr407df022018-05-25 18:20:06 +0200503 test_state_chg_keep_timer();
Neels Hofmeyrbd5a1dc2019-01-28 15:38:09 +0100504 test_state_chg_T();
Vadim Yanitskiyd2964a92022-07-19 06:08:42 +0700505 test_state_chg_Ts();
506 test_state_chg_Tms();
Neels Hofmeyr975ee6b2018-04-09 00:42:12 +0200507
Max8b25a3f2016-11-01 11:02:17 +0100508 osmo_fsm_unregister(&fsm);
Harald Welte136e7372016-05-29 10:53:17 +0900509 exit(0);
510}