-fix
[oweals/gnunet.git] / src / testing / testing_new.c
1 /*
2       This file is part of GNUnet
3       (C) 2008, 2009, 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 testing/testing_new.c
23  * @brief convenience API for writing testcases for GNUnet
24  *        Many testcases need to start and stop a peer/service
25  *        and this library is supposed to make that easier
26  *        for TESTCASES.  Normal programs should always
27  *        use functions from gnunet_{util,arm}_lib.h.  This API is
28  *        ONLY for writing testcases (or internal use of the testbed).
29  * @author Christian Grothoff
30  *
31  */
32 #include "platform.h"
33 #include "gnunet_testing_lib-new.h"
34
35
36 /**
37  * Handle for a system on which GNUnet peers are executed;
38  * a system is used for reserving unique paths and ports.
39  */
40 struct GNUNET_TESTING_System
41 {
42   /**
43    * Prefix (i.e. "/tmp/gnunet-testing/") we prepend to each
44    * SERVICEHOME. 
45    */
46   char *tmppath;
47
48   /**
49    * Bitmap where each TCP port that has already been reserved for
50    * some GNUnet peer is recorded.  Note that we additionally need to
51    * test if a port is already in use by non-GNUnet components before
52    * assigning it to a peer/service.  If we detect that a port is
53    * already in use, we also mark it in this bitmap.  So all the bits
54    * that are zero merely indicate ports that MIGHT be available for
55    * peers.
56    */
57   uint32_t reserved_tcp_ports[65536 / 32];
58
59   /**
60    * Bitmap where each UDP port that has already been reserved for
61    * some GNUnet peer is recorded.  Note that we additionally need to
62    * test if a port is already in use by non-GNUnet components before
63    * assigning it to a peer/service.  If we detect that a port is
64    * already in use, we also mark it in this bitmap.  So all the bits
65    * that are zero merely indicate ports that MIGHT be available for
66    * peers.
67    */
68   uint32_t reserved_udp_ports[65536 / 32];
69
70   /**
71    * Counter we use to make service home paths unique on this system;
72    * the full path consists of the tmppath and this number.  Each
73    * UNIXPATH for a peer is also modified to include the respective
74    * path counter to ensure uniqueness.  This field is incremented
75    * by one for each configured peer.  Even if peers are destroyed,
76    * we never re-use path counters.
77    */
78   uint32_t path_counter;
79 };
80
81
82 /**
83  * Handle for a GNUnet peer controlled by testing.
84  */
85 struct GNUNET_TESTING_Peer
86 {
87
88   /**
89    * Path to the configuration file for this peer.
90    */
91   char *cfgfile;
92
93   /**
94    * Binary to be executed during 'GNUNET_TESTING_peer_start'.
95    * Typically 'gnunet-service-arm' (but can be set to a 
96    * specific service by 'GNUNET_TESTING_service_run' if
97    * necessary).
98    */ 
99   char *main_binary;
100   
101   /**
102    * Handle to the running binary of the service, NULL if the
103    * peer/service is currently not running.
104    */
105   struct GNUNET_OS_Process *main_process;
106
107 };
108
109
110 /**
111  * Create a system handle.  There must only be one system
112  * handle per operating system.
113  *
114  * @param tmppath prefix path to use for all service homes
115  * @param controller hostname of the controlling host, 
116  *        service configurations are modified to allow 
117  *        control connections from this host; can be NULL
118  * @return handle to this system, NULL on error
119  */
120 struct GNUNET_TESTING_System *
121 GNUNET_TESTING_system_create (const char *tmppath,
122                               const char *controller)
123 {
124   GNUNET_break (0);
125   return NULL;
126 }
127
128
129 /**
130  * Free system resources.
131  *
132  * @param system system to be freed
133  * @param remove_paths should the 'tmppath' and all subdirectories
134  *        be removed (clean up on shutdown)?
135  */
136 void
137 GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system,
138                                int remove_paths)
139 {
140   GNUNET_break (0);
141 }
142
143
144 /**
145  * Reserve a TCP or UDP port for a peer.
146  *
147  * @param system system to use for reservation tracking
148  * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP
149  * @return 0 if no free port was available
150  */
151 // static 
152 uint16_t 
153 reserve_port (struct GNUNET_TESTING_System *system,
154               int is_tcp)
155 {
156   GNUNET_break (0);
157   return 0;
158 }
159
160
161 /**
162  * Release reservation of a TCP or UDP port for a peer
163  * (used during GNUNET_TESTING_peer_destroy).
164  *
165  * @param system system to use for reservation tracking
166  * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP
167  * @param port reserved port to release
168  */
169 // static 
170 void
171 release_port (struct GNUNET_TESTING_System *system,
172               int is_tcp,
173               uint16_t port)
174 {
175   GNUNET_break (0);
176 }
177
178
179 /**
180  * Reserve a SERVICEHOME path for a peer.
181  *
182  * @param system system to use for reservation tracking
183  * @return NULL on error, otherwise fresh unique path to use
184  *         as the servicehome for the peer
185  */
186 // static 
187 char *
188 reserve_path (struct GNUNET_TESTING_System *system)
189 {
190   GNUNET_break (0);
191   return NULL;
192 }             
193
194
195 /**
196  * Testing includes a number of pre-created hostkeys for
197  * faster peer startup.  This function can be used to
198  * access the n-th key of those pre-created hostkeys; note
199  * that these keys are ONLY useful for testing and not
200  * secure as the private keys are part of the public 
201  * GNUnet source code.
202  *
203  * This is primarily a helper function used internally
204  * by 'GNUNET_TESTING_peer_configure'.
205  *
206  * @param key_number desired pre-created hostkey to obtain
207  * @param filename where to store the hostkey (file will
208  *        be created, or overwritten if it already exists)
209  * @param id set to the peer's identity (hash of the public
210  *        key; can be NULL
211  * @return GNUNET_SYSERR on error (not enough keys)
212  */
213 int
214 GNUNET_TESTING_hostkey_get (uint32_t key_number,
215                             const char *filename,
216                             struct GNUNET_PeerIdentity *id)
217 {
218   GNUNET_break (0);
219   return GNUNET_SYSERR;
220 }
221
222
223 /**
224  * Create a new configuration using the given configuration
225  * as a template; ports and paths will be modified to select
226  * available ports on the local system.  If we run
227  * out of "*port" numbers, return SYSERR.
228  *
229  * This is primarily a helper function used internally
230  * by 'GNUNET_TESTING_peer_configure'.
231  *
232  * @param system system to use to coordinate resource usage
233  * @param cfg template configuration to update
234  * @return GNUNET_OK on success, GNUNET_SYSERR on error
235  */
236 int
237 GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system,
238                                      struct GNUNET_CONFIGURATION_Handle *cfg)
239 {
240   GNUNET_break (0);
241   return GNUNET_SYSERR;
242 }
243
244
245 /**
246  * Configure a GNUnet peer.  GNUnet must be installed on the local
247  * system and available in the PATH. 
248  *
249  * @param system system to use to coordinate resource usage
250  * @param cfg configuration to use; will be UPDATED (to reflect needed
251  *            changes in port numbers and paths)
252  * @param key_number number of the hostkey to use for the peer
253  * @param id identifier for the daemon, will be set, can be NULL
254  * @param emsg set to error message (set to NULL on success), can be NULL
255  * @return handle to the peer, NULL on error
256  */
257 struct GNUNET_TESTING_Peer *
258 GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system,
259                                struct GNUNET_CONFIGURATION_Handle *cfg,
260                                uint32_t key_number,
261                                struct GNUNET_PeerIdentity *id,
262                                char **emsg)
263 {
264   GNUNET_break (0);
265   return NULL;
266 }
267
268
269 /**
270  * Start the peer. 
271  *
272  * @param peer peer to start
273  * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer already running)
274  */
275 int
276 GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer)
277 {
278   GNUNET_break (0);
279   return GNUNET_SYSERR;
280 }
281
282
283 /**
284  * Stop the peer. 
285  *
286  * @param peer peer to stop
287  * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer not running)
288  */
289 int
290 GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer)
291 {
292   GNUNET_break (0);
293   return GNUNET_SYSERR;
294 }
295
296
297 /**
298  * Destroy the peer.  Releases resources locked during peer configuration.
299  * If the peer is still running, it will be stopped AND a warning will be
300  * printed (users of the API should stop the peer explicitly first).
301  *
302  * @param peer peer to destroy
303  */
304 void
305 GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer)
306 {
307   GNUNET_break (0);
308 }
309
310
311
312 /**
313  * Start a single peer and run a test using the testing library.
314  * Starts a peer using the given configuration and then invokes the
315  * given callback.  This function ALSO initializes the scheduler loop
316  * and should thus be called directly from "main".  The testcase
317  * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'.
318  *
319  * @param tmppath path for storing temporary data for the test
320  * @param cfgfilename name of the configuration file to use;
321  *         use NULL to only run with defaults
322  * @param tm main function of the testcase
323  * @param tm_cls closure for 'tm'
324  * @return 0 on success, 1 on error
325  */
326 int
327 GNUNET_TESTING_peer_run (const char *tmppath,
328                          const char *cfgfilename,
329                          GNUNET_TESTING_TestMain tm,
330                          void *tm_cls)
331 {
332   return GNUNET_TESTING_service_run (tmppath, "arm",
333                                      cfgfilename, tm, tm_cls);
334 }
335
336
337
338 /**
339  * Start a single service (no ARM, except of course if the given
340  * service name is 'arm') and run a test using the testing library.
341  * Starts a service using the given configuration and then invokes the
342  * given callback.  This function ALSO initializes the scheduler loop
343  * and should thus be called directly from "main".  The testcase
344  * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'.
345  *
346  * This function is useful if the testcase is for a single service
347  * and if that service doesn't itself depend on other services.
348  *
349  * @param tmppath path for storing temporary data for the test
350  * @param service_name name of the service to run
351  * @param cfgfilename name of the configuration file to use;
352  *         use NULL to only run with defaults
353  * @param tm main function of the testcase
354  * @param tm_cls closure for 'tm'
355  * @return 0 on success, 1 on error
356  */
357 int
358 GNUNET_TESTING_service_run (const char *tmppath,
359                             const char *service_name,
360                             const char *cfgfilename,
361                             GNUNET_TESTING_TestMain tm,
362                             void *tm_cls)
363 {
364   GNUNET_break (0);
365   return 1;
366 }
367
368
369
370 /* end of testing_new.c */