summaryrefslogtreecommitdiff
path: root/auto_tests
diff options
context:
space:
mode:
Diffstat (limited to 'auto_tests')
-rw-r--r--auto_tests/Makefile.inc5
-rw-r--r--auto_tests/conference_double_invite_test.c4
-rw-r--r--auto_tests/conference_invite_merge_test.c244
3 files changed, 252 insertions, 1 deletions
diff --git a/auto_tests/Makefile.inc b/auto_tests/Makefile.inc
index fcaeff5b..983c83d3 100644
--- a/auto_tests/Makefile.inc
+++ b/auto_tests/Makefile.inc
@@ -3,6 +3,7 @@ if BUILD_TESTS
3TESTS = \ 3TESTS = \
4 bootstrap_test \ 4 bootstrap_test \
5 conference_double_invite_test \ 5 conference_double_invite_test \
6 conference_invite_merge_test \
6 conference_peer_nick_test \ 7 conference_peer_nick_test \
7 conference_simple_test \ 8 conference_simple_test \
8 conference_test \ 9 conference_test \
@@ -73,6 +74,10 @@ conference_double_invite_test_SOURCES = ../auto_tests/conference_double_invite_t
73conference_double_invite_test_CFLAGS = $(AUTOTEST_CFLAGS) 74conference_double_invite_test_CFLAGS = $(AUTOTEST_CFLAGS)
74conference_double_invite_test_LDADD = $(AUTOTEST_LDADD) 75conference_double_invite_test_LDADD = $(AUTOTEST_LDADD)
75 76
77conference_invite_merge_test_SOURCES = ../auto_tests/conference_invite_merge_test.c
78conference_invite_merge_test_CFLAGS = $(AUTOTEST_CFLAGS)
79conference_invite_merge_test_LDADD = $(AUTOTEST_LDADD)
80
76conference_peer_nick_test_SOURCES = ../auto_tests/conference_peer_nick_test.c 81conference_peer_nick_test_SOURCES = ../auto_tests/conference_peer_nick_test.c
77conference_peer_nick_test_CFLAGS = $(AUTOTEST_CFLAGS) 82conference_peer_nick_test_CFLAGS = $(AUTOTEST_CFLAGS)
78conference_peer_nick_test_LDADD = $(AUTOTEST_LDADD) 83conference_peer_nick_test_LDADD = $(AUTOTEST_LDADD)
diff --git a/auto_tests/conference_double_invite_test.c b/auto_tests/conference_double_invite_test.c
index 17124f1c..c9e64e5b 100644
--- a/auto_tests/conference_double_invite_test.c
+++ b/auto_tests/conference_double_invite_test.c
@@ -28,6 +28,8 @@ static void handle_conference_invite(
28 state->index, friend_number, type, (unsigned)length); 28 state->index, friend_number, type, (unsigned)length);
29 fprintf(stderr, "tox%u joining conference\n", state->index); 29 fprintf(stderr, "tox%u joining conference\n", state->index);
30 30
31 ck_assert_msg(!state->joined, "invitation callback generated for already joined conference");
32
31 if (friend_number != -1) { 33 if (friend_number != -1) {
32 Tox_Err_Conference_Join err; 34 Tox_Err_Conference_Join err;
33 state->conference = tox_conference_join(tox, friend_number, cookie, length, &err); 35 state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
@@ -71,7 +73,7 @@ static void conference_double_invite_test(Tox **toxes, State *state)
71 73
72 fprintf(stderr, "Invitations accepted\n"); 74 fprintf(stderr, "Invitations accepted\n");
73 75
74 // Invite one more time, resulting in friend -1 inviting tox1 (toxes[1]). 76 fprintf(stderr, "Sending second invitation; should be ignored\n");
75 tox_conference_invite(toxes[0], 0, state[0].conference, nullptr); 77 tox_conference_invite(toxes[0], 0, state[0].conference, nullptr);
76 78
77 iterate_all_wait(2, toxes, state, ITERATION_INTERVAL); 79 iterate_all_wait(2, toxes, state, ITERATION_INTERVAL);
diff --git a/auto_tests/conference_invite_merge_test.c b/auto_tests/conference_invite_merge_test.c
new file mode 100644
index 00000000..e7ec499c
--- /dev/null
+++ b/auto_tests/conference_invite_merge_test.c
@@ -0,0 +1,244 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <stdbool.h>
6#include <stdint.h>
7#include <stdlib.h>
8
9typedef struct State {
10 uint32_t index;
11 uint64_t clock;
12
13 size_t save_size;
14 uint8_t *save_state;
15 bool alive;
16
17 bool connected;
18 uint32_t conference;
19} State;
20
21#define NUM_INVITE_MERGE_TOX 5
22
23#include "run_auto_test.h"
24
25static void handle_conference_invite(
26 Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
27 const uint8_t *cookie, size_t length, void *user_data)
28{
29 State *state = (State *)user_data;
30
31 if (friend_number != -1) {
32 Tox_Err_Conference_Join err;
33 state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
34 ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
35 "attempting to join the conference returned with an error: %d", err);
36 fprintf(stderr, "#%u accepted invite to conference %u\n", state->index, state->conference);
37 }
38}
39
40static void handle_conference_connected(
41 Tox *tox, uint32_t conference_number, void *user_data)
42{
43 State *state = (State *)user_data;
44 fprintf(stderr, "#%u connected to conference %u\n", state->index, state->conference);
45 state->connected = true;
46}
47
48static void iterate_alive(Tox **toxes, State *state)
49{
50 for (uint32_t i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
51 if (!state[i].alive) {
52 continue;
53 }
54
55 tox_iterate(toxes[i], &state[i]);
56 state[i].clock += ITERATION_INTERVAL;
57 }
58
59 c_sleep(20);
60}
61
62static void save(Tox **toxes, State *state, uint32_t n)
63{
64 fprintf(stderr, "Saving #%u\n", state[n].index);
65
66 if (state[n].save_state != nullptr) {
67 free(state[n].save_state);
68 }
69
70 state[n].save_size = tox_get_savedata_size(toxes[n]);
71 state[n].save_state = (uint8_t *)malloc(state[n].save_size);
72 ck_assert_msg(state[n].save_state != nullptr, "malloc failed");
73 tox_get_savedata(toxes[n], state[n].save_state);
74}
75
76static void kill(Tox **toxes, State *state, uint32_t n)
77{
78 fprintf(stderr, "Killing #%u\n", state[n].index);
79 state[n].alive = false;
80 tox_kill(toxes[n]);
81}
82
83static void reload(Tox **toxes, State *state, uint32_t n)
84{
85 if (state[n].alive) {
86 state[n].alive = false;
87 tox_kill(toxes[n]);
88 }
89
90 fprintf(stderr, "Reloading #%u\n", state[n].index);
91 ck_assert(state[n].save_state != nullptr);
92
93 struct Tox_Options *const options = tox_options_new(nullptr);
94 tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
95 tox_options_set_savedata_data(options, state[n].save_state, state[n].save_size);
96 toxes[n] = tox_new_log(options, nullptr, &state[n].index);
97 tox_options_free(options);
98
99 set_mono_time_callback(toxes[n], &state[n]);
100 state[n].alive = true;
101}
102
103static void wait_connected(Tox **toxes, State *state, uint32_t n, uint32_t friendnumber)
104{
105 do {
106 iterate_alive(toxes, state);
107 } while (tox_friend_get_connection_status(toxes[n], friendnumber, nullptr) == TOX_CONNECTION_NONE);
108}
109
110static void do_invite(Tox **toxes, State *state, uint32_t inviter, uint32_t invitee, uint32_t friendnum)
111{
112 fprintf(stderr, "#%u inviting #%u\n", state[inviter].index, state[invitee].index);
113
114 Tox_Err_Conference_Invite err;
115 tox_conference_invite(toxes[inviter], friendnum, state[inviter].conference, &err);
116 ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK,
117 "#%u attempting to invite #%u (friendnumber %u) returned with an error: %d", state[inviter].index, state[invitee].index,
118 friendnum, err);
119
120 do {
121 iterate_alive(toxes, state);
122 } while (!state[invitee].connected);
123}
124
125static bool group_complete(Tox **toxes, State *state)
126{
127 int c = -1, size = 0;
128
129 for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
130 if (!state[i].alive) {
131 continue;
132 }
133
134 const int ct = tox_conference_peer_count(toxes[i], state[i].conference, nullptr);
135
136 if (c == -1) {
137 c = ct;
138 } else if (c != ct) {
139 return false;
140 }
141
142 ++size;
143 }
144
145 return (c == size);
146}
147
148static void wait_group_complete(Tox **toxes, State *state)
149{
150 do {
151 iterate_alive(toxes, state);
152 } while (!group_complete(toxes, state));
153}
154
155static void conference_invite_merge_test(Tox **toxes, State *state)
156{
157 // Test that an explicit invite between peers in different connected
158 // components will cause a split group to merge
159
160 for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
161 tox_callback_conference_invite(toxes[i], handle_conference_invite);
162 tox_callback_conference_connected(toxes[i], &handle_conference_connected);
163 state[i].alive = true;
164 state[i].save_state = nullptr;
165 }
166
167 {
168 // Create new conference, tox 2 is the founder.
169 Tox_Err_Conference_New err;
170 state[2].conference = tox_conference_new(toxes[2], &err);
171 state[2].connected = true;
172 ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK,
173 "attempting to create a new conference returned with an error: %d", err);
174 fprintf(stderr, "Created conference: index=%u\n", state[2].conference);
175 }
176
177 save(toxes, state, 2);
178
179 do_invite(toxes, state, 2, 1, 0);
180 do_invite(toxes, state, 1, 0, 0);
181
182 save(toxes, state, 1);
183 kill(toxes, state, 1);
184
185 do {
186 iterate_alive(toxes, state);
187 } while (tox_conference_peer_count(toxes[2], state[2].conference, nullptr) != 1);
188
189 do_invite(toxes, state, 2, 3, 1);
190 do_invite(toxes, state, 3, 4, 1);
191
192 kill(toxes, state, 2);
193
194 reload(toxes, state, 1);
195
196 uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
197 tox_self_get_public_key(toxes[1], public_key);
198 tox_friend_add_norequest(toxes[3], public_key, nullptr);
199 tox_self_get_public_key(toxes[3], public_key);
200 tox_friend_add_norequest(toxes[1], public_key, nullptr);
201 wait_connected(toxes, state, 1, 2);
202
203 do_invite(toxes, state, 1, 3, 2);
204
205 fprintf(stderr, "Waiting for group to merge\n");
206
207 wait_group_complete(toxes, state);
208
209 fprintf(stderr, "Group merged\n");
210
211 reload(toxes, state, 2);
212 wait_connected(toxes, state, 2, 0);
213 do_invite(toxes, state, 2, 1, 0);
214
215 fprintf(stderr, "Waiting for #2 to rejoin\n");
216
217 wait_group_complete(toxes, state);
218
219 kill(toxes, state, 2);
220 wait_group_complete(toxes, state);
221 reload(toxes, state, 2);
222 wait_connected(toxes, state, 2, 0);
223 wait_connected(toxes, state, 1, 1);
224
225 do_invite(toxes, state, 1, 2, 1);
226
227 fprintf(stderr, "Waiting for #2 to rejoin\n");
228
229 wait_group_complete(toxes, state);
230
231 for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
232 if (state[i].save_state != nullptr) {
233 free(state[i].save_state);
234 }
235 }
236}
237
238int main(void)
239{
240 setvbuf(stdout, nullptr, _IONBF, 0);
241
242 run_auto_test(NUM_INVITE_MERGE_TOX, conference_invite_merge_test, true);
243 return 0;
244}