Coverage Report

Created: 2025-10-08 19:34

/work/auto_tests/tox_dispatch_test.c
Line
Count
Source (jump to first uncovered line)
1
/* Auto Tests: Many clients.
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/tox.h"
11
#include "../toxcore/tox_dispatch.h"
12
#include "../toxcore/tox_events.h"
13
#include "../toxcore/tox_private.h"
14
#include "../toxcore/tox_unpack.h"
15
#include "auto_test_support.h"
16
#include "check_compat.h"
17
18
// Set to true to produce an msgpack file at /tmp/test.mp.
19
static const bool want_dump_events = false;
20
21
static void handle_events_friend_message(const Tox_Event_Friend_Message *event, void *user_data)
22
1
{
23
1
    bool *success = (bool *)user_data;
24
25
1
    ck_assert(tox_event_friend_message_get_message_length(event) == sizeof("hello"));
26
1
    const uint8_t *msg = tox_event_friend_message_get_message(event);
27
1
    ck_assert_msg(memcmp(msg, "hello", sizeof("hello")) == 0,
28
1
                  "message was not expected 'hello' but '%s'", (const char *)msg);
29
30
1
    *success = true;
31
1
}
32
33
static void dump_events(const char *path, const Tox_Events *events)
34
0
{
35
0
    FILE *fh = fopen(path, "w");
36
0
    ck_assert(fh != nullptr);
37
0
    const uint32_t len = tox_events_bytes_size(events);
38
0
    uint8_t *buf = (uint8_t *)malloc(len);
39
0
    ck_assert(buf != nullptr);
40
0
    ck_assert(tox_events_get_bytes(events, buf));
41
0
    fwrite(buf, 1, len, fh);
42
0
    free(buf);
43
0
    fclose(fh);
44
0
}
45
46
static void print_events(const Tox_System *sys, Tox_Events *events)
47
402
{
48
402
    const uint32_t size = tox_events_bytes_size(events);
49
50
402
    uint8_t *bytes1 = (uint8_t *)malloc(size);
51
402
    uint8_t *bytes2 = (uint8_t *)malloc(size);
52
402
    ck_assert(bytes1 != nullptr);
53
402
    ck_assert(bytes2 != nullptr);
54
55
402
    ck_assert(tox_events_get_bytes(events, bytes1));
56
402
    ck_assert(tox_events_get_bytes(events, bytes2));
57
58
    // Make sure get_bytes is deterministic.
59
402
    ck_assert(memcmp(bytes1, bytes2, size) == 0);
60
61
402
    Tox_Events *events_copy = tox_events_load(sys, bytes1, size);
62
402
    ck_assert(events_copy != nullptr);
63
402
    free(bytes1);
64
402
    free(bytes2);
65
66
402
    ck_assert(tox_events_equal(sys, events, events_copy));
67
68
402
    tox_events_free(events_copy);
69
402
    tox_events_free(events);
70
402
}
71
72
static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch)
73
1
{
74
1
    const Tox_System *sys = tox_get_system(toxes[0]);
75
76
1
    for (uint32_t i = 0; i < 100; ++i) {
77
        // Ignore events on tox 1.
78
1
        print_events(sys, tox_events_iterate(toxes[0], false, nullptr));
79
        // Check if tox 2 got the message from tox 1.
80
1
        Tox_Events *events = tox_events_iterate(toxes[1], false, nullptr);
81
82
1
        if (want_dump_events) {
83
0
            dump_events("/tmp/test.mp", events);
84
0
        }
85
86
1
        bool success = false;
87
1
        tox_dispatch_invoke(dispatch, events, &success);
88
1
        print_events(sys, events);
89
90
1
        if (success) {
91
1
            return true;
92
1
        }
93
94
0
        c_sleep(tox_iteration_interval(toxes[0]));
95
0
    }
96
97
0
    return false;
98
1
}
99
100
static void test_tox_events(void)
101
1
{
102
1
    uint8_t message[sizeof("hello")];
103
1
    memcpy(message, "hello", sizeof(message));
104
105
1
    Tox *toxes[2];
106
1
    uint32_t index[2];
107
108
3
    for (uint32_t i = 0; i < 2; ++i) {
109
2
        index[i] = i + 1;
110
2
        toxes[i] = tox_new_log(nullptr, nullptr, &index[i]);
111
2
        tox_events_init(toxes[i]);
112
2
        ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i);
113
2
    }
114
115
1
    const Tox_System *sys = tox_get_system(toxes[0]);
116
117
1
    Tox_Err_Dispatch_New err_new;
118
1
    Tox_Dispatch *dispatch = tox_dispatch_new(&err_new);
119
1
    ck_assert_msg(dispatch != nullptr, "failed to create event dispatcher");
120
1
    ck_assert(err_new == TOX_ERR_DISPATCH_NEW_OK);
121
122
1
    tox_events_callback_friend_message(dispatch, handle_events_friend_message);
123
124
1
    uint8_t pk[TOX_PUBLIC_KEY_SIZE];
125
1
    tox_self_get_dht_id(toxes[0], pk);
126
1
    tox_bootstrap(toxes[1], "localhost", tox_self_get_udp_port(toxes[0], nullptr), pk, nullptr);
127
128
1
    tox_self_get_public_key(toxes[0], pk);
129
1
    tox_friend_add_norequest(toxes[1], pk, nullptr);
130
131
1
    tox_self_get_public_key(toxes[1], pk);
132
1
    tox_friend_add_norequest(toxes[0], pk, nullptr);
133
134
1
    printf("bootstrapping and connecting 2 toxes\n");
135
136
159
    while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE ||
137
159
            tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) {
138
        // Ignore connection events for now.
139
158
        print_events(sys, tox_events_iterate(toxes[0], false, nullptr));
140
158
        print_events(sys, tox_events_iterate(toxes[1], false, nullptr));
141
142
158
        c_sleep(tox_iteration_interval(toxes[0]));
143
158
    }
144
145
1
    printf("toxes online, waiting for friend connection\n");
146
147
43
    while (tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_NONE ||
148
43
            tox_friend_get_connection_status(toxes[1], 0, nullptr) == TOX_CONNECTION_NONE) {
149
        // Ignore connection events for now.
150
42
        print_events(sys, tox_events_iterate(toxes[0], false, nullptr));
151
42
        print_events(sys, tox_events_iterate(toxes[1], false, nullptr));
152
153
42
        c_sleep(tox_iteration_interval(toxes[0]));
154
42
    }
155
156
1
    printf("friends are connected via %s, now sending message\n",
157
1
           tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_TCP ? "TCP" : "UDP");
158
159
1
    Tox_Err_Friend_Send_Message err;
160
1
    tox_friend_send_message(toxes[0], 0, TOX_MESSAGE_TYPE_NORMAL, message, sizeof(message), &err);
161
1
    ck_assert(err == TOX_ERR_FRIEND_SEND_MESSAGE_OK);
162
163
1
    ck_assert(await_message(toxes, dispatch));
164
165
1
    tox_dispatch_free(dispatch);
166
167
3
    for (uint32_t i = 0; i < 2; ++i) {
168
2
        tox_kill(toxes[i]);
169
2
    }
170
1
}
171
172
int main(void)
173
545
{
174
545
    setvbuf(stdout, nullptr, _IONBF, 0);
175
545
    test_tox_events();
176
545
    return 0;
177
545
}