Coverage Report

Created: 2026-10-24 08:16

/work/auto_tests/scenarios/scenario_group_state_test.c
Line
Count
Source (jump to first uncovered line)
1
#include "framework/framework.h"
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
6
1.14k
#define NUM_PEERS 5
7
2
#define GROUP_NAME "The Crystal Palace"
8
1
#define GROUP_NAME_LEN (sizeof(GROUP_NAME) - 1)
9
10
#define PASSWORD "dadada"
10
5
#define PASS_LEN (sizeof(PASSWORD) - 1)
11
1
#define PEER_LIMIT_1 NUM_PEERS
12
1
#define PEER_LIMIT_2 50
13
14
typedef struct {
15
    uint32_t group_number;
16
    uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
17
    uint32_t peer_count;
18
    Tox_Group_Privacy_State privacy_state;
19
    Tox_Group_Voice_State voice_state;
20
    Tox_Group_Topic_Lock topic_lock;
21
    uint32_t peer_limit;
22
    uint8_t password[TOX_GROUP_MAX_PASSWORD_SIZE];
23
    size_t password_len;
24
} GroupState;
25
26
static void on_group_peer_join(const Tox_Event_Group_Peer_Join *event, void *user_data)
27
25
{
28
25
    ToxNode *self = (ToxNode *)user_data;
29
25
    GroupState *state = (GroupState *)tox_node_get_script_ctx(self);
30
25
    state->peer_count++;
31
25
}
32
33
static void on_group_privacy_state(const Tox_Event_Group_Privacy_State *event, void *user_data)
34
4
{
35
4
    ToxNode *self = (ToxNode *)user_data;
36
4
    GroupState *state = (GroupState *)tox_node_get_script_ctx(self);
37
4
    state->privacy_state = tox_event_group_privacy_state_get_privacy_state(event);
38
4
}
39
40
static void on_group_voice_state(const Tox_Event_Group_Voice_State *event, void *user_data)
41
16
{
42
16
    ToxNode *self = (ToxNode *)user_data;
43
16
    GroupState *state = (GroupState *)tox_node_get_script_ctx(self);
44
16
    state->voice_state = tox_event_group_voice_state_get_voice_state(event);
45
16
}
46
47
static void on_group_topic_lock(const Tox_Event_Group_Topic_Lock *event, void *user_data)
48
8
{
49
8
    ToxNode *self = (ToxNode *)user_data;
50
8
    GroupState *state = (GroupState *)tox_node_get_script_ctx(self);
51
8
    state->topic_lock = tox_event_group_topic_lock_get_topic_lock(event);
52
8
}
53
54
static void on_group_peer_limit(const Tox_Event_Group_Peer_Limit *event, void *user_data)
55
8
{
56
8
    ToxNode *self = (ToxNode *)user_data;
57
8
    GroupState *state = (GroupState *)tox_node_get_script_ctx(self);
58
8
    state->peer_limit = tox_event_group_peer_limit_get_peer_limit(event);
59
8
}
60
61
static void on_group_password(const Tox_Event_Group_Password *event, void *user_data)
62
4
{
63
4
    ToxNode *self = (ToxNode *)user_data;
64
4
    GroupState *state = (GroupState *)tox_node_get_script_ctx(self);
65
4
    state->password_len = tox_event_group_password_get_password_length(event);
66
4
    if (state->password_len > 0) {
67
0
        memcpy(state->password, tox_event_group_password_get_password(event), state->password_len);
68
0
    }
69
4
}
70
71
static void founder_script(ToxNode *self, void *ctx)
72
1
{
73
1
    GroupState *state = (GroupState *)ctx;
74
1
    Tox *tox = tox_node_get_tox(self);
75
1
    Tox_Dispatch *dispatch = tox_node_get_dispatch(self);
76
77
1
    tox_events_callback_group_peer_join(dispatch, on_group_peer_join);
78
79
1
    tox_node_wait_for_self_connected(self);
80
81
1
    Tox_Err_Group_New err_new;
82
1
    state->group_number = tox_group_new(tox, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)GROUP_NAME, GROUP_NAME_LEN,
83
1
                                        (const uint8_t *)"Founder", 7, &err_new);
84
1
    ck_assert(err_new == TOX_ERR_GROUP_NEW_OK);
85
1
    tox_group_get_chat_id(tox, state->group_number, state->chat_id, nullptr);
86
87
1
    tox_group_set_peer_limit(tox, state->group_number, PEER_LIMIT_1, nullptr);
88
1
    tox_group_set_privacy_state(tox, state->group_number, TOX_GROUP_PRIVACY_STATE_PUBLIC, nullptr);
89
1
    tox_group_set_password(tox, state->group_number, (const uint8_t *)PASSWORD, PASS_LEN, nullptr);
90
1
    tox_group_set_topic_lock(tox, state->group_number, TOX_GROUP_TOPIC_LOCK_ENABLED, nullptr);
91
1
    tox_group_set_voice_state(tox, state->group_number, TOX_GROUP_VOICE_STATE_ALL, nullptr);
92
93
1
    tox_scenario_barrier_wait(self); // Barrier 1: Founder set initial state
94
95
1
    WAIT_UNTIL(state->peer_count == NUM_PEERS - 1);
96
1
    tox_node_log(self, "All peers joined.");
97
98
1
    tox_scenario_barrier_wait(self); // Barrier 2: All peers joined
99
100
1
    tox_node_log(self, "Changing group state...");
101
1
    tox_group_set_peer_limit(tox, state->group_number, PEER_LIMIT_2, nullptr);
102
1
    tox_group_set_privacy_state(tox, state->group_number, TOX_GROUP_PRIVACY_STATE_PRIVATE, nullptr);
103
1
    tox_group_set_password(tox, state->group_number, nullptr, 0, nullptr);
104
1
    tox_group_set_topic_lock(tox, state->group_number, TOX_GROUP_TOPIC_LOCK_DISABLED, nullptr);
105
1
    tox_group_set_voice_state(tox, state->group_number, TOX_GROUP_VOICE_STATE_MODERATOR, nullptr);
106
107
1
    tox_scenario_barrier_wait(self); // Barrier 3: State changed
108
109
1
    tox_scenario_barrier_wait(self); // Barrier 4: All peers verified state
110
1
}
111
112
static void peer_script(ToxNode *self, void *ctx)
113
4
{
114
4
    const GroupState *state = (const GroupState *)ctx;
115
4
    Tox *tox = tox_node_get_tox(self);
116
4
    Tox_Dispatch *dispatch = tox_node_get_dispatch(self);
117
118
4
    tox_events_callback_group_peer_join(dispatch, on_group_peer_join);
119
4
    tox_events_callback_group_privacy_state(dispatch, on_group_privacy_state);
120
4
    tox_events_callback_group_voice_state(dispatch, on_group_voice_state);
121
4
    tox_events_callback_group_topic_lock(dispatch, on_group_topic_lock);
122
4
    tox_events_callback_group_peer_limit(dispatch, on_group_peer_limit);
123
4
    tox_events_callback_group_password(dispatch, on_group_password);
124
125
4
    tox_node_wait_for_self_connected(self);
126
127
4
    const ToxNode *founder = tox_scenario_get_node(tox_node_get_scenario(self), 0);
128
4
    const GroupState *founder_view = (const GroupState *)tox_node_get_peer_ctx(founder);
129
130
4
    tox_scenario_barrier_wait(self); // Barrier 1: Founder set initial state
131
132
4
    Tox_Err_Group_Join join_err;
133
4
    tox_group_join(tox, founder_view->chat_id, (const uint8_t *)"Peer", 4, (const uint8_t *)PASSWORD, PASS_LEN, &join_err);
134
4
    if (join_err != TOX_ERR_GROUP_JOIN_OK) {
135
0
        tox_node_log(self, "tox_group_join failed with error: %s", tox_err_group_join_to_string(join_err));
136
0
    }
137
4
    ck_assert(join_err == TOX_ERR_GROUP_JOIN_OK);
138
139
4
    WAIT_UNTIL(tox_group_is_connected(tox, 0, nullptr));
140
141
4
    tox_scenario_barrier_wait(self); // Barrier 2: All peers joined
142
143
4
    tox_scenario_barrier_wait(self); // Barrier 3: State changed
144
145
4
    WAIT_UNTIL(state->privacy_state == TOX_GROUP_PRIVACY_STATE_PRIVATE);
146
4
    WAIT_UNTIL(state->voice_state == TOX_GROUP_VOICE_STATE_MODERATOR);
147
4
    WAIT_UNTIL(state->topic_lock == TOX_GROUP_TOPIC_LOCK_DISABLED);
148
4
    WAIT_UNTIL(state->peer_limit == PEER_LIMIT_2);
149
4
    WAIT_UNTIL(state->password_len == 0);
150
151
4
    tox_node_log(self, "State verified.");
152
153
4
    tox_scenario_barrier_wait(self); // Barrier 4: All peers verified state
154
4
}
155
156
int main(int argc, char *argv[])
157
2
{
158
2
    ToxScenario *s = tox_scenario_new(argc, argv, 60000);
159
2
    GroupState states[NUM_PEERS] = {{0}};
160
161
2
    ToxNode *nodes[NUM_PEERS];
162
2
    nodes[0] = tox_scenario_add_node(s, "Founder", founder_script, &states[0], sizeof(GroupState));
163
134
    for (int i = 1; i < NUM_PEERS; ++i) {
164
132
        char alias[16];
165
132
        snprintf(alias, sizeof(alias), "Peer%d", i);
166
132
        nodes[i] = tox_scenario_add_node(s, alias, peer_script, &states[i], sizeof(GroupState));
167
132
    }
168
169
1.01k
    for (int i = 1; i < NUM_PEERS; ++i) {
170
1.01k
        tox_node_bootstrap(nodes[i], nodes[0]);
171
1.01k
    }
172
173
2
    ToxScenarioStatus res = tox_scenario_run(s);
174
2
    if (res != TOX_SCENARIO_DONE) {
175
0
        return 1;
176
0
    }
177
178
2
    tox_scenario_free(s);
179
2
    return 0;
180
2
}
181
182
#undef PASSWORD
183
#undef PASS_LEN
184
#undef GROUP_NAME
185
#undef GROUP_NAME_LEN
186
#undef NUM_PEERS