浏览代码

Unit tests for microdescriptor cache

May help with tracking down bug #2022
Nick Mathewson 13 年之前
父节点
当前提交
3061a036c8
共有 4 个文件被更改,包括 40 次插入22 次删除
  1. 7 8
      src/or/microdesc.c
  2. 1 1
      src/or/microdesc.h
  3. 1 0
      src/test/Makefile.am
  4. 31 13
      src/test/test.c

+ 7 - 8
src/or/microdesc.c

@@ -316,21 +316,20 @@ microdesc_cache_reload(microdesc_cache_t *cache)
 
 /** DOCDOC */
 void
-microdesc_cache_clean(microdesc_cache_t *cache)
+microdesc_cache_clean(microdesc_cache_t *cache, time_t cutoff, int force)
 {
-  networkstatus_t *consensus;
-  time_t cutoff;
   microdesc_t **mdp, *victim;
   int dropped=0, kept=0;
   size_t bytes_dropped = 0;
   time_t now = time(NULL);
 
   /* If we don't know a consensus, never believe last_listed values */
-  consensus = networkstatus_get_reasonably_live_consensus(now, FLAV_MICRODESC);
-  if (consensus == NULL)
-    return;
+  if (! force &&
+      ! networkstatus_get_reasonably_live_consensus(now, FLAV_MICRODESC))
+      return;
 
-  cutoff = now - TOLERATE_MICRODESC_AGE;
+  if (cutoff <= 0)
+    cutoff = now - TOLERATE_MICRODESC_AGE;
 
   for (mdp = HT_START(microdesc_map, &cache->map); mdp != NULL; ) {
     if ((*mdp)->last_listed < cutoff) {
@@ -368,7 +367,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache)
 
   log_info(LD_DIR, "Rebuilding the microdescriptor cache...");
 
-  microdesc_cache_clean(cache);
+  microdesc_cache_clean(cache, 0/*cutoff*/, 0/*force*/);
 
   orig_size = (int)(cache->cache_content ? cache->cache_content->size : 0);
   orig_size += (int)cache->journal_len;

+ 1 - 1
src/or/microdesc.h

@@ -22,7 +22,7 @@ smartlist_t *microdescs_add_list_to_cache(microdesc_cache_t *cache,
                         smartlist_t *descriptors, saved_location_t where,
                         int no_save);
 
-void microdesc_cache_clean(microdesc_cache_t *cache);
+void microdesc_cache_clean(microdesc_cache_t *cache, time_t cutoff, int force);
 int microdesc_cache_rebuild(microdesc_cache_t *cache);
 int microdesc_cache_reload(microdesc_cache_t *cache);
 void microdesc_cache_clear(microdesc_cache_t *cache);

+ 1 - 0
src/test/Makefile.am

@@ -19,6 +19,7 @@ test_SOURCES = \
 	test_dir.c \
 	test_containers.c \
 	test_util.c \
+	test_microdesc.c \
 	tinytest.c
 
 if USE_BUFFEREVENTS

+ 31 - 13
src/test/test.c

@@ -113,30 +113,46 @@ get_fname(const char *name)
   return buf;
 }
 
-/** Remove all files stored under the temporary directory, and the directory
- * itself.  Called by atexit(). */
+/* Remove a directory and all of its subdirectories */
 static void
-remove_directory(void)
+rm_rf(const char *dir)
 {
+  struct stat st;
   smartlist_t *elements;
-  if (getpid() != temp_dir_setup_in_pid) {
-    /* Only clean out the tempdir when the main process is exiting. */
-    return;
-  }
-  elements = tor_listdir(temp_dir);
+
+  elements = tor_listdir(dir);
   if (elements) {
     SMARTLIST_FOREACH(elements, const char *, cp,
        {
-         size_t len = strlen(cp)+strlen(temp_dir)+16;
-         char *tmp = tor_malloc(len);
-         tor_snprintf(tmp, len, "%s"PATH_SEPARATOR"%s", temp_dir, cp);
-         unlink(tmp);
+         char *tmp = NULL;
+         tor_asprintf(&tmp, "%s"PATH_SEPARATOR"%s", dir, cp);
+         if (0 == stat(tmp,&st) && (st.st_mode & S_IFDIR)) {
+           rm_rf(tmp);
+         } else {
+           if (unlink(tmp)) {
+             fprintf(stderr, "Error removing %s: %s\n", tmp, strerror(errno));
+           }
+         }
          tor_free(tmp);
        });
     SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
     smartlist_free(elements);
   }
-  rmdir(temp_dir);
+  if (rmdir(dir))
+    fprintf(stderr, "Error removing directory %s: %s\n", dir, strerror(errno));
+}
+
+/** Remove all files stored under the temporary directory, and the directory
+ * itself.  Called by atexit(). */
+static void
+remove_directory(void)
+{
+  if (getpid() != temp_dir_setup_in_pid) {
+    /* Only clean out the tempdir when the main process is exiting. */
+    return;
+  }
+
+  rm_rf(temp_dir);
 }
 
 /** Define this if unit tests spend too much time generating public keys*/
@@ -1180,6 +1196,7 @@ extern struct testcase_t crypto_tests[];
 extern struct testcase_t container_tests[];
 extern struct testcase_t util_tests[];
 extern struct testcase_t dir_tests[];
+extern struct testcase_t microdesc_tests[];
 
 static struct testgroup_t testgroups[] = {
   { "", test_array },
@@ -1188,6 +1205,7 @@ static struct testgroup_t testgroups[] = {
   { "container/", container_tests },
   { "util/", util_tests },
   { "dir/", dir_tests },
+  { "dir/md/", microdesc_tests },
   END_OF_GROUPS
 };