aboutsummaryrefslogtreecommitdiff
path: root/src/scalarproduct/test_scalarproduct_api_regression2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scalarproduct/test_scalarproduct_api_regression2.c')
-rw-r--r--src/scalarproduct/test_scalarproduct_api_regression2.c931
1 files changed, 931 insertions, 0 deletions
diff --git a/src/scalarproduct/test_scalarproduct_api_regression2.c b/src/scalarproduct/test_scalarproduct_api_regression2.c
new file mode 100644
index 000000000..8a0162b40
--- /dev/null
+++ b/src/scalarproduct/test_scalarproduct_api_regression2.c
@@ -0,0 +1,931 @@
1/*
2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/**
22 * @file vectorproduct/test_vectorproduct_api_regression2.c
23 * @brief Regression test, destroys requester service before receiving response
24 * responder service
25 * @author Gaurav Kukreja
26 * @author Christian Fuchs
27 */
28
29#include <string.h>
30
31#include <inttypes.h>
32#include "platform.h"
33#include "gnunet_util_lib.h"
34#include "gnunet_testbed_service.h"
35#include "gnunet_common.h"
36#include "gnunet_vectorproduct_service.h"
37#include "gnunet_protocols.h"
38
39#define LOG(kind,...) GNUNET_log_from (kind, "test-vectorproduct-api-regression2",__VA_ARGS__)
40#define NUM_PEERS 2
41
42/**
43 * Structure for holding peer's sockets and IO Handles
44 */
45struct PeerData
46{
47 /**
48 * Handle to testbed peer
49 */
50 struct GNUNET_TESTBED_Peer *peer;
51
52 /**
53 * The service connect operation to stream
54 */
55 struct GNUNET_TESTBED_Operation *op;
56
57 /**
58 * Our Peer id
59 */
60 struct GNUNET_PeerIdentity our_id;
61
62 /**
63 * Pointer to Vector Product Handle
64 */
65 struct GNUNET_VECTORPRODUCT_Handle *vh;
66};
67
68/**
69 * Different states in test setup
70 */
71enum SetupState
72{
73 /**
74 * Get the identity of peer 1
75 */
76 PEER1_GET_IDENTITY,
77
78 /**
79 * Get the identity of peer 2
80 */
81 PEER2_GET_IDENTITY,
82
83 /**
84 * Connect to stream service of peer 1
85 */
86 PEER1_VECTORPRODUCT_CONNECT,
87
88 /**
89 * Connect to stream service of peer 2
90 */
91 PEER2_VECTORPRODUCT_CONNECT
92
93};
94
95/******************************************************************************
96 *** Global Variables *****************************
97 ******************************************************************************/
98
99/**
100 * Maximum allowed message-ids we can check in one go (with one GNUNET_message)
101 */
102static unsigned int max_mids;
103
104/**
105 * Session Key used by both the test peers
106 */
107char input_key[103] = "helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhe";
108
109/**
110 * Input elements for peer1
111 */
112char input_elements_peer1[] = "11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11";
113//char input_elements_peer1[] = "11,11,11";
114
115/**
116 * Input Mask for peer 1
117 */
118char input_mask_peer1[] = "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1";
119//char input_mask_peer1[] = "1,1,1";
120
121/**
122 * the array of converted message IDs to send to our service
123 */
124static int32_t * elements_peer1 = NULL;
125
126/**
127 * the array of converted message IDs to send to our service
128 */
129static unsigned char * mask_peer1 = NULL;
130
131/**
132 * Number of elements
133 */
134uint16_t element_count_peer1 = 0;
135
136/**
137 * Input elements for peer2
138 */
139char input_elements_peer2[] = "11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11";
140//char input_elements_peer2[] = "11,11,11";
141
142/**
143 * Input Mask for peer 2
144 */
145char input_mask_peer2[] = "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1";
146//char input_mask_peer2[] = "1,1,1";
147
148/**
149 * the array of converted message IDs to send to our service
150 */
151static int32_t * elements_peer2 = NULL;
152
153/**
154 * the array of converted message IDs to send to our service
155 */
156static unsigned char * mask_peer2 = NULL;
157
158/**
159 * Number of elements
160 */
161uint16_t element_count_peer2 = 0;
162
163/**
164 * Data context for peer 1
165 */
166static struct PeerData peer1;
167
168/**
169 * Data context for peer 2
170 */
171static struct PeerData peer2;
172
173/**
174 * Various states during test setup
175 */
176static enum SetupState setup_state;
177
178/**
179 * Testbed operation handle
180 */
181static struct GNUNET_TESTBED_Operation *op;
182
183static int ok;
184
185static int responder_ok;
186
187static int requester_ok;
188
189static GNUNET_SCHEDULER_TaskIdentifier abort_task;
190/******************************************************************************
191 *** Static Functions *****************************
192 ******************************************************************************/
193
194static void
195do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
196
197
198/**
199 * Close sockets and stop testing deamons nicely
200 */
201static void
202do_close (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
203{
204 static int closed;
205
206 if (peer1.op != NULL)
207 {
208 do_shutdown (&peer1, NULL);
209 }
210
211 if (peer2.op != NULL)
212 {
213 do_shutdown (&peer2, NULL);
214 }
215
216 if (GNUNET_SCHEDULER_NO_TASK != abort_task)
217 {
218 GNUNET_SCHEDULER_cancel (abort_task);
219 abort_task = GNUNET_SCHEDULER_NO_TASK;
220 GNUNET_SCHEDULER_shutdown (); /* For shutting down testbed */
221 }
222
223 if (!closed)
224 {
225 closed++;
226 GNUNET_SCHEDULER_shutdown (); /* For shutting down testbed */
227 }
228}
229
230/**
231 * Shutdown a peer
232 *
233 * @param cls closure is a pointer to the struct PeerData of the peer to be disconnected
234 * @param tc Task Context
235 */
236static void
237do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
238{
239 static int shutdown;
240 shutdown++;
241 struct PeerData* peer = (struct PeerData*) cls;
242
243 // peer->op contains handle to the TESTBED_connect_service operation
244 // calling operation done, leads to call to vectorproduct_da
245 if (peer->op != NULL)
246 {
247 if (peer == &peer1)
248 LOG (GNUNET_ERROR_TYPE_INFO, "Disconnecting Peer1\n\n");
249 else if (peer == &peer2)
250 LOG (GNUNET_ERROR_TYPE_INFO, "Disconnecting Peer2\n\n");
251
252 GNUNET_TESTBED_operation_done (peer->op);
253 peer->op = NULL;
254 }
255
256 if (peer1.op == NULL && peer2.op == NULL)
257 GNUNET_SCHEDULER_add_now (&do_close, NULL);
258}
259
260
261/**
262 * Something went wrong and timed out. Kill everything and set error flag
263 */
264static void
265do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
266{
267 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: ABORT due to Timeout\n");
268 ok = GNUNET_SYSERR;
269 abort_task = GNUNET_SCHEDULER_NO_TASK;
270 GNUNET_SCHEDULER_add_now (&do_shutdown, &peer1);
271 GNUNET_SCHEDULER_add_now (&do_shutdown, &peer2);
272}
273
274
275/**
276 * Controller event callback
277 *
278 * @param cls NULL
279 * @param event the controller event
280 */
281static void
282controller_event_cb (void *cls,
283 const struct GNUNET_TESTBED_EventInformation *event)
284{
285 switch (event->type)
286 {
287 case GNUNET_TESTBED_ET_OPERATION_FINISHED:
288 switch (setup_state)
289 {
290 case PEER1_VECTORPRODUCT_CONNECT:
291 case PEER2_VECTORPRODUCT_CONNECT:
292 GNUNET_assert (NULL == event->details.operation_finished.emsg);
293 break;
294 default:
295 GNUNET_assert (0);
296 }
297 break;
298 default:
299 GNUNET_assert (0);
300 }
301}
302
303
304static void
305responder_callback (void *cls,
306 const struct GNUNET_HashCode * key,
307 enum GNUNET_VECTORPRODUCT_ResponseStatus status)
308{
309 if (status == GNUNET_VECTORPRODUCT_Status_Failure)
310 {
311 LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received status failure\n");
312 responder_ok = -1;
313 }
314 else if (status == GNUNET_VECTORPRODUCT_Status_InvalidResponse)
315 {
316 LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received status invalid response\n");
317 responder_ok = -1;
318 }
319 else if (GNUNET_VECTORPRODUCT_Status_Timeout == status)
320 {
321 LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received timeout occured\n");
322 // In this regression test, requester is supposed to fail due to timeout
323 // therefore responder_ok is set to 1, to make regression test pass
324 responder_ok = 1;
325 }
326 else if (GNUNET_VECTORPRODUCT_Status_ServiceDisconnected == status)
327 {
328 LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received service disconnected!!\n");
329 responder_ok = -1;
330 }
331 else if (GNUNET_VECTORPRODUCT_Status_Success == status)
332 {
333 LOG (GNUNET_ERROR_TYPE_DEBUG, "Responder Client expected response received!\n");
334 responder_ok = 1;
335 }
336 else
337 {
338 LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client status = %d!\n", (int) status);
339 responder_ok = -1;
340 }
341 // TODO : Responder Session Complete. Shutdown Test Cleanly!!!
342 //do_shutdown(&peer1, NULL);
343 GNUNET_SCHEDULER_add_now (&do_shutdown, &peer1);
344 return;
345}
346
347
348static void
349requester_callback (void *cls,
350 const struct GNUNET_HashCode * key,
351 const struct GNUNET_PeerIdentity * peer,
352 enum GNUNET_VECTORPRODUCT_ResponseStatus status,
353 uint16_t size, struct GNUNET_VECTORPRODUCT_client_response *msg,
354 uint16_t type)
355{
356 uint32_t product_len;
357
358 if (status == GNUNET_VECTORPRODUCT_Status_Failure)
359 {
360 LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client received status failure\n");
361 // In this regression test, requester is supposed to receive status failure
362 // therefore requester_ok is set to 1, to make regression test pass
363 requester_ok = 1;
364 }
365 else if (status == GNUNET_VECTORPRODUCT_Status_InvalidResponse)
366 {
367 LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client received status invalid response\n");
368 requester_ok = -1;
369 }
370 else if (GNUNET_VECTORPRODUCT_Status_Timeout == status)
371 {
372 LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client timeout occured\n");
373 requester_ok = -1;
374 }
375 else if (GNUNET_VECTORPRODUCT_Status_ServiceDisconnected == status)
376 {
377 LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client service disconnected!!\n");
378 requester_ok = -1;
379 }
380 else if (GNUNET_VECTORPRODUCT_Status_Success != status)
381 {
382 LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client Status = %d\n", (int) status);
383 requester_ok = -1;
384 }
385 else if (GNUNET_VECTORPRODUCT_Status_Success == status)
386 {
387 LOG (GNUNET_ERROR_TYPE_DEBUG, "Requester Client expected response received!\n");
388
389 product_len = ntohl (msg->product_length);
390
391 if (0 < product_len)
392 {
393 gcry_mpi_t result;
394 gcry_error_t ret = 0;
395 size_t read = 0;
396
397 ret = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, (void *) &msg[1], product_len, &read);
398
399 if (0 != ret)
400 {
401 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not convert to mpi to value!\n");
402 ok = -1;
403 }
404 else
405 {
406 uint16_t i = 0;
407
408 // calculate expected product
409 gcry_mpi_t expected_result;
410 gcry_mpi_t v1;
411 gcry_mpi_t v2;
412 gcry_mpi_t v1_v2_prod;
413
414 expected_result = gcry_mpi_new (0);
415
416 for (i = 0; i < element_count_peer1; i++)
417 {
418 uint32_t value;
419 v1_v2_prod = gcry_mpi_new (0);
420
421 // long to gcry_mpi_t
422 value = elements_peer1[i] >= 0 ? elements_peer1[i] : -elements_peer1[i];
423 if (elements_peer1[i] < 0)
424 {
425 v1 = gcry_mpi_new (0);
426 gcry_mpi_sub_ui (v1, v1, value);
427 }
428 else
429 v1 = gcry_mpi_set_ui (NULL, value);
430
431 // long to gcry_mpi_t
432 value = elements_peer2[i] >= 0 ? elements_peer2[i] : -elements_peer2[i];
433 if (elements_peer2[i] < 0)
434 {
435 v2 = gcry_mpi_new (0);
436 gcry_mpi_sub_ui (v2, v2, value);
437 }
438 else
439 v2 = gcry_mpi_set_ui (NULL, value);
440
441 gcry_mpi_mul (v1_v2_prod, v1, v2);
442 gcry_mpi_add (expected_result, expected_result, v1_v2_prod);
443
444 gcry_mpi_release (v1);
445 gcry_mpi_release (v2);
446 gcry_mpi_release (v1_v2_prod);
447
448 }
449
450 // compare the result
451 if (!gcry_mpi_cmp (expected_result, result))
452 {
453 LOG (GNUNET_ERROR_TYPE_DEBUG, "Scalar Product matches expected Result!!\n");
454 requester_ok = 1;
455 }
456 else
457 {
458 LOG (GNUNET_ERROR_TYPE_WARNING, "Scalar Product DOES NOT match expected Result!!\n");
459 requester_ok = -1;
460 }
461 gcry_mpi_release (result);
462 gcry_mpi_release (expected_result);
463 }
464 }
465 else
466 { //currently not used, but if we get more info due to MESH we will need this
467 LOG (GNUNET_ERROR_TYPE_WARNING, "Error during computation of vector product, return code: %d\n", product_len);
468 requester_ok = -1;
469 }
470 }
471
472 //do_shutdown(&peer2, NULL);
473 GNUNET_SCHEDULER_add_now (&do_shutdown, &peer2);
474 return;
475}
476
477
478static struct GNUNET_VECTORPRODUCT_QueueEntry *
479requester_request ()
480{
481 GNUNET_assert (peer2.vh != NULL);
482
483 unsigned int i;
484 //uint16_t element_count_peer2 = 0;
485 uint16_t mask_length = 0;
486 char * begin = input_elements_peer2;
487 char * end;
488 int32_t element;
489
490 struct GNUNET_VECTORPRODUCT_QueueEntry *qe;
491
492 struct GNUNET_HashCode key;
493 GNUNET_CRYPTO_hash (input_key, strlen (input_key), &key);
494
495 int exit_loop = 0;
496 /* Read input_elements_peer2, and put in elements_peer2 array */
497 do
498 {
499 unsigned int mcount = element_count_peer2;
500 //ignore empty rows of ,,,,,,
501 while (*begin == ',')
502 begin++;
503 // get the length of the current element and replace , with null
504 for (end = begin; *end && *end != ','; end++);
505
506 if (*end == '\0')
507 exit_loop = 1;
508
509 if (1 != sscanf (begin, "%" SCNd32, &element))
510 {
511 FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin);
512 ok = -1;
513 return NULL;
514 }
515
516 GNUNET_array_append (elements_peer2, mcount, element);
517 element_count_peer2++;
518
519 begin = ++end;
520 }
521 while (!exit_loop && element_count_peer2 < max_mids);
522
523 GNUNET_assert (elements_peer2 != NULL);
524 GNUNET_assert (element_count_peer2 >= 1);
525 mask_length = element_count_peer2 / 8 + (element_count_peer2 % 8 ? 1 : 0);
526 mask_peer2 = GNUNET_malloc ((element_count_peer2 / 8) + 2);
527 GNUNET_assert (NULL != mask_peer2);
528
529 /* Read input_mask_peer2 and read in mask_peer2 array */
530 if (NULL != input_mask_peer2)
531 {
532 begin = input_mask_peer2;
533 unsigned short mask_count = 0;
534 int exit_loop = 0;
535
536 do
537 {
538 //ignore empty rows of ,,,,,,
539 while (* begin == ',')
540 begin++;
541 // get the length of the current element and replace , with null
542 // gnunet_ascii-armor uses base32, thus we can use , as separator!
543 for (end = begin; *end && *end != ','; end++);
544
545 if (*end == '\0')
546 exit_loop = 1;
547
548 if (1 != sscanf (begin, "%" SCNd32, &element))
549 {
550 FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin);
551 ok = -1;
552 return NULL;
553 }
554
555 GNUNET_assert (mask_count <= element_count_peer2);
556
557 if (element)
558 mask_peer2[mask_count / 8] = mask_peer2[mask_count / 8] | 1 << (mask_count % 8);
559
560 mask_count++;
561 begin = ++end;
562 }
563 while (!exit_loop);
564 // +1 to see if we would have more data, which would indicate malformed/superficial input
565 GNUNET_assert (mask_count == element_count_peer2);
566 }
567 else
568 {
569 for (i = 0; i <= mask_length; i++)
570 mask_peer2[i] = UCHAR_MAX; // all 1's
571 }
572
573 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Responder peer key %s\n", &peer1.our_id);
574
575 // TODO : Create the mask array
576 qe = GNUNET_VECTORPRODUCT_request (peer2.vh,
577 &key,
578 &peer1.our_id,
579 element_count_peer2,
580 mask_length,
581 elements_peer2, mask_peer2,
582 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
583 &requester_callback,
584 NULL);
585
586 if (qe == NULL)
587 {
588 FPRINTF (stderr, "%s", _ ("Could not send request to vectorproduct service! Exitting!"));
589 ok = -1;
590 return NULL;
591 }
592
593 return qe;
594}
595
596
597/**
598 * Function prepares the message to be sent by peer1 to its vectorproduct service
599 * to prepare response, and wait for a request session to be initiated by peer1
600 */
601static struct GNUNET_VECTORPRODUCT_QueueEntry *
602responder_prepare_response ()
603{
604 GNUNET_assert (peer1.vh != NULL);
605
606 unsigned int i;
607 //uint16_t element_count_peer1 = 0;
608 char * begin = input_elements_peer1;
609 char * end;
610 int32_t element;
611
612 struct GNUNET_VECTORPRODUCT_QueueEntry *qe;
613
614 struct GNUNET_HashCode key;
615 GNUNET_CRYPTO_hash (input_key, strlen (input_key), &key);
616
617 int exit_loop = 0;
618 /* Read input_elements_peer1, and put in elements_peer1 array */
619 do
620 {
621 unsigned int mcount = element_count_peer1;
622 //ignore empty rows of ,,,,,,
623 while (*begin == ',')
624 begin++;
625 // get the length of the current element and replace , with null
626 for (end = begin; *end && *end != ','; end++);
627
628 if (*end == '\0')
629 exit_loop = 1;
630
631 if (*end == ',')
632 *end = '\0';
633
634 if (1 != sscanf (begin, "%" SCNd32, &element))
635 {
636 FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin);
637 ok = -1;
638 return NULL;
639 }
640
641 GNUNET_array_append (elements_peer1, mcount, element);
642 element_count_peer1++;
643
644 begin = ++end;
645 }
646 while (!exit_loop && element_count_peer1 < max_mids);
647
648 GNUNET_assert (elements_peer1 != NULL);
649 GNUNET_assert (element_count_peer1 >= 1);
650
651 qe = GNUNET_VECTORPRODUCT_prepare_response (peer1.vh,
652 &key,
653 element_count_peer1,
654 elements_peer1,
655 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
656 &responder_callback,
657 NULL);
658
659 if (qe == NULL)
660 {
661 FPRINTF (stderr, "%s", _ ("Could not send request to vectorproduct service! Exitting!"));
662 ok = -1;
663 return NULL;
664 }
665 return qe;
666}
667
668
669/**
670 * Scheduler task to initiate requester client
671 *
672 * @param cls void* to struct PeerData
673 * @param tc Task Context
674 */
675static void
676request_task (void *cls,
677 const struct GNUNET_SCHEDULER_TaskContext
678 * tc)
679{
680 struct PeerData * peer = cls;
681
682 requester_request ();
683 return;
684}
685
686
687/**
688 * Scheduler task to initiate responder client
689 *
690 * @param cls void* to struct PeerData
691 * @param tc Task Context
692 */
693static void
694prepare_response_task (void *cls,
695 const struct GNUNET_SCHEDULER_TaskContext
696 * tc)
697{
698 struct PeerData * peer = cls;
699
700 responder_prepare_response ();
701 return;
702}
703
704
705static void
706peer_stop_callback (void *cls,
707 const char *emsg)
708{
709 GNUNET_TESTBED_peer_destroy (peer2.peer);
710}
711
712/**
713 * Destroys Peer2 i.e. the initiator peer (Alice) This function is scheduled to
714 * run a few milliseconds after the request has been sent to the Responding Peer (Bob).
715 * This function tries to emulate a crash of Peer2.
716 *
717 * @param cls Not used
718 * @param tc Task Context - Not used
719 */
720static void
721destroy_server (void *cls,
722 const struct GNUNET_SCHEDULER_TaskContext *tc)
723{
724 LOG (GNUNET_ERROR_TYPE_INFO, "\n***\nKilling the Requesting Client, hopefully before it receives response\n***\n");
725 do_shutdown (&peer2, NULL);
726 GNUNET_TESTBED_peer_stop (peer2.peer, &peer_stop_callback, NULL);
727}
728
729
730/**
731 * Adapter function called to destroy a connection to
732 * a service. This function is called when GNUNET_TESTBED_operation_done is
733 * called for peer->op, which holds the handle for GNUNET_TESTBED_service_connect
734 * operation.
735 *
736 * @param cls closure
737 * @param op_result service handle returned from the connect adapter
738 */
739static void
740vectorproduct_da (void *cls, void *op_result)
741{
742 struct PeerData* peer = (struct PeerData*) cls;
743
744 GNUNET_VECTORPRODUCT_disconnect (peer->vh);
745 return;
746}
747
748
749/**
750 * Adapter function called to establish a connection to
751 * a service. This function is called to by GNUNET_TESTBED_service_connect.
752 *
753 * @param cls closure
754 * @param cfg configuration of the peer to connect to; will be available until
755 * GNUNET_TESTBED_operation_done() is called on the operation returned
756 * from GNUNET_TESTBED_service_connect()
757 * @return service handle to return in 'op_result', NULL on error
758 */
759static void *
760vectorproduct_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
761{
762 struct PeerData *p = cls;
763
764 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') started\n", (&peer1 == p) ? 1 : 2,
765 GNUNET_i2s (&p->our_id));
766
767 switch (setup_state)
768 {
769 case PEER1_VECTORPRODUCT_CONNECT:
770 /* Connect peer 2 to vectorproduct service */
771 /* The connect adapter vectorproduct_ca will be called to perform the actual connection */
772 {
773 peer2.op = GNUNET_TESTBED_service_connect (&peer2, peer2.peer, "vectorproduct",
774 NULL, NULL, vectorproduct_ca,
775 vectorproduct_da, &peer2);
776 setup_state = PEER2_VECTORPRODUCT_CONNECT;
777 }
778
779 /* Actually connect peer 1 to vectorproduct service */
780 peer1.vh = GNUNET_VECTORPRODUCT_connect (cfg);
781 return peer1.vh;
782
783 case PEER2_VECTORPRODUCT_CONNECT:
784 /* Actually connect peer 2 to vectorproduct service */
785 peer2.vh = GNUNET_VECTORPRODUCT_connect (cfg);
786
787
788 if (peer1.vh != NULL && peer2.vh != NULL)
789 {
790 GNUNET_SCHEDULER_add_now (&prepare_response_task, &peer1);
791 GNUNET_SCHEDULER_add_now (&request_task, &peer2);
792 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 6),
793 &destroy_server, NULL);
794 }
795 else
796 {
797 // TODO : Handle error. One of the peers is not connected. Cleanly shutdown
798 ok = -1;
799 return NULL;
800 }
801 return peer2.vh;
802 default:
803 GNUNET_assert (0);
804 }
805}
806
807
808/**
809 * Callback to be called when the requested peer information is available
810 *
811 * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information()
812 * @param op the operation this callback corresponds to
813 * @param pinfo the result; will be NULL if the operation has failed
814 * @param emsg error message if the operation has failed; will be NULL if the
815 * operation is successfull
816 */
817static void
818peerinfo_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op_,
819 const struct GNUNET_TESTBED_PeerInformation *pinfo,
820 const char *emsg)
821{
822 GNUNET_assert (NULL == emsg);
823 GNUNET_assert (op == op_);
824 switch (setup_state)
825 {
826 case PEER1_GET_IDENTITY:
827 {
828 memcpy (&peer1.our_id, pinfo->result.id,
829 sizeof (struct GNUNET_PeerIdentity));
830 GNUNET_TESTBED_operation_done (op);
831
832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 1 id: %s\n", GNUNET_i2s_full
833 (&peer1.our_id));
834
835 /* Request for peer id of peer 2*/
836 op = GNUNET_TESTBED_peer_get_information (peer2.peer,
837 GNUNET_TESTBED_PIT_IDENTITY,
838 &peerinfo_cb, NULL);
839 setup_state = PEER2_GET_IDENTITY;
840 }
841 break;
842 case PEER2_GET_IDENTITY:
843 {
844 memcpy (&peer2.our_id, pinfo->result.id,
845 sizeof (struct GNUNET_PeerIdentity));
846 GNUNET_TESTBED_operation_done (op);
847
848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 2 id: %s\n", GNUNET_i2s_full
849 (&peer2.our_id));
850
851 /* Connect peer 1 to vectorproduct service */
852 /* The connect adapter vectorproduct_ca will be called to perform the actual connection */
853 peer1.op = GNUNET_TESTBED_service_connect (&peer1, peer1.peer, "vectorproduct",
854 NULL, NULL, vectorproduct_ca,
855 vectorproduct_da, &peer1);
856 setup_state = PEER1_VECTORPRODUCT_CONNECT;
857 }
858 break;
859 default:
860 GNUNET_assert (0);
861 }
862}
863
864
865/**
866 * Signature of a main function for a testcase.
867 *
868 * @param cls closure
869 * @param num_peers number of peers in 'peers'
870 * @param peers handle to peers run in the testbed
871 */
872static void
873test_master (void *cls, unsigned int num_peers,
874 struct GNUNET_TESTBED_Peer **peers)
875{
876 GNUNET_assert (NULL != peers);
877 GNUNET_assert (NULL != peers[0]);
878 GNUNET_assert (NULL != peers[1]);
879 peer1.peer = peers[0];
880 peer2.peer = peers[1];
881 /* Get the peer identity and configuration of peer 1 */
882 op = GNUNET_TESTBED_peer_get_information (peer1.peer,
883 GNUNET_TESTBED_PIT_IDENTITY,
884 &peerinfo_cb, NULL);
885 setup_state = PEER1_GET_IDENTITY;
886 abort_task =
887 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
888 (GNUNET_TIME_UNIT_SECONDS, 20), &do_abort,
889 NULL);
890}
891
892
893/**
894 * Main function
895 */
896int
897main (int argc, char **argv)
898{
899 uint64_t event_mask;
900
901 ok = GNUNET_NO;
902 event_mask = 0;
903 event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED);
904 max_mids = (GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_MessageHeader))
905 / sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1;
906
907 (void) GNUNET_TESTBED_test_run ("test_vectorproduct_api_regression2",
908 "test_vectorproduct_api_data.conf",
909 NUM_PEERS, event_mask, &controller_event_cb,
910 NULL,
911 &test_master, NULL);
912 if (GNUNET_SYSERR == ok)
913 {
914 LOG (GNUNET_ERROR_TYPE_ERROR, "Test failing due to some error before calling API for request or prepare_response\n");
915 return 1;
916 }
917 else if (GNUNET_SYSERR == responder_ok)
918 {
919 LOG (GNUNET_ERROR_TYPE_ERROR, "Test failing due to some error in response for responding_client\n");
920 return 1;
921 }
922 else if (GNUNET_SYSERR == requester_ok)
923 {
924 LOG (GNUNET_ERROR_TYPE_ERROR, "Test failing due to some error in response for requesting client\n");
925 return 1;
926 }
927 else
928 return 0;
929}
930
931