2020-01-09 00:39:17 +01:00
|
|
|
/* Copyright (c) 2013-2020, The Tor Project, Inc. */
|
2019-10-28 18:15:56 +01:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
|
|
|
#define CIRCUITMUX_PRIVATE
|
|
|
|
#define CIRCUITMUX_EWMA_PRIVATE
|
|
|
|
|
|
|
|
#include "core/or/or.h"
|
|
|
|
#include "core/or/circuitmux.h"
|
|
|
|
#include "core/or/circuitmux_ewma.h"
|
|
|
|
|
|
|
|
#include "test/fakechans.h"
|
|
|
|
#include "test/fakecircs.h"
|
|
|
|
#include "test/test.h"
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_cmux_ewma_active_circuit(void *arg)
|
|
|
|
{
|
|
|
|
circuitmux_t cmux; /* garbage */
|
|
|
|
circuitmux_policy_data_t *pol_data = NULL;
|
|
|
|
circuit_t circ; /* garbage */
|
|
|
|
circuitmux_policy_circ_data_t *circ_data = NULL;
|
|
|
|
|
|
|
|
(void) arg;
|
|
|
|
|
|
|
|
pol_data = ewma_policy.alloc_cmux_data(&cmux);
|
|
|
|
tt_assert(pol_data);
|
|
|
|
circ_data = ewma_policy.alloc_circ_data(&cmux, pol_data, &circ,
|
|
|
|
CELL_DIRECTION_OUT, 42);
|
|
|
|
tt_assert(circ_data);
|
|
|
|
|
|
|
|
/* Get EWMA specific objects. */
|
|
|
|
|
|
|
|
/* Make circuit active. */
|
|
|
|
ewma_policy.notify_circ_active(&cmux, pol_data, &circ, circ_data);
|
|
|
|
|
|
|
|
circuit_t *entry = ewma_policy.pick_active_circuit(&cmux, pol_data);
|
|
|
|
tt_mem_op(entry, OP_EQ, &circ, sizeof(circ));
|
|
|
|
|
|
|
|
done:
|
|
|
|
ewma_policy.free_circ_data(&cmux, pol_data, &circ, circ_data);
|
|
|
|
ewma_policy.free_cmux_data(&cmux, pol_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_cmux_ewma_xmit_cell(void *arg)
|
|
|
|
{
|
|
|
|
circuitmux_t cmux; /* garbage */
|
|
|
|
circuitmux_policy_data_t *pol_data = NULL;
|
|
|
|
circuit_t circ; /* garbage */
|
|
|
|
circuitmux_policy_circ_data_t *circ_data = NULL;
|
|
|
|
ewma_policy_data_t *ewma_pol_data;
|
|
|
|
ewma_policy_circ_data_t *ewma_data;
|
|
|
|
double old_cell_count;
|
|
|
|
|
|
|
|
(void) arg;
|
|
|
|
|
|
|
|
pol_data = ewma_policy.alloc_cmux_data(&cmux);
|
|
|
|
tt_assert(pol_data);
|
|
|
|
circ_data = ewma_policy.alloc_circ_data(&cmux, pol_data, &circ,
|
|
|
|
CELL_DIRECTION_OUT, 42);
|
|
|
|
tt_assert(circ_data);
|
|
|
|
ewma_pol_data = TO_EWMA_POL_DATA(pol_data);
|
|
|
|
ewma_data = TO_EWMA_POL_CIRC_DATA(circ_data);
|
|
|
|
|
|
|
|
/* Make circuit active. */
|
|
|
|
ewma_policy.notify_circ_active(&cmux, pol_data, &circ, circ_data);
|
|
|
|
|
|
|
|
/* Move back in time the last time we calibrated so we scale the active
|
|
|
|
* circuit when emitting a cell. */
|
|
|
|
ewma_pol_data->active_circuit_pqueue_last_recalibrated -= 100;
|
|
|
|
ewma_data->cell_ewma.last_adjusted_tick =
|
|
|
|
ewma_pol_data->active_circuit_pqueue_last_recalibrated;
|
|
|
|
|
|
|
|
/* Grab old cell count. */
|
|
|
|
old_cell_count = ewma_data->cell_ewma.cell_count;
|
|
|
|
|
|
|
|
ewma_policy.notify_xmit_cells(&cmux, pol_data, &circ, circ_data, 1);
|
|
|
|
|
|
|
|
/* Our old cell count should be lower to what we have since we just emitted
|
|
|
|
* a cell and thus we scale. */
|
|
|
|
tt_double_op(old_cell_count, OP_LT, ewma_data->cell_ewma.cell_count);
|
|
|
|
|
|
|
|
done:
|
|
|
|
ewma_policy.free_circ_data(&cmux, pol_data, &circ, circ_data);
|
|
|
|
ewma_policy.free_cmux_data(&cmux, pol_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_cmux_ewma_notify_circ(void *arg)
|
|
|
|
{
|
|
|
|
circuitmux_t cmux; /* garbage */
|
|
|
|
circuitmux_policy_data_t *pol_data = NULL;
|
|
|
|
circuit_t circ; /* garbage */
|
|
|
|
circuitmux_policy_circ_data_t *circ_data = NULL;
|
|
|
|
const ewma_policy_data_t *ewma_pol_data;
|
|
|
|
|
|
|
|
(void) arg;
|
|
|
|
|
|
|
|
pol_data = ewma_policy.alloc_cmux_data(&cmux);
|
|
|
|
tt_assert(pol_data);
|
|
|
|
circ_data = ewma_policy.alloc_circ_data(&cmux, pol_data, &circ,
|
|
|
|
CELL_DIRECTION_OUT, 42);
|
|
|
|
tt_assert(circ_data);
|
|
|
|
|
|
|
|
/* Currently, notify_circ_active() ignores cmux and circ. They can not be
|
|
|
|
* NULL so it is fine to pass garbage. */
|
|
|
|
ewma_policy.notify_circ_active(&cmux, pol_data, &circ, circ_data);
|
|
|
|
|
|
|
|
/* We should have an active circuit in the queue so its EWMA value can be
|
|
|
|
* tracked. */
|
|
|
|
ewma_pol_data = TO_EWMA_POL_DATA(pol_data);
|
|
|
|
tt_int_op(smartlist_len(ewma_pol_data->active_circuit_pqueue), OP_EQ, 1);
|
|
|
|
tt_uint_op(ewma_pol_data->active_circuit_pqueue_last_recalibrated, OP_NE, 0);
|
|
|
|
|
|
|
|
ewma_policy.notify_circ_inactive(&cmux, pol_data, &circ, circ_data);
|
|
|
|
/* Should be removed from the active queue. */
|
|
|
|
ewma_pol_data = TO_EWMA_POL_DATA(pol_data);
|
|
|
|
tt_int_op(smartlist_len(ewma_pol_data->active_circuit_pqueue), OP_EQ, 0);
|
|
|
|
tt_uint_op(ewma_pol_data->active_circuit_pqueue_last_recalibrated, OP_NE, 0);
|
|
|
|
|
|
|
|
done:
|
|
|
|
ewma_policy.free_circ_data(&cmux, pol_data, &circ, circ_data);
|
|
|
|
ewma_policy.free_cmux_data(&cmux, pol_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_cmux_ewma_policy_circ_data(void *arg)
|
|
|
|
{
|
|
|
|
circuitmux_t cmux; /* garbage */
|
|
|
|
circuitmux_policy_data_t pol_data; /* garbage */
|
|
|
|
circuit_t circ; /* garbage */
|
|
|
|
circuitmux_policy_circ_data_t *circ_data = NULL;
|
|
|
|
const ewma_policy_circ_data_t *ewma_data;
|
|
|
|
|
|
|
|
(void) arg;
|
|
|
|
|
|
|
|
/* Currently, alloc_circ_data() ignores every parameter _except_ the cell
|
|
|
|
* direction so it is OK to pass garbage. They can not be NULL. */
|
|
|
|
circ_data = ewma_policy.alloc_circ_data(&cmux, &pol_data, &circ,
|
|
|
|
CELL_DIRECTION_OUT, 42);
|
|
|
|
tt_assert(circ_data);
|
|
|
|
tt_uint_op(circ_data->magic, OP_EQ, EWMA_POL_CIRC_DATA_MAGIC);
|
|
|
|
|
|
|
|
ewma_data = TO_EWMA_POL_CIRC_DATA(circ_data);
|
|
|
|
tt_mem_op(ewma_data->circ, OP_EQ, &circ, sizeof(circuit_t));
|
|
|
|
tt_double_op(ewma_data->cell_ewma.cell_count, OP_LE, 0.0);
|
|
|
|
tt_int_op(ewma_data->cell_ewma.heap_index, OP_EQ, -1);
|
|
|
|
tt_uint_op(ewma_data->cell_ewma.is_for_p_chan, OP_EQ, 0);
|
|
|
|
ewma_policy.free_circ_data(&cmux, &pol_data, &circ, circ_data);
|
|
|
|
|
|
|
|
circ_data = ewma_policy.alloc_circ_data(&cmux, &pol_data, &circ,
|
|
|
|
CELL_DIRECTION_IN, 42);
|
|
|
|
tt_assert(circ_data);
|
|
|
|
tt_uint_op(circ_data->magic, OP_EQ, EWMA_POL_CIRC_DATA_MAGIC);
|
|
|
|
|
|
|
|
ewma_data = TO_EWMA_POL_CIRC_DATA(circ_data);
|
|
|
|
tt_mem_op(ewma_data->circ, OP_EQ, &circ, sizeof(circuit_t));
|
|
|
|
tt_double_op(ewma_data->cell_ewma.cell_count, OP_LE, 0.0);
|
|
|
|
tt_int_op(ewma_data->cell_ewma.heap_index, OP_EQ, -1);
|
|
|
|
tt_uint_op(ewma_data->cell_ewma.is_for_p_chan, OP_EQ, 1);
|
|
|
|
|
|
|
|
done:
|
|
|
|
ewma_policy.free_circ_data(&cmux, &pol_data, &circ, circ_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_cmux_ewma_policy_data(void *arg)
|
|
|
|
{
|
|
|
|
circuitmux_t cmux; /* garbage. */
|
|
|
|
circuitmux_policy_data_t *pol_data = NULL;
|
|
|
|
const ewma_policy_data_t *ewma_pol_data;
|
|
|
|
|
|
|
|
(void) arg;
|
|
|
|
|
|
|
|
pol_data = ewma_policy.alloc_cmux_data(&cmux);
|
|
|
|
tt_assert(pol_data);
|
|
|
|
tt_uint_op(pol_data->magic, OP_EQ, EWMA_POL_DATA_MAGIC);
|
|
|
|
|
|
|
|
/* Test EWMA object. */
|
|
|
|
ewma_pol_data = TO_EWMA_POL_DATA(pol_data);
|
|
|
|
tt_assert(ewma_pol_data->active_circuit_pqueue);
|
|
|
|
tt_uint_op(ewma_pol_data->active_circuit_pqueue_last_recalibrated, OP_NE, 0);
|
|
|
|
|
|
|
|
done:
|
|
|
|
ewma_policy.free_cmux_data(&cmux, pol_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
cmux_ewma_setup_test(const struct testcase_t *tc)
|
|
|
|
{
|
|
|
|
static int whatever;
|
|
|
|
|
|
|
|
(void) tc;
|
|
|
|
|
|
|
|
cell_ewma_initialize_ticks();
|
|
|
|
cmux_ewma_set_options(NULL, NULL);
|
|
|
|
|
|
|
|
return &whatever;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
cmux_ewma_cleanup_test(const struct testcase_t *tc, void *ptr)
|
|
|
|
{
|
|
|
|
(void) tc;
|
|
|
|
(void) ptr;
|
|
|
|
|
|
|
|
circuitmux_ewma_free_all();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct testcase_setup_t cmux_ewma_test_setup = {
|
|
|
|
.setup_fn = cmux_ewma_setup_test,
|
|
|
|
.cleanup_fn = cmux_ewma_cleanup_test,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define TEST_CMUX_EWMA(name) \
|
|
|
|
{ #name, test_cmux_ewma_##name, TT_FORK, &cmux_ewma_test_setup, NULL }
|
|
|
|
|
|
|
|
struct testcase_t circuitmux_ewma_tests[] = {
|
|
|
|
TEST_CMUX_EWMA(active_circuit),
|
|
|
|
TEST_CMUX_EWMA(policy_data),
|
|
|
|
TEST_CMUX_EWMA(policy_circ_data),
|
|
|
|
TEST_CMUX_EWMA(notify_circ),
|
|
|
|
TEST_CMUX_EWMA(xmit_cell),
|
|
|
|
|
|
|
|
END_OF_TESTCASES
|
|
|
|
};
|