test_scheduler.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  1. /* Copyright (c) 2014-2018, 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. /*
  313. * Install the compare channels mock so we can test
  314. * scheduler_touch_channel().
  315. */
  316. MOCK(scheduler_compare_channels, scheduler_compare_channels_mock);
  317. /*
  318. * Disable scheduler_run so we can just check the state transitions
  319. * without having to make everything it might call work too.
  320. */
  321. ((scheduler_t *) the_scheduler)->run = scheduler_run_noop_mock;
  322. tt_int_op(smartlist_len(channels_pending), OP_EQ, 0);
  323. /* Set up a fake channel */
  324. ch1 = new_fake_channel();
  325. tt_assert(ch1);
  326. /* Start it off in OPENING */
  327. ch1->state = CHANNEL_STATE_OPENING;
  328. /* Try to register it */
  329. channel_register(ch1);
  330. tt_assert(ch1->registered);
  331. /* It should start off in SCHED_CHAN_IDLE */
  332. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  333. /* Now get another one */
  334. ch2 = new_fake_channel();
  335. tt_assert(ch2);
  336. ch2->state = CHANNEL_STATE_OPENING;
  337. channel_register(ch2);
  338. tt_assert(ch2->registered);
  339. /* Send ch1 to SCHED_CHAN_WAITING_TO_WRITE */
  340. scheduler_channel_has_waiting_cells(ch1);
  341. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  342. /* This should send it to SCHED_CHAN_PENDING */
  343. scheduler_channel_wants_writes(ch1);
  344. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  345. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  346. /* Now send ch2 to SCHED_CHAN_WAITING_FOR_CELLS */
  347. scheduler_channel_wants_writes(ch2);
  348. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  349. /* Drop ch2 back to idle */
  350. scheduler_channel_doesnt_want_writes(ch2);
  351. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  352. /* ...and back to SCHED_CHAN_WAITING_FOR_CELLS */
  353. scheduler_channel_wants_writes(ch2);
  354. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  355. /* ...and this should kick ch2 into SCHED_CHAN_PENDING */
  356. scheduler_channel_has_waiting_cells(ch2);
  357. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  358. tt_int_op(smartlist_len(channels_pending), OP_EQ, 2);
  359. /* This should send ch2 to SCHED_CHAN_WAITING_TO_WRITE */
  360. scheduler_channel_doesnt_want_writes(ch2);
  361. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  362. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  363. /* ...and back to SCHED_CHAN_PENDING */
  364. scheduler_channel_wants_writes(ch2);
  365. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  366. tt_int_op(smartlist_len(channels_pending), OP_EQ, 2);
  367. /* Now we exercise scheduler_touch_channel */
  368. old_count = scheduler_compare_channels_mock_ctr;
  369. scheduler_touch_channel(ch1);
  370. tt_assert(scheduler_compare_channels_mock_ctr > old_count);
  371. /* Release the ch2 and then do it another time to make sure it doesn't blow
  372. * up and we are still in a quiescent state. */
  373. scheduler_release_channel(ch2);
  374. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  375. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  376. /* Cheat a bit so make the release more confused but also will tells us if
  377. * the release did put the channel in the right state. */
  378. ch2->scheduler_state = SCHED_CHAN_PENDING;
  379. scheduler_release_channel(ch2);
  380. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  381. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  382. /* Close */
  383. channel_mark_for_close(ch1);
  384. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_CLOSING);
  385. channel_mark_for_close(ch2);
  386. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_CLOSING);
  387. channel_closed(ch1);
  388. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_CLOSED);
  389. ch1 = NULL;
  390. channel_closed(ch2);
  391. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_CLOSED);
  392. ch2 = NULL;
  393. /* Shut things down */
  394. channel_free_all();
  395. scheduler_free_all();
  396. done:
  397. tor_free(ch1);
  398. tor_free(ch2);
  399. UNMOCK(scheduler_compare_channels);
  400. UNMOCK(get_options);
  401. cleanup_scheduler_options();
  402. return;
  403. }
  404. static void
  405. test_scheduler_compare_channels(void *arg)
  406. {
  407. /* We don't actually need whole fake channels... */
  408. channel_t c1, c2;
  409. /* ...and some dummy circuitmuxes too */
  410. circuitmux_t *cm1 = NULL, *cm2 = NULL;
  411. int result;
  412. (void)arg;
  413. /* We can't actually see sizeof(circuitmux_t) from here */
  414. cm1 = tor_malloc_zero(sizeof(void *));
  415. cm2 = tor_malloc_zero(sizeof(void *));
  416. c1.cmux = cm1;
  417. c2.cmux = cm2;
  418. /* Configure circuitmux_get_policy() mock */
  419. mock_cgp_tgt_1 = cm1;
  420. mock_cgp_tgt_2 = cm2;
  421. /*
  422. * This is to test the different-policies case, which uses the policy
  423. * cast to an uintptr_t as an arbitrary but definite thing to compare.
  424. */
  425. mock_cgp_val_1 = tor_malloc_zero(16);
  426. mock_cgp_val_2 = tor_malloc_zero(16);
  427. if ( ((uintptr_t) mock_cgp_val_1) > ((uintptr_t) mock_cgp_val_2) ) {
  428. void *tmp = mock_cgp_val_1;
  429. mock_cgp_val_1 = mock_cgp_val_2;
  430. mock_cgp_val_2 = tmp;
  431. }
  432. MOCK(circuitmux_get_policy, circuitmux_get_policy_mock);
  433. /* Now set up circuitmux_compare_muxes() mock using cm1/cm2 */
  434. mock_ccm_tgt_1 = cm1;
  435. mock_ccm_tgt_2 = cm2;
  436. MOCK(circuitmux_compare_muxes, circuitmux_compare_muxes_mock);
  437. /* Equal-channel case */
  438. result = scheduler_compare_channels(&c1, &c1);
  439. tt_int_op(result, OP_EQ, 0);
  440. /* Distinct channels, distinct policies */
  441. result = scheduler_compare_channels(&c1, &c2);
  442. tt_int_op(result, OP_EQ, -1);
  443. result = scheduler_compare_channels(&c2, &c1);
  444. tt_int_op(result, OP_EQ, 1);
  445. /* Distinct channels, same policy */
  446. tor_free(mock_cgp_val_2);
  447. mock_cgp_val_2 = mock_cgp_val_1;
  448. result = scheduler_compare_channels(&c1, &c2);
  449. tt_int_op(result, OP_EQ, -1);
  450. result = scheduler_compare_channels(&c2, &c1);
  451. tt_int_op(result, OP_EQ, 1);
  452. done:
  453. UNMOCK(circuitmux_compare_muxes);
  454. mock_ccm_tgt_1 = NULL;
  455. mock_ccm_tgt_2 = NULL;
  456. UNMOCK(circuitmux_get_policy);
  457. mock_cgp_tgt_1 = NULL;
  458. mock_cgp_tgt_2 = NULL;
  459. tor_free(cm1);
  460. tor_free(cm2);
  461. if (mock_cgp_val_1 != mock_cgp_val_2)
  462. tor_free(mock_cgp_val_1);
  463. tor_free(mock_cgp_val_2);
  464. mock_cgp_val_1 = NULL;
  465. mock_cgp_val_2 = NULL;
  466. return;
  467. }
  468. /******************************************************************************
  469. * The actual tests!
  470. *****************************************************************************/
  471. static void
  472. test_scheduler_loop_vanilla(void *arg)
  473. {
  474. (void)arg;
  475. channel_t *ch1 = NULL, *ch2 = NULL;
  476. void (*run_func_ptr)(void);
  477. /* setup options so we're sure about what sched we are running */
  478. MOCK(get_options, mock_get_options);
  479. clear_options();
  480. set_scheduler_options(SCHEDULER_VANILLA);
  481. mocked_options.KISTSchedRunInterval = 0;
  482. /* Set up scheduler */
  483. scheduler_init();
  484. /*
  485. * Install the compare channels mock so we can test
  486. * scheduler_touch_channel().
  487. */
  488. MOCK(scheduler_compare_channels, scheduler_compare_channels_mock);
  489. /*
  490. * Disable scheduler_run so we can just check the state transitions
  491. * without having to make everything it might call work too.
  492. */
  493. run_func_ptr = the_scheduler->run;
  494. ((scheduler_t *) the_scheduler)->run = scheduler_run_noop_mock;
  495. tt_int_op(smartlist_len(channels_pending), OP_EQ, 0);
  496. /* Set up a fake channel */
  497. ch1 = new_fake_channel();
  498. ch1->magic = TLS_CHAN_MAGIC;
  499. tt_assert(ch1);
  500. /* Start it off in OPENING */
  501. ch1->state = CHANNEL_STATE_OPENING;
  502. /* Try to register it */
  503. channel_register(ch1);
  504. tt_assert(ch1->registered);
  505. /* Finish opening it */
  506. channel_change_state_open(ch1);
  507. /* It should start off in SCHED_CHAN_IDLE */
  508. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  509. /* Now get another one */
  510. ch2 = new_fake_channel();
  511. ch2->magic = TLS_CHAN_MAGIC;
  512. tt_assert(ch2);
  513. ch2->state = CHANNEL_STATE_OPENING;
  514. channel_register(ch2);
  515. tt_assert(ch2->registered);
  516. /*
  517. * Don't open ch2; then channel_num_cells_writeable() will return
  518. * zero and we'll get coverage of that exception case in scheduler_run()
  519. */
  520. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_OPEN);
  521. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_OPENING);
  522. /* Send it to SCHED_CHAN_WAITING_TO_WRITE */
  523. scheduler_channel_has_waiting_cells(ch1);
  524. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  525. /* This should send it to SCHED_CHAN_PENDING */
  526. scheduler_channel_wants_writes(ch1);
  527. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  528. tt_int_op(smartlist_len(channels_pending), OP_EQ, 1);
  529. /* Now send ch2 to SCHED_CHAN_WAITING_FOR_CELLS */
  530. scheduler_channel_wants_writes(ch2);
  531. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  532. /* Drop ch2 back to idle */
  533. scheduler_channel_doesnt_want_writes(ch2);
  534. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  535. /* ...and back to SCHED_CHAN_WAITING_FOR_CELLS */
  536. scheduler_channel_wants_writes(ch2);
  537. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  538. /* ...and this should kick ch2 into SCHED_CHAN_PENDING */
  539. scheduler_channel_has_waiting_cells(ch2);
  540. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  541. tt_int_op(smartlist_len(channels_pending), OP_EQ, 2);
  542. /*
  543. * Now we've got two pending channels and need to fire off
  544. * the scheduler run() that we kept.
  545. */
  546. run_func_ptr();
  547. /*
  548. * Assert that they're still in the states we left and aren't still
  549. * pending
  550. */
  551. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_OPEN);
  552. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_OPENING);
  553. tt_assert(ch1->scheduler_state != SCHED_CHAN_PENDING);
  554. tt_assert(ch2->scheduler_state != SCHED_CHAN_PENDING);
  555. tt_int_op(smartlist_len(channels_pending), OP_EQ, 0);
  556. /* Now, finish opening ch2, and get both back to pending */
  557. channel_change_state_open(ch2);
  558. scheduler_channel_wants_writes(ch1);
  559. scheduler_channel_wants_writes(ch2);
  560. scheduler_channel_has_waiting_cells(ch1);
  561. scheduler_channel_has_waiting_cells(ch2);
  562. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_OPEN);
  563. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_OPEN);
  564. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  565. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  566. tt_int_op(smartlist_len(channels_pending), OP_EQ, 2);
  567. /* Now, set up the channel_flush_some_cells() mock */
  568. MOCK(channel_flush_some_cells, channel_flush_some_cells_mock);
  569. /*
  570. * 16 cells on ch1 means it'll completely drain into the 32 cells
  571. * fakechan's num_cells_writeable() returns.
  572. */
  573. channel_flush_some_cells_mock_set(ch1, 16);
  574. /*
  575. * This one should get sent back to pending, since num_cells_writeable()
  576. * will still return non-zero.
  577. */
  578. channel_flush_some_cells_mock_set(ch2, 48);
  579. /*
  580. * And re-run the scheduler run() loop with non-zero returns from
  581. * channel_flush_some_cells() this time.
  582. */
  583. run_func_ptr();
  584. /*
  585. * ch1 should have gone to SCHED_CHAN_WAITING_FOR_CELLS, with 16 flushed
  586. * and 32 writeable.
  587. */
  588. tt_int_op(ch1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  589. /*
  590. * ...ch2 should also have gone to SCHED_CHAN_WAITING_FOR_CELLS, with
  591. * channel_more_to_flush() returning false and channel_num_cells_writeable()
  592. * > 0/
  593. */
  594. tt_int_op(ch2->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  595. /* Close */
  596. channel_mark_for_close(ch1);
  597. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_CLOSING);
  598. channel_mark_for_close(ch2);
  599. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_CLOSING);
  600. channel_closed(ch1);
  601. tt_int_op(ch1->state, OP_EQ, CHANNEL_STATE_CLOSED);
  602. ch1 = NULL;
  603. channel_closed(ch2);
  604. tt_int_op(ch2->state, OP_EQ, CHANNEL_STATE_CLOSED);
  605. ch2 = NULL;
  606. /* Shut things down */
  607. channel_flush_some_cells_mock_free_all();
  608. channel_free_all();
  609. scheduler_free_all();
  610. done:
  611. tor_free(ch1);
  612. tor_free(ch2);
  613. cleanup_scheduler_options();
  614. UNMOCK(channel_flush_some_cells);
  615. UNMOCK(scheduler_compare_channels);
  616. UNMOCK(get_options);
  617. }
  618. static void
  619. test_scheduler_loop_kist(void *arg)
  620. {
  621. (void) arg;
  622. #ifndef HAVE_KIST_SUPPORT
  623. return;
  624. #endif
  625. channel_t *ch1 = new_fake_channel(), *ch2 = new_fake_channel();
  626. channel_t *ch3 = new_fake_channel();
  627. /* setup options so we're sure about what sched we are running */
  628. MOCK(get_options, mock_get_options);
  629. MOCK(channel_flush_some_cells, channel_flush_some_cells_mock);
  630. MOCK(channel_more_to_flush, channel_more_to_flush_mock);
  631. MOCK(channel_write_to_kernel, channel_write_to_kernel_mock);
  632. MOCK(channel_should_write_to_kernel, channel_should_write_to_kernel_mock);
  633. MOCK(update_socket_info_impl, update_socket_info_impl_mock);
  634. clear_options();
  635. mocked_options.KISTSchedRunInterval = 11;
  636. set_scheduler_options(SCHEDULER_KIST);
  637. scheduler_init();
  638. tt_assert(ch1);
  639. ch1->magic = TLS_CHAN_MAGIC;
  640. ch1->state = CHANNEL_STATE_OPENING;
  641. channel_register(ch1);
  642. tt_assert(ch1->registered);
  643. channel_change_state_open(ch1);
  644. scheduler_channel_has_waiting_cells(ch1);
  645. scheduler_channel_wants_writes(ch1);
  646. channel_flush_some_cells_mock_set(ch1, 5);
  647. tt_assert(ch2);
  648. ch2->magic = TLS_CHAN_MAGIC;
  649. ch2->state = CHANNEL_STATE_OPENING;
  650. channel_register(ch2);
  651. tt_assert(ch2->registered);
  652. channel_change_state_open(ch2);
  653. scheduler_channel_has_waiting_cells(ch2);
  654. scheduler_channel_wants_writes(ch2);
  655. channel_flush_some_cells_mock_set(ch2, 5);
  656. the_scheduler->run();
  657. scheduler_channel_has_waiting_cells(ch1);
  658. channel_flush_some_cells_mock_set(ch1, 5);
  659. the_scheduler->run();
  660. scheduler_channel_has_waiting_cells(ch1);
  661. channel_flush_some_cells_mock_set(ch1, 5);
  662. scheduler_channel_has_waiting_cells(ch2);
  663. channel_flush_some_cells_mock_set(ch2, 5);
  664. the_scheduler->run();
  665. channel_flush_some_cells_mock_free_all();
  666. /* We'll try to run this closed channel threw the scheduler loop and make
  667. * sure it ends up in the right state. */
  668. tt_assert(ch3);
  669. ch3->magic = TLS_CHAN_MAGIC;
  670. ch3->state = CHANNEL_STATE_OPEN;
  671. circuitmux_free(ch3->cmux);
  672. ch3->cmux = circuitmux_alloc();
  673. channel_register(ch3);
  674. tt_assert(ch3->registered);
  675. ch3->scheduler_state = SCHED_CHAN_WAITING_FOR_CELLS;
  676. scheduler_channel_has_waiting_cells(ch3);
  677. /* Should be in the pending list now waiting to be handled. */
  678. tt_int_op(ch3->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  679. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  680. /* By running the scheduler on a closed channel, it should end up in the
  681. * IDLE state and not in the pending channel list. */
  682. ch3->state = CHANNEL_STATE_CLOSED;
  683. the_scheduler->run();
  684. tt_int_op(ch3->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  685. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  686. done:
  687. /* Prep the channel so the free() function doesn't explode. */
  688. ch1->state = ch2->state = ch3->state = CHANNEL_STATE_CLOSED;
  689. ch1->registered = ch2->registered = ch3->registered = 0;
  690. channel_free(ch1);
  691. channel_free(ch2);
  692. channel_free(ch3);
  693. UNMOCK(update_socket_info_impl);
  694. UNMOCK(channel_should_write_to_kernel);
  695. UNMOCK(channel_write_to_kernel);
  696. UNMOCK(channel_more_to_flush);
  697. UNMOCK(channel_flush_some_cells);
  698. UNMOCK(get_options);
  699. scheduler_free_all();
  700. return;
  701. }
  702. static void
  703. test_scheduler_channel_states(void *arg)
  704. {
  705. (void)arg;
  706. perform_channel_state_tests(-1, SCHEDULER_VANILLA);
  707. perform_channel_state_tests(11, SCHEDULER_KIST_LITE);
  708. #ifdef HAVE_KIST_SUPPORT
  709. perform_channel_state_tests(11, SCHEDULER_KIST);
  710. #endif
  711. }
  712. static void
  713. test_scheduler_initfree(void *arg)
  714. {
  715. (void)arg;
  716. tt_ptr_op(channels_pending, ==, NULL);
  717. tt_ptr_op(run_sched_ev, ==, NULL);
  718. MOCK(get_options, mock_get_options);
  719. set_scheduler_options(SCHEDULER_KIST);
  720. set_scheduler_options(SCHEDULER_KIST_LITE);
  721. set_scheduler_options(SCHEDULER_VANILLA);
  722. scheduler_init();
  723. tt_ptr_op(channels_pending, !=, NULL);
  724. tt_ptr_op(run_sched_ev, !=, NULL);
  725. /* We have specified nothing in the torrc and there's no consensus so the
  726. * KIST scheduler is what should be in use */
  727. tt_ptr_op(the_scheduler, ==, get_kist_scheduler());
  728. tt_int_op(sched_run_interval, ==, 10);
  729. scheduler_free_all();
  730. tt_ptr_op(channels_pending, ==, NULL);
  731. tt_ptr_op(run_sched_ev, ==, NULL);
  732. done:
  733. UNMOCK(get_options);
  734. cleanup_scheduler_options();
  735. return;
  736. }
  737. static void
  738. test_scheduler_can_use_kist(void *arg)
  739. {
  740. (void)arg;
  741. int res_should, res_freq;
  742. MOCK(get_options, mock_get_options);
  743. /* Test force enabling of KIST */
  744. clear_options();
  745. mocked_options.KISTSchedRunInterval = 1234;
  746. res_should = scheduler_can_use_kist();
  747. res_freq = kist_scheduler_run_interval();
  748. #ifdef HAVE_KIST_SUPPORT
  749. tt_int_op(res_should, ==, 1);
  750. #else /* HAVE_KIST_SUPPORT */
  751. tt_int_op(res_should, ==, 0);
  752. #endif /* HAVE_KIST_SUPPORT */
  753. tt_int_op(res_freq, ==, 1234);
  754. /* Test defer to consensus, but no consensus available */
  755. clear_options();
  756. mocked_options.KISTSchedRunInterval = 0;
  757. res_should = scheduler_can_use_kist();
  758. res_freq = kist_scheduler_run_interval();
  759. #ifdef HAVE_KIST_SUPPORT
  760. tt_int_op(res_should, ==, 1);
  761. #else /* HAVE_KIST_SUPPORT */
  762. tt_int_op(res_should, ==, 0);
  763. #endif /* HAVE_KIST_SUPPORT */
  764. tt_int_op(res_freq, ==, 10);
  765. /* Test defer to consensus, and kist consensus available */
  766. MOCK(networkstatus_get_param, mock_kist_networkstatus_get_param);
  767. clear_options();
  768. mocked_options.KISTSchedRunInterval = 0;
  769. res_should = scheduler_can_use_kist();
  770. res_freq = kist_scheduler_run_interval();
  771. #ifdef HAVE_KIST_SUPPORT
  772. tt_int_op(res_should, ==, 1);
  773. #else /* HAVE_KIST_SUPPORT */
  774. tt_int_op(res_should, ==, 0);
  775. #endif /* HAVE_KIST_SUPPORT */
  776. tt_int_op(res_freq, ==, 12);
  777. UNMOCK(networkstatus_get_param);
  778. /* Test defer to consensus, and vanilla consensus available */
  779. MOCK(networkstatus_get_param, mock_vanilla_networkstatus_get_param);
  780. clear_options();
  781. mocked_options.KISTSchedRunInterval = 0;
  782. res_should = scheduler_can_use_kist();
  783. res_freq = kist_scheduler_run_interval();
  784. tt_int_op(res_should, ==, 0);
  785. tt_int_op(res_freq, ==, 0);
  786. UNMOCK(networkstatus_get_param);
  787. done:
  788. UNMOCK(get_options);
  789. return;
  790. }
  791. static void
  792. test_scheduler_ns_changed(void *arg)
  793. {
  794. (void) arg;
  795. /*
  796. * Currently no scheduler implementations use the old/new consensuses passed
  797. * in scheduler_notify_networkstatus_changed, so it is okay to pass NULL.
  798. *
  799. * "But then what does test actually exercise???" It tests that
  800. * scheduler_notify_networkstatus_changed fetches the correct value from the
  801. * consensus, and then switches the scheduler if necessasry.
  802. */
  803. MOCK(get_options, mock_get_options);
  804. clear_options();
  805. set_scheduler_options(SCHEDULER_KIST);
  806. set_scheduler_options(SCHEDULER_VANILLA);
  807. tt_ptr_op(the_scheduler, ==, NULL);
  808. /* Change from vanilla to kist via consensus */
  809. the_scheduler = get_vanilla_scheduler();
  810. MOCK(networkstatus_get_param, mock_kist_networkstatus_get_param);
  811. scheduler_notify_networkstatus_changed();
  812. UNMOCK(networkstatus_get_param);
  813. #ifdef HAVE_KIST_SUPPORT
  814. tt_ptr_op(the_scheduler, ==, get_kist_scheduler());
  815. #else
  816. tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler());
  817. #endif
  818. /* Change from kist to vanilla via consensus */
  819. the_scheduler = get_kist_scheduler();
  820. MOCK(networkstatus_get_param, mock_vanilla_networkstatus_get_param);
  821. scheduler_notify_networkstatus_changed();
  822. UNMOCK(networkstatus_get_param);
  823. tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler());
  824. /* Doesn't change when using KIST */
  825. the_scheduler = get_kist_scheduler();
  826. MOCK(networkstatus_get_param, mock_kist_networkstatus_get_param);
  827. scheduler_notify_networkstatus_changed();
  828. UNMOCK(networkstatus_get_param);
  829. #ifdef HAVE_KIST_SUPPORT
  830. tt_ptr_op(the_scheduler, ==, get_kist_scheduler());
  831. #else
  832. tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler());
  833. #endif
  834. /* Doesn't change when using vanilla */
  835. the_scheduler = get_vanilla_scheduler();
  836. MOCK(networkstatus_get_param, mock_vanilla_networkstatus_get_param);
  837. scheduler_notify_networkstatus_changed();
  838. UNMOCK(networkstatus_get_param);
  839. tt_ptr_op(the_scheduler, ==, get_vanilla_scheduler());
  840. done:
  841. UNMOCK(get_options);
  842. cleanup_scheduler_options();
  843. return;
  844. }
  845. /*
  846. * Mocked functions for the kist_pending_list test.
  847. */
  848. static int mock_flush_some_cells_num = 1;
  849. static int mock_more_to_flush = 0;
  850. static int mock_update_socket_info_limit = 0;
  851. static ssize_t
  852. channel_flush_some_cells_mock_var(channel_t *chan, ssize_t num_cells)
  853. {
  854. (void) chan;
  855. (void) num_cells;
  856. return mock_flush_some_cells_num;
  857. }
  858. /* Because when we flush cells, it is possible that the connection outbuf gets
  859. * fully drained, the wants to write scheduler event is fired back while we
  860. * are in the scheduler loop so this mock function does it for us.
  861. * Furthermore, the socket limit is set to 0 so once this is triggered, it
  862. * informs the scheduler that it can't write on the socket anymore. */
  863. static void
  864. channel_write_to_kernel_mock_trigger_24700(channel_t *chan)
  865. {
  866. static int chan_id_seen[2] = {0};
  867. if (++chan_id_seen[chan->global_identifier - 1] > 1) {
  868. tt_assert(0);
  869. }
  870. scheduler_channel_wants_writes(chan);
  871. done:
  872. return;
  873. }
  874. static int
  875. channel_more_to_flush_mock_var(channel_t *chan)
  876. {
  877. (void) chan;
  878. return mock_more_to_flush;
  879. }
  880. static void
  881. update_socket_info_impl_mock_var(socket_table_ent_t *ent)
  882. {
  883. ent->cwnd = ent->unacked = ent->mss = ent->notsent = 0;
  884. ent->limit = mock_update_socket_info_limit;
  885. }
  886. static void
  887. test_scheduler_kist_pending_list(void *arg)
  888. {
  889. (void) arg;
  890. #ifndef HAVE_KIST_SUPPORT
  891. return;
  892. #endif
  893. /* This is for testing the channel flow with the pending list that is
  894. * depending on the channel state, what will be the expected behavior of the
  895. * scheduler with that list.
  896. *
  897. * For instance, we want to catch double channel add or removing a channel
  898. * that doesn't exists, or putting a channel in the list in a wrong state.
  899. * Essentially, this will articifically test cases of the KIST main loop and
  900. * entry point in the channel subsystem.
  901. *
  902. * In part, this is to also catch things like #24700 and provide a test bed
  903. * for more testing in the future like so. */
  904. /* Mocking a series of scheduler function to control the flow of the
  905. * scheduler loop to test every use cases and assess the pending list. */
  906. MOCK(get_options, mock_get_options);
  907. MOCK(channel_flush_some_cells, channel_flush_some_cells_mock_var);
  908. MOCK(channel_more_to_flush, channel_more_to_flush_mock_var);
  909. MOCK(update_socket_info_impl, update_socket_info_impl_mock_var);
  910. MOCK(channel_write_to_kernel, channel_write_to_kernel_mock);
  911. MOCK(channel_should_write_to_kernel, channel_should_write_to_kernel_mock);
  912. /* Setup options so we're sure about what sched we are running */
  913. mocked_options.KISTSchedRunInterval = 10;
  914. set_scheduler_options(SCHEDULER_KIST);
  915. /* Init scheduler. */
  916. scheduler_init();
  917. /* Initialize a channel. We'll need a second channel for the #24700 bug
  918. * test. */
  919. channel_t *chan1 = new_fake_channel();
  920. channel_t *chan2 = new_fake_channel();
  921. tt_assert(chan1);
  922. tt_assert(chan2);
  923. chan1->magic = chan2->magic = TLS_CHAN_MAGIC;
  924. channel_register(chan1);
  925. channel_register(chan2);
  926. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  927. tt_int_op(chan1->sched_heap_idx, OP_EQ, -1);
  928. tt_int_op(chan2->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  929. tt_int_op(chan2->sched_heap_idx, OP_EQ, -1);
  930. /* Once a channel becomes OPEN, it always have at least one cell in it so
  931. * the scheduler is notified that the channel wants to write so this is the
  932. * first step. Might not make sense to you but it is the way it is. */
  933. scheduler_channel_wants_writes(chan1);
  934. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  935. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  936. /* Signal the scheduler that it has waiting cells which means the channel
  937. * will get scheduled. */
  938. scheduler_channel_has_waiting_cells(chan1);
  939. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  940. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  941. /* Subsequent call should not add it more times. It is possible we add many
  942. * cells in rapid succession before the channel is scheduled. */
  943. scheduler_channel_has_waiting_cells(chan1);
  944. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  945. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  946. scheduler_channel_has_waiting_cells(chan1);
  947. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  948. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  949. /* We'll flush one cell and make it that the socket can write but no more to
  950. * flush else we end up in an infinite loop. We expect the channel to be put
  951. * in waiting for cells state and the pending list empty. */
  952. mock_update_socket_info_limit = INT_MAX;
  953. mock_more_to_flush = 0;
  954. the_scheduler->run();
  955. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  956. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  957. /* Lets make believe that a cell is now in the channel but this time the
  958. * channel can't write so obviously it has more to flush. We expect the
  959. * channel to be back in the pending list. */
  960. scheduler_channel_has_waiting_cells(chan1);
  961. mock_update_socket_info_limit = 0;
  962. mock_more_to_flush = 1;
  963. the_scheduler->run();
  964. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  965. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  966. /* Channel is in the pending list now, during that time, we'll trigger a
  967. * wants to write event because maybe the channel buffers were emptied in
  968. * the meantime. This is possible because once the connection outbuf is
  969. * flushed down the low watermark, the scheduler is notified.
  970. *
  971. * We expect the channel to NOT be added in the pending list again and stay
  972. * in PENDING state. */
  973. scheduler_channel_wants_writes(chan1);
  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. /* Make it that the channel can write now but has nothing else to flush. We
  977. * expect that it is removed from the pending list and waiting for cells. */
  978. mock_update_socket_info_limit = INT_MAX;
  979. mock_more_to_flush = 0;
  980. the_scheduler->run();
  981. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  982. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  983. /* While waiting for cells, lets say we were able to write more things on
  984. * the connection outbuf (unlikely that this can happen but let say it
  985. * does). We expect the channel to stay in waiting for cells. */
  986. scheduler_channel_wants_writes(chan1);
  987. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  988. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  989. /* We'll not put it in the pending list and make the flush cell fail with 0
  990. * cell flushed. We expect that it is put back in waiting for cells. */
  991. scheduler_channel_has_waiting_cells(chan1);
  992. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  993. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  994. mock_flush_some_cells_num = 0;
  995. the_scheduler->run();
  996. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  997. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_FOR_CELLS);
  998. /* Set the channel to a state where it doesn't want to write more. We expect
  999. * that the channel becomes idle. */
  1000. scheduler_channel_doesnt_want_writes(chan1);
  1001. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  1002. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_IDLE);
  1003. /* Some cells arrive on the channel now. We expect it to go back in waiting
  1004. * to write. You might wonder why it is not put in the pending list? Because
  1005. * once the channel becomes OPEN again (the doesn't want to write event only
  1006. * occurs if the channel goes in MAINT mode), if there are cells in the
  1007. * channel, the wants to write event is triggered thus putting the channel
  1008. * in pending mode.
  1009. *
  1010. * Else, if no cells, it stays IDLE and then once a cell comes in, it should
  1011. * go in waiting to write which is a BUG itself because the channel can't be
  1012. * scheduled until a second cell comes in. Hopefully, #24554 will fix that
  1013. * for KIST. */
  1014. scheduler_channel_has_waiting_cells(chan1);
  1015. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  1016. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  1017. /* Second cell comes in, unfortunately, it won't get scheduled until a wants
  1018. * to write event occurs like described above. */
  1019. scheduler_channel_has_waiting_cells(chan1);
  1020. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 0);
  1021. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_WAITING_TO_WRITE);
  1022. /* Unblock everything putting the channel in the pending list. */
  1023. scheduler_channel_wants_writes(chan1);
  1024. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 1);
  1025. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  1026. /* Testing bug #24700 which is the situation where we have at least two
  1027. * different channels in the pending list. The first one gets flushed and
  1028. * bytes are written on the wire which triggers a wants to write event
  1029. * because the outbuf is below the low watermark. The bug was that this
  1030. * exact channel was added back in the pending list because its state wasn't
  1031. * PENDING.
  1032. *
  1033. * The following does some ninja-tsu to try to make it happen. We need two
  1034. * different channels so we create a second one and add it to the pending
  1035. * list. Then, we have a custom function when we write to kernel that does
  1036. * two important things:
  1037. *
  1038. * 1) Calls scheduler_channel_wants_writes(chan) on the channel.
  1039. * 2) Keeps track of how many times it sees the channel going through. If
  1040. * that limit goes > 1, it means we've added the channel twice in the
  1041. * pending list.
  1042. *
  1043. * In the end, we expect both channels to be in the pending list after this
  1044. * scheduler run. */
  1045. /* Put the second channel in the pending list. */
  1046. scheduler_channel_wants_writes(chan2);
  1047. scheduler_channel_has_waiting_cells(chan2);
  1048. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 2);
  1049. tt_int_op(chan2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  1050. /* This makes it that the first pass on socket_can_write() will be true but
  1051. * then when a single cell is flushed (514 + 29 bytes), the second call to
  1052. * socket_can_write() will be false. If it wasn't sending back false on the
  1053. * second run, we end up in an infinite loop of the scheduler. */
  1054. mock_update_socket_info_limit = 600;
  1055. /* We want to hit "Case 3:" of the scheduler so channel_more_to_flush() is
  1056. * true but socket_can_write() has to be false on the second check on the
  1057. * channel. */
  1058. mock_more_to_flush = 1;
  1059. mock_flush_some_cells_num = 1;
  1060. MOCK(channel_write_to_kernel, channel_write_to_kernel_mock_trigger_24700);
  1061. the_scheduler->run();
  1062. tt_int_op(smartlist_len(get_channels_pending()), OP_EQ, 2);
  1063. tt_int_op(chan1->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  1064. tt_int_op(chan2->scheduler_state, OP_EQ, SCHED_CHAN_PENDING);
  1065. done:
  1066. chan1->state = chan2->state = CHANNEL_STATE_CLOSED;
  1067. chan1->registered = chan2->registered = 0;
  1068. channel_free(chan1);
  1069. channel_free(chan2);
  1070. scheduler_free_all();
  1071. UNMOCK(get_options);
  1072. UNMOCK(channel_flush_some_cells);
  1073. UNMOCK(channel_more_to_flush);
  1074. UNMOCK(update_socket_info_impl);
  1075. UNMOCK(channel_write_to_kernel);
  1076. UNMOCK(channel_should_write_to_kernel);
  1077. }
  1078. struct testcase_t scheduler_tests[] = {
  1079. { "compare_channels", test_scheduler_compare_channels,
  1080. TT_FORK, NULL, NULL },
  1081. { "channel_states", test_scheduler_channel_states, TT_FORK, NULL, NULL },
  1082. { "initfree", test_scheduler_initfree, TT_FORK, NULL, NULL },
  1083. { "loop_vanilla", test_scheduler_loop_vanilla, TT_FORK, NULL, NULL },
  1084. { "loop_kist", test_scheduler_loop_kist, TT_FORK, NULL, NULL },
  1085. { "ns_changed", test_scheduler_ns_changed, TT_FORK, NULL, NULL},
  1086. { "should_use_kist", test_scheduler_can_use_kist, TT_FORK, NULL, NULL },
  1087. { "kist_pending_list", test_scheduler_kist_pending_list, TT_FORK,
  1088. NULL, NULL },
  1089. END_OF_TESTCASES
  1090. };