tor/src/test/test_circuitmux.c
Nick Mathewson 5e395ba2c2 Rewrite time-handling in circuitmux_ewma to use monotime_coarse
This part of the code was the only part that used "cached
getttimeofday" feature, which wasn't monotonic, which we updated at
slight expense, and which I'd rather not maintain.
2018-04-26 11:50:58 -04:00

127 lines
3.2 KiB
C

/* Copyright (c) 2013-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#define TOR_CHANNEL_INTERNAL_
#define CIRCUITMUX_PRIVATE
#define CIRCUITMUX_EWMA_PRIVATE
#define RELAY_PRIVATE
#include "or.h"
#include "channel.h"
#include "circuitmux.h"
#include "circuitmux_ewma.h"
#include "relay.h"
#include "scheduler.h"
#include "test.h"
/* XXXX duplicated function from test_circuitlist.c */
static channel_t *
new_fake_channel(void)
{
channel_t *chan = tor_malloc_zero(sizeof(channel_t));
channel_init(chan);
return chan;
}
static int
has_queued_writes(channel_t *c)
{
(void) c;
return 1;
}
/** Test destroy cell queue with no interference from other queues. */
static void
test_cmux_destroy_cell_queue(void *arg)
{
circuitmux_t *cmux = NULL;
channel_t *ch = NULL;
circuit_t *circ = NULL;
destroy_cell_queue_t *cq = NULL;
packed_cell_t *pc = NULL;
destroy_cell_t *dc = NULL;
scheduler_init();
(void) arg;
cmux = circuitmux_alloc();
tt_assert(cmux);
ch = new_fake_channel();
circuitmux_set_policy(cmux, &ewma_policy);
ch->has_queued_writes = has_queued_writes;
ch->wide_circ_ids = 1;
circ = circuitmux_get_first_active_circuit(cmux, &cq);
tt_ptr_op(circ, OP_EQ, NULL);
tt_ptr_op(cq, OP_EQ, NULL);
circuitmux_append_destroy_cell(ch, cmux, 100, 10);
circuitmux_append_destroy_cell(ch, cmux, 190, 6);
circuitmux_append_destroy_cell(ch, cmux, 30, 1);
tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 3);
circ = circuitmux_get_first_active_circuit(cmux, &cq);
tt_ptr_op(circ, OP_EQ, NULL);
tt_assert(cq);
tt_int_op(cq->n, OP_EQ, 3);
dc = destroy_cell_queue_pop(cq);
tt_assert(dc);
tt_uint_op(dc->circid, OP_EQ, 100);
tt_int_op(circuitmux_num_cells(cmux), OP_EQ, 2);
done:
circuitmux_free(cmux);
channel_free(ch);
packed_cell_free(pc);
tor_free(dc);
}
static void
test_cmux_compute_ticks(void *arg)
{
const int64_t NS_PER_S = 1000 * 1000 * 1000;
const int64_t START_NS = U64_LITERAL(1217709000)*NS_PER_S;
int64_t now;
double rem;
unsigned tick;
(void)arg;
circuitmux_ewma_free_all();
monotime_enable_test_mocking();
monotime_coarse_set_mock_time_nsec(START_NS);
cell_ewma_initialize_ticks();
const unsigned tick_zero = cell_ewma_get_current_tick_and_fraction(&rem);
tt_double_op(rem, OP_GT, -1e-9);
tt_double_op(rem, OP_LT, 1e-9);
/* 1.5 second later and we should still be in the same tick. */
now = START_NS + NS_PER_S + NS_PER_S/2;
monotime_coarse_set_mock_time_nsec(now);
tick = cell_ewma_get_current_tick_and_fraction(&rem);
tt_uint_op(tick, OP_EQ, tick_zero);
tt_double_op(rem, OP_GT, .149999999);
tt_double_op(rem, OP_LT, .150000001);
/* 25 second later and we should be in another tick. */
now = START_NS + NS_PER_S * 25;
monotime_coarse_set_mock_time_nsec(now);
tick = cell_ewma_get_current_tick_and_fraction(&rem);
tt_uint_op(tick, OP_EQ, tick_zero + 2);
tt_double_op(rem, OP_GT, .499999999);
tt_double_op(rem, OP_LT, .500000001);
done:
;
}
struct testcase_t circuitmux_tests[] = {
{ "destroy_cell_queue", test_cmux_destroy_cell_queue, TT_FORK, NULL, NULL },
{ "compute_ticks", test_cmux_compute_ticks, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};