- barriers test case; more fixes
[oweals/gnunet.git] / src / testbed / test_testbed_api_barriers.c
1 /*
2       This file is part of GNUnet
3       (C) 2008--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 testbed/test_testbed_api_barriers.c
23  * @brief testcase binary for testing testbed barriers API
24  * @author Sree Harsha Totakura <sreeharsha@totakura.in> 
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_testbed_service.h"
30 #include "test_testbed_api_barriers.h"
31
32
33 /**
34  * logging short hand
35  */
36 #define LOG(type,...) \
37   GNUNET_log (type, __VA_ARGS__);
38
39 /**
40  * Number of peers we start in this test case
41  */
42 #define NUM_PEERS 3
43
44
45 /**
46  * Our barrier
47  */
48 struct GNUNET_TESTBED_Barrier *barrier;
49
50 /**
51  * Identifier for the shutdown task
52  */
53 static GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
54
55 /**
56  * Result of this test case
57  */
58 static int result;
59
60
61 /**
62  * Shutdown this test case when it takes too long
63  *
64  * @param cls NULL
65  * @param tc scheduler task context
66  */
67 static void
68 do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
69 {
70   shutdown_task = GNUNET_SCHEDULER_NO_TASK;
71   if (NULL != barrier)
72   {
73     GNUNET_TESTBED_barrier_cancel (barrier);
74     barrier = NULL;
75   }
76   
77   GNUNET_SCHEDULER_shutdown ();
78 }
79
80
81 /**
82  * Functions of this type are to be given as callback argument to
83  * GNUNET_TESTBED_barrier_init().  The callback will be called when status
84  * information is available for the barrier.
85  *
86  * @param cls the closure given to GNUNET_TESTBED_barrier_init()
87  * @param name the name of the barrier
88  * @param barrier the barrier handle
89  * @param status status of the barrier; GNUNET_OK if the barrier is crossed;
90  *   GNUNET_SYSERR upon error
91  * @param emsg if the status were to be GNUNET_SYSERR, this parameter has the
92  *   error messsage
93  */
94 static void
95 barrier_cb (void *cls,
96             const char *name,
97             struct GNUNET_TESTBED_Barrier *_barrier,
98             enum GNUNET_TESTBED_BarrierStatus status,
99             const char *emsg)
100 {
101   static enum GNUNET_TESTBED_BarrierStatus old_status;
102   
103   GNUNET_assert (NULL == cls);
104   GNUNET_assert (_barrier == barrier);
105   switch (status)
106   {
107   case BARRIER_STATUS_INITIALISED:
108     LOG (GNUNET_ERROR_TYPE_INFO, "Barrier initialised\n");
109     old_status = status;
110     return;
111   case BARRIER_STATUS_ERROR:
112     LOG (GNUNET_ERROR_TYPE_ERROR, "Barrier initialisation failed: %s", 
113          (NULL == emsg) ? "unknown reason" : emsg);
114     barrier = NULL;
115     GNUNET_SCHEDULER_shutdown ();    
116     return;
117   case BARRIER_STATUS_CROSSED:
118     LOG (GNUNET_ERROR_TYPE_INFO, "Barrier crossed\n");
119     if (old_status == BARRIER_STATUS_INITIALISED) 
120       result = GNUNET_OK;
121     barrier = NULL;
122     GNUNET_SCHEDULER_shutdown ();
123     return;
124   default:
125     GNUNET_assert (0);
126   }
127 }
128
129
130 /**
131  * Signature of a main function for a testcase.
132  *
133  * @param cls closure
134  * @param h the run handle
135  * @param num_peers number of peers in 'peers'
136  * @param peers_ handle to peers run in the testbed
137  * @param links_succeeded the number of overlay link connection attempts that
138  *          succeeded
139  * @param links_failed the number of overlay link connection attempts that
140  *          failed
141  */
142 static void
143 test_master (void *cls,
144              struct GNUNET_TESTBED_RunHandle *h,
145              unsigned int num_peers,
146              struct GNUNET_TESTBED_Peer **peers_,
147              unsigned int links_succeeded,
148              unsigned int links_failed)
149 {
150   struct GNUNET_TESTBED_Controller *c;
151
152   GNUNET_assert (NULL == cls);
153   if (NULL == peers_)
154   {
155     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failing test due to timeout\n");
156     return;
157   }
158   GNUNET_assert (NUM_PEERS == num_peers);
159   c = GNUNET_TESTBED_run_get_controller_handle (h);
160   barrier = GNUNET_TESTBED_barrier_init (c, TEST_BARRIER_NAME, 100,
161                                          &barrier_cb, NULL);
162   shutdown_task =
163       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
164                                     (GNUNET_TIME_UNIT_SECONDS, 
165                                      10 * (NUM_PEERS + 1)),
166                                     &do_shutdown, NULL);
167 }
168
169
170 /**
171  * Main function
172  */
173 int
174 main (int argc, char **argv)
175 {
176   uint64_t event_mask;
177
178   result = GNUNET_SYSERR;
179   event_mask = 0;
180   (void) GNUNET_TESTBED_test_run ("test_testbed_api_barriers",
181                                   "test_testbed_api_barriers.conf", NUM_PEERS,
182                                   event_mask, NULL, NULL,
183                                   &test_master, NULL);
184   if (GNUNET_OK != result)
185     return 1;
186   return 0;
187 }