commit f12f7159a53f191a981104bae3f87d65a581e1f8 Author: Andrea Shepard andrea@torproject.org Date: Wed Jan 22 02:11:59 2014 -0800
Add channel/flushmux unit test --- src/test/test_channel.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+)
diff --git a/src/test/test_channel.c b/src/test/test_channel.c index 18746df..2f5e946 100644 --- a/src/test/test_channel.c +++ b/src/test/test_channel.c @@ -32,7 +32,12 @@ static int test_doesnt_want_writes_count = 0; static int test_has_waiting_cells_count = 0; static double test_overhead_estimate = 1.0f; static int test_releases_count = 0; +static circuitmux_t *test_target_cmux = NULL; +static unsigned int test_cmux_cells = 0;
+static int chan_test_channel_flush_from_first_active_circuit_mock( + channel_t *chan, int max); +static unsigned int chan_test_circuitmux_num_cells_mock(circuitmux_t *cmux); static void channel_note_destroy_not_pending_mock(channel_t *ch, circid_t circid); static void chan_test_cell_handler(channel_t *ch, @@ -51,6 +56,7 @@ static int chan_test_write_var_cell(channel_t *ch, var_cell_t *var_cell); static void scheduler_channel_doesnt_want_writes_mock(channel_t *ch);
static void test_channel_flush(void *arg); +static void test_channel_flushmux(void *arg); static void test_channel_incoming(void *arg); static void test_channel_lifecycle(void *arg); static void test_channel_multi(void *arg); @@ -67,6 +73,62 @@ channel_note_destroy_not_pending_mock(channel_t *ch, ++test_destroy_not_pending_calls; }
+/** + * If the target cmux is the cmux for chan, make fake cells up to the + * target number of cells and write them to chan. Otherwise, invoke + * the real channel_flush_from_first_active_circuit(). + */ + +static int +chan_test_channel_flush_from_first_active_circuit_mock(channel_t *chan, + int max) +{ + int result = 0, c = 0; + packed_cell_t *cell = NULL; + + test_assert(chan != NULL); + if (test_target_cmux != NULL && + test_target_cmux == chan->cmux) { + while (c <= max && test_cmux_cells > 0) { + cell = packed_cell_new(); + channel_write_packed_cell(chan, cell); + ++c; + --test_cmux_cells; + } + result = c; + } else { + result = channel_flush_from_first_active_circuit__real(chan, max); + } + + done: + return result; +} + +/** + * If we have a target cmux set and this matches it, lie about how + * many cells we have according to the number indicated; otherwise + * pass to the real circuitmux_num_cells(). + */ + +static unsigned int +chan_test_circuitmux_num_cells_mock(circuitmux_t *cmux) +{ + unsigned int result = 0; + + test_assert(cmux != NULL); + if (cmux != NULL) { + if (cmux == test_target_cmux) { + result = test_cmux_cells; + } else { + result = circuitmux_num_cells__real(cmux); + } + } + + done: + + return result; +} + /* * Handle an incoming fixed-size cell for unit tests */ @@ -411,6 +473,61 @@ test_channel_flush(void *arg) return; }
+/** + * Channel flush tests that require cmux mocking + */ + +static void +test_channel_flushmux(void *arg) +{ + channel_t *ch = NULL; + int old_count; + ssize_t result; + + (void)arg; + + init_cell_pool(); + + /* Install mocks we need for this test */ + MOCK(channel_flush_from_first_active_circuit, + chan_test_channel_flush_from_first_active_circuit_mock); + MOCK(circuitmux_num_cells, + chan_test_circuitmux_num_cells_mock); + + ch = new_fake_channel(); + test_assert(ch); + ch->cmux = circuitmux_alloc(); + + old_count = test_cells_written; + + test_target_cmux = ch->cmux; + test_cmux_cells = 1; + + /* Enable cell acceptance */ + test_chan_accept_cells = 1; + + result = channel_flush_some_cells(ch, 1); + + test_eq(result, 1); + test_eq(test_cells_written, old_count + 1); + test_eq(test_cmux_cells, 0); + + test_target_cmux = NULL; + test_cmux_cells = 0; + + done: + tor_free(ch); + + UNMOCK(channel_flush_from_first_active_circuit); + UNMOCK(circuitmux_num_cells); + + test_chan_accept_cells = 0; + + free_cell_pool(); + + return; +} + static void test_channel_incoming(void *arg) { @@ -1291,6 +1408,7 @@ test_channel_write(void *arg)
struct testcase_t channel_tests[] = { { "flush", test_channel_flush, TT_FORK, NULL, NULL }, + { "flushmux", test_channel_flushmux, TT_FORK, NULL, NULL }, { "incoming", test_channel_incoming, TT_FORK, NULL, NULL }, { "lifecycle", test_channel_lifecycle, TT_FORK, NULL, NULL }, { "lifecycle_2", test_channel_lifecycle_2, TT_FORK, NULL, NULL },