forked from Green-Sky/tomato
Green Sky
9ace11a0e2
8f0d505f9a feat: add ngc events 9b8216e70c refactor: Make event dispatch ordered by receive time. 814c12a6f4 cleanup: Add dynamically derived array sizes to the API. 226b23be12 cleanup: Add explicit array sizes to toxencryptsave. ef33cb4de0 cleanup: Add Toxav alias for ToxAV. 1da723b34d cleanup: Make Tox_Options a typedef. b148a2afff chore: Simplify msvc build using vcpkg. 5cac6d7eb1 cleanup: Move `tox_get_system` out of the public API. c9ca4007e3 refactor: Align group message sending with other send functions. 6c6c0b1b1b cleanup: Make setters take non-const `Tox *`. a76f758d70 cleanup: Mark arrays in the tox API as `[]` instead of `*`. baf6d1f6cf cleanup: Make array params in toxav `[]` instead of `*`. 79f55bd06a cleanup: Put the size of fixed arrays into the API types. 1e73698db2 cleanup: Add typedefs for public API int identifiers. cac074c57f chore: Add fetch-sha256 script to update bootstrap node hash. 32576656bb Make the comment capitalization uniform aff4dda17c Spellcheck tox-bootstrapd 40b5fbbe9d chore: Remove settings.yml in favour of hs-github-tools. ebafd51be7 chore: Use GPL license with https. 0e42752f0f cleanup: Move all vptr-to-ptr casts to the beginning of a function. 5407384211 cleanup: Use github actions matrix to simplify CI. 82d8265688 fix: Use QueryPerformanceCounter on windows for monotonic time. 1224e656e3 chore: Add `net_(new|kill)_strerror` to cppcheck's allocators. 6a90ddfe4e cleanup: Run clang-tidy on headers, as well. bd930cc80a cleanup: Make TCP connection failures a warning instead of error. fad6e4e173 cleanup: Make all .c files include the headers they need. ef4897a898 cleanup: Upgrade to clang-tidy-17 and fix some warnings. REVERT: f1df709b87 feat: add ngc events REVERT: 1b6c907235 refactor: Make event dispatch ordered by receive time. git-subtree-dir: external/toxcore/c-toxcore git-subtree-split: 8f0d505f9a598cc41c682178e1589bcc01efe9cb
248 lines
7.8 KiB
C
248 lines
7.8 KiB
C
/*
|
|
* Does a basic functionality test for TCP connections.
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include "auto_test_support.h"
|
|
|
|
#define NUM_GROUP_TOXES 2
|
|
#define CODEWORD "RONALD MCDONALD"
|
|
#define CODEWORD_LEN (sizeof(CODEWORD) - 1)
|
|
|
|
typedef struct State {
|
|
size_t num_peers;
|
|
bool got_code;
|
|
bool got_second_code;
|
|
uint32_t peer_id[NUM_GROUP_TOXES - 1];
|
|
} State;
|
|
|
|
static void group_invite_handler(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length,
|
|
const uint8_t *group_name, size_t group_name_length, void *user_data)
|
|
{
|
|
printf("Accepting friend invite\n");
|
|
|
|
Tox_Err_Group_Invite_Accept err_accept;
|
|
tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)"test", 4,
|
|
nullptr, 0, &err_accept);
|
|
ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK);
|
|
}
|
|
|
|
static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data)
|
|
{
|
|
AutoTox *autotox = (AutoTox *)user_data;
|
|
ck_assert(autotox != nullptr);
|
|
|
|
State *state = (State *)autotox->state;
|
|
fprintf(stderr, "joined: %zu, %u\n", state->num_peers, peer_id);
|
|
ck_assert_msg(state->num_peers < NUM_GROUP_TOXES - 1, "%zu", state->num_peers);
|
|
|
|
state->peer_id[state->num_peers++] = peer_id;
|
|
}
|
|
|
|
static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
|
|
const uint8_t *message, size_t length, void *user_data)
|
|
{
|
|
AutoTox *autotox = (AutoTox *)user_data;
|
|
ck_assert(autotox != nullptr);
|
|
|
|
State *state = (State *)autotox->state;
|
|
|
|
ck_assert(length == CODEWORD_LEN);
|
|
ck_assert(memcmp(CODEWORD, message, length) == 0);
|
|
|
|
printf("Codeword: %s\n", CODEWORD);
|
|
|
|
state->got_code = true;
|
|
}
|
|
|
|
static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
|
|
const uint8_t *message, size_t length, uint32_t message_id, void *user_data)
|
|
{
|
|
AutoTox *autotox = (AutoTox *)user_data;
|
|
ck_assert(autotox != nullptr);
|
|
|
|
State *state = (State *)autotox->state;
|
|
|
|
ck_assert(length == CODEWORD_LEN);
|
|
ck_assert(memcmp(CODEWORD, message, length) == 0);
|
|
|
|
printf("Codeword: %s\n", CODEWORD);
|
|
|
|
state->got_second_code = true;
|
|
}
|
|
|
|
/*
|
|
* We need different constants to make TCP run smoothly. TODO(Jfreegman): is this because of the group
|
|
* implementation or just an autotest quirk?
|
|
*/
|
|
#define GROUP_ITERATION_INTERVAL 100
|
|
static void iterate_group(AutoTox *autotoxes, uint32_t num_toxes, size_t interval)
|
|
{
|
|
for (uint32_t i = 0; i < num_toxes; i++) {
|
|
if (autotoxes[i].alive) {
|
|
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
|
|
autotoxes[i].clock += interval;
|
|
}
|
|
}
|
|
|
|
c_sleep(50);
|
|
}
|
|
|
|
static bool all_peers_connected(AutoTox *autotoxes)
|
|
{
|
|
iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL);
|
|
|
|
size_t count = 0;
|
|
|
|
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
|
const State *state = (const State *)autotoxes[i].state;
|
|
|
|
if (state->num_peers == NUM_GROUP_TOXES - 1) {
|
|
++count;
|
|
}
|
|
}
|
|
|
|
return count == NUM_GROUP_TOXES;
|
|
}
|
|
|
|
static bool all_peers_got_code(AutoTox *autotoxes)
|
|
{
|
|
iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL);
|
|
|
|
size_t count = 0;
|
|
|
|
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
|
const State *state = (const State *)autotoxes[i].state;
|
|
|
|
if (state->got_code) {
|
|
++count;
|
|
}
|
|
}
|
|
|
|
return count == NUM_GROUP_TOXES - 1;
|
|
}
|
|
|
|
static void group_tcp_test(AutoTox *autotoxes)
|
|
{
|
|
ck_assert(NUM_GROUP_TOXES >= 2);
|
|
|
|
State *state0 = (State *)autotoxes[0].state;
|
|
State *state1 = (State *)autotoxes[1].state;
|
|
|
|
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
|
tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
|
|
tox_callback_group_private_message(autotoxes[i].tox, group_private_message_handler);
|
|
}
|
|
|
|
tox_callback_group_message(autotoxes[1].tox, group_message_handler);
|
|
tox_callback_group_invite(autotoxes[1].tox, group_invite_handler);
|
|
|
|
Tox_Err_Group_New new_err;
|
|
uint32_t groupnumber = tox_group_new(autotoxes[0].tox, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)"test", 4,
|
|
(const uint8_t *)"test", 4, &new_err);
|
|
ck_assert_msg(new_err == TOX_ERR_GROUP_NEW_OK, "tox_group_new failed: %d", new_err);
|
|
|
|
iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL);
|
|
|
|
Tox_Err_Group_State_Queries id_err;
|
|
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
|
|
|
tox_group_get_chat_id(autotoxes[0].tox, groupnumber, chat_id, &id_err);
|
|
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err);
|
|
|
|
printf("Tox 0 created new group...\n");
|
|
|
|
for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) {
|
|
Tox_Err_Group_Join jerr;
|
|
tox_group_join(autotoxes[i].tox, chat_id, (const uint8_t *)"test", 4, nullptr, 0, &jerr);
|
|
ck_assert_msg(jerr == TOX_ERR_GROUP_JOIN_OK, "%d", jerr);
|
|
iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL * 10);
|
|
}
|
|
|
|
while (!all_peers_connected(autotoxes))
|
|
;
|
|
|
|
printf("%d peers successfully joined. Waiting for code...\n", NUM_GROUP_TOXES);
|
|
printf("Tox 0 sending secret code to all peers\n");
|
|
|
|
|
|
for (size_t i = 0; i < NUM_GROUP_TOXES - 1; ++i) {
|
|
|
|
Tox_Err_Group_Send_Private_Message perr;
|
|
tox_group_send_private_message(autotoxes[0].tox, groupnumber, state0->peer_id[i],
|
|
TOX_MESSAGE_TYPE_NORMAL,
|
|
(const uint8_t *)CODEWORD, CODEWORD_LEN, &perr);
|
|
ck_assert_msg(perr == TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_OK, "%d", perr);
|
|
}
|
|
|
|
while (!all_peers_got_code(autotoxes))
|
|
;
|
|
|
|
Tox_Err_Group_Leave err_exit;
|
|
tox_group_leave(autotoxes[1].tox, groupnumber, nullptr, 0, &err_exit);
|
|
ck_assert(err_exit == TOX_ERR_GROUP_LEAVE_OK);
|
|
|
|
iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL);
|
|
|
|
state0->num_peers = 0;
|
|
state1->num_peers = 0;
|
|
|
|
// now do a friend invite to make sure the TCP-specific logic for friend invites is okay
|
|
|
|
printf("Tox1 leaves group and Tox0 does a friend group invite for tox1\n");
|
|
|
|
Tox_Err_Group_Invite_Friend err_invite;
|
|
tox_group_invite_friend(autotoxes[0].tox, groupnumber, 0, &err_invite);
|
|
ck_assert(err_invite == TOX_ERR_GROUP_INVITE_FRIEND_OK);
|
|
|
|
while (state0->num_peers == 0 && state1->num_peers == 0) {
|
|
iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL);
|
|
}
|
|
|
|
printf("Tox 1 successfully joined. Waiting for code...\n");
|
|
|
|
Tox_Err_Group_Send_Message merr;
|
|
tox_group_send_message(autotoxes[0].tox, groupnumber, TOX_MESSAGE_TYPE_NORMAL,
|
|
(const uint8_t *)CODEWORD, CODEWORD_LEN, &merr);
|
|
ck_assert(merr == TOX_ERR_GROUP_SEND_MESSAGE_OK);
|
|
|
|
while (!state1->got_second_code) {
|
|
iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL);
|
|
}
|
|
|
|
for (size_t i = 0; i < NUM_GROUP_TOXES; i++) {
|
|
tox_group_leave(autotoxes[i].tox, groupnumber, nullptr, 0, &err_exit);
|
|
ck_assert(err_exit == TOX_ERR_GROUP_LEAVE_OK);
|
|
}
|
|
|
|
printf("Test passed!\n");
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
setvbuf(stdout, nullptr, _IONBF, 0);
|
|
|
|
struct Tox_Options *options = tox_options_new(nullptr);
|
|
ck_assert(options != nullptr);
|
|
|
|
tox_options_set_udp_enabled(options, false);
|
|
|
|
Run_Auto_Options autotest_opts = default_run_auto_options();
|
|
autotest_opts.graph = GRAPH_COMPLETE;
|
|
|
|
// TODO(JFreegman): Fix this test and remove the "if".
|
|
if (argc > 2) {
|
|
run_auto_test(options, NUM_GROUP_TOXES, group_tcp_test, sizeof(State), &autotest_opts);
|
|
}
|
|
|
|
tox_options_free(options);
|
|
return 0;
|
|
}
|
|
|
|
#undef CODEWORD_LEN
|
|
#undef CODEWORD
|
|
#undef NUM_GROUP_TOXES
|