Coverage Report

Created: 2024-01-26 01:52

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