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