[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [tor/master] Unit tests for channel_get_cell_queue_entry_size() and channel_write_*() functions
commit 6d886787e3e112693dc8ac9cda021c93eaefee8b
Author: Andrea Shepard <andrea@xxxxxxxxxxxxxx>
Date: Fri Dec 13 06:34:46 2013 -0800
Unit tests for channel_get_cell_queue_entry_size() and channel_write_*() functions
---
src/test/Makefile.nmake | 2 +-
src/test/include.am | 1 +
src/test/test.c | 3 +
src/test/test_channel.c | 295 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 300 insertions(+), 1 deletion(-)
diff --git a/src/test/Makefile.nmake b/src/test/Makefile.nmake
index 822431f..fceef99 100644
--- a/src/test/Makefile.nmake
+++ b/src/test/Makefile.nmake
@@ -11,7 +11,7 @@ LIBS = ..\..\..\build-alpha\lib\libevent.lib \
ws2_32.lib advapi32.lib shell32.lib \
crypt32.lib gdi32.lib user32.lib
-TEST_OBJECTS = test.obj test_addr.obj test_containers.obj \
+TEST_OBJECTS = test.obj test_addr.obj test_channel.obj test_containers.obj \
test_controller_events.ogj test_crypto.obj test_data.obj test_dir.obj \
test_microdesc.obj test_pt.obj test_util.obj test_config.obj \
test_cell_formats.obj test_replay.obj test_introduce.obj tinytest.obj \
diff --git a/src/test/include.am b/src/test/include.am
index 77c92f1..547f23b 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -20,6 +20,7 @@ src_test_test_SOURCES = \
src/test/test_addr.c \
src/test/test_buffers.c \
src/test/test_cell_formats.c \
+ src/test/test_channel.c \
src/test/test_circuitlist.c \
src/test/test_circuitmux.c \
src/test/test_containers.c \
diff --git a/src/test/test.c b/src/test/test.c
index cfbe203..4d4f6f2 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1308,6 +1308,8 @@ extern struct testcase_t oom_tests[];
extern struct testcase_t policy_tests[];
extern struct testcase_t status_tests[];
extern struct testcase_t routerset_tests[];
+extern struct testcase_t router_tests[];
+extern struct testcase_t channel_tests[];
static struct testgroup_t testgroups[] = {
{ "", test_array },
@@ -1340,6 +1342,7 @@ static struct testgroup_t testgroups[] = {
{ "policy/" , policy_tests },
{ "status/" , status_tests },
{ "routerset/" , routerset_tests },
+ { "channel/", channel_tests },
END_OF_GROUPS
};
diff --git a/src/test/test_channel.c b/src/test/test_channel.c
new file mode 100644
index 0000000..c4241db
--- /dev/null
+++ b/src/test/test_channel.c
@@ -0,0 +1,295 @@
+/* Copyright (c) 2013, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define TOR_CHANNEL_INTERNAL_
+#include "or.h"
+#include "channel.h"
+/* For channel_note_destroy_not_pending */
+#include "circuitlist.h"
+/* For var_cell_free */
+#include "connection_or.h"
+/* For packed_cell stuff */
+#define RELAY_PRIVATE
+#include "relay.h"
+/* For init/free stuff */
+#include "scheduler.h"
+#include "test.h"
+
+static int test_chan_accept_cells = 0;
+static int test_cells_written = 0;
+static int test_destroy_not_pending_calls = 0;
+
+static void channel_note_destroy_not_pending_mock(channel_t *ch,
+ circid_t circid);
+static void chan_test_close(channel_t *ch);
+static size_t chan_test_num_bytes_queued(channel_t *ch);
+static int chan_test_write_cell(channel_t *ch, cell_t *cell);
+static int chan_test_write_packed_cell(channel_t *ch,
+ packed_cell_t *packed_cell);
+static int chan_test_write_var_cell(channel_t *ch, var_cell_t *var_cell);
+static void make_fake_cell(cell_t *c);
+static void make_fake_var_cell(var_cell_t *c);
+static channel_t * new_fake_channel(void);
+static void scheduler_release_channel_mock(channel_t *ch);
+static void test_channel_write(void *arg);
+
+static void
+channel_note_destroy_not_pending_mock(channel_t *ch,
+ circid_t circid)
+{
+ (void)ch;
+ (void)circid;
+
+ ++test_destroy_not_pending_calls;
+}
+
+static void
+chan_test_close(channel_t *ch)
+{
+ test_assert(ch);
+
+ done:
+ return;
+}
+
+static size_t
+chan_test_num_bytes_queued(channel_t *ch)
+{
+ test_assert(ch);
+
+ done:
+ return 0;
+}
+
+static int
+chan_test_write_cell(channel_t *ch, cell_t *cell)
+{
+ int rv = 0;
+
+ test_assert(ch);
+ test_assert(cell);
+
+ if (test_chan_accept_cells) {
+ /* Free the cell and bump the counter */
+ tor_free(cell);
+ ++test_cells_written;
+ rv = 1;
+ }
+ /* else return 0, we didn't accept it */
+
+ done:
+ return rv;
+}
+
+static int
+chan_test_write_packed_cell(channel_t *ch,
+ packed_cell_t *packed_cell)
+{
+ int rv = 0;
+
+ test_assert(ch);
+ test_assert(packed_cell);
+
+ if (test_chan_accept_cells) {
+ /* Free the cell and bump the counter */
+ packed_cell_free(packed_cell);
+ ++test_cells_written;
+ rv = 1;
+ }
+ /* else return 0, we didn't accept it */
+
+ done:
+ return rv;
+}
+
+static int
+chan_test_write_var_cell(channel_t *ch, var_cell_t *var_cell)
+{
+ int rv = 0;
+
+ test_assert(ch);
+ test_assert(var_cell);
+
+ if (test_chan_accept_cells) {
+ /* Free the cell and bump the counter */
+ var_cell_free(var_cell);
+ ++test_cells_written;
+ rv = 1;
+ }
+ /* else return 0, we didn't accept it */
+
+ done:
+ return rv;
+}
+
+static void
+make_fake_cell(cell_t *c)
+{
+ test_assert(c != NULL);
+
+ c->circ_id = 1;
+ c->command = CELL_RELAY;
+ memset(c->payload, 0, CELL_PAYLOAD_SIZE);
+
+ done:
+ return;
+}
+
+static void
+make_fake_var_cell(var_cell_t *c)
+{
+ test_assert(c != NULL);
+
+ c->circ_id = 1;
+ c->command = CELL_VERSIONS;
+ c->payload_len = CELL_PAYLOAD_SIZE / 2;
+ memset(c->payload, 0, c->payload_len);
+
+ done:
+ return;
+}
+
+static channel_t *
+new_fake_channel(void)
+{
+ channel_t *chan = tor_malloc_zero(sizeof(channel_t));
+ channel_init(chan);
+
+ chan->close = chan_test_close;
+ chan->num_bytes_queued = chan_test_num_bytes_queued;
+ chan->write_cell = chan_test_write_cell;
+ chan->write_packed_cell = chan_test_write_packed_cell;
+ chan->write_var_cell = chan_test_write_var_cell;
+ chan->state = CHANNEL_STATE_OPEN;
+
+ return chan;
+}
+
+static void
+scheduler_release_channel_mock(channel_t *ch)
+{
+ (void)ch;
+
+ /* Increment counter */
+ ++test_releases_count;
+
+ return;
+}
+
+static void
+test_channel_write(void *arg)
+{
+ channel_t *ch = NULL;
+ cell_t *cell = tor_malloc_zero(sizeof(cell_t));
+ packed_cell_t *packed_cell = NULL;
+ var_cell_t *var_cell =
+ tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
+ int old_count;
+
+ (void)arg;
+
+ init_cell_pool();
+
+ packed_cell = packed_cell_new();
+ test_assert(packed_cell);
+
+ ch = new_fake_channel();
+ test_assert(ch);
+ make_fake_cell(cell);
+ make_fake_var_cell(var_cell);
+
+ /* Tell it to accept cells */
+ test_chan_accept_cells = 1;
+
+ old_count = test_cells_written;
+ channel_write_cell(ch, cell);
+ test_assert(test_cells_written == old_count + 1);
+
+ channel_write_var_cell(ch, var_cell);
+ test_assert(test_cells_written == old_count + 2);
+
+ channel_write_packed_cell(ch, packed_cell);
+ test_assert(test_cells_written == old_count + 3);
+
+ /* Now we test queueing; tell it not to accept cells */
+ test_chan_accept_cells = 0;
+ /* ...and keep it from trying to flush the queue */
+ ch->state = CHANNEL_STATE_MAINT;
+
+ /* Get a fresh cell */
+ cell = tor_malloc_zero(sizeof(cell_t));
+ make_fake_cell(cell);
+
+ old_count = test_cells_written;
+ channel_write_cell(ch, cell);
+ test_assert(test_cells_written == old_count);
+
+ /*
+ * Now change back to open with channel_change_state() and assert that it
+ * gets drained from the queue.
+ */
+ test_chan_accept_cells = 1;
+ channel_change_state(ch, CHANNEL_STATE_OPEN);
+ test_assert(test_cells_written == old_count + 1);
+
+ /*
+ * Check the note destroy case
+ */
+ cell = tor_malloc_zero(sizeof(cell_t));
+ make_fake_cell(cell);
+ cell->command = CELL_DESTROY;
+
+ /* Set up the mock */
+ MOCK(channel_note_destroy_not_pending,
+ channel_note_destroy_not_pending_mock);
+
+ old_count = test_destroy_not_pending_calls;
+ channel_write_cell(ch, cell);
+ test_assert(test_destroy_not_pending_calls == old_count + 1);
+
+ /* Now send a non-destroy and check we don't call it */
+ cell = tor_malloc_zero(sizeof(cell_t));
+ make_fake_cell(cell);
+ channel_write_cell(ch, cell);
+ test_assert(test_destroy_not_pending_calls == old_count + 1);
+
+ UNMOCK(channel_note_destroy_not_pending);
+
+ /*
+ * Now switch it to CLOSING so we can test the discard-cells case
+ * in the channel_write_*() functions.
+ */
+ MOCK(scheduler_release_channel, scheduler_release_channel_mock);
+ channel_mark_for_close(ch);
+ UNMOCK(scheduler_release_channel);
+
+ /* Send cells that will drop in the closing state */
+ old_count = test_cells_written;
+
+ cell = tor_malloc_zero(sizeof(cell_t));
+ make_fake_cell(cell);
+ channel_write_cell(ch, cell);
+ test_assert(test_cells_written == old_count);
+
+ var_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
+ make_fake_var_cell(var_cell);
+ channel_write_var_cell(ch, var_cell);
+ test_assert(test_cells_written == old_count);
+
+ packed_cell = packed_cell_new();
+ channel_write_packed_cell(ch, packed_cell);
+ test_assert(test_cells_written == old_count);
+
+ free_cell_pool();
+
+ done:
+ tor_free(ch);
+
+ return;
+}
+
+struct testcase_t channel_tests[] = {
+ { "write", test_channel_write, TT_FORK, NULL, NULL },
+ END_OF_TESTCASES
+};
+
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits