test_scheduler.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291
  1. /* Copyright (c) 2014-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #include "orconfig.h"
  4. #include <math.h>
  5. #define SCHEDULER_KIST_PRIVATE
  6. #define TOR_CHANNEL_INTERNAL_
  7. #define CHANNEL_PRIVATE_
  8. #include "core/or/or.h"
  9. #include "app/config/config.h"
  10. #include "lib/evloop/compat_libevent.h"
  11. #include "core/or/channel.h"
  12. #include "core/or/channeltls.h"
  13. #include "core/mainloop/connection.h"
  14. #include "feature/nodelist/networkstatus.h"
  15. #define SCHEDULER_PRIVATE_
  16. #include "core/or/scheduler.h"
  17. /* Test suite stuff */
  18. #include "test/test.h"
  19. #include "test/fakechans.h"
  20. /* Shamelessly stolen from compat_libevent.c */
  21. #define V(major, minor, patch) \
  22. (((major) << 24) | ((minor) << 16) | ((patch) << 8))
  23. /******************************************************************************
  24. * Statistical info
  25. *****************************************************************************/
  26. static int scheduler_compare_channels_mock_ctr = 0;
  27. static int scheduler_run_mock_ctr = 0;
  28. /******************************************************************************
  29. * Utility functions and things we need to mock
  30. *****************************************************************************/
  31. static or_options_t mocked_options;
  32. static const or_options_t *
  33. mock_get_options(void)
  34. {
  35. return &mocked_options;
  36. }
  37. static void
  38. cleanup_scheduler_options(void)
  39. {
  40. if (mocked_options.SchedulerTypes_) {
  41. SMARTLIST_FOREACH(mocked_options.SchedulerTypes_, int *, i, tor_free(i));
  42. smartlist_free(mocked_options.SchedulerTypes_);
  43. mocked_options.SchedulerTypes_ = NULL;
  44. }
  45. }
  46. static void
  47. set_scheduler_options(int val)
  48. {
  49. int *type;
  50. if (mocked_options.SchedulerTypes_ == NULL) {
  51. mocked_options.SchedulerTypes_ = smartlist_new();
  52. }
  53. type = tor_malloc_zero(sizeof(int));
  54. *type = val;
  55. smartlist_add(mocked_options.SchedulerTypes_, type);
  56. }
  57. static void
  58. clear_options(void)
  59. {
  60. cleanup_scheduler_options();
  61. memset(&mocked_options, 0, sizeof(mocked_options));
  62. }
  63. static int32_t
  64. mock_vanilla_networkstatus_get_param(
  65. const networkstatus_t *ns, const char *param_name, int32_t default_val,
  66. int32_t min_val, int32_t max_val)
  67. {
  68. (void)ns;
  69. (void)default_val;
  70. (void)min_val;
  71. (void)max_val;
  72. // only support KISTSchedRunInterval right now
  73. tor_assert(strcmp(param_name, "KISTSchedRunInterval")==0);
  74. return 0;
  75. }
  76. static int32_t
  77. mock_kist_networkstatus_get_param(
  78. const networkstatus_t *ns, const char *param_name, int32_t default_val,
  79. int32_t min_val, int32_t max_val)
  80. {
  81. (void)ns;
  82. (void)default_val;
  83. (void)min_val;
  84. (void)max_val;
  85. // only support KISTSchedRunInterval right now
  86. tor_assert(strcmp(param_name, "KISTSchedRunInterval")==0);
  87. return 12;
  88. }
  89. static int
  90. scheduler_compare_channels_mock(const void *c1_v,
  91. const void *c2_v)
  92. {
  93. uintptr_t p1, p2;
  94. p1 = (uintptr_t)(c1_v);
  95. p2 = (uintptr_t)(c2_v);
  96. ++scheduler_compare_channels_mock_ctr;
  97. if (p1 == p2) return 0;
  98. else if (p1 < p2) return 1;
  99. else return -1;
  100. }
  101. static void
  102. scheduler_run_noop_mock(void)
  103. {
  104. ++scheduler_run_mock_ctr;
  105. }
  106. static circuitmux_t *mock_ccm_tgt_1 = NULL;
  107. static circuitmux_t *mock_ccm_tgt_2 = NULL;
  108. static circuitmux_t *mock_cgp_tgt_1 = NULL;
  109. static circuitmux_policy_t *mock_cgp_val_1 = NULL;
  110. static circuitmux_t *mock_cgp_tgt_2 = NULL;
  111. static circuitmux_policy_t *mock_cgp_val_2 = NULL;
  112. static const circuitmux_policy_t *
  113. circuitmux_get_policy_mock(circuitmux_t *cmux)
  114. {
  115. const circuitmux_policy_t *result = NULL;
  116. tt_assert(cmux != NULL);
  117. if (cmux) {
  118. if (cmux == mock_cgp_tgt_1) result = mock_cgp_val_1;
  119. else if (cmux == mock_cgp_tgt_2) result = mock_cgp_val_2;
  120. else result = circuitmux_get_policy__real(cmux);
  121. }
  122. done:
  123. return result;
  124. }
  125. static int
  126. circuitmux_compare_muxes_mock(circuitmux_t *cmux_1,
  127. circuitmux_t *cmux_2)
  128. {
  129. int result = 0;
  130. tt_assert(cmux_1 != NULL);
  131. tt_assert(cmux_2 != NULL);
  132. if (cmux_1 != cmux_2) {
  133. if (cmux_1 == mock_ccm_tgt_1 && cmux_2 == mock_ccm_tgt_2) result = -1;
  134. else if (cmux_1 == mock_ccm_tgt_2 && cmux_2 == mock_ccm_tgt_1) {
  135. result = 1;
  136. } else {
  137. if (cmux_1 == mock_ccm_tgt_1 || cmux_1 == mock_ccm_tgt_2) result = -1;
  138. else if (cmux_2 == mock_ccm_tgt_1 || cmux_2 == mock_ccm_tgt_2) {
  139. result = 1;
  140. } else {
  141. result = circuitmux_compare_muxes__real(cmux_1, cmux_2);
  142. }
  143. }
  144. }
  145. /* else result = 0 always */
  146. done:
  147. return result;
  148. }
  149. typedef struct {
  150. const channel_t *chan;
  151. ssize_t cells;
  152. } flush_mock_channel_t;
  153. static smartlist_t *chans_for_flush_mock = NULL;
  154. static void
  155. channel_flush_some_cells_mock_free_all(void)
  156. {
  157. if (chans_for_flush_mock) {
  158. SMARTLIST_FOREACH_BEGIN(chans_for_flush_mock,
  159. flush_mock_channel_t *,
  160. flush_mock_ch) {
  161. SMARTLIST_DEL_CURRENT(chans_for_flush_mock, flush_mock_ch);
  162. tor_free(flush_mock_ch);
  163. } SMARTLIST_FOREACH_END(flush_mock_ch);
  164. smartlist_free(chans_for_flush_mock);
  165. chans_for_flush_mock = NULL;
  166. }
  167. }
  168. static void
  169. channel_flush_some_cells_mock_set(channel_t *chan, ssize_t num_cells)
  170. {
  171. int found = 0;
  172. if (!chan) return;
  173. if (num_cells <= 0) return;
  174. if (!chans_for_flush_mock) {
  175. chans_for_flush_mock = smartlist_new();
  176. }
  177. SMARTLIST_FOREACH_BEGIN(chans_for_flush_mock,
  178. flush_mock_channel_t *,
  179. flush_mock_ch) {
  180. if (flush_mock_ch != NULL && flush_mock_ch->chan != NULL) {
  181. if (flush_mock_ch->chan == chan) {
  182. /* Found it */
  183. flush_mock_ch->cells = num_cells;
  184. found = 1;
  185. break;
  186. }
  187. } else {
  188. /* That shouldn't be there... */
  189. SMARTLIST_DEL_CURRENT(chans_for_flush_mock, flush_mock_ch);
  190. tor_free(flush_mock_ch);
  191. }
  192. } SMARTLIST_FOREACH_END(flush_mock_ch);
  193. if (! found) {
  194. /* The loop didn't find it */
  195. flush_mock_channel_t *flush_mock_ch;
  196. flush_mock_ch = tor_malloc_zero(sizeof(*flush_mock_ch));
  197. flush_mock_ch->chan = chan;
  198. flush_mock_ch->cells = num_cells;
  199. smartlist_add(chans_for_flush_mock, flush_mock_ch);
  200. }
  201. }
  202. static int
  203. channel_more_to_flush_mock(channel_t *chan)
  204. {
  205. tor_assert(chan);
  206. flush_mock_channel_t *found_mock_ch = NULL;
  207. SMARTLIST_FOREACH_BEGIN(chans_for_flush_mock,
  208. flush_mock_channel_t *,
  209. flush_mock_ch) {
  210. if (flush_mock_ch != NULL && flush_mock_ch->chan != NULL) {
  211. if (flush_mock_ch->chan == chan) {
  212. /* Found it */
  213. found_mock_ch = flush_mock_ch;
  214. break;
  215. }
  216. } else {
  217. /* That shouldn't be there... */
  218. SMARTLIST_DEL_CURRENT(chans_for_flush_mock, flush_mock_ch);
  219. tor_free(flush_mock_ch);
  220. }
  221. } SMARTLIST_FOREACH_END(flush_mock_ch);
  222. tor_assert(found_mock_ch);
  223. /* Check if any circuits would like to queue some */
  224. /* special for the mock: return the number of cells (instead of 1), or zero
  225. * if nothing to flush */
  226. return (found_mock_ch->cells > 0 ? (int)found_mock_ch->cells : 0 );
  227. }
  228. static void
  229. channel_write_to_kernel_mock(channel_t *chan)
  230. {
  231. (void)chan;
  232. //log_debug(LD_SCHED, "chan=%d writing to kernel",
  233. // (int)chan->global_identifier);
  234. }
  235. static int
  236. channel_should_write_to_kernel_mock(outbuf_table_t *ot, channel_t *chan)
  237. {
  238. (void)ot;
  239. (void)chan;
  240. return 1;
  241. /* We could make this more complicated if we wanted. But I don't think doing
  242. * so tests much of anything */
  243. //static int called_counter = 0;
  244. //if (++called_counter >= 3) {
  245. // called_counter -= 3;
  246. // log_debug(LD_SCHED, "chan=%d should write to kernel",
  247. // (int)chan->global_identifier);
  248. // return 1;
  249. //}
  250. //return 0;
  251. }
  252. static ssize_t
  253. channel_flush_some_cells_mock(channel_t *chan, ssize_t num_cells)
  254. {
  255. ssize_t flushed = 0, max;
  256. char unlimited = 0;
  257. flush_mock_channel_t *found = NULL;
  258. tt_ptr_op(chan, OP_NE, NULL);
  259. if (chan) {
  260. if (num_cells < 0) {
  261. num_cells = 0;
  262. unlimited = 1;
  263. }
  264. /* Check if we have it */
  265. if (chans_for_flush_mock != NULL) {
  266. SMARTLIST_FOREACH_BEGIN(chans_for_flush_mock,
  267. flush_mock_channel_t *,
  268. flush_mock_ch) {
  269. if (flush_mock_ch != NULL && flush_mock_ch->chan != NULL) {
  270. if (flush_mock_ch->chan == chan) {
  271. /* Found it */
  272. found = flush_mock_ch;
  273. break;
  274. }
  275. } else {
  276. /* That shouldn't be there... */
  277. SMARTLIST_DEL_CURRENT(chans_for_flush_mock, flush_mock_ch);
  278. tor_free(flush_mock_ch);
  279. }
  280. } SMARTLIST_FOREACH_END(flush_mock_ch);
  281. if (found) {
  282. /* We found one */
  283. if (found->cells < 0) found->cells = 0;
  284. if (unlimited) max = found->cells;
  285. else max = MIN(found->cells, num_cells);
  286. flushed += max;
  287. found->cells -= max;
  288. }
  289. }
  290. }
  291. done:
  292. return flushed;
  293. }
  294. static void
  295. update_socket_info_impl_mock(socket_table_ent_t *ent)
  296. {
  297. ent->cwnd = ent->unacked = ent->mss = ent->notsent = 0;
  298. ent->limit = INT_MAX;
  299. }
  300. static void
  301. perform_channel_state_tests(int KISTSchedRunInterval, int sched_type)
  302. {
  303. channel_t *ch1 = NULL, *ch2 = NULL;
  304. int old_count;
  305. /* setup options so we're sure about what sched we are running */
  306. MOCK(get_options, mock_get_options);
  307. clear_options();
  308. mocked_options.KISTSchedRunInterval = KISTSchedRunInterval;
  309. set_scheduler_options(sched_type);
  310. /* Set up scheduler */
  311. scheduler_init();
  312. scheduler_attach_mainloop();
  313. scheduler_conf_changed();
  314. /*
  315. * Install the compare channels mock so we can test
  316. * scheduler_touch_channel().
  317. */
  318. MOCK(scheduler_compare_channels, scheduler_compare_channels_mock);
  319. /*
  320. * Disable scheduler_run so we can just check the state transitions
  321. * without having to make everything it might call work too.
  322. */
  323. ((scheduler_t *) the_scheduler)->run = scheduler_run_noop_mock;
  324. tt_int_op(smartlist_len(channels_pending), OP_EQ, 0);
  325. /* Set up a fake channel */
  326. ch1 = new_fake_channel();
  327. tt_assert(ch1);
  328. /* Start it off in OPENING */
  329. ch1->state = CHANNEL_STATE_OPENING;
  330. /* Try to register it */
  331. channel_register(ch1);
  332. tt_assert(ch1->registered);
  333. /* It should start off in SCHED_CHAN_IDLE */
  334. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  335. /* Now get another one */
  336. ch2 = new_fake_channel();
  337. tt_assert(ch2);
  338. ch2->state = CHANNEL_STATE_OPENING;
  339. channel_register(ch2);
  340. tt_assert(ch2->registered);
  341. /* Send ch1 to SCHED_CHAN_WAITING_TO_WRITE */
  342. scheduler_channel_has_waiting_cells(ch1);
  343. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  344. /* This should send it to SCHED_CHAN_PENDING */
  345. scheduler_channel_wants_writes(ch1);
  346. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  347. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  348. /* Now send ch2 to SCHED_CHAN_WAITING_FOR_CELLS */
  349. scheduler_channel_wants_writes(ch2);
  350. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  351. /* Drop ch2 back to idle */
  352. scheduler_channel_doesnt_want_writes(ch2);
  353. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  354. /* ...and back to SCHED_CHAN_WAITING_FOR_CELLS */
  355. scheduler_channel_wants_writes(ch2);
  356. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  357. /* ...and this should kick ch2 into SCHED_CHAN_PENDING */
  358. scheduler_channel_has_waiting_cells(ch2);
  359. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  360. tt_int_op(smartlist_len(channels_pending), OP_EQ, 2);
  361. /* This should send ch2 to SCHED_CHAN_WAITING_TO_WRITE */
  362. scheduler_channel_doesnt_want_writes(ch2);
  363. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  364. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  365. /* ...and back to SCHED_CHAN_PENDING */
  366. scheduler_channel_wants_writes(ch2);
  367. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  368. tt_int_op(smartlist_len(channels_pending), OP_EQ, 2);
  369. /* Now we exercise scheduler_touch_channel */
  370. old_count = scheduler_compare_channels_mock_ctr;
  371. scheduler_touch_channel(ch1);
  372. tt_assert(scheduler_compare_channels_mock_ctr > old_count);
  373. /* Release the ch2 and then do it another time to make sure it doesn't blow
  374. * up and we are still in a quiescent state. */
  375. scheduler_release_channel(ch2);
  376. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  377. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  378. /* Cheat a bit so make the release more confused but also will tells us if
  379. * the release did put the channel in the right state. */
  380. ch2->scheduler_state = SCHED_CHAN_PENDING;
  381. scheduler_release_channel(ch2);
  382. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  383. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  384. /* Close */
  385. channel_mark_for_close(ch1);
  386. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_CLOSING);
  387. channel_mark_for_close(ch2);
  388. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_CLOSING);
  389. channel_closed(ch1);
  390. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_CLOSED);
  391. ch1 = NULL;
  392. channel_closed(ch2);
  393. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_CLOSED);
  394. ch2 = NULL;
  395. /* Shut things down */
  396. channel_free_all();
  397. scheduler_free_all();
  398. done:
  399. tor_free(ch1);
  400. tor_free(ch2);
  401. UNMOCK(scheduler_compare_channels);
  402. UNMOCK(get_options);
  403. cleanup_scheduler_options();
  404. return;
  405. }
  406. static void
  407. test_scheduler_compare_channels(void *arg)
  408. {
  409. /* We don't actually need whole fake channels... */
  410. channel_t c1, c2;
  411. /* ...and some dummy circuitmuxes too */
  412. circuitmux_t *cm1 = NULL, *cm2 = NULL;
  413. int result;
  414. (void)arg;
  415. /* We can't actually see sizeof(circuitmux_t) from here */
  416. cm1 = tor_malloc_zero(sizeof(void *));
  417. cm2 = tor_malloc_zero(sizeof(void *));
  418. c1.cmux = cm1;
  419. c2.cmux = cm2;
  420. /* Configure circuitmux_get_policy() mock */
  421. mock_cgp_tgt_1 = cm1;
  422. mock_cgp_tgt_2 = cm2;
  423. /*
  424. * This is to test the different-policies case, which uses the policy
  425. * cast to an uintptr_t as an arbitrary but definite thing to compare.
  426. */
  427. mock_cgp_val_1 = tor_malloc_zero(16);
  428. mock_cgp_val_2 = tor_malloc_zero(16);
  429. if ( ((uintptr_t) mock_cgp_val_1) > ((uintptr_t) mock_cgp_val_2) ) {
  430. void *tmp = mock_cgp_val_1;
  431. mock_cgp_val_1 = mock_cgp_val_2;
  432. mock_cgp_val_2 = tmp;
  433. }
  434. MOCK(circuitmux_get_policy, circuitmux_get_policy_mock);
  435. /* Now set up circuitmux_compare_muxes() mock using cm1/cm2 */
  436. mock_ccm_tgt_1 = cm1;
  437. mock_ccm_tgt_2 = cm2;
  438. MOCK(circuitmux_compare_muxes, circuitmux_compare_muxes_mock);
  439. /* Equal-channel case */
  440. result = scheduler_compare_channels(&c1, &c1);
  441. tt_int_op(result, OP_EQ, 0);
  442. /* Distinct channels, distinct policies */
  443. result = scheduler_compare_channels(&c1, &c2);
  444. tt_int_op(result, OP_EQ, -1);
  445. result = scheduler_compare_channels(&c2, &c1);
  446. tt_int_op(result, OP_EQ, 1);
  447. /* Distinct channels, same policy */
  448. tor_free(mock_cgp_val_2);
  449. mock_cgp_val_2 = mock_cgp_val_1;
  450. result = scheduler_compare_channels(&c1, &c2);
  451. tt_int_op(result, OP_EQ, -1);
  452. result = scheduler_compare_channels(&c2, &c1);
  453. tt_int_op(result, OP_EQ, 1);
  454. done:
  455. UNMOCK(circuitmux_compare_muxes);
  456. mock_ccm_tgt_1 = NULL;
  457. mock_ccm_tgt_2 = NULL;
  458. UNMOCK(circuitmux_get_policy);
  459. mock_cgp_tgt_1 = NULL;
  460. mock_cgp_tgt_2 = NULL;
  461. tor_free(cm1);
  462. tor_free(cm2);
  463. if (mock_cgp_val_1 != mock_cgp_val_2)
  464. tor_free(mock_cgp_val_1);
  465. tor_free(mock_cgp_val_2);
  466. mock_cgp_val_1 = NULL;
  467. mock_cgp_val_2 = NULL;
  468. return;
  469. }
  470. /******************************************************************************
  471. * The actual tests!
  472. *****************************************************************************/
  473. static void
  474. test_scheduler_loop_vanilla(void *arg)
  475. {
  476. (void)arg;
  477. channel_t *ch1 = NULL, *ch2 = NULL;
  478. void (*run_func_ptr)(void);
  479. /* setup options so we're sure about what sched we are running */
  480. MOCK(get_options, mock_get_options);
  481. clear_options();
  482. set_scheduler_options(SCHEDULER_VANILLA);
  483. mocked_options.KISTSchedRunInterval = 0;
  484. /* Set up scheduler */
  485. scheduler_init();
  486. scheduler_attach_mainloop();
  487. scheduler_conf_changed();
  488. /*
  489. * Install the compare channels mock so we can test
  490. * scheduler_touch_channel().
  491. */
  492. MOCK(scheduler_compare_channels, scheduler_compare_channels_mock);
  493. /*
  494. * Disable scheduler_run so we can just check the state transitions
  495. * without having to make everything it might call work too.
  496. */
  497. run_func_ptr = the_scheduler->run;
  498. ((scheduler_t *) the_scheduler)->run = scheduler_run_noop_mock;
  499. tt_int_op(smartlist_len(channels_pending), OP_EQ, 0);
  500. /* Set up a fake channel */
  501. ch1 = new_fake_channel();
  502. ch1->magic = TLS_CHAN_MAGIC;
  503. tt_assert(ch1);
  504. /* Start it off in OPENING */
  505. ch1->state = CHANNEL_STATE_OPENING;
  506. /* Try to register it */
  507. channel_register(ch1);
  508. tt_assert(ch1->registered);
  509. /* Finish opening it */
  510. channel_change_state_open(ch1);
  511. /* It should start off in SCHED_CHAN_IDLE */
  512. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  513. /* Now get another one */
  514. ch2 = new_fake_channel();
  515. ch2->magic = TLS_CHAN_MAGIC;
  516. tt_assert(ch2);
  517. ch2->state = CHANNEL_STATE_OPENING;
  518. channel_register(ch2);
  519. tt_assert(ch2->registered);
  520. /*
  521. * Don't open ch2; then channel_num_cells_writeable() will return
  522. * zero and we'll get coverage of that exception case in scheduler_run()
  523. */
  524. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_OPEN);
  525. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_OPENING);
  526. /* Send it to SCHED_CHAN_WAITING_TO_WRITE */
  527. scheduler_channel_has_waiting_cells(ch1);
  528. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  529. /* This should send it to SCHED_CHAN_PENDING */
  530. scheduler_channel_wants_writes(ch1);
  531. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  532. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  533. /* Now send ch2 to SCHED_CHAN_WAITING_FOR_CELLS */
  534. scheduler_channel_wants_writes(ch2);
  535. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  536. /* Drop ch2 back to idle */
  537. scheduler_channel_doesnt_want_writes(ch2);
  538. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  539. /* ...and back to SCHED_CHAN_WAITING_FOR_CELLS */
  540. scheduler_channel_wants_writes(ch2);
  541. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  542. /* ...and this should kick ch2 into SCHED_CHAN_PENDING */
  543. scheduler_channel_has_waiting_cells(ch2);
  544. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  545. tt_int_op(smartlist_len(channels_pending), OP_EQ, 2);
  546. /*
  547. * Now we've got two pending channels and need to fire off
  548. * the scheduler run() that we kept.
  549. */
  550. run_func_ptr();
  551. /*
  552. * Assert that they're still in the states we left and aren't still
  553. * pending
  554. */
  555. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_OPEN);
  556. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_OPENING);
  557. tt_assert(ch1->scheduler_state != SCHED_CHAN_PENDING);
  558. tt_assert(ch2->scheduler_state != SCHED_CHAN_PENDING);
  559. tt_int_op(smartlist_len(channels_pending), OP_EQ, 0);
  560. /* Now, finish opening ch2, and get both back to pending */
  561. channel_change_state_open(ch2);
  562. scheduler_channel_wants_writes(ch1);
  563. scheduler_channel_wants_writes(ch2);
  564. scheduler_channel_has_waiting_cells(ch1);
  565. scheduler_channel_has_waiting_cells(ch2);
  566. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_OPEN);
  567. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_OPEN);
  568. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  569. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  570. tt_int_op(smartlist_len(channels_pending), OP_EQ, 2);
  571. /* Now, set up the channel_flush_some_cells() mock */
  572. MOCK(channel_flush_some_cells, channel_flush_some_cells_mock);
  573. /*
  574. * 16 cells on ch1 means it'll completely drain into the 32 cells
  575. * fakechan's num_cells_writeable() returns.
  576. */
  577. channel_flush_some_cells_mock_set(ch1, 16);
  578. /*
  579. * This one should get sent back to pending, since num_cells_writeable()
  580. * will still return non-zero.
  581. */
  582. channel_flush_some_cells_mock_set(ch2, 48);
  583. /*
  584. * And re-run the scheduler run() loop with non-zero returns from
  585. * channel_flush_some_cells() this time.
  586. */
  587. run_func_ptr();
  588. /*
  589. * ch1 should have gone to SCHED_CHAN_WAITING_FOR_CELLS, with 16 flushed
  590. * and 32 writeable.
  591. */
  592. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  593. /*
  594. * ...ch2 should also have gone to SCHED_CHAN_WAITING_FOR_CELLS, with
  595. * channel_more_to_flush() returning false and channel_num_cells_writeable()
  596. * > 0/
  597. */
  598. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  599. /* Close */
  600. channel_mark_for_close(ch1);
  601. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_CLOSING);
  602. channel_mark_for_close(ch2);
  603. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_CLOSING);
  604. channel_closed(ch1);
  605. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_CLOSED);
  606. ch1 = NULL;
  607. channel_closed(ch2);
  608. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_CLOSED);
  609. ch2 = NULL;
  610. /* Shut things down */
  611. channel_flush_some_cells_mock_free_all();
  612. channel_free_all();
  613. scheduler_free_all();
  614. done:
  615. tor_free(ch1);
  616. tor_free(ch2);
  617. cleanup_scheduler_options();
  618. UNMOCK(channel_flush_some_cells);
  619. UNMOCK(scheduler_compare_channels);
  620. UNMOCK(get_options);
  621. }
  622. static void
  623. test_scheduler_loop_kist(void *arg)
  624. {
  625. (void) arg;
  626. #ifndef HAVE_KIST_SUPPORT
  627. return;
  628. #endif
  629. channel_t *ch1 = new_fake_channel(), *ch2 = new_fake_channel();
  630. channel_t *ch3 = new_fake_channel();
  631. /* setup options so we're sure about what sched we are running */
  632. MOCK(get_options, mock_get_options);
  633. MOCK(channel_flush_some_cells, channel_flush_some_cells_mock);
  634. MOCK(channel_more_to_flush, channel_more_to_flush_mock);
  635. MOCK(channel_write_to_kernel, channel_write_to_kernel_mock);
  636. MOCK(channel_should_write_to_kernel, channel_should_write_to_kernel_mock);
  637. MOCK(update_socket_info_impl, update_socket_info_impl_mock);
  638. clear_options();
  639. mocked_options.KISTSchedRunInterval = 11;
  640. set_scheduler_options(SCHEDULER_KIST);
  641. scheduler_init();
  642. scheduler_attach_mainloop();
  643. scheduler_conf_changed();
  644. tt_assert(ch1);
  645. ch1->magic = TLS_CHAN_MAGIC;
  646. ch1->state = CHANNEL_STATE_OPENING;
  647. channel_register(ch1);
  648. tt_assert(ch1->registered);
  649. channel_change_state_open(ch1);
  650. scheduler_channel_has_waiting_cells(ch1);
  651. scheduler_channel_wants_writes(ch1);
  652. channel_flush_some_cells_mock_set(ch1, 5);
  653. tt_assert(ch2);
  654. ch2->magic = TLS_CHAN_MAGIC;
  655. ch2->state = CHANNEL_STATE_OPENING;
  656. channel_register(ch2);
  657. tt_assert(ch2->registered);
  658. channel_change_state_open(ch2);
  659. scheduler_channel_has_waiting_cells(ch2);
  660. scheduler_channel_wants_writes(ch2);
  661. channel_flush_some_cells_mock_set(ch2, 5);
  662. the_scheduler->run();
  663. scheduler_channel_has_waiting_cells(ch1);
  664. channel_flush_some_cells_mock_set(ch1, 5);
  665. the_scheduler->run();
  666. scheduler_channel_has_waiting_cells(ch1);
  667. channel_flush_some_cells_mock_set(ch1, 5);
  668. scheduler_channel_has_waiting_cells(ch2);
  669. channel_flush_some_cells_mock_set(ch2, 5);
  670. the_scheduler->run();
  671. channel_flush_some_cells_mock_free_all();
  672. /* We'll try to run this closed channel threw the scheduler loop and make
  673. * sure it ends up in the right state. */
  674. tt_assert(ch3);
  675. ch3->magic = TLS_CHAN_MAGIC;
  676. ch3->state = CHANNEL_STATE_OPEN;
  677. circuitmux_free(ch3->cmux);
  678. ch3->cmux = circuitmux_alloc();
  679. channel_register(ch3);
  680. tt_assert(ch3->registered);
  681. ch3->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS;
  682. scheduler_channel_has_waiting_cells(ch3);
  683. /* Should be in the pending list now waiting to be handled. */
  684. tt_int_op(ch3->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  685. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  686. /* By running the scheduler on a closed channel, it should end up in the
  687. * IDLE state and not in the pending channel list. */
  688. ch3->state = CHANNEL_STATE_CLOSED;
  689. the_scheduler->run();
  690. tt_int_op(ch3->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  691. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  692. done:
  693. /* Prep the channel so the free() function doesn't explode. */
  694. ch1->state = ch2->state = ch3->state = CHANNEL_STATE_CLOSED;
  695. ch1->registered = ch2->registered = ch3->registered = 0;
  696. channel_free(ch1);
  697. channel_free(ch2);
  698. channel_free(ch3);
  699. UNMOCK(update_socket_info_impl);
  700. UNMOCK(channel_should_write_to_kernel);
  701. UNMOCK(channel_write_to_kernel);
  702. UNMOCK(channel_more_to_flush);
  703. UNMOCK(channel_flush_some_cells);
  704. UNMOCK(get_options);
  705. scheduler_free_all();
  706. return;
  707. }
  708. static void
  709. test_scheduler_channel_states(void *arg)
  710. {
  711. (void)arg;
  712. perform_channel_state_tests(-1, SCHEDULER_VANILLA);
  713. perform_channel_state_tests(11, SCHEDULER_KIST_LITE);
  714. #ifdef HAVE_KIST_SUPPORT
  715. perform_channel_state_tests(11, SCHEDULER_KIST);
  716. #endif
  717. }
  718. static void
  719. test_scheduler_initfree(void *arg)
  720. {
  721. (void)arg;
  722. tt_ptr_op(channels_pending, ==, NULL);
  723. tt_ptr_op(run_sched_ev, ==, NULL);
  724. MOCK(get_options, mock_get_options);
  725. set_scheduler_options(SCHEDULER_KIST);
  726. set_scheduler_options(SCHEDULER_KIST_LITE);
  727. set_scheduler_options(SCHEDULER_VANILLA);
  728. scheduler_init();
  729. scheduler_attach_mainloop();
  730. scheduler_conf_changed();
  731. tt_ptr_op(channels_pending, !=, NULL);
  732. tt_ptr_op(run_sched_ev, !=, NULL);
  733. /* We have specified nothing in the torrc and there's no consensus so the
  734. * KIST scheduler is what should be in use */
  735. tt_ptr_op(the_scheduler, ==, get_kist_scheduler());
  736. tt_int_op(sched_run_interval, ==, 10);
  737. scheduler_free_all();
  738. tt_ptr_op(channels_pending, ==, NULL);
  739. tt_ptr_op(run_sched_ev, ==, NULL);
  740. done:
  741. UNMOCK(get_options);
  742. cleanup_scheduler_options();
  743. return;
  744. }
  745. static void
  746. test_scheduler_can_use_kist(void *arg)
  747. {
  748. (void)arg;
  749. int res_should, res_freq;
  750. MOCK(get_options, mock_get_options);
  751. /* Test force enabling of KIST */
  752. clear_options();
  753. mocked_options.KISTSchedRunInterval = 1234;
  754. res_should = scheduler_can_use_kist();
  755. res_freq = kist_scheduler_run_interval();
  756. #ifdef HAVE_KIST_SUPPORT
  757. tt_int_op(res_should, ==, 1);
  758. #else /* HAVE_KIST_SUPPORT */
  759. tt_int_op(res_should, ==, 0);
  760. #endif /* HAVE_KIST_SUPPORT */
  761. tt_int_op(res_freq, ==, 1234);
  762. /* Test defer to consensus, but no consensus available */
  763. clear_options();
  764. mocked_options.KISTSchedRunInterval = 0;
  765. res_should = scheduler_can_use_kist();
  766. res_freq = kist_scheduler_run_interval();
  767. #ifdef HAVE_KIST_SUPPORT
  768. tt_int_op(res_should, ==, 1);
  769. #else /* HAVE_KIST_SUPPORT */
  770. tt_int_op(res_should, ==, 0);
  771. #endif /* HAVE_KIST_SUPPORT */
  772. tt_int_op(res_freq, ==, 10);
  773. /* Test defer to consensus, and kist consensus available */
  774. MOCK(networkstatus_get_param, mock_kist_networkstatus_get_param);
  775. clear_options();
  776. mocked_options.KISTSchedRunInterval = 0;
  777. res_should = scheduler_can_use_kist();
  778. res_freq = kist_scheduler_run_interval();
  779. #ifdef HAVE_KIST_SUPPORT
  780. tt_int_op(res_should, ==, 1);
  781. #else /* HAVE_KIST_SUPPORT */
  782. tt_int_op(res_should, ==, 0);
  783. #endif /* HAVE_KIST_SUPPORT */
  784. tt_int_op(res_freq, ==, 12);
  785. UNMOCK(networkstatus_get_param);
  786. /* Test defer to consensus, and vanilla consensus available */
  787. MOCK(networkstatus_get_param, mock_vanilla_networkstatus_get_param);
  788. clear_options();
  789. mocked_options.KISTSchedRunInterval = 0;
  790. res_should = scheduler_can_use_kist();
  791. res_freq = kist_scheduler_run_interval();
  792. tt_int_op(res_should, ==, 0);
  793. tt_int_op(res_freq, ==, 0);
  794. UNMOCK(networkstatus_get_param);
  795. done:
  796. UNMOCK(get_options);
  797. return;
  798. }
  799. static void
  800. test_scheduler_ns_changed(void *arg)
  801. {
  802. (void) arg;
  803. /*
  804. * Currently no scheduler implementations use the old/new consensuses passed
  805. * in scheduler_notify_networkstatus_changed, so it is okay to pass NULL.
  806. *
  807. * "But then what does test actually exercise???" It tests that
  808. * scheduler_notify_networkstatus_changed fetches the correct value from the
  809. * consensus, and then switches the scheduler if necessasry.
  810. */
  811. MOCK(get_options, mock_get_options);
  812. clear_options();
  813. set_scheduler_options(SCHEDULER_KIST);
  814. set_scheduler_options(SCHEDULER_VANILLA);
  815. tt_ptr_op(the_scheduler, ==, NULL);
  816. /* Change from vanilla to kist via consensus */
  817. the_scheduler = get_vanilla_scheduler();
  818. MOCK(networkstatus_get_param, mock_kist_networkstatus_get_param);
  819. scheduler_notify_networkstatus_changed();
  820. UNMOCK(networkstatus_get_param);
  821. #ifdef HAVE_KIST_SUPPORT
  822. tt_ptr_op(the_scheduler, ==, get_kist_scheduler());
  823. #else
  824. tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler());
  825. #endif
  826. /* Change from kist to vanilla via consensus */
  827. the_scheduler = get_kist_scheduler();
  828. MOCK(networkstatus_get_param, mock_vanilla_networkstatus_get_param);
  829. scheduler_notify_networkstatus_changed();
  830. UNMOCK(networkstatus_get_param);
  831. tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler());
  832. /* Doesn't change when using KIST */
  833. the_scheduler = get_kist_scheduler();
  834. MOCK(networkstatus_get_param, mock_kist_networkstatus_get_param);
  835. scheduler_notify_networkstatus_changed();
  836. UNMOCK(networkstatus_get_param);
  837. #ifdef HAVE_KIST_SUPPORT
  838. tt_ptr_op(the_scheduler, ==, get_kist_scheduler());
  839. #else
  840. tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler());
  841. #endif
  842. /* Doesn't change when using vanilla */
  843. the_scheduler = get_vanilla_scheduler();
  844. MOCK(networkstatus_get_param, mock_vanilla_networkstatus_get_param);
  845. scheduler_notify_networkstatus_changed();
  846. UNMOCK(networkstatus_get_param);
  847. tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler());
  848. done:
  849. UNMOCK(get_options);
  850. cleanup_scheduler_options();
  851. return;
  852. }
  853. /*
  854. * Mocked functions for the kist_pending_list test.
  855. */
  856. static int mock_flush_some_cells_num = 1;
  857. static int mock_more_to_flush = 0;
  858. static int mock_update_socket_info_limit = 0;
  859. static ssize_t
  860. channel_flush_some_cells_mock_var(channel_t *chan, ssize_t num_cells)
  861. {
  862. (void) chan;
  863. (void) num_cells;
  864. return mock_flush_some_cells_num;
  865. }
  866. /* Because when we flush cells, it is possible that the connection outbuf gets
  867. * fully drained, the wants to write scheduler event is fired back while we
  868. * are in the scheduler loop so this mock function does it for us.
  869. * Furthermore, the socket limit is set to 0 so once this is triggered, it
  870. * informs the scheduler that it can't write on the socket anymore. */
  871. static void
  872. channel_write_to_kernel_mock_trigger_24700(channel_t *chan)
  873. {
  874. static int chan_id_seen[2] = {0};
  875. if (++chan_id_seen[chan->global_identifier - 1] > 1) {
  876. tt_assert(0);
  877. }
  878. scheduler_channel_wants_writes(chan);
  879. done:
  880. return;
  881. }
  882. static int
  883. channel_more_to_flush_mock_var(channel_t *chan)
  884. {
  885. (void) chan;
  886. return mock_more_to_flush;
  887. }
  888. static void
  889. update_socket_info_impl_mock_var(socket_table_ent_t *ent)
  890. {
  891. ent->cwnd = ent->unacked = ent->mss = ent->notsent = 0;
  892. ent->limit = mock_update_socket_info_limit;
  893. }
  894. static void
  895. test_scheduler_kist_pending_list(void *arg)
  896. {
  897. (void) arg;
  898. #ifndef HAVE_KIST_SUPPORT
  899. return;
  900. #endif
  901. /* This is for testing the channel flow with the pending list that is
  902. * depending on the channel state, what will be the expected behavior of the
  903. * scheduler with that list.
  904. *
  905. * For instance, we want to catch double channel add or removing a channel
  906. * that doesn't exists, or putting a channel in the list in a wrong state.
  907. * Essentially, this will articifically test cases of the KIST main loop and
  908. * entry point in the channel subsystem.
  909. *
  910. * In part, this is to also catch things like #24700 and provide a test bed
  911. * for more testing in the future like so. */
  912. /* Mocking a series of scheduler function to control the flow of the
  913. * scheduler loop to test every use cases and assess the pending list. */
  914. MOCK(get_options, mock_get_options);
  915. MOCK(channel_flush_some_cells, channel_flush_some_cells_mock_var);
  916. MOCK(channel_more_to_flush, channel_more_to_flush_mock_var);
  917. MOCK(update_socket_info_impl, update_socket_info_impl_mock_var);
  918. MOCK(channel_write_to_kernel, channel_write_to_kernel_mock);
  919. MOCK(channel_should_write_to_kernel, channel_should_write_to_kernel_mock);
  920. /* Setup options so we're sure about what sched we are running */
  921. mocked_options.KISTSchedRunInterval = 10;
  922. set_scheduler_options(SCHEDULER_KIST);
  923. /* Init scheduler. */
  924. scheduler_init();
  925. scheduler_attach_mainloop();
  926. scheduler_conf_changed();
  927. /* Initialize a channel. We'll need a second channel for the #24700 bug
  928. * test. */
  929. channel_t *chan1 = new_fake_channel();
  930. channel_t *chan2 = new_fake_channel();
  931. tt_assert(chan1);
  932. tt_assert(chan2);
  933. chan1->magic = chan2->magic = TLS_CHAN_MAGIC;
  934. channel_register(chan1);
  935. channel_register(chan2);
  936. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  937. tt_int_op(chan1->sched_heap_idx, OP_EQ, -1);
  938. tt_int_op(chan2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  939. tt_int_op(chan2->sched_heap_idx, OP_EQ, -1);
  940. /* Once a channel becomes OPEN, it always have at least one cell in it so
  941. * the scheduler is notified that the channel wants to write so this is the
  942. * first step. Might not make sense to you but it is the way it is. */
  943. scheduler_channel_wants_writes(chan1);
  944. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  945. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  946. /* Signal the scheduler that it has waiting cells which means the channel
  947. * will get scheduled. */
  948. scheduler_channel_has_waiting_cells(chan1);
  949. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  950. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  951. /* Subsequent call should not add it more times. It is possible we add many
  952. * cells in rapid succession before the channel is scheduled. */
  953. scheduler_channel_has_waiting_cells(chan1);
  954. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  955. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  956. scheduler_channel_has_waiting_cells(chan1);
  957. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  958. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  959. /* We'll flush one cell and make it that the socket can write but no more to
  960. * flush else we end up in an infinite loop. We expect the channel to be put
  961. * in waiting for cells state and the pending list empty. */
  962. mock_update_socket_info_limit = INT_MAX;
  963. mock_more_to_flush = 0;
  964. the_scheduler->run();
  965. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  966. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  967. /* Lets make believe that a cell is now in the channel but this time the
  968. * channel can't write so obviously it has more to flush. We expect the
  969. * channel to be back in the pending list. */
  970. scheduler_channel_has_waiting_cells(chan1);
  971. mock_update_socket_info_limit = 0;
  972. mock_more_to_flush = 1;
  973. the_scheduler->run();
  974. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  975. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  976. /* Channel is in the pending list now, during that time, we'll trigger a
  977. * wants to write event because maybe the channel buffers were emptied in
  978. * the meantime. This is possible because once the connection outbuf is
  979. * flushed down the low watermark, the scheduler is notified.
  980. *
  981. * We expect the channel to NOT be added in the pending list again and stay
  982. * in PENDING state. */
  983. scheduler_channel_wants_writes(chan1);
  984. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  985. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  986. /* Make it that the channel can write now but has nothing else to flush. We
  987. * expect that it is removed from the pending list and waiting for cells. */
  988. mock_update_socket_info_limit = INT_MAX;
  989. mock_more_to_flush = 0;
  990. the_scheduler->run();
  991. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  992. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  993. /* While waiting for cells, lets say we were able to write more things on
  994. * the connection outbuf (unlikely that this can happen but let say it
  995. * does). We expect the channel to stay in waiting for cells. */
  996. scheduler_channel_wants_writes(chan1);
  997. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  998. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  999. /* We'll not put it in the pending list and make the flush cell fail with 0
  1000. * cell flushed. We expect that it is put back in waiting for cells. */
  1001. scheduler_channel_has_waiting_cells(chan1);
  1002. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  1003. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  1004. mock_flush_some_cells_num = 0;
  1005. the_scheduler->run();
  1006. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  1007. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  1008. /* Set the channel to a state where it doesn't want to write more. We expect
  1009. * that the channel becomes idle. */
  1010. scheduler_channel_doesnt_want_writes(chan1);
  1011. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  1012. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  1013. /* Some cells arrive on the channel now. We expect it to go back in waiting
  1014. * to write. You might wonder why it is not put in the pending list? Because
  1015. * once the channel becomes OPEN again (the doesn't want to write event only
  1016. * occurs if the channel goes in MAINT mode), if there are cells in the
  1017. * channel, the wants to write event is triggered thus putting the channel
  1018. * in pending mode.
  1019. *
  1020. * Else, if no cells, it stays IDLE and then once a cell comes in, it should
  1021. * go in waiting to write which is a BUG itself because the channel can't be
  1022. * scheduled until a second cell comes in. Hopefully, #24554 will fix that
  1023. * for KIST. */
  1024. scheduler_channel_has_waiting_cells(chan1);
  1025. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  1026. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  1027. /* Second cell comes in, unfortunately, it won't get scheduled until a wants
  1028. * to write event occurs like described above. */
  1029. scheduler_channel_has_waiting_cells(chan1);
  1030. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  1031. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  1032. /* Unblock everything putting the channel in the pending list. */
  1033. scheduler_channel_wants_writes(chan1);
  1034. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  1035. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  1036. /* Testing bug #24700 which is the situation where we have at least two
  1037. * different channels in the pending list. The first one gets flushed and
  1038. * bytes are written on the wire which triggers a wants to write event
  1039. * because the outbuf is below the low watermark. The bug was that this
  1040. * exact channel was added back in the pending list because its state wasn't
  1041. * PENDING.
  1042. *
  1043. * The following does some ninja-tsu to try to make it happen. We need two
  1044. * different channels so we create a second one and add it to the pending
  1045. * list. Then, we have a custom function when we write to kernel that does
  1046. * two important things:
  1047. *
  1048. * 1) Calls scheduler_channel_wants_writes(chan) on the channel.
  1049. * 2) Keeps track of how many times it sees the channel going through. If
  1050. * that limit goes > 1, it means we've added the channel twice in the
  1051. * pending list.
  1052. *
  1053. * In the end, we expect both channels to be in the pending list after this
  1054. * scheduler run. */
  1055. /* Put the second channel in the pending list. */
  1056. scheduler_channel_wants_writes(chan2);
  1057. scheduler_channel_has_waiting_cells(chan2);
  1058. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 2);
  1059. tt_int_op(chan2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  1060. /* This makes it that the first pass on socket_can_write() will be true but
  1061. * then when a single cell is flushed (514 + 29 bytes), the second call to
  1062. * socket_can_write() will be false. If it wasn't sending back false on the
  1063. * second run, we end up in an infinite loop of the scheduler. */
  1064. mock_update_socket_info_limit = 600;
  1065. /* We want to hit "Case 3:" of the scheduler so channel_more_to_flush() is
  1066. * true but socket_can_write() has to be false on the second check on the
  1067. * channel. */
  1068. mock_more_to_flush = 1;
  1069. mock_flush_some_cells_num = 1;
  1070. MOCK(channel_write_to_kernel, channel_write_to_kernel_mock_trigger_24700);
  1071. the_scheduler->run();
  1072. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 2);
  1073. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  1074. tt_int_op(chan2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  1075. done:
  1076. chan1->state = chan2->state = CHANNEL_STATE_CLOSED;
  1077. chan1->registered = chan2->registered = 0;
  1078. channel_free(chan1);
  1079. channel_free(chan2);
  1080. scheduler_free_all();
  1081. UNMOCK(get_options);
  1082. UNMOCK(channel_flush_some_cells);
  1083. UNMOCK(channel_more_to_flush);
  1084. UNMOCK(update_socket_info_impl);
  1085. UNMOCK(channel_write_to_kernel);
  1086. UNMOCK(channel_should_write_to_kernel);
  1087. }
  1088. struct testcase_t scheduler_tests[] = {
  1089. { "compare_channels", test_scheduler_compare_channels,
  1090. TT_FORK, NULL, NULL },
  1091. { "channel_states", test_scheduler_channel_states, TT_FORK, NULL, NULL },
  1092. { "initfree", test_scheduler_initfree, TT_FORK, NULL, NULL },
  1093. { "loop_vanilla", test_scheduler_loop_vanilla, TT_FORK, NULL, NULL },
  1094. { "loop_kist", test_scheduler_loop_kist, TT_FORK, NULL, NULL },
  1095. { "ns_changed", test_scheduler_ns_changed, TT_FORK, NULL, NULL},
  1096. { "should_use_kist", test_scheduler_can_use_kist, TT_FORK, NULL, NULL },
  1097. { "kist_pending_list", test_scheduler_kist_pending_list, TT_FORK,
  1098. NULL, NULL },
  1099. END_OF_TESTCASES
  1100. };