浏览代码

Merge remote-tracking branch 'twstrike/directory-tests'

Nick Mathewson 8 年之前
父节点
当前提交
537214d10e
共有 3 个文件被更改,包括 398 次插入28 次删除
  1. 14 14
      src/or/directory.c
  2. 17 8
      src/or/directory.h
  3. 367 6
      src/test/test_dir.c

+ 14 - 14
src/or/directory.c

@@ -143,7 +143,7 @@ purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose)
 
 /** Return a newly allocated string describing <b>auth</b>. Only describes
  * authority features. */
-static char *
+STATIC char *
 authdir_type_to_string(dirinfo_type_t auth)
 {
   char *result;
@@ -162,7 +162,7 @@ authdir_type_to_string(dirinfo_type_t auth)
 }
 
 /** Return a string describing a given directory connection purpose. */
-static const char *
+STATIC const char *
 dir_conn_purpose_to_string(int purpose)
 {
   switch (purpose)
@@ -370,7 +370,7 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
 
 /** Return true iff, according to the values in <b>options</b>, we should be
  * using directory guards for direct downloads of directory information. */
-static int
+STATIC int
 should_use_directory_guards(const or_options_t *options)
 {
   /* Public (non-bridge) servers never use directory guards. */
@@ -669,15 +669,15 @@ directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
  * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
  * want to fetch.
  */
-void
-directory_initiate_command_routerstatus(const routerstatus_t *status,
-                                        uint8_t dir_purpose,
-                                        uint8_t router_purpose,
-                                        dir_indirection_t indirection,
-                                        const char *resource,
-                                        const char *payload,
-                                        size_t payload_len,
-                                        time_t if_modified_since)
+MOCK_IMPL(void, directory_initiate_command_routerstatus,
+                (const routerstatus_t *status,
+                 uint8_t dir_purpose,
+                 uint8_t router_purpose,
+                 dir_indirection_t indirection,
+                 const char *resource,
+                 const char *payload,
+                 size_t payload_len,
+                 time_t if_modified_since))
 {
   directory_initiate_command_routerstatus_rend(status, dir_purpose,
                                           router_purpose,
@@ -2601,7 +2601,7 @@ client_likes_consensus(networkstatus_t *v, const char *want_url)
 
 /** Return the compression level we should use for sending a compressed
  * response of size <b>n_bytes</b>. */
-static zlib_compression_level_t
+STATIC zlib_compression_level_t
 choose_compression_level(ssize_t n_bytes)
 {
   if (! have_been_under_memory_pressure()) {
@@ -3670,7 +3670,7 @@ connection_dir_finished_connecting(dir_connection_t *conn)
  * Then return a list of int pointers defining download delays in seconds.
  * Helper function for download_status_increment_failure(),
  * download_status_reset(), and download_status_increment_attempt(). */
-static const smartlist_t *
+STATIC const smartlist_t *
 find_dl_schedule(download_status_t *dls, const or_options_t *options)
 {
   const int dir_server = dir_server_mode(options);

+ 17 - 8
src/or/directory.h

@@ -39,14 +39,16 @@ typedef enum {
   DIRIND_ANON_DIRPORT,
 } dir_indirection_t;
 
-void directory_initiate_command_routerstatus(const routerstatus_t *status,
-                                             uint8_t dir_purpose,
-                                             uint8_t router_purpose,
-                                             dir_indirection_t indirection,
-                                             const char *resource,
-                                             const char *payload,
-                                             size_t payload_len,
-                                             time_t if_modified_since);
+MOCK_DECL(void, directory_initiate_command_routerstatus,
+                (const routerstatus_t *status,
+                 uint8_t dir_purpose,
+                 uint8_t router_purpose,
+                 dir_indirection_t indirection,
+                 const char *resource,
+                 const char *payload,
+                 size_t payload_len,
+                 time_t if_modified_since));
+
 void directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
                                                   uint8_t dir_purpose,
                                                   uint8_t router_purpose,
@@ -147,6 +149,13 @@ STATIC int connection_dir_would_close_consensus_conn_helper(void);
 STATIC int download_status_schedule_get_delay(download_status_t *dls,
                                               const smartlist_t *schedule,
                                               time_t now);
+
+STATIC char* authdir_type_to_string(dirinfo_type_t auth);
+STATIC const char * dir_conn_purpose_to_string(int purpose);
+STATIC int should_use_directory_guards(const or_options_t *options);
+STATIC zlib_compression_level_t choose_compression_level(ssize_t n_bytes);
+STATIC const smartlist_t *find_dl_schedule(download_status_t *dls,
+                                           const or_options_t *options);
 #endif
 
 #endif

+ 367 - 6
src/test/test_dir.c

@@ -6,19 +6,24 @@
 #include "orconfig.h"
 #include <math.h>
 
+#define CONFIG_PRIVATE
 #define DIRSERV_PRIVATE
 #define DIRVOTE_PRIVATE
 #define ROUTER_PRIVATE
 #define ROUTERLIST_PRIVATE
 #define HIBERNATE_PRIVATE
 #define NETWORKSTATUS_PRIVATE
+#define RELAY_PRIVATE
+
 #include "or.h"
+#include "confparse.h"
 #include "config.h"
 #include "crypto_ed25519.h"
 #include "directory.h"
 #include "dirserv.h"
 #include "dirvote.h"
 #include "hibernate.h"
+#include "memarea.h"
 #include "networkstatus.h"
 #include "router.h"
 #include "routerkeys.h"
@@ -28,6 +33,9 @@
 #include "test.h"
 #include "test_dir_common.h"
 #include "torcert.h"
+#include "relay.h"
+
+#define NS_MODULE dir
 
 static void
 test_dir_nicknames(void *arg)
@@ -489,6 +497,7 @@ test_dir_routerinfo_parsing(void *arg)
 #undef CHECK_FAIL
 #undef CHECK_OK
  done:
+  memarea_clear_freelist();
   routerinfo_free(ri);
 }
 
@@ -591,6 +600,8 @@ test_dir_extrainfo_parsing(void *arg)
 #undef CHECK_FAIL
 
  done:
+  escaped(NULL);
+  memarea_clear_freelist();
   extrainfo_free(ei);
   routerinfo_free(ri);
   digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_);
@@ -3109,12 +3120,33 @@ static void
 test_dir_fetch_type(void *arg)
 {
   (void)arg;
-  tt_assert(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL,
-                           NULL) == MICRODESC_DIRINFO);
-  tt_assert(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_BRIDGE,
-                           NULL) == BRIDGE_DIRINFO);
-  tt_assert(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
-                           "microdesc") == (V3_DIRINFO | MICRODESC_DIRINFO));
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_BRIDGE,
+                           NULL), OP_EQ, EXTRAINFO_DIRINFO | BRIDGE_DIRINFO);
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_EXTRAINFO, ROUTER_PURPOSE_GENERAL,
+                           NULL), OP_EQ, EXTRAINFO_DIRINFO | V3_DIRINFO);
+
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC, ROUTER_PURPOSE_BRIDGE,
+                           NULL), OP_EQ, BRIDGE_DIRINFO);
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_SERVERDESC,
+                           ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
+
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_STATUS_VOTE,
+                           ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
+                           ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CERTIFICATE,
+                           ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, V3_DIRINFO);
+
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
+                           "microdesc"), OP_EQ, V3_DIRINFO|MICRODESC_DIRINFO);
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_CONSENSUS, ROUTER_PURPOSE_GENERAL,
+                           NULL), OP_EQ, V3_DIRINFO);
+
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_MICRODESC, ROUTER_PURPOSE_GENERAL,
+                           NULL), OP_EQ, MICRODESC_DIRINFO);
+
+  tt_int_op(dir_fetch_type(DIR_PURPOSE_FETCH_RENDDESC_V2,
+                           ROUTER_PURPOSE_GENERAL, NULL), OP_EQ, NO_DIRINFO);
  done: ;
 }
 
@@ -3692,6 +3724,327 @@ test_dir_download_status_increment(void *arg)
   mock_get_options_calls = 0;
 }
 
+static void
+test_dir_authdir_type_to_string(void *data)
+{
+  (void)data;
+  char *res;
+
+  tt_str_op(res = authdir_type_to_string(NO_DIRINFO), OP_EQ,
+            "[Not an authority]");
+  tor_free(res);
+
+  tt_str_op(res = authdir_type_to_string(EXTRAINFO_DIRINFO), OP_EQ,
+            "[Not an authority]");
+  tor_free(res);
+
+  tt_str_op(res = authdir_type_to_string(MICRODESC_DIRINFO), OP_EQ,
+            "[Not an authority]");
+  tor_free(res);
+
+  tt_str_op(res = authdir_type_to_string(V3_DIRINFO), OP_EQ, "V3");
+  tor_free(res);
+
+  tt_str_op(res = authdir_type_to_string(BRIDGE_DIRINFO), OP_EQ, "Bridge");
+  tor_free(res);
+
+  tt_str_op(res = authdir_type_to_string(
+            V3_DIRINFO | BRIDGE_DIRINFO | EXTRAINFO_DIRINFO), OP_EQ,
+            "V3, Bridge");
+  done:
+  tor_free(res);
+}
+
+static void
+test_dir_conn_purpose_to_string(void *data)
+{
+  (void)data;
+
+#define EXPECT_CONN_PURPOSE(purpose, expected) \
+  tt_str_op(dir_conn_purpose_to_string(purpose), OP_EQ, expected);
+
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_DIR, "server descriptor upload");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_VOTE, "server vote upload");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_SIGNATURES,
+                      "consensus signature upload");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_SERVERDESC, "server descriptor fetch");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_EXTRAINFO, "extra-info fetch");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CONSENSUS,
+                      "consensus network-status fetch");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_CERTIFICATE, "authority cert fetch");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_STATUS_VOTE, "status vote fetch");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES,
+                      "consensus signature fetch");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_RENDDESC_V2,
+                      "hidden-service v2 descriptor fetch");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_UPLOAD_RENDDESC_V2,
+                      "hidden-service v2 descriptor upload");
+  EXPECT_CONN_PURPOSE(DIR_PURPOSE_FETCH_MICRODESC, "microdescriptor fetch");
+  EXPECT_CONN_PURPOSE(1024, "(unknown)");
+
+  done: ;
+}
+
+NS_DECL(int,
+public_server_mode, (const or_options_t *options));
+
+static int
+NS(public_server_mode)(const or_options_t *options)
+{
+  (void)options;
+
+  if (CALLED(public_server_mode)++ == 0) {
+    return 1;
+  }
+
+  return 0;
+}
+
+static void
+test_dir_should_use_directory_guards(void *data)
+{
+  or_options_t *options;
+  char *errmsg = NULL;
+  (void)data;
+
+  NS_MOCK(public_server_mode);
+
+  options = options_new();
+  options_init(options);
+
+  tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
+  tt_int_op(CALLED(public_server_mode), OP_EQ, 1);
+
+  options->UseEntryGuardsAsDirGuards = 1;
+  options->UseEntryGuards = 1;
+  options->DownloadExtraInfo = 0;
+  options->FetchDirInfoEarly = 0;
+  options->FetchDirInfoExtraEarly = 0;
+  options->FetchUselessDescriptors = 0;
+  tt_int_op(should_use_directory_guards(options), OP_EQ, 1);
+  tt_int_op(CALLED(public_server_mode), OP_EQ, 2);
+
+  options->UseEntryGuards = 0;
+  tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
+  tt_int_op(CALLED(public_server_mode), OP_EQ, 3);
+  options->UseEntryGuards = 1;
+
+  options->UseEntryGuardsAsDirGuards = 0;
+  tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
+  tt_int_op(CALLED(public_server_mode), OP_EQ, 4);
+  options->UseEntryGuardsAsDirGuards = 1;
+
+  options->DownloadExtraInfo = 1;
+  tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
+  tt_int_op(CALLED(public_server_mode), OP_EQ, 5);
+  options->DownloadExtraInfo = 0;
+
+  options->FetchDirInfoEarly = 1;
+  tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
+  tt_int_op(CALLED(public_server_mode), OP_EQ, 6);
+  options->FetchDirInfoEarly = 0;
+
+  options->FetchDirInfoExtraEarly = 1;
+  tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
+  tt_int_op(CALLED(public_server_mode), OP_EQ, 7);
+  options->FetchDirInfoExtraEarly = 0;
+
+  options->FetchUselessDescriptors = 1;
+  tt_int_op(should_use_directory_guards(options), OP_EQ, 0);
+  tt_int_op(CALLED(public_server_mode), OP_EQ, 8);
+  options->FetchUselessDescriptors = 0;
+
+  done:
+    NS_UNMOCK(public_server_mode);
+    or_options_free(options);
+    tor_free(errmsg);
+}
+
+NS_DECL(void,
+directory_initiate_command_routerstatus, (const routerstatus_t *status,
+                                          uint8_t dir_purpose,
+                                          uint8_t router_purpose,
+                                          dir_indirection_t indirection,
+                                          const char *resource,
+                                          const char *payload,
+                                          size_t payload_len,
+                                          time_t if_modified_since));
+
+static void
+test_dir_should_not_init_request_to_ourselves(void *data)
+{
+  char digest[DIGEST_LEN];
+  dir_server_t *ourself = NULL;
+  crypto_pk_t *key = pk_generate(2);
+  (void) data;
+
+  NS_MOCK(directory_initiate_command_routerstatus);
+
+  clear_dir_servers();
+  routerlist_free_all();
+
+  set_server_identity_key(key);
+  crypto_pk_get_digest(key, (char*) &digest);
+  ourself = trusted_dir_server_new("ourself", "127.0.0.1", 9059, 9060, digest,
+                                   NULL, V3_DIRINFO, 1.0);
+
+  tt_assert(ourself);
+  dir_server_add(ourself);
+
+  directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
+  tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0);
+
+  directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
+                                     NULL);
+
+  tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0);
+
+  done:
+    NS_UNMOCK(directory_initiate_command_routerstatus);
+    clear_dir_servers();
+    routerlist_free_all();
+    crypto_pk_free(key);
+}
+
+static void
+test_dir_should_not_init_request_to_dir_auths_without_v3_info(void *data)
+{
+  dir_server_t *ds = NULL;
+  dirinfo_type_t dirinfo_type = BRIDGE_DIRINFO | EXTRAINFO_DIRINFO \
+                                | MICRODESC_DIRINFO;
+  (void) data;
+
+  NS_MOCK(directory_initiate_command_routerstatus);
+
+  clear_dir_servers();
+  routerlist_free_all();
+
+  ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060,
+                              "12345678901234567890", NULL, dirinfo_type, 1.0);
+  tt_assert(ds);
+  dir_server_add(ds);
+
+  directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
+  tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0);
+
+  directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
+                                     NULL);
+  tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 0);
+
+  done:
+    NS_UNMOCK(directory_initiate_command_routerstatus);
+    clear_dir_servers();
+    routerlist_free_all();
+}
+
+static void
+test_dir_should_init_request_to_dir_auths(void *data)
+{
+  dir_server_t *ds = NULL;
+  (void) data;
+
+  NS_MOCK(directory_initiate_command_routerstatus);
+
+  clear_dir_servers();
+  routerlist_free_all();
+
+  ds = trusted_dir_server_new("ds", "10.0.0.1", 9059, 9060,
+                              "12345678901234567890", NULL, V3_DIRINFO, 1.0);
+  tt_assert(ds);
+  dir_server_add(ds);
+
+  directory_get_from_all_authorities(DIR_PURPOSE_FETCH_STATUS_VOTE, 0, NULL);
+  tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 1);
+
+  directory_get_from_all_authorities(DIR_PURPOSE_FETCH_DETACHED_SIGNATURES, 0,
+                                     NULL);
+  tt_int_op(CALLED(directory_initiate_command_routerstatus), OP_EQ, 2);
+
+  done:
+    NS_UNMOCK(directory_initiate_command_routerstatus);
+    clear_dir_servers();
+    routerlist_free_all();
+}
+
+void
+NS(directory_initiate_command_routerstatus)(const routerstatus_t *status,
+                                            uint8_t dir_purpose,
+                                            uint8_t router_purpose,
+                                            dir_indirection_t indirection,
+                                            const char *resource,
+                                            const char *payload,
+                                            size_t payload_len,
+                                            time_t if_modified_since)
+{
+  (void)status;
+  (void)dir_purpose;
+  (void)router_purpose;
+  (void)indirection;
+  (void)resource;
+  (void)payload;
+  (void)payload_len;
+  (void)if_modified_since;
+  CALLED(directory_initiate_command_routerstatus)++;
+}
+
+static void
+test_dir_choose_compression_level(void* data)
+{
+  (void)data;
+
+  /* It starts under_memory_pressure */
+  tt_int_op(have_been_under_memory_pressure(), OP_EQ, 1);
+
+  tt_assert(HIGH_COMPRESSION == choose_compression_level(-1));
+  tt_assert(LOW_COMPRESSION == choose_compression_level(1024-1));
+  tt_assert(MEDIUM_COMPRESSION == choose_compression_level(2048-1));
+  tt_assert(HIGH_COMPRESSION == choose_compression_level(2048));
+
+  /* Reset under_memory_pressure timer */
+  cell_queues_check_size();
+  tt_int_op(have_been_under_memory_pressure(), OP_EQ, 0);
+
+  tt_assert(HIGH_COMPRESSION == choose_compression_level(-1));
+  tt_assert(HIGH_COMPRESSION == choose_compression_level(1024-1));
+  tt_assert(HIGH_COMPRESSION == choose_compression_level(2048-1));
+  tt_assert(HIGH_COMPRESSION == choose_compression_level(2048));
+
+  done: ;
+}
+
+static void
+test_dir_find_dl_schedule_and_len(void* data)
+{
+  download_status_t dls;
+  smartlist_t server, client, server_cons, client_cons, bridge;
+  (void)data;
+
+  mock_options = malloc(sizeof(or_options_t));
+  reset_options(mock_options, &mock_get_options_calls);
+  MOCK(get_options, mock_get_options);
+
+  mock_options->TestingServerDownloadSchedule = &server;
+  mock_options->TestingClientDownloadSchedule = &client;
+  mock_options->TestingServerConsensusDownloadSchedule = &server_cons;
+  mock_options->TestingClientConsensusDownloadSchedule = &client_cons;
+  mock_options->TestingBridgeDownloadSchedule = &bridge;
+
+  dls.schedule = DL_SCHED_GENERIC;
+  tt_ptr_op(find_dl_schedule_and_len(&dls, 0), OP_EQ, &client);
+  tt_ptr_op(find_dl_schedule_and_len(&dls, 1), OP_EQ, &server);
+
+  dls.schedule = DL_SCHED_CONSENSUS;
+  tt_ptr_op(find_dl_schedule_and_len(&dls, 0), OP_EQ, &client_cons);
+  tt_ptr_op(find_dl_schedule_and_len(&dls, 1), OP_EQ, &server_cons);
+
+  dls.schedule = DL_SCHED_BRIDGE;
+  tt_ptr_op(find_dl_schedule_and_len(&dls, 0), OP_EQ, &bridge);
+  tt_ptr_op(find_dl_schedule_and_len(&dls, 1), OP_EQ, &bridge);
+
+  done:
+    UNMOCK(get_options);
+}
+
 #define DIR_LEGACY(name)                                                   \
   { #name, test_dir_ ## name , TT_FORK, NULL, NULL }
 
@@ -3725,6 +4078,14 @@ struct testcase_t dir_tests[] = {
   DIR(packages, 0),
   DIR(download_status_schedule, 0),
   DIR(download_status_increment, 0),
+  DIR(authdir_type_to_string, 0),
+  DIR(conn_purpose_to_string, 0),
+  DIR(should_use_directory_guards, 0),
+  DIR(should_not_init_request_to_ourselves, TT_FORK),
+  DIR(should_not_init_request_to_dir_auths_without_v3_info, 0),
+  DIR(should_init_request_to_dir_auths, 0),
+  DIR(choose_compression_level, 0),
+  DIR(find_dl_schedule_and_len, 0),
   END_OF_TESTCASES
 };