Coverage Report

Created: 2025-10-08 19:34

/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
}