Coverage Report

Created: 2025-10-08 19:34

/work/auto_tests/tox_many_tcp_test.c
Line
Count
Source (jump to first uncovered line)
1
/* Auto Tests: Many TCP.
2
 */
3
4
#include <stdio.h>
5
#include <string.h>
6
#include <time.h>
7
8
#include "../testing/misc_tools.h"
9
#include "../toxcore/crypto_core.h"
10
#include "../toxcore/os_random.h"
11
#include "../toxcore/tox.h"
12
#include "auto_test_support.h"
13
#include "check_compat.h"
14
15
#ifndef USE_IPV6
16
#define USE_IPV6 1
17
#endif
18
19
#ifdef TOX_LOCALHOST
20
#undef TOX_LOCALHOST
21
#endif
22
#if USE_IPV6
23
#define TOX_LOCALHOST "::1"
24
#else
25
#define TOX_LOCALHOST "127.0.0.1"
26
#endif
27
28
typedef struct State {
29
    uint32_t to_comp;
30
    Tox *tox;
31
} State;
32
33
static bool enable_broken_tests = false;
34
35
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata)
36
50
{
37
50
    State *state = (State *)userdata;
38
39
50
    const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
40
50
    const uint8_t *message = tox_event_friend_request_get_message(event);
41
50
    const uint32_t message_length = tox_event_friend_request_get_message_length(event);
42
43
50
    if (state->to_comp != 974536) {
44
0
        return;
45
0
    }
46
47
50
    if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) {
48
50
        tox_friend_add_norequest(state->tox, public_key, nullptr);
49
50
    }
50
50
}
51
52
200
#define NUM_FRIENDS 50
53
12.4k
#define NUM_TOXES_TCP 40
54
55
static uint16_t tcp_relay_port = 33448;
56
57
static void test_many_clients_tcp(void)
58
1
{
59
1
    const Random *rng = os_random();
60
1
    ck_assert(rng != nullptr);
61
1
    long long unsigned int cur_time = time(nullptr);
62
1
    Tox *toxes[NUM_TOXES_TCP];
63
1
    uint32_t index[NUM_TOXES_TCP];
64
1
    uint32_t to_comp = 974536;
65
66
41
    for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
67
40
        struct Tox_Options *opts = tox_options_new(nullptr);
68
69
40
        if (i == 0) {
70
1
            tox_options_set_tcp_port(opts, tcp_relay_port);
71
39
        } else {
72
39
            tox_options_set_udp_enabled(opts, false);
73
39
        }
74
75
40
        index[i] = i + 1;
76
40
        Tox_Err_New err;
77
40
        toxes[i] = tox_new_log(opts, &err, &index[i]);
78
40
        if (i == 0 && err == TOX_ERR_NEW_PORT_ALLOC) {
79
0
            ck_assert(toxes[i] == nullptr);
80
0
            --i;
81
0
            ++tcp_relay_port;
82
0
            tox_options_free(opts);
83
0
            continue;
84
0
        }
85
40
        ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i);
86
40
        tox_events_init(toxes[i]);
87
40
        uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
88
40
        tox_self_get_dht_id(toxes[0], dpk);
89
40
        Tox_Err_Bootstrap error;
90
40
        ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port, dpk, &error), "add relay error, %u, %u", i,
91
40
                      error);
92
40
        uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr);
93
40
        ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, first_port, dpk, nullptr), "Bootstrap error");
94
95
40
        tox_options_free(opts);
96
40
    }
97
98
1
    Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
99
1
    ck_assert(dispatch != nullptr);
100
101
1
    tox_events_callback_friend_request(dispatch, accept_friend_request);
102
103
1
    struct {
104
1
        uint16_t tox1;
105
1
        uint16_t tox2;
106
1
    } pairs[NUM_FRIENDS];
107
108
1
    uint8_t address[TOX_ADDRESS_SIZE];
109
110
51
    for (uint32_t i = 0; i < NUM_FRIENDS; ++i) {
111
50
loop_top:
112
50
        pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP;
113
50
        pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
114
115
1.27k
        for (uint32_t j = 0; j < i; ++j) {
116
1.22k
            if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) {
117
0
                goto loop_top;
118
0
            }
119
1.22k
        }
120
121
50
        tox_self_get_address(toxes[pairs[i].tox1], address);
122
123
50
        Tox_Err_Friend_Add test;
124
50
        uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (const uint8_t *)"Gentoo", 7, &test);
125
126
50
        if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) {
127
0
            goto loop_top;
128
0
        }
129
130
50
        ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %u", test);
131
50
    }
132
133
149
    while (true) {
134
149
        uint16_t counter = 0;
135
136
6.10k
        for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
137
14.3k
            for (uint32_t j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) {
138
8.41k
                if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) {
139
297
                    ++counter;
140
297
                }
141
8.41k
            }
142
5.96k
        }
143
144
149
        if (counter == NUM_FRIENDS * 2) {
145
1
            break;
146
1
        }
147
148
6.06k
        for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
149
5.92k
            Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
150
5.92k
            Tox_Events *events = tox_events_iterate(toxes[i], true, &err);
151
5.92k
            ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
152
5.92k
            State state = {to_comp, toxes[i]};
153
5.92k
            tox_dispatch_invoke(dispatch, events, &state);
154
5.92k
            tox_events_free(events);
155
5.92k
        }
156
157
148
        c_sleep(50);
158
148
    }
159
160
1
    tox_dispatch_free(dispatch);
161
41
    for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
162
40
        tox_kill(toxes[i]);
163
40
    }
164
165
1
    printf("test_many_clients_tcp succeeded, took %llu seconds\n", time(nullptr) - cur_time);
166
1
}
167
168
0
#define NUM_TCP_RELAYS 3
169
170
static void test_many_clients_tcp_b(void)
171
0
{
172
0
    const Random *rng = os_random();
173
0
    ck_assert(rng != nullptr);
174
0
    long long unsigned int cur_time = time(nullptr);
175
0
    Tox *toxes[NUM_TOXES_TCP];
176
0
    uint32_t index[NUM_TOXES_TCP];
177
0
    uint32_t to_comp = 974536;
178
179
0
    for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
180
0
        struct Tox_Options *opts = tox_options_new(nullptr);
181
182
0
        if (i < NUM_TCP_RELAYS) {
183
0
            tox_options_set_tcp_port(opts, tcp_relay_port + i);
184
0
        } else {
185
0
            tox_options_set_udp_enabled(opts, 0);
186
0
        }
187
188
0
        index[i] = i + 1;
189
0
        toxes[i] = tox_new_log(opts, nullptr, &index[i]);
190
0
        ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i);
191
0
        tox_events_init(toxes[i]);
192
0
        uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
193
0
        tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk);
194
0
        ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port + (i % NUM_TCP_RELAYS), dpk, nullptr),
195
0
                      "add relay error");
196
0
        tox_self_get_dht_id(toxes[0], dpk);
197
0
        uint16_t first_port = tox_self_get_udp_port(toxes[0], nullptr);
198
0
        ck_assert_msg(tox_bootstrap(toxes[i], TOX_LOCALHOST, first_port, dpk, nullptr), "Bootstrap error");
199
200
0
        tox_options_free(opts);
201
0
    }
202
203
0
    Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
204
0
    ck_assert(dispatch != nullptr);
205
206
0
    tox_events_callback_friend_request(dispatch, accept_friend_request);
207
208
0
    struct {
209
0
        uint16_t tox1;
210
0
        uint16_t tox2;
211
0
    } pairs[NUM_FRIENDS];
212
213
0
    uint8_t address[TOX_ADDRESS_SIZE];
214
215
0
    for (uint32_t i = 0; i < NUM_FRIENDS; ++i) {
216
0
loop_top:
217
0
        pairs[i].tox1 = random_u32(rng) % NUM_TOXES_TCP;
218
0
        pairs[i].tox2 = (pairs[i].tox1 + random_u32(rng) % (NUM_TOXES_TCP - 1) + 1) % NUM_TOXES_TCP;
219
220
0
        for (uint32_t j = 0; j < i; ++j) {
221
0
            if (pairs[j].tox2 == pairs[i].tox1 && pairs[j].tox1 == pairs[i].tox2) {
222
0
                goto loop_top;
223
0
            }
224
0
        }
225
226
0
        tox_self_get_address(toxes[pairs[i].tox1], address);
227
228
0
        Tox_Err_Friend_Add test;
229
0
        uint32_t num = tox_friend_add(toxes[pairs[i].tox2], address, (const uint8_t *)"Gentoo", 7, &test);
230
231
0
        if (test == TOX_ERR_FRIEND_ADD_ALREADY_SENT) {
232
0
            goto loop_top;
233
0
        }
234
235
0
        ck_assert_msg(num != UINT32_MAX && test == TOX_ERR_FRIEND_ADD_OK, "Failed to add friend error code: %u", test);
236
0
    }
237
238
0
    uint16_t last_count = 0;
239
240
0
    while (true) {
241
0
        uint16_t counter = 0;
242
243
0
        for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
244
0
            for (uint32_t j = 0; j < tox_self_get_friend_list_size(toxes[i]); ++j) {
245
0
                if (tox_friend_get_connection_status(toxes[i], j, nullptr) == TOX_CONNECTION_TCP) {
246
0
                    ++counter;
247
0
                }
248
0
            }
249
0
        }
250
251
0
        if (counter != last_count) {
252
0
            printf("many_clients_tcp_b got to %u\n", counter);
253
0
            last_count = counter;
254
0
        }
255
256
0
        if (counter == NUM_FRIENDS * 2) {
257
0
            break;
258
0
        }
259
260
0
        for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
261
0
            Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
262
0
            Tox_Events *events = tox_events_iterate(toxes[i], true, &err);
263
0
            ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
264
0
            State state = {to_comp, toxes[i]};
265
0
            tox_dispatch_invoke(dispatch, events, &state);
266
0
            tox_events_free(events);
267
0
        }
268
269
0
        c_sleep(30);
270
0
    }
271
272
0
    tox_dispatch_free(dispatch);
273
0
    for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
274
0
        tox_kill(toxes[i]);
275
0
    }
276
277
0
    printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(nullptr) - cur_time);
278
0
}
279
280
static void tox_suite(void)
281
1
{
282
    /* Each tox connects to a single tox TCP    */
283
1
    test_many_clients_tcp();
284
285
1
    if (enable_broken_tests) {
286
        /* Try to make a connection to each "older sibling" tox instance via TCP */
287
        /* Currently this test intermittently fails for unknown reasons. */
288
0
        test_many_clients_tcp_b();
289
0
    }
290
1
}
291
292
int main(void)
293
545
{
294
545
    setvbuf(stdout, nullptr, _IONBF, 0);
295
545
    tox_suite();
296
545
    return 0;
297
545
}