3614fa0d7ec69c91f05cceabbd03ffc934f27ceb
[oweals/gnunet.git] / src / transport / test_quota_compliance.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010 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  * @file transport/test_quota_compliance.c
22  * @brief base test case for transport implementations
23  *
24  * This test case tests quota compliance both on core and transport level
25  */
26 #include "platform.h"
27 #include "gnunet_common.h"
28 #include "gnunet_hello_lib.h"
29 #include "gnunet_getopt_lib.h"
30 #include "gnunet_os_lib.h"
31 #include "gnunet_program_lib.h"
32 #include "gnunet_scheduler_lib.h"
33 #include "gnunet_server_lib.h"
34 #include "gnunet_transport_service.h"
35 #include "transport.h"
36
37 #define VERBOSE GNUNET_YES
38
39 #define VERBOSE_ARM GNUNET_NO
40
41 #define START_ARM GNUNET_YES
42 #define DEBUG_MEASUREMENT GNUNET_NO
43 #define DEBUG_CONNECTIONS GNUNET_NO
44
45 #define MEASUREMENT_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
46 #define MEASUREMENT_MSG_SIZE 10000
47 #define MEASUREMENT_MSG_SIZE_BIG 32768
48 #define MEASUREMENT_MAX_QUOTA 1024 * 1024 * 1024
49 #define MEASUREMENT_MIN_QUOTA 1024 * 10
50 #define SEND_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 35)
51 /**
52  * Testcase timeout
53  */
54 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 200)
55
56
57
58 #define MTYPE 11111
59
60 struct PeerContext
61 {
62   struct GNUNET_CONFIGURATION_Handle *cfg;
63   struct GNUNET_TRANSPORT_Handle *th;
64   struct GNUNET_PeerIdentity id;
65 #if START_ARM
66   pid_t arm_pid;
67 #endif
68 };
69
70 /**
71  * Handle for a transmission-ready request.
72  */
73 struct GNUNET_TRANSPORT_TransmitHandle
74 {
75
76   /**
77    * Neighbour for this handle, NULL for control-traffic.
78    */
79   struct NeighbourList *neighbour;
80
81   /**
82    * Function to call when notify_size bytes are available
83    * for transmission.
84    */
85   GNUNET_CONNECTION_TransmitReadyNotify notify;
86
87   /**
88    * Closure for notify.
89    */
90   void *notify_cls;
91
92   /**
93    * transmit_ready task Id.  The task is used to introduce the
94    * artificial delay that may be required to maintain the bandwidth
95    * limits.  Later, this will be the ID of the "transmit_timeout"
96    * task which is used to signal a timeout if the transmission could
97    * not be done in a timely fashion.
98    */
99   GNUNET_SCHEDULER_TaskIdentifier notify_delay_task;
100
101   /**
102    * Timeout for this request.
103    */
104   struct GNUNET_TIME_Absolute timeout;
105
106   /**
107    * How many bytes is our notify callback waiting for?
108    */
109   size_t notify_size;
110
111   /**
112    * How important is this message?
113    */
114   unsigned int priority;
115
116 };
117
118 static struct PeerContext p1;
119
120 static struct PeerContext p2;
121
122 static struct GNUNET_SCHEDULER_Handle *sched;
123
124 static int ok;
125
126 static int connected;
127 static int measurement_running;
128 static int send_running;
129 static int recv_running;
130
131 static unsigned long long total_bytes;
132 static unsigned long long current_quota_p1;
133 static unsigned long long current_quota_p2;
134
135 static int is_tcp;
136 static int is_tcp_nat;
137 static int is_http;
138 static int is_https;
139 static int is_udp;
140 static int is_asymmetric_send_constant;
141 static int is_asymmetric_recv_constant;
142
143 static struct GNUNET_TIME_Absolute start_time;
144
145 static GNUNET_SCHEDULER_TaskIdentifier die_task;
146 static GNUNET_SCHEDULER_TaskIdentifier measurement_task;
147 static GNUNET_SCHEDULER_TaskIdentifier measurement_counter_task;
148
149 struct GNUNET_TRANSPORT_TransmitHandle * transmit_handle;
150
151 #if VERBOSE
152 #define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
153 #else
154 #define OKPP do { ok++; } while (0)
155 #endif
156
157
158
159 static void
160 end_send ()
161 {
162
163 }
164
165 static void
166 end ()
167 {
168   GNUNET_SCHEDULER_cancel (sched, die_task);
169   die_task = GNUNET_SCHEDULER_NO_TASK;
170
171   if (measurement_task != GNUNET_SCHEDULER_NO_TASK)
172   {
173             GNUNET_SCHEDULER_cancel (sched, measurement_task);
174             measurement_task = GNUNET_SCHEDULER_NO_TASK;
175   }
176   if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
177   {
178             GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
179             measurement_counter_task = GNUNET_SCHEDULER_NO_TASK;
180   }
181   GNUNET_SCHEDULER_shutdown (sched);
182 #if DEBUG_CONNECTIONS
183   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transports!\n");
184 #endif
185   GNUNET_TRANSPORT_disconnect (p1.th);
186   GNUNET_TRANSPORT_disconnect (p2.th);
187 #if DEBUG_CONNECTIONS
188   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
189               "Transports disconnected, returning success!\n");
190 #endif
191   GNUNET_SCHEDULER_shutdown (sched);
192 }
193
194
195
196 static void
197 stop_arm (struct PeerContext *p)
198 {
199 #if START_ARM
200   if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
201     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
202   GNUNET_OS_process_wait (p->arm_pid);
203 #endif
204   GNUNET_CONFIGURATION_destroy (p->cfg);
205 }
206
207
208 static void
209 end_badly (void *cls,
210            const struct GNUNET_SCHEDULER_TaskContext *tc)
211 {
212   if (measurement_task != GNUNET_SCHEDULER_NO_TASK)
213   {
214             GNUNET_SCHEDULER_cancel (sched, measurement_task);
215             measurement_task = GNUNET_SCHEDULER_NO_TASK;
216   }
217   if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
218   {
219             GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
220             measurement_counter_task = GNUNET_SCHEDULER_NO_TASK;
221   }
222   GNUNET_break (0);
223   if (p1.th != NULL)
224           GNUNET_TRANSPORT_disconnect (p1.th);
225   if (p2.th != NULL)
226           GNUNET_TRANSPORT_disconnect (p2.th);
227   ok = 1;
228 }
229
230 struct TestMessage
231 {
232   struct GNUNET_MessageHeader header;
233   uint32_t num;
234 };
235
236 static unsigned int
237 get_size (unsigned int iter)
238 {
239   return MEASUREMENT_MSG_SIZE + sizeof (struct TestMessage);
240 }
241
242 static void
243 notify_receive_new (void *cls,
244                 const struct GNUNET_PeerIdentity *peer,
245                 const struct GNUNET_MessageHeader *message,
246                 struct GNUNET_TIME_Relative latency,
247                 uint32_t distance)
248 {
249   static int n;
250   unsigned int s;
251   const struct TestMessage *hdr;
252
253   hdr = (const struct TestMessage*) message;
254   s = get_size (n);
255   if (measurement_running == GNUNET_NO)
256           return;
257   if (MTYPE != ntohs (message->type))
258     return;
259 #if DEBUG_MEASUREMENT
260   if (ntohl(hdr->num) % 5000 == 0)
261     {
262       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
263                   "Got message %u of size %u\n",
264                   ntohl (hdr->num),
265                   ntohs (message->size));
266     }
267 #endif
268   n++;
269 }
270
271 static size_t
272 notify_ready_new (void *cls, size_t size, void *buf)
273 {
274   static int n;
275   char *cbuf = buf;
276   struct TestMessage hdr;
277   unsigned int s;
278   unsigned int ret;
279
280   transmit_handle = NULL;
281
282   if (measurement_task == GNUNET_SCHEDULER_NO_TASK)
283           return 0;
284
285   if (buf == NULL)
286     {
287       ok = 42;
288       return 0;
289     }
290
291   if (measurement_running != GNUNET_YES)
292   {
293           send_running = GNUNET_NO;
294           end_send();
295           return 0;
296   }
297
298   send_running = GNUNET_YES;
299   ret = 0;
300   s = get_size (n);
301   GNUNET_assert (size >= s);
302   GNUNET_assert (buf != NULL);
303   cbuf = buf;
304   do
305     {
306       hdr.header.size = htons (s);
307       hdr.header.type = htons (MTYPE);
308       hdr.num = htonl (n);
309       memcpy (&cbuf[ret], &hdr, sizeof (struct TestMessage));
310       ret += sizeof (struct TestMessage);
311       memset (&cbuf[ret], n, s - sizeof (struct TestMessage));
312       ret += s - sizeof (struct TestMessage);
313 #if DEBUG_MEASUREMENT
314       if (n % 5000 == 0)
315        {
316           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
317                       "Sending message %u\n",n);
318        }
319 #endif
320       n++;
321       s = get_size (n);
322       if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16))
323         break; /* sometimes pack buffer full, sometimes not */
324     }
325   while (size - ret >= s);
326   transmit_handle = GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
327                                             &p1.id,
328                                             s, 0, SEND_TIMEOUT,
329                                             &notify_ready_new,
330                                             NULL);
331   total_bytes += s;
332   return ret;
333 }
334
335 static void measure (unsigned long long quota_p1, unsigned long long quota_p2 );
336
337 static void measurement_counter
338  (void *cls,
339            const struct GNUNET_SCHEDULER_TaskContext *tc)
340 {
341   measurement_counter_task = GNUNET_SCHEDULER_NO_TASK;
342
343   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
344         return;
345
346 #if VERBOSE
347   fprintf(stderr,".");
348 #endif
349   measurement_counter_task = GNUNET_SCHEDULER_add_delayed (sched,
350                                                            GNUNET_TIME_UNIT_SECONDS,
351                                                            &measurement_counter,
352                                                            NULL);
353 }
354
355 static void
356 measurement_end (void *cls,
357            const struct GNUNET_SCHEDULER_TaskContext *tc)
358 {
359   measurement_task  = GNUNET_SCHEDULER_NO_TASK;
360   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
361         return;
362
363   measurement_running = GNUNET_NO;
364   struct GNUNET_TIME_Relative duration = GNUNET_TIME_absolute_get_difference(start_time, GNUNET_TIME_absolute_get());
365
366
367   if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
368   {
369     GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
370     measurement_counter_task = GNUNET_SCHEDULER_NO_TASK;
371   }
372 #if VERBOSE
373   fprintf(stderr,"\n");
374 #endif
375   /*
376   if (transmit_handle != NULL)
377   {
378           GNUNET_TRANSPORT_notify_transmit_ready_cancel(transmit_handle);
379           transmit_handle = NULL;
380   }
381   */
382   if ((total_bytes/(duration.rel_value / 1000)) > (current_quota_p1 + (current_quota_p1 / 10)))
383   {
384           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
385                           "\nQuota compliance failed: \n"\
386                           "Quota allowed: %10llu kB/s\n"\
387                           "Throughput   : %10llu kB/s\n", (current_quota_p1 / (1024)) , (total_bytes/(duration.rel_value / 1000)/1024));
388           ok = 1;
389 /*        end();
390           return;*/
391   }
392   else
393   {
394
395           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
396                           "\nQuota compliance ok: \n"\
397                           "Quota allowed: %10llu kB/s\n"\
398                           "Throughput   : %10llu kB/s\n", (current_quota_p1 / (1024)) , (total_bytes/(duration.rel_value / 1000)/1024));
399           ok = 0;
400   }
401
402   if ((current_quota_p1 < MEASUREMENT_MIN_QUOTA) || (current_quota_p2 < MEASUREMENT_MIN_QUOTA))
403   {
404           end();
405           return;
406   }
407   else
408   {
409 #if VERBOSE
410   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
411               "Scheduling next measurement\n");
412 #endif
413    if (is_asymmetric_send_constant == GNUNET_YES)
414            measure (current_quota_p1 / 10, MEASUREMENT_MAX_QUOTA);
415    else if (is_asymmetric_recv_constant == GNUNET_YES)
416            measure (MEASUREMENT_MAX_QUOTA, current_quota_p2 / 10);
417    else
418            measure (current_quota_p1 / 10, current_quota_p2 / 10);
419   }
420 }
421
422 static void measure (unsigned long long quota_p1, unsigned long long quota_p2 )
423 {
424           current_quota_p1 = quota_p1;
425           current_quota_p2 = quota_p2;
426 #if VERBOSE
427   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
428               "Starting transport level measurement for %u seconds and p1 quota %llu kB/s p2 quota %llu\n", MEASUREMENT_INTERVALL.rel_value / 1000 , current_quota_p1 / 1024, current_quota_p2 / 1024);
429 #endif
430                 GNUNET_TRANSPORT_set_quota (p1.th,
431                           &p2.id,
432                           GNUNET_BANDWIDTH_value_init (current_quota_p1 ),
433                           GNUNET_BANDWIDTH_value_init (current_quota_p1 ),
434                           GNUNET_TIME_UNIT_FOREVER_REL,
435                           NULL, NULL);
436                 GNUNET_TRANSPORT_set_quota (p2.th,
437                           &p1.id,
438                           GNUNET_BANDWIDTH_value_init (current_quota_p2),
439                           GNUNET_BANDWIDTH_value_init (current_quota_p2),
440                           GNUNET_TIME_UNIT_FOREVER_REL,
441                           NULL, NULL);
442
443                 GNUNET_SCHEDULER_cancel (sched, die_task);
444                 die_task = GNUNET_SCHEDULER_add_delayed (sched,
445                                                    TIMEOUT,
446                                                    &end_badly,
447                                                    NULL);
448                 if (measurement_counter_task != GNUNET_SCHEDULER_NO_TASK)
449                   GNUNET_SCHEDULER_cancel (sched, measurement_counter_task);
450                 measurement_counter_task = GNUNET_SCHEDULER_add_delayed (sched,
451                                                                    GNUNET_TIME_UNIT_SECONDS,
452                                                                    &measurement_counter,
453                                                                    NULL);
454                 measurement_task = GNUNET_SCHEDULER_add_delayed (sched,
455                                                    MEASUREMENT_INTERVALL,
456                                                    &measurement_end,
457                                                    NULL);
458                 total_bytes = 0;
459                 measurement_running = GNUNET_YES;
460                 start_time = GNUNET_TIME_absolute_get ();
461
462                 if (transmit_handle != NULL)
463                           GNUNET_TRANSPORT_notify_transmit_ready_cancel(transmit_handle);
464                 transmit_handle = GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
465                                                                                           &p1.id,
466                                                                                           get_size (0), 0, SEND_TIMEOUT,
467                                                                                           &notify_ready_new,
468                                                                                           NULL);
469 }
470
471 static void
472 notify_connect (void *cls,
473                 const struct GNUNET_PeerIdentity *peer,
474                 struct GNUNET_TIME_Relative latency,
475                 uint32_t distance)
476 {
477   if (cls == &p1)
478     {
479 #if DEBUG_CONNECTIONS
480   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
481               "Peer 1 `%4s' connected to us (%p)!\n", GNUNET_i2s (peer), cls);
482 #endif
483           connected++;
484     }
485   else
486     {
487 #if DEBUG_CONNECTIONS
488   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
489               "Peer 2 `%4s' connected to us (%p)!\n", GNUNET_i2s (peer), cls);
490 #endif
491       connected++;
492     }
493   if (connected == 2)
494     {
495           measure(MEASUREMENT_MAX_QUOTA,MEASUREMENT_MAX_QUOTA);
496     }
497 }
498
499
500 static void
501 notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
502 {
503 #if DEBUG_CONNECTIONS
504   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
505               "Peer `%4s' disconnected (%p)!\n",
506               GNUNET_i2s (peer), cls);
507 #endif
508 }
509
510
511 static void
512 setup_peer (struct PeerContext *p, const char *cfgname)
513 {
514   p->cfg = GNUNET_CONFIGURATION_create ();
515 #if START_ARM
516   p->arm_pid = GNUNET_OS_start_process (NULL, NULL,
517                                         "gnunet-service-arm",
518                                         "gnunet-service-arm",
519 #if VERBOSE_ARM
520                                         "-L", "DEBUG",
521 #endif
522                                         "-c", cfgname, NULL);
523 #endif
524
525   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
526   p->th = GNUNET_TRANSPORT_connect (sched, p->cfg, NULL,
527                                     p,
528                                     &notify_receive_new,
529                                     &notify_connect,
530                                     &notify_disconnect);
531   GNUNET_assert (p->th != NULL);
532 }
533
534
535 static void
536 exchange_hello_last (void *cls,
537                      const struct GNUNET_MessageHeader *message)
538 {
539   struct PeerContext *me = cls;
540
541   GNUNET_TRANSPORT_get_hello_cancel (p2.th, &exchange_hello_last, me);
542
543   GNUNET_assert (ok >= 3);
544   OKPP;
545   GNUNET_assert (message != NULL);
546   GNUNET_assert (GNUNET_OK ==
547                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
548                                       message, &me->id));
549   /* both HELLOs exchanged, get ready to test transmission! */
550 }
551
552
553 static void
554 exchange_hello (void *cls,
555                 const struct GNUNET_MessageHeader *message)
556 {
557   struct PeerContext *me = cls;
558
559   GNUNET_TRANSPORT_get_hello_cancel (p1.th, &exchange_hello, me);
560   GNUNET_assert (ok >= 2);
561   OKPP;
562   GNUNET_assert (message != NULL);
563   GNUNET_assert (GNUNET_OK ==
564                  GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
565                                       message, &me->id));
566   GNUNET_TRANSPORT_offer_hello (p2.th, message);
567   GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_last, &p2);
568 }
569
570 static void
571 run (void *cls,
572      struct GNUNET_SCHEDULER_Handle *s,
573      char *const *args,
574      const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
575 {
576   GNUNET_assert (ok == 1);
577   OKPP;
578   sched = s;
579
580   die_task = GNUNET_SCHEDULER_add_delayed (sched,
581                                            TIMEOUT,
582                                            &end_badly,
583                                            NULL);
584   measurement_running = GNUNET_NO;
585   send_running = GNUNET_NO;
586   recv_running = GNUNET_NO;
587
588   if (is_tcp)
589     {
590           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing quota compliance for TCP transport plugin\n");
591       setup_peer (&p1, "test_quota_compliance_tcp_peer1.conf");
592       setup_peer (&p2, "test_quota_compliance_tcp_peer2.conf");
593     }
594   else if (is_http)
595     {
596           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing quota compliance for HTTP transport plugin\n");
597       setup_peer (&p1, "test_quota_compliance_http_peer1.conf");
598       setup_peer (&p2, "test_quota_compliance_http_peer2.conf");
599     }
600   else if (is_https)
601     {
602           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing quota compliance for HTTPS transport plugin\n");
603       setup_peer (&p1, "test_quota_compliance_https_peer1.conf");
604       setup_peer (&p2, "test_quota_compliance_https_peer2.conf");
605     }
606   else if (is_udp)
607     {
608           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing quota compliance for UDP transport plugin\n");
609       setup_peer (&p1, "test_quota_compliance_udp_peer1.conf");
610       setup_peer (&p2, "test_quota_compliance_udp_peer2.conf");
611     }
612   else if (is_tcp_nat)
613     {
614       setup_peer (&p1, "test_quota_compliance_tcp_peer1.conf");
615       setup_peer (&p2, "test_quota_compliance_tcp_peer2.conf");
616     }
617   else
618     GNUNET_assert (0);
619
620   GNUNET_assert(p1.th != NULL);
621   GNUNET_assert(p2.th != NULL);
622   GNUNET_TRANSPORT_get_hello (p1.th, &exchange_hello, &p1);
623 }
624
625 int
626 main (int argc, char *argv[])
627 {
628   int ret = 0;
629 #ifdef MINGW
630   return GNUNET_SYSERR;
631 #endif
632   if (strstr(argv[0], "tcp_nat") != NULL)
633     {
634       is_tcp_nat = GNUNET_YES;
635     }
636   else if (strstr(argv[0], "tcp") != NULL)
637     {
638       is_tcp = GNUNET_YES;
639     }
640   else if (strstr(argv[0], "https") != NULL)
641     {
642       is_https = GNUNET_YES;
643     }
644   else if (strstr(argv[0], "http") != NULL)
645     {
646       is_http = GNUNET_YES;
647     }
648   else if (strstr(argv[0], "udp") != NULL)
649     {
650       is_udp = GNUNET_YES;
651     }
652
653   GNUNET_log_setup ("test-quota-compliance",
654 #if VERBOSE
655                     "DEBUG",
656 #else
657                     "WARNING",
658 #endif
659                     NULL);
660   char *const argv1[] = { "test-quota-compliance",
661     "-c",
662     "test_quota_compliance_data.conf",
663 #if VERBOSE
664     "-L", "DEBUG",
665 #endif
666     NULL
667   };
668   struct GNUNET_GETOPT_CommandLineOption options[] = {
669     GNUNET_GETOPT_OPTION_END
670   };
671
672   if (strstr(argv[0], "asymmetric_recv") != NULL)
673   {
674       is_asymmetric_recv_constant = GNUNET_YES;
675   }
676   else
677           is_asymmetric_recv_constant = GNUNET_NO;
678   if (strstr(argv[0], "asymmetric_send") != NULL)
679   {
680       is_asymmetric_send_constant = GNUNET_YES;
681   }
682   else
683           is_asymmetric_send_constant = GNUNET_NO;
684   ok = 1;
685   GNUNET_PROGRAM_run ((sizeof (argv1) / sizeof (char *)) - 1,
686                       argv1, "test-quota-compliance", "nohelp",
687                       options, &run, &ok);
688   ret = ok;
689   stop_arm (&p1);
690   stop_arm (&p2);
691   GNUNET_DISK_directory_remove ("/tmp/test_quota_compliance_peer1");
692   GNUNET_DISK_directory_remove ("/tmp/test_quota_compliance_peer2");
693   return ret;
694 }
695
696 /* end of test_quota_compliance.c */