Back to index

tor  0.2.3.18-rc
Functions | Variables
test_microdesc.c File Reference
#include "orconfig.h"
#include "or.h"
#include "config.h"
#include "microdesc.h"
#include "test.h"
#include <dirent.h>

Go to the source code of this file.

Functions

static void test_md_cache (void *data)

Variables

static const char test_md1 [] = "-----END RSA PUBLIC KEY-----\n"
static const char test_md2 [] = "-----END RSA PUBLIC KEY-----\n"
static const char test_md3 [] = "family nodeX nodeY nodeZ\n"

Function Documentation

static void test_md_cache ( void *  data) [static]

Definition at line 47 of file test_microdesc.c.

{
  or_options_t *options = NULL;
  microdesc_cache_t *mc = NULL ;
  smartlist_t *added = NULL, *wanted = NULL;
  microdesc_t *md1, *md2, *md3;
  char d1[DIGEST256_LEN], d2[DIGEST256_LEN], d3[DIGEST256_LEN];
  const char *test_md3_noannotation = strchr(test_md3, '\n')+1;
  time_t time1, time2, time3;
  char *fn = NULL, *s = NULL;
  (void)data;

  options = get_options_mutable();
  tt_assert(options);

  time1 = time(NULL);
  time2 = time(NULL) - 2*24*60*60;
  time3 = time(NULL) - 15*24*60*60;

  /* Possibly, turn this into a test setup/cleanup pair */
  tor_free(options->DataDirectory);
  options->DataDirectory = tor_strdup(get_fname("md_datadir_test"));
#ifdef _WIN32
  tt_int_op(0, ==, mkdir(options->DataDirectory));
#else
  tt_int_op(0, ==, mkdir(options->DataDirectory, 0700));
#endif

  tt_assert(!strcmpstart(test_md3_noannotation, "onion-key"));

  crypto_digest256(d1, test_md1, strlen(test_md1), DIGEST_SHA256);
  crypto_digest256(d2, test_md2, strlen(test_md1), DIGEST_SHA256);
  crypto_digest256(d3, test_md3_noannotation, strlen(test_md3_noannotation),
                   DIGEST_SHA256);

  mc = get_microdesc_cache();

  added = microdescs_add_to_cache(mc, test_md1, NULL, SAVED_NOWHERE, 0,
                                  time1, NULL);
  tt_int_op(1, ==, smartlist_len(added));
  md1 = smartlist_get(added, 0);
  smartlist_free(added);
  added = NULL;

  wanted = smartlist_new();
  added = microdescs_add_to_cache(mc, test_md2, NULL, SAVED_NOWHERE, 0,
                                  time2, wanted);
  /* Should fail, since we didn't list test_md2's digest in wanted */
  tt_int_op(0, ==, smartlist_len(added));
  smartlist_free(added);
  added = NULL;

  smartlist_add(wanted, tor_memdup(d2, DIGEST256_LEN));
  smartlist_add(wanted, tor_memdup(d3, DIGEST256_LEN));
  added = microdescs_add_to_cache(mc, test_md2, NULL, SAVED_NOWHERE, 0,
                                  time2, wanted);
  /* Now it can work. md2 should have been added */
  tt_int_op(1, ==, smartlist_len(added));
  md2 = smartlist_get(added, 0);
  /* And it should have gotten removed from 'wanted' */
  tt_int_op(smartlist_len(wanted), ==, 1);
  test_mem_op(smartlist_get(wanted, 0), ==, d3, DIGEST256_LEN);
  smartlist_free(added);
  added = NULL;

  added = microdescs_add_to_cache(mc, test_md3, NULL,
                                  SAVED_NOWHERE, 0, -1, NULL);
  /* Must fail, since SAVED_NOWHERE precludes annotations */
  tt_int_op(0, ==, smartlist_len(added));
  smartlist_free(added);
  added = NULL;

  added = microdescs_add_to_cache(mc, test_md3_noannotation, NULL,
                                  SAVED_NOWHERE, 0, time3, NULL);
  /* Now it can work */
  tt_int_op(1, ==, smartlist_len(added));
  md3 = smartlist_get(added, 0);
  smartlist_free(added);
  added = NULL;

  /* Okay.  We added 1...3.  Let's poke them to see how they look, and make
   * sure they're really in the journal. */
  tt_ptr_op(md1, ==, microdesc_cache_lookup_by_digest256(mc, d1));
  tt_ptr_op(md2, ==, microdesc_cache_lookup_by_digest256(mc, d2));
  tt_ptr_op(md3, ==, microdesc_cache_lookup_by_digest256(mc, d3));

  tt_int_op(md1->last_listed, ==, time1);
  tt_int_op(md2->last_listed, ==, time2);
  tt_int_op(md3->last_listed, ==, time3);

  tt_int_op(md1->saved_location, ==, SAVED_IN_JOURNAL);
  tt_int_op(md2->saved_location, ==, SAVED_IN_JOURNAL);
  tt_int_op(md3->saved_location, ==, SAVED_IN_JOURNAL);

  tt_int_op(md1->bodylen, ==, strlen(test_md1));
  tt_int_op(md2->bodylen, ==, strlen(test_md2));
  tt_int_op(md3->bodylen, ==, strlen(test_md3_noannotation));
  test_mem_op(md1->body, ==, test_md1, strlen(test_md1));
  test_mem_op(md2->body, ==, test_md2, strlen(test_md2));
  test_mem_op(md3->body, ==, test_md3_noannotation,
              strlen(test_md3_noannotation));

  tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs.new",
               options->DataDirectory);
  s = read_file_to_str(fn, RFTS_BIN, NULL);
  tt_assert(s);
  test_mem_op(md1->body, ==, s + md1->off, md1->bodylen);
  test_mem_op(md2->body, ==, s + md2->off, md2->bodylen);
  test_mem_op(md3->body, ==, s + md3->off, md3->bodylen);

  tt_ptr_op(md1->family, ==, NULL);
  tt_ptr_op(md3->family, !=, NULL);
  tt_int_op(smartlist_len(md3->family), ==, 3);
  tt_str_op(smartlist_get(md3->family, 0), ==, "nodeX");

  /* Now rebuild the cache! */
  tt_int_op(microdesc_cache_rebuild(mc, 1), ==, 0);

  tt_int_op(md1->saved_location, ==, SAVED_IN_CACHE);
  tt_int_op(md2->saved_location, ==, SAVED_IN_CACHE);
  tt_int_op(md3->saved_location, ==, SAVED_IN_CACHE);

  /* The journal should be empty now */
  tor_free(s);
  s = read_file_to_str(fn, RFTS_BIN, NULL);
  tt_str_op(s, ==, "");
  tor_free(s);
  tor_free(fn);

  /* read the cache. */
  tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
               options->DataDirectory);
  s = read_file_to_str(fn, RFTS_BIN, NULL);
  test_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
  test_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
  test_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));

  /* Okay, now we are going to forget about the cache entirely, and reload it
   * from the disk. */
  microdesc_free_all();
  mc = get_microdesc_cache();
  md1 = microdesc_cache_lookup_by_digest256(mc, d1);
  md2 = microdesc_cache_lookup_by_digest256(mc, d2);
  md3 = microdesc_cache_lookup_by_digest256(mc, d3);
  test_assert(md1);
  test_assert(md2);
  test_assert(md3);
  test_mem_op(md1->body, ==, s + md1->off, strlen(test_md1));
  test_mem_op(md2->body, ==, s + md2->off, strlen(test_md2));
  test_mem_op(md3->body, ==, s + md3->off, strlen(test_md3_noannotation));

  tt_int_op(md1->last_listed, ==, time1);
  tt_int_op(md2->last_listed, ==, time2);
  tt_int_op(md3->last_listed, ==, time3);

  /* Okay, now we are going to clear out everything older than a week old.
   * In practice, that means md3 */
  microdesc_cache_clean(mc, time(NULL)-7*24*60*60, 1/*force*/);
  tt_ptr_op(md1, ==, microdesc_cache_lookup_by_digest256(mc, d1));
  tt_ptr_op(md2, ==, microdesc_cache_lookup_by_digest256(mc, d2));
  tt_ptr_op(NULL, ==, microdesc_cache_lookup_by_digest256(mc, d3));
  md3 = NULL; /* it's history now! */

  /* rebuild again, make sure it stays gone. */
  microdesc_cache_rebuild(mc, 1);
  tt_ptr_op(md1, ==, microdesc_cache_lookup_by_digest256(mc, d1));
  tt_ptr_op(md2, ==, microdesc_cache_lookup_by_digest256(mc, d2));
  tt_ptr_op(NULL, ==, microdesc_cache_lookup_by_digest256(mc, d3));

 done:
  if (options)
    tor_free(options->DataDirectory);
  microdesc_free_all();

  smartlist_free(added);
  if (wanted)
    SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
  smartlist_free(wanted);
  tor_free(s);
  tor_free(fn);
}

Here is the call graph for this function:


Variable Documentation

const char test_md1[] = "-----END RSA PUBLIC KEY-----\n" [static]

Definition at line 19 of file test_microdesc.c.

const char test_md2[] = "-----END RSA PUBLIC KEY-----\n" [static]

Definition at line 27 of file test_microdesc.c.

const char test_md3[] = "family nodeX nodeY nodeZ\n" [static]

Definition at line 35 of file test_microdesc.c.