summaryrefslogtreecommitdiff
path: root/auto_tests
diff options
context:
space:
mode:
authorzugz (tox) <mbays+tox@sdf.org>2020-03-01 00:00:00 +0000
committerzugz (tox) <mbays+tox@sdf.org>2020-03-18 00:00:00 +0000
commitdb07bda7f7b1ab7f5f219a9ed3d7f732b7da66b0 (patch)
treee5b4e5b43320c4073b619c006c1b32040cd06b8d /auto_tests
parent84e6a8d05704d9f4db79898984af861d759c478a (diff)
Add "member" invite response
This allows invitations to work in the case that the invitee is already in the group, which can happen if the group becomes split. Such an invitation is automatically accepted, leading to the peers becoming connected in the group and sharing peer lists.
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}