test_scheduler.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /*********************************************************************
  2. * _ _ _
  3. * _ __ | |_ _ | | __ _ | |__ ___
  4. * | '__|| __|(_)| | / _` || '_ \ / __|
  5. * | | | |_ _ | || (_| || |_) |\__ \
  6. * |_| \__|(_)|_| \__,_||_.__/ |___/
  7. *
  8. * www.rt-labs.com
  9. * Copyright 2018 rt-labs AB, Sweden.
  10. *
  11. * This software is dual-licensed under GPLv3 and a commercial
  12. * license. See the file LICENSE.md distributed with this software for
  13. * full license information.
  14. ********************************************************************/
  15. #include "utils_for_testing.h"
  16. #include "mocks.h"
  17. #include "pf_includes.h"
  18. #include <gtest/gtest.h>
  19. class SchedulerTest : public PnetIntegrationTest
  20. {
  21. };
  22. class SchedulerUnitTest : public PnetUnitTest
  23. {
  24. };
  25. void test_scheduler_callback_a (pnet_t * net, void * arg, uint32_t current_time)
  26. {
  27. app_data_for_testing_t * appdata = (app_data_for_testing_t *)arg;
  28. appdata->call_counters.scheduler_callback_a_calls += 1;
  29. pf_scheduler_reset_handle (&appdata->scheduler_handle_a);
  30. }
  31. void test_scheduler_callback_b (pnet_t * net, void * arg, uint32_t current_time)
  32. {
  33. app_data_for_testing_t * appdata = (app_data_for_testing_t *)arg;
  34. appdata->call_counters.scheduler_callback_b_calls += 1;
  35. pf_scheduler_reset_handle (&appdata->scheduler_handle_b);
  36. }
  37. TEST_F (SchedulerUnitTest, SchedulerSanitizeDelayTest)
  38. {
  39. const uint32_t cycle_len = 1000;
  40. const uint32_t margin = 10u;
  41. uint32_t result = 0;
  42. uint32_t input_delay = 0;
  43. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  44. ASSERT_NEAR (result, 500, margin);
  45. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  46. ASSERT_NEAR (result, 1000, margin);
  47. input_delay = 500;
  48. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  49. ASSERT_NEAR (result, 500, margin);
  50. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  51. ASSERT_NEAR (result, 1000, margin);
  52. input_delay = 1000;
  53. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  54. ASSERT_NEAR (result, 500, margin);
  55. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  56. ASSERT_NEAR (result, 1000, margin);
  57. input_delay = 1400;
  58. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  59. ASSERT_NEAR (result, 500, margin);
  60. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  61. ASSERT_NEAR (result, 1000, margin);
  62. input_delay = 1600;
  63. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  64. ASSERT_NEAR (result, 1500, margin);
  65. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  66. ASSERT_NEAR (result, 2000, margin);
  67. input_delay = 2000;
  68. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  69. ASSERT_NEAR (result, 1500, margin);
  70. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  71. ASSERT_NEAR (result, 2000, margin);
  72. input_delay = 2400;
  73. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  74. ASSERT_NEAR (result, 1500, margin);
  75. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  76. ASSERT_NEAR (result, 2000, margin);
  77. input_delay = 2600;
  78. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  79. ASSERT_NEAR (result, 2500, margin);
  80. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  81. ASSERT_NEAR (result, 3000, margin);
  82. input_delay = 3000;
  83. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  84. ASSERT_NEAR (result, 2500, margin);
  85. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  86. ASSERT_NEAR (result, 3000, margin);
  87. input_delay = 3400;
  88. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  89. ASSERT_NEAR (result, 2500, margin);
  90. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  91. ASSERT_NEAR (result, 3000, margin);
  92. input_delay = 1000000; /* 1 second */
  93. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  94. ASSERT_NEAR (result, 999500u, margin);
  95. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  96. ASSERT_NEAR (result, 1000000, margin);
  97. input_delay = 10000000; /* 10 seconds */
  98. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  99. ASSERT_NEAR (result, 9999500u, margin);
  100. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  101. ASSERT_NEAR (result, 10000000, margin);
  102. input_delay = 1000000000; /* Unrealisticly far in the future (1000 s) */
  103. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  104. ASSERT_NEAR (result, 500, margin);
  105. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  106. ASSERT_NEAR (result, 1000, margin);
  107. input_delay = (uint32_t)(-4); /* Next execution has already passed */
  108. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, true);
  109. ASSERT_NEAR (result, 500, margin);
  110. result = pf_scheduler_sanitize_delay (input_delay, cycle_len, false);
  111. ASSERT_NEAR (result, 1000, margin);
  112. }
  113. TEST_F (SchedulerTest, SchedulerAddRemove)
  114. {
  115. int ret;
  116. pf_scheduler_handle_t * p_a = &appdata.scheduler_handle_a;
  117. pf_scheduler_handle_t * p_b = &appdata.scheduler_handle_b;
  118. const char scheduler_name_a[] = "testhandle_a";
  119. const char scheduler_name_b[] = "testhandle_b";
  120. const char * resulting_name = NULL;
  121. uint32_t value;
  122. bool is_scheduled;
  123. pf_scheduler_init (net, TEST_TICK_INTERVAL_US);
  124. run_stack (TEST_SCHEDULER_RUNTIME);
  125. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 0);
  126. /* Initialize and verify handle */
  127. pf_scheduler_init_handle (p_a, scheduler_name_a);
  128. pf_scheduler_init_handle (p_b, scheduler_name_b);
  129. resulting_name = pf_scheduler_get_name (p_a);
  130. EXPECT_EQ (strcmp (resulting_name, scheduler_name_a), 0);
  131. resulting_name = pf_scheduler_get_name (p_b);
  132. EXPECT_EQ (strcmp (resulting_name, scheduler_name_b), 0);
  133. value = pf_scheduler_get_value (p_a);
  134. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  135. value = pf_scheduler_get_value (p_b);
  136. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  137. is_scheduled = pf_scheduler_is_running (p_a);
  138. EXPECT_FALSE (is_scheduled);
  139. is_scheduled = pf_scheduler_is_running (p_b);
  140. EXPECT_FALSE (is_scheduled);
  141. /* Reset non-running handle */
  142. pf_scheduler_reset_handle (p_a);
  143. resulting_name = pf_scheduler_get_name (p_a);
  144. EXPECT_EQ (strcmp (resulting_name, scheduler_name_a), 0);
  145. value = pf_scheduler_get_value (p_a);
  146. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  147. is_scheduled = pf_scheduler_is_running (p_a);
  148. EXPECT_FALSE (is_scheduled);
  149. /* Schedule callback A */
  150. ret = pf_scheduler_add (
  151. net,
  152. TEST_SCHEDULER_CALLBACK_DELAY,
  153. test_scheduler_callback_a,
  154. &appdata,
  155. p_a);
  156. EXPECT_EQ (ret, 0);
  157. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 0);
  158. resulting_name = pf_scheduler_get_name (p_a);
  159. EXPECT_EQ (strcmp (resulting_name, scheduler_name_a), 0);
  160. value = pf_scheduler_get_value (p_a);
  161. EXPECT_EQ (value, 1UL); /* Implementation detail */
  162. is_scheduled = pf_scheduler_is_running (p_a);
  163. EXPECT_TRUE (is_scheduled);
  164. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 0);
  165. resulting_name = pf_scheduler_get_name (p_b);
  166. EXPECT_EQ (strcmp (resulting_name, scheduler_name_b), 0);
  167. value = pf_scheduler_get_value (p_b);
  168. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  169. is_scheduled = pf_scheduler_is_running (p_b);
  170. EXPECT_FALSE (is_scheduled);
  171. /* Verify that it not is triggered */
  172. run_stack (TEST_TICK_INTERVAL_US);
  173. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 0);
  174. value = pf_scheduler_get_value (p_a);
  175. EXPECT_EQ (value, 1UL); /* Implementation detail */
  176. is_scheduled = pf_scheduler_is_running (p_a);
  177. EXPECT_TRUE (is_scheduled);
  178. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 0);
  179. resulting_name = pf_scheduler_get_name (p_b);
  180. EXPECT_EQ (strcmp (resulting_name, scheduler_name_b), 0);
  181. value = pf_scheduler_get_value (p_b);
  182. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  183. is_scheduled = pf_scheduler_is_running (p_b);
  184. EXPECT_FALSE (is_scheduled);
  185. /* Verify that callback A is triggered */
  186. run_stack (TEST_SCHEDULER_RUNTIME);
  187. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 1);
  188. value = pf_scheduler_get_value (p_a);
  189. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  190. is_scheduled = pf_scheduler_is_running (p_a);
  191. EXPECT_FALSE (is_scheduled);
  192. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 0);
  193. resulting_name = pf_scheduler_get_name (p_b);
  194. EXPECT_EQ (strcmp (resulting_name, scheduler_name_b), 0);
  195. value = pf_scheduler_get_value (p_b);
  196. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  197. is_scheduled = pf_scheduler_is_running (p_b);
  198. EXPECT_FALSE (is_scheduled);
  199. /* Schedule both callbacks */
  200. ret = pf_scheduler_add (
  201. net,
  202. TEST_SCHEDULER_CALLBACK_DELAY,
  203. test_scheduler_callback_a,
  204. &appdata,
  205. p_a);
  206. EXPECT_EQ (ret, 0);
  207. ret = pf_scheduler_add (
  208. net,
  209. TEST_SCHEDULER_RUNTIME + TEST_SCHEDULER_CALLBACK_DELAY,
  210. test_scheduler_callback_b,
  211. &appdata,
  212. p_b);
  213. EXPECT_EQ (ret, 0);
  214. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 1);
  215. resulting_name = pf_scheduler_get_name (p_a);
  216. EXPECT_EQ (strcmp (resulting_name, scheduler_name_a), 0);
  217. value = pf_scheduler_get_value (p_a);
  218. EXPECT_EQ (value, 1UL); /* Implementation detail */
  219. is_scheduled = pf_scheduler_is_running (p_a);
  220. EXPECT_TRUE (is_scheduled);
  221. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 0);
  222. resulting_name = pf_scheduler_get_name (p_b);
  223. EXPECT_EQ (strcmp (resulting_name, scheduler_name_b), 0);
  224. value = pf_scheduler_get_value (p_b);
  225. EXPECT_EQ (value, 2UL); /* Implementation detail */
  226. is_scheduled = pf_scheduler_is_running (p_b);
  227. EXPECT_TRUE (is_scheduled);
  228. /* Verify that they not are triggered */
  229. run_stack (TEST_TICK_INTERVAL_US);
  230. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 1);
  231. value = pf_scheduler_get_value (p_a);
  232. EXPECT_EQ (value, 1UL); /* Implementation detail */
  233. is_scheduled = pf_scheduler_is_running (p_a);
  234. EXPECT_TRUE (is_scheduled);
  235. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 0);
  236. resulting_name = pf_scheduler_get_name (p_b);
  237. EXPECT_EQ (strcmp (resulting_name, scheduler_name_b), 0);
  238. value = pf_scheduler_get_value (p_b);
  239. EXPECT_EQ (value, 2UL); /* Implementation detail */
  240. is_scheduled = pf_scheduler_is_running (p_b);
  241. EXPECT_TRUE (is_scheduled);
  242. /* Verify that callback A (but not B) is triggered */
  243. run_stack (TEST_SCHEDULER_RUNTIME);
  244. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  245. value = pf_scheduler_get_value (p_a);
  246. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  247. is_scheduled = pf_scheduler_is_running (p_a);
  248. EXPECT_FALSE (is_scheduled);
  249. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 0);
  250. resulting_name = pf_scheduler_get_name (p_b);
  251. EXPECT_EQ (strcmp (resulting_name, scheduler_name_b), 0);
  252. value = pf_scheduler_get_value (p_b);
  253. EXPECT_EQ (value, 2UL); /* Implementation detail */
  254. is_scheduled = pf_scheduler_is_running (p_b);
  255. EXPECT_TRUE (is_scheduled);
  256. /* Verify that both callbacks have been triggered */
  257. run_stack (TEST_SCHEDULER_RUNTIME);
  258. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  259. value = pf_scheduler_get_value (p_a);
  260. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  261. is_scheduled = pf_scheduler_is_running (p_a);
  262. EXPECT_FALSE (is_scheduled);
  263. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  264. resulting_name = pf_scheduler_get_name (p_b);
  265. EXPECT_EQ (strcmp (resulting_name, scheduler_name_b), 0);
  266. value = pf_scheduler_get_value (p_b);
  267. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  268. is_scheduled = pf_scheduler_is_running (p_b);
  269. EXPECT_FALSE (is_scheduled);
  270. /* Remove non-scheduled event */
  271. run_stack (TEST_SCHEDULER_RUNTIME);
  272. pf_scheduler_remove_if_running (net, p_a);
  273. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  274. value = pf_scheduler_get_value (p_a);
  275. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  276. is_scheduled = pf_scheduler_is_running (p_a);
  277. EXPECT_FALSE (is_scheduled);
  278. pf_scheduler_remove (net, p_a); /* Will log error message */
  279. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  280. value = pf_scheduler_get_value (p_a);
  281. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  282. is_scheduled = pf_scheduler_is_running (p_a);
  283. EXPECT_FALSE (is_scheduled);
  284. /* Remove scheduled event */
  285. run_stack (TEST_SCHEDULER_RUNTIME);
  286. ret = pf_scheduler_add (
  287. net,
  288. TEST_SCHEDULER_CALLBACK_DELAY,
  289. test_scheduler_callback_a,
  290. &appdata,
  291. p_a);
  292. EXPECT_EQ (ret, 0);
  293. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  294. value = pf_scheduler_get_value (p_a);
  295. EXPECT_EQ (value, 2UL); /* Implementation detail */
  296. is_scheduled = pf_scheduler_is_running (p_a);
  297. EXPECT_TRUE (is_scheduled);
  298. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  299. value = pf_scheduler_get_value (p_b);
  300. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  301. is_scheduled = pf_scheduler_is_running (p_b);
  302. EXPECT_FALSE (is_scheduled);
  303. run_stack (TEST_TICK_INTERVAL_US);
  304. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  305. value = pf_scheduler_get_value (p_a);
  306. EXPECT_EQ (value, 2UL); /* Implementation detail */
  307. is_scheduled = pf_scheduler_is_running (p_a);
  308. EXPECT_TRUE (is_scheduled);
  309. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  310. value = pf_scheduler_get_value (p_b);
  311. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  312. is_scheduled = pf_scheduler_is_running (p_b);
  313. EXPECT_FALSE (is_scheduled);
  314. pf_scheduler_remove (net, p_a);
  315. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  316. value = pf_scheduler_get_value (p_a);
  317. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  318. is_scheduled = pf_scheduler_is_running (p_a);
  319. EXPECT_FALSE (is_scheduled);
  320. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  321. value = pf_scheduler_get_value (p_b);
  322. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  323. is_scheduled = pf_scheduler_is_running (p_b);
  324. EXPECT_FALSE (is_scheduled);
  325. run_stack (TEST_SCHEDULER_RUNTIME);
  326. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  327. value = pf_scheduler_get_value (p_a);
  328. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  329. is_scheduled = pf_scheduler_is_running (p_a);
  330. EXPECT_FALSE (is_scheduled);
  331. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  332. value = pf_scheduler_get_value (p_b);
  333. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  334. is_scheduled = pf_scheduler_is_running (p_b);
  335. EXPECT_FALSE (is_scheduled);
  336. /* Remove scheduled event, using utility function */
  337. run_stack (TEST_SCHEDULER_RUNTIME);
  338. ret = pf_scheduler_add (
  339. net,
  340. TEST_SCHEDULER_CALLBACK_DELAY,
  341. test_scheduler_callback_a,
  342. &appdata,
  343. p_a);
  344. EXPECT_EQ (ret, 0);
  345. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  346. value = pf_scheduler_get_value (p_a);
  347. EXPECT_EQ (value, 2UL); /* Implementation detail */ // TODO
  348. is_scheduled = pf_scheduler_is_running (p_a);
  349. EXPECT_TRUE (is_scheduled);
  350. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  351. value = pf_scheduler_get_value (p_b);
  352. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  353. is_scheduled = pf_scheduler_is_running (p_b);
  354. EXPECT_FALSE (is_scheduled);
  355. run_stack (TEST_TICK_INTERVAL_US);
  356. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  357. value = pf_scheduler_get_value (p_a);
  358. EXPECT_EQ (value, 2UL); /* Implementation detail */
  359. is_scheduled = pf_scheduler_is_running (p_a);
  360. EXPECT_TRUE (is_scheduled);
  361. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  362. value = pf_scheduler_get_value (p_b);
  363. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  364. is_scheduled = pf_scheduler_is_running (p_b);
  365. EXPECT_FALSE (is_scheduled);
  366. pf_scheduler_remove_if_running (net, p_a);
  367. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  368. value = pf_scheduler_get_value (p_a);
  369. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  370. is_scheduled = pf_scheduler_is_running (p_a);
  371. EXPECT_FALSE (is_scheduled);
  372. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  373. value = pf_scheduler_get_value (p_b);
  374. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  375. is_scheduled = pf_scheduler_is_running (p_b);
  376. EXPECT_FALSE (is_scheduled);
  377. run_stack (TEST_SCHEDULER_RUNTIME);
  378. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  379. value = pf_scheduler_get_value (p_a);
  380. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  381. is_scheduled = pf_scheduler_is_running (p_a);
  382. EXPECT_FALSE (is_scheduled);
  383. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  384. value = pf_scheduler_get_value (p_b);
  385. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  386. is_scheduled = pf_scheduler_is_running (p_b);
  387. EXPECT_FALSE (is_scheduled);
  388. /* Schedule and restart */
  389. ret = pf_scheduler_add (
  390. net,
  391. TEST_SCHEDULER_CALLBACK_DELAY,
  392. test_scheduler_callback_a,
  393. &appdata,
  394. p_a);
  395. EXPECT_EQ (ret, 0);
  396. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  397. value = pf_scheduler_get_value (p_a);
  398. EXPECT_EQ (value, 2UL); /* Implementation detail */
  399. is_scheduled = pf_scheduler_is_running (p_a);
  400. EXPECT_TRUE (is_scheduled);
  401. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  402. is_scheduled = pf_scheduler_is_running (p_b);
  403. EXPECT_FALSE (is_scheduled);
  404. run_stack (TEST_TICK_INTERVAL_US);
  405. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  406. value = pf_scheduler_get_value (p_a);
  407. EXPECT_EQ (value, 2UL); /* Implementation detail */
  408. is_scheduled = pf_scheduler_is_running (p_a);
  409. EXPECT_TRUE (is_scheduled);
  410. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  411. is_scheduled = pf_scheduler_is_running (p_b);
  412. EXPECT_FALSE (is_scheduled);
  413. ret = pf_scheduler_restart (
  414. net,
  415. TEST_SCHEDULER_RUNTIME + TEST_SCHEDULER_CALLBACK_DELAY,
  416. test_scheduler_callback_a,
  417. &appdata,
  418. p_a);
  419. run_stack (TEST_SCHEDULER_RUNTIME);
  420. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 2);
  421. value = pf_scheduler_get_value (p_a);
  422. EXPECT_EQ (value, 2UL); /* Implementation detail */
  423. is_scheduled = pf_scheduler_is_running (p_a);
  424. EXPECT_TRUE (is_scheduled);
  425. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  426. is_scheduled = pf_scheduler_is_running (p_b);
  427. EXPECT_FALSE (is_scheduled);
  428. run_stack (TEST_SCHEDULER_RUNTIME);
  429. EXPECT_EQ (appdata.call_counters.scheduler_callback_a_calls, 3);
  430. value = pf_scheduler_get_value (p_a);
  431. EXPECT_EQ (value, UINT32_MAX); /* Implementation detail */
  432. is_scheduled = pf_scheduler_is_running (p_a);
  433. EXPECT_FALSE (is_scheduled);
  434. EXPECT_EQ (appdata.call_counters.scheduler_callback_b_calls, 1);
  435. is_scheduled = pf_scheduler_is_running (p_b);
  436. EXPECT_FALSE (is_scheduled);
  437. }