extend API to enalbe exclusive port ranges to be specified for testing-system objects
[oweals/gnunet.git] / src / include / gnunet_testing_lib-new.h
index 0943d6d06ee99bc232f4c90d544ad9bd7f86f5a8..802839d17045d077f6b6335634060e25f436f011 100644 (file)
@@ -60,26 +60,56 @@ struct GNUNET_TESTING_Peer;
 
 /**
  * Create a system handle.  There must only be one system
- * handle per operating system.
+ * handle per operating system.  Uses a default range for allowed ports.
+ * Ports are still tested for availability.
  *
- * @param tmppath prefix path to use for all service homes
+ * @param testdir only the directory name without any path. This is used for
+ *          all service homes; the directory will be created in a temporary
+ *          location depending on the underlying OS
  * @param controller hostname of the controlling host, 
  *        service configurations are modified to allow 
  *        control connections from this host; can be NULL
  * @return handle to this system, NULL on error
  */
 struct GNUNET_TESTING_System *
-GNUNET_TESTING_system_create (const char *tmppath,
+GNUNET_TESTING_system_create (const char *testdir,
                              const char *controller);
 
 
+/**
+ * Create a system handle.  There must only be one system
+ * handle per operating system.  Use this function directly
+ * if multiple system objects are created for the same host
+ * (only really useful when testing --- or to make the port
+ * range configureable).
+ *
+ * @param testdir only the directory name without any path. This is used for
+ *          all service homes; the directory will be created in a temporary
+ *          location depending on the underlying OS
+ * @param controller hostname of the controlling host, 
+ *        service configurations are modified to allow 
+ *        control connections from this host; can be NULL
+ * @param lowport lowest port number this system is allowed to allocate (inclusive)
+ * @param highport highest port number this system is allowed to allocate (exclusive)
+ * @return handle to this system, NULL on error
+ */
+struct GNUNET_TESTING_System *
+GNUNET_TESTING_system_create_with_portrange (const char *testdir,
+                                            const char *controller,
+                                            uint16_t lowport,
+                                            uint16_t highport);
+
+
 /**
  * Free system resources.
  *
  * @param system system to be freed
+ * @param remove_paths should the 'testdir' and all subdirectories
+ *        be removed (clean up on shutdown)?
  */
 void
-GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system);
+GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system,
+                              int remove_paths);
 
 
 /**
@@ -93,24 +123,50 @@ GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system);
  * This is primarily a helper function used internally
  * by 'GNUNET_TESTING_peer_configure'.
  *
+ * @param system the testing system handle
  * @param key_number desired pre-created hostkey to obtain
- * @param filename where to store the hostkey (file will
- *        be created, or overwritten if it already exists)
  * @param id set to the peer's identity (hash of the public
- *        key; can be NULL
- * @return GNUNET_SYSERR on error (not enough keys)
+ *        key; if NULL, GNUNET_SYSERR is returned immediately
+ * @return NULL on error (not enough keys)
  */
-int
-GNUNET_TESTING_hostkey_get (uint32_t key_number,
-                           const char *filename,
+struct GNUNET_CRYPTO_RsaPrivateKey *
+GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system,
+                           uint32_t key_number,
                            struct GNUNET_PeerIdentity *id);
 
 
+/**
+ * Reserve a TCP or UDP port for a peer.
+ *
+ * @param system system to use for reservation tracking
+ * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP
+ * @return 0 if no free port was available
+ */
+uint16_t 
+GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system,
+                            int is_tcp);
+
+
+/**
+ * Release reservation of a TCP or UDP port for a peer
+ * (used during GNUNET_TESTING_peer_destroy).
+ *
+ * @param system system to use for reservation tracking
+ * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP
+ * @param port reserved port to release
+ */
+void
+GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system,
+                            int is_tcp,
+                            uint16_t port);
+
 
 /**
- * Create a new configuration using the given configuration
- * as a template; ports and paths will be modified to select
- * available ports on the local system.  If we run
+ * Create a new configuration using the given configuration as a template;
+ * ports and paths will be modified to select available ports on the local
+ * system. The default configuration will be available in PATHS section under
+ * the option DEFAULTCONFIG after the call. SERVICE_HOME is also set in PATHS
+ * section to the temporary directory specific to this configuration. If we run
  * out of "*port" numbers, return SYSERR.
  *
  * This is primarily a helper function used internally
@@ -118,11 +174,13 @@ GNUNET_TESTING_hostkey_get (uint32_t key_number,
  *
  * @param system system to use to coordinate resource usage
  * @param cfg template configuration to update
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error - the configuration will
+ *           be incomplete and should not be used there upon
  */
 int
 GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system,
                                     struct GNUNET_CONFIGURATION_Handle *cfg);
+// FIXME: add dual to 'release' ports again...
 
 
 /**
@@ -134,7 +192,8 @@ GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system,
  *            changes in port numbers and paths)
  * @param key_number number of the hostkey to use for the peer
  * @param id identifier for the daemon, will be set, can be NULL
- * @param emsg set to error message (set to NULL on success), can be NULL
+ * @param emsg set to freshly allocated error message (set to NULL on success), 
+ *          can be NULL
  * @return handle to the peer, NULL on error
  */
 struct GNUNET_TESTING_Peer *
@@ -145,6 +204,17 @@ GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system,
                               char **emsg);
 
 
+/**
+ * Obtain the peer identity from a peer handle.
+ *
+ * @param peer peer handle for which we want the peer's identity
+ * @param id identifier for the daemon, will be set
+ */
+void
+GNUNET_TESTING_peer_get_identity (const struct GNUNET_TESTING_Peer *peer,
+                                 struct GNUNET_PeerIdentity *id);
+
+
 /**
  * Start the peer. 
  *
@@ -182,9 +252,11 @@ GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer);
  * 
  * @param cls closure
  * @param cfg configuration of the peer that was started
+ * @param peer identity of the peer that was created
  */
 typedef void (*GNUNET_TESTING_TestMain)(void *cls,
-                                       const struct GNUNET_CONFIGURATION_Handle *cfg);
+                                       const struct GNUNET_CONFIGURATION_Handle *cfg,
+                                       struct GNUNET_TESTING_Peer *peer);
 
 
 /**
@@ -194,7 +266,9 @@ typedef void (*GNUNET_TESTING_TestMain)(void *cls,
  * and should thus be called directly from "main".  The testcase
  * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'.
  *
- * @param tmppath path for storing temporary data for the test
+ * @param testdir only the directory name without any path. This is used for
+ *          all service homes; the directory will be created in a temporary
+ *          location depending on the underlying OS
  * @param cfgfilename name of the configuration file to use;
  *         use NULL to only run with defaults
  * @param tm main function of the testcase
@@ -202,13 +276,12 @@ typedef void (*GNUNET_TESTING_TestMain)(void *cls,
  * @return 0 on success, 1 on error
  */
 int
-GNUNET_TESTING_peer_run (const char *tmppath,
+GNUNET_TESTING_peer_run (const char *testdir,
                         const char *cfgfilename,
                         GNUNET_TESTING_TestMain tm,
                         void *tm_cls);
 
 
-
 /**
  * Start a single service (no ARM, except of course if the given
  * service name is 'arm') and run a test using the testing library.
@@ -220,7 +293,9 @@ GNUNET_TESTING_peer_run (const char *tmppath,
  * This function is useful if the testcase is for a single service
  * and if that service doesn't itself depend on other services.
  *
- * @param tmppath path for storing temporary data for the test
+ * @param testdir only the directory name without any path. This is used for
+ *          all service homes; the directory will be created in a temporary
+ *          location depending on the underlying OS
  * @param service_name name of the service to run
  * @param cfgfilename name of the configuration file to use;
  *         use NULL to only run with defaults
@@ -229,13 +304,29 @@ GNUNET_TESTING_peer_run (const char *tmppath,
  * @return 0 on success, 1 on error
  */
 int
-GNUNET_TESTING_service_run (const char *tmppath,
+GNUNET_TESTING_service_run (const char *testdir,
                            const char *service_name,
                            const char *cfgfilename,
                            GNUNET_TESTING_TestMain tm,
                            void *tm_cls);
 
 
+/**
+ * Sometimes we use the binary name to determine which specific
+ * test to run.  In those cases, the string after the last "_"
+ * in 'argv[0]' specifies a string that determines the configuration
+ * file or plugin to use.  
+ *
+ * This function returns the respective substring, taking care
+ * of issues such as binaries ending in '.exe' on W32.
+ *
+ * @param argv0 the name of the binary
+ * @return string between the last '_' and the '.exe' (or the end of the string),
+ *         NULL if argv0 has no '_' 
+ */
+char *
+GNUNET_TESTING_get_testname_from_underscore (const char *argv0);
+
 
 #if 0                           /* keep Emacsens' auto-indent happy */
 {