commit f12f7159a53f191a981104bae3f87d65a581e1f8
Author: Andrea Shepard <andrea(a)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 },