[tor-commits] [tor/master] Add unit test for ClientTransportPlugin/ServerTransportPlugin config line parsing

nickm at torproject.org nickm at torproject.org
Tue Nov 4 14:56:57 UTC 2014


commit 5d81fd25a0558794902b93d0d73c0f0134ccfce6
Author: Andrea Shepard <andrea at torproject.org>
Date:   Fri Jul 25 21:42:12 2014 -0700

    Add unit test for ClientTransportPlugin/ServerTransportPlugin config line parsing
---
 src/test/test_config.c |  248 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 248 insertions(+)

diff --git a/src/test/test_config.c b/src/test/test_config.c
index b35984f..5975e1e 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -14,6 +14,8 @@
 #include "test.h"
 #include "util.h"
 #include "address.h"
+#include "entrynodes.h"
+#include "transports.h"
 
 static void
 test_config_addressmap(void *arg)
@@ -552,6 +554,251 @@ test_config_parse_transport_options_line(void *arg)
   }
 }
 
+/* Mocks needed for the transport plugin line test */
+
+static void pt_kickstart_proxy_mock(const smartlist_t *transport_list,
+                                    char **proxy_argv, int is_server);
+static int transport_add_from_config_mock(const tor_addr_t *addr,
+                                          uint16_t port, const char *name,
+                                          int socks_ver);
+static int transport_is_needed_mock(const char *transport_name);
+
+static int pt_kickstart_proxy_mock_call_count = 0;
+static int transport_add_from_config_mock_call_count = 0;
+static int transport_is_needed_mock_call_count = 0;
+static int transport_is_needed_mock_return = 0;
+
+static void
+pt_kickstart_proxy_mock(const smartlist_t *transport_list,
+                        char **proxy_argv, int is_server)
+{
+  ++pt_kickstart_proxy_mock_call_count;
+}
+
+static int
+transport_add_from_config_mock(const tor_addr_t *addr,
+                               uint16_t port, const char *name,
+                               int socks_ver)
+{
+  ++transport_add_from_config_mock_call_count;
+
+  return 0;
+}
+
+static int
+transport_is_needed_mock(const char *transport_name)
+{
+  ++transport_is_needed_mock_call_count;
+
+  return transport_is_needed_mock_return;
+}
+
+/**
+ * Test parsing for the ClientTransportPlugin and ServerTransportPlugin config
+ * options.
+ */
+
+static void
+test_config_parse_transport_plugin_line(void *arg)
+{
+  or_options_t *options = get_options_mutable();
+  int r, tmp;
+  int old_pt_kickstart_proxy_mock_call_count;
+  int old_transport_add_from_config_mock_call_count;
+  int old_transport_is_needed_mock_call_count;
+
+  /* Bad transport lines - too short */
+  r = parse_client_transport_line(options, "bad", 1);
+  test_assert(r < 0);
+  r = parse_server_transport_line(options, "bad", 1);
+  test_assert(r < 0);
+  r = parse_client_transport_line(options, "bad bad", 1);
+  test_assert(r < 0);
+  r = parse_server_transport_line(options, "bad bad", 1);
+  test_assert(r < 0);
+
+  /* Test transport list parsing */
+  r = parse_client_transport_line(options,
+      "transport_1 exec /usr/bin/fake-transport", 1);
+  test_assert(r == 0);
+  r = parse_server_transport_line(options,
+   "transport_1 exec /usr/bin/fake-transport", 1);
+  test_assert(r == 0);
+  r = parse_client_transport_line(options,
+      "transport_1,transport_2 exec /usr/bin/fake-transport", 1);
+  test_assert(r == 0);
+  r = parse_server_transport_line(options,
+      "transport_1,transport_2 exec /usr/bin/fake-transport", 1);
+  test_assert(r == 0);
+  /* Bad transport identifiers */
+  r = parse_client_transport_line(options,
+      "transport_* exec /usr/bin/fake-transport", 1);
+  test_assert(r < 0);
+  r = parse_server_transport_line(options,
+      "transport_* exec /usr/bin/fake-transport", 1);
+  test_assert(r < 0);
+
+  /* Check SOCKS cases for client transport */
+  r = parse_client_transport_line(options,
+      "transport_1 socks4 1.2.3.4:567", 1);
+  test_assert(r == 0);
+  r = parse_client_transport_line(options,
+      "transport_1 socks5 1.2.3.4:567", 1);
+  test_assert(r == 0);
+  /* Proxy case for server transport */
+  r = parse_server_transport_line(options,
+      "transport_1 proxy 1.2.3.4:567", 1);
+  test_assert(r == 0);
+  /* Multiple-transport error exit */
+  r = parse_client_transport_line(options,
+      "transport_1,transport_2 socks5 1.2.3.4:567", 1);
+  test_assert(r < 0);
+  r = parse_server_transport_line(options,
+      "transport_1,transport_2 proxy 1.2.3.4:567", 1);
+  /* No port error exit */
+  r = parse_client_transport_line(options,
+      "transport_1 socks5 1.2.3.4", 1);
+  test_assert(r < 0);
+  r = parse_server_transport_line(options,
+     "transport_1 proxy 1.2.3.4", 1);
+  test_assert(r < 0);
+  /* Unparsable address error exit */
+  r = parse_client_transport_line(options,
+      "transport_1 socks5 1.2.3:6x7", 1);
+  test_assert(r < 0);
+  r = parse_server_transport_line(options,
+      "transport_1 proxy 1.2.3:6x7", 1);
+  test_assert(r < 0);
+
+  /* "Strange {Client|Server}TransportPlugin field" error exit */
+  r = parse_client_transport_line(options,
+      "transport_1 foo bar", 1);
+  test_assert(r < 0);
+  r = parse_server_transport_line(options,
+      "transport_1 foo bar", 1);
+  test_assert(r < 0);
+
+  /* No sandbox mode error exit */
+  tmp = options->Sandbox;
+  options->Sandbox = 1;
+  r = parse_client_transport_line(options,
+      "transport_1 exec /usr/bin/fake-transport", 1);
+  test_assert(r < 0);
+  r = parse_server_transport_line(options,
+      "transport_1 exec /usr/bin/fake-transport", 1);
+  test_assert(r < 0);
+  options->Sandbox = tmp;
+
+  /*
+   * These final test cases cover code paths that only activate without
+   * validate_only, so they need mocks in place.
+   */
+  MOCK(pt_kickstart_proxy, pt_kickstart_proxy_mock);
+  old_pt_kickstart_proxy_mock_call_count =
+    pt_kickstart_proxy_mock_call_count;
+  r = parse_server_transport_line(options,
+      "transport_1 exec /usr/bin/fake-transport", 0);
+  test_assert(r == 0);
+  test_assert(pt_kickstart_proxy_mock_call_count ==
+      old_pt_kickstart_proxy_mock_call_count + 1);
+  UNMOCK(pt_kickstart_proxy);
+
+  /* This one hits a log line in the !validate_only case only */
+  r = parse_server_transport_line(options,
+      "transport_1 proxy 1.2.3.4:567", 0);
+  test_assert(r == 0);
+
+  /* Check mocked client transport cases */
+  MOCK(pt_kickstart_proxy, pt_kickstart_proxy_mock);
+  MOCK(transport_add_from_config, transport_add_from_config_mock);
+  MOCK(transport_is_needed, transport_is_needed_mock);
+
+  /* Unnecessary transport case */
+  transport_is_needed_mock_return = 0;
+  old_pt_kickstart_proxy_mock_call_count =
+    pt_kickstart_proxy_mock_call_count;
+  old_transport_add_from_config_mock_call_count =
+    transport_add_from_config_mock_call_count;
+  old_transport_is_needed_mock_call_count =
+    transport_is_needed_mock_call_count;
+  r = parse_client_transport_line(options,
+      "transport_1 exec /usr/bin/fake-transport", 0);
+  /* Should have succeeded */
+  test_assert(r == 0);
+  /* transport_is_needed() should have been called */
+  test_assert(transport_is_needed_mock_call_count ==
+      old_transport_is_needed_mock_call_count + 1);
+  /*
+   * pt_kickstart_proxy() and transport_add_from_config() should
+   * not have been called.
+   */
+  test_assert(pt_kickstart_proxy_mock_call_count ==
+      old_pt_kickstart_proxy_mock_call_count);
+  test_assert(transport_add_from_config_mock_call_count ==
+      old_transport_add_from_config_mock_call_count);
+
+  /* Necessary transport case */
+  transport_is_needed_mock_return = 1;
+  old_pt_kickstart_proxy_mock_call_count =
+    pt_kickstart_proxy_mock_call_count;
+  old_transport_add_from_config_mock_call_count =
+    transport_add_from_config_mock_call_count;
+  old_transport_is_needed_mock_call_count =
+    transport_is_needed_mock_call_count;
+  r = parse_client_transport_line(options,
+      "transport_1 exec /usr/bin/fake-transport", 0);
+  /* Should have succeeded */
+  test_assert(r == 0);
+  /*
+   * transport_is_needed() and pt_kickstart_proxy() should have been
+   * called.
+   */
+  test_assert(pt_kickstart_proxy_mock_call_count ==
+      old_pt_kickstart_proxy_mock_call_count + 1);
+  test_assert(transport_is_needed_mock_call_count ==
+      old_transport_is_needed_mock_call_count + 1);
+  /* transport_add_from_config() should not have been called. */
+  test_assert(transport_add_from_config_mock_call_count ==
+      old_transport_add_from_config_mock_call_count);
+
+  /* proxy case */
+  transport_is_needed_mock_return = 1;
+  old_pt_kickstart_proxy_mock_call_count =
+    pt_kickstart_proxy_mock_call_count;
+  old_transport_add_from_config_mock_call_count =
+    transport_add_from_config_mock_call_count;
+  old_transport_is_needed_mock_call_count =
+    transport_is_needed_mock_call_count;
+  r = parse_client_transport_line(options,
+      "transport_1 socks5 1.2.3.4:567", 0);
+  /* Should have succeeded */
+  test_assert(r == 0);
+  /*
+   * transport_is_needed() and transport_add_from_config() should have
+   * been called.
+   */
+  test_assert(transport_add_from_config_mock_call_count ==
+      old_transport_add_from_config_mock_call_count + 1);
+  test_assert(transport_is_needed_mock_call_count ==
+      old_transport_is_needed_mock_call_count + 1);
+  /* pt_kickstart_proxy() should not have been called. */
+  test_assert(pt_kickstart_proxy_mock_call_count ==
+      old_pt_kickstart_proxy_mock_call_count);
+
+  /* Done with mocked client transport cases */
+  UNMOCK(transport_is_needed);
+  UNMOCK(transport_add_from_config);
+  UNMOCK(pt_kickstart_proxy);
+
+ done:
+  /* Make sure we undo all mocks */
+  UNMOCK(pt_kickstart_proxy);
+  UNMOCK(transport_add_from_config);
+  UNMOCK(transport_is_needed);
+
+  return;
+}
+
 // Tests if an options with MyFamily fingerprints missing '$' normalises
 // them correctly and also ensure it also works with multiple fingerprints
 static void
@@ -596,6 +843,7 @@ struct testcase_t config_tests[] = {
   CONFIG_TEST(addressmap, 0),
   CONFIG_TEST(parse_bridge_line, 0),
   CONFIG_TEST(parse_transport_options_line, 0),
+  CONFIG_TEST(parse_transport_plugin_line, TT_FORK),
   CONFIG_TEST(check_or_create_data_subdir, TT_FORK),
   CONFIG_TEST(write_to_data_subdir, TT_FORK),
   CONFIG_TEST(fix_my_family, 0),





More information about the tor-commits mailing list