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