Write tests for mark_my_descriptor_dirty_if_too_old()

This commit is contained in:
Nick Mathewson 2018-12-03 14:06:53 -05:00
parent 31a6d9f499
commit a2f81b644b
5 changed files with 109 additions and 6 deletions

View File

@ -724,8 +724,8 @@ networkstatus_vote_find_mutable_entry(networkstatus_t *ns, const char *digest)
/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
* NULL if none was found. */
const routerstatus_t *
networkstatus_vote_find_entry(networkstatus_t *ns, const char *digest)
MOCK_IMPL(const routerstatus_t *,
networkstatus_vote_find_entry,(networkstatus_t *ns, const char *digest))
{
return networkstatus_vote_find_mutable_entry(ns, digest);
}

View File

@ -40,8 +40,9 @@ int compare_digest_to_routerstatus_entry(const void *_key,
const void **_member);
int compare_digest_to_vote_routerstatus_entry(const void *_key,
const void **_member);
const routerstatus_t *networkstatus_vote_find_entry(networkstatus_t *ns,
const char *digest);
MOCK_DECL(const routerstatus_t *,networkstatus_vote_find_entry,(
networkstatus_t *ns,
const char *digest));
routerstatus_t *networkstatus_vote_find_mutable_entry(networkstatus_t *ns,
const char *digest);
int networkstatus_vote_find_entry_idx(networkstatus_t *ns,

View File

@ -1471,9 +1471,9 @@ static extrainfo_t *desc_extrainfo = NULL;
static const char *desc_gen_reason = "uninitialized reason";
/** Since when has our descriptor been "clean"? 0 if we need to regenerate it
* now. */
static time_t desc_clean_since = 0;
STATIC time_t desc_clean_since = 0;
/** Why did we mark the descriptor dirty? */
static const char *desc_dirty_reason = "Tor just started";
STATIC const char *desc_dirty_reason = "Tor just started";
/** Boolean: do we need to regenerate the above? */
static int desc_needs_upload = 0;

View File

@ -117,6 +117,10 @@ void router_free_all(void);
/* Used only by router.c and test.c */
STATIC void get_platform_str(char *platform, size_t len);
STATIC int router_write_fingerprint(int hashed);
#ifdef TOR_UNIT_TESTS
extern time_t desc_clean_since;
extern const char *desc_dirty_reason;
#endif
#endif
#endif /* !defined(TOR_ROUTER_H) */

View File

@ -7,12 +7,17 @@
* \brief Unittests for code in router.c
**/
#define ROUTER_PRIVATE
#include "core/or/or.h"
#include "app/config/config.h"
#include "core/mainloop/mainloop.h"
#include "feature/hibernate/hibernate.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/networkstatus_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerstatus_st.h"
#include "feature/relay/router.h"
#include "feature/stats/rephist.h"
#include "lib/crypt_ops/crypto_curve25519.h"
@ -231,11 +236,104 @@ test_router_check_descriptor_bandwidth_changed(void *arg)
UNMOCK(we_are_hibernating);
}
static networkstatus_t *mock_ns = NULL;
static networkstatus_t *
mock_networkstatus_get_live_consensus(time_t now)
{
(void)now;
return mock_ns;
}
static routerstatus_t *mock_rs = NULL;
static const routerstatus_t *
mock_networkstatus_vote_find_entry(networkstatus_t *ns, const char *digest)
{
(void)ns;
(void)digest;
return mock_rs;
}
static void
test_router_mark_if_too_old(void *arg)
{
(void)arg;
time_t now = approx_time();
MOCK(networkstatus_get_live_consensus,
mock_networkstatus_get_live_consensus);
MOCK(networkstatus_vote_find_entry, mock_networkstatus_vote_find_entry);
routerstatus_t rs;
networkstatus_t ns;
memset(&rs, 0, sizeof(rs));
memset(&ns, 0, sizeof(ns));
mock_ns = &ns;
mock_ns->valid_after = now-3600;
mock_rs = &rs;
mock_rs->published_on = now - 10;
// no reason to mark this time.
desc_clean_since = now-10;
desc_dirty_reason = NULL;
mark_my_descriptor_dirty_if_too_old(now);
tt_i64_op(desc_clean_since, OP_EQ, now-10);
// Doesn't appear in consensus? Still don't mark it.
mock_ns = NULL;
mark_my_descriptor_dirty_if_too_old(now);
tt_i64_op(desc_clean_since, OP_EQ, now-10);
mock_ns = &ns;
// No new descriptor in a long time? Mark it.
desc_clean_since = now - 3600 * 96;
mark_my_descriptor_dirty_if_too_old(now);
tt_i64_op(desc_clean_since, OP_EQ, 0);
tt_str_op(desc_dirty_reason, OP_EQ, "time for new descriptor");
// Version in consensus published a long time ago? We won't mark it
// if it's been clean for only a short time.
desc_clean_since = now - 10;
desc_dirty_reason = NULL;
mock_rs->published_on = now - 3600 * 96;
mark_my_descriptor_dirty_if_too_old(now);
tt_i64_op(desc_clean_since, OP_EQ, now - 10);
// ... but if it's been clean a while, we mark.
desc_clean_since = now - 2 * 3600;
mark_my_descriptor_dirty_if_too_old(now);
tt_i64_op(desc_clean_since, OP_EQ, 0);
tt_str_op(desc_dirty_reason, OP_EQ,
"version listed in consensus is quite old");
// same deal if we're marked stale.
desc_clean_since = now - 2 * 3600;
desc_dirty_reason = NULL;
mock_rs->published_on = now - 10;
mock_rs->is_staledesc = 1;
mark_my_descriptor_dirty_if_too_old(now);
tt_i64_op(desc_clean_since, OP_EQ, 0);
tt_str_op(desc_dirty_reason, OP_EQ,
"listed as stale in consensus");
// same deal if we're absent from the consensus.
desc_clean_since = now - 2 * 3600;
desc_dirty_reason = NULL;
mock_rs = NULL;
mark_my_descriptor_dirty_if_too_old(now);
tt_i64_op(desc_clean_since, OP_EQ, 0);
tt_str_op(desc_dirty_reason, OP_EQ,
"not listed in consensus");
done:
UNMOCK(networkstatus_get_live_consensus);
UNMOCK(networkstatus_vote_find_entry);
}
#define ROUTER_TEST(name, flags) \
{ #name, test_router_ ## name, flags, NULL, NULL }
struct testcase_t router_tests[] = {
ROUTER_TEST(check_descriptor_bandwidth_changed, TT_FORK),
ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method, TT_FORK),
ROUTER_TEST(mark_if_too_old, TT_FORK),
END_OF_TESTCASES
};