Squashed 'external/toxcore/c-toxcore/' changes from 1828c5356..c9cdae001
c9cdae001 fix(toxav): remove extra copy of video frame on encode 4f6d4546b test: Improve the fake network library. a2581e700 refactor(toxcore): generate `Friend_Request` and `Dht_Nodes_Response` 2aaa11770 refactor(toxcore): use Tox_Memory in generated events 5c367452b test(toxcore): fix incorrect mutex in tox_scenario_get_time 8f92e710f perf: Add a timed limit of number of cookie requests. 695b6417a test: Add some more simulated network support. 815ae9ce9 test(toxcore): fix thread-safety in scenario framework 6d85c754e test(toxcore): add unit tests for net_crypto 9c22e79cc test(support): add SimulatedEnvironment for deterministic testing f34fcb195 chore: Update windows Dockerfile to debian stable (trixie). ece0e8980 fix(group_moderation): allow validating unsorted sanction list signatures a4fa754d7 refactor: rename struct Packet to struct Net_Packet d6f330f85 cleanup: Fix some warnings from coverity. e206bffa2 fix(group_chats): fix sync packets reverting topics 0e4715598 test: Add new scenario testing framework. 668291f44 refactor(toxcore): decouple Network_Funcs from sockaddr via IP_Port fc4396cef fix: potential division by zero in toxav and unsafe hex parsing 8e8b352ab refactor: Add nullable annotations to struct members. 7740bb421 refactor: decouple net_crypto from DHT 1936d4296 test: add benchmark for toxav audio and video 46bfdc2df fix: correct printf format specifiers for unsigned integers REVERT: 1828c5356 fix(toxav): remove extra copy of video frame on encode git-subtree-dir: external/toxcore/c-toxcore git-subtree-split: c9cdae001341e701fca980c9bb9febfeb95d2902
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
#include "../toxcore/tox_dispatch.h"
|
||||
#include "../toxcore/tox_events.h"
|
||||
#include "../toxcore/tox_struct.h"
|
||||
#include "../toxcore/net_crypto.h"
|
||||
#include "../toxcore/DHT.h"
|
||||
|
||||
#include "auto_test_support.h"
|
||||
|
||||
@@ -15,20 +17,31 @@
|
||||
#define ABORT_ON_LOG_ERROR true
|
||||
#endif
|
||||
|
||||
static const uint8_t *auto_test_nc_dht_get_shared_key_sent_wrapper(void *dht, const uint8_t *public_key)
|
||||
{
|
||||
return dht_get_shared_key_sent((DHT *)dht, public_key);
|
||||
}
|
||||
|
||||
static const uint8_t *auto_test_nc_dht_get_self_public_key_wrapper(const void *dht)
|
||||
{
|
||||
return dht_get_self_public_key((const DHT *)dht);
|
||||
}
|
||||
|
||||
static const uint8_t *auto_test_nc_dht_get_self_secret_key_wrapper(const void *dht)
|
||||
{
|
||||
return dht_get_self_secret_key((const DHT *)dht);
|
||||
}
|
||||
|
||||
const Net_Crypto_DHT_Funcs auto_test_dht_funcs = {
|
||||
auto_test_nc_dht_get_shared_key_sent_wrapper,
|
||||
auto_test_nc_dht_get_self_public_key_wrapper,
|
||||
auto_test_nc_dht_get_self_secret_key_wrapper,
|
||||
};
|
||||
|
||||
#ifndef USE_IPV6
|
||||
#define USE_IPV6 1
|
||||
#endif
|
||||
|
||||
Run_Auto_Options default_run_auto_options(void)
|
||||
{
|
||||
return (Run_Auto_Options) {
|
||||
.graph = GRAPH_COMPLETE,
|
||||
.init_autotox = nullptr,
|
||||
.tcp_port = 33188,
|
||||
.events = true,
|
||||
};
|
||||
}
|
||||
|
||||
// List of live bootstrap nodes. These nodes should have TCP server enabled.
|
||||
static const struct BootstrapNodes {
|
||||
const char *ip;
|
||||
@@ -92,320 +105,8 @@ void bootstrap_tox_live_network(Tox *tox, bool enable_tcp)
|
||||
}
|
||||
}
|
||||
|
||||
bool all_connected(const AutoTox *autotoxes, uint32_t tox_count)
|
||||
{
|
||||
if (tox_count) {
|
||||
ck_assert(autotoxes != nullptr);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
if (tox_self_get_connection_status(autotoxes[i].tox) == TOX_CONNECTION_NONE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool all_friends_connected(const AutoTox *autotoxes, uint32_t tox_count)
|
||||
{
|
||||
if (tox_count) {
|
||||
ck_assert(autotoxes != nullptr);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
const size_t friend_count = tox_self_get_friend_list_size(autotoxes[i].tox);
|
||||
|
||||
for (size_t j = 0; j < friend_count; ++j) {
|
||||
if (tox_friend_get_connection_status(autotoxes[i].tox, j, nullptr) == TOX_CONNECTION_NONE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void iterate_all_wait(AutoTox *autotoxes, uint32_t tox_count, uint32_t wait)
|
||||
{
|
||||
if (tox_count) {
|
||||
ck_assert(autotoxes != nullptr);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
if (autotoxes[i].alive) {
|
||||
if (autotoxes[i].events) {
|
||||
Tox_Err_Events_Iterate err;
|
||||
Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]);
|
||||
tox_events_free(events);
|
||||
} else {
|
||||
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
|
||||
}
|
||||
autotoxes[i].clock += wait;
|
||||
}
|
||||
}
|
||||
|
||||
/* Also actually sleep a little, to allow for local network processing */
|
||||
c_sleep(5);
|
||||
}
|
||||
|
||||
static uint64_t get_state_clock_callback(void *user_data)
|
||||
{
|
||||
const uint64_t *clock = (const uint64_t *)user_data;
|
||||
return *clock;
|
||||
}
|
||||
|
||||
void set_mono_time_callback(AutoTox *autotox)
|
||||
{
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
Mono_Time *mono_time = autotox->tox->mono_time;
|
||||
|
||||
autotox->clock = current_time_monotonic(mono_time);
|
||||
ck_assert_msg(autotox->clock >= 1000,
|
||||
"clock is too low (not initialised?): %lu", (unsigned long)autotox->clock);
|
||||
mono_time_set_current_time_callback(mono_time, nullptr, nullptr); // set to default first
|
||||
mono_time_set_current_time_callback(mono_time, get_state_clock_callback, &autotox->clock);
|
||||
}
|
||||
|
||||
void save_autotox(AutoTox *autotox)
|
||||
{
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
fprintf(stderr, "Saving #%u\n", autotox->index);
|
||||
|
||||
free(autotox->save_state);
|
||||
autotox->save_state = nullptr;
|
||||
|
||||
autotox->save_size = tox_get_savedata_size(autotox->tox);
|
||||
ck_assert_msg(autotox->save_size > 0, "save is invalid size %u", (unsigned)autotox->save_size);
|
||||
autotox->save_state = (uint8_t *)malloc(autotox->save_size);
|
||||
ck_assert_msg(autotox->save_state != nullptr, "malloc failed");
|
||||
tox_get_savedata(autotox->tox, autotox->save_state);
|
||||
}
|
||||
|
||||
void kill_autotox(AutoTox *autotox)
|
||||
{
|
||||
ck_assert(autotox != nullptr);
|
||||
ck_assert(autotox->alive);
|
||||
fprintf(stderr, "Killing #%u\n", autotox->index);
|
||||
autotox->alive = false;
|
||||
tox_dispatch_free(autotox->dispatch);
|
||||
tox_kill(autotox->tox);
|
||||
}
|
||||
|
||||
void reload(AutoTox *autotox)
|
||||
{
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
if (autotox->alive) {
|
||||
kill_autotox(autotox);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Reloading #%u\n", autotox->index);
|
||||
ck_assert(autotox->save_state != nullptr);
|
||||
|
||||
struct Tox_Options *const options = tox_options_new(nullptr);
|
||||
ck_assert(options != nullptr);
|
||||
tox_options_set_ipv6_enabled(options, USE_IPV6);
|
||||
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
|
||||
tox_options_set_savedata_data(options, autotox->save_state, autotox->save_size);
|
||||
autotox->tox = tox_new_log(options, nullptr, &autotox->index);
|
||||
ck_assert(autotox->tox != nullptr);
|
||||
autotox->dispatch = tox_dispatch_new(nullptr);
|
||||
ck_assert(autotox->dispatch != nullptr);
|
||||
if (autotox->events) {
|
||||
tox_events_init(autotox->tox);
|
||||
}
|
||||
tox_options_free(options);
|
||||
|
||||
set_mono_time_callback(autotox);
|
||||
autotox->alive = true;
|
||||
}
|
||||
|
||||
static void initialise_autotox(struct Tox_Options *options, AutoTox *autotox, uint32_t index, uint32_t state_size,
|
||||
Run_Auto_Options *autotest_opts)
|
||||
{
|
||||
autotox->index = index;
|
||||
autotox->events = autotest_opts->events;
|
||||
|
||||
Tox_Err_New err = TOX_ERR_NEW_OK;
|
||||
|
||||
if (index == 0) {
|
||||
struct Tox_Options *default_opts = tox_options_new(nullptr);
|
||||
ck_assert(default_opts != nullptr);
|
||||
|
||||
tox_options_set_ipv6_enabled(default_opts, USE_IPV6);
|
||||
|
||||
if (options == nullptr) {
|
||||
options = default_opts;
|
||||
}
|
||||
|
||||
if (tox_options_get_udp_enabled(options)) {
|
||||
tox_options_set_tcp_port(options, 0);
|
||||
autotest_opts->tcp_port = 0;
|
||||
autotox->tox = tox_new_log(options, &err, &autotox->index);
|
||||
ck_assert_msg(err == TOX_ERR_NEW_OK, "unexpected tox_new error: %u", err);
|
||||
} else {
|
||||
// Try a few ports for the TCP relay.
|
||||
for (uint16_t tcp_port = autotest_opts->tcp_port; tcp_port < autotest_opts->tcp_port + 200; ++tcp_port) {
|
||||
tox_options_set_tcp_port(options, tcp_port);
|
||||
autotox->tox = tox_new_log(options, &err, &autotox->index);
|
||||
|
||||
if (autotox->tox != nullptr) {
|
||||
autotest_opts->tcp_port = tcp_port;
|
||||
break;
|
||||
}
|
||||
|
||||
ck_assert_msg(err == TOX_ERR_NEW_PORT_ALLOC, "unexpected tox_new error (expected PORT_ALLOC): %u", err);
|
||||
}
|
||||
}
|
||||
|
||||
tox_options_free(default_opts);
|
||||
} else {
|
||||
// No TCP relay enabled for all the other toxes.
|
||||
if (options != nullptr) {
|
||||
tox_options_set_tcp_port(options, 0);
|
||||
}
|
||||
|
||||
autotox->tox = tox_new_log(options, &err, &autotox->index);
|
||||
}
|
||||
|
||||
ck_assert_msg(autotox->tox != nullptr, "failed to create tox instance #%u (error = %u)", index, err);
|
||||
|
||||
set_mono_time_callback(autotox);
|
||||
|
||||
autotox->dispatch = tox_dispatch_new(nullptr);
|
||||
ck_assert(autotox->dispatch != nullptr);
|
||||
if (autotox->events) {
|
||||
tox_events_init(autotox->tox);
|
||||
}
|
||||
|
||||
autotox->alive = true;
|
||||
autotox->save_state = nullptr;
|
||||
|
||||
if (state_size > 0) {
|
||||
autotox->state = calloc(1, state_size);
|
||||
ck_assert(autotox->state != nullptr);
|
||||
ck_assert_msg(autotox->state != nullptr, "failed to allocate state");
|
||||
} else {
|
||||
autotox->state = nullptr;
|
||||
}
|
||||
|
||||
if (autotest_opts->init_autotox != nullptr) {
|
||||
autotest_opts->init_autotox(autotox, index);
|
||||
}
|
||||
}
|
||||
|
||||
static void autotox_add_friend(AutoTox *autotoxes, uint32_t adding, uint32_t added)
|
||||
{
|
||||
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_public_key(autotoxes[added].tox, public_key);
|
||||
Tox_Err_Friend_Add err;
|
||||
tox_friend_add_norequest(autotoxes[adding].tox, public_key, &err);
|
||||
ck_assert(err == TOX_ERR_FRIEND_ADD_OK);
|
||||
}
|
||||
|
||||
static void initialise_friend_graph(Graph_Type graph, uint32_t num_toxes, AutoTox *autotoxes)
|
||||
{
|
||||
if (graph == GRAPH_LINEAR) {
|
||||
printf("toxes #%d-#%u each add adjacent toxes as friends\n", 0, num_toxes - 1);
|
||||
|
||||
for (uint32_t i = 0; i < num_toxes; ++i) {
|
||||
for (uint32_t j = i - 1; j != i + 3; j += 2) {
|
||||
if (j < num_toxes) {
|
||||
autotox_add_friend(autotoxes, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (graph == GRAPH_COMPLETE) {
|
||||
printf("toxes #%d-#%u add each other as friends\n", 0, num_toxes - 1);
|
||||
|
||||
for (uint32_t i = 0; i < num_toxes; ++i) {
|
||||
for (uint32_t j = 0; j < num_toxes; ++j) {
|
||||
if (i != j) {
|
||||
autotox_add_friend(autotoxes, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ck_abort_msg("Unknown graph type");
|
||||
}
|
||||
}
|
||||
|
||||
static void bootstrap_autotoxes(const Tox_Options *options, uint32_t tox_count, const Run_Auto_Options *autotest_opts,
|
||||
AutoTox *autotoxes)
|
||||
{
|
||||
const bool udp_enabled = options != nullptr ? tox_options_get_udp_enabled(options) : true;
|
||||
|
||||
printf("bootstrapping all toxes off tox 0\n");
|
||||
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_dht_id(autotoxes[0].tox, dht_key);
|
||||
const uint16_t dht_port = tox_self_get_udp_port(autotoxes[0].tox, nullptr);
|
||||
|
||||
for (uint32_t i = 1; i < tox_count; ++i) {
|
||||
Tox_Err_Bootstrap err;
|
||||
tox_bootstrap(autotoxes[i].tox, "localhost", dht_port, dht_key, &err);
|
||||
ck_assert_msg(err == TOX_ERR_BOOTSTRAP_OK, "bootstrap error for port %d: %u", dht_port, err);
|
||||
}
|
||||
|
||||
if (!udp_enabled) {
|
||||
ck_assert(autotest_opts->tcp_port != 0);
|
||||
printf("bootstrapping all toxes to local TCP relay running on port %d\n", autotest_opts->tcp_port);
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
Tox_Err_Bootstrap err;
|
||||
tox_add_tcp_relay(autotoxes[i].tox, "localhost", autotest_opts->tcp_port, dht_key, &err);
|
||||
ck_assert(err == TOX_ERR_BOOTSTRAP_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef void autotox_test_cb(AutoTox *autotoxes);
|
||||
|
||||
void run_auto_test(struct Tox_Options *options, uint32_t tox_count, autotox_test_cb *test,
|
||||
uint32_t state_size, Run_Auto_Options *autotest_opts)
|
||||
{
|
||||
printf("initialising %u toxes\n", tox_count);
|
||||
|
||||
AutoTox *autotoxes = (AutoTox *)calloc(tox_count, sizeof(AutoTox));
|
||||
|
||||
ck_assert(autotoxes != nullptr);
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
initialise_autotox(options, &autotoxes[i], i, state_size, autotest_opts);
|
||||
}
|
||||
|
||||
initialise_friend_graph(autotest_opts->graph, tox_count, autotoxes);
|
||||
|
||||
bootstrap_autotoxes(options, tox_count, autotest_opts, autotoxes);
|
||||
|
||||
do {
|
||||
iterate_all_wait(autotoxes, tox_count, ITERATION_INTERVAL);
|
||||
} while (!all_connected(autotoxes, tox_count));
|
||||
|
||||
printf("toxes are online\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(autotoxes, tox_count, ITERATION_INTERVAL);
|
||||
} while (!all_friends_connected(autotoxes, tox_count));
|
||||
|
||||
printf("tox clients connected\n");
|
||||
|
||||
test(autotoxes);
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
tox_dispatch_free(autotoxes[i].dispatch);
|
||||
tox_kill(autotoxes[i].tox);
|
||||
free(autotoxes[i].state);
|
||||
free(autotoxes[i].save_state);
|
||||
}
|
||||
|
||||
free(autotoxes);
|
||||
}
|
||||
|
||||
static const char *tox_log_level_name(Tox_Log_Level level)
|
||||
{
|
||||
switch (level) {
|
||||
|
||||
Reference in New Issue
Block a user