diff --git a/auto_tests/conference_test.c b/auto_tests/conference_test.c index 1826324e..2fbb9c98 100644 --- a/auto_tests/conference_test.c +++ b/auto_tests/conference_test.c @@ -20,59 +20,61 @@ #include "helpers.h" -#define NUM_GROUP_TOX 32 +#define NUM_GROUP_TOX 8 -static void g_accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, - void *userdata) +static void handle_self_connection_status(Tox *tox, TOX_CONNECTION connection_status, void *user_data) { - if (*((uint32_t *)userdata) != 234212) { - return; - } + int id = *(int *)user_data; - if (length == 7 && memcmp("Gentoo", data, 7) == 0) { - tox_friend_add_norequest(m, public_key, nullptr); + if (connection_status != TOX_CONNECTION_NONE) { + printf("tox #%d: is now connected\n", id); + } else { + printf("tox #%d: is now disconnected\n", id); } } -static Tox *invite_tox; -static unsigned int invite_counter; - -static void print_group_invite_callback(Tox *tox, uint32_t friendnumber, TOX_CONFERENCE_TYPE type, const uint8_t *data, - size_t length, - void *userdata) +static void handle_friend_connection_status(Tox *tox, uint32_t friendnumber, TOX_CONNECTION connection_status, + void *user_data) { - if (*((uint32_t *)userdata) != 234212) { - return; + int id = *(int *)user_data; + + if (connection_status != TOX_CONNECTION_NONE) { + printf("tox #%d: is now connected to friend %d\n", id, friendnumber); + } else { + printf("tox #%d: is now disconnected from friend %d\n", id, friendnumber); } +} - if (type != TOX_CONFERENCE_TYPE_TEXT) { - return; +static void handle_conference_invite(Tox *tox, uint32_t friendnumber, TOX_CONFERENCE_TYPE type, const uint8_t *data, + size_t length, void *user_data) +{ + int id = *(int *)user_data; + ck_assert_msg(type == TOX_CONFERENCE_TYPE_TEXT, "tox #%d: wrong conference type: %d", id, 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 #%d: error joining group: %d", id, err); + ck_assert_msg(g_num == 0, "tox #%d: group number was not 0", id); + + // 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 #%d: joining groupchat twice should be impossible.", id); + + if (tox_self_get_friend_list_size(tox) > 1) { + printf("tox #%d: inviting next friend\n", id); + ck_assert_msg(tox_conference_invite(tox, 1, g_num, nullptr) != 0, "Failed to invite friend"); + } else { + printf("tox #%d was the last tox, no further invites happening\n", id); } - - uint32_t g_num; - - if ((g_num = tox_conference_join(tox, friendnumber, data, length, nullptr)) == UINT32_MAX) { - return; - } - - ck_assert_msg(g_num == 0, "Group number was not 0"); - ck_assert_msg(tox_conference_join(tox, friendnumber, data, length, nullptr) == -1, - "Joining groupchat twice should be impossible."); - - invite_tox = tox; - invite_counter = 4; } static unsigned int num_recv; -static void print_group_message(Tox *tox, uint32_t groupnumber, uint32_t peernumber, TOX_MESSAGE_TYPE type, - const uint8_t *message, size_t length, - void *userdata) +static void handle_conference_message(Tox *tox, uint32_t groupnumber, uint32_t peernumber, TOX_MESSAGE_TYPE type, + const uint8_t *message, size_t length, void *user_data) { - if (*((uint32_t *)userdata) != 234212) { - return; - } - if (length == (sizeof("Install Gentoo") - 1) && memcmp(message, "Install Gentoo", sizeof("Install Gentoo") - 1) == 0) { ++num_recv; } @@ -80,28 +82,26 @@ static void print_group_message(Tox *tox, uint32_t groupnumber, uint32_t peernum START_TEST(test_many_group) { - long long unsigned int test_start_time = time(nullptr); - -group_test_restart: - ; + const time_t test_start_time = time(nullptr); Tox *toxes[NUM_GROUP_TOX]; uint32_t tox_index[NUM_GROUP_TOX]; - unsigned int i, j, k; - uint32_t to_comp = 234212; - int test_run = 0; - long long unsigned int cur_time = time(nullptr); + time_t cur_time = time(nullptr); struct Tox_Options *opts = tox_options_new(nullptr); - /* FIXME: Currently here is problems with IPv6 */ - tox_options_set_ipv6_enabled(opts, false); + tox_options_set_start_port(opts, 33445); + tox_options_set_end_port(opts, 34445); - for (i = 0; i < NUM_GROUP_TOX; ++i) { + printf("creating %d toxes\n", NUM_GROUP_TOX); + + for (unsigned i = 0; i < NUM_GROUP_TOX; ++i) { + TOX_ERR_NEW err; tox_index[i] = i + 1; - toxes[i] = tox_new_log(opts, nullptr, &tox_index[i]); + toxes[i] = tox_new_log(opts, &err, &tox_index[i]); - ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i); - tox_callback_friend_request(toxes[i], &g_accept_friend_request); - tox_callback_conference_invite(toxes[i], &print_group_invite_callback); + ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instance %u: error %d", i, err); + 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_options_free(opts); @@ -114,88 +114,80 @@ group_test_restart: ck_assert_msg(error == TOX_ERR_GET_PORT_OK, "wrong error"); } - uint8_t address[TOX_ADDRESS_SIZE]; - tox_self_get_address(toxes[NUM_GROUP_TOX - 1], address); + printf("creating a chain of friends\n"); - for (i = 0; i < NUM_GROUP_TOX; ++i) { - ck_assert_msg(tox_friend_add(toxes[i], address, (const uint8_t *)"Gentoo", 7, nullptr) == 0, "Failed to add friend"); + for (unsigned i = 1; i < NUM_GROUP_TOX; ++i) { + TOX_ERR_FRIEND_ADD err; + uint8_t key[TOX_PUBLIC_KEY_SIZE]; - tox_self_get_address(toxes[i], address); + tox_self_get_public_key(toxes[i - 1], key); + tox_friend_add_norequest(toxes[i], key, &err); + ck_assert_msg(err == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend: error %d", err); + + tox_self_get_public_key(toxes[i], key); + tox_friend_add_norequest(toxes[i - 1], key, &err); + ck_assert_msg(err == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend: error %d", err); } - while (1) { - for (i = 0; i < NUM_GROUP_TOX; ++i) { - if (tox_friend_get_connection_status(toxes[i], 0, nullptr) != TOX_CONNECTION_UDP) { - break; - } + printf("waiting for everyone to come online\n"); + unsigned online_count = 0; + + while (online_count != NUM_GROUP_TOX) { + online_count = 0; + + for (unsigned i = 0; i < NUM_GROUP_TOX; ++i) { + tox_iterate(toxes[i], &tox_index[i]); + online_count += tox_friend_get_connection_status(toxes[i], 0, nullptr) != TOX_CONNECTION_NONE; } - if (i == NUM_GROUP_TOX) { - break; - } + printf("currently %d toxes are online\n", online_count); + fflush(stdout); - for (i = 0; i < NUM_GROUP_TOX; ++i) { - tox_iterate(toxes[i], &to_comp); - } - - c_sleep(25); + c_sleep(1000); } - printf("friends connected, took %llu seconds\n", time(nullptr) - cur_time); + printf("friends connected, took %d seconds\n", (int)(time(nullptr) - cur_time)); ck_assert_msg(tox_conference_new(toxes[0], nullptr) != UINT32_MAX, "Failed to create group"); + printf("tox #%d: inviting its first friend\n", tox_index[0]); ck_assert_msg(tox_conference_invite(toxes[0], 0, 0, nullptr) != 0, "Failed to invite friend"); ck_assert_msg(tox_conference_set_title(toxes[0], 0, (const uint8_t *)"Gentoo", sizeof("Gentoo") - 1, nullptr) != 0, "Failed to set group title"); - invite_counter = ~0; - unsigned int done = ~0; - done -= 5; - - while (1) { - for (i = 0; i < NUM_GROUP_TOX; ++i) { - tox_iterate(toxes[i], &to_comp); - } - - if (!invite_counter) { - ck_assert_msg(tox_conference_invite(invite_tox, 0, 0, nullptr) != 0, "Failed to invite friend"); - } - - if (done == invite_counter) { - break; - } - - --invite_counter; - c_sleep(50); + // One iteration for all the invitations to happen. + for (unsigned i = 0; i < NUM_GROUP_TOX; ++i) { + tox_iterate(toxes[i], &tox_index[i]); } - for (i = 0; i < NUM_GROUP_TOX; ++i) { - uint32_t peer_count = tox_conference_peer_count(toxes[i], 0, nullptr); + cur_time = time(nullptr); + printf("waiting for all toxes to be in the group\n"); + unsigned invited_count = 0; - /** - * Group chats fail unpredictably, currently they'll rerun as many times - * as they need to until they pass the test, or the time out is reached - * Either way in this case it's fine */ - if (peer_count != NUM_GROUP_TOX) { - ++test_run; - printf("\tError starting up the first group (peer_count %" PRIu32 " != %d, test_run = %d)\n", peer_count, NUM_GROUP_TOX, - test_run); + while (invited_count != NUM_GROUP_TOX) { + invited_count = 0; + printf("current peer counts: ["); - for (j = 0; j < NUM_GROUP_TOX; ++j) { - tox_kill(toxes[j]); + for (unsigned i = 0; i < NUM_GROUP_TOX; ++i) { + tox_iterate(toxes[i], &tox_index[i]); + uint32_t peer_count = tox_conference_peer_count(toxes[i], 0, nullptr); + invited_count += peer_count == NUM_GROUP_TOX; + + if (i != 0) { + printf(", "); } - c_sleep(1000); - - goto group_test_restart; + printf("%d", peer_count); } - /** - * This check will never fail because it'll jump before this event - * I've decided to leave it in because eventually, we may want to only - * restart this test once, in which case this check will become - * important again. - */ + printf("]\n"); + fflush(stdout); + + c_sleep(1000); + } + + for (unsigned i = 0; i < NUM_GROUP_TOX; ++i) { + uint32_t peer_count = tox_conference_peer_count(toxes[i], 0, nullptr); + ck_assert_msg(peer_count == NUM_GROUP_TOX, "\n\tBad number of group peers (pre check)." "\n\t\t\tExpected: %u but tox_instance(%u) only has: %" PRIu32 "\n\n", NUM_GROUP_TOX, i, peer_count); @@ -207,10 +199,10 @@ group_test_restart: ck_assert_msg(memcmp("Gentoo", title, ret) == 0, "Wrong title"); } - printf("group connected\n"); + printf("group connected, took %d seconds\n", (int)(time(nullptr) - cur_time)); - for (i = 0; i < NUM_GROUP_TOX; ++i) { - tox_callback_conference_message(toxes[i], &print_group_message); + for (unsigned i = 0; i < NUM_GROUP_TOX; ++i) { + tox_callback_conference_message(toxes[i], &handle_conference_message); } TOX_ERR_CONFERENCE_SEND_MESSAGE err; @@ -222,9 +214,9 @@ group_test_restart: err == TOX_ERR_CONFERENCE_SEND_MESSAGE_OK, "Failed to send group message."); num_recv = 0; - for (j = 0; j < 20; ++j) { - for (i = 0; i < NUM_GROUP_TOX; ++i) { - tox_iterate(toxes[i], &to_comp); + for (unsigned j = 0; j < 20; ++j) { + for (unsigned i = 0; i < NUM_GROUP_TOX; ++i) { + tox_iterate(toxes[i], &tox_index[i]); } c_sleep(25); @@ -233,18 +225,18 @@ group_test_restart: c_sleep(25); ck_assert_msg(num_recv == NUM_GROUP_TOX, "Failed to recv group messages."); - for (k = NUM_GROUP_TOX; k != 0 ; --k) { + for (unsigned k = NUM_GROUP_TOX; k != 0 ; --k) { tox_conference_delete(toxes[k - 1], 0, nullptr); - for (j = 0; j < 10; ++j) { - for (i = 0; i < NUM_GROUP_TOX; ++i) { - tox_iterate(toxes[i], &to_comp); + for (unsigned j = 0; j < 10; ++j) { + for (unsigned i = 0; i < NUM_GROUP_TOX; ++i) { + tox_iterate(toxes[i], &tox_index[i]); } c_sleep(50); } - for (i = 0; i < (k - 1); ++i) { + for (unsigned i = 0; i < (k - 1); ++i) { uint32_t peer_count = tox_conference_peer_count(toxes[i], 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: %" PRIu32 "\n\n", @@ -252,11 +244,11 @@ group_test_restart: } } - for (i = 0; i < NUM_GROUP_TOX; ++i) { + for (unsigned i = 0; i < NUM_GROUP_TOX; ++i) { tox_kill(toxes[i]); } - printf("test_many_group succeeded, took %llu seconds\n", time(nullptr) - test_start_time); + printf("test_many_group succeeded, took %d seconds\n", (int)(time(nullptr) - test_start_time)); } END_TEST @@ -264,13 +256,7 @@ static Suite *tox_suite(void) { Suite *s = suite_create("Tox conference"); - /* This test works VERY unreliably. So it's worthless in its current state. - * Anyone reading this is welcome to try to fix it, but because there is a - * new version of group chats for Tox already completed, and nearly ready to - * merge, No one is willing/available to give this test the time in needs */ -#ifndef DISABLE_GROUP_TESTS DEFTESTCASE_SLOW(many_group, 80); -#endif return s; }