summaryrefslogtreecommitdiff
path: root/auto_tests/toxav_many_test.c
diff options
context:
space:
mode:
authormannol <eniz_vukovic@hotmail.com>2014-05-03 01:46:03 +0200
committermannol <eniz_vukovic@hotmail.com>2014-05-03 01:46:03 +0200
commit0fa03b924030c5791599451389ba84b81be84da8 (patch)
tree0d3b93baeb3c18b2f1afce5b9455c9b8bd21ec89 /auto_tests/toxav_many_test.c
parent42b25a4d3e2fe66f03cbd8c866d8af7bd4f6e5a7 (diff)
Bunch of random changes
Diffstat (limited to 'auto_tests/toxav_many_test.c')
-rw-r--r--auto_tests/toxav_many_test.c407
1 files changed, 407 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..7ffa5138
--- /dev/null
+++ b/auto_tests/toxav_many_test.c
@@ -0,0 +1,407 @@
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 ( uint32_t call_index, void *_arg )
64{/*
65 Status *cast = _arg;
66
67 cast->calls[call_index].Callee.status = Ringing;*/
68}
69void callback_recv_ringing ( uint32_t call_index, void *_arg )
70{
71 Status *cast = _arg;
72
73 cast->calls[call_index].Caller.status = Ringing;
74}
75void callback_recv_starting ( uint32_t call_index, void *_arg )
76{
77 Status *cast = _arg;
78
79 cast->calls[call_index].Caller.status = InCall;
80}
81void callback_recv_ending ( uint32_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 ( uint32_t call_index, void *_arg )
89{
90 ck_assert_msg(0, "AV internal error");
91}
92
93void callback_call_started ( uint32_t call_index, void *_arg )
94{/*
95 Status *cast = _arg;
96
97 cast->calls[call_index].Callee.status = InCall;*/
98}
99void callback_call_canceled ( uint32_t call_index, void *_arg )
100{/*
101 Status *cast = _arg;
102
103 cast->calls[call_index].Callee.status = Cancel;*/
104}
105void callback_call_rejected ( uint32_t call_index, void *_arg )
106{
107 Status *cast = _arg;
108
109 cast->calls[call_index].Caller.status = Rejected;
110}
111void callback_call_ended ( uint32_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 ( uint32_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 int16_t sample_payload[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
135 vpx_image_t *sample_image = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, 128, 128, 1);
136
137 memcpy(sample_image->planes[VPX_PLANE_Y], sample_payload, 10);
138 memcpy(sample_image->planes[VPX_PLANE_U], sample_payload, 10);
139 memcpy(sample_image->planes[VPX_PLANE_V], sample_payload, 10);
140
141
142 /* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */
143 while (running) {
144
145 switch ( step ) {
146 case 0: /* CALLER */
147 toxav_call(this_call->Caller.av, &call_idx, this_call->Callee.id, TypeVideo, 10);
148 call_print(call_idx, "Calling ...");
149 step++;
150 break;
151 case 1: /* CALLEE */
152 if (this_call->Caller.status == Ringing) {
153 call_print(call_idx, "Callee answers ...");
154 toxav_answer(this_call->Callee.av, 0, TypeVideo);
155 step++;
156 start = time(NULL);
157 } break;
158 case 2: /* Rtp transmission */
159 if (this_call->Caller.status == InCall) { /* I think this is okay */
160 call_print(call_idx, "Sending rtp ...");
161
162 c_sleep(1000); /* We have race condition here */
163 toxav_prepare_transmission(this_call->Callee.av, 0, 1);
164 toxav_prepare_transmission(this_call->Caller.av, call_idx, 1);
165
166 while (time(NULL) - start < 10) { /* 10 seconds */
167 /* Both send */
168 toxav_send_audio(this_call->Caller.av, call_idx, sample_payload, 10);
169 toxav_send_video(this_call->Caller.av, call_idx, sample_image);
170
171 toxav_send_audio(this_call->Callee.av, 0, sample_payload, 10);
172 toxav_send_video(this_call->Callee.av, 0, sample_image);
173
174 /* Both receive */
175 int16_t storage[10];
176 vpx_image_t *video_storage;
177 int recved;
178
179 /* Payload from CALLEE */
180 recved = toxav_recv_audio(this_call->Caller.av, call_idx, 10, storage);
181
182 if ( recved ) {
183 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLEE is invalid");*/
184 memset(storage, 0, 10);
185 }
186
187 /* Video payload */
188 toxav_recv_video(this_call->Caller.av, call_idx, &video_storage);
189
190 if ( video_storage ) {
191 /*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
192 * memcmp(video_storage->planes[VPX_PLANE_U], sample_payload, 10) == 0 ||
193 * memcmp(video_storage->planes[VPX_PLANE_V], sample_payload, 10) == 0 , "Payload from CALLEE is invalid");*/
194 vpx_img_free(video_storage);
195 }
196
197
198
199 /* Payload from CALLER */
200 recved = toxav_recv_audio(this_call->Callee.av, 0, 10, storage);
201
202 if ( recved ) {
203 /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLER is invalid");*/
204 }
205
206 /* Video payload */
207 toxav_recv_video(this_call->Callee.av, 0, &video_storage);
208
209 if ( video_storage ) {
210 /*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
211 * memcmp(video_storage->planes[VPX_PLANE_U], sample_payload, 10) == 0 ||
212 * memcmp(video_storage->planes[VPX_PLANE_V], sample_payload, 10) == 0 , "Payload from CALLER is invalid");*/
213 vpx_img_free(video_storage);
214 }
215
216 }
217
218 step++; /* This terminates the loop */
219
220 toxav_kill_transmission(this_call->Callee.av, 0);
221 toxav_kill_transmission(this_call->Caller.av, call_idx);
222
223 /* Call over CALLER hangs up */
224 toxav_hangup(this_call->Caller.av, call_idx);
225 call_print(call_idx, "Hanging up ...");
226 }
227 break;
228 case 3: /* Wait for Both to have status ended */
229 if (this_call->Caller.status == Ended) {
230 c_sleep(1000); /* race condition */
231 this_call->Callee.status == Ended;
232 running = 0;
233 }
234
235 break;
236
237 }
238 c_sleep(20);
239 }
240
241 call_print(call_idx, "Call ended successfully!");
242 pthread_exit(NULL);
243}
244
245
246
247
248
249START_TEST(test_AV_three_calls)
250{
251 long long unsigned int cur_time = time(NULL);
252 Tox *bootstrap_node = tox_new(0);
253 Tox *caller = tox_new(0);
254 Tox *callees[3] = {
255 tox_new(0),
256 tox_new(0),
257 tox_new(0),
258 };
259
260
261 ck_assert_msg(bootstrap_node != NULL, "Failed to create bootstrap node");
262
263 int i = 0;
264 for (; i < 3; i ++) {
265 ck_assert_msg(callees[i] != NULL, "Failed to create 3 tox instances");
266 }
267
268 for ( i = 0; i < 3; i ++ ) {
269 uint32_t to_compare = 974536;
270 tox_callback_friend_request(callees[i], accept_friend_request, &to_compare);
271 uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
272 tox_get_address(callees[i], address);
273
274 int test = tox_add_friend(caller, address, (uint8_t *)"gentoo", 7);
275 ck_assert_msg( test == i, "Failed to add friend error code: %i", test);
276 }
277
278 uint8_t off = 1;
279
280 while (1) {
281 tox_do(bootstrap_node);
282 tox_do(caller);
283
284 for (i = 0; i < 3; i ++) {
285 tox_do(callees[i]);
286 }
287
288
289 if (tox_isconnected(bootstrap_node) &&
290 tox_isconnected(caller) &&
291 tox_isconnected(callees[0]) &&
292 tox_isconnected(callees[1]) &&
293 tox_isconnected(callees[2]) && off) {
294 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
295 off = 0;
296 }
297
298
299 if (tox_get_friend_connection_status(caller, 0) == 1 &&
300 tox_get_friend_connection_status(caller, 1) == 1 &&
301 tox_get_friend_connection_status(caller, 2) == 1 )
302 break;
303
304 c_sleep(20);
305 }
306
307 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time);
308
309
310 ToxAvCodecSettings cast = av_DefaultSettings;
311
312 ToxAv* uniqcallerav = toxav_new(caller, &cast, 3);
313
314 Status status_control = {
315 0,
316 {none, uniqcallerav, 0},
317 {none, toxav_new(callees[0], &cast, 1), 0},
318
319 0,
320 {none, uniqcallerav},
321 {none, toxav_new(callees[1], &cast, 1), 1},
322
323 0,
324 {none, uniqcallerav},
325 {none, toxav_new(callees[2], &cast, 1), 2}
326 };
327
328
329 toxav_register_callstate_callback(callback_call_started, av_OnStart, &status_control);
330 toxav_register_callstate_callback(callback_call_canceled, av_OnCancel, &status_control);
331 toxav_register_callstate_callback(callback_call_rejected, av_OnReject, &status_control);
332 toxav_register_callstate_callback(callback_call_ended, av_OnEnd, &status_control);
333 toxav_register_callstate_callback(callback_recv_invite, av_OnInvite, &status_control);
334
335 toxav_register_callstate_callback(callback_recv_ringing, av_OnRinging, &status_control);
336 toxav_register_callstate_callback(callback_recv_starting, av_OnStarting, &status_control);
337 toxav_register_callstate_callback(callback_recv_ending, av_OnEnding, &status_control);
338
339 toxav_register_callstate_callback(callback_recv_error, av_OnError, &status_control);
340 toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control);
341
342
343
344 for ( i = 0; i < 3; i++ )
345 pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]);
346
347
348 /* Now start 3 calls and they'll run for 10 s */
349
350 for ( i = 0; i < 3; i++ )
351 pthread_detach(status_control.calls[i].tid);
352
353 while (
354 status_control.calls[0].Callee.status != Ended && status_control.calls[0].Caller.status != Ended &&
355 status_control.calls[1].Callee.status != Ended && status_control.calls[1].Caller.status != Ended &&
356 status_control.calls[2].Callee.status != Ended && status_control.calls[2].Caller.status != Ended
357 ) {
358 tox_do(bootstrap_node);
359 tox_do(caller);
360 tox_do(callees[0]);
361 tox_do(callees[1]);
362 tox_do(callees[2]);
363 c_sleep(20);
364 }
365
366 toxav_kill(status_control.calls[0].Caller.av);
367 toxav_kill(status_control.calls[0].Callee.av);
368 toxav_kill(status_control.calls[1].Callee.av);
369 toxav_kill(status_control.calls[2].Callee.av);
370
371 tox_kill(bootstrap_node);
372 tox_kill(caller);
373 for ( i = 0; i < 3; i ++)
374 tox_kill(callees[i]);
375
376}
377END_TEST
378
379
380
381
382Suite *tox_suite(void)
383{
384 Suite *s = suite_create("ToxAV");
385
386 TCase *tc_av_three_calls = tcase_create("AV_three_calls");
387 tcase_add_test(tc_av_three_calls, test_AV_three_calls);
388 tcase_set_timeout(tc_av_three_calls, 150);
389 suite_add_tcase(s, tc_av_three_calls);
390
391 return s;
392}
393int main(int argc, char *argv[])
394{
395 Suite *tox = tox_suite();
396 SRunner *test_runner = srunner_create(tox);
397
398 setbuf(stdout, NULL);
399
400 srunner_run_all(test_runner, CK_NORMAL);
401 int number_failed = srunner_ntests_failed(test_runner);
402
403 srunner_free(test_runner);
404
405 return number_failed;
406
407} \ No newline at end of file