Browse Source

White-box tests for the succeeding case of ext_or_port handshake.

(Okay, white-box plus mocking enough other functions so they don't
crash.)
Nick Mathewson 10 years ago
parent
commit
28bb673584
5 changed files with 78 additions and 15 deletions
  1. 2 2
      src/or/connection_or.c
  2. 2 1
      src/or/connection_or.h
  3. 8 8
      src/or/main.c
  4. 4 4
      src/or/main.h
  5. 62 0
      src/test/test_extorport.c

+ 2 - 2
src/or/connection_or.c

@@ -1281,8 +1281,8 @@ connection_or_close_for_error(or_connection_t *orconn, int flush)
  *
  * Return -1 if <b>conn</b> is broken, else return 0.
  */
-int
-connection_tls_start_handshake(or_connection_t *conn, int receiving)
+MOCK_IMPL(int,
+connection_tls_start_handshake,(or_connection_t *conn, int receiving))
 {
   channel_listener_t *chan_listener;
   channel_t *chan;

+ 2 - 1
src/or/connection_or.h

@@ -45,7 +45,8 @@ void connection_or_close_for_error(or_connection_t *orconn, int flush);
 
 void connection_or_report_broken_states(int severity, int domain);
 
-int connection_tls_start_handshake(or_connection_t *conn, int receiving);
+MOCK_DECL(int,connection_tls_start_handshake,(or_connection_t *conn,
+                                              int receiving));
 int connection_tls_continue_handshake(or_connection_t *conn);
 
 int connection_init_or_handshake_state(or_connection_t *conn,

+ 8 - 8
src/or/main.c

@@ -519,8 +519,8 @@ connection_is_reading(connection_t *conn)
 }
 
 /** Tell the main loop to stop notifying <b>conn</b> of any read events. */
-void
-connection_stop_reading(connection_t *conn)
+MOCK_IMPL(void,
+connection_stop_reading,(connection_t *conn))
 {
   tor_assert(conn);
 
@@ -544,8 +544,8 @@ connection_stop_reading(connection_t *conn)
 }
 
 /** Tell the main loop to start notifying <b>conn</b> of any read events. */
-void
-connection_start_reading(connection_t *conn)
+MOCK_IMPL(void,
+connection_start_reading,(connection_t *conn))
 {
   tor_assert(conn);
 
@@ -584,8 +584,8 @@ connection_is_writing(connection_t *conn)
 }
 
 /** Tell the main loop to stop notifying <b>conn</b> of any write events. */
-void
-connection_stop_writing(connection_t *conn)
+MOCK_IMPL(void,
+connection_stop_writing,(connection_t *conn))
 {
   tor_assert(conn);
 
@@ -610,8 +610,8 @@ connection_stop_writing(connection_t *conn)
 }
 
 /** Tell the main loop to start notifying <b>conn</b> of any write events. */
-void
-connection_start_writing(connection_t *conn)
+MOCK_IMPL(void,
+connection_start_writing,(connection_t *conn))
 {
   tor_assert(conn);
 

+ 4 - 4
src/or/main.h

@@ -36,12 +36,12 @@ typedef enum watchable_events {
 } watchable_events_t;
 void connection_watch_events(connection_t *conn, watchable_events_t events);
 int connection_is_reading(connection_t *conn);
-void connection_stop_reading(connection_t *conn);
-void connection_start_reading(connection_t *conn);
+MOCK_DECL(void,connection_stop_reading,(connection_t *conn));
+MOCK_DECL(void,connection_start_reading,(connection_t *conn));
 
 int connection_is_writing(connection_t *conn);
-void connection_stop_writing(connection_t *conn);
-void connection_start_writing(connection_t *conn);
+MOCK_DECL(void,connection_stop_writing,(connection_t *conn));
+MOCK_DECL(void,connection_start_writing,(connection_t *conn));
 
 void connection_stop_reading_from_linked_conn(connection_t *conn);
 

+ 62 - 0
src/test/test_extorport.c

@@ -7,6 +7,7 @@
 #include "or.h"
 #include "buffers.h"
 #include "connection.h"
+#include "connection_or.h"
 #include "config.h"
 #include "control.h"
 #include "ext_orport.h"
@@ -344,6 +345,30 @@ ignore_bootstrap_problem(const char *warn, int reason)
   (void)reason;
 }
 
+static int is_reading = 1;
+static int handshake_start_called = 0;
+
+static void
+note_read_stopped(connection_t *conn)
+{
+  (void)conn;
+  is_reading=0;
+}
+static void
+note_read_started(connection_t *conn)
+{
+  (void)conn;
+  is_reading=1;
+}
+static int
+handshake_start(or_connection_t *conn, int receiving)
+{
+  if (!conn || !receiving)
+    TT_FAIL(("Bad arguments to handshake_start"));
+  handshake_start_called = 1;
+  return 0;
+}
+
 static void
 test_ext_or_handshake(void *arg)
 {
@@ -422,6 +447,10 @@ test_ext_or_handshake(void *arg)
   conn = NULL;
   UNMOCK(control_event_bootstrap_problem);
 
+  MOCK(connection_start_reading, note_read_started);
+  MOCK(connection_stop_reading, note_read_stopped);
+  MOCK(connection_tls_start_handshake, handshake_start);
+
   /* Okay, this time let's succeed. */
   conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
   tt_int_op(0, ==, connection_ext_or_start_auth(conn));
@@ -444,6 +473,39 @@ test_ext_or_handshake(void *arg)
   tt_assert(! TO_CONN(conn)->marked_for_close);
   tt_int_op(TO_CONN(conn)->state, ==, EXT_OR_CONN_STATE_OPEN);
 
+  /* Now let's run through some messages. */
+  /* First let's send some junk and make sure it's ignored. */
+  WRITE("\xff\xf0\x00\x03""ABC", 7);
+  tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
+  CONTAINS("", 0);
+  /* Now let's send a USERADDR command. */
+  WRITE("\x00\x01\x00\x0c""1.2.3.4:5678", 16);
+  tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
+  tt_int_op(TO_CONN(conn)->port, ==, 5678);
+  tt_int_op(tor_addr_to_ipv4h(&TO_CONN(conn)->addr), ==, 0x01020304);
+  /* Now let's send a TRANSPORT command. */
+  WRITE("\x00\x02\x00\x07""rfc1149", 11);
+  tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
+  tt_ptr_op(NULL, !=, conn->ext_or_transport);
+  tt_str_op("rfc1149", ==, conn->ext_or_transport);
+  tt_int_op(is_reading,==,1);
+  tt_int_op(TO_CONN(conn)->state, ==, EXT_OR_CONN_STATE_OPEN);
+  /* DONE */
+  WRITE("\x00\x00\x00\x00", 4);
+  tt_int_op(0, ==, connection_ext_or_process_inbuf(conn));
+  tt_int_op(TO_CONN(conn)->state, ==, EXT_OR_CONN_STATE_FLUSHING);
+  tt_int_op(is_reading,==,0);
+  CONTAINS("\x10\x00\x00\x00", 4);
+  tt_int_op(handshake_start_called,==,0);
+  tt_int_op(0, ==, connection_ext_or_finished_flushing(conn));
+  tt_int_op(is_reading,==,1);
+  tt_int_op(handshake_start_called,==,1);
+  tt_int_op(TO_CONN(conn)->type, ==, CONN_TYPE_OR);
+  /* XXXXX the state is now nonsensical! It should be set to something
+   * neutral (zero?) before we connection_or_change_state; right now
+   * it's EXT_OR_CONN_STATE_FLUSHING */
+  /* tt_int_op(TO_CONN(conn)->state, ==, 0); XXXX */
+
  done:
   UNMOCK(connection_write_to_buf_impl_);
   UNMOCK(crypto_rand);