Unit tests for microdescriptor cache

May help with tracking down bug #2022
This commit is contained in:
Nick Mathewson 2010-10-07 15:28:54 -04:00
parent 4c71be65d8
commit 3061a036c8
4 changed files with 40 additions and 22 deletions

View File

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

View File

@ -22,7 +22,7 @@ smartlist_t *microdescs_add_list_to_cache(microdesc_cache_t *cache,
smartlist_t *descriptors, saved_location_t where, smartlist_t *descriptors, saved_location_t where,
int no_save); 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_rebuild(microdesc_cache_t *cache);
int microdesc_cache_reload(microdesc_cache_t *cache); int microdesc_cache_reload(microdesc_cache_t *cache);
void microdesc_cache_clear(microdesc_cache_t *cache); void microdesc_cache_clear(microdesc_cache_t *cache);

View File

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

View File

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