Coverage Report

Created: 2026-10-24 08:16

/work/auto_tests/scenarios/scenario_conference_test.c
Line
Count
Source (jump to first uncovered line)
1
#include "framework/framework.h"
2
#include <stdio.h>
3
#include <string.h>
4
#include <stdlib.h>
5
6
65
#define NUM_PEERS 16
7
38
#define GROUP_MESSAGE "Install Gentoo"
8
9
typedef struct {
10
    bool joined;
11
    bool connected;
12
    uint32_t conference;
13
    uint32_t peer_count;
14
    uint32_t messages_received;
15
} PeerState;
16
17
static void on_conference_invite(const Tox_Event_Conference_Invite *event, void *user_data)
18
19
{
19
19
    ToxNode *self = (ToxNode *)user_data;
20
19
    PeerState *state = (PeerState *)tox_node_get_script_ctx(self);
21
22
19
    state->conference = tox_conference_join(tox_node_get_tox(self),
23
19
                                            tox_event_conference_invite_get_friend_number(event),
24
19
                                            tox_event_conference_invite_get_cookie(event),
25
19
                                            tox_event_conference_invite_get_cookie_length(event),
26
19
                                            nullptr);
27
19
    tox_node_log(self, "Joined conference %u", state->conference);
28
19
    state->joined = true;
29
19
}
30
31
static void on_conference_connected(const Tox_Event_Conference_Connected *event, void *user_data)
32
20
{
33
20
    ToxNode *self = (ToxNode *)user_data;
34
20
    PeerState *state = (PeerState *)tox_node_get_script_ctx(self);
35
20
    state->connected = true;
36
20
    tox_node_log(self, "Connected to conference %u", tox_event_conference_connected_get_conference_number(event));
37
20
}
38
39
static void on_peer_list_changed(const Tox_Event_Conference_Peer_List_Changed *event, void *user_data)
40
255
{
41
255
    ToxNode *self = (ToxNode *)user_data;
42
255
    PeerState *state = (PeerState *)tox_node_get_script_ctx(self);
43
255
    state->peer_count = tox_conference_peer_count(tox_node_get_tox(self), tox_event_conference_peer_list_changed_get_conference_number(event), nullptr);
44
255
    tox_node_log(self, "Peer count changed: %u", state->peer_count);
45
255
}
46
47
static void on_conference_message(const Tox_Event_Conference_Message *event, void *user_data)
48
18
{
49
18
    ToxNode *self = (ToxNode *)user_data;
50
18
    PeerState *state = (PeerState *)tox_node_get_script_ctx(self);
51
18
    const uint8_t *msg = tox_event_conference_message_get_message(event);
52
18
    if (memcmp(msg, GROUP_MESSAGE, sizeof(GROUP_MESSAGE) - 1) == 0) {
53
18
        state->messages_received++;
54
18
        tox_node_log(self, "Received message %u", state->messages_received);
55
18
    }
56
18
}
57
58
static void peer_script(ToxNode *self, void *ctx)
59
16
{
60
16
    Tox *tox = tox_node_get_tox(self);
61
16
    PeerState *state = (PeerState *)ctx;
62
16
    uint32_t my_index = tox_node_get_index(self);
63
64
16
    tox_events_callback_conference_invite(tox_node_get_dispatch(self), on_conference_invite);
65
16
    tox_events_callback_conference_connected(tox_node_get_dispatch(self), on_conference_connected);
66
16
    tox_events_callback_conference_peer_list_changed(tox_node_get_dispatch(self), on_peer_list_changed);
67
16
    tox_events_callback_conference_message(tox_node_get_dispatch(self), on_conference_message);
68
69
16
    WAIT_UNTIL(tox_node_is_self_connected(self));
70
16
    tox_node_log(self, "Self connected");
71
72
    // Founder (Node 0) creates group
73
16
    if (my_index == 0) {
74
1
        state->conference = tox_conference_new(tox, nullptr);
75
1
        tox_node_log(self, "Created conference %u", state->conference);
76
1
        state->joined = true;
77
1
        state->connected = true;
78
79
        // Invite friend 0 (Node 1)
80
1
        WAIT_UNTIL(tox_node_is_friend_connected(self, 0));
81
1
        tox_node_log(self, "Friend 0 (Node 1) connected, inviting...");
82
1
        tox_conference_invite(tox, 0, state->conference, nullptr);
83
15
    } else {
84
15
        WAIT_UNTIL(state->joined);
85
15
        WAIT_UNTIL(state->connected);
86
87
        // Invite next friends if any
88
        // In linear topology, each node has 2 friends (except ends)
89
        // We invite friend 1 (the next node in line)
90
15
        if (my_index < NUM_PEERS - 1) {
91
14
            WAIT_UNTIL(tox_node_is_friend_connected(self, 1));
92
14
            tox_node_log(self, "Friend 1 (Node %u) connected, inviting...", my_index + 1);
93
14
            Tox_Err_Conference_Invite err;
94
14
            if (!tox_conference_invite(tox, 1, state->conference, &err)) {
95
0
                tox_node_log(self, "Failed to invite Node %u: %u", my_index + 1, err);
96
0
            }
97
14
        }
98
15
    }
99
100
    // Wait for all to join
101
16
    WAIT_UNTIL(state->peer_count == NUM_PEERS);
102
16
    tox_node_log(self, "All peers joined");
103
104
    // One peer sends a message
105
16
    if (my_index == 0) {
106
1
        tox_node_log(self, "Sending message");
107
1
        tox_conference_send_message(tox, state->conference, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)GROUP_MESSAGE, sizeof(GROUP_MESSAGE) - 1, nullptr);
108
1
    }
109
110
    // Wait for message propagation
111
16
    WAIT_UNTIL(state->messages_received > 0);
112
16
    tox_node_log(self, "Done");
113
16
}
114
115
int main(int argc, char *argv[])
116
1
{
117
1
    ToxScenario *s = tox_scenario_new(argc, argv, 300000);
118
1
    PeerState states[NUM_PEERS] = {0};
119
120
1
    ToxNode *nodes[NUM_PEERS];
121
17
    for (int i = 0; i < NUM_PEERS; ++i) {
122
16
        char alias[16];
123
16
        snprintf(alias, sizeof(alias), "Peer%d", i);
124
16
        nodes[i] = tox_scenario_add_node(s, alias, peer_script, &states[i], sizeof(PeerState));
125
16
    }
126
127
    // Linear topology
128
17
    for (int i = 0; i < NUM_PEERS; ++i) {
129
16
        if (i > 0) {
130
15
            tox_node_friend_add(nodes[i], nodes[i - 1]);
131
15
            tox_node_bootstrap(nodes[i], nodes[i - 1]);
132
15
        }
133
16
        if (i < NUM_PEERS - 1) {
134
15
            tox_node_friend_add(nodes[i], nodes[i + 1]);
135
15
        }
136
16
    }
137
138
1
    ToxScenarioStatus res = tox_scenario_run(s);
139
1
    if (res != TOX_SCENARIO_DONE) {
140
0
        tox_scenario_log(s, "Test failed with status %u", res);
141
0
        return 1;
142
0
    }
143
144
1
    tox_scenario_free(s);
145
1
    return 0;
146
1
}
147
148
#undef NUM_PEERS