1d49e706d8e79944a1aa612127bd166c6adb8d4b
[oweals/gnunet.git] / src / testbed / testbed_api_test.c
1 /*
2       This file is part of GNUnet
3       (C) 2008--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 testbed/testbed_api_test.c
23  * @brief high-level test function
24  * @author Christian Grothoff
25  * @author Sree Harsha Totakura
26  */
27 #include "platform.h"
28 #include "gnunet_testbed_service.h"
29
30
31 /**
32  * Context information for test run
33  */
34 struct TestRunContext
35 {
36   /**
37    * Test master callback
38    */
39   GNUNET_TESTBED_TestMaster test_master;
40
41   /**
42    * Closure for test master
43    */
44   void *test_master_cls;
45
46   /**
47    * Number of peers to start
48    */
49   unsigned int num_peers;
50
51   /**
52    * counter for loading peers
53    */
54   unsigned int peer_cnt;
55
56   /**
57    * Followed by peers list
58    */
59   struct GNUNET_TESTBED_Peer *peers[0];
60 };
61
62
63 /**
64  * Controller event callback
65  *
66  * @param cls NULL
67  * @param event the controller event
68  */
69 static void
70 controller_event_cb (void *cls,
71                      const struct GNUNET_TESTBED_EventInformation *event)
72 {
73   struct TestRunContext *rc = cls;
74
75   if (rc->peer_cnt == rc->num_peers)
76     return;
77   GNUNET_assert (GNUNET_TESTBED_ET_PEER_START == event->type);
78   GNUNET_assert (NULL == rc->peers[rc->peer_cnt]);
79   GNUNET_assert (NULL != event->details.peer_start.peer);
80   rc->peers[rc->peer_cnt++] = event->details.peer_start.peer;
81 }
82
83
84 /**
85  * Task to be executed when peers are ready
86  *
87  * @param cls NULL
88  * @param tc the task context
89  */
90 static void
91 master_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
92 {
93   struct TestRunContext *rc = cls;
94
95   GNUNET_assert (rc->peer_cnt == rc->num_peers);
96   rc->test_master (rc->test_master_cls, rc->num_peers, rc->peers);
97 }
98
99
100 /**
101  * Main run function.
102  *
103  * @param cls NULL
104  * @param args arguments passed to GNUNET_PROGRAM_run
105  * @param cfgfile the path to configuration file
106  * @param cfg the configuration file handle
107  */
108 static void
109 run (void *cls, char *const *args, const char *cfgfile,
110      const struct GNUNET_CONFIGURATION_Handle *config)
111 {
112   struct TestRunContext *rc = cls;
113
114   GNUNET_TESTBED_run (NULL, config, rc->num_peers, 0, &controller_event_cb, rc,
115                       &master_task, rc);
116 }
117
118
119 /**
120  * Convenience method for running a "simple" test on the local system
121  * with a single call from 'main'.  Underlay and overlay topology are
122  * configured using the "UNDERLAY" and "OVERLAY" options in the
123  * "[testbed]" section of the configuration (with possible options
124  * given in "UNDERLAY_XXX" and/or "OVERLAY_XXX").
125  *
126  * The test is to be terminated using a call to
127  * "GNUNET_SCHEDULER_shutdown".  If starting the test fails,
128  * the program is stopped without 'master' ever being run.
129  *
130  * NOTE: this function should be called from 'main', NOT from
131  * within a GNUNET_SCHEDULER-loop.  This function will initialze
132  * the scheduler loop, the testbed and then pass control to
133  * 'master'.
134  *
135  * @param testname name of the testcase (to configure logging, etc.)
136  * @param cfg_filename configuration filename to use
137  *              (for testbed, controller and peers)
138  * @param num_peers number of peers to start
139  * @param test_master task to run once the test is ready
140  * @param test_master_cls closure for 'task'.
141  */
142 void
143 GNUNET_TESTBED_test_run (const char *testname, const char *cfg_filename,
144                          unsigned int num_peers,
145                          GNUNET_TESTBED_TestMaster test_master,
146                          void *test_master_cls)
147 {
148   char *argv2[] = {
149     NULL,
150     "-c",
151     NULL,
152     NULL
153   };
154   struct GNUNET_GETOPT_CommandLineOption options[] = {
155     GNUNET_GETOPT_OPTION_END
156   };
157   struct TestRunContext *rc;
158
159   argv2[0] = GNUNET_strdup (testname);
160   argv2[2] = GNUNET_strdup (cfg_filename);
161   GNUNET_assert (NULL != test_master);
162   rc = GNUNET_malloc (sizeof (struct TestRunContext) +
163                       (num_peers * sizeof (struct GNUNET_TESTBED_Peer *)));
164   rc->test_master = test_master;
165   rc->test_master_cls = test_master_cls;
166   rc->num_peers = num_peers;
167   (void) GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
168                              testname, "nohelp", options, &run, rc);
169   GNUNET_free (rc);
170   GNUNET_free (argv2[0]);
171   GNUNET_free (argv2[2]);
172 }
173
174 /* end of testbed_api_test.c */