summaryrefslogtreecommitdiff
path: root/auto_tests/toxav_many_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'auto_tests/toxav_many_test.c')
-rw-r--r--auto_tests/toxav_many_test.c388
1 files changed, 388 insertions, 0 deletions
diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c
new file mode 100644
index 00000000..b499b439
--- /dev/null
+++ b/auto_tests/toxav_many_test.c
@@ -0,0 +1,388 @@
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <sys/types.h>
6#include <stdint.h>
7#include <string.h>
8#include <stdio.h>
9#include <check.h>
10#include <stdlib.h>
11#include <time.h>
12#include <assert.h>
13
14#include "../toxcore/tox.h"
15#include "../toxcore/logger.h"
16#include "../toxav/toxav.h"
17
18#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
19#define c_sleep(x) Sleep(1*x)
20#else
21#include <unistd.h>
22#include <pthread.h>
23#define c_sleep(x) usleep(1000*x)
24#endif
25
26
27typedef enum _CallStatus {
28 none,
29 InCall,
30 Ringing,
31 Ended,
32 Rejected,
33 Cancel
34
35} CallStatus;
36
37typedef struct _Party {
38 CallStatus status;
39 ToxAv *av;
40 int id;
41} Party;
42
43typedef struct _ACall {
44 pthread_t tid;
45
46 Party Caller;
47 Party Callee;
48} ACall;
49
50typedef struct _Status {
51 ACall calls[3]; /* Make 3 calls for this test */
52} Status;
53
54void accept_friend_request(Tox *m, uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
55{
56 if (length == 7 && memcmp("gentoo", data, 7) == 0) {
57 tox_add_friend_norequest(m, public_key);
58 }
59}
60
61
62/******************************************************************************/
63void callback_recv_invite ( int32_t call_index, void *_arg )
64{/*
65 Status *cast = _arg;
66
67 cast->calls[call_index].Callee.status = Ringing;*/
68}
69void callback_recv_ringing ( int32_t call_index, void *_arg )
70{
71 Status *cast = _arg;
72
73 cast->calls[call_index].Caller.status = Ringing;
74}
75void callback_recv_starting ( int32_t call_index, void *_arg )
76{
77 Status *cast = _arg;
78
79 cast->calls[call_index].Caller.status = InCall;
80}
81void callback_recv_ending ( int32_t call_index, void *_arg )
82{
83 Status *cast = _arg;
84
85 cast->calls[call_index].Caller.status = Ended;
86}
87
88void callback_recv_error ( int32_t call_index, void *_arg )
89{
90 ck_assert_msg(0, "AV internal error");
91}
92
93void callback_call_started ( int32_t call_index, void *_arg )
94{/*
95 Status *cast = _arg;
96
97 cast->calls[call_index].Callee.status = InCall;*/
98}
99void callback_call_canceled ( int32_t call_index, void *_arg )
100{/*
101 Status *cast = _arg;
102
103 cast->calls[call_index].Callee.status = Cancel;*/
104}
105void callback_call_rejected ( int32_t call_index, void *_arg )
106{
107 Status *cast = _arg;
108
109 cast->calls[call_index].Caller.status = Rejected;
110}
111void callback_call_ended ( int32_t call_index, void *_arg )
112{/*
113 Status *cast = _arg;
114
115 cast->calls[call_index].Callee.status = Ended;*/
116}
117
118void callback_requ_timeout ( int32_t call_index, void *_arg )
119{
120 ck_assert_msg(0, "No answer!");
121}
122/*************************************************************************************************/
123
124
125void* in_thread_call (void* arg)
126{
127#define call_print(call, what, args...) printf("[%d] " what "\n", call, ##args)
128
129 ACall* this_call = arg;
130 uint64_t start = 0;
131 int step = 0,running = 1;
132 int call_idx;
133
134
135 int16_t sample_payload[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
136 uint8_t prepared_payload[1000];
137
138
139 /* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */
140 while (running) {
141
142 switch ( step ) {
143 case 0: /* CALLER */
144 toxav_call(this_call->Caller.av, &call_idx, this_call->Callee.id, TypeVideo, 10);
145 call_print(call_idx, "Calling ...");
146 step++;
147 break;
148 case 1: /* CALLEE */
149 if (this_call->Caller.status == Ringing) {
150 call_print(call_idx, "Callee answers ...");
151 toxav_answer(this_call->Callee.av, 0, TypeVideo);
152 step++;
153 start = time(NULL);
154 } break;
155 case 2: /* Rtp transmission */
156 if (this_call->Caller.status == InCall) { /* I think this is okay */
157 call_print(call_idx, "Sending rtp ...");
158
159 ToxAvCodecSettings cast = av_DefaultSettings;
160
161 c_sleep(1000); /* We have race condition here */
162 toxav_prepare_transmission(this_call->Callee.av, 0, &cast, 1);
163 toxav_prepare_transmission(this_call->Caller.av, call_idx, &cast, 1);
164
165 int payload_size = toxav_prepare_audio_frame(this_call->Caller.av, call_idx, prepared_payload, 1000, sample_payload, 120);
166 if (!( payload_size > 0 )) {
167 ck_assert_msg ( 0, "Failed to encode payload" );
168 }
169
170 while (time(NULL) - start < 10) { /* 10 seconds */
171 /* Both send */
172 toxav_send_audio(this_call->Caller.av, call_idx, prepared_payload, payload_size);
173
174 toxav_send_audio(this_call->Callee.av, 0, prepared_payload, payload_size);
175
176 call_print(time(NULL) - start, "Blaaah");
177 /* Both receive */
178 int16_t storage[1000];
179 int recved;
180
181 /* Payload from CALLER */
182 recved = toxav_recv_audio(this_call->Callee.av, 0, 120, storage);
183
184 if ( recved ) {
185 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLER is invalid");*/
186 }
187
188 /* Payload from CALLEE */
189 recved = toxav_recv_audio(this_call->Caller.av, call_idx, 120, storage);
190
191 if ( recved ) {
192 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLEE is invalid");*/
193 }
194
195 //c_sleep(20);
196 }
197
198 step++; /* This terminates the loop */
199
200 toxav_kill_transmission(this_call->Callee.av, 0);
201 toxav_kill_transmission(this_call->Caller.av, call_idx);
202
203 /* Call over CALLER hangs up */
204 toxav_hangup(this_call->Caller.av, call_idx);
205 call_print(call_idx, "Hanging up ...");
206 }
207 break;
208 case 3: /* Wait for Both to have status ended */
209 if (this_call->Caller.status == Ended) {
210 c_sleep(1000); /* race condition */
211 this_call->Callee.status == Ended;
212 running = 0;
213 }
214
215 break;
216
217 }
218 c_sleep(20);
219 }
220
221 call_print(call_idx, "Call ended successfully!");
222 pthread_exit(NULL);
223}
224
225
226
227
228
229START_TEST(test_AV_three_calls)
230// void test_AV_three_calls()
231{
232 long long unsigned int cur_time = time(NULL);
233 Tox *bootstrap_node = tox_new(0);
234 Tox *caller = tox_new(0);
235 Tox *callees[3] = {
236 tox_new(0),
237 tox_new(0),
238 tox_new(0),
239 };
240
241
242 ck_assert_msg(bootstrap_node != NULL, "Failed to create bootstrap node");
243
244 int i = 0;
245 for (; i < 3; i ++) {
246 ck_assert_msg(callees[i] != NULL, "Failed to create 3 tox instances");
247 }
248
249 for ( i = 0; i < 3; i ++ ) {
250 uint32_t to_compare = 974536;
251 tox_callback_friend_request(callees[i], accept_friend_request, &to_compare);
252 uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
253 tox_get_address(callees[i], address);
254
255 int test = tox_add_friend(caller, address, (uint8_t *)"gentoo", 7);
256 ck_assert_msg( test == i, "Failed to add friend error code: %i", test);
257 }
258
259 uint8_t off = 1;
260
261 while (1) {
262 tox_do(bootstrap_node);
263 tox_do(caller);
264
265 for (i = 0; i < 3; i ++) {
266 tox_do(callees[i]);
267 }
268
269
270 if (tox_isconnected(bootstrap_node) &&
271 tox_isconnected(caller) &&
272 tox_isconnected(callees[0]) &&
273 tox_isconnected(callees[1]) &&
274 tox_isconnected(callees[2]) && off) {
275 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
276 off = 0;
277 }
278
279
280 if (tox_get_friend_connection_status(caller, 0) == 1 &&
281 tox_get_friend_connection_status(caller, 1) == 1 &&
282 tox_get_friend_connection_status(caller, 2) == 1 )
283 break;
284
285 c_sleep(20);
286 }
287
288 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time);
289
290 ToxAv* uniqcallerav = toxav_new(caller, 3);
291
292 Status status_control = {
293 0,
294 {none, uniqcallerav, 0},
295 {none, toxav_new(callees[0], 1), 0},
296
297 0,
298 {none, uniqcallerav},
299 {none, toxav_new(callees[1], 1), 1},
300
301 0,
302 {none, uniqcallerav},
303 {none, toxav_new(callees[2], 1), 2}
304 };
305
306
307 toxav_register_callstate_callback(callback_call_started, av_OnStart, &status_control);
308 toxav_register_callstate_callback(callback_call_canceled, av_OnCancel, &status_control);
309 toxav_register_callstate_callback(callback_call_rejected, av_OnReject, &status_control);
310 toxav_register_callstate_callback(callback_call_ended, av_OnEnd, &status_control);
311 toxav_register_callstate_callback(callback_recv_invite, av_OnInvite, &status_control);
312
313 toxav_register_callstate_callback(callback_recv_ringing, av_OnRinging, &status_control);
314 toxav_register_callstate_callback(callback_recv_starting, av_OnStarting, &status_control);
315 toxav_register_callstate_callback(callback_recv_ending, av_OnEnding, &status_control);
316
317 toxav_register_callstate_callback(callback_recv_error, av_OnError, &status_control);
318 toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control);
319
320
321
322 for ( i = 0; i < 3; i++ )
323 pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]);
324
325
326 /* Now start 3 calls and they'll run for 10 s */
327
328 for ( i = 0; i < 3; i++ )
329 pthread_detach(status_control.calls[i].tid);
330
331 while (
332 status_control.calls[0].Callee.status != Ended && status_control.calls[0].Caller.status != Ended &&
333 status_control.calls[1].Callee.status != Ended && status_control.calls[1].Caller.status != Ended &&
334 status_control.calls[2].Callee.status != Ended && status_control.calls[2].Caller.status != Ended
335 ) {
336 tox_do(bootstrap_node);
337 tox_do(caller);
338 tox_do(callees[0]);
339 tox_do(callees[1]);
340 tox_do(callees[2]);
341 c_sleep(20);
342 }
343
344 toxav_kill(status_control.calls[0].Caller.av);
345 toxav_kill(status_control.calls[0].Callee.av);
346 toxav_kill(status_control.calls[1].Callee.av);
347 toxav_kill(status_control.calls[2].Callee.av);
348
349 tox_kill(bootstrap_node);
350 tox_kill(caller);
351 for ( i = 0; i < 3; i ++)
352 tox_kill(callees[i]);
353
354}
355END_TEST
356
357
358
359
360Suite *tox_suite(void)
361{
362 Suite *s = suite_create("ToxAV");
363
364 TCase *tc_av_three_calls = tcase_create("AV_three_calls");
365 tcase_add_test(tc_av_three_calls, test_AV_three_calls);
366 tcase_set_timeout(tc_av_three_calls, 150);
367 suite_add_tcase(s, tc_av_three_calls);
368
369 return s;
370}
371int main(int argc, char *argv[])
372{
373 Suite *tox = tox_suite();
374 SRunner *test_runner = srunner_create(tox);
375
376 setbuf(stdout, NULL);
377
378 srunner_run_all(test_runner, CK_NORMAL);
379 int number_failed = srunner_ntests_failed(test_runner);
380
381 srunner_free(test_runner);
382
383 return number_failed;
384
385// test_AV_three_calls();
386//
387// return 0;
388} \ No newline at end of file