mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 13:43:47 +01:00
Write unittests for v3 metrics.
This commit is contained in:
parent
5c00bee1b1
commit
131da887d7
@ -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
|
* on the real network) and hence we don't want to collect statistics if it's
|
||||||
* not yet the time to do so.
|
* not yet the time to do so.
|
||||||
*/
|
*/
|
||||||
static bool
|
MOCK_IMPL(STATIC bool,
|
||||||
should_collect_v3_stats(void)
|
should_collect_v3_stats,(void))
|
||||||
{
|
{
|
||||||
return start_of_hs_v3_stats_interval <= approx_time();
|
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
|
/** Allocate and return a string containing hidden service stats that
|
||||||
* are meant to be placed in the extra-info descriptor. */
|
* are meant to be placed in the extra-info descriptor. */
|
||||||
static char *
|
STATIC char *
|
||||||
rep_hist_format_hs_v2_stats(time_t now)
|
rep_hist_format_hs_v2_stats(time_t now)
|
||||||
{
|
{
|
||||||
char t[ISO_TIME_LEN+1];
|
char t[ISO_TIME_LEN+1];
|
||||||
|
@ -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_v2_stats(time_t now);
|
||||||
STATIC char *rep_hist_format_hs_v3_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) */
|
#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);
|
void rep_hist_padding_count_timers(uint64_t num_timers);
|
||||||
|
|
||||||
#ifdef TOR_UNIT_TESTS
|
#ifdef TOR_UNIT_TESTS
|
||||||
typedef struct hs_v2_stats_t hs_v2_stats_t;
|
struct hs_v2_stats_t;
|
||||||
const hs_v2_stats_t *rep_hist_get_hs_v2_stats(void);
|
const struct hs_v2_stats_t *rep_hist_get_hs_v2_stats(void);
|
||||||
typedef struct hs_v3_stats_t hs_v3_stats_t;
|
struct hs_v3_stats_t;
|
||||||
const hs_v3_stats_t *rep_hist_get_hs_v3_stats(void);
|
const struct hs_v3_stats_t *rep_hist_get_hs_v3_stats(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* !defined(TOR_REPHIST_H) */
|
#endif /* !defined(TOR_REPHIST_H) */
|
||||||
|
@ -134,7 +134,8 @@ hs_helper_build_intro_point(const ed25519_keypair_t *signing_kp, time_t now,
|
|||||||
* points are added. */
|
* points are added. */
|
||||||
static hs_descriptor_t *
|
static hs_descriptor_t *
|
||||||
hs_helper_build_hs_desc_impl(unsigned int no_ip,
|
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 ret;
|
||||||
int i;
|
int i;
|
||||||
@ -161,7 +162,7 @@ hs_helper_build_hs_desc_impl(unsigned int no_ip,
|
|||||||
&signing_kp->pubkey, now, 3600,
|
&signing_kp->pubkey, now, 3600,
|
||||||
CERT_FLAG_INCLUDE_SIGNING_KEY);
|
CERT_FLAG_INCLUDE_SIGNING_KEY);
|
||||||
tt_assert(desc->plaintext_data.signing_key_cert);
|
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;
|
desc->plaintext_data.lifetime_sec = 3 * 60 * 60;
|
||||||
|
|
||||||
hs_get_subcredential(&signing_kp->pubkey, &blinded_kp.pubkey,
|
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);
|
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. */
|
/* Build a descriptor with introduction points. */
|
||||||
hs_descriptor_t *
|
hs_descriptor_t *
|
||||||
hs_helper_build_hs_desc_with_ip(const ed25519_keypair_t *signing_kp)
|
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. */
|
/* Build a descriptor without any introduction points. */
|
||||||
hs_descriptor_t *
|
hs_descriptor_t *
|
||||||
hs_helper_build_hs_desc_no_ip(const ed25519_keypair_t *signing_kp)
|
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 *
|
hs_descriptor_t *
|
||||||
@ -247,7 +256,7 @@ hs_helper_build_hs_desc_with_client_auth(
|
|||||||
const ed25519_keypair_t *signing_kp)
|
const ed25519_keypair_t *signing_kp)
|
||||||
{
|
{
|
||||||
curve25519_keypair_t auth_ephemeral_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;
|
hs_desc_authorized_client_t *desc_client;
|
||||||
|
|
||||||
/* The number of client authorized auth has tobe a multiple of
|
/* The number of client authorized auth has tobe a multiple of
|
||||||
|
@ -17,6 +17,10 @@ hs_descriptor_t *hs_helper_build_hs_desc_no_ip(
|
|||||||
const ed25519_keypair_t *signing_kp);
|
const ed25519_keypair_t *signing_kp);
|
||||||
hs_descriptor_t *hs_helper_build_hs_desc_with_ip(
|
hs_descriptor_t *hs_helper_build_hs_desc_with_ip(
|
||||||
const ed25519_keypair_t *signing_kp);
|
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(
|
hs_descriptor_t *hs_helper_build_hs_desc_with_client_auth(
|
||||||
const uint8_t *descriptor_cookie,
|
const uint8_t *descriptor_cookie,
|
||||||
const curve25519_public_key_t *client_pk,
|
const curve25519_public_key_t *client_pk,
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#include "lib/crypt_ops/crypto_rand.h"
|
#include "lib/crypt_ops/crypto_rand.h"
|
||||||
#include "app/config/or_state_st.h"
|
#include "app/config/or_state_st.h"
|
||||||
#include "test/rng_test_helpers.h"
|
#include "test/rng_test_helpers.h"
|
||||||
|
#include "feature/hs/hs_cache.h"
|
||||||
|
#include "test/hs_test_helpers.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -31,6 +33,7 @@
|
|||||||
#define MAINLOOP_PRIVATE
|
#define MAINLOOP_PRIVATE
|
||||||
#define STATEFILE_PRIVATE
|
#define STATEFILE_PRIVATE
|
||||||
#define BWHIST_PRIVATE
|
#define BWHIST_PRIVATE
|
||||||
|
#define REPHIST_PRIVATE
|
||||||
|
|
||||||
#include "core/or/or.h"
|
#include "core/or/or.h"
|
||||||
#include "lib/err/backtrace.h"
|
#include "lib/err/backtrace.h"
|
||||||
@ -493,6 +496,126 @@ test_get_bandwidth_lines(void *arg)
|
|||||||
bwhist_free_all();
|
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) \
|
#define ENT(name) \
|
||||||
{ #name, test_ ## name , 0, NULL, NULL }
|
{ #name, test_ ## name , 0, NULL, NULL }
|
||||||
#define FORK(name) \
|
#define FORK(name) \
|
||||||
@ -506,6 +629,7 @@ struct testcase_t stats_tests[] = {
|
|||||||
FORK(add_obs),
|
FORK(add_obs),
|
||||||
FORK(fill_bandwidth_history),
|
FORK(fill_bandwidth_history),
|
||||||
FORK(get_bandwidth_lines),
|
FORK(get_bandwidth_lines),
|
||||||
|
FORK(rephist_v3_onions),
|
||||||
|
|
||||||
END_OF_TESTCASES
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user