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