Coverage Report

Created: 2024-01-26 01:52

/work/auto_tests/group_message_test.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Tests message sending capabilities, including:
3
 * - The ability to send/receive plain, action, and custom messages
4
 * - The lossless UDP implementation
5
 * - The packet splitting implementation
6
 * - The ignore feature
7
 */
8
9
#include <stdbool.h>
10
#include <stdint.h>
11
#include <string.h>
12
13
#include "auto_test_support.h"
14
#include "check_compat.h"
15
#include "../toxcore/util.h"
16
17
typedef struct State {
18
    uint32_t peer_id;
19
    bool peer_joined;
20
    bool message_sent;
21
    bool message_received;
22
    uint32_t pseudo_msg_id;
23
    bool private_message_received;
24
    size_t custom_packets_received;
25
    size_t custom_private_packets_received;
26
    bool lossless_check;
27
    bool wraparound_check;
28
    int32_t last_msg_recv;
29
} State;
30
31
1.66k
#define NUM_GROUP_TOXES 2
32
603
#define MAX_NUM_MESSAGES_LOSSLESS_TEST 300
33
18.0k
#define MAX_NUM_MESSAGES_WRAPAROUND_TEST 9001
34
35
2
#define TEST_MESSAGE "Where is it I've read that someone condemned to death says or thinks, an hour before his death, that if he had to live on some high rock, on such a narrow ledge that he'd only room to stand, and the ocean, everlasting darkness, everlasting solitude, everlasting tempest around him, if he had to remain standing on a square yard of space all his life, a thousand years, eternity, it were better to live so than to die at once. Only to live, to live and live! Life, whatever it may be!"
36
1
#define TEST_MESSAGE_LEN (sizeof(TEST_MESSAGE) - 1)
37
38
2
#define TEST_GROUP_NAME "Utah Data Center"
39
1
#define TEST_GROUP_NAME_LEN (sizeof(TEST_GROUP_NAME) - 1)
40
41
2
#define TEST_PRIVATE_MESSAGE "Don't spill yer beans"
42
1
#define TEST_PRIVATE_MESSAGE_LEN (sizeof(TEST_PRIVATE_MESSAGE) - 1)
43
44
4
#define TEST_CUSTOM_PACKET "Why'd ya spill yer beans?"
45
2
#define TEST_CUSTOM_PACKET_LEN (sizeof(TEST_CUSTOM_PACKET) - 1)
46
47
2
#define TEST_CUSTOM_PACKET_LARGE "Where is it I've read that someone condemned to death says or thinks, an hour before his death, that if he had to live on some high rock, on such a narrow ledge that he'd only room to stand, and the ocean, everlasting darkness, everlasting solitude, everlasting tempest around him, if he had to remain standing on a square yard of space all his life, a thousand years, eternity, it were better to live so than to die at once. Only to live, to live and live! Life, whatever it may be! ...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................0123456789"
48
1
#define TEST_CUSTOM_PACKET_LARGE_LEN (sizeof(TEST_CUSTOM_PACKET_LARGE) - 1)
49
static_assert(TEST_CUSTOM_PACKET_LARGE_LEN == TOX_GROUP_MAX_CUSTOM_LOSSY_PACKET_LENGTH, "Should be max");
50
51
4
#define TEST_CUSTOM_PRIVATE_PACKET "This is a custom private packet. Enjoy."
52
2
#define TEST_CUSTOM_PRIVATE_PACKET_LEN (sizeof(TEST_CUSTOM_PRIVATE_PACKET) - 1)
53
54
2
#define IGNORE_MESSAGE "Am I bothering you?"
55
1
#define IGNORE_MESSAGE_LEN (sizeof(IGNORE_MESSAGE) - 1)
56
57
190
#define PEER0_NICK "Thomas"
58
95
#define PEER0_NICK_LEN (sizeof(PEER0_NICK) - 1)
59
60
2
#define PEER1_NICK "Winslow"
61
1
#define PEER1_NICK_LEN (sizeof(PEER1_NICK) - 1)
62
63
static uint16_t get_message_checksum(const uint8_t *message, uint16_t length)
64
602
{
65
602
    uint16_t sum = 0;
66
67
394k
    for (size_t i = 0; i < length; ++i) {
68
394k
        sum += message[i];
69
394k
    }
70
71
602
    return sum;
72
602
}
73
74
static void group_invite_handler(Tox *tox, const Tox_Event_Group_Invite *event, void *user_data)
75
95
{
76
95
    const uint32_t friend_number = tox_event_group_invite_get_friend_number(event);
77
95
    const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event);
78
95
    const size_t length = tox_event_group_invite_get_invite_data_length(event);
79
80
95
    printf("invite arrived; accepting\n");
81
95
    Tox_Err_Group_Invite_Accept err_accept;
82
95
    tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)PEER0_NICK, PEER0_NICK_LEN,
83
95
                            nullptr, 0, &err_accept);
84
95
    ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK);
85
95
}
86
87
static void group_join_fail_handler(Tox *tox, const Tox_Event_Group_Join_Fail *event, void *user_data)
88
0
{
89
0
    const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event);
90
0
    printf("join failed: %d\n", fail_type);
91
0
}
92
93
static void group_peer_join_handler(Tox *tox, const Tox_Event_Group_Peer_Join *event, void *user_data)
94
22
{
95
22
    AutoTox *autotox = (AutoTox *)user_data;
96
22
    ck_assert(autotox != nullptr);
97
98
22
    State *state = (State *)autotox->state;
99
100
22
    const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
101
102
22
    ck_assert_msg(state->peer_joined == false, "Peer timedout");
103
104
22
    printf("peer %u joined, sending message\n", peer_id);
105
22
    state->peer_joined = true;
106
22
    state->peer_id = peer_id;
107
22
}
108
109
static void group_custom_private_packet_handler(Tox *tox, const Tox_Event_Group_Custom_Private_Packet *event, void *user_data)
110
2
{
111
2
    const uint32_t groupnumber = tox_event_group_custom_private_packet_get_group_number(event);
112
2
    const uint32_t peer_id = tox_event_group_custom_private_packet_get_peer_id(event);
113
2
    const uint8_t *data = tox_event_group_custom_private_packet_get_data(event);
114
2
    const size_t length = tox_event_group_custom_private_packet_get_data_length(event);
115
116
2
    ck_assert_msg(length == TEST_CUSTOM_PRIVATE_PACKET_LEN,
117
2
                  "Failed to receive custom private packet. Invalid length: %zu\n", length);
118
119
2
    char message_buf[TOX_MAX_CUSTOM_PACKET_SIZE + 1];
120
2
    memcpy(message_buf, data, length);
121
2
    message_buf[length] = 0;
122
123
2
    Tox_Err_Group_Peer_Query q_err;
124
2
    size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
125
126
2
    ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
127
2
    ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
128
129
2
    char peer_name[TOX_MAX_NAME_LENGTH + 1];
130
2
    tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
131
2
    peer_name[peer_name_len] = 0;
132
133
2
    ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
134
2
    ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
135
136
2
    Tox_Err_Group_Self_Query s_err;
137
2
    size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
138
2
    ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
139
2
    ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
140
141
2
    char self_name[TOX_MAX_NAME_LENGTH + 1];
142
2
    tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
143
2
    self_name[self_name_len] = 0;
144
145
2
    ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
146
2
    ck_assert(memcmp(self_name, PEER1_NICK, self_name_len) == 0);
147
148
2
    printf("%s sent custom private packet to %s: %s\n", peer_name, self_name, message_buf);
149
2
    ck_assert(memcmp(message_buf, TEST_CUSTOM_PRIVATE_PACKET, length) == 0);
150
151
2
    AutoTox *autotox = (AutoTox *)user_data;
152
2
    ck_assert(autotox != nullptr);
153
154
2
    State *state = (State *)autotox->state;
155
156
2
    ++state->custom_private_packets_received;
157
2
}
158
159
static void group_custom_packet_handler(Tox *tox, const Tox_Event_Group_Custom_Packet *event, void *user_data)
160
2
{
161
2
    const uint32_t groupnumber = tox_event_group_custom_packet_get_group_number(event);
162
2
    const uint32_t peer_id = tox_event_group_custom_packet_get_peer_id(event);
163
2
    const uint8_t *data = tox_event_group_custom_packet_get_data(event);
164
2
    const size_t length = tox_event_group_custom_packet_get_data_length(event);
165
166
2
    ck_assert_msg(length == TEST_CUSTOM_PACKET_LEN, "Failed to receive custom packet. Invalid length: %zu\n", length);
167
168
2
    char message_buf[TOX_MAX_CUSTOM_PACKET_SIZE + 1];
169
2
    memcpy(message_buf, data, length);
170
2
    message_buf[length] = 0;
171
172
2
    Tox_Err_Group_Peer_Query q_err;
173
2
    size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
174
175
2
    ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
176
2
    ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
177
178
2
    char peer_name[TOX_MAX_NAME_LENGTH + 1];
179
2
    tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
180
2
    peer_name[peer_name_len] = 0;
181
182
2
    ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
183
2
    ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
184
185
2
    Tox_Err_Group_Self_Query s_err;
186
2
    size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
187
2
    ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
188
2
    ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
189
190
2
    char self_name[TOX_MAX_NAME_LENGTH + 1];
191
2
    tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
192
2
    self_name[self_name_len] = 0;
193
194
2
    ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
195
2
    ck_assert(memcmp(self_name, PEER1_NICK, self_name_len) == 0);
196
197
2
    printf("%s sent custom packet to %s: %s\n", peer_name, self_name, message_buf);
198
2
    ck_assert(memcmp(message_buf, TEST_CUSTOM_PACKET, length) == 0);
199
200
2
    AutoTox *autotox = (AutoTox *)user_data;
201
2
    ck_assert(autotox != nullptr);
202
203
2
    State *state = (State *)autotox->state;
204
205
2
    ++state->custom_packets_received;
206
2
}
207
208
static void group_custom_packet_large_handler(Tox *tox, const Tox_Event_Group_Custom_Packet *event, void *user_data)
209
1
{
210
1
    const uint8_t *data = tox_event_group_custom_packet_get_data(event);
211
1
    const size_t length = tox_event_group_custom_packet_get_data_length(event);
212
213
1
    ck_assert_msg(length == TEST_CUSTOM_PACKET_LARGE_LEN, "Failed to receive large custom packet. Invalid length: %zu\n", length);
214
215
1
    ck_assert(memcmp(data, TEST_CUSTOM_PACKET_LARGE, length) == 0);
216
217
1
    AutoTox *autotox = (AutoTox *)user_data;
218
1
    ck_assert(autotox != nullptr);
219
220
1
    State *state = (State *)autotox->state;
221
222
1
    ++state->custom_packets_received;
223
1
}
224
225
static void group_message_handler(Tox *tox, const Tox_Event_Group_Message *event, void *user_data)
226
1
{
227
1
    const uint32_t groupnumber = tox_event_group_message_get_group_number(event);
228
1
    const uint32_t peer_id = tox_event_group_message_get_peer_id(event);
229
1
    const uint8_t *message = tox_event_group_message_get_message(event);
230
1
    const size_t length = tox_event_group_message_get_message_length(event);
231
1
    const uint32_t pseudo_msg_id = tox_event_group_message_get_message_id(event);
232
233
1
    ck_assert(!(length == IGNORE_MESSAGE_LEN && memcmp(message, IGNORE_MESSAGE, length) == 0));
234
1
    ck_assert_msg(length == TEST_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length);
235
236
1
    char message_buf[TOX_GROUP_MAX_MESSAGE_LENGTH + 1];
237
1
    memcpy(message_buf, message, length);
238
1
    message_buf[length] = 0;
239
240
1
    Tox_Err_Group_Peer_Query q_err;
241
1
    size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
242
243
1
    ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
244
1
    ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
245
246
1
    char peer_name[TOX_MAX_NAME_LENGTH + 1];
247
1
    tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
248
1
    peer_name[peer_name_len] = 0;
249
250
1
    ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
251
1
    ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
252
253
1
    Tox_Err_Group_Self_Query s_err;
254
1
    size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
255
1
    ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
256
1
    ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
257
258
1
    char self_name[TOX_MAX_NAME_LENGTH + 1];
259
1
    tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
260
1
    self_name[self_name_len] = 0;
261
262
1
    ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
263
1
    ck_assert(memcmp(self_name, PEER1_NICK, self_name_len) == 0);
264
265
1
    printf("%s sent message to %s:(id:%u) %s\n", peer_name, self_name, pseudo_msg_id, message_buf);
266
1
    ck_assert(memcmp(message_buf, TEST_MESSAGE, length) == 0);
267
268
1
    AutoTox *autotox = (AutoTox *)user_data;
269
1
    ck_assert(autotox != nullptr);
270
271
1
    State *state = (State *)autotox->state;
272
273
1
    state->message_received = true;
274
275
1
    state->pseudo_msg_id = pseudo_msg_id;
276
1
}
277
278
static void group_private_message_handler(Tox *tox, const Tox_Event_Group_Private_Message *event, void *user_data)
279
1
{
280
1
    const uint32_t groupnumber = tox_event_group_private_message_get_group_number(event);
281
1
    const uint32_t peer_id = tox_event_group_private_message_get_peer_id(event);
282
1
    const Tox_Message_Type type = tox_event_group_private_message_get_type(event);
283
1
    const uint8_t *message = tox_event_group_private_message_get_message(event);
284
1
    const size_t length = tox_event_group_private_message_get_message_length(event);
285
286
1
    ck_assert_msg(length == TEST_PRIVATE_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length);
287
288
1
    char message_buf[TOX_GROUP_MAX_MESSAGE_LENGTH + 1];
289
1
    memcpy(message_buf, message, length);
290
1
    message_buf[length] = 0;
291
292
1
    Tox_Err_Group_Peer_Query q_err;
293
1
    size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
294
295
1
    ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
296
1
    ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
297
298
1
    char peer_name[TOX_MAX_NAME_LENGTH + 1];
299
1
    tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
300
1
    peer_name[peer_name_len] = 0;
301
302
1
    ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
303
1
    ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
304
305
1
    Tox_Err_Group_Self_Query s_err;
306
1
    size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
307
1
    ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
308
1
    ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
309
310
1
    char self_name[TOX_MAX_NAME_LENGTH + 1];
311
1
    tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
312
1
    self_name[self_name_len] = 0;
313
314
1
    ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
315
1
    ck_assert(memcmp(self_name, PEER1_NICK, self_name_len) == 0);
316
317
1
    printf("%s sent private action to %s: %s\n", peer_name, self_name, message_buf);
318
1
    ck_assert(memcmp(message_buf, TEST_PRIVATE_MESSAGE, length) == 0);
319
320
1
    ck_assert(type == TOX_MESSAGE_TYPE_ACTION);
321
322
1
    AutoTox *autotox = (AutoTox *)user_data;
323
1
    ck_assert(autotox != nullptr);
324
325
1
    State *state = (State *)autotox->state;
326
327
1
    state->private_message_received = true;
328
1
}
329
330
static void group_message_handler_lossless_test(Tox *tox, const Tox_Event_Group_Message *event, void *user_data)
331
301
{
332
301
    const uint8_t *message = tox_event_group_message_get_message(event);
333
301
    const size_t length = tox_event_group_message_get_message_length(event);
334
335
301
    AutoTox *autotox = (AutoTox *)user_data;
336
301
    ck_assert(autotox != nullptr);
337
338
301
    State *state = (State *)autotox->state;
339
340
301
    ck_assert(length >= 4 && length <= TOX_GROUP_MAX_MESSAGE_LENGTH);
341
342
301
    uint16_t start;
343
301
    uint16_t checksum;
344
301
    memcpy(&start, message, sizeof(uint16_t));
345
301
    memcpy(&checksum, message + sizeof(uint16_t), sizeof(uint16_t));
346
347
301
    ck_assert_msg(start == state->last_msg_recv + 1, "Expected %d, got start %u", state->last_msg_recv + 1, start);
348
301
    ck_assert_msg(checksum == get_message_checksum(message + 4, length - 4), "Wrong checksum");
349
350
301
    state->last_msg_recv = start;
351
352
301
    if (state->last_msg_recv == MAX_NUM_MESSAGES_LOSSLESS_TEST) {
353
1
        state->lossless_check = true;
354
1
    }
355
301
}
356
static void group_message_handler_wraparound_test(Tox *tox, const Tox_Event_Group_Message *event, void *user_data)
357
9.00k
{
358
9.00k
    const uint8_t *message = tox_event_group_message_get_message(event);
359
9.00k
    const size_t length = tox_event_group_message_get_message_length(event);
360
361
9.00k
    AutoTox *autotox = (AutoTox *)user_data;
362
9.00k
    ck_assert(autotox != nullptr);
363
364
9.00k
    State *state = (State *)autotox->state;
365
366
9.00k
    ck_assert(length == 2);
367
368
9.00k
    uint16_t num;
369
9.00k
    memcpy(&num, message, sizeof(uint16_t));
370
371
9.00k
    ck_assert_msg(num == state->last_msg_recv + 1, "Expected %d, got start %u", state->last_msg_recv + 1, num);
372
373
9.00k
    state->last_msg_recv = num;
374
375
9.00k
    if (state->last_msg_recv == MAX_NUM_MESSAGES_WRAPAROUND_TEST) {
376
1
        state->wraparound_check = true;
377
1
    }
378
9.00k
}
379
380
static void group_message_test(AutoTox *autotoxes)
381
1
{
382
1
    ck_assert_msg(NUM_GROUP_TOXES >= 2, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
383
384
1
    const Random *rng = os_random();
385
1
    ck_assert(rng != nullptr);
386
387
1
    Tox *tox0 = autotoxes[0].tox;
388
1
    const Tox *tox1 = autotoxes[1].tox;
389
390
1
    State *state0 = (State *)autotoxes[0].state;
391
1
    State *state1 = (State *)autotoxes[1].state;
392
393
    // initialize to different values
394
1
    state0->pseudo_msg_id = 0;
395
1
    state1->pseudo_msg_id = 1;
396
397
1
    tox_events_callback_group_invite(autotoxes[1].dispatch, group_invite_handler);
398
1
    tox_events_callback_group_join_fail(autotoxes[1].dispatch, group_join_fail_handler);
399
1
    tox_events_callback_group_peer_join(autotoxes[1].dispatch, group_peer_join_handler);
400
1
    tox_events_callback_group_join_fail(autotoxes[0].dispatch, group_join_fail_handler);
401
1
    tox_events_callback_group_peer_join(autotoxes[0].dispatch, group_peer_join_handler);
402
1
    tox_events_callback_group_message(autotoxes[0].dispatch, group_message_handler);
403
1
    tox_events_callback_group_custom_packet(autotoxes[0].dispatch, group_custom_packet_handler);
404
1
    tox_events_callback_group_custom_private_packet(autotoxes[0].dispatch, group_custom_private_packet_handler);
405
1
    tox_events_callback_group_private_message(autotoxes[0].dispatch, group_private_message_handler);
406
407
1
    Tox_Err_Group_Send_Message err_send;
408
409
1
    fprintf(stderr, "Tox 0 creates new group and invites tox1...\n");
410
411
    // tox0 makes new group.
412
1
    Tox_Err_Group_New err_new;
413
1
    const uint32_t group_number = tox_group_new(tox0, TOX_GROUP_PRIVACY_STATE_PRIVATE, (const uint8_t *)TEST_GROUP_NAME,
414
1
                                  TEST_GROUP_NAME_LEN, (const uint8_t *)PEER1_NICK, PEER1_NICK_LEN, &err_new);
415
416
1
    ck_assert(err_new == TOX_ERR_GROUP_NEW_OK);
417
418
    // tox0 invites tox1
419
1
    Tox_Err_Group_Invite_Friend err_invite;
420
1
    tox_group_invite_friend(tox0, group_number, 0, &err_invite);
421
1
    ck_assert(err_invite == TOX_ERR_GROUP_INVITE_FRIEND_OK);
422
423
8
    while (!state0->message_received) {
424
7
        iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
425
426
7
        if (state1->peer_joined && !state1->message_sent) {
427
1
            state1->pseudo_msg_id = tox_group_send_message(
428
1
                    tox1, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)TEST_MESSAGE,
429
1
                    TEST_MESSAGE_LEN, &err_send);
430
1
            ck_assert(err_send == TOX_ERR_GROUP_SEND_MESSAGE_OK);
431
1
            state1->message_sent = true;
432
1
        }
433
7
    }
434
435
1
    ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u", state0->pseudo_msg_id, state1->pseudo_msg_id);
436
437
    // Make sure we're still connected to each friend
438
1
    Tox_Connection conn_1 = tox_friend_get_connection_status(tox0, 0, nullptr);
439
1
    Tox_Connection conn_2 = tox_friend_get_connection_status(tox1, 0, nullptr);
440
441
1
    ck_assert(conn_1 != TOX_CONNECTION_NONE && conn_2 != TOX_CONNECTION_NONE);
442
443
    // tox0 ignores tox1
444
1
    Tox_Err_Group_Set_Ignore ig_err;
445
1
    tox_group_set_ignore(tox0, group_number, state0->peer_id, true, &ig_err);
446
1
    ck_assert_msg(ig_err == TOX_ERR_GROUP_SET_IGNORE_OK, "%d", ig_err);
447
448
1
    iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
449
450
    // tox1 sends group a message which should not be seen by tox0's message handler
451
1
    tox_group_send_message(tox1, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)IGNORE_MESSAGE,
452
1
                           IGNORE_MESSAGE_LEN, &err_send);
453
454
1
    iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
455
456
    // tox0 unignores tox1
457
1
    tox_group_set_ignore(tox0, group_number, state0->peer_id, false, &ig_err);
458
1
    ck_assert_msg(ig_err == TOX_ERR_GROUP_SET_IGNORE_OK, "%d", ig_err);
459
460
1
    fprintf(stderr, "Sending private message...\n");
461
462
    // tox0 sends a private action to tox1
463
1
    Tox_Err_Group_Send_Private_Message m_err;
464
1
    tox_group_send_private_message(tox1, group_number, state1->peer_id, TOX_MESSAGE_TYPE_ACTION,
465
1
                                   (const uint8_t *)TEST_PRIVATE_MESSAGE, TEST_PRIVATE_MESSAGE_LEN, &m_err);
466
1
    ck_assert_msg(m_err == TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_OK, "%d", m_err);
467
468
1
    fprintf(stderr, "Sending custom packets...\n");
469
470
    // tox0 sends a lossless and lossy custom packet to tox1
471
1
    Tox_Err_Group_Send_Custom_Packet c_err;
472
1
    tox_group_send_custom_packet(tox1, group_number, true, (const uint8_t *)TEST_CUSTOM_PACKET, TEST_CUSTOM_PACKET_LEN,
473
1
                                 &c_err);
474
1
    ck_assert_msg(c_err == TOX_ERR_GROUP_SEND_CUSTOM_PACKET_OK, "%d", c_err);
475
476
1
    tox_group_send_custom_packet(tox1, group_number, false, (const uint8_t *)TEST_CUSTOM_PACKET, TEST_CUSTOM_PACKET_LEN,
477
1
                                 &c_err);
478
1
    ck_assert_msg(c_err == TOX_ERR_GROUP_SEND_CUSTOM_PACKET_OK, "%d", c_err);
479
480
1
    fprintf(stderr, "Sending custom private packets...\n");
481
482
    // tox0 sends a lossless and lossy custom private packet to tox1
483
1
    Tox_Err_Group_Send_Custom_Private_Packet cperr;
484
1
    tox_group_send_custom_private_packet(tox1, group_number, state1->peer_id, true,
485
1
                                         (const uint8_t *)TEST_CUSTOM_PRIVATE_PACKET,
486
1
                                         TEST_CUSTOM_PRIVATE_PACKET_LEN, &cperr);
487
488
1
    ck_assert_msg(cperr == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK, "%d", cperr);
489
490
1
    tox_group_send_custom_private_packet(tox1, group_number, state1->peer_id, false,
491
1
                                         (const uint8_t *)TEST_CUSTOM_PRIVATE_PACKET,
492
1
                                         TEST_CUSTOM_PRIVATE_PACKET_LEN, &cperr);
493
494
1
    ck_assert_msg(cperr == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK, "%d", cperr);
495
496
2
    while (!state0->private_message_received || state0->custom_packets_received < 2
497
2
            || state0->custom_private_packets_received < 2) {
498
1
        iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
499
1
    }
500
501
    // tox0 sends a large max sized lossy custom packet
502
503
    // overwrite callback for larger packet
504
1
    tox_events_callback_group_custom_packet(autotoxes[0].dispatch, group_custom_packet_large_handler);
505
506
1
    tox_group_send_custom_packet(tox1, group_number, false, (const uint8_t *)TEST_CUSTOM_PACKET_LARGE, TEST_CUSTOM_PACKET_LARGE_LEN,
507
1
                                 &c_err);
508
1
    ck_assert_msg(c_err == TOX_ERR_GROUP_SEND_CUSTOM_PACKET_OK, "%d", c_err);
509
510
2
    while (state0->custom_packets_received < 3) {
511
1
        iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
512
1
    }
513
514
1
    uint8_t m[TOX_GROUP_MAX_MESSAGE_LENGTH] = {0};
515
516
1
    fprintf(stderr, "Doing lossless packet test...\n");
517
518
1
    tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler_lossless_test);
519
1
    state1->last_msg_recv = -1;
520
521
    // lossless and packet splitting/reassembly test
522
302
    for (uint16_t i = 0; i <= MAX_NUM_MESSAGES_LOSSLESS_TEST; ++i) {
523
301
        if (i % 10 == 0) {
524
31
            iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
525
31
        }
526
527
301
        uint16_t message_size = min_u16(4 + (random_u16(rng) % TOX_GROUP_MAX_MESSAGE_LENGTH), TOX_GROUP_MAX_MESSAGE_LENGTH);
528
529
301
        memcpy(m, &i, sizeof(uint16_t));
530
531
197k
        for (size_t j = 4; j < message_size; ++j) {
532
197k
            m[j] = random_u32(rng);
533
197k
        }
534
535
301
        const uint16_t checksum = get_message_checksum(m + 4, message_size - 4);
536
537
301
        memcpy(m + 2, &checksum, sizeof(uint16_t));
538
539
301
        tox_group_send_message(tox0, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)m, message_size, &err_send);
540
541
301
        ck_assert(err_send == TOX_ERR_GROUP_SEND_MESSAGE_OK);
542
301
    }
543
544
2
    while (!state1->lossless_check) {
545
1
        iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
546
1
    }
547
548
1
    state1->last_msg_recv = -1;
549
1
    tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler_wraparound_test);
550
551
1
    fprintf(stderr, "Doing wraparound test...\n");
552
553
    // packet array wrap-around test
554
9.00k
    for (uint16_t i = 0; i <= MAX_NUM_MESSAGES_WRAPAROUND_TEST; ++i) {
555
9.00k
        if (i % 10 == 0) {
556
901
            iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
557
901
        }
558
559
9.00k
        memcpy(m, &i, sizeof(uint16_t));
560
561
9.00k
        tox_group_send_message(tox0, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)m, 2, &err_send);
562
9.00k
        ck_assert(err_send == TOX_ERR_GROUP_SEND_MESSAGE_OK);
563
9.00k
    }
564
565
2
    while (!state1->wraparound_check) {
566
1
        iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
567
1
    }
568
569
3
    for (size_t i = 0; i < NUM_GROUP_TOXES; i++) {
570
2
        Tox_Err_Group_Leave err_exit;
571
2
        tox_group_leave(autotoxes[i].tox, group_number, nullptr, 0, &err_exit);
572
2
        ck_assert(err_exit == TOX_ERR_GROUP_LEAVE_OK);
573
2
    }
574
575
1
    fprintf(stderr, "All tests passed!\n");
576
1
}
577
578
int main(void)
579
721
{
580
721
    setvbuf(stdout, nullptr, _IONBF, 0);
581
582
721
    Run_Auto_Options autotest_opts = default_run_auto_options();
583
721
    autotest_opts.graph = GRAPH_COMPLETE;
584
585
721
    run_auto_test(nullptr, NUM_GROUP_TOXES, group_message_test, sizeof(State), &autotest_opts);
586
721
    return 0;
587
721
}
588
589
#undef NUM_GROUP_TOXES
590
#undef PEER1_NICK
591
#undef PEER1_NICK_LEN
592
#undef PEER0_NICK
593
#undef PEER0_NICK_LEN
594
#undef TEST_GROUP_NAME
595
#undef TEST_GROUP_NAME_LEN
596
#undef TEST_MESSAGE
597
#undef TEST_MESSAGE_LEN
598
#undef TEST_PRIVATE_MESSAGE_LEN
599
#undef TEST_CUSTOM_PACKET
600
#undef TEST_CUSTOM_PACKET_LEN
601
#undef TEST_CUSTOM_PACKET_LARGE
602
#undef TEST_CUSTOM_PACKET_LARGE_LEN
603
#undef TEST_CUSTOM_PRIVATE_PACKET
604
#undef TEST_CUSTOM_PRIVATE_PACKET_LEN
605
#undef IGNORE_MESSAGE
606
#undef IGNORE_MESSAGE_LEN
607
#undef MAX_NUM_MESSAGES_LOSSLESS_TEST
608
#undef MAX_NUM_MESSAGES_WRAPAROUND_TEST