mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Separate run_auto_tests into a library
This commit is contained in:
parent
5a88159b8f
commit
1157e4e68c
|
@ -71,6 +71,7 @@ jobs:
|
|||
- run: *apt_install
|
||||
- checkout
|
||||
- run: infer --no-progress-bar -- cc
|
||||
auto_tests/auto_test_support.c
|
||||
auto_tests/lossless_packet_test.c
|
||||
testing/misc_tools.c
|
||||
toxav/*.c
|
||||
|
|
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
|
@ -106,6 +106,7 @@ jobs:
|
|||
-o send_message_test
|
||||
-Wall -Werror
|
||||
-bench -g
|
||||
auto_tests/auto_test_support.c
|
||||
auto_tests/send_message_test.c
|
||||
testing/misc_tools.c
|
||||
toxav/*.c
|
||||
|
@ -117,6 +118,7 @@ jobs:
|
|||
- name: Build amalgamation file with TCC
|
||||
run:
|
||||
other/make_single_file
|
||||
auto_tests/auto_test_support.c
|
||||
auto_tests/send_message_test.c
|
||||
testing/misc_tools.c |
|
||||
tcc -
|
||||
|
@ -141,6 +143,7 @@ jobs:
|
|||
-Wno-unknown-pragmas
|
||||
-Wno-unused-variable
|
||||
-fstruct-passing -fno-unprototyped -g
|
||||
auto_tests/auto_test_support.c
|
||||
auto_tests/send_message_test.c
|
||||
testing/misc_tools.c
|
||||
toxav/*.c
|
||||
|
|
|
@ -391,11 +391,18 @@ endif()
|
|||
|
||||
option(AUTOTEST "Enable autotests (mainly for CI)" OFF)
|
||||
|
||||
if(AUTOTEST)
|
||||
add_library(auto_test_support
|
||||
auto_tests/auto_test_support.c
|
||||
auto_tests/auto_test_support.h)
|
||||
target_link_modules(auto_test_support toxcore misc_tools)
|
||||
endif()
|
||||
|
||||
function(auto_test target)
|
||||
if(AUTOTEST AND NOT (MSVC AND ARGV1 STREQUAL "MSVC_DONT_BUILD"))
|
||||
add_executable(auto_${target}_test ${CPUFEATURES}
|
||||
auto_tests/${target}_test.c)
|
||||
target_link_modules(auto_${target}_test toxcore misc_tools)
|
||||
target_link_modules(auto_${target}_test toxcore misc_tools auto_test_support)
|
||||
if(NOT ARGV1 STREQUAL "DONT_RUN")
|
||||
add_test(NAME ${target} COMMAND ${CROSSCOMPILING_EMULATOR} auto_${target}_test)
|
||||
set_tests_properties(${target} PROPERTIES TIMEOUT "${TEST_TIMEOUT_SECONDS}")
|
||||
|
|
|
@ -9,9 +9,17 @@ cc_library(
|
|||
)
|
||||
|
||||
cc_library(
|
||||
name = "run_auto_test",
|
||||
name = "auto_test_support",
|
||||
testonly = True,
|
||||
hdrs = ["run_auto_test.h"],
|
||||
srcs = ["auto_test_support.c"],
|
||||
hdrs = ["auto_test_support.h"],
|
||||
deps = [
|
||||
":check_compat",
|
||||
"//c-toxcore/testing:misc_tools",
|
||||
"//c-toxcore/toxcore:Messenger",
|
||||
"//c-toxcore/toxcore:mono_time",
|
||||
"//c-toxcore/toxcore",
|
||||
],
|
||||
)
|
||||
|
||||
flaky_tests = {
|
||||
|
@ -33,7 +41,7 @@ flaky_tests = {
|
|||
),
|
||||
deps = [
|
||||
":check_compat",
|
||||
":run_auto_test",
|
||||
":auto_test_support",
|
||||
"//c-toxcore/testing:misc_tools",
|
||||
"//c-toxcore/toxav",
|
||||
"//c-toxcore/toxcore",
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
if BUILD_TESTS
|
||||
|
||||
noinst_LTLIBRARIES += libauto_test_support.la
|
||||
libauto_test_support_la_SOURCES = ../auto_tests/auto_test_support.c ../auto_tests/auto_test_support.h
|
||||
libauto_test_support_la_LIBADD = libmisc_tools.la libtoxcore.la
|
||||
|
||||
TESTS = \
|
||||
conference_double_invite_test \
|
||||
conference_invite_merge_test \
|
||||
|
@ -51,6 +55,7 @@ AUTOTEST_LDADD = \
|
|||
$(LIBSODIUM_LDFLAGS) \
|
||||
$(NACL_LDFLAGS) \
|
||||
libmisc_tools.la \
|
||||
libauto_test_support.la \
|
||||
libtoxcore.la \
|
||||
libtoxencryptsave.la \
|
||||
$(LIBSODIUM_LIBS) \
|
||||
|
@ -239,4 +244,4 @@ endif
|
|||
EXTRA_DIST += \
|
||||
$(top_srcdir)/auto_tests/data/save.tox \
|
||||
$(top_srcdir)/auto_tests/check_compat.h \
|
||||
$(top_srcdir)/auto_tests/run_auto_test.h
|
||||
$(top_srcdir)/auto_tests/auto_test_support.h
|
||||
|
|
309
auto_tests/auto_test_support.c
Normal file
309
auto_tests/auto_test_support.c
Normal file
|
@ -0,0 +1,309 @@
|
|||
#include <stdlib.h> // calloc, free
|
||||
|
||||
#include "check_compat.h"
|
||||
#include "../testing/misc_tools.h"
|
||||
#include "../toxcore/Messenger.h"
|
||||
#include "../toxcore/mono_time.h"
|
||||
|
||||
#include "auto_test_support.h"
|
||||
|
||||
const Run_Auto_Options default_run_auto_options = { GRAPH_COMPLETE, nullptr };
|
||||
|
||||
// List of live bootstrap nodes. These nodes should have TCP server enabled.
|
||||
static const struct BootstrapNodes {
|
||||
const char *ip;
|
||||
uint16_t port;
|
||||
const uint8_t key[32];
|
||||
} BootstrapNodes[] = {
|
||||
#ifndef USE_TEST_NETWORK
|
||||
{
|
||||
"tox.abilinski.com", 33445,
|
||||
0x10, 0xC0, 0x0E, 0xB2, 0x50, 0xC3, 0x23, 0x3E,
|
||||
0x34, 0x3E, 0x2A, 0xEB, 0xA0, 0x71, 0x15, 0xA5,
|
||||
0xC2, 0x89, 0x20, 0xE9, 0xC8, 0xD2, 0x94, 0x92,
|
||||
0xF6, 0xD0, 0x0B, 0x29, 0x04, 0x9E, 0xDC, 0x7E,
|
||||
},
|
||||
{
|
||||
"tox.initramfs.io", 33445,
|
||||
0x02, 0x80, 0x7C, 0xF4, 0xF8, 0xBB, 0x8F, 0xB3,
|
||||
0x90, 0xCC, 0x37, 0x94, 0xBD, 0xF1, 0xE8, 0x44,
|
||||
0x9E, 0x9A, 0x83, 0x92, 0xC5, 0xD3, 0xF2, 0x20,
|
||||
0x00, 0x19, 0xDA, 0x9F, 0x1E, 0x81, 0x2E, 0x46,
|
||||
},
|
||||
{
|
||||
"tox.plastiras.org", 33445,
|
||||
0x8E, 0x8B, 0x63, 0x29, 0x9B, 0x3D, 0x52, 0x0F,
|
||||
0xB3, 0x77, 0xFE, 0x51, 0x00, 0xE6, 0x5E, 0x33,
|
||||
0x22, 0xF7, 0xAE, 0x5B, 0x20, 0xA0, 0xAC, 0xED,
|
||||
0x29, 0x81, 0x76, 0x9F, 0xC5, 0xB4, 0x37, 0x25,
|
||||
},
|
||||
{
|
||||
"tox.novg.net", 33445,
|
||||
0xD5, 0x27, 0xE5, 0x84, 0x7F, 0x83, 0x30, 0xD6,
|
||||
0x28, 0xDA, 0xB1, 0x81, 0x4F, 0x0A, 0x42, 0x2F,
|
||||
0x6D, 0xC9, 0xD0, 0xA3, 0x00, 0xE6, 0xC3, 0x57,
|
||||
0x63, 0x4E, 0xE2, 0xDA, 0x88, 0xC3, 0x54, 0x63,
|
||||
},
|
||||
#else
|
||||
{
|
||||
"172.93.52.70", 33445,
|
||||
0x79, 0xCA, 0xDA, 0x49, 0x74, 0xB0, 0x92, 0x6F,
|
||||
0x28, 0x6F, 0x02, 0x5C, 0xD5, 0xFF, 0xDF, 0x3E,
|
||||
0x65, 0x4A, 0x37, 0x58, 0xC5, 0x3E, 0x02, 0x73,
|
||||
0xEC, 0xFC, 0x4D, 0x12, 0xC2, 0x1D, 0xCA, 0x48,
|
||||
},
|
||||
#endif // USE_TEST_NETWORK
|
||||
{ nullptr, 0, 0 },
|
||||
};
|
||||
|
||||
void bootstrap_tox_live_network(Tox *tox, bool enable_tcp)
|
||||
{
|
||||
for (size_t j = 0; BootstrapNodes[j].ip != nullptr; ++j) {
|
||||
const char *ip = BootstrapNodes[j].ip;
|
||||
uint16_t port = BootstrapNodes[j].port;
|
||||
const uint8_t *key = BootstrapNodes[j].key;
|
||||
|
||||
Tox_Err_Bootstrap err;
|
||||
tox_bootstrap(tox, ip, port, key, &err);
|
||||
|
||||
if (err != TOX_ERR_BOOTSTRAP_OK) {
|
||||
fprintf(stderr, "Failed to bootstrap node %zu (%s): error %d\n", j, ip, err);
|
||||
}
|
||||
|
||||
if (enable_tcp) {
|
||||
tox_add_tcp_relay(tox, ip, port, key, &err);
|
||||
|
||||
if (err != TOX_ERR_BOOTSTRAP_OK) {
|
||||
fprintf(stderr, "Failed to add TCP relay %zu (%s): error %d\n", j, ip, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool all_connected(uint32_t tox_count, AutoTox *autotoxes)
|
||||
{
|
||||
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(uint32_t tox_count, AutoTox *autotoxes)
|
||||
{
|
||||
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(uint32_t tox_count, AutoTox *autotoxes, uint32_t wait)
|
||||
{
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
if (autotoxes[i].alive) {
|
||||
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(Mono_Time *mono_time, void *user_data)
|
||||
{
|
||||
const uint64_t *clock = (const uint64_t *)user_data;
|
||||
return *clock;
|
||||
}
|
||||
|
||||
void set_mono_time_callback(AutoTox *autotox)
|
||||
{
|
||||
// TODO(iphydf): Don't rely on toxcore internals.
|
||||
Mono_Time *mono_time = ((Messenger *)autotox->tox)->mono_time;
|
||||
|
||||
autotox->clock = current_time_monotonic(mono_time);
|
||||
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_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_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);
|
||||
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,
|
||||
const Run_Auto_Options *autotest_opts)
|
||||
{
|
||||
autotox->index = index;
|
||||
autotox->tox = tox_new_log(options, nullptr, &autotox->index);
|
||||
ck_assert_msg(autotox->tox != nullptr, "failed to create tox instance #%u", index);
|
||||
|
||||
set_mono_time_callback(autotox);
|
||||
|
||||
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 #%u-#%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 #%u-#%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(struct 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;
|
||||
|
||||
if (udp_enabled) {
|
||||
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(err == TOX_ERR_BOOTSTRAP_OK);
|
||||
}
|
||||
} else {
|
||||
printf("bootstrapping all toxes to tcp relays\n");
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
bootstrap_tox_live_network(autotoxes[i].tox, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(AutoTox *autotoxes),
|
||||
uint32_t state_size, const 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(tox_count, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!all_connected(tox_count, autotoxes));
|
||||
|
||||
printf("toxes are online\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(tox_count, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!all_friends_connected(tox_count, autotoxes));
|
||||
|
||||
printf("tox clients connected\n");
|
||||
|
||||
test(autotoxes);
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
tox_kill(autotoxes[i].tox);
|
||||
free(autotoxes[i].state);
|
||||
free(autotoxes[i].save_state);
|
||||
}
|
||||
|
||||
free(autotoxes);
|
||||
}
|
53
auto_tests/auto_test_support.h
Normal file
53
auto_tests/auto_test_support.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef RUN_AUTO_TEST_H
|
||||
#define RUN_AUTO_TEST_H
|
||||
|
||||
#include <stdlib.h> // calloc, free
|
||||
|
||||
#include "check_compat.h"
|
||||
#include "../testing/misc_tools.h"
|
||||
#include "../toxcore/Messenger.h"
|
||||
#include "../toxcore/mono_time.h"
|
||||
|
||||
typedef struct AutoTox {
|
||||
Tox *tox;
|
||||
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
|
||||
size_t save_size;
|
||||
uint8_t *save_state;
|
||||
bool alive;
|
||||
|
||||
void *state;
|
||||
} AutoTox;
|
||||
|
||||
bool all_connected(uint32_t tox_count, AutoTox *toxes);
|
||||
|
||||
bool all_friends_connected(uint32_t tox_count, AutoTox *toxes);
|
||||
|
||||
void iterate_all_wait(uint32_t tox_count, AutoTox *toxes, uint32_t wait);
|
||||
|
||||
void save_autotox(AutoTox *autotox);
|
||||
void kill_autotox(AutoTox *autotox);
|
||||
void reload(AutoTox *autotox);
|
||||
|
||||
void set_mono_time_callback(AutoTox *tox);
|
||||
|
||||
typedef enum Graph_Type {
|
||||
GRAPH_COMPLETE = 0,
|
||||
GRAPH_LINEAR
|
||||
} Graph_Type;
|
||||
|
||||
typedef struct Run_Auto_Options {
|
||||
Graph_Type graph;
|
||||
void (*init_autotox)(AutoTox *autotox, uint32_t n);
|
||||
} Run_Auto_Options;
|
||||
|
||||
extern const Run_Auto_Options default_run_auto_options;
|
||||
|
||||
void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(AutoTox *autotoxes),
|
||||
uint32_t state_size, const Run_Auto_Options *autotest_opts);
|
||||
|
||||
void bootstrap_tox_live_network(Tox *tox, bool enable_tcp);
|
||||
|
||||
#endif
|
|
@ -3,12 +3,7 @@
|
|||
#include "../testing/misc_tools.h"
|
||||
#include "check_compat.h"
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
@ -16,7 +11,7 @@ int main(void)
|
|||
|
||||
Tox *tox_udp = tox_new_log(nullptr, nullptr, nullptr);
|
||||
|
||||
bootstrap_toxes_live_network(&tox_udp, 1, false);
|
||||
bootstrap_tox_live_network(tox_udp, false);
|
||||
|
||||
printf("Waiting for connection");
|
||||
|
||||
|
@ -35,7 +30,5 @@ int main(void)
|
|||
|
||||
tox_kill(tox_udp);
|
||||
|
||||
(void)run_auto_test;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,51 +13,49 @@
|
|||
#define NUM_AV_DISCONNECT (NUM_AV_GROUP_TOX / 2)
|
||||
#define NUM_AV_DISABLE (NUM_AV_GROUP_TOX / 2)
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
#include "auto_test_support.h"
|
||||
|
||||
typedef struct State {
|
||||
bool invited_next;
|
||||
|
||||
uint32_t received_audio_peers[NUM_AV_GROUP_TOX];
|
||||
uint32_t received_audio_num;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
|
||||
static void handle_self_connection_status(
|
||||
Tox *tox, Tox_Connection connection_status, void *user_data)
|
||||
{
|
||||
const State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
|
||||
if (connection_status != TOX_CONNECTION_NONE) {
|
||||
printf("tox #%u: is now connected\n", state->index);
|
||||
printf("tox #%u: is now connected\n", autotox->index);
|
||||
} else {
|
||||
printf("tox #%u: is now disconnected\n", state->index);
|
||||
printf("tox #%u: is now disconnected\n", autotox->index);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_friend_connection_status(
|
||||
Tox *tox, uint32_t friendnumber, Tox_Connection connection_status, void *user_data)
|
||||
{
|
||||
const State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
|
||||
if (connection_status != TOX_CONNECTION_NONE) {
|
||||
printf("tox #%u: is now connected to friend %u\n", state->index, friendnumber);
|
||||
printf("tox #%u: is now connected to friend %u\n", autotox->index, friendnumber);
|
||||
} else {
|
||||
printf("tox #%u: is now disconnected from friend %u\n", state->index, friendnumber);
|
||||
printf("tox #%u: is now disconnected from friend %u\n", autotox->index, friendnumber);
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_callback(void *tox, uint32_t groupnumber, uint32_t peernumber,
|
||||
const int16_t *pcm, unsigned int samples, uint8_t channels, uint32_t
|
||||
sample_rate, void *userdata)
|
||||
sample_rate, void *user_data)
|
||||
{
|
||||
if (samples == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
State *state = (State *)userdata;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
for (uint32_t i = 0; i < state->received_audio_num; ++i) {
|
||||
if (state->received_audio_peers[i] == peernumber) {
|
||||
|
@ -75,17 +73,18 @@ static void handle_conference_invite(
|
|||
Tox *tox, uint32_t friendnumber, Tox_Conference_Type type,
|
||||
const uint8_t *data, size_t length, void *user_data)
|
||||
{
|
||||
const State *state = (State *)user_data;
|
||||
ck_assert_msg(type == TOX_CONFERENCE_TYPE_AV, "tox #%u: wrong conference type: %d", state->index, type);
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert_msg(type == TOX_CONFERENCE_TYPE_AV, "tox #%u: wrong conference type: %d", autotox->index, type);
|
||||
|
||||
ck_assert_msg(toxav_join_av_groupchat(tox, friendnumber, data, length, audio_callback, user_data) == 0,
|
||||
"tox #%u: failed to join group", state->index);
|
||||
"tox #%u: failed to join group", autotox->index);
|
||||
}
|
||||
|
||||
static void handle_conference_connected(
|
||||
Tox *tox, uint32_t conference_number, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) {
|
||||
return;
|
||||
|
@ -93,12 +92,13 @@ static void handle_conference_connected(
|
|||
|
||||
Tox_Err_Conference_Invite err;
|
||||
tox_conference_invite(tox, 1, 0, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", state->index, err);
|
||||
printf("tox #%u: invited next friend\n", state->index);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index,
|
||||
err);
|
||||
printf("tox #%u: invited next friend\n", autotox->index);
|
||||
state->invited_next = true;
|
||||
}
|
||||
|
||||
static bool toxes_are_disconnected_from_group(uint32_t tox_count, Tox **toxes,
|
||||
static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes,
|
||||
bool *disconnected)
|
||||
{
|
||||
uint32_t num_disconnected = 0;
|
||||
|
@ -112,7 +112,7 @@ static bool toxes_are_disconnected_from_group(uint32_t tox_count, Tox **toxes,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (tox_conference_peer_count(toxes[i], 0, nullptr) > tox_count - num_disconnected) {
|
||||
if (tox_conference_peer_count(autotoxes[i].tox, 0, nullptr) > tox_count - num_disconnected) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ static bool toxes_are_disconnected_from_group(uint32_t tox_count, Tox **toxes,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void disconnect_toxes(uint32_t tox_count, Tox **toxes, State *state,
|
||||
static void disconnect_toxes(uint32_t tox_count, AutoTox *autotoxes,
|
||||
const bool *disconnect, const bool *exclude)
|
||||
{
|
||||
/* Fake a network outage for a set of peers D by iterating only the other
|
||||
|
@ -138,22 +138,22 @@ static void disconnect_toxes(uint32_t tox_count, Tox **toxes, State *state,
|
|||
do {
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
if (!disconnect_now[i]) {
|
||||
tox_iterate(toxes[i], &state[i]);
|
||||
state[i].clock += 1000;
|
||||
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
|
||||
autotoxes[i].clock += 1000;
|
||||
}
|
||||
}
|
||||
|
||||
c_sleep(20);
|
||||
} while (!toxes_are_disconnected_from_group(tox_count, toxes, disconnect_now));
|
||||
} while (!toxes_are_disconnected_from_group(tox_count, autotoxes, disconnect_now));
|
||||
|
||||
invert = !invert;
|
||||
} while (invert);
|
||||
}
|
||||
|
||||
static bool all_connected_to_group(uint32_t tox_count, Tox **toxes)
|
||||
static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes)
|
||||
{
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
if (tox_conference_peer_count(toxes[i], 0, nullptr) < tox_count) {
|
||||
if (tox_conference_peer_count(autotoxes[i].tox, 0, nullptr) < tox_count) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ static uint32_t random_false_index(bool *list, const uint32_t length)
|
|||
return index;
|
||||
}
|
||||
|
||||
static bool all_got_audio(State *state, const bool *disabled)
|
||||
static bool all_got_audio(AutoTox *autotoxes, const bool *disabled)
|
||||
{
|
||||
uint32_t num_disabled = 0;
|
||||
|
||||
|
@ -185,7 +185,9 @@ static bool all_got_audio(State *state, const bool *disabled)
|
|||
}
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
if (disabled[i] ^ (state[i].received_audio_num
|
||||
State *state = (State *)autotoxes[i].state;
|
||||
|
||||
if (disabled[i] ^ (state->received_audio_num
|
||||
!= NUM_AV_GROUP_TOX - num_disabled - 1)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -194,10 +196,10 @@ static bool all_got_audio(State *state, const bool *disabled)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void reset_received_audio(Tox **toxes, State *state)
|
||||
static void reset_received_audio(AutoTox *autotoxes)
|
||||
{
|
||||
for (uint32_t j = 0; j < NUM_AV_GROUP_TOX; ++j) {
|
||||
state[j].received_audio_num = 0;
|
||||
((State *)autotoxes[j].state)->received_audio_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,7 +211,7 @@ static void reset_received_audio(Tox **toxes, State *state)
|
|||
* buffers fill up. */
|
||||
#define GROUP_AV_AUDIO_ITERATIONS (8 + NUM_AV_GROUP_TOX)
|
||||
|
||||
static bool test_audio(Tox **toxes, State *state, const bool *disabled, bool quiet)
|
||||
static bool test_audio(AutoTox *autotoxes, const bool *disabled, bool quiet)
|
||||
{
|
||||
if (!quiet) {
|
||||
printf("testing sending and receiving audio\n");
|
||||
|
@ -217,7 +219,7 @@ static bool test_audio(Tox **toxes, State *state, const bool *disabled, bool qui
|
|||
|
||||
const int16_t PCM[GROUP_AV_TEST_SAMPLES] = {0};
|
||||
|
||||
reset_received_audio(toxes, state);
|
||||
reset_received_audio(autotoxes);
|
||||
|
||||
for (uint32_t n = 0; n < GROUP_AV_AUDIO_ITERATIONS; ++n) {
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
|
@ -225,18 +227,18 @@ static bool test_audio(Tox **toxes, State *state, const bool *disabled, bool qui
|
|||
continue;
|
||||
}
|
||||
|
||||
if (toxav_group_send_audio(toxes[i], 0, PCM, GROUP_AV_TEST_SAMPLES, 1, 48000) != 0) {
|
||||
if (toxav_group_send_audio(autotoxes[i].tox, 0, PCM, GROUP_AV_TEST_SAMPLES, 1, 48000) != 0) {
|
||||
if (!quiet) {
|
||||
ck_abort_msg("#%u failed to send audio", state[i].index);
|
||||
ck_abort_msg("#%u failed to send audio", autotoxes[i].index);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
|
||||
if (all_got_audio(state, disabled)) {
|
||||
if (all_got_audio(autotoxes, disabled)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -248,32 +250,32 @@ static bool test_audio(Tox **toxes, State *state, const bool *disabled, bool qui
|
|||
return false;
|
||||
}
|
||||
|
||||
static void test_eventual_audio(Tox **toxes, State *state, const bool *disabled, uint64_t timeout)
|
||||
static void test_eventual_audio(AutoTox *autotoxes, const bool *disabled, uint64_t timeout)
|
||||
{
|
||||
uint64_t start = state[0].clock;
|
||||
uint64_t start = autotoxes[0].clock;
|
||||
|
||||
while (state[0].clock < start + timeout) {
|
||||
if (test_audio(toxes, state, disabled, true)
|
||||
&& test_audio(toxes, state, disabled, true)) {
|
||||
printf("audio test successful after %d seconds\n", (int)((state[0].clock - start) / 1000));
|
||||
while (autotoxes[0].clock < start + timeout) {
|
||||
if (test_audio(autotoxes, disabled, true)
|
||||
&& test_audio(autotoxes, disabled, true)) {
|
||||
printf("audio test successful after %d seconds\n", (int)((autotoxes[0].clock - start) / 1000));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("audio seems not to be getting through: testing again with errors.\n");
|
||||
test_audio(toxes, state, disabled, false);
|
||||
test_audio(autotoxes, disabled, false);
|
||||
}
|
||||
|
||||
static void do_audio(Tox **toxes, State *state, uint32_t iterations)
|
||||
static void do_audio(AutoTox *autotoxes, uint32_t iterations)
|
||||
{
|
||||
const int16_t PCM[GROUP_AV_TEST_SAMPLES] = {0};
|
||||
printf("running audio for %u iterations\n", iterations);
|
||||
|
||||
for (uint32_t f = 0; f < iterations; ++f) {
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
ck_assert_msg(toxav_group_send_audio(toxes[i], 0, PCM, GROUP_AV_TEST_SAMPLES, 1, 48000) == 0,
|
||||
"#%u failed to send audio", state[i].index);
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
ck_assert_msg(toxav_group_send_audio(autotoxes[i].tox, 0, PCM, GROUP_AV_TEST_SAMPLES, 1, 48000) == 0,
|
||||
"#%u failed to send audio", autotoxes[i].index);
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,15 +285,15 @@ static void do_audio(Tox **toxes, State *state, uint32_t iterations)
|
|||
|
||||
#define JITTER_SETTLE_TIME (GROUP_JBUF_DEAD_SECONDS*1000 + NUM_AV_GROUP_TOX*ITERATION_INTERVAL*(GROUP_AV_AUDIO_ITERATIONS+1))
|
||||
|
||||
static void run_conference_tests(Tox **toxes, State *state)
|
||||
static void run_conference_tests(AutoTox *autotoxes)
|
||||
{
|
||||
bool disabled[NUM_AV_GROUP_TOX] = {0};
|
||||
|
||||
test_audio(toxes, state, disabled, false);
|
||||
test_audio(autotoxes, disabled, false);
|
||||
|
||||
/* have everyone send audio for a bit so we can test that the audio
|
||||
* sequnums dropping to 0 on restart isn't a problem */
|
||||
do_audio(toxes, state, 20);
|
||||
do_audio(autotoxes, 20);
|
||||
|
||||
printf("letting random toxes timeout\n");
|
||||
bool disconnected[NUM_AV_GROUP_TOX] = {0};
|
||||
|
@ -305,55 +307,41 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
|
||||
if (i < NUM_AV_DISCONNECT / 2) {
|
||||
restarting[disconnect] = true;
|
||||
printf("Restarting #%u\n", state[disconnect].index);
|
||||
printf("Restarting #%u\n", autotoxes[disconnect].index);
|
||||
} else {
|
||||
printf("Disconnecting #%u\n", state[disconnect].index);
|
||||
printf("Disconnecting #%u\n", autotoxes[disconnect].index);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *save[NUM_AV_GROUP_TOX];
|
||||
size_t save_size[NUM_AV_GROUP_TOX];
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
if (restarting[i]) {
|
||||
save_size[i] = tox_get_savedata_size(toxes[i]);
|
||||
ck_assert_msg(save_size[i] != 0, "save is invalid size %u", (unsigned)save_size[i]);
|
||||
save[i] = (uint8_t *)malloc(save_size[i]);
|
||||
ck_assert_msg(save[i] != nullptr, "malloc failed");
|
||||
tox_get_savedata(toxes[i], save[i]);
|
||||
tox_kill(toxes[i]);
|
||||
save_autotox(&autotoxes[i]);
|
||||
kill_autotox(&autotoxes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
disconnect_toxes(NUM_AV_GROUP_TOX, toxes, state, disconnected, restarting);
|
||||
disconnect_toxes(NUM_AV_GROUP_TOX, autotoxes, disconnected, restarting);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
if (restarting[i]) {
|
||||
struct Tox_Options *const options = tox_options_new(nullptr);
|
||||
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
|
||||
tox_options_set_savedata_data(options, save[i], save_size[i]);
|
||||
toxes[i] = tox_new_log(options, nullptr, &state[i].index);
|
||||
tox_options_free(options);
|
||||
free(save[i]);
|
||||
|
||||
set_mono_time_callback(toxes[i], &state[i]);
|
||||
reload(&autotoxes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("reconnecting toxes\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!all_connected_to_group(NUM_AV_GROUP_TOX, toxes));
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!all_connected_to_group(NUM_AV_GROUP_TOX, autotoxes));
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
if (restarting[i]) {
|
||||
ck_assert_msg(!toxav_groupchat_av_enabled(toxes[i], 0),
|
||||
"#%u restarted but av enabled", state[i].index);
|
||||
ck_assert_msg(toxav_groupchat_enable_av(toxes[i], 0, audio_callback, &state[i]) == 0,
|
||||
"#%u failed to re-enable av", state[i].index);
|
||||
ck_assert_msg(toxav_groupchat_av_enabled(toxes[i], 0),
|
||||
"#%u av not enabled even after enabling", state[i].index);
|
||||
ck_assert_msg(!toxav_groupchat_av_enabled(autotoxes[i].tox, 0),
|
||||
"#%u restarted but av enabled", autotoxes[i].index);
|
||||
ck_assert_msg(toxav_groupchat_enable_av(autotoxes[i].tox, 0, audio_callback, &autotoxes[i]) == 0,
|
||||
"#%u failed to re-enable av", autotoxes[i].index);
|
||||
ck_assert_msg(toxav_groupchat_av_enabled(autotoxes[i].tox, 0),
|
||||
"#%u av not enabled even after enabling", autotoxes[i].index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,7 +351,7 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
* connected enough for lossy messages to get through
|
||||
* (all_connected_to_group() only checks lossless connectivity, which is a
|
||||
* looser condition). */
|
||||
test_eventual_audio(toxes, state, disabled, JITTER_SETTLE_TIME + NUM_AV_GROUP_TOX * 1000);
|
||||
test_eventual_audio(autotoxes, disabled, JITTER_SETTLE_TIME + NUM_AV_GROUP_TOX * 1000);
|
||||
|
||||
printf("testing disabling av\n");
|
||||
|
||||
|
@ -372,18 +360,18 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
for (uint32_t i = 0; i < NUM_AV_DISABLE; ++i) {
|
||||
uint32_t disable = random_false_index(disabled, NUM_AV_GROUP_TOX);
|
||||
disabled[disable] = true;
|
||||
printf("Disabling #%u\n", state[disable].index);
|
||||
ck_assert_msg(toxav_groupchat_enable_av(toxes[disable], 0, audio_callback, &state[disable]) != 0,
|
||||
"#%u could enable already enabled av!", state[i].index);
|
||||
ck_assert_msg(toxav_groupchat_disable_av(toxes[disable], 0) == 0,
|
||||
"#%u failed to disable av", state[i].index);
|
||||
printf("Disabling #%u\n", autotoxes[disable].index);
|
||||
ck_assert_msg(toxav_groupchat_enable_av(autotoxes[disable].tox, 0, audio_callback, &autotoxes[disable]) != 0,
|
||||
"#%u could enable already enabled av!", autotoxes[i].index);
|
||||
ck_assert_msg(toxav_groupchat_disable_av(autotoxes[disable].tox, 0) == 0,
|
||||
"#%u failed to disable av", autotoxes[i].index);
|
||||
}
|
||||
|
||||
// Run test without error to clear out messages from now-disabled peers.
|
||||
test_audio(toxes, state, disabled, true);
|
||||
test_audio(autotoxes, disabled, true);
|
||||
|
||||
printf("testing audio with some peers having disabled their av\n");
|
||||
test_audio(toxes, state, disabled, false);
|
||||
test_audio(autotoxes, disabled, false);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_DISABLE; ++i) {
|
||||
if (!disabled[i]) {
|
||||
|
@ -391,59 +379,60 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
}
|
||||
|
||||
disabled[i] = false;
|
||||
ck_assert_msg(toxav_groupchat_disable_av(toxes[i], 0) != 0,
|
||||
"#%u could disable already disabled av!", state[i].index);
|
||||
ck_assert_msg(!toxav_groupchat_av_enabled(toxes[i], 0),
|
||||
"#%u av enabled after disabling", state[i].index);
|
||||
ck_assert_msg(toxav_groupchat_enable_av(toxes[i], 0, audio_callback, &state[i]) == 0,
|
||||
"#%u failed to re-enable av", state[i].index);
|
||||
ck_assert_msg(toxav_groupchat_disable_av(autotoxes[i].tox, 0) != 0,
|
||||
"#%u could disable already disabled av!", autotoxes[i].index);
|
||||
ck_assert_msg(!toxav_groupchat_av_enabled(autotoxes[i].tox, 0),
|
||||
"#%u av enabled after disabling", autotoxes[i].index);
|
||||
ck_assert_msg(toxav_groupchat_enable_av(autotoxes[i].tox, 0, audio_callback, &autotoxes[i]) == 0,
|
||||
"#%u failed to re-enable av", autotoxes[i].index);
|
||||
}
|
||||
|
||||
printf("testing audio after re-enabling all av\n");
|
||||
test_eventual_audio(toxes, state, disabled, JITTER_SETTLE_TIME);
|
||||
test_eventual_audio(autotoxes, disabled, JITTER_SETTLE_TIME);
|
||||
}
|
||||
|
||||
static void test_groupav(Tox **toxes, State *state)
|
||||
static void test_groupav(AutoTox *autotoxes)
|
||||
{
|
||||
const time_t test_start_time = time(nullptr);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
tox_callback_self_connection_status(toxes[i], &handle_self_connection_status);
|
||||
tox_callback_friend_connection_status(toxes[i], &handle_friend_connection_status);
|
||||
tox_callback_conference_invite(toxes[i], &handle_conference_invite);
|
||||
tox_callback_conference_connected(toxes[i], &handle_conference_connected);
|
||||
tox_callback_self_connection_status(autotoxes[i].tox, &handle_self_connection_status);
|
||||
tox_callback_friend_connection_status(autotoxes[i].tox, &handle_friend_connection_status);
|
||||
tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite);
|
||||
tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected);
|
||||
}
|
||||
|
||||
ck_assert_msg(toxav_add_av_groupchat(toxes[0], audio_callback, &state[0]) != UINT32_MAX, "failed to create group");
|
||||
printf("tox #%u: inviting its first friend\n", state[0].index);
|
||||
ck_assert_msg(tox_conference_invite(toxes[0], 0, 0, nullptr) != 0, "failed to invite friend");
|
||||
state[0].invited_next = true;
|
||||
ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != UINT32_MAX,
|
||||
"failed to create group");
|
||||
printf("tox #%u: inviting its first friend\n", autotoxes[0].index);
|
||||
ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend");
|
||||
((State *)autotoxes[0].state)->invited_next = true;
|
||||
|
||||
|
||||
printf("waiting for invitations to be made\n");
|
||||
uint32_t invited_count = 0;
|
||||
|
||||
do {
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
|
||||
invited_count = 0;
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
invited_count += state[i].invited_next;
|
||||
invited_count += ((State *)autotoxes[i].state)->invited_next;
|
||||
}
|
||||
} while (invited_count != NUM_AV_GROUP_TOX - 1);
|
||||
|
||||
uint64_t pregroup_clock = state[0].clock;
|
||||
uint64_t pregroup_clock = autotoxes[0].clock;
|
||||
printf("waiting for all toxes to be in the group\n");
|
||||
uint32_t fully_connected_count = 0;
|
||||
|
||||
do {
|
||||
fully_connected_count = 0;
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(NUM_AV_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
Tox_Err_Conference_Peer_Query err;
|
||||
uint32_t peer_count = tox_conference_peer_count(toxes[i], 0, &err);
|
||||
uint32_t peer_count = tox_conference_peer_count(autotoxes[i].tox, 0, &err);
|
||||
|
||||
if (err != TOX_ERR_CONFERENCE_PEER_QUERY_OK) {
|
||||
peer_count = 0;
|
||||
|
@ -453,9 +442,9 @@ static void test_groupav(Tox **toxes, State *state)
|
|||
}
|
||||
} while (fully_connected_count != NUM_AV_GROUP_TOX);
|
||||
|
||||
printf("group connected, took %d seconds\n", (int)((state[0].clock - pregroup_clock) / 1000));
|
||||
printf("group connected, took %d seconds\n", (int)((autotoxes[0].clock - pregroup_clock) / 1000));
|
||||
|
||||
run_conference_tests(toxes, state);
|
||||
run_conference_tests(autotoxes);
|
||||
|
||||
printf("test_many_group succeeded, took %d seconds\n", (int)(time(nullptr) - test_start_time));
|
||||
}
|
||||
|
@ -464,6 +453,10 @@ int main(void)
|
|||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, NUM_AV_GROUP_TOX, test_groupav, true);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
|
||||
run_auto_test(nullptr, NUM_AV_GROUP_TOX, test_groupav, sizeof(State), &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
#include <stdint.h>
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
|
||||
bool self_online;
|
||||
bool friend_online;
|
||||
|
||||
|
@ -12,17 +9,18 @@ typedef struct State {
|
|||
uint32_t conference;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
static void handle_conference_invite(
|
||||
Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
|
||||
const uint8_t *cookie, size_t length, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n",
|
||||
state->index, friend_number, type, (unsigned)length);
|
||||
fprintf(stderr, "tox%u joining conference\n", state->index);
|
||||
autotox->index, friend_number, type, (unsigned)length);
|
||||
fprintf(stderr, "tox%u joining conference\n", autotox->index);
|
||||
|
||||
ck_assert_msg(!state->joined, "invitation callback generated for already joined conference");
|
||||
|
||||
|
@ -31,31 +29,35 @@ static void handle_conference_invite(
|
|||
state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
|
||||
"attempting to join the conference returned with an error: %d", err);
|
||||
fprintf(stderr, "tox%u joined conference %u\n", state->index, state->conference);
|
||||
fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference);
|
||||
state->joined = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void conference_double_invite_test(Tox **toxes, State *state)
|
||||
static void conference_double_invite_test(AutoTox *autotoxes)
|
||||
{
|
||||
// Conference callbacks.
|
||||
tox_callback_conference_invite(toxes[0], handle_conference_invite);
|
||||
tox_callback_conference_invite(toxes[1], handle_conference_invite);
|
||||
tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite);
|
||||
tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite);
|
||||
|
||||
State *state[2];
|
||||
state[0] = (State *)autotoxes[0].state;
|
||||
state[1] = (State *)autotoxes[1].state;
|
||||
|
||||
{
|
||||
// Create new conference, tox0 is the founder.
|
||||
Tox_Err_Conference_New err;
|
||||
state[0].conference = tox_conference_new(toxes[0], &err);
|
||||
state[0].joined = true;
|
||||
state[0]->conference = tox_conference_new(autotoxes[0].tox, &err);
|
||||
state[0]->joined = true;
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK,
|
||||
"attempting to create a new conference returned with an error: %d", err);
|
||||
fprintf(stderr, "Created conference: index=%u\n", state[0].conference);
|
||||
fprintf(stderr, "Created conference: index=%u\n", state[0]->conference);
|
||||
}
|
||||
|
||||
{
|
||||
// Invite friend.
|
||||
Tox_Err_Conference_Invite err;
|
||||
tox_conference_invite(toxes[0], 0, state[0].conference, &err);
|
||||
tox_conference_invite(autotoxes[0].tox, 0, state[0]->conference, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK,
|
||||
"attempting to invite a friend returned with an error: %d", err);
|
||||
fprintf(stderr, "tox0 invited tox1\n");
|
||||
|
@ -64,21 +66,25 @@ static void conference_double_invite_test(Tox **toxes, State *state)
|
|||
fprintf(stderr, "Waiting for invitation to arrive\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(2, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!state[0].joined || !state[1].joined);
|
||||
iterate_all_wait(2, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!state[0]->joined || !state[1]->joined);
|
||||
|
||||
fprintf(stderr, "Invitations accepted\n");
|
||||
|
||||
fprintf(stderr, "Sending second invitation; should be ignored\n");
|
||||
tox_conference_invite(toxes[0], 0, state[0].conference, nullptr);
|
||||
tox_conference_invite(autotoxes[0].tox, 0, state[0]->conference, nullptr);
|
||||
|
||||
iterate_all_wait(2, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(2, autotoxes, ITERATION_INTERVAL);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, 2, conference_double_invite_test, false);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
|
||||
run_auto_test(nullptr, 2, conference_double_invite_test, sizeof(State), &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,133 +3,72 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
|
||||
size_t save_size;
|
||||
uint8_t *save_state;
|
||||
bool alive;
|
||||
|
||||
bool connected;
|
||||
uint32_t conference;
|
||||
} State;
|
||||
|
||||
#define NUM_INVITE_MERGE_TOX 5
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
static void handle_conference_invite(
|
||||
Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
|
||||
const uint8_t *cookie, size_t length, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
if (friend_number != -1) {
|
||||
Tox_Err_Conference_Join err;
|
||||
state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
|
||||
"attempting to join the conference returned with an error: %d", err);
|
||||
fprintf(stderr, "#%u accepted invite to conference %u\n", state->index, state->conference);
|
||||
fprintf(stderr, "#%u accepted invite to conference %u\n", autotox->index, state->conference);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_conference_connected(
|
||||
Tox *tox, uint32_t conference_number, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
fprintf(stderr, "#%u connected to conference %u\n", state->index, state->conference);
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
fprintf(stderr, "#%u connected to conference %u\n", autotox->index, state->conference);
|
||||
state->connected = true;
|
||||
}
|
||||
|
||||
static void iterate_alive(Tox **toxes, State *state)
|
||||
{
|
||||
for (uint32_t i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
|
||||
if (!state[i].alive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tox_iterate(toxes[i], &state[i]);
|
||||
state[i].clock += ITERATION_INTERVAL;
|
||||
}
|
||||
|
||||
c_sleep(20);
|
||||
}
|
||||
|
||||
static void save(Tox **toxes, State *state, uint32_t n)
|
||||
{
|
||||
fprintf(stderr, "Saving #%u\n", state[n].index);
|
||||
|
||||
if (state[n].save_state != nullptr) {
|
||||
free(state[n].save_state);
|
||||
}
|
||||
|
||||
state[n].save_size = tox_get_savedata_size(toxes[n]);
|
||||
state[n].save_state = (uint8_t *)malloc(state[n].save_size);
|
||||
ck_assert_msg(state[n].save_state != nullptr, "malloc failed");
|
||||
tox_get_savedata(toxes[n], state[n].save_state);
|
||||
}
|
||||
|
||||
static void kill(Tox **toxes, State *state, uint32_t n)
|
||||
{
|
||||
fprintf(stderr, "Killing #%u\n", state[n].index);
|
||||
state[n].alive = false;
|
||||
tox_kill(toxes[n]);
|
||||
}
|
||||
|
||||
static void reload(Tox **toxes, State *state, uint32_t n)
|
||||
{
|
||||
if (state[n].alive) {
|
||||
state[n].alive = false;
|
||||
tox_kill(toxes[n]);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Reloading #%u\n", state[n].index);
|
||||
ck_assert(state[n].save_state != nullptr);
|
||||
|
||||
struct Tox_Options *const options = tox_options_new(nullptr);
|
||||
ck_assert(options != nullptr);
|
||||
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
|
||||
tox_options_set_savedata_data(options, state[n].save_state, state[n].save_size);
|
||||
toxes[n] = tox_new_log(options, nullptr, &state[n].index);
|
||||
ck_assert(toxes[n] != nullptr);
|
||||
tox_options_free(options);
|
||||
|
||||
set_mono_time_callback(toxes[n], &state[n]);
|
||||
state[n].alive = true;
|
||||
}
|
||||
|
||||
static void wait_connected(Tox **toxes, State *state, uint32_t n, uint32_t friendnumber)
|
||||
static void wait_connected(AutoTox *autotoxes, AutoTox *autotox, uint32_t friendnumber)
|
||||
{
|
||||
do {
|
||||
iterate_alive(toxes, state);
|
||||
} while (tox_friend_get_connection_status(toxes[n], friendnumber, nullptr) == TOX_CONNECTION_NONE);
|
||||
iterate_all_wait(NUM_INVITE_MERGE_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
} while (tox_friend_get_connection_status(autotox->tox, friendnumber, nullptr) == TOX_CONNECTION_NONE);
|
||||
}
|
||||
|
||||
static void do_invite(Tox **toxes, State *state, uint32_t inviter, uint32_t invitee, uint32_t friendnum)
|
||||
static void do_invite(AutoTox *autotoxes, AutoTox *inviter, AutoTox *invitee, uint32_t friendnum)
|
||||
{
|
||||
fprintf(stderr, "#%u inviting #%u\n", state[inviter].index, state[invitee].index);
|
||||
fprintf(stderr, "#%u inviting #%u\n", inviter->index, invitee->index);
|
||||
|
||||
Tox_Err_Conference_Invite err;
|
||||
tox_conference_invite(toxes[inviter], friendnum, state[inviter].conference, &err);
|
||||
tox_conference_invite(inviter->tox, friendnum, ((State *)inviter->state)->conference, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK,
|
||||
"#%u attempting to invite #%u (friendnumber %u) returned with an error: %d", state[inviter].index, state[invitee].index,
|
||||
"#%u attempting to invite #%u (friendnumber %u) returned with an error: %d", inviter->index, invitee->index,
|
||||
friendnum, err);
|
||||
|
||||
do {
|
||||
iterate_alive(toxes, state);
|
||||
} while (!state[invitee].connected);
|
||||
iterate_all_wait(NUM_INVITE_MERGE_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!((State *)invitee->state)->connected);
|
||||
}
|
||||
|
||||
static bool group_complete(Tox **toxes, State *state)
|
||||
static bool group_complete(AutoTox *autotoxes)
|
||||
{
|
||||
int c = -1, size = 0;
|
||||
|
||||
for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
|
||||
if (!state[i].alive) {
|
||||
if (!autotoxes[i].alive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const int ct = tox_conference_peer_count(toxes[i], state[i].conference, nullptr);
|
||||
const int ct = tox_conference_peer_count(autotoxes[i].tox, ((State *)autotoxes[i].state)->conference, nullptr);
|
||||
|
||||
if (c == -1) {
|
||||
c = ct;
|
||||
|
@ -143,100 +82,98 @@ static bool group_complete(Tox **toxes, State *state)
|
|||
return (c == size);
|
||||
}
|
||||
|
||||
static void wait_group_complete(Tox **toxes, State *state)
|
||||
static void wait_group_complete(AutoTox *autotoxes)
|
||||
{
|
||||
do {
|
||||
iterate_alive(toxes, state);
|
||||
} while (!group_complete(toxes, state));
|
||||
iterate_all_wait(NUM_INVITE_MERGE_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!group_complete(autotoxes));
|
||||
}
|
||||
|
||||
static void conference_invite_merge_test(Tox **toxes, State *state)
|
||||
static void conference_invite_merge_test(AutoTox *autotoxes)
|
||||
{
|
||||
// Test that an explicit invite between peers in different connected
|
||||
// components will cause a split group to merge
|
||||
|
||||
for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
|
||||
tox_callback_conference_invite(toxes[i], handle_conference_invite);
|
||||
tox_callback_conference_connected(toxes[i], &handle_conference_connected);
|
||||
state[i].alive = true;
|
||||
state[i].save_state = nullptr;
|
||||
tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite);
|
||||
tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected);
|
||||
}
|
||||
|
||||
State *state2 = (State *)autotoxes[2].state;
|
||||
|
||||
{
|
||||
// Create new conference, tox 2 is the founder.
|
||||
Tox_Err_Conference_New err;
|
||||
state[2].conference = tox_conference_new(toxes[2], &err);
|
||||
state[2].connected = true;
|
||||
state2->conference = tox_conference_new(autotoxes[2].tox, &err);
|
||||
state2->connected = true;
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK,
|
||||
"attempting to create a new conference returned with an error: %d", err);
|
||||
fprintf(stderr, "Created conference: index=%u\n", state[2].conference);
|
||||
fprintf(stderr, "Created conference: index=%u\n", state2->conference);
|
||||
}
|
||||
|
||||
save(toxes, state, 2);
|
||||
save_autotox(&autotoxes[2]);
|
||||
|
||||
do_invite(toxes, state, 2, 1, 0);
|
||||
do_invite(toxes, state, 1, 0, 0);
|
||||
do_invite(autotoxes, &autotoxes[2], &autotoxes[1], 0);
|
||||
do_invite(autotoxes, &autotoxes[1], &autotoxes[0], 0);
|
||||
|
||||
save(toxes, state, 1);
|
||||
kill(toxes, state, 1);
|
||||
save_autotox(&autotoxes[1]);
|
||||
kill_autotox(&autotoxes[1]);
|
||||
|
||||
do {
|
||||
iterate_alive(toxes, state);
|
||||
} while (tox_conference_peer_count(toxes[2], state[2].conference, nullptr) != 1);
|
||||
iterate_all_wait(NUM_INVITE_MERGE_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
} while (tox_conference_peer_count(autotoxes[2].tox, state2->conference, nullptr) != 1);
|
||||
|
||||
do_invite(toxes, state, 2, 3, 1);
|
||||
do_invite(toxes, state, 3, 4, 1);
|
||||
do_invite(autotoxes, &autotoxes[2], &autotoxes[3], 1);
|
||||
do_invite(autotoxes, &autotoxes[3], &autotoxes[4], 1);
|
||||
|
||||
kill(toxes, state, 2);
|
||||
kill_autotox(&autotoxes[2]);
|
||||
|
||||
reload(toxes, state, 1);
|
||||
reload(&autotoxes[1]);
|
||||
|
||||
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_public_key(toxes[1], public_key);
|
||||
tox_friend_add_norequest(toxes[3], public_key, nullptr);
|
||||
tox_self_get_public_key(toxes[3], public_key);
|
||||
tox_friend_add_norequest(toxes[1], public_key, nullptr);
|
||||
wait_connected(toxes, state, 1, 2);
|
||||
tox_self_get_public_key(autotoxes[1].tox, public_key);
|
||||
tox_friend_add_norequest(autotoxes[3].tox, public_key, nullptr);
|
||||
tox_self_get_public_key(autotoxes[3].tox, public_key);
|
||||
tox_friend_add_norequest(autotoxes[1].tox, public_key, nullptr);
|
||||
wait_connected(autotoxes, &autotoxes[1], 2);
|
||||
|
||||
do_invite(toxes, state, 1, 3, 2);
|
||||
do_invite(autotoxes, &autotoxes[1], &autotoxes[3], 2);
|
||||
|
||||
fprintf(stderr, "Waiting for group to merge\n");
|
||||
|
||||
wait_group_complete(toxes, state);
|
||||
wait_group_complete(autotoxes);
|
||||
|
||||
fprintf(stderr, "Group merged\n");
|
||||
|
||||
reload(toxes, state, 2);
|
||||
wait_connected(toxes, state, 2, 0);
|
||||
do_invite(toxes, state, 2, 1, 0);
|
||||
reload(&autotoxes[2]);
|
||||
wait_connected(autotoxes, &autotoxes[2], 0);
|
||||
do_invite(autotoxes, &autotoxes[2], &autotoxes[1], 0);
|
||||
|
||||
fprintf(stderr, "Waiting for #2 to rejoin\n");
|
||||
|
||||
wait_group_complete(toxes, state);
|
||||
wait_group_complete(autotoxes);
|
||||
|
||||
kill(toxes, state, 2);
|
||||
wait_group_complete(toxes, state);
|
||||
reload(toxes, state, 2);
|
||||
wait_connected(toxes, state, 2, 0);
|
||||
wait_connected(toxes, state, 1, 1);
|
||||
kill_autotox(&autotoxes[2]);
|
||||
wait_group_complete(autotoxes);
|
||||
reload(&autotoxes[2]);
|
||||
wait_connected(autotoxes, &autotoxes[2], 0);
|
||||
wait_connected(autotoxes, &autotoxes[1], 1);
|
||||
|
||||
do_invite(toxes, state, 1, 2, 1);
|
||||
do_invite(autotoxes, &autotoxes[1], &autotoxes[2], 1);
|
||||
|
||||
fprintf(stderr, "Waiting for #2 to rejoin\n");
|
||||
|
||||
wait_group_complete(toxes, state);
|
||||
|
||||
for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
|
||||
if (state[i].save_state != nullptr) {
|
||||
free(state[i].save_state);
|
||||
}
|
||||
}
|
||||
wait_group_complete(autotoxes);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, NUM_INVITE_MERGE_TOX, conference_invite_merge_test, true);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
|
||||
run_auto_test(nullptr, NUM_INVITE_MERGE_TOX, conference_invite_merge_test, sizeof(State), &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
#include <stdint.h>
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
|
||||
bool self_online;
|
||||
bool friend_online;
|
||||
bool friend_in_group;
|
||||
|
@ -13,38 +10,40 @@ typedef struct State {
|
|||
uint32_t conference;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
static void handle_conference_invite(
|
||||
Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
|
||||
const uint8_t *cookie, size_t length, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n",
|
||||
state->index, friend_number, type, (unsigned)length);
|
||||
fprintf(stderr, "tox%u joining conference\n", state->index);
|
||||
autotox->index, friend_number, type, (unsigned)length);
|
||||
fprintf(stderr, "tox%u joining conference\n", autotox->index);
|
||||
|
||||
Tox_Err_Conference_Join err;
|
||||
state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
|
||||
"attempting to join the conference returned with an error: %d", err);
|
||||
fprintf(stderr, "tox%u joined conference %u\n", state->index, state->conference);
|
||||
fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference);
|
||||
state->joined = true;
|
||||
}
|
||||
|
||||
static void handle_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
fprintf(stderr, "handle_peer_list_changed(#%u, %u, _)\n",
|
||||
state->index, conference_number);
|
||||
autotox->index, conference_number);
|
||||
|
||||
Tox_Err_Conference_Peer_Query err;
|
||||
uint32_t const count = tox_conference_peer_count(tox, conference_number, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_PEER_QUERY_OK,
|
||||
"failed to get conference peer count: err = %d", err);
|
||||
printf("tox%u has %u peers\n", state->index, count);
|
||||
printf("tox%u has %u peers\n", autotox->index, count);
|
||||
state->friend_in_group = count == 2;
|
||||
}
|
||||
|
||||
|
@ -73,32 +72,36 @@ static void rebuild_peer_list(Tox *tox)
|
|||
}
|
||||
}
|
||||
|
||||
static void conference_peer_nick_test(Tox **toxes, State *state)
|
||||
static void conference_peer_nick_test(AutoTox *autotoxes)
|
||||
{
|
||||
// Conference callbacks.
|
||||
tox_callback_conference_invite(toxes[0], handle_conference_invite);
|
||||
tox_callback_conference_invite(toxes[1], handle_conference_invite);
|
||||
tox_callback_conference_peer_list_changed(toxes[0], handle_peer_list_changed);
|
||||
tox_callback_conference_peer_list_changed(toxes[1], handle_peer_list_changed);
|
||||
tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite);
|
||||
tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite);
|
||||
tox_callback_conference_peer_list_changed(autotoxes[0].tox, handle_peer_list_changed);
|
||||
tox_callback_conference_peer_list_changed(autotoxes[1].tox, handle_peer_list_changed);
|
||||
|
||||
// Set the names of the toxes.
|
||||
tox_self_set_name(toxes[0], (const uint8_t *)"test-tox-0", 10, nullptr);
|
||||
tox_self_set_name(toxes[1], (const uint8_t *)"test-tox-1", 10, nullptr);
|
||||
tox_self_set_name(autotoxes[0].tox, (const uint8_t *)"test-tox-0", 10, nullptr);
|
||||
tox_self_set_name(autotoxes[1].tox, (const uint8_t *)"test-tox-1", 10, nullptr);
|
||||
|
||||
State *state[2];
|
||||
state[0] = (State *)autotoxes[0].state;
|
||||
state[1] = (State *)autotoxes[1].state;
|
||||
|
||||
{
|
||||
// Create new conference, tox0 is the founder.
|
||||
Tox_Err_Conference_New err;
|
||||
state[0].conference = tox_conference_new(toxes[0], &err);
|
||||
state[0].joined = true;
|
||||
state[0]->conference = tox_conference_new(autotoxes[0].tox, &err);
|
||||
state[0]->joined = true;
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK,
|
||||
"attempting to create a new conference returned with an error: %d", err);
|
||||
fprintf(stderr, "Created conference: index=%u\n", state[0].conference);
|
||||
fprintf(stderr, "Created conference: index=%u\n", state[0]->conference);
|
||||
}
|
||||
|
||||
{
|
||||
// Invite friend.
|
||||
Tox_Err_Conference_Invite err;
|
||||
tox_conference_invite(toxes[0], 0, state[0].conference, &err);
|
||||
tox_conference_invite(autotoxes[0].tox, 0, state[0]->conference, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK,
|
||||
"attempting to invite a friend returned with an error: %d", err);
|
||||
fprintf(stderr, "tox0 invited tox1\n");
|
||||
|
@ -107,17 +110,17 @@ static void conference_peer_nick_test(Tox **toxes, State *state)
|
|||
fprintf(stderr, "Waiting for invitation to arrive and peers to be in the group\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(2, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!state[0].joined || !state[1].joined || !state[0].friend_in_group || !state[1].friend_in_group);
|
||||
iterate_all_wait(2, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!state[0]->joined || !state[1]->joined || !state[0]->friend_in_group || !state[1]->friend_in_group);
|
||||
|
||||
fprintf(stderr, "Running tox0, but not tox1, waiting for tox1 to drop out\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(1, toxes, state, 1000);
|
||||
iterate_all_wait(1, autotoxes, 1000);
|
||||
|
||||
// Rebuild peer list after every iteration.
|
||||
rebuild_peer_list(toxes[0]);
|
||||
} while (state[0].friend_in_group);
|
||||
rebuild_peer_list(autotoxes[0].tox);
|
||||
} while (state[0]->friend_in_group);
|
||||
|
||||
fprintf(stderr, "Invitations accepted\n");
|
||||
}
|
||||
|
@ -126,6 +129,9 @@ int main(void)
|
|||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, 2, conference_peer_nick_test, false);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
run_auto_test(nullptr, 2, conference_peer_nick_test, sizeof(State), &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,35 +19,32 @@
|
|||
#define NEW_NAME_FORMAT_STR "New #%4u"
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
|
||||
bool invited_next;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
static void handle_self_connection_status(
|
||||
Tox *tox, Tox_Connection connection_status, void *user_data)
|
||||
{
|
||||
const State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
|
||||
if (connection_status != TOX_CONNECTION_NONE) {
|
||||
printf("tox #%u: is now connected\n", state->index);
|
||||
printf("tox #%u: is now connected\n", autotox->index);
|
||||
} else {
|
||||
printf("tox #%u: is now disconnected\n", state->index);
|
||||
printf("tox #%u: is now disconnected\n", autotox->index);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_friend_connection_status(
|
||||
Tox *tox, uint32_t friendnumber, Tox_Connection connection_status, void *user_data)
|
||||
{
|
||||
const State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
|
||||
if (connection_status != TOX_CONNECTION_NONE) {
|
||||
printf("tox #%u: is now connected to friend %u\n", state->index, friendnumber);
|
||||
printf("tox #%u: is now connected to friend %u\n", autotox->index, friendnumber);
|
||||
} else {
|
||||
printf("tox #%u: is now disconnected from friend %u\n", state->index, friendnumber);
|
||||
printf("tox #%u: is now disconnected from friend %u\n", autotox->index, friendnumber);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,25 +52,26 @@ static void handle_conference_invite(
|
|||
Tox *tox, uint32_t friendnumber, Tox_Conference_Type type,
|
||||
const uint8_t *data, size_t length, void *user_data)
|
||||
{
|
||||
const State *state = (State *)user_data;
|
||||
ck_assert_msg(type == TOX_CONFERENCE_TYPE_TEXT, "tox #%u: wrong conference type: %d", state->index, type);
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert_msg(type == TOX_CONFERENCE_TYPE_TEXT, "tox #%u: wrong conference type: %d", autotox->index, type);
|
||||
|
||||
Tox_Err_Conference_Join err;
|
||||
uint32_t g_num = tox_conference_join(tox, friendnumber, data, length, &err);
|
||||
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "tox #%u: error joining group: %d", state->index, err);
|
||||
ck_assert_msg(g_num == 0, "tox #%u: group number was not 0", state->index);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "tox #%u: error joining group: %d", autotox->index, err);
|
||||
ck_assert_msg(g_num == 0, "tox #%u: group number was not 0", autotox->index);
|
||||
|
||||
// Try joining again. We should only be allowed to join once.
|
||||
tox_conference_join(tox, friendnumber, data, length, &err);
|
||||
ck_assert_msg(err != TOX_ERR_CONFERENCE_JOIN_OK,
|
||||
"tox #%u: joining groupchat twice should be impossible.", state->index);
|
||||
"tox #%u: joining groupchat twice should be impossible.", autotox->index);
|
||||
}
|
||||
|
||||
static void handle_conference_connected(
|
||||
Tox *tox, uint32_t conference_number, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) {
|
||||
return;
|
||||
|
@ -81,8 +79,9 @@ static void handle_conference_connected(
|
|||
|
||||
Tox_Err_Conference_Invite err;
|
||||
tox_conference_invite(tox, 1, 0, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", state->index, err);
|
||||
printf("tox #%u: invited next friend\n", state->index);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index,
|
||||
err);
|
||||
printf("tox #%u: invited next friend\n", autotox->index);
|
||||
state->invited_next = true;
|
||||
}
|
||||
|
||||
|
@ -97,7 +96,7 @@ static void handle_conference_message(
|
|||
}
|
||||
}
|
||||
|
||||
static bool toxes_are_disconnected_from_group(uint32_t tox_count, Tox **toxes,
|
||||
static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes,
|
||||
bool *disconnected)
|
||||
{
|
||||
uint32_t num_disconnected = 0;
|
||||
|
@ -111,7 +110,7 @@ static bool toxes_are_disconnected_from_group(uint32_t tox_count, Tox **toxes,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (tox_conference_peer_count(toxes[i], 0, nullptr) > tox_count - num_disconnected) {
|
||||
if (tox_conference_peer_count(autotoxes[i].tox, 0, nullptr) > tox_count - num_disconnected) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -119,7 +118,7 @@ static bool toxes_are_disconnected_from_group(uint32_t tox_count, Tox **toxes,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void disconnect_toxes(uint32_t tox_count, Tox **toxes, State *state,
|
||||
static void disconnect_toxes(uint32_t tox_count, AutoTox *autotoxes,
|
||||
const bool *disconnect, const bool *exclude)
|
||||
{
|
||||
/* Fake a network outage for a set of peers D by iterating only the other
|
||||
|
@ -137,22 +136,22 @@ static void disconnect_toxes(uint32_t tox_count, Tox **toxes, State *state,
|
|||
do {
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
if (!disconnect_now[i]) {
|
||||
tox_iterate(toxes[i], &state[i]);
|
||||
state[i].clock += 1000;
|
||||
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
|
||||
autotoxes[i].clock += 1000;
|
||||
}
|
||||
}
|
||||
|
||||
c_sleep(20);
|
||||
} while (!toxes_are_disconnected_from_group(tox_count, toxes, disconnect_now));
|
||||
} while (!toxes_are_disconnected_from_group(tox_count, autotoxes, disconnect_now));
|
||||
|
||||
invert = !invert;
|
||||
} while (invert);
|
||||
}
|
||||
|
||||
static bool all_connected_to_group(uint32_t tox_count, Tox **toxes)
|
||||
static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes)
|
||||
{
|
||||
for (uint32_t i = 0; i < tox_count; i++) {
|
||||
if (tox_conference_peer_count(toxes[i], 0, nullptr) < tox_count) {
|
||||
if (tox_conference_peer_count(autotoxes[i].tox, 0, nullptr) < tox_count) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -160,11 +159,11 @@ static bool all_connected_to_group(uint32_t tox_count, Tox **toxes)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool names_propagated(uint32_t tox_count, Tox **toxes, State *state)
|
||||
static bool names_propagated(uint32_t tox_count, AutoTox *autotoxes)
|
||||
{
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
for (uint32_t j = 0; j < tox_count; ++j) {
|
||||
const size_t len = tox_conference_peer_get_name_size(toxes[i], 0, j, nullptr);
|
||||
const size_t len = tox_conference_peer_get_name_size(autotoxes[i].tox, 0, j, nullptr);
|
||||
|
||||
if (len != NAMELEN) {
|
||||
return false;
|
||||
|
@ -191,7 +190,7 @@ static uint32_t random_false_index(bool *list, const uint32_t length)
|
|||
return index;
|
||||
}
|
||||
|
||||
static void run_conference_tests(Tox **toxes, State *state)
|
||||
static void run_conference_tests(AutoTox *autotoxes)
|
||||
{
|
||||
/* disabling name change propagation check for now, as it occasionally
|
||||
* fails due to disconnections too short to trigger freezing */
|
||||
|
@ -204,9 +203,9 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
|
||||
for (uint16_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
Tox_Err_Conference_Set_Max_Offline err;
|
||||
tox_conference_set_max_offline(toxes[i], 0, max_frozen, &err);
|
||||
tox_conference_set_max_offline(autotoxes[i].tox, 0, max_frozen, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_SET_MAX_OFFLINE_OK,
|
||||
"tox #%u failed to set max offline: err = %d", state[i].index, err);
|
||||
"tox #%u failed to set max offline: err = %d", autotoxes[i].index, err);
|
||||
}
|
||||
|
||||
printf("letting random toxes timeout\n");
|
||||
|
@ -221,9 +220,9 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
|
||||
if (i < NUM_DISCONNECT / 2) {
|
||||
restarting[disconnect] = true;
|
||||
printf("Restarting #%u\n", state[disconnect].index);
|
||||
printf("Restarting #%u\n", autotoxes[disconnect].index);
|
||||
} else {
|
||||
printf("Disconnecting #%u\n", state[disconnect].index);
|
||||
printf("Disconnecting #%u\n", autotoxes[disconnect].index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,16 +231,16 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
|
||||
for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
if (restarting[i]) {
|
||||
save_size[i] = tox_get_savedata_size(toxes[i]);
|
||||
save_size[i] = tox_get_savedata_size(autotoxes[i].tox);
|
||||
ck_assert_msg(save_size[i] != 0, "save is invalid size %u", (unsigned)save_size[i]);
|
||||
save[i] = (uint8_t *)malloc(save_size[i]);
|
||||
ck_assert_msg(save[i] != nullptr, "malloc failed");
|
||||
tox_get_savedata(toxes[i], save[i]);
|
||||
tox_kill(toxes[i]);
|
||||
tox_get_savedata(autotoxes[i].tox, save[i]);
|
||||
tox_kill(autotoxes[i].tox);
|
||||
}
|
||||
}
|
||||
|
||||
disconnect_toxes(NUM_GROUP_TOX, toxes, state, disconnected, restarting);
|
||||
disconnect_toxes(NUM_GROUP_TOX, autotoxes, disconnected, restarting);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
if (restarting[i]) {
|
||||
|
@ -249,13 +248,13 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
ck_assert(options != nullptr);
|
||||
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
|
||||
tox_options_set_savedata_data(options, save[i], save_size[i]);
|
||||
toxes[i] = tox_new_log(options, nullptr, &state[i].index);
|
||||
ck_assert(toxes[i] != nullptr);
|
||||
autotoxes[i].tox = tox_new_log(options, nullptr, &autotoxes[i].index);
|
||||
ck_assert(autotoxes[i].tox != nullptr);
|
||||
tox_options_free(options);
|
||||
free(save[i]);
|
||||
|
||||
set_mono_time_callback(toxes[i], &state[i]);
|
||||
tox_conference_set_max_offline(toxes[i], 0, max_frozen, nullptr);
|
||||
set_mono_time_callback(&autotoxes[i]);
|
||||
tox_conference_set_max_offline(autotoxes[i].tox, 0, max_frozen, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,43 +263,43 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
|
||||
for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
char name[NAMELEN + 1];
|
||||
snprintf(name, NAMELEN + 1, NEW_NAME_FORMAT_STR, state[i].index);
|
||||
tox_self_set_name(toxes[i], (const uint8_t *)name, NAMELEN, nullptr);
|
||||
snprintf(name, NAMELEN + 1, NEW_NAME_FORMAT_STR, autotoxes[i].index);
|
||||
tox_self_set_name(autotoxes[i].tox, (const uint8_t *)name, NAMELEN, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
const uint32_t num_frozen = tox_conference_offline_peer_count(toxes[i], 0, nullptr);
|
||||
const uint32_t num_frozen = tox_conference_offline_peer_count(autotoxes[i].tox, 0, nullptr);
|
||||
ck_assert_msg(num_frozen <= max_frozen,
|
||||
"tox #%u has too many offline peers: %u\n",
|
||||
state[i].index, num_frozen);
|
||||
autotoxes[i].index, num_frozen);
|
||||
}
|
||||
|
||||
printf("reconnecting toxes\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(NUM_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!all_connected_to_group(NUM_GROUP_TOX, toxes));
|
||||
iterate_all_wait(NUM_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!all_connected_to_group(NUM_GROUP_TOX, autotoxes));
|
||||
|
||||
printf("running conference tests\n");
|
||||
|
||||
for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
tox_callback_conference_message(toxes[i], &handle_conference_message);
|
||||
tox_callback_conference_message(autotoxes[i].tox, &handle_conference_message);
|
||||
|
||||
iterate_all_wait(NUM_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(NUM_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
}
|
||||
|
||||
Tox_Err_Conference_Send_Message err;
|
||||
ck_assert_msg(
|
||||
tox_conference_send_message(
|
||||
toxes[random_u32() % NUM_GROUP_TOX], 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE,
|
||||
autotoxes[random_u32() % NUM_GROUP_TOX].tox, 0, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE,
|
||||
sizeof(GROUP_MESSAGE) - 1, &err) != 0, "failed to send group message");
|
||||
ck_assert_msg(
|
||||
err == TOX_ERR_CONFERENCE_SEND_MESSAGE_OK, "failed to send group message");
|
||||
num_recv = 0;
|
||||
|
||||
for (uint8_t j = 0; j < NUM_GROUP_TOX * 2; ++j) {
|
||||
iterate_all_wait(NUM_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(NUM_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
}
|
||||
|
||||
ck_assert_msg(num_recv == NUM_GROUP_TOX, "failed to recv group messages");
|
||||
|
@ -309,23 +308,23 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
for (uint32_t j = 0; j < NUM_GROUP_TOX; ++j) {
|
||||
uint8_t name[NAMELEN];
|
||||
tox_conference_peer_get_name(toxes[i], 0, j, name, nullptr);
|
||||
tox_conference_peer_get_name(autotoxes[i].tox, 0, j, name, nullptr);
|
||||
/* Note the toxes will have been reordered */
|
||||
ck_assert_msg(memcmp(name, "New", 3) == 0,
|
||||
"name of #%u according to #%u not updated", state[j].index, state[i].index);
|
||||
"name of #%u according to #%u not updated", autotoxes[j].index, autotoxes[i].index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t k = NUM_GROUP_TOX; k != 0 ; --k) {
|
||||
tox_conference_delete(toxes[k - 1], 0, nullptr);
|
||||
tox_conference_delete(autotoxes[k - 1].tox, 0, nullptr);
|
||||
|
||||
for (uint8_t j = 0; j < 10 || j < NUM_GROUP_TOX; ++j) {
|
||||
iterate_all_wait(NUM_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(NUM_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < k - 1; ++i) {
|
||||
uint32_t peer_count = tox_conference_peer_count(toxes[i], 0, nullptr);
|
||||
uint32_t peer_count = tox_conference_peer_count(autotoxes[i].tox, 0, nullptr);
|
||||
ck_assert_msg(peer_count == (k - 1), "\n\tBad number of group peers (post check)."
|
||||
"\n\t\t\tExpected: %u but tox_instance(%u) only has: %u\n\n",
|
||||
k - 1, i, (unsigned)peer_count);
|
||||
|
@ -333,26 +332,27 @@ static void run_conference_tests(Tox **toxes, State *state)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_many_group(Tox **toxes, State *state)
|
||||
static void test_many_group(AutoTox *autotoxes)
|
||||
{
|
||||
const time_t test_start_time = time(nullptr);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
tox_callback_self_connection_status(toxes[i], &handle_self_connection_status);
|
||||
tox_callback_friend_connection_status(toxes[i], &handle_friend_connection_status);
|
||||
tox_callback_conference_invite(toxes[i], &handle_conference_invite);
|
||||
tox_callback_conference_connected(toxes[i], &handle_conference_connected);
|
||||
tox_callback_self_connection_status(autotoxes[i].tox, &handle_self_connection_status);
|
||||
tox_callback_friend_connection_status(autotoxes[i].tox, &handle_friend_connection_status);
|
||||
tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite);
|
||||
tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected);
|
||||
|
||||
char name[NAMELEN + 1];
|
||||
snprintf(name, NAMELEN + 1, NAME_FORMAT_STR, state[i].index);
|
||||
tox_self_set_name(toxes[i], (const uint8_t *)name, NAMELEN, nullptr);
|
||||
snprintf(name, NAMELEN + 1, NAME_FORMAT_STR, autotoxes[i].index);
|
||||
tox_self_set_name(autotoxes[i].tox, (const uint8_t *)name, NAMELEN, nullptr);
|
||||
}
|
||||
|
||||
ck_assert_msg(tox_conference_new(toxes[0], nullptr) != UINT32_MAX, "failed to create group");
|
||||
printf("tox #%u: inviting its first friend\n", state[0].index);
|
||||
ck_assert_msg(tox_conference_invite(toxes[0], 0, 0, nullptr) != 0, "failed to invite friend");
|
||||
state[0].invited_next = true;
|
||||
ck_assert_msg(tox_conference_set_title(toxes[0], 0, (const uint8_t *)"Gentoo", sizeof("Gentoo") - 1, nullptr) != 0,
|
||||
ck_assert_msg(tox_conference_new(autotoxes[0].tox, nullptr) != UINT32_MAX, "failed to create group");
|
||||
printf("tox #%u: inviting its first friend\n", autotoxes[0].index);
|
||||
ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend");
|
||||
((State *)autotoxes[0].state)->invited_next = true;
|
||||
ck_assert_msg(tox_conference_set_title(autotoxes[0].tox, 0, (const uint8_t *)"Gentoo", sizeof("Gentoo") - 1,
|
||||
nullptr) != 0,
|
||||
"failed to set group title");
|
||||
|
||||
|
||||
|
@ -360,16 +360,16 @@ static void test_many_group(Tox **toxes, State *state)
|
|||
uint32_t invited_count = 0;
|
||||
|
||||
do {
|
||||
iterate_all_wait(NUM_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(NUM_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
|
||||
invited_count = 0;
|
||||
|
||||
for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
invited_count += state[i].invited_next;
|
||||
invited_count += ((State *)autotoxes[i].state)->invited_next;
|
||||
}
|
||||
} while (invited_count != NUM_GROUP_TOX - 1);
|
||||
|
||||
uint64_t pregroup_clock = state[0].clock;
|
||||
uint64_t pregroup_clock = autotoxes[0].clock;
|
||||
printf("waiting for all toxes to be in the group\n");
|
||||
uint32_t fully_connected_count = 0;
|
||||
|
||||
|
@ -377,11 +377,11 @@ static void test_many_group(Tox **toxes, State *state)
|
|||
fully_connected_count = 0;
|
||||
printf("current peer counts: [");
|
||||
|
||||
iterate_all_wait(NUM_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(NUM_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
Tox_Err_Conference_Peer_Query err;
|
||||
uint32_t peer_count = tox_conference_peer_count(toxes[i], 0, &err);
|
||||
uint32_t peer_count = tox_conference_peer_count(autotoxes[i].tox, 0, &err);
|
||||
|
||||
if (err != TOX_ERR_CONFERENCE_PEER_QUERY_OK) {
|
||||
peer_count = 0;
|
||||
|
@ -401,28 +401,28 @@ static void test_many_group(Tox **toxes, State *state)
|
|||
} while (fully_connected_count != NUM_GROUP_TOX);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_GROUP_TOX; ++i) {
|
||||
uint32_t peer_count = tox_conference_peer_count(toxes[i], 0, nullptr);
|
||||
uint32_t peer_count = tox_conference_peer_count(autotoxes[i].tox, 0, nullptr);
|
||||
|
||||
ck_assert_msg(peer_count == NUM_GROUP_TOX, "\n\tBad number of group peers (pre check)."
|
||||
"\n\t\t\tExpected: %d but tox_instance(%u) only has: %u\n\n",
|
||||
NUM_GROUP_TOX, i, (unsigned)peer_count);
|
||||
|
||||
uint8_t title[2048];
|
||||
size_t ret = tox_conference_get_title_size(toxes[i], 0, nullptr);
|
||||
size_t ret = tox_conference_get_title_size(autotoxes[i].tox, 0, nullptr);
|
||||
ck_assert_msg(ret == sizeof("Gentoo") - 1, "Wrong title length");
|
||||
tox_conference_get_title(toxes[i], 0, title, nullptr);
|
||||
tox_conference_get_title(autotoxes[i].tox, 0, title, nullptr);
|
||||
ck_assert_msg(memcmp("Gentoo", title, ret) == 0, "Wrong title");
|
||||
}
|
||||
|
||||
printf("waiting for names to propagate\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(NUM_GROUP_TOX, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!names_propagated(NUM_GROUP_TOX, toxes, state));
|
||||
iterate_all_wait(NUM_GROUP_TOX, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!names_propagated(NUM_GROUP_TOX, autotoxes));
|
||||
|
||||
printf("group connected, took %d seconds\n", (int)((state[0].clock - pregroup_clock) / 1000));
|
||||
printf("group connected, took %d seconds\n", (int)((autotoxes[0].clock - pregroup_clock) / 1000));
|
||||
|
||||
run_conference_tests(toxes, state);
|
||||
run_conference_tests(autotoxes);
|
||||
|
||||
printf("test_many_group succeeded, took %d seconds\n", (int)(time(nullptr) - test_start_time));
|
||||
}
|
||||
|
@ -431,6 +431,9 @@ int main(void)
|
|||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, NUM_GROUP_TOX, test_many_group, true);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
|
||||
run_auto_test(nullptr, NUM_GROUP_TOX, test_many_group, sizeof(State), &options);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,14 +7,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
} State;
|
||||
#include "auto_test_support.h"
|
||||
|
||||
#include "run_auto_test.h"
|
||||
|
||||
static void friend_connection_test(Tox **toxes, State *state)
|
||||
static void friend_connection_test(AutoTox *toxes)
|
||||
{
|
||||
// Nothing to do here. When copying this test, add test-specific code here.
|
||||
}
|
||||
|
@ -23,6 +18,9 @@ int main(void)
|
|||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, 2, friend_connection_test, false);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
run_auto_test(nullptr, 2, friend_connection_test, 0, &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,20 +13,18 @@
|
|||
#include "check_compat.h"
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
|
||||
bool custom_packet_received;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
#define LOSSLESS_PACKET_FILLER 160
|
||||
|
||||
static void handle_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
|
||||
void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
uint8_t cmp_packet[TOX_MAX_CUSTOM_PACKET_SIZE];
|
||||
memset(cmp_packet, LOSSLESS_PACKET_FILLER, sizeof(cmp_packet));
|
||||
|
@ -36,27 +34,31 @@ static void handle_lossless_packet(Tox *tox, uint32_t friend_number, const uint8
|
|||
}
|
||||
}
|
||||
|
||||
static void test_lossless_packet(Tox **toxes, State *state)
|
||||
static void test_lossless_packet(AutoTox *autotoxes)
|
||||
{
|
||||
tox_callback_friend_lossless_packet(toxes[1], &handle_lossless_packet);
|
||||
tox_callback_friend_lossless_packet(autotoxes[1].tox, &handle_lossless_packet);
|
||||
uint8_t packet[TOX_MAX_CUSTOM_PACKET_SIZE + 1];
|
||||
memset(packet, LOSSLESS_PACKET_FILLER, sizeof(packet));
|
||||
|
||||
bool ret = tox_friend_send_lossless_packet(toxes[0], 0, packet, sizeof(packet), nullptr);
|
||||
bool ret = tox_friend_send_lossless_packet(autotoxes[0].tox, 0, packet, sizeof(packet), nullptr);
|
||||
ck_assert_msg(ret == false, "should not be able to send custom packets this big %i", ret);
|
||||
|
||||
ret = tox_friend_send_lossless_packet(toxes[0], 0, packet, TOX_MAX_CUSTOM_PACKET_SIZE, nullptr);
|
||||
ret = tox_friend_send_lossless_packet(autotoxes[0].tox, 0, packet, TOX_MAX_CUSTOM_PACKET_SIZE, nullptr);
|
||||
ck_assert_msg(ret == true, "tox_friend_send_lossless_packet fail %i", ret);
|
||||
|
||||
do {
|
||||
iterate_all_wait(2, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!state[1].custom_packet_received);
|
||||
iterate_all_wait(2, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!((State *)autotoxes[1].state)->custom_packet_received);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, 2, test_lossless_packet, false);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
|
||||
run_auto_test(nullptr, 2, test_lossless_packet, sizeof(State), &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -11,13 +11,10 @@
|
|||
#include "check_compat.h"
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
|
||||
bool custom_packet_received;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
#define LOSSY_PACKET_FILLER 200
|
||||
|
||||
|
@ -27,32 +24,37 @@ static void handle_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t
|
|||
memset(cmp_packet, LOSSY_PACKET_FILLER, sizeof(cmp_packet));
|
||||
|
||||
if (length == TOX_MAX_CUSTOM_PACKET_SIZE && memcmp(data, cmp_packet, sizeof(cmp_packet)) == 0) {
|
||||
State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
state->custom_packet_received = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_lossy_packet(Tox **toxes, State *state)
|
||||
static void test_lossy_packet(AutoTox *autotoxes)
|
||||
{
|
||||
tox_callback_friend_lossy_packet(toxes[1], &handle_lossy_packet);
|
||||
tox_callback_friend_lossy_packet(autotoxes[1].tox, &handle_lossy_packet);
|
||||
uint8_t packet[TOX_MAX_CUSTOM_PACKET_SIZE + 1];
|
||||
memset(packet, LOSSY_PACKET_FILLER, sizeof(packet));
|
||||
|
||||
bool ret = tox_friend_send_lossy_packet(toxes[0], 0, packet, sizeof(packet), nullptr);
|
||||
bool ret = tox_friend_send_lossy_packet(autotoxes[0].tox, 0, packet, sizeof(packet), nullptr);
|
||||
ck_assert_msg(ret == false, "should not be able to send custom packets this big %i", ret);
|
||||
|
||||
ret = tox_friend_send_lossy_packet(toxes[0], 0, packet, TOX_MAX_CUSTOM_PACKET_SIZE, nullptr);
|
||||
ret = tox_friend_send_lossy_packet(autotoxes[0].tox, 0, packet, TOX_MAX_CUSTOM_PACKET_SIZE, nullptr);
|
||||
ck_assert_msg(ret == true, "tox_friend_send_lossy_packet fail %i", ret);
|
||||
|
||||
do {
|
||||
iterate_all_wait(2, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!state[1].custom_packet_received);
|
||||
iterate_all_wait(2, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!((State *)autotoxes[1].state)->custom_packet_received);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, 2, test_lossy_packet, false);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
|
||||
run_auto_test(nullptr, 2, test_lossy_packet, sizeof(State), &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4,26 +4,24 @@
|
|||
#include <stdint.h>
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
|
||||
uint32_t recv_count;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
#define NUM_MSGS 40000
|
||||
|
||||
static void handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type,
|
||||
const uint8_t *message, size_t length, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
state->recv_count++;
|
||||
}
|
||||
|
||||
static void net_crypto_overflow_test(Tox **toxes, State *state)
|
||||
static void net_crypto_overflow_test(AutoTox *autotoxes)
|
||||
{
|
||||
tox_callback_friend_message(toxes[0], handle_friend_message);
|
||||
tox_callback_friend_message(autotoxes[0].tox, handle_friend_message);
|
||||
|
||||
printf("sending many messages to tox0\n");
|
||||
|
||||
|
@ -33,7 +31,7 @@ static void net_crypto_overflow_test(Tox **toxes, State *state)
|
|||
snprintf((char *)message, sizeof(message), "%u-%u", tox_index, i);
|
||||
|
||||
Tox_Err_Friend_Send_Message err;
|
||||
tox_friend_send_message(toxes[tox_index], 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof message, &err);
|
||||
tox_friend_send_message(autotoxes[tox_index].tox, 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof message, &err);
|
||||
|
||||
if (err == TOX_ERR_FRIEND_SEND_MESSAGE_SENDQ) {
|
||||
printf("tox%u sent %u messages to friend 0\n", tox_index, i);
|
||||
|
@ -48,16 +46,19 @@ static void net_crypto_overflow_test(Tox **toxes, State *state)
|
|||
// TODO(iphydf): Wait until all messages have arrived. Currently, not all
|
||||
// messages arrive, so this test would always fail.
|
||||
for (uint32_t i = 0; i < 200; i++) {
|
||||
iterate_all_wait(3, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(3, autotoxes, ITERATION_INTERVAL);
|
||||
}
|
||||
|
||||
printf("tox%u received %u messages\n", state[0].index, state[0].recv_count);
|
||||
printf("tox%u received %u messages\n", autotoxes[0].index, ((State *)autotoxes[0].state)->recv_count);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, 3, net_crypto_overflow_test, false);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
run_auto_test(nullptr, 3, net_crypto_overflow_test, sizeof(State), &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,23 +3,18 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
#define NUM_MSGS 40000
|
||||
|
||||
static void net_crypto_overflow_test(Tox **toxes, State *state)
|
||||
static void net_crypto_overflow_test(AutoTox *autotoxes)
|
||||
{
|
||||
const uint8_t message[] = {0};
|
||||
bool errored = false;
|
||||
|
||||
for (uint32_t i = 0; i < NUM_MSGS; i++) {
|
||||
Tox_Err_Friend_Send_Message err;
|
||||
tox_friend_send_message(toxes[0], 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof message, &err);
|
||||
tox_friend_send_message(autotoxes[0].tox, 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof message, &err);
|
||||
|
||||
if (err != TOX_ERR_FRIEND_SEND_MESSAGE_OK) {
|
||||
errored = true;
|
||||
|
@ -43,6 +38,9 @@ int main(void)
|
|||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, 2, net_crypto_overflow_test, false);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
run_auto_test(nullptr, 2, net_crypto_overflow_test, 0, &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -18,20 +18,15 @@
|
|||
#define TOX_COUNT 2
|
||||
#define RECONNECT_TIME_MAX (FRIEND_CONNECTION_TIMEOUT + 3)
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
} State;
|
||||
#include "auto_test_support.h"
|
||||
|
||||
#include "run_auto_test.h"
|
||||
|
||||
static uint32_t tox_connected_count(uint32_t tox_count, Tox **toxes, State *state, uint32_t index)
|
||||
static uint32_t tox_connected_count(uint32_t tox_count, AutoTox *autotoxes, uint32_t index)
|
||||
{
|
||||
const size_t friend_count = tox_self_get_friend_list_size(toxes[index]);
|
||||
const size_t friend_count = tox_self_get_friend_list_size(autotoxes[index].tox);
|
||||
uint32_t connected_count = 0;
|
||||
|
||||
for (size_t j = 0; j < friend_count; j++) {
|
||||
if (tox_friend_get_connection_status(toxes[index], j, nullptr) != TOX_CONNECTION_NONE) {
|
||||
if (tox_friend_get_connection_status(autotoxes[index].tox, j, nullptr) != TOX_CONNECTION_NONE) {
|
||||
++connected_count;
|
||||
}
|
||||
}
|
||||
|
@ -39,14 +34,14 @@ static uint32_t tox_connected_count(uint32_t tox_count, Tox **toxes, State *stat
|
|||
return connected_count;
|
||||
}
|
||||
|
||||
static bool all_disconnected_from(uint32_t tox_count, Tox **toxes, State *state, uint32_t index)
|
||||
static bool all_disconnected_from(uint32_t tox_count, AutoTox *autotoxes, uint32_t index)
|
||||
{
|
||||
for (uint32_t i = 0; i < tox_count; i++) {
|
||||
if (i == index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tox_connected_count(tox_count, toxes, state, i) >= tox_count - 1) {
|
||||
if (tox_connected_count(tox_count, autotoxes, i) >= tox_count - 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -54,39 +49,39 @@ static bool all_disconnected_from(uint32_t tox_count, Tox **toxes, State *state,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void test_reconnect(Tox **toxes, State *state)
|
||||
static void test_reconnect(AutoTox *autotoxes)
|
||||
{
|
||||
const time_t test_start_time = time(nullptr);
|
||||
|
||||
printf("letting connections settle\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(TOX_COUNT, toxes, state, ITERATION_INTERVAL);
|
||||
iterate_all_wait(TOX_COUNT, autotoxes, ITERATION_INTERVAL);
|
||||
} while (time(nullptr) - test_start_time < 2);
|
||||
|
||||
uint16_t disconnect = random_u16() % TOX_COUNT;
|
||||
printf("disconnecting #%u\n", state[disconnect].index);
|
||||
printf("disconnecting #%u\n", autotoxes[disconnect].index);
|
||||
|
||||
do {
|
||||
for (uint16_t i = 0; i < TOX_COUNT; ++i) {
|
||||
if (i != disconnect) {
|
||||
tox_iterate(toxes[i], &state[i]);
|
||||
state[i].clock += 1000;
|
||||
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
|
||||
autotoxes[i].clock += 1000;
|
||||
}
|
||||
}
|
||||
|
||||
c_sleep(20);
|
||||
} while (!all_disconnected_from(TOX_COUNT, toxes, state, disconnect));
|
||||
} while (!all_disconnected_from(TOX_COUNT, autotoxes, disconnect));
|
||||
|
||||
const uint64_t reconnect_start_time = state[0].clock;
|
||||
const uint64_t reconnect_start_time = autotoxes[0].clock;
|
||||
|
||||
printf("reconnecting\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(TOX_COUNT, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!all_friends_connected(TOX_COUNT, toxes));
|
||||
iterate_all_wait(TOX_COUNT, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!all_friends_connected(TOX_COUNT, autotoxes));
|
||||
|
||||
const uint64_t reconnect_time = state[0].clock - reconnect_start_time;
|
||||
const uint64_t reconnect_time = autotoxes[0].clock - reconnect_start_time;
|
||||
ck_assert_msg(reconnect_time <= RECONNECT_TIME_MAX * 1000, "reconnection took %d seconds; expected at most %d seconds",
|
||||
(int)(reconnect_time / 1000), RECONNECT_TIME_MAX);
|
||||
|
||||
|
@ -97,6 +92,9 @@ int main(void)
|
|||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, TOX_COUNT, test_reconnect, false);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
run_auto_test(nullptr, TOX_COUNT, test_reconnect, 0, &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,232 +0,0 @@
|
|||
#include <stdlib.h> // calloc, free
|
||||
#include "check_compat.h"
|
||||
#include "../testing/misc_tools.h"
|
||||
#include "../toxcore/Messenger.h"
|
||||
#include "../toxcore/mono_time.h"
|
||||
|
||||
// List of live bootstrap nodes. These nodes should have TCP server enabled.
|
||||
static const struct BootstrapNodes {
|
||||
const char *ip;
|
||||
uint16_t port;
|
||||
const uint8_t key[32];
|
||||
} BootstrapNodes[] = {
|
||||
#ifndef USE_TEST_NETWORK
|
||||
{
|
||||
"tox.abilinski.com", 33445,
|
||||
0x10, 0xC0, 0x0E, 0xB2, 0x50, 0xC3, 0x23, 0x3E,
|
||||
0x34, 0x3E, 0x2A, 0xEB, 0xA0, 0x71, 0x15, 0xA5,
|
||||
0xC2, 0x89, 0x20, 0xE9, 0xC8, 0xD2, 0x94, 0x92,
|
||||
0xF6, 0xD0, 0x0B, 0x29, 0x04, 0x9E, 0xDC, 0x7E,
|
||||
},
|
||||
{
|
||||
"tox.initramfs.io", 33445,
|
||||
0x02, 0x80, 0x7C, 0xF4, 0xF8, 0xBB, 0x8F, 0xB3,
|
||||
0x90, 0xCC, 0x37, 0x94, 0xBD, 0xF1, 0xE8, 0x44,
|
||||
0x9E, 0x9A, 0x83, 0x92, 0xC5, 0xD3, 0xF2, 0x20,
|
||||
0x00, 0x19, 0xDA, 0x9F, 0x1E, 0x81, 0x2E, 0x46,
|
||||
},
|
||||
{
|
||||
"tox.plastiras.org", 33445,
|
||||
0x8E, 0x8B, 0x63, 0x29, 0x9B, 0x3D, 0x52, 0x0F,
|
||||
0xB3, 0x77, 0xFE, 0x51, 0x00, 0xE6, 0x5E, 0x33,
|
||||
0x22, 0xF7, 0xAE, 0x5B, 0x20, 0xA0, 0xAC, 0xED,
|
||||
0x29, 0x81, 0x76, 0x9F, 0xC5, 0xB4, 0x37, 0x25,
|
||||
},
|
||||
{
|
||||
"tox.novg.net", 33445,
|
||||
0xD5, 0x27, 0xE5, 0x84, 0x7F, 0x83, 0x30, 0xD6,
|
||||
0x28, 0xDA, 0xB1, 0x81, 0x4F, 0x0A, 0x42, 0x2F,
|
||||
0x6D, 0xC9, 0xD0, 0xA3, 0x00, 0xE6, 0xC3, 0x57,
|
||||
0x63, 0x4E, 0xE2, 0xDA, 0x88, 0xC3, 0x54, 0x63,
|
||||
},
|
||||
#else
|
||||
{
|
||||
"172.93.52.70", 33445,
|
||||
0x79, 0xCA, 0xDA, 0x49, 0x74, 0xB0, 0x92, 0x6F,
|
||||
0x28, 0x6F, 0x02, 0x5C, 0xD5, 0xFF, 0xDF, 0x3E,
|
||||
0x65, 0x4A, 0x37, 0x58, 0xC5, 0x3E, 0x02, 0x73,
|
||||
0xEC, 0xFC, 0x4D, 0x12, 0xC2, 0x1D, 0xCA, 0x48,
|
||||
},
|
||||
#endif // USE_TEST_NETWORK
|
||||
{ nullptr, 0, 0 },
|
||||
};
|
||||
|
||||
static void bootstrap_toxes_live_network(Tox **toxes, uint32_t tox_count, bool enable_tcp)
|
||||
{
|
||||
for (size_t i = 0; i < tox_count; ++i) {
|
||||
for (size_t j = 0; BootstrapNodes[j].ip != nullptr; ++j) {
|
||||
const char *ip = BootstrapNodes[j].ip;
|
||||
uint16_t port = BootstrapNodes[j].port;
|
||||
const uint8_t *key = BootstrapNodes[j].key;
|
||||
|
||||
Tox_Err_Bootstrap err;
|
||||
tox_bootstrap(toxes[i], ip, port, key, &err);
|
||||
|
||||
if (err != TOX_ERR_BOOTSTRAP_OK) {
|
||||
fprintf(stderr, "Failed to bootstrap node %zu (%s): error %d\n", j, ip, err);
|
||||
}
|
||||
|
||||
if (enable_tcp) {
|
||||
tox_add_tcp_relay(toxes[i], ip, port, key, &err);
|
||||
|
||||
if (err != TOX_ERR_BOOTSTRAP_OK) {
|
||||
fprintf(stderr, "Failed to add TCP relay %zu (%s): error %d\n", j, ip, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool all_connected(uint32_t tox_count, Tox **toxes)
|
||||
{
|
||||
for (uint32_t i = 0; i < tox_count; i++) {
|
||||
if (tox_self_get_connection_status(toxes[i]) == TOX_CONNECTION_NONE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool all_friends_connected(uint32_t tox_count, Tox **toxes)
|
||||
{
|
||||
for (uint32_t i = 0; i < tox_count; i++) {
|
||||
const size_t friend_count = tox_self_get_friend_list_size(toxes[i]);
|
||||
|
||||
for (size_t j = 0; j < friend_count; j++) {
|
||||
if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_NONE) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void iterate_all_wait(uint32_t tox_count, Tox **toxes, State *state, uint32_t wait)
|
||||
{
|
||||
for (uint32_t i = 0; i < tox_count; i++) {
|
||||
tox_iterate(toxes[i], &state[i]);
|
||||
state[i].clock += wait;
|
||||
}
|
||||
|
||||
/* Also actually sleep a little, to allow for local network processing */
|
||||
c_sleep(5);
|
||||
}
|
||||
|
||||
static uint64_t get_state_clock_callback(Mono_Time *mono_time, void *user_data)
|
||||
{
|
||||
const State *state = (const State *)user_data;
|
||||
return state->clock;
|
||||
}
|
||||
|
||||
static void set_mono_time_callback(Tox *tox, State *state)
|
||||
{
|
||||
// TODO(iphydf): Don't rely on toxcore internals.
|
||||
Mono_Time *mono_time = ((Messenger *)tox)->mono_time;
|
||||
|
||||
state->clock = current_time_monotonic(mono_time);
|
||||
mono_time_set_current_time_callback(mono_time, get_state_clock_callback, state);
|
||||
}
|
||||
|
||||
static void add_friend(uint32_t i, uint32_t j, Tox **toxes)
|
||||
{
|
||||
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_public_key(toxes[j], public_key);
|
||||
Tox_Err_Friend_Add err;
|
||||
tox_friend_add_norequest(toxes[i], public_key, &err);
|
||||
ck_assert(err == TOX_ERR_FRIEND_ADD_OK);
|
||||
}
|
||||
|
||||
static void build_friend_graph(uint32_t tox_count, bool chain, Tox **toxes)
|
||||
{
|
||||
if (chain) {
|
||||
printf("each tox adds adjacent toxes as friends\n");
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; i++) {
|
||||
for (uint32_t j = i - 1; j != i + 3; j += 2) {
|
||||
if (j >= tox_count) {
|
||||
continue;
|
||||
}
|
||||
|
||||
add_friend(i, j, toxes);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("toxes all add each other as friends\n");
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; i++) {
|
||||
for (uint32_t j = 0; j < tox_count; j++) {
|
||||
if (i != j) {
|
||||
add_friend(i, j, toxes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wait_friend_connections(uint32_t tox_count, Tox **toxes, State *state)
|
||||
{
|
||||
do {
|
||||
iterate_all_wait(tox_count, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!all_connected(tox_count, toxes));
|
||||
|
||||
printf("toxes are online\n");
|
||||
|
||||
do {
|
||||
iterate_all_wait(tox_count, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!all_friends_connected(tox_count, toxes));
|
||||
|
||||
printf("tox clients connected\n");
|
||||
}
|
||||
|
||||
static void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(Tox **toxes, State *state),
|
||||
bool chain)
|
||||
{
|
||||
printf("initialising %u toxes\n", tox_count);
|
||||
Tox **toxes = (Tox **)calloc(tox_count, sizeof(Tox *));
|
||||
State *state = (State *)calloc(tox_count, sizeof(State));
|
||||
|
||||
ck_assert(toxes != nullptr);
|
||||
ck_assert(state != nullptr);
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; i++) {
|
||||
state[i].index = i;
|
||||
toxes[i] = tox_new_log(options, nullptr, &state[i].index);
|
||||
ck_assert_msg(toxes[i], "failed to create %u tox instances", i + 1);
|
||||
|
||||
set_mono_time_callback(toxes[i], &state[i]);
|
||||
}
|
||||
|
||||
build_friend_graph(tox_count, chain, toxes);
|
||||
|
||||
const bool udp_enabled = options != nullptr ? tox_options_get_udp_enabled(options) : true;
|
||||
Tox_Err_Bootstrap err;
|
||||
|
||||
if (udp_enabled) {
|
||||
printf("bootstrapping all toxes off toxes[0]\n");
|
||||
|
||||
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_dht_id(toxes[0], dht_key);
|
||||
const uint16_t dht_port = tox_self_get_udp_port(toxes[0], nullptr);
|
||||
|
||||
for (uint32_t i = 1; i < tox_count; i++) {
|
||||
tox_bootstrap(toxes[i], "localhost", dht_port, dht_key, &err);
|
||||
ck_assert(err == TOX_ERR_BOOTSTRAP_OK);
|
||||
}
|
||||
} else {
|
||||
printf("bootstrapping all toxes to tcp relays\n");
|
||||
bootstrap_toxes_live_network(toxes, tox_count, true);
|
||||
}
|
||||
|
||||
wait_friend_connections(tox_count, toxes, state);
|
||||
|
||||
test(toxes, state);
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; i++) {
|
||||
tox_kill(toxes[i]);
|
||||
}
|
||||
|
||||
free(state);
|
||||
free(toxes);
|
||||
}
|
|
@ -6,21 +6,19 @@
|
|||
#include <string.h>
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
|
||||
bool message_received;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
#define MESSAGE_FILLER 'G'
|
||||
|
||||
static void message_callback(
|
||||
Tox *m, uint32_t friendnumber, Tox_Message_Type type,
|
||||
const uint8_t *string, size_t length, void *userdata)
|
||||
const uint8_t *string, size_t length, void *user_data)
|
||||
{
|
||||
State *state = (State *)userdata;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
if (type != TOX_MESSAGE_TYPE_NORMAL) {
|
||||
ck_abort_msg("Bad type");
|
||||
|
@ -34,29 +32,32 @@ static void message_callback(
|
|||
}
|
||||
}
|
||||
|
||||
static void send_message_test(Tox **toxes, State *state)
|
||||
static void send_message_test(AutoTox *autotoxes)
|
||||
{
|
||||
tox_callback_friend_message(toxes[1], &message_callback);
|
||||
tox_callback_friend_message(autotoxes[1].tox, &message_callback);
|
||||
|
||||
uint8_t msgs[TOX_MAX_MESSAGE_LENGTH + 1];
|
||||
memset(msgs, MESSAGE_FILLER, sizeof(msgs));
|
||||
|
||||
Tox_Err_Friend_Send_Message errm;
|
||||
tox_friend_send_message(toxes[0], 0, TOX_MESSAGE_TYPE_NORMAL, msgs, TOX_MAX_MESSAGE_LENGTH + 1, &errm);
|
||||
tox_friend_send_message(autotoxes[0].tox, 0, TOX_MESSAGE_TYPE_NORMAL, msgs, TOX_MAX_MESSAGE_LENGTH + 1, &errm);
|
||||
ck_assert_msg(errm == TOX_ERR_FRIEND_SEND_MESSAGE_TOO_LONG, "TOX_MAX_MESSAGE_LENGTH is too small? error=%d", errm);
|
||||
|
||||
tox_friend_send_message(toxes[0], 0, TOX_MESSAGE_TYPE_NORMAL, msgs, TOX_MAX_MESSAGE_LENGTH, &errm);
|
||||
tox_friend_send_message(autotoxes[0].tox, 0, TOX_MESSAGE_TYPE_NORMAL, msgs, TOX_MAX_MESSAGE_LENGTH, &errm);
|
||||
ck_assert_msg(errm == TOX_ERR_FRIEND_SEND_MESSAGE_OK, "TOX_MAX_MESSAGE_LENGTH is too big? error=%d", errm);
|
||||
|
||||
do {
|
||||
iterate_all_wait(2, toxes, state, ITERATION_INTERVAL);
|
||||
} while (!state[1].message_received);
|
||||
iterate_all_wait(2, autotoxes, ITERATION_INTERVAL);
|
||||
} while (!((State *)autotoxes[1].state)->message_received);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
||||
run_auto_test(nullptr, 2, send_message_test, false);
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
run_auto_test(nullptr, 2, send_message_test, sizeof(State), &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3,12 +3,7 @@
|
|||
#include "../testing/misc_tools.h"
|
||||
#include "check_compat.h"
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
@ -19,7 +14,7 @@ int main(void)
|
|||
Tox *tox_tcp = tox_new_log(opts, nullptr, nullptr);
|
||||
tox_options_free(opts);
|
||||
|
||||
bootstrap_toxes_live_network(&tox_tcp, 1, true);
|
||||
bootstrap_tox_live_network(tox_tcp, true);
|
||||
|
||||
printf("Waiting for connection");
|
||||
|
||||
|
@ -38,7 +33,5 @@ int main(void)
|
|||
|
||||
tox_kill(tox_tcp);
|
||||
|
||||
(void)run_auto_test;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,40 +12,39 @@
|
|||
#include "check_compat.h"
|
||||
|
||||
typedef struct State {
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
bool friend_is_typing;
|
||||
} State;
|
||||
|
||||
#include "run_auto_test.h"
|
||||
#include "auto_test_support.h"
|
||||
|
||||
static void typing_callback(Tox *m, uint32_t friendnumber, bool typing, void *userdata)
|
||||
static void typing_callback(Tox *m, uint32_t friendnumber, bool typing, void *user_data)
|
||||
{
|
||||
State *state = (State *)userdata;
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
state->friend_is_typing = typing;
|
||||
}
|
||||
|
||||
static void test_typing(Tox **toxes, State *state)
|
||||
static void test_typing(AutoTox *autotoxes)
|
||||
{
|
||||
time_t cur_time = time(nullptr);
|
||||
|
||||
tox_callback_friend_typing(toxes[1], &typing_callback);
|
||||
tox_self_set_typing(toxes[0], 0, true, nullptr);
|
||||
tox_callback_friend_typing(autotoxes[1].tox, &typing_callback);
|
||||
tox_self_set_typing(autotoxes[0].tox, 0, true, nullptr);
|
||||
|
||||
do {
|
||||
iterate_all_wait(2, toxes, state, 200);
|
||||
} while (!state[1].friend_is_typing);
|
||||
iterate_all_wait(2, autotoxes, 200);
|
||||
} while (!((State *)autotoxes[1].state)->friend_is_typing);
|
||||
|
||||
ck_assert_msg(tox_friend_get_typing(toxes[1], 0, nullptr) == 1,
|
||||
ck_assert_msg(tox_friend_get_typing(autotoxes[1].tox, 0, nullptr) == 1,
|
||||
"tox_friend_get_typing should have returned true, but it didn't");
|
||||
tox_self_set_typing(toxes[0], 0, false, nullptr);
|
||||
tox_self_set_typing(autotoxes[0].tox, 0, false, nullptr);
|
||||
|
||||
do {
|
||||
iterate_all_wait(2, toxes, state, 200);
|
||||
} while (state[1].friend_is_typing);
|
||||
iterate_all_wait(2, autotoxes, 200);
|
||||
} while (((State *)autotoxes[1].state)->friend_is_typing);
|
||||
|
||||
Tox_Err_Friend_Query err_t;
|
||||
ck_assert_msg(tox_friend_get_typing(toxes[1], 0, &err_t) == 0,
|
||||
ck_assert_msg(tox_friend_get_typing(autotoxes[1].tox, 0, &err_t) == 0,
|
||||
"tox_friend_get_typing should have returned false, but it didn't");
|
||||
ck_assert_msg(err_t == TOX_ERR_FRIEND_QUERY_OK, "tox_friend_get_typing call did not return correct error");
|
||||
|
||||
|
@ -55,6 +54,10 @@ static void test_typing(Tox **toxes, State *state)
|
|||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
run_auto_test(nullptr, 2, test_typing, false);
|
||||
|
||||
Run_Auto_Options options = default_run_auto_options;
|
||||
options.graph = GRAPH_LINEAR;
|
||||
run_auto_test(nullptr, 2, test_typing, sizeof(State), &options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user