remvod verbose debugging in stream api; fixed warning in stream_big test case
[oweals/gnunet.git] / src / stream / test_stream_2peers_halfclose.c
1 /*
2      This file is part of GNUnet.
3      (C) 2011, 2012 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 stream/test_stream_2peers_halfclose.c
23  * @brief Testcases for Stream API halfclosed connections between 2 peers
24  * @author Sree Harsha Totakura
25  */
26
27 #include <string.h>
28
29 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_mesh_service.h"
32 #include "gnunet_stream_lib.h"
33 #include "gnunet_testing_lib.h"
34 #include "gnunet_scheduler_lib.h"
35
36 #define VERBOSE 1
37
38 /**
39  * Number of peers
40  */
41 #define NUM_PEERS 2
42
43 /**
44  * Structure for holding peer's sockets and IO Handles
45  */
46 struct PeerData
47 {
48   /**
49    * Peer's stream socket
50    */
51   struct GNUNET_STREAM_Socket *socket;
52
53   /**
54    * Peer's io write handle
55    */
56   struct GNUNET_STREAM_IOWriteHandle *io_write_handle;
57
58   /**
59    * Peer's io read handle
60    */
61   struct GNUNET_STREAM_IOReadHandle *io_read_handle;
62
63   /**
64    * Peer's shutdown handle
65    */
66   struct GNUNET_STREAM_ShutdownHandle *shutdown_handle;
67
68   /**
69    * Our Peer id
70    */
71   struct GNUNET_PeerIdentity our_id;
72
73   /**
74    * Bytes the peer has written
75    */
76   unsigned int bytes_wrote;
77
78   /**
79    * Byte the peer has read
80    */
81   unsigned int bytes_read;
82
83   /**
84    * GNUNET_YES if the peer has successfully completed the current test
85    */
86   unsigned int test_ok;
87
88   /**
89    * The shutdown operation that has to be used by the stream_shutdown_task
90    */
91   int shutdown_operation;
92 };
93
94 /**
95  * The current peer group
96  */
97 static struct GNUNET_TESTING_PeerGroup *pg;
98
99 /**
100  * Peer 1 daemon
101  */
102 static struct GNUNET_TESTING_Daemon *d1;
103
104 /**
105  * Peer 2 daemon
106  */
107 static struct GNUNET_TESTING_Daemon *d2;
108
109
110 /**
111  * Peer1 writes first and then calls for SHUT_WR
112  * Peer2 reads first and then calls for SHUT_RD
113  * Attempt to write again by Peer1 should be rejected
114  * Attempt to read again by Peer2 should be rejected
115  * Peer1 then reads from Peer2 which writes
116  */
117 static struct PeerData peer1;
118 static struct PeerData peer2;
119 static struct GNUNET_STREAM_ListenSocket *peer2_listen_socket;
120 static struct GNUNET_CONFIGURATION_Handle *config;
121
122 static GNUNET_SCHEDULER_TaskIdentifier abort_task;
123 static GNUNET_SCHEDULER_TaskIdentifier read_task;
124
125 static char *data = "ABCD";
126 static int result;
127
128 /**
129  * Enumeration for various tests that are to be passed in the same order as
130  * below
131  */
132 enum Test
133   {
134     /**
135      * Peer1 writing; Peer2 reading
136      */
137     PEER1_WRITE,
138
139     /**
140      * Peer1 write shutdown; Peer2 should get an error when it tries to read;
141      */
142     PEER1_WRITE_SHUTDOWN,
143
144     /**
145      * Peer1 reads; Peer2 writes (connection is halfclosed)
146      */
147     PEER1_HALFCLOSE_READ,
148
149     /**
150      * Peer1 attempts to write; Should fail with stream already shutdown error
151      */
152     PEER1_HALFCLOSE_WRITE_FAIL,
153
154     /**
155      * Peer1 read shutdown; Peer2 should get stream shutdown error during write
156      */
157     PEER1_READ_SHUTDOWN,
158
159     /**
160      * All tests successfully finished
161      */
162     SUCCESS
163   };
164
165 /**
166  * Current running test
167  */
168 enum Test current_test;
169
170 /**
171  * Input processor
172  *
173  * @param cls the closure from GNUNET_STREAM_write/read
174  * @param status the status of the stream at the time this function is called
175  * @param data traffic from the other side
176  * @param size the number of bytes available in data read 
177  * @return number of bytes of processed from 'data' (any data remaining should be
178  *         given to the next time the read processor is called).
179  */
180 static size_t
181 input_processor (void *cls,
182                  enum GNUNET_STREAM_Status status,
183                  const void *input_data,
184                  size_t size);
185
186
187 /**
188  * The transition function; responsible for the transitions among tests
189  */
190 static void
191 transition();
192
193
194 /**
195  * Task for calling STREAM_read
196  *
197  * @param cls the peer data entity
198  * @param tc the task context
199  */
200 static void
201 stream_read_task (void *cls,
202                   const struct GNUNET_SCHEDULER_TaskContext *tc)
203 {
204   struct PeerData *peer = cls;
205   
206   peer->io_read_handle = GNUNET_STREAM_read (peer->socket,
207                                              GNUNET_TIME_relative_multiply
208                                              (GNUNET_TIME_UNIT_SECONDS, 5),
209                                              &input_processor,
210                                              cls);
211   switch (current_test)
212     {
213     case PEER1_WRITE_SHUTDOWN:
214       GNUNET_assert (&peer2 == peer);
215       GNUNET_assert (NULL == peer->io_read_handle);
216       transition ();            /* to PEER1_HALFCLOSE_READ */
217       break;
218     default:
219       GNUNET_assert (NULL != peer->io_read_handle);
220     }
221 }
222
223
224 /**
225  * The write completion function; called upon writing some data to stream or
226  * upon error
227  *
228  * @param cls the closure from GNUNET_STREAM_write/read
229  * @param status the status of the stream at the time this function is called
230  * @param size the number of bytes read or written
231  */
232 static void 
233 write_completion (void *cls,
234                   enum GNUNET_STREAM_Status status,
235                   size_t size);
236
237
238 /**
239  * Task for calling STREAM_write
240  *
241  * @param cls the peer data entity
242  * @param tc the task context
243  */
244 static void
245 stream_write_task (void *cls,
246                    const struct GNUNET_SCHEDULER_TaskContext *tc)
247 {
248   struct PeerData *peer = cls;
249   
250   peer->io_write_handle = 
251     GNUNET_STREAM_write (peer->socket,
252                          (void *) data,
253                          strlen(data) - peer->bytes_wrote,
254                          GNUNET_TIME_relative_multiply
255                          (GNUNET_TIME_UNIT_SECONDS, 5),
256                          &write_completion,
257                          peer);
258   switch (current_test)
259     {
260     case PEER1_HALFCLOSE_WRITE_FAIL:
261       GNUNET_assert (&peer1 == peer);
262       GNUNET_assert (NULL == peer->io_write_handle);
263       transition();             /* To PEER1_READ_SHUTDOWN */
264       break;
265     case PEER1_READ_SHUTDOWN:
266       GNUNET_assert (&peer2 == peer);
267       GNUNET_assert (NULL == peer->io_write_handle);
268       transition ();            /* To SUCCESS */
269       break;
270     default:
271         GNUNET_assert (NULL != peer->io_write_handle);
272     }
273 }
274
275
276 /**
277  * Check whether peers successfully shut down.
278  */
279 static void
280 peergroup_shutdown_callback (void *cls, const char *emsg)
281 {
282   if (emsg != NULL)
283   {
284     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
285                 "Shutdown of peers failed!\n");
286   }
287   else
288   {
289     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
290                 "All peers successfully shut down!\n");
291   }
292   GNUNET_CONFIGURATION_destroy (config);
293 }
294
295
296 /**
297  * Close sockets and stop testing deamons nicely
298  */
299 static void
300 do_close (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
301 {
302   if (NULL != peer1.socket)
303     GNUNET_STREAM_close (peer1.socket);
304   if (NULL != peer2.socket)
305     GNUNET_STREAM_close (peer2.socket);
306   if (NULL != peer2_listen_socket)
307     GNUNET_STREAM_listen_close (peer2_listen_socket);
308
309   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n");
310   if (0 != abort_task)
311   {
312     GNUNET_SCHEDULER_cancel (abort_task);
313   }
314
315   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Wait\n");
316
317   GNUNET_TESTING_daemons_stop (pg,
318                                GNUNET_TIME_relative_multiply
319                                (GNUNET_TIME_UNIT_SECONDS, 5),
320                                &peergroup_shutdown_callback,
321                                NULL);
322 }
323
324
325 /**
326  * Completion callback for shutdown
327  *
328  * @param cls the closure from GNUNET_STREAM_shutdown call
329  * @param operation the operation that was shutdown (SHUT_RD, SHUT_WR,
330  *          SHUT_RDWR) 
331  */
332 void 
333 shutdown_completion (void *cls,
334                      int operation)
335 {
336   switch (current_test)
337     {
338     case PEER1_WRITE:
339       GNUNET_assert (0);
340     case PEER1_WRITE_SHUTDOWN:
341       GNUNET_assert (cls == &peer1);
342       GNUNET_assert (SHUT_WR == operation);
343       peer1.test_ok = GNUNET_YES;
344       /* Peer2 should read with error */
345       peer2.bytes_read = 0;
346       GNUNET_SCHEDULER_add_now (&stream_read_task, &peer2);
347       break;
348     case PEER1_READ_SHUTDOWN:
349       peer1.test_ok = GNUNET_YES;
350       peer2.bytes_wrote = 0;
351       GNUNET_SCHEDULER_add_now (&stream_write_task, &peer2);
352       break;
353     case PEER1_HALFCLOSE_READ:
354     case PEER1_HALFCLOSE_WRITE_FAIL:
355     case SUCCESS:
356       GNUNET_assert (0);        /* We shouldn't reach here */
357     }
358 }
359
360
361 /**
362  * Task for calling STREAM_shutdown
363  *
364  * @param cls the peer entity
365  * @param tc the TaskContext
366  */
367 static void
368 stream_shutdown_task (void *cls,
369                       const struct GNUNET_SCHEDULER_TaskContext *tc)
370 {
371   struct PeerData *peer = cls;
372
373   peer->shutdown_handle = GNUNET_STREAM_shutdown (peer->socket,
374                                                   peer->shutdown_operation,
375                                                   &shutdown_completion,
376                                                   peer);
377   GNUNET_assert (NULL != peer->shutdown_handle);
378 }
379
380
381 /**
382  * Something went wrong and timed out. Kill everything and set error flag
383  */
384 static void
385 do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
386 {
387   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: ABORT\n");
388   if (0 != read_task)
389     {
390       GNUNET_SCHEDULER_cancel (read_task);
391     }
392   result = GNUNET_SYSERR;
393   abort_task = 0;
394   do_close (cls, tc);  
395 }
396
397
398 /**
399  * The transition function; responsible for the transitions among tests
400  */
401 static void
402 transition()
403 {
404   if ((GNUNET_YES == peer1.test_ok) && (GNUNET_YES == peer2.test_ok))
405     {
406       peer1.test_ok = GNUNET_NO;
407       peer2.test_ok = GNUNET_NO;
408       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
409                   "TEST %d SUCCESSFULL\n", current_test);
410       switch (current_test)
411         {
412         case PEER1_WRITE:
413           current_test = PEER1_WRITE_SHUTDOWN;
414           /* Peer1 should shutdown writing */
415           peer1.shutdown_operation = SHUT_WR;
416           GNUNET_SCHEDULER_add_now (&stream_shutdown_task, &peer1);
417           break;
418         case PEER1_WRITE_SHUTDOWN:
419           current_test = PEER1_HALFCLOSE_READ;
420           /* Peer2 should be able to write successfully */
421           peer2.bytes_wrote = 0;
422           GNUNET_SCHEDULER_add_now (&stream_write_task, &peer2);
423           
424           /* Peer1 should be able to read successfully */
425           peer1.bytes_read = 0;
426           GNUNET_SCHEDULER_add_now (&stream_read_task, &peer1);
427           break;
428         case PEER1_HALFCLOSE_READ:
429           current_test = PEER1_HALFCLOSE_WRITE_FAIL;
430           peer1.bytes_wrote = 0;
431           peer2.bytes_read = 0;
432           peer2.test_ok = GNUNET_YES;
433           GNUNET_SCHEDULER_add_now (&stream_write_task, &peer1);
434           break;
435         case PEER1_HALFCLOSE_WRITE_FAIL:
436           current_test = PEER1_READ_SHUTDOWN;
437           peer1.shutdown_operation = SHUT_RD;
438           GNUNET_SCHEDULER_add_now (&stream_shutdown_task, &peer1);
439           break;
440         case PEER1_READ_SHUTDOWN:
441           current_test = SUCCESS;
442           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
443                       "All tests successful\n");
444           GNUNET_SCHEDULER_add_now (&do_close, NULL);
445           break;
446         case SUCCESS:
447           GNUNET_assert (0);    /* We shouldn't reach here */
448           
449         }
450     }
451 }
452
453 /**
454  * The write completion function; called upon writing some data to stream or
455  * upon error
456  *
457  * @param cls the closure from GNUNET_STREAM_write/read
458  * @param status the status of the stream at the time this function is called
459  * @param size the number of bytes read or written
460  */
461 static void 
462 write_completion (void *cls,
463                   enum GNUNET_STREAM_Status status,
464                   size_t size)
465 {
466   struct PeerData *peer = cls;
467
468   switch (current_test)
469     {
470     case PEER1_WRITE:
471     case PEER1_HALFCLOSE_READ:
472
473     GNUNET_assert (GNUNET_STREAM_OK == status);
474     GNUNET_assert (size <= strlen (data));
475     peer->bytes_wrote += size;
476
477     if (peer->bytes_wrote < strlen(data)) /* Have more data to send */
478       {
479         GNUNET_SCHEDULER_add_now (&stream_write_task, peer);
480       }
481     else
482       {
483         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
484                     "Writing completed\n");
485
486         if (&peer1 == peer)
487           {
488             peer1.test_ok = GNUNET_YES;
489             transition ();       /* to PEER1_WRITE_SHUTDOWN */
490           }
491         else            /* This will happen during PEER1_HALFCLOSE_READ */
492           {
493             peer2.test_ok = GNUNET_YES;
494             transition ();      /* to PEER1_HALFCLOSE_WRITE_FAIL */
495           }
496       }
497     break;
498     case PEER1_HALFCLOSE_WRITE_FAIL:
499       GNUNET_assert (peer == &peer1);
500       GNUNET_assert (GNUNET_STREAM_SHUTDOWN == status);
501       GNUNET_assert (0 == size);
502       peer1.test_ok = GNUNET_YES;
503       break;
504     case PEER1_READ_SHUTDOWN:
505       GNUNET_assert (peer == &peer2);
506       GNUNET_assert (GNUNET_STREAM_SHUTDOWN == status);
507       GNUNET_assert (0 == size);
508       peer2.test_ok = GNUNET_YES;
509       break;
510     case PEER1_WRITE_SHUTDOWN:
511     case SUCCESS:
512       GNUNET_assert (0);        /* We shouldn't reach here */
513     } 
514 }
515
516
517 /**
518  * Function executed after stream has been established
519  *
520  * @param cls the closure from GNUNET_STREAM_open
521  * @param socket socket to use to communicate with the other side (read/write)
522  */
523 static void 
524 stream_open_cb (void *cls,
525                 struct GNUNET_STREAM_Socket *socket)
526 {
527   struct PeerData *peer;
528
529   GNUNET_assert (socket == peer1.socket);
530   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
531               "%s: Stream established from peer1\n",
532               GNUNET_i2s (&peer1.our_id));
533   peer = (struct PeerData *) cls;
534   peer->bytes_wrote = 0;
535   GNUNET_assert (socket == peer1.socket);
536   GNUNET_assert (socket == peer->socket);
537   peer1.test_ok = GNUNET_NO;
538   peer2.test_ok = GNUNET_NO;
539   current_test = PEER1_WRITE;
540   GNUNET_SCHEDULER_add_now (&stream_write_task, peer);
541 }
542
543
544 /**
545  * Input processor
546  *
547  * @param cls the closure from GNUNET_STREAM_write/read
548  * @param status the status of the stream at the time this function is called
549  * @param data traffic from the other side
550  * @param size the number of bytes available in data read 
551  * @return number of bytes of processed from 'data' (any data remaining should be
552  *         given to the next time the read processor is called).
553  */
554 static size_t
555 input_processor (void *cls,
556                  enum GNUNET_STREAM_Status status,
557                  const void *input_data,
558                  size_t size)
559 {
560   struct PeerData *peer;
561
562   peer = (struct PeerData *) cls;
563
564   switch (current_test)
565     {
566     case PEER1_WRITE:
567     case PEER1_HALFCLOSE_READ:
568       if (GNUNET_STREAM_TIMEOUT == status)
569         {
570           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
571                       "Read operation timedout - reading again!\n");
572           GNUNET_assert (0 == size);
573           GNUNET_SCHEDULER_add_now (&stream_read_task, peer);
574           return 0;
575         }
576
577       GNUNET_assert (GNUNET_STREAM_OK == status);
578       GNUNET_assert (size <= strlen (data));
579       GNUNET_assert (0 == strncmp ((const char *) data + peer->bytes_read,
580                                    (const char *) input_data,
581                                    size));
582       peer->bytes_read += size;
583   
584       if (peer->bytes_read < strlen (data))
585         {
586           GNUNET_SCHEDULER_add_now (&stream_read_task, peer);
587         }
588       else  
589         {
590           if (&peer2 == peer) /* Peer2 has completed reading; should write */
591             {
592               peer2.test_ok = GNUNET_YES;
593               transition ();    /* Transition to PEER1_WRITE_SHUTDOWN */
594             }
595           else         /* Peer1 has completed reading. End of tests */
596             {
597               peer1.test_ok = GNUNET_YES;
598               transition ();    /* to PEER1_HALFCLOSE_WRITE_FAIL */
599             }
600         }
601       break;
602     case PEER1_WRITE_SHUTDOWN:
603       GNUNET_assert (GNUNET_STREAM_SHUTDOWN == status);
604       peer2.test_ok = GNUNET_YES;
605       break;
606     case PEER1_HALFCLOSE_WRITE_FAIL:
607     case PEER1_READ_SHUTDOWN:
608     case SUCCESS:
609       GNUNET_assert (0);        /* We shouldn't reach here */
610     }
611   
612   return size;
613 }
614
615   
616 /**
617  * Scheduler call back; to be executed when a new stream is connected
618  * Called from listen connect for peer2
619  */
620 static void
621 stream_read (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
622 {
623   read_task = GNUNET_SCHEDULER_NO_TASK;
624   GNUNET_assert (NULL != cls);
625   peer2.bytes_read = 0;
626   GNUNET_SCHEDULER_add_now (&stream_read_task, &peer2);
627 }
628
629
630 /**
631  * Functions of this type are called upon new stream connection from other peers
632  *
633  * @param cls the closure from GNUNET_STREAM_listen
634  * @param socket the socket representing the stream
635  * @param initiator the identity of the peer who wants to establish a stream
636  *            with us
637  * @return GNUNET_OK to keep the socket open, GNUNET_SYSERR to close the
638  *             stream (the socket will be invalid after the call)
639  */
640 static int
641 stream_listen_cb (void *cls,
642                   struct GNUNET_STREAM_Socket *socket,
643                   const struct GNUNET_PeerIdentity *initiator)
644 {
645   GNUNET_assert (NULL != socket);
646   GNUNET_assert (NULL != initiator);
647   GNUNET_assert (socket != peer1.socket);
648
649   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
650               "%s: Peer connected: %s\n",
651               GNUNET_i2s (&peer2.our_id),
652               GNUNET_i2s(initiator));
653
654   peer2.socket = socket;
655   /* FIXME: reading should be done right now instead of a scheduled call */
656   read_task = GNUNET_SCHEDULER_add_now (&stream_read, (void *) socket);
657   return GNUNET_OK;
658 }
659
660
661 /**
662  * Callback to be called when testing peer group is ready
663  *
664  * @param cls NULL
665  * @param emsg NULL on success
666  */
667 void
668 peergroup_ready (void *cls, const char *emsg)
669 {
670   if (NULL != emsg)
671     {
672       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
673                   "Starting peer group failed: %s\n", emsg);
674       return;
675     }
676   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
677               "Peer group is now ready\n");
678   
679   GNUNET_assert (2 == GNUNET_TESTING_daemons_running (pg));
680   
681   d1 = GNUNET_TESTING_daemon_get (pg, 0);
682   GNUNET_assert (NULL != d1);
683   
684   d2 = GNUNET_TESTING_daemon_get (pg, 1);
685   GNUNET_assert (NULL != d2);
686
687   GNUNET_TESTING_get_peer_identity (d1->cfg,
688                                     &peer1.our_id);
689   GNUNET_TESTING_get_peer_identity (d2->cfg,
690                                     &peer2.our_id);
691   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
692               "%s : %s\n",
693               GNUNET_i2s (&peer1.our_id),
694               GNUNET_i2s (&d1->id));
695   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
696               "%s : %s\n",
697               GNUNET_i2s (&peer2.our_id),
698               GNUNET_i2s (&d2->id));
699
700   peer2_listen_socket = GNUNET_STREAM_listen (d2->cfg,
701                                               10, /* App port */
702                                               &stream_listen_cb,
703                                               NULL);
704   GNUNET_assert (NULL != peer2_listen_socket);
705
706   /* Connect to stream library */
707   peer1.socket = GNUNET_STREAM_open (d1->cfg,
708                                      &d2->id,         /* Null for local peer? */
709                                      10,           /* App port */
710                                      &stream_open_cb,
711                                      &peer1,
712                                      GNUNET_STREAM_OPTION_END);
713   GNUNET_assert (NULL != peer1.socket);
714 }
715
716
717 /**
718  * Initialize framework and start test
719  */
720 static void
721 run (void *cls, char *const *args, const char *cfgfile,
722      const struct GNUNET_CONFIGURATION_Handle *cfg)
723 {
724   struct GNUNET_TESTING_Host *hosts; /* FIXME: free hosts (DLL) */
725
726   /* GNUNET_log_setup ("test_stream_local", */
727   /*                   "DEBUG", */
728   /*                   NULL); */
729
730   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
731               "Starting test\n");
732   /* Duplicate the configuration */
733   config = GNUNET_CONFIGURATION_dup (cfg);
734
735   hosts = GNUNET_TESTING_hosts_load (config);
736   
737   pg = GNUNET_TESTING_peergroup_start (config,
738                                        2,
739                                        GNUNET_TIME_relative_multiply
740                                        (GNUNET_TIME_UNIT_SECONDS, 3),
741                                        NULL,
742                                        &peergroup_ready,
743                                        NULL,
744                                        hosts);
745   GNUNET_assert (NULL != pg);
746                                        
747   abort_task =
748     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
749                                   (GNUNET_TIME_UNIT_SECONDS, 40), &do_abort,
750                                   NULL);
751 }
752
753 /**
754  * Main function
755  */
756 int main (int argc, char **argv)
757 {
758   int ret;
759
760   char *argv2[] = { "test-stream-2peers-halfclose",
761                     "-L", "DEBUG",
762                     "-c", "test_stream_local.conf",
763                     NULL};
764   
765   struct GNUNET_GETOPT_CommandLineOption options[] = {
766     GNUNET_GETOPT_OPTION_END
767   };
768
769   ret =
770       GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
771                           "test-stream-2peers-halfclose", "nohelp", options, &run, NULL);
772
773   if (GNUNET_OK != ret)
774   {
775     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n",
776                 ret);
777     return 1;
778   }
779   if (GNUNET_SYSERR == result)
780   {
781     GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test failed\n");
782     return 1;
783   }
784   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test ok\n");
785   return 0;
786 }