guix-env: some update.
[oweals/gnunet.git] / src / testbed / test_testbed_api_testbed_run.c
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2008--2013 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18   Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file testbed/test_testbed_api_testbed_run.c
23  * @brief Test cases for testing high-level testbed management
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
31 /**
32  * Number of peers we want to start
33  */
34 #define NUM_PEERS 5
35
36 /**
37  * The array of peers; we fill this as the peers are given to us by the testbed
38  */
39 static struct GNUNET_TESTBED_Peer *peers[NUM_PEERS];
40
41 /**
42  * Operation handle
43  */
44 static struct GNUNET_TESTBED_Operation *op;
45
46 /**
47  * Abort task identifier
48  */
49 static struct GNUNET_SCHEDULER_Task * abort_task;
50
51 /**
52  * Current peer id
53  */
54 static unsigned int peer_id;
55
56 /**
57  * Testing result
58  */
59 static int result;
60
61 /**
62  * Should we wait forever after testbed is initialized?
63  */
64 static int wait_forever;
65
66
67 /**
68  * Shutdown nicely
69  *
70  * @param cls NULL
71  */
72 static void
73 do_shutdown (void *cls)
74 {
75   if (NULL != abort_task)
76     GNUNET_SCHEDULER_cancel (abort_task);
77   GNUNET_SCHEDULER_shutdown (); /* Stop scheduler to shutdown testbed run */
78 }
79
80
81 /**
82  * abort task to run on test timed out
83  *
84  * @param cls NULL
85  */
86 static void
87 do_abort (void *cls)
88 {
89   abort_task = NULL;
90   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
91               "Test timed out -- Aborting\n");
92   GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
93 }
94
95
96 /**
97  * Signature of a main function for a testcase.
98  *
99  * @param cls closure
100  * @param h the run handle
101  * @param num_peers number of peers in 'peers'
102  * @param peers_ handle to peers run in the testbed
103  * @param links_succeeded the number of overlay link connection attempts that
104  *          succeeded
105  * @param links_failed the number of overlay link connection attempts that
106  *          failed
107  */
108 static void
109 test_master (void *cls,
110              struct GNUNET_TESTBED_RunHandle *h,
111              unsigned int num_peers,
112              struct GNUNET_TESTBED_Peer **peers_,
113              unsigned int links_succeeded,
114              unsigned int links_failed)
115 {
116   result = GNUNET_OK;
117   if (GNUNET_YES == wait_forever)
118   {
119     if (NULL == abort_task)
120       return;                   /* abort already scheduled */
121     GNUNET_SCHEDULER_cancel (abort_task);
122     abort_task = NULL;
123     GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
124     return;
125   }
126   GNUNET_assert (NULL != peers[0]);
127   op = GNUNET_TESTBED_peer_stop (NULL, peers[0], NULL, NULL);
128   GNUNET_assert (NULL != op);
129 }
130
131
132 /**
133  * Controller event callback
134  *
135  * @param cls NULL
136  * @param event the controller event
137  */
138 static void
139 controller_event_cb (void *cls,
140                      const struct GNUNET_TESTBED_EventInformation *event)
141 {
142
143   switch (event->type)
144   {
145   case GNUNET_TESTBED_ET_PEER_START:
146     GNUNET_assert (NULL == peers[peer_id]);
147     GNUNET_assert (NULL != event->details.peer_start.peer);
148     peers[peer_id++] = event->details.peer_start.peer;
149     break;
150   case GNUNET_TESTBED_ET_PEER_STOP:
151     GNUNET_assert (NULL != op);
152     GNUNET_TESTBED_operation_done (op);
153     GNUNET_assert (peers[0] == event->details.peer_stop.peer);
154     GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
155     break;
156   default:
157     GNUNET_assert (0);
158   }
159 }
160
161
162 /**
163  * Main run function.
164  *
165  * @param cls NULL
166  * @param args arguments passed to GNUNET_PROGRAM_run
167  * @param cfgfile the path to configuration file
168  * @param cfg the configuration file handle
169  */
170 static void
171 run (void *cls,
172      char *const *args,
173      const char *cfgfile,
174      const struct GNUNET_CONFIGURATION_Handle *config)
175 {
176   uint64_t event_mask;
177
178   event_mask = 0;
179   event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_START);
180   event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_STOP);
181   GNUNET_TESTBED_run (NULL, config, NUM_PEERS, event_mask,
182                       &controller_event_cb, NULL,
183                       &test_master, NULL);
184   abort_task =
185       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
186                                     (GNUNET_TIME_UNIT_SECONDS, 300),
187                                     &do_abort,
188                                     NULL);
189 }
190
191
192 /**
193  * Main function
194  */
195 int
196 main (int argc, char **argv)
197 {
198   char *argv2[] = {
199     "test_testbed_api_testbed_run",
200     "-c", NULL,
201     NULL
202   };
203   struct GNUNET_GETOPT_CommandLineOption options[] = {
204     GNUNET_GETOPT_OPTION_END
205   };
206   char *testname;
207   char *config_filename;
208   int ret;
209
210   if (NULL == (testname = strrchr (argv[0], (int) '_')))
211   {
212     GNUNET_break (0);
213     return 1;
214   }
215   testname++;
216   testname = GNUNET_strdup (testname);
217 #ifdef MINGW
218   {
219     char *period;
220
221     /* check and remove .exe extension */
222     period = strrchr (testname, (int) '.');
223     if (NULL != period)
224       *period = '\0';
225     else
226       GNUNET_break (0);         /* Windows with no .exe? */
227   }
228 #endif
229   if (0 == strcmp ("waitforever", testname))
230     wait_forever = GNUNET_YES;
231   if ( (GNUNET_YES != wait_forever) && (0 != strcmp ("run", testname)) )
232   {
233     GNUNET_asprintf (&config_filename, "test_testbed_api_testbed_run_%s.conf",
234                      testname);
235   }
236   else
237     config_filename = GNUNET_strdup ("test_testbed_api.conf");
238   GNUNET_free (testname);
239   argv2[2] = config_filename;
240   result = GNUNET_SYSERR;
241   ret =
242       GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
243                           "test_testbed_api_testbed_run", "nohelp", options,
244                           &run, NULL);
245   GNUNET_free (config_filename);
246   if ((GNUNET_OK != ret) || (GNUNET_OK != result))
247     return 1;
248   return 0;
249 }
250
251 /* end of test_testbed_api_testbed_run.c */