Coverage Report

Created: 2024-01-26 01:52

/work/auto_tests/conference_invite_merge_test.c
Line
Count
Source (jump to first uncovered line)
1
#include <stdbool.h>
2
#include <stdint.h>
3
#include <stdlib.h>
4
5
typedef struct State {
6
    bool connected;
7
    uint32_t conference;
8
} State;
9
10
943
#define NUM_INVITE_MERGE_TOX 5
11
12
#include "auto_test_support.h"
13
14
static void handle_conference_invite(
15
    Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data)
16
4
{
17
4
    const AutoTox *autotox = (AutoTox *)user_data;
18
4
    State *state = (State *)autotox->state;
19
20
4
    const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
21
4
    const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
22
4
    const size_t length = tox_event_conference_invite_get_cookie_length(event);
23
24
4
    if (friend_number != -1) {
25
4
        Tox_Err_Conference_Join err;
26
4
        state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
27
4
        ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
28
4
                      "attempting to join the conference returned with an error: %d", err);
29
4
        fprintf(stderr, "#%u accepted invite to conference %u\n", autotox->index, state->conference);
30
4
    }
31
4
}
32
33
static void handle_conference_connected(
34
    Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data)
35
4
{
36
4
    const AutoTox *autotox = (AutoTox *)user_data;
37
4
    State *state = (State *)autotox->state;
38
39
4
    fprintf(stderr, "#%u connected to conference %u\n", autotox->index, state->conference);
40
4
    state->connected = true;
41
4
}
42
43
static void wait_connected(AutoTox *autotoxes, const AutoTox *autotox, uint32_t friendnumber)
44
4
{
45
161
    do {
46
161
        iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL);
47
161
    } while (tox_friend_get_connection_status(autotox->tox, friendnumber, nullptr) == TOX_CONNECTION_NONE);
48
4
}
49
50
static void do_invite(AutoTox *autotoxes, AutoTox *inviter, AutoTox *invitee, uint32_t friendnum)
51
7
{
52
7
    fprintf(stderr, "#%u inviting #%u\n", inviter->index, invitee->index);
53
54
7
    Tox_Err_Conference_Invite err;
55
7
    tox_conference_invite(inviter->tox, friendnum, ((State *)inviter->state)->conference, &err);
56
7
    ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK,
57
7
                  "#%u attempting to invite #%u (friendnumber %u) returned with an error: %d", inviter->index, invitee->index,
58
7
                  friendnum, err);
59
60
11
    do {
61
11
        iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL);
62
11
    } while (!((State *)invitee->state)->connected);
63
7
}
64
65
static bool group_complete(AutoTox *autotoxes)
66
9
{
67
9
    int c = -1, size = 0;
68
69
34
    for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
70
30
        if (!autotoxes[i].alive) {
71
2
            continue;
72
2
        }
73
74
28
        const int ct = tox_conference_peer_count(autotoxes[i].tox, ((State *)autotoxes[i].state)->conference, nullptr);
75
76
28
        if (c == -1) {
77
9
            c = ct;
78
19
        } else if (c != ct) {
79
5
            return false;
80
5
        }
81
82
23
        ++size;
83
23
    }
84
85
4
    return (c == size);
86
9
}
87
88
static void wait_group_complete(AutoTox *autotoxes)
89
4
{
90
9
    do {
91
9
        iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL);
92
9
    } while (!group_complete(autotoxes));
93
4
}
94
95
static void conference_invite_merge_test(AutoTox *autotoxes)
96
1
{
97
    // Test that an explicit invite between peers in different connected
98
    // components will cause a split group to merge
99
100
6
    for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
101
5
        tox_events_callback_conference_invite(autotoxes[i].dispatch, handle_conference_invite);
102
5
        tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected);
103
5
    }
104
105
1
    State *state2 = (State *)autotoxes[2].state;
106
107
1
    {
108
        // Create new conference, tox 2 is the founder.
109
1
        Tox_Err_Conference_New err;
110
1
        state2->conference = tox_conference_new(autotoxes[2].tox, &err);
111
1
        state2->connected = true;
112
1
        ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK,
113
1
                      "attempting to create a new conference returned with an error: %d", err);
114
1
        fprintf(stderr, "Created conference: index=%u\n", state2->conference);
115
1
    }
116
117
0
    save_autotox(&autotoxes[2]);
118
119
1
    do_invite(autotoxes, &autotoxes[2], &autotoxes[1], 0);
120
1
    do_invite(autotoxes, &autotoxes[1], &autotoxes[0], 0);
121
122
1
    save_autotox(&autotoxes[1]);
123
1
    kill_autotox(&autotoxes[1]);
124
125
1
    do {
126
1
        iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL);
127
1
    } while (tox_conference_peer_count(autotoxes[2].tox, state2->conference, nullptr) != 1);
128
129
1
    do_invite(autotoxes, &autotoxes[2], &autotoxes[3], 1);
130
1
    do_invite(autotoxes, &autotoxes[3], &autotoxes[4], 1);
131
132
1
    kill_autotox(&autotoxes[2]);
133
134
1
    reload(&autotoxes[1]);
135
136
1
    uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
137
1
    tox_self_get_public_key(autotoxes[1].tox, public_key);
138
1
    tox_friend_add_norequest(autotoxes[3].tox, public_key, nullptr);
139
1
    tox_self_get_public_key(autotoxes[3].tox, public_key);
140
1
    tox_friend_add_norequest(autotoxes[1].tox, public_key, nullptr);
141
1
    wait_connected(autotoxes, &autotoxes[1], 2);
142
143
1
    do_invite(autotoxes, &autotoxes[1], &autotoxes[3], 2);
144
145
1
    fprintf(stderr, "Waiting for group to merge\n");
146
147
1
    wait_group_complete(autotoxes);
148
149
1
    fprintf(stderr, "Group merged\n");
150
151
1
    reload(&autotoxes[2]);
152
1
    wait_connected(autotoxes, &autotoxes[2], 0);
153
1
    do_invite(autotoxes, &autotoxes[2], &autotoxes[1], 0);
154
155
1
    fprintf(stderr, "Waiting for #2 to rejoin\n");
156
157
1
    wait_group_complete(autotoxes);
158
159
1
    kill_autotox(&autotoxes[2]);
160
1
    wait_group_complete(autotoxes);
161
1
    reload(&autotoxes[2]);
162
1
    wait_connected(autotoxes, &autotoxes[2], 0);
163
1
    wait_connected(autotoxes, &autotoxes[1], 1);
164
165
1
    do_invite(autotoxes, &autotoxes[1], &autotoxes[2], 1);
166
167
1
    fprintf(stderr, "Waiting for #2 to rejoin\n");
168
169
1
    wait_group_complete(autotoxes);
170
1
}
171
172
int main(void)
173
721
{
174
721
    setvbuf(stdout, nullptr, _IONBF, 0);
175
176
721
    Run_Auto_Options options = default_run_auto_options();
177
721
    options.graph = GRAPH_LINEAR;
178
179
721
    run_auto_test(nullptr, NUM_INVITE_MERGE_TOX, conference_invite_merge_test, sizeof(State), &options);
180
181
721
    return 0;
182
721
}