/work/auto_tests/reconnect_test.c
Line | Count | Source |
1 | | /* Auto Tests: Reconnection. |
2 | | * |
3 | | * This test checks that when a tox instance is suspended for long enough that |
4 | | * its friend connections time out, those connections are promptly |
5 | | * re-established when the instance is resumed. |
6 | | */ |
7 | | |
8 | | #include <stdlib.h> |
9 | | #include <string.h> |
10 | | #include <time.h> |
11 | | |
12 | | #include "../testing/misc_tools.h" |
13 | | #include "../toxcore/friend_connection.h" |
14 | | #include "../toxcore/tox.h" |
15 | | #include "../toxcore/util.h" |
16 | | #include "check_compat.h" |
17 | | |
18 | 1.51k | #define TOX_COUNT 2 |
19 | | #define RECONNECT_TIME_MAX (FRIEND_CONNECTION_TIMEOUT + 3) |
20 | | |
21 | | #include "auto_test_support.h" |
22 | | |
23 | | static uint32_t tox_connected_count(uint32_t tox_count, AutoTox *autotoxes, uint32_t index) |
24 | 29 | { |
25 | 29 | const size_t friend_count = tox_self_get_friend_list_size(autotoxes[index].tox); |
26 | 29 | uint32_t connected_count = 0; |
27 | | |
28 | 58 | for (size_t j = 0; j < friend_count; j++) { |
29 | 29 | if (tox_friend_get_connection_status(autotoxes[index].tox, j, nullptr) != TOX_CONNECTION_NONE) { |
30 | 28 | ++connected_count; |
31 | 28 | } |
32 | 29 | } |
33 | | |
34 | 29 | return connected_count; |
35 | 29 | } |
36 | | |
37 | | static bool all_disconnected_from(uint32_t tox_count, AutoTox *autotoxes, uint32_t index) |
38 | 29 | { |
39 | 31 | for (uint32_t i = 0; i < tox_count; i++) { |
40 | 30 | if (i == index) { |
41 | 1 | continue; |
42 | 1 | } |
43 | | |
44 | 29 | if (tox_connected_count(tox_count, autotoxes, i) >= tox_count - 1) { |
45 | 28 | return false; |
46 | 28 | } |
47 | 29 | } |
48 | | |
49 | 1 | return true; |
50 | 29 | } |
51 | | |
52 | | static void test_reconnect(AutoTox *autotoxes) |
53 | 1 | { |
54 | 1 | const Random *rng = os_random(); |
55 | 1 | ck_assert(rng != nullptr); |
56 | 1 | const time_t test_start_time = time(nullptr); |
57 | | |
58 | 1 | printf("letting connections settle\n"); |
59 | | |
60 | 338 | do { |
61 | 338 | iterate_all_wait(autotoxes, TOX_COUNT, ITERATION_INTERVAL); |
62 | 338 | } while (time(nullptr) - test_start_time < 2); |
63 | | |
64 | 1 | const uint16_t disconnect = random_u16(rng) % TOX_COUNT; |
65 | 1 | printf("disconnecting #%u\n", autotoxes[disconnect].index); |
66 | | |
67 | 29 | do { |
68 | 87 | for (uint16_t i = 0; i < TOX_COUNT; ++i) { |
69 | 58 | if (i != disconnect) { |
70 | 29 | Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK; |
71 | 29 | Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err); |
72 | 29 | ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK); |
73 | 29 | tox_dispatch_invoke(autotoxes[i].dispatch, events, autotoxes[i].tox, &autotoxes[i]); |
74 | 29 | tox_events_free(events); |
75 | | |
76 | 29 | autotoxes[i].clock += 1000; |
77 | 29 | } |
78 | 58 | } |
79 | | |
80 | 29 | c_sleep(20); |
81 | 29 | } while (!all_disconnected_from(TOX_COUNT, autotoxes, disconnect)); |
82 | | |
83 | 1 | const uint64_t reconnect_start_time = autotoxes[0].clock; |
84 | | |
85 | 1 | printf("reconnecting\n"); |
86 | | |
87 | 170 | do { |
88 | 170 | iterate_all_wait(autotoxes, TOX_COUNT, ITERATION_INTERVAL); |
89 | 170 | } while (!all_friends_connected(autotoxes, TOX_COUNT)); |
90 | | |
91 | 1 | const uint64_t reconnect_time = autotoxes[0].clock - reconnect_start_time; |
92 | 1 | ck_assert_msg(reconnect_time <= RECONNECT_TIME_MAX * 1000, "reconnection took %d seconds; expected at most %d seconds", |
93 | 1 | (int)(reconnect_time / 1000), RECONNECT_TIME_MAX); |
94 | | |
95 | 1 | printf("test_reconnect succeeded, took %d seconds\n", (int)(time(nullptr) - test_start_time)); |
96 | 1 | } |
97 | | |
98 | | int main(void) |
99 | 721 | { |
100 | 721 | setvbuf(stdout, nullptr, _IONBF, 0); |
101 | | |
102 | 721 | Run_Auto_Options options = default_run_auto_options(); |
103 | 721 | options.graph = GRAPH_LINEAR; |
104 | 721 | run_auto_test(nullptr, TOX_COUNT, test_reconnect, 0, &options); |
105 | | |
106 | 721 | return 0; |
107 | 721 | } |