[tor-commits] [obfsproxy/master] Add unit test for dummy protocol

nickm at torproject.org nickm at torproject.org
Fri Sep 9 17:08:56 UTC 2011


commit 4e90322f70ceaeebc4308d0412262df2e714333b
Author: Zack Weinberg <zackw at panix.com>
Date:   Wed Jul 20 15:14:12 2011 -0700

    Add unit test for dummy protocol
---
 Makefile.am               |    5 +-
 src/test/unittest.c       |    6 +-
 src/test/unittest_dummy.c |  200 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 207 insertions(+), 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index ff518ad..fe47256 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -29,8 +29,9 @@ unittests_SOURCES = \
 	src/test/unittest.c \
 	src/test/unittest_container.c \
 	src/test/unittest_crypt.c \
-	src/test/unittest_obfs2.c \
-	src/test/unittest_socks.c
+	src/test/unittest_socks.c \
+	src/test/unittest_dummy.c \
+	src/test/unittest_obfs2.c
 
 noinst_HEADERS = \
 	src/container.h \
diff --git a/src/test/unittest.c b/src/test/unittest.c
index f872550..6ff938e 100644
--- a/src/test/unittest.c
+++ b/src/test/unittest.c
@@ -7,14 +7,16 @@
 
 extern struct testcase_t container_tests[];
 extern struct testcase_t crypt_tests[];
-extern struct testcase_t obfs2_tests[];
 extern struct testcase_t socks_tests[];
+extern struct testcase_t dummy_tests[];
+extern struct testcase_t obfs2_tests[];
 
 struct testgroup_t groups[] = {
   { "container/", container_tests },
   { "crypt/", crypt_tests },
-  { "obfs2/", obfs2_tests },
   { "socks/", socks_tests },
+  { "dummy/", dummy_tests },
+  { "obfs2/", obfs2_tests },
   END_OF_GROUPS
 };
 
diff --git a/src/test/unittest_dummy.c b/src/test/unittest_dummy.c
new file mode 100644
index 0000000..1739e1f
--- /dev/null
+++ b/src/test/unittest_dummy.c
@@ -0,0 +1,200 @@
+/* Copyright 2011 Nick Mathewson, George Kadianakis
+   See LICENSE for other credits and copying information
+*/
+
+#include "../util.h"
+#include "../protocol.h"
+#include "tinytest_macros.h"
+
+#include <event2/buffer.h>
+
+static void
+test_dummy_option_parsing(void *unused)
+{
+  struct option_parsing_case {
+    struct protocol_params_t *result;
+    short should_succeed;
+    short n_opts;
+    const char *const opts[4];
+  };
+  static struct option_parsing_case cases[] = {
+    /* wrong number of options */
+    { 0, 0, 1, {"dummy"} },
+    { 0, 0, 2, {"dummy", "client"} },
+    { 0, 0, 4, {"dummy", "client", "127.0.0.1:5552", "oops"} },
+    { 0, 0, 4, {"dummy", "--frobozz", "client", "127.0.0.1:5552"} },
+    /* unrecognized mode */
+    { 0, 0, 3, {"dummy", "floodcontrol", "127.0.0.1:5552" } },
+    /* bad address */
+    { 0, 0, 3, {"dummy", "client", "@:5552"} },
+    { 0, 0, 3, {"dummy", "client", "127.0.0.1:notanumber"} },
+    /* should succeed */
+    { 0, 1, 3, {"dummy", "client", "127.0.0.1:5552" } },
+    { 0, 1, 3, {"dummy", "client", "127.0.0.1" } },
+    { 0, 1, 3, {"dummy", "server", "127.0.0.1:5552" } },
+    { 0, 1, 3, {"dummy", "socks", "127.0.0.1:5552" } },
+
+    { 0, 0, 0, {0} }
+  };
+
+  /* Suppress logs for the duration of this function. */
+  log_set_method(LOG_METHOD_NULL, NULL);
+
+  struct option_parsing_case *c;
+  for (c = cases; c->n_opts; c++) {
+    c->result = proto_params_init(c->n_opts, c->opts);
+    if (c->should_succeed)
+      tt_ptr_op(c->result, !=, NULL);
+    else
+      tt_ptr_op(c->result, ==, NULL);
+  }
+
+ end:
+  for (c = cases; c->n_opts; c++)
+    if (c->result)
+      proto_params_free(c->result);
+
+  /* Unsuspend logging */
+  log_set_method(LOG_METHOD_STDOUT, NULL);
+}
+
+/* All the tests below use this test environment: */
+struct test_dummy_state
+{
+  struct protocol_params_t *proto_params_client;
+  struct protocol_params_t *proto_params_server;
+  struct protocol_t *client_proto;
+  struct protocol_t *server_proto;
+  struct evbuffer *output_buffer;
+  struct evbuffer *dummy_buffer;
+};
+
+static int
+cleanup_dummy_state(const struct testcase_t *unused, void *state)
+{
+  struct test_dummy_state *s = (struct test_dummy_state *)state;
+
+  if (s->client_proto)
+      proto_destroy(s->client_proto);
+  if (s->server_proto)
+      proto_destroy(s->server_proto);
+
+  if (s->proto_params_client)
+    proto_params_free(s->proto_params_client);
+  if (s->proto_params_server)
+    proto_params_free(s->proto_params_server);
+
+  if (s->output_buffer)
+    evbuffer_free(s->output_buffer);
+  if (s->dummy_buffer)
+    evbuffer_free(s->dummy_buffer);
+
+  free(state);
+  return 1;
+}
+
+#define ALEN(x) (sizeof x/sizeof x[0])
+
+static const char *const options_client[] =
+  {"dummy", "socks", "127.0.0.1:1800"};
+
+static const char *const options_server[] =
+  {"dummy", "server", "127.0.0.1:1800"};
+
+static void *
+setup_dummy_state(const struct testcase_t *unused)
+{
+  struct test_dummy_state *s = xzalloc(sizeof(struct test_dummy_state));
+
+  s->proto_params_client =
+    proto_params_init(ALEN(options_client), options_client);
+  tt_assert(s->proto_params_client);
+
+  s->proto_params_server =
+    proto_params_init(ALEN(options_server), options_server);
+  tt_assert(s->proto_params_server);
+
+  s->client_proto = proto_create(s->proto_params_client);
+  tt_assert(s->client_proto);
+
+  s->server_proto = proto_create(s->proto_params_server);
+  tt_assert(s->server_proto);
+
+  s->output_buffer = evbuffer_new();
+  tt_assert(s->output_buffer);
+
+  s->dummy_buffer = evbuffer_new();
+  tt_assert(s->dummy_buffer);
+
+  return s;
+
+ end:
+  cleanup_dummy_state(NULL, s);
+  return NULL;
+}
+
+static const struct testcase_setup_t dummy_fixture =
+  { setup_dummy_state, cleanup_dummy_state };
+
+static void
+test_dummy_transfer(void *state)
+{
+  struct test_dummy_state *s = (struct test_dummy_state *)state;
+  int n;
+  struct evbuffer_iovec v[2];
+
+  /* Call the handshake method to satisfy the high-level contract,
+     even though dummy doesn't use a handshake */
+  tt_int_op(proto_handshake(s->client_proto, s->output_buffer), >=, 0);
+
+  /* That should have put nothing into the output buffer */
+  tt_int_op(evbuffer_get_length(s->output_buffer), ==, 0);
+
+  /* Ditto on the server side */
+  tt_int_op(proto_handshake(s->server_proto, s->output_buffer), >=, 0);
+  tt_int_op(evbuffer_get_length(s->output_buffer), ==, 0);
+
+  const char *msg1 = "this is a 54-byte message passed from client to server";
+  const char *msg2 = "this is a 55-byte message passed from server to client!";
+
+  /* client -> server */
+  evbuffer_add(s->dummy_buffer, msg1, 54);
+  proto_send(s->client_proto, s->dummy_buffer, s->output_buffer);
+
+  tt_assert(RECV_GOOD == proto_recv(s->server_proto, s->output_buffer,
+                                    s->dummy_buffer));
+
+  n = evbuffer_peek(s->dummy_buffer, -1, NULL, &v[0], 2);
+  tt_int_op(n, ==, 1); /* expect contiguous data */
+  tt_int_op(0, ==, strncmp(msg1, v[0].iov_base, 54));
+
+  /* emptying dummy_buffer before next test  */
+  size_t buffer_len = evbuffer_get_length(s->dummy_buffer);
+  tt_int_op(0, ==, evbuffer_drain(s->dummy_buffer, buffer_len));
+
+  /* client <- server */
+  evbuffer_add(s->dummy_buffer, msg2, 55);
+  tt_int_op(0, <=, proto_send(s->server_proto, s->dummy_buffer,
+                              s->output_buffer));
+
+  tt_assert(RECV_GOOD == proto_recv(s->client_proto, s->output_buffer,
+                                    s->dummy_buffer));
+
+  n = evbuffer_peek(s->dummy_buffer, -1, NULL, &v[1], 2);
+  tt_int_op(n, ==, 1); /* expect contiguous data */
+  tt_int_op(0, ==, strncmp(msg2, v[1].iov_base, 55));
+
+ end:;
+}
+
+#define T(name) \
+  { #name, test_dummy_##name, 0, NULL, NULL }
+
+#define TF(name) \
+  { #name, test_dummy_##name, 0, &dummy_fixture, NULL }
+
+struct testcase_t dummy_tests[] = {
+  T(option_parsing),
+  TF(transfer),
+  END_OF_TESTCASES
+};





More information about the tor-commits mailing list