Write unittests for v3 metrics.

This commit is contained in:
George Kadianakis 2020-10-21 14:17:30 +03:00
parent 5c00bee1b1
commit 131da887d7
5 changed files with 152 additions and 12 deletions

View File

@ -1871,8 +1871,8 @@ rep_hist_reset_hs_v3_stats(time_t now)
* on the real network) and hence we don't want to collect statistics if it's
* not yet the time to do so.
*/
static bool
should_collect_v3_stats(void)
MOCK_IMPL(STATIC bool,
should_collect_v3_stats,(void))
{
return start_of_hs_v3_stats_interval <= approx_time();
}
@ -1973,7 +1973,7 @@ rep_hist_hs_stats_term(void)
/** Allocate and return a string containing hidden service stats that
* are meant to be placed in the extra-info descriptor. */
static char *
STATIC char *
rep_hist_format_hs_v2_stats(time_t now)
{
char t[ISO_TIME_LEN+1];

View File

@ -117,6 +117,9 @@ typedef struct hs_v3_stats_t {
STATIC char *rep_hist_format_hs_v2_stats(time_t now);
STATIC char *rep_hist_format_hs_v3_stats(time_t now);
MOCK_DECL(STATIC bool, should_collect_v3_stats,(void));
#endif /* defined(REPHIST_PRIVATE) */
/**
@ -145,10 +148,10 @@ void rep_hist_prep_published_padding_counts(time_t now);
void rep_hist_padding_count_timers(uint64_t num_timers);
#ifdef TOR_UNIT_TESTS
typedef struct hs_v2_stats_t hs_v2_stats_t;
const hs_v2_stats_t *rep_hist_get_hs_v2_stats(void);
typedef struct hs_v3_stats_t hs_v3_stats_t;
const hs_v3_stats_t *rep_hist_get_hs_v3_stats(void);
struct hs_v2_stats_t;
const struct hs_v2_stats_t *rep_hist_get_hs_v2_stats(void);
struct hs_v3_stats_t;
const struct hs_v3_stats_t *rep_hist_get_hs_v3_stats(void);
#endif
#endif /* !defined(TOR_REPHIST_H) */

View File

@ -134,7 +134,8 @@ hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now,
* points are added. */
static hs_descriptor_t *
hs_helper_build_hs_desc_impl(unsigned int no_ip,
const ed25519_keypair_t *signing_kp)
const ed25519_keypair_t *signing_kp,
uint64_t rev_counter)
{
int ret;
int i;
@ -161,7 +162,7 @@ hs_helper_build_hs_desc_impl(unsigned int no_ip,
&signing_kp->pubkey, now, 3600,
CERT_FLAG_INCLUDE_SIGNING_KEY);
tt_assert(desc->plaintext_data.signing_key_cert);
desc->plaintext_data.revision_counter = 42;
desc->plaintext_data.revision_counter = rev_counter;
desc->plaintext_data.lifetime_sec = 3 * 60 * 60;
hs_get_subcredential(&signing_kp->pubkey, &blinded_kp.pubkey,
@ -226,18 +227,26 @@ hs_helper_get_subcred_from_identity_keypair(ed25519_keypair_t *signing_kp,
subcred_out);
}
/* Build a descriptor with a specific rev counter. */
hs_descriptor_t *
hs_helper_build_hs_desc_with_rev_counter(const ed25519_keypair_t *signing_kp,
uint64_t revision_counter)
{
return hs_helper_build_hs_desc_impl(0, signing_kp, revision_counter);
}
/* Build a descriptor with introduction points. */
hs_descriptor_t *
hs_helper_build_hs_desc_with_ip(const ed25519_keypair_t *signing_kp)
{
return hs_helper_build_hs_desc_impl(0, signing_kp);
return hs_helper_build_hs_desc_impl(0, signing_kp, 42);
}
/* Build a descriptor without any introduction points. */
hs_descriptor_t *
hs_helper_build_hs_desc_no_ip(const ed25519_keypair_t *signing_kp)
{
return hs_helper_build_hs_desc_impl(1, signing_kp);
return hs_helper_build_hs_desc_impl(1, signing_kp, 42);
}
hs_descriptor_t *
@ -247,7 +256,7 @@ hs_helper_build_hs_desc_with_client_auth(
const ed25519_keypair_t *signing_kp)
{
curve25519_keypair_t auth_ephemeral_kp;
hs_descriptor_t *desc = hs_helper_build_hs_desc_impl(0, signing_kp);
hs_descriptor_t *desc = hs_helper_build_hs_desc_impl(0, signing_kp, 42);
hs_desc_authorized_client_t *desc_client;
/* The number of client authorized auth has tobe a multiple of

View File

@ -17,6 +17,10 @@ hs_descriptor_t *hs_helper_build_hs_desc_no_ip(
const ed25519_keypair_t *signing_kp);
hs_descriptor_t *hs_helper_build_hs_desc_with_ip(
const ed25519_keypair_t *signing_kp);
hs_descriptor_t *
hs_helper_build_hs_desc_with_rev_counter(const ed25519_keypair_t *signing_kp,
uint64_t revision_counter);
hs_descriptor_t *hs_helper_build_hs_desc_with_client_auth(
const uint8_t *descriptor_cookie,
const curve25519_public_key_t *client_pk,

View File

@ -12,6 +12,8 @@
#include "lib/crypt_ops/crypto_rand.h"
#include "app/config/or_state_st.h"
#include "test/rng_test_helpers.h"
#include "feature/hs/hs_cache.h"
#include "test/hs_test_helpers.h"
#include <stdio.h>
@ -31,6 +33,7 @@
#define MAINLOOP_PRIVATE
#define STATEFILE_PRIVATE
#define BWHIST_PRIVATE
#define REPHIST_PRIVATE
#include "core/or/or.h"
#include "lib/err/backtrace.h"
@ -493,6 +496,126 @@ test_get_bandwidth_lines(void *arg)
bwhist_free_all();
}
static bool
mock_should_collect_v3_stats(void)
{
return true;
}
/* Test v3 metrics */
static void
test_rephist_v3_onions(void *arg)
{
int ret;
char *stats_string = NULL;
char *desc1_str = NULL;
ed25519_keypair_t signing_kp1;
hs_descriptor_t *desc1 = NULL;
const hs_v3_stats_t *hs_v3_stats = NULL;
(void) arg;
MOCK(should_collect_v3_stats, mock_should_collect_v3_stats);
get_options_mutable()->HiddenServiceStatistics = 1;
/* Initialize the subsystems */
hs_cache_init();
rep_hist_hs_stats_init(0);
update_approx_time(10101010101);
/* HS stats should be zero here */
hs_v3_stats = rep_hist_get_hs_v3_stats();
tt_int_op(digestmap_size(hs_v3_stats->v3_onions_seen_this_period), OP_EQ, 0);
/* Generate a valid descriptor */
ret = ed25519_keypair_generate(&signing_kp1, 0);
tt_int_op(ret, OP_EQ, 0);
desc1 = hs_helper_build_hs_desc_with_rev_counter(&signing_kp1, 42);
tt_assert(desc1);
ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str);
tt_int_op(ret, OP_EQ, 0);
/* Store descriptor and check that stats got updated */
ret = hs_cache_store_as_dir(desc1_str);
tt_int_op(ret, OP_EQ, 0);
hs_v3_stats = rep_hist_get_hs_v3_stats();
tt_int_op(digestmap_size(hs_v3_stats->v3_onions_seen_this_period), OP_EQ, 1);
/* cleanup */
hs_descriptor_free(desc1);
tor_free(desc1_str);
/* Generate another valid descriptor */
ret = ed25519_keypair_generate(&signing_kp1, 0);
tt_int_op(ret, OP_EQ, 0);
desc1 = hs_helper_build_hs_desc_with_rev_counter(&signing_kp1, 42);
tt_assert(desc1);
ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str);
tt_int_op(ret, OP_EQ, 0);
/* Store descriptor and check that stats are updated */
ret = hs_cache_store_as_dir(desc1_str);
tt_int_op(ret, OP_EQ, 0);
hs_v3_stats = rep_hist_get_hs_v3_stats();
tt_int_op(digestmap_size(hs_v3_stats->v3_onions_seen_this_period), OP_EQ, 2);
/* Check that storing the same descriptor twice does not work */
ret = hs_cache_store_as_dir(desc1_str);
tt_int_op(ret, OP_EQ, -1);
/* cleanup */
hs_descriptor_free(desc1);
tor_free(desc1_str);
/* Create a descriptor with the same identity key but diff rev counter and
same blinded key */
desc1 = hs_helper_build_hs_desc_with_rev_counter(&signing_kp1, 43);
tt_assert(desc1);
ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str);
tt_int_op(ret, OP_EQ, 0);
/* Store descriptor and check that stats are updated */
ret = hs_cache_store_as_dir(desc1_str);
tt_int_op(ret, OP_EQ, 0);
tt_int_op(digestmap_size(hs_v3_stats->v3_onions_seen_this_period), OP_EQ, 2);
/* cleanup */
hs_descriptor_free(desc1);
tor_free(desc1_str);
/* Now let's skip to four days forward so that the blinded key rolls
forward */
update_approx_time(approx_time() + 345600);
/* Now create a descriptor with the same identity key but diff rev counter
and different blinded key */
desc1 = hs_helper_build_hs_desc_with_rev_counter(&signing_kp1, 44);
tt_assert(desc1);
ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str);
tt_int_op(ret, OP_EQ, 0);
/* Store descriptor and check that stats are updated */
ret = hs_cache_store_as_dir(desc1_str);
tt_int_op(ret, OP_EQ, 0);
tt_int_op(digestmap_size(hs_v3_stats->v3_onions_seen_this_period), OP_EQ, 3);
/* cleanup */
hs_descriptor_free(desc1);
tor_free(desc1_str);
/* Because of differential privacy we can't actually check the stat value,
but let's just check that it's formatted correctly. */
stats_string = rep_hist_format_hs_v3_stats(approx_time(), true);
tt_assert(strstr(stats_string, "hidserv-dir-v3-onions-seen"));
done:
UNMOCK(should_collect_v3_stats);
tor_free(stats_string);
}
#define ENT(name) \
{ #name, test_ ## name , 0, NULL, NULL }
#define FORK(name) \
@ -506,6 +629,7 @@ struct testcase_t stats_tests[] = {
FORK(add_obs),
FORK(fill_bandwidth_history),
FORK(get_bandwidth_lines),
FORK(rephist_v3_onions),
END_OF_TESTCASES
};