test_channel.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /* Copyright (c) 2013, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #define TOR_CHANNEL_INTERNAL_
  4. #include "or.h"
  5. #include "channel.h"
  6. /* For channel_note_destroy_not_pending */
  7. #include "circuitlist.h"
  8. /* For var_cell_free */
  9. #include "connection_or.h"
  10. /* For packed_cell stuff */
  11. #define RELAY_PRIVATE
  12. #include "relay.h"
  13. /* For init/free stuff */
  14. #include "scheduler.h"
  15. /* Test suite stuff */
  16. #include "test.h"
  17. #include "fakechans.h"
  18. static int test_chan_accept_cells = 0;
  19. static int test_cells_written = 0;
  20. static int test_destroy_not_pending_calls = 0;
  21. static int test_doesnt_want_writes_count = 0;
  22. static double test_overhead_estimate = 1.0f;
  23. static int test_releases_count = 0;
  24. static void channel_note_destroy_not_pending_mock(channel_t *ch,
  25. circid_t circid);
  26. static void chan_test_close(channel_t *ch);
  27. static size_t chan_test_num_bytes_queued(channel_t *ch);
  28. static int chan_test_num_cells_writeable(channel_t *ch);
  29. static int chan_test_write_cell(channel_t *ch, cell_t *cell);
  30. static int chan_test_write_packed_cell(channel_t *ch,
  31. packed_cell_t *packed_cell);
  32. static int chan_test_write_var_cell(channel_t *ch, var_cell_t *var_cell);
  33. static void scheduler_channel_doesnt_want_writes_mock(channel_t *ch);
  34. static void scheduler_release_channel_mock(channel_t *ch);
  35. static void test_channel_flush(void *arg);
  36. static void test_channel_lifecycle(void *arg);
  37. static void test_channel_multi(void *arg);
  38. static void test_channel_queue_size(void *arg);
  39. static void test_channel_write(void *arg);
  40. static void
  41. channel_note_destroy_not_pending_mock(channel_t *ch,
  42. circid_t circid)
  43. {
  44. (void)ch;
  45. (void)circid;
  46. ++test_destroy_not_pending_calls;
  47. }
  48. static void
  49. chan_test_close(channel_t *ch)
  50. {
  51. test_assert(ch);
  52. done:
  53. return;
  54. }
  55. static double
  56. chan_test_get_overhead_estimate(channel_t *ch)
  57. {
  58. test_assert(ch);
  59. done:
  60. return test_overhead_estimate;
  61. }
  62. static size_t
  63. chan_test_num_bytes_queued(channel_t *ch)
  64. {
  65. test_assert(ch);
  66. done:
  67. return 0;
  68. }
  69. static int
  70. chan_test_num_cells_writeable(channel_t *ch)
  71. {
  72. test_assert(ch);
  73. done:
  74. return 32;
  75. }
  76. static int
  77. chan_test_write_cell(channel_t *ch, cell_t *cell)
  78. {
  79. int rv = 0;
  80. test_assert(ch);
  81. test_assert(cell);
  82. if (test_chan_accept_cells) {
  83. /* Free the cell and bump the counter */
  84. tor_free(cell);
  85. ++test_cells_written;
  86. rv = 1;
  87. }
  88. /* else return 0, we didn't accept it */
  89. done:
  90. return rv;
  91. }
  92. static int
  93. chan_test_write_packed_cell(channel_t *ch,
  94. packed_cell_t *packed_cell)
  95. {
  96. int rv = 0;
  97. test_assert(ch);
  98. test_assert(packed_cell);
  99. if (test_chan_accept_cells) {
  100. /* Free the cell and bump the counter */
  101. packed_cell_free(packed_cell);
  102. ++test_cells_written;
  103. rv = 1;
  104. }
  105. /* else return 0, we didn't accept it */
  106. done:
  107. return rv;
  108. }
  109. static int
  110. chan_test_write_var_cell(channel_t *ch, var_cell_t *var_cell)
  111. {
  112. int rv = 0;
  113. test_assert(ch);
  114. test_assert(var_cell);
  115. if (test_chan_accept_cells) {
  116. /* Free the cell and bump the counter */
  117. var_cell_free(var_cell);
  118. ++test_cells_written;
  119. rv = 1;
  120. }
  121. /* else return 0, we didn't accept it */
  122. done:
  123. return rv;
  124. }
  125. /**
  126. * Fill out c with a new fake cell for test suite use
  127. */
  128. void
  129. make_fake_cell(cell_t *c)
  130. {
  131. test_assert(c != NULL);
  132. c->circ_id = 1;
  133. c->command = CELL_RELAY;
  134. memset(c->payload, 0, CELL_PAYLOAD_SIZE);
  135. done:
  136. return;
  137. }
  138. /**
  139. * Fill out c with a new fake var_cell for test suite use
  140. */
  141. void
  142. make_fake_var_cell(var_cell_t *c)
  143. {
  144. test_assert(c != NULL);
  145. c->circ_id = 1;
  146. c->command = CELL_VERSIONS;
  147. c->payload_len = CELL_PAYLOAD_SIZE / 2;
  148. memset(c->payload, 0, c->payload_len);
  149. done:
  150. return;
  151. }
  152. /**
  153. * Set up a new fake channel for the test suite
  154. */
  155. channel_t *
  156. new_fake_channel(void)
  157. {
  158. channel_t *chan = tor_malloc_zero(sizeof(channel_t));
  159. channel_init(chan);
  160. chan->close = chan_test_close;
  161. chan->get_overhead_estimate = chan_test_get_overhead_estimate;
  162. chan->num_bytes_queued = chan_test_num_bytes_queued;
  163. chan->num_cells_writeable = chan_test_num_cells_writeable;
  164. chan->write_cell = chan_test_write_cell;
  165. chan->write_packed_cell = chan_test_write_packed_cell;
  166. chan->write_var_cell = chan_test_write_var_cell;
  167. chan->state = CHANNEL_STATE_OPEN;
  168. return chan;
  169. }
  170. static void
  171. scheduler_channel_doesnt_want_writes_mock(channel_t *ch)
  172. {
  173. (void)ch;
  174. /* Increment counter */
  175. ++test_doesnt_want_writes_count;
  176. return;
  177. }
  178. static void
  179. scheduler_release_channel_mock(channel_t *ch)
  180. {
  181. (void)ch;
  182. /* Increment counter */
  183. ++test_releases_count;
  184. return;
  185. }
  186. static void
  187. test_channel_flush(void *arg)
  188. {
  189. channel_t *ch = NULL;
  190. cell_t *cell = NULL;
  191. packed_cell_t *p_cell = NULL;
  192. var_cell_t *v_cell = NULL;
  193. int init_count;
  194. (void)arg;
  195. init_cell_pool();
  196. ch = new_fake_channel();
  197. test_assert(ch);
  198. /* Cache the original count */
  199. init_count = test_cells_written;
  200. /* Stop accepting so we can queue some */
  201. test_chan_accept_cells = 0;
  202. /* Queue a regular cell */
  203. cell = tor_malloc_zero(sizeof(cell_t));
  204. make_fake_cell(cell);
  205. channel_write_cell(ch, cell);
  206. /* It should be queued, so assert that we didn't write it */
  207. test_eq(test_cells_written, init_count);
  208. /* Queue a var cell */
  209. v_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
  210. make_fake_var_cell(v_cell);
  211. channel_write_var_cell(ch, v_cell);
  212. /* It should be queued, so assert that we didn't write it */
  213. test_eq(test_cells_written, init_count);
  214. /* Try a packed cell now */
  215. p_cell = packed_cell_new();
  216. test_assert(p_cell);
  217. channel_write_packed_cell(ch, p_cell);
  218. /* It should be queued, so assert that we didn't write it */
  219. test_eq(test_cells_written, init_count);
  220. /* Now allow writes through again */
  221. test_chan_accept_cells = 1;
  222. /* ...and flush */
  223. channel_flush_cells(ch);
  224. /* All three should have gone through */
  225. test_eq(test_cells_written, init_count + 3);
  226. done:
  227. tor_free(ch);
  228. free_cell_pool();
  229. return;
  230. }
  231. static void
  232. test_channel_lifecycle(void *arg)
  233. {
  234. channel_t *ch1 = NULL, *ch2 = NULL;
  235. cell_t *cell = NULL;
  236. int old_count, init_doesnt_want_writes_count;
  237. int init_releases_count;
  238. (void)arg;
  239. /* Mock these for the whole lifecycle test */
  240. MOCK(scheduler_channel_doesnt_want_writes,
  241. scheduler_channel_doesnt_want_writes_mock);
  242. MOCK(scheduler_release_channel,
  243. scheduler_release_channel_mock);
  244. /* Cache some initial counter values */
  245. init_doesnt_want_writes_count = test_doesnt_want_writes_count;
  246. init_releases_count = test_releases_count;
  247. /* Accept cells to lower layer */
  248. test_chan_accept_cells = 1;
  249. /* Use default overhead factor */
  250. test_overhead_estimate = 1.0f;
  251. ch1 = new_fake_channel();
  252. test_assert(ch1);
  253. /* Start it off in OPENING */
  254. ch1->state = CHANNEL_STATE_OPENING;
  255. /* Try to register it */
  256. channel_register(ch1);
  257. test_assert(ch1->registered);
  258. /* Try to write a cell through (should queue) */
  259. cell = tor_malloc_zero(sizeof(cell_t));
  260. make_fake_cell(cell);
  261. old_count = test_cells_written;
  262. channel_write_cell(ch1, cell);
  263. test_eq(old_count, test_cells_written);
  264. /* Move it to OPEN and flush */
  265. channel_change_state(ch1, CHANNEL_STATE_OPEN);
  266. /* Queue should drain */
  267. test_eq(old_count + 1, test_cells_written);
  268. /* Get another one */
  269. ch2 = new_fake_channel();
  270. test_assert(ch2);
  271. ch2->state = CHANNEL_STATE_OPENING;
  272. /* Register */
  273. channel_register(ch2);
  274. test_assert(ch2->registered);
  275. /* Check counters */
  276. test_eq(test_doesnt_want_writes_count, init_doesnt_want_writes_count);
  277. test_eq(test_releases_count, init_releases_count);
  278. /* Move ch1 to MAINT */
  279. channel_change_state(ch1, CHANNEL_STATE_MAINT);
  280. test_eq(test_doesnt_want_writes_count, init_doesnt_want_writes_count + 1);
  281. test_eq(test_releases_count, init_releases_count);
  282. /* Move ch2 to OPEN */
  283. channel_change_state(ch2, CHANNEL_STATE_OPEN);
  284. test_eq(test_doesnt_want_writes_count, init_doesnt_want_writes_count + 1);
  285. test_eq(test_releases_count, init_releases_count);
  286. /* Move ch1 back to OPEN */
  287. channel_change_state(ch1, CHANNEL_STATE_OPEN);
  288. test_eq(test_doesnt_want_writes_count, init_doesnt_want_writes_count + 1);
  289. test_eq(test_releases_count, init_releases_count);
  290. /* Mark ch2 for close */
  291. channel_mark_for_close(ch2);
  292. test_eq(ch2->state, CHANNEL_STATE_CLOSING);
  293. test_eq(test_doesnt_want_writes_count, init_doesnt_want_writes_count + 1);
  294. test_eq(test_releases_count, init_releases_count + 1);
  295. /* Shut down channels */
  296. channel_free_all();
  297. ch1 = ch2 = NULL;
  298. test_eq(test_doesnt_want_writes_count, init_doesnt_want_writes_count + 1);
  299. /* channel_free() calls scheduler_release_channel() */
  300. test_eq(test_releases_count, init_releases_count + 4);
  301. done:
  302. tor_free(ch1);
  303. tor_free(ch2);
  304. UNMOCK(scheduler_channel_doesnt_want_writes);
  305. UNMOCK(scheduler_release_channel);
  306. return;
  307. }
  308. static void
  309. test_channel_multi(void *arg)
  310. {
  311. channel_t *ch1 = NULL, *ch2 = NULL;
  312. uint64_t global_queue_estimate;
  313. cell_t *cell = NULL;
  314. (void)arg;
  315. /* Accept cells to lower layer */
  316. test_chan_accept_cells = 1;
  317. /* Use default overhead factor */
  318. test_overhead_estimate = 1.0f;
  319. ch1 = new_fake_channel();
  320. test_assert(ch1);
  321. ch2 = new_fake_channel();
  322. test_assert(ch2);
  323. /* Initial queue size update */
  324. channel_update_xmit_queue_size(ch1);
  325. test_eq(ch1->bytes_queued_for_xmit, 0);
  326. channel_update_xmit_queue_size(ch2);
  327. test_eq(ch2->bytes_queued_for_xmit, 0);
  328. global_queue_estimate = channel_get_global_queue_estimate();
  329. test_eq(global_queue_estimate, 0);
  330. /* Queue some cells, check queue estimates */
  331. cell = tor_malloc_zero(sizeof(cell_t));
  332. make_fake_cell(cell);
  333. channel_write_cell(ch1, cell);
  334. cell = tor_malloc_zero(sizeof(cell_t));
  335. make_fake_cell(cell);
  336. channel_write_cell(ch2, cell);
  337. channel_update_xmit_queue_size(ch1);
  338. channel_update_xmit_queue_size(ch2);
  339. test_eq(ch1->bytes_queued_for_xmit, 0);
  340. test_eq(ch2->bytes_queued_for_xmit, 0);
  341. global_queue_estimate = channel_get_global_queue_estimate();
  342. test_eq(global_queue_estimate, 0);
  343. /* Stop accepting cells at lower layer */
  344. test_chan_accept_cells = 0;
  345. /* Queue some cells and check queue estimates */
  346. cell = tor_malloc_zero(sizeof(cell_t));
  347. make_fake_cell(cell);
  348. channel_write_cell(ch1, cell);
  349. channel_update_xmit_queue_size(ch1);
  350. test_eq(ch1->bytes_queued_for_xmit, 512);
  351. global_queue_estimate = channel_get_global_queue_estimate();
  352. test_eq(global_queue_estimate, 512);
  353. cell = tor_malloc_zero(sizeof(cell_t));
  354. make_fake_cell(cell);
  355. channel_write_cell(ch2, cell);
  356. channel_update_xmit_queue_size(ch2);
  357. test_eq(ch2->bytes_queued_for_xmit, 512);
  358. global_queue_estimate = channel_get_global_queue_estimate();
  359. test_eq(global_queue_estimate, 1024);
  360. /* Allow cells through again */
  361. test_chan_accept_cells = 1;
  362. /* Flush chan 2 */
  363. channel_flush_cells(ch2);
  364. /* Update and check queue sizes */
  365. channel_update_xmit_queue_size(ch1);
  366. channel_update_xmit_queue_size(ch2);
  367. test_eq(ch1->bytes_queued_for_xmit, 512);
  368. test_eq(ch2->bytes_queued_for_xmit, 0);
  369. global_queue_estimate = channel_get_global_queue_estimate();
  370. test_eq(global_queue_estimate, 512);
  371. /* Flush chan 1 */
  372. channel_flush_cells(ch1);
  373. /* Update and check queue sizes */
  374. channel_update_xmit_queue_size(ch1);
  375. channel_update_xmit_queue_size(ch2);
  376. test_eq(ch1->bytes_queued_for_xmit, 0);
  377. test_eq(ch2->bytes_queued_for_xmit, 0);
  378. global_queue_estimate = channel_get_global_queue_estimate();
  379. test_eq(global_queue_estimate, 0);
  380. /* Now block again */
  381. test_chan_accept_cells = 0;
  382. /* Queue some cells */
  383. cell = tor_malloc_zero(sizeof(cell_t));
  384. make_fake_cell(cell);
  385. channel_write_cell(ch1, cell);
  386. cell = tor_malloc_zero(sizeof(cell_t));
  387. make_fake_cell(cell);
  388. channel_write_cell(ch2, cell);
  389. /* Check the estimates */
  390. channel_update_xmit_queue_size(ch1);
  391. channel_update_xmit_queue_size(ch2);
  392. test_eq(ch1->bytes_queued_for_xmit, 512);
  393. test_eq(ch2->bytes_queued_for_xmit, 512);
  394. global_queue_estimate = channel_get_global_queue_estimate();
  395. test_eq(global_queue_estimate, 1024);
  396. /* Now close channel 2; it should be subtracted from the global queue */
  397. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  398. channel_mark_for_close(ch2);
  399. UNMOCK(scheduler_release_channel);
  400. global_queue_estimate = channel_get_global_queue_estimate();
  401. test_eq(global_queue_estimate, 512);
  402. /*
  403. * Since the fake channels aren't registered, channel_free_all() can't
  404. * see them properly.
  405. */
  406. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  407. channel_mark_for_close(ch1);
  408. UNMOCK(scheduler_release_channel);
  409. global_queue_estimate = channel_get_global_queue_estimate();
  410. test_eq(global_queue_estimate, 0);
  411. /* Now free everything */
  412. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  413. channel_free_all();
  414. UNMOCK(scheduler_release_channel);
  415. done:
  416. tor_free(ch1);
  417. tor_free(ch2);
  418. return;
  419. }
  420. static void
  421. test_channel_queue_size(void *arg)
  422. {
  423. channel_t *ch = NULL;
  424. cell_t *cell = NULL;
  425. int n, old_count;
  426. uint64_t global_queue_estimate;
  427. (void)arg;
  428. ch = new_fake_channel();
  429. test_assert(ch);
  430. /* Initial queue size update */
  431. channel_update_xmit_queue_size(ch);
  432. test_eq(ch->bytes_queued_for_xmit, 0);
  433. global_queue_estimate = channel_get_global_queue_estimate();
  434. test_eq(global_queue_estimate, 0);
  435. /* Test the call-through to our fake lower layer */
  436. n = channel_num_cells_writeable(ch);
  437. /* chan_test_num_cells_writeable() always returns 32 */
  438. test_eq(n, 32);
  439. /*
  440. * Now we queue some cells and check that channel_num_cells_writeable()
  441. * adjusts properly
  442. */
  443. /* tell it not to accept cells */
  444. test_chan_accept_cells = 0;
  445. /* ...and keep it from trying to flush the queue */
  446. ch->state = CHANNEL_STATE_MAINT;
  447. /* Get a fresh cell */
  448. cell = tor_malloc_zero(sizeof(cell_t));
  449. make_fake_cell(cell);
  450. old_count = test_cells_written;
  451. channel_write_cell(ch, cell);
  452. /* Assert that it got queued, not written through, correctly */
  453. test_eq(test_cells_written, old_count);
  454. /* Now check chan_test_num_cells_writeable() again */
  455. n = channel_num_cells_writeable(ch);
  456. test_eq(n, 0); /* Should return 0 since we're in CHANNEL_STATE_MAINT */
  457. /* Update queue size estimates */
  458. channel_update_xmit_queue_size(ch);
  459. /* One cell, times an overhead factor of 1.0 */
  460. test_eq(ch->bytes_queued_for_xmit, 512);
  461. /* Try a different overhead factor */
  462. test_overhead_estimate = 0.5f;
  463. /* This one should be ignored since it's below 1.0 */
  464. channel_update_xmit_queue_size(ch);
  465. test_eq(ch->bytes_queued_for_xmit, 512);
  466. /* Now try a larger one */
  467. test_overhead_estimate = 2.0f;
  468. channel_update_xmit_queue_size(ch);
  469. test_eq(ch->bytes_queued_for_xmit, 1024);
  470. /* Go back to 1.0 */
  471. test_overhead_estimate = 1.0f;
  472. channel_update_xmit_queue_size(ch);
  473. test_eq(ch->bytes_queued_for_xmit, 512);
  474. /* Check the global estimate too */
  475. global_queue_estimate = channel_get_global_queue_estimate();
  476. test_eq(global_queue_estimate, 512);
  477. /* Go to open */
  478. old_count = test_cells_written;
  479. channel_change_state(ch, CHANNEL_STATE_OPEN);
  480. /*
  481. * It should try to write, but we aren't accepting cells right now, so
  482. * it'll requeue
  483. */
  484. test_eq(test_cells_written, old_count);
  485. /* Check the queue size again */
  486. channel_update_xmit_queue_size(ch);
  487. test_eq(ch->bytes_queued_for_xmit, 512);
  488. global_queue_estimate = channel_get_global_queue_estimate();
  489. test_eq(global_queue_estimate, 512);
  490. /*
  491. * Now the cell is in the queue, and we're open, so we should get 31
  492. * writeable cells.
  493. */
  494. n = channel_num_cells_writeable(ch);
  495. test_eq(n, 31);
  496. /* Accept cells again */
  497. test_chan_accept_cells = 1;
  498. /* ...and re-process the queue */
  499. old_count = test_cells_written;
  500. channel_flush_cells(ch);
  501. test_eq(test_cells_written, old_count + 1);
  502. /* Should have 32 writeable now */
  503. n = channel_num_cells_writeable(ch);
  504. test_eq(n, 32);
  505. /* Should have queue size estimate of zero */
  506. channel_update_xmit_queue_size(ch);
  507. test_eq(ch->bytes_queued_for_xmit, 0);
  508. global_queue_estimate = channel_get_global_queue_estimate();
  509. test_eq(global_queue_estimate, 0);
  510. /* Okay, now we're done with this one */
  511. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  512. channel_mark_for_close(ch);
  513. UNMOCK(scheduler_release_channel);
  514. done:
  515. tor_free(ch);
  516. return;
  517. }
  518. static void
  519. test_channel_write(void *arg)
  520. {
  521. channel_t *ch = NULL;
  522. cell_t *cell = tor_malloc_zero(sizeof(cell_t));
  523. packed_cell_t *packed_cell = NULL;
  524. var_cell_t *var_cell =
  525. tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
  526. int old_count;
  527. (void)arg;
  528. init_cell_pool();
  529. packed_cell = packed_cell_new();
  530. test_assert(packed_cell);
  531. ch = new_fake_channel();
  532. test_assert(ch);
  533. make_fake_cell(cell);
  534. make_fake_var_cell(var_cell);
  535. /* Tell it to accept cells */
  536. test_chan_accept_cells = 1;
  537. old_count = test_cells_written;
  538. channel_write_cell(ch, cell);
  539. test_assert(test_cells_written == old_count + 1);
  540. channel_write_var_cell(ch, var_cell);
  541. test_assert(test_cells_written == old_count + 2);
  542. channel_write_packed_cell(ch, packed_cell);
  543. test_assert(test_cells_written == old_count + 3);
  544. /* Now we test queueing; tell it not to accept cells */
  545. test_chan_accept_cells = 0;
  546. /* ...and keep it from trying to flush the queue */
  547. ch->state = CHANNEL_STATE_MAINT;
  548. /* Get a fresh cell */
  549. cell = tor_malloc_zero(sizeof(cell_t));
  550. make_fake_cell(cell);
  551. old_count = test_cells_written;
  552. channel_write_cell(ch, cell);
  553. test_assert(test_cells_written == old_count);
  554. /*
  555. * Now change back to open with channel_change_state() and assert that it
  556. * gets drained from the queue.
  557. */
  558. test_chan_accept_cells = 1;
  559. channel_change_state(ch, CHANNEL_STATE_OPEN);
  560. test_assert(test_cells_written == old_count + 1);
  561. /*
  562. * Check the note destroy case
  563. */
  564. cell = tor_malloc_zero(sizeof(cell_t));
  565. make_fake_cell(cell);
  566. cell->command = CELL_DESTROY;
  567. /* Set up the mock */
  568. MOCK(channel_note_destroy_not_pending,
  569. channel_note_destroy_not_pending_mock);
  570. old_count = test_destroy_not_pending_calls;
  571. channel_write_cell(ch, cell);
  572. test_assert(test_destroy_not_pending_calls == old_count + 1);
  573. /* Now send a non-destroy and check we don't call it */
  574. cell = tor_malloc_zero(sizeof(cell_t));
  575. make_fake_cell(cell);
  576. channel_write_cell(ch, cell);
  577. test_assert(test_destroy_not_pending_calls == old_count + 1);
  578. UNMOCK(channel_note_destroy_not_pending);
  579. /*
  580. * Now switch it to CLOSING so we can test the discard-cells case
  581. * in the channel_write_*() functions.
  582. */
  583. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  584. channel_mark_for_close(ch);
  585. UNMOCK(scheduler_release_channel);
  586. /* Send cells that will drop in the closing state */
  587. old_count = test_cells_written;
  588. cell = tor_malloc_zero(sizeof(cell_t));
  589. make_fake_cell(cell);
  590. channel_write_cell(ch, cell);
  591. test_assert(test_cells_written == old_count);
  592. var_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
  593. make_fake_var_cell(var_cell);
  594. channel_write_var_cell(ch, var_cell);
  595. test_assert(test_cells_written == old_count);
  596. packed_cell = packed_cell_new();
  597. channel_write_packed_cell(ch, packed_cell);
  598. test_assert(test_cells_written == old_count);
  599. free_cell_pool();
  600. done:
  601. tor_free(ch);
  602. return;
  603. }
  604. struct testcase_t channel_tests[] = {
  605. { "flush", test_channel_flush, TT_FORK, NULL, NULL },
  606. { "lifecycle", test_channel_lifecycle, TT_FORK, NULL, NULL },
  607. { "multi", test_channel_multi, TT_FORK, NULL, NULL },
  608. { "queue_size", test_channel_queue_size, TT_FORK, NULL, NULL },
  609. { "write", test_channel_write, TT_FORK, NULL, NULL },
  610. END_OF_TESTCASES
  611. };