#define GNUNET_TESTBED_SERVICE_H
#include "gnunet_util_lib.h"
+#include "gnunet_testing_lib-new.h"
#ifdef __cplusplus
extern "C"
*/
unsigned int
GNUNET_TESTBED_hosts_load_from_file (const char *filename,
- struct GNUNET_TESTBED_Host **hosts);
+ struct GNUNET_TESTBED_Host ***hosts);
/**
*/
GNUNET_TESTBED_PIT_GENERIC = 0,
- /**
- * What host is the peer running on? Returns a 'const struct
- * GNUNET_TESTBED_Host *'. Valid until
- * 'GNUNET_TESTBED_operation_done' is called.
- */
- GNUNET_TESTBED_PIT_HOST,
-
/**
* What configuration is the peer using? Returns a 'const struct
* GNUNET_CONFIGURATION_Handle *'. Valid until
const char *emsg;
/**
- * Peer information type; captures which of the types
- * in the 'op_result' is actually in use.
- */
- enum GNUNET_TESTBED_PeerInformationType pit;
-
- /**
- * Pointer to an operation-specific return value; NULL on error;
- * can be NULL for certain operations. Valid until
- * 'GNUNET_TESTBED_operation_done' is called.
+ * No result (NULL pointer) or generic result
+ * (whatever the GNUNET_TESTBED_ConnectAdapter returned).
*/
- union
- {
- /**
- * No result (NULL pointer) or generic result
- * (whatever the GNUNET_TESTBED_ConnectAdapter returned).
- */
- void *generic;
-
- /**
- * Identity of host running the peer.
- */
- struct GNUNET_TESTBED_Host *host;
-
- /**
- * Identity of the peer.
- */
- const struct GNUNET_PeerIdentity *pid;
-
- /**
- * Configuration of the peer.
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- } op_result;
-
+ void *generic;
+
} operation_finished;
/**
- * Function called on errors with the controller.
+ * Callback to signal successfull startup of the controller process
*
- * @param cls closure
- * @param emsg error message if available; can be NULL, which does NOT mean
- * that there was no error
+ * @param cls the closure from GNUNET_TESTBED_controller_start()
+ * @param cfg the configuration with which the controller has been started;
+ * NULL if status is not GNUNET_OK
+ * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not,
+ * GNUNET_TESTBED_controller_stop() shouldn't be called in this case
*/
-typedef void (*GNUNET_TESTBED_ControllerErrorCallback)(void *cls,
- const char *emsg);
+typedef void (*GNUNET_TESTBED_ControllerStatusCallback) (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ int status);
/**
- * Starts a controller process at the host
+ * Starts a controller process at the host.
*
- * @param system used for reserving ports if host is NULL and to determine
- * which 'host' to set as TRUSTED ('controller') when starting testbed remotely
- * @param host the host where the controller has to be started; NULL for localhost
- * @param cfg template configuration to use for the remote controller; will
- * be modified to contain the actual host/port/unixpath used for
- * the testbed service
- * @param cec function called if the contoller dies unexpectedly; will not be
- * invoked after GNUNET_TESTBED_controller_stop, if 'cec' was called,
- * GNUNET_TESTBED_controller_stop must no longer be called; will
- * never be called in the same task as 'GNUNET_TESTBED_controller_start'
- * (synchronous errors will be signalled by returning NULL)
- * @param cec_cls closure for 'cec'
+ * @param controller_ip the ip address of the controller. Will be set as TRUSTED
+ * host when starting testbed controller at host
+ * @param host the host where the controller has to be started; NULL for
+ * localhost
+ * @param cfg template configuration to use for the remote controller; the
+ * remote controller will be started with a slightly modified
+ * configuration (port numbers, unix domain sockets and service home
+ * values are changed as per TESTING library on the remote host)
+ * @param cb function called when the controller is successfully started or
+ * dies unexpectedly; GNUNET_TESTBED_controller_stop shouldn't be
+ * called if cb is called with GNUNET_SYSERR as status. Will never be
+ * called in the same task as 'GNUNET_TESTBED_controller_start'
+ * (synchronous errors will be signalled by returning NULL). This
+ * parameter cannot be NULL.
+ * @param cls closure for above callbacks
* @return the controller process handle, NULL on errors
*/
struct GNUNET_TESTBED_ControllerProc *
-GNUNET_TESTBED_controller_start (struct GNUNET_TESTING_System *system,
+GNUNET_TESTBED_controller_start (const char *controller_ip,
struct GNUNET_TESTBED_Host *host,
- struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_TESTBED_ControllerErrorCallback cec,
- void *cec_cls);
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_TESTBED_ControllerStatusCallback cb,
+ void *cls);
/**
*handle);
+/**
+ * Callback to be called when an operation is completed
+ *
+ * @param cls the callback closure from functions generating an operation
+ * @param op the operation that has been finished
+ * @param emsg error message in case the operation has failed; will be NULL if
+ * operation has executed successfully.
+ */
+typedef void (*GNUNET_TESTBED_OperationCompletionCallback) (void *cls,
+ struct
+ GNUNET_TESTBED_Operation
+ *op,
+ const char *emsg);
+
+
/**
* Create a link from slave controller to delegated controller. Whenever the
* master controller is asked to start a peer at the delegated controller the
* @param is_subordinate GNUNET_YES if the controller at delegated_host should
* be started by the master controller; GNUNET_NO if we are just
* allowed to use the slave via TCP/IP
+ * @return the operation handle
*/
-void
+struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_controller_link (struct GNUNET_TESTBED_Controller *master,
struct GNUNET_TESTBED_Host *delegated_host,
struct GNUNET_TESTBED_Host *slave_host,
* @param slave_host which host is used to run the slave controller; use NULL to
* make the master controller connect to the delegated host
* @param sxcfg serialized and compressed configuration
- * @param sxcfg_size the size scfg
+ * @param sxcfg_size the size sxcfg
* @param scfg_size the size of uncompressed serialized configuration
* @param is_subordinate GNUNET_YES if the controller at delegated_host should
* be started by the master controller; GNUNET_NO if we are just
* allowed to use the slave via TCP/IP
+ * @return the operation handle
*/
-void
+struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_controller_link_2 (struct GNUNET_TESTBED_Controller *master,
struct GNUNET_TESTBED_Host *delegated_host,
struct GNUNET_TESTBED_Host *slave_host,
const char *sxcfg,
size_t sxcfg_size,
size_t scfg_size,
- int is_subordinate);
+ int is_subordinate);
+
+
+/**
+ * Functions of this signature are called when a peer has been successfully
+ * created
+ *
+ * @param cls the closure from GNUNET_TESTBED_peer_create()
+ * @param peer the handle for the created peer; NULL on any error during
+ * creation
+ * @param emsg NULL if peer is not NULL; else MAY contain the error description
+ */
+typedef void (*GNUNET_TESTBED_PeerCreateCallback) (void *cls,
+ struct GNUNET_TESTBED_Peer *peer,
+ const char *emsg);
/**
*
* @param controller controller process to use
* @param host host to run the peer on
- * @param cfg configuration to use for the peer
- * @return handle to the peer (actual startup will happen asynchronously)
+ * @param cfg Template configuration to use for the peer. Should exist until
+ * operation is cancelled or GNUNET_TESTBED_operation_done() is called
+ * @param cb the callback to call when the peer has been created
+ * @param cls the closure to the above callback
+ * @return the operation handle
*/
-struct GNUNET_TESTBED_Peer *
+struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_peer_create (struct GNUNET_TESTBED_Controller *controller,
struct GNUNET_TESTBED_Host *host,
- const struct GNUNET_CONFIGURATION_Handle *cfg);
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GNUNET_TESTBED_PeerCreateCallback cb,
+ void *cls);
+
+
+/**
+ * Functions of this signature are called when a peer has been successfully
+ * started or stopped.
+ *
+ * @param cls the closure from GNUNET_TESTBED_peer_start/stop()
+ * @param emsg NULL on success; otherwise an error description
+ */
+typedef void (*GNUNET_TESTBED_PeerChurnCallback) (void *cls,
+ const char *emsg);
/**
* Start the given peer.
*
* @param peer peer to start
+ * @param pcc function to call upon completion
+ * @param pcc_cls closure for 'pcc'
* @return handle to the operation
*/
struct GNUNET_TESTBED_Operation *
-GNUNET_TESTBED_peer_start (struct GNUNET_TESTBED_Peer *peer);
+GNUNET_TESTBED_peer_start (struct GNUNET_TESTBED_Peer *peer,
+ GNUNET_TESTBED_PeerChurnCallback pcc,
+ void *pcc_cls);
/**
* state of the peer).
*
* @param peer peer to stop
+ * @param pcc function to call upon completion
+ * @param pcc_cls closure for 'pcc'
* @return handle to the operation
*/
struct GNUNET_TESTBED_Operation *
-GNUNET_TESTBED_peer_stop (struct GNUNET_TESTBED_Peer *peer);
+GNUNET_TESTBED_peer_stop (struct GNUNET_TESTBED_Peer *peer,
+ GNUNET_TESTBED_PeerChurnCallback pcc,
+ void *pcc_cls);
+
+
+/**
+ * Data returned from GNUNET_TESTBED_peer_get_information
+ */
+struct GNUNET_TESTBED_PeerInformation
+{
+ /**
+ * Peer information type; captures which of the types
+ * in the 'op_result' is actually in use.
+ */
+ enum GNUNET_TESTBED_PeerInformationType pit;
+
+ /**
+ * The result of the get information operation; Choose according to the pit
+ */
+ union
+ {
+ /**
+ * The configuration of the peer
+ */
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ /**
+ * The identity of the peer
+ */
+ struct GNUNET_PeerIdentity *id;
+ } result;
+};
/**
- * Request information about a peer.
+ * Callback to be called when the requested peer information is available
+ *
+ * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information()
+ * @param op the operation this callback corresponds to
+ * @param pinfo the result; will be NULL if the operation has failed
+ * @param emsg error message if the operation has failed; will be NULL if the
+ * operation is successfull
+ */
+typedef void (*GNUNET_TESTBED_PeerInfoCallback) (void *cb_cls,
+ struct GNUNET_TESTBED_Operation
+ *op,
+ const struct
+ GNUNET_TESTBED_PeerInformation
+ *pinfo,
+ const char *emsg);
+
+
+/**
+ * Request information about a peer. The controller callback will not be called
+ * with event type GNUNET_TESTBED_ET_OPERATION_FINISHED when result for this
+ * operation is available. Instead, the GNUNET_TESTBED_PeerInfoCallback() will
+ * be called.
*
* @param peer peer to request information about
* @param pit desired information
+ * @param cb the convenience callback to be called when results for this
+ * operation are available
+ * @param cb_cls the closure for the above callback
* @return handle to the operation
*/
struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_peer_get_information (struct GNUNET_TESTBED_Peer *peer,
- enum GNUNET_TESTBED_PeerInformationType pit);
+ enum GNUNET_TESTBED_PeerInformationType
+ pit,
+ GNUNET_TESTBED_PeerInfoCallback cb,
+ void *cb_cls);
/**
* and asks 'p2' to connect to 'p1'.
*
* @param op_cls closure argument to give with the operation event
+ * @param cb the callback to call when this operation has finished
+ * @param cb_cls the closure for the above callback
* @param p1 first peer
* @param p2 second peer
* @return handle to the operation, NULL if connecting these two
*/
struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_overlay_connect (void *op_cls,
+ GNUNET_TESTBED_OperationCompletionCallback cb,
+ void *cb_cls,
struct GNUNET_TESTBED_Peer *p1,
struct GNUNET_TESTBED_Peer *p2);
* @param va topology-specific options
* @return handle to the operation, NULL if connecting these
* peers is fundamentally not possible at this time (peers
- * not running or underlay disallows)
+ * not running or underlay disallows) or if num_peers is less than 2
*/
struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls,
unsigned int num_peers,
- struct GNUNET_TESTBED_Peer *peers,
+ struct GNUNET_TESTBED_Peer **peers,
enum GNUNET_TESTBED_TopologyOption topo,
va_list va);
* @param ... topology-specific options
* @return handle to the operation, NULL if connecting these
* peers is fundamentally not possible at this time (peers
- * not running or underlay disallows)
+ * not running or underlay disallows) or if num_peers is less than 2
*/
struct GNUNET_TESTBED_Operation *
GNUNET_TESTBED_overlay_configure_topology (void *op_cls,
unsigned int num_peers,
- struct GNUNET_TESTBED_Peer *peers,
+ struct GNUNET_TESTBED_Peer **peers,
enum GNUNET_TESTBED_TopologyOption topo,
...);
* Ask the testbed controller to write the current overlay topology to
* a file. Naturally, the file will only contain a snapshot as the
* topology may evolve all the time.
+ * FIXME: needs continuation!?
*
* @param controller overlay controller to inspect
* @param filename name of the file the topology should
* a service.
*
* @param cls closure
- * @param cfg configuration of the peer to connect to
+ * @param cfg configuration of the peer to connect to; will be available until
+ * GNUNET_TESTBED_operation_done() is called on the operation returned
+ * from GNUNET_TESTBED_service_connect()
* @return service handle to return in 'op_result', NULL on error
*/
typedef void * (*GNUNET_TESTBED_ConnectAdapter)(void *cls,
void *op_result);
+/**
+ * Callback to be called when a service connect operation is completed
+ *
+ * @param cls the callback closure from functions generating an operation
+ * @param op the operation that has been finished
+ * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
+ * @param emsg error message in case the operation has failed; will be NULL if
+ * operation has executed successfully.
+ */
+typedef void (*GNUNET_TESTBED_ServiceConnectCompletionCallback) (void *cls,
+ struct
+ GNUNET_TESTBED_Operation
+ *op,
+ void
+ *ca_result,
+ const char
+ *emsg );
+
+
/**
* Connect to a service offered by the given peer. Will ensure that
* the request is queued to not overwhelm our ability to create and
* @param op_cls closure to pass in operation event
* @param peer peer that runs the service
* @param service_name name of the service to connect to
+ * @param cb the callback to call when this operation finishes
+ * @param cb_cls closure for the above callback
* @param ca helper function to establish the connection
* @param da helper function to close the connection
* @param cada_cls closure for ca and da
GNUNET_TESTBED_service_connect (void *op_cls,
struct GNUNET_TESTBED_Peer *peer,
const char *service_name,
+ GNUNET_TESTBED_ServiceConnectCompletionCallback cb,
+ void *cb_cls,
GNUNET_TESTBED_ConnectAdapter ca,
GNUNET_TESTBED_DisconnectAdapter da,
void *cada_cls);
GNUNET_TESTBED_destroy (struct GNUNET_TESTBED_Testbed *testbed);
+/**
+ * Callback function to process statistic values from all peers.
+ *
+ * @param cls closure
+ * @param peer the peer the statistic belong to
+ * @param subsystem name of subsystem that created the statistic
+ * @param name the name of the datum
+ * @param value the current value
+ * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
+ * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
+ */
+typedef int (*GNUNET_TESTBED_StatisticsIterator) (void *cls,
+ const struct GNUNET_TESTBED_Peer *peer,
+ const char *subsystem,
+ const char *name,
+ uint64_t value,
+ int is_persistent);
+
+
+/**
+ * Convenience method that iterates over all (running) peers
+ * and retrieves all statistics from each peer.
+ *
+ * @param num_peers number of peers to iterate over
+ * @param peers array of peers to iterate over
+ * @param proc processing function for each statistic retrieved
+ * @param cont continuation to call once call is completed(?)
+ * @param cls closure to pass to proc and cont
+ * @return operation handle to cancel the operation
+ */
+struct GNUNET_TESTBED_Operation *
+GNUNET_TESTBED_get_statistics (unsigned int num_peers,
+ struct GNUNET_TESTBED_Peer **peers,
+ GNUNET_TESTBED_StatisticsIterator proc,
+ GNUNET_TESTBED_OperationCompletionCallback cont,
+ void *cls);
+
+
/**
* Convenience method for running a testbed with
* a single call. Underlay and overlay topology
* @param host_filename name of the file with the 'hosts', NULL
* to run everything on 'localhost'
* @param cfg configuration to use (for testbed, controller and peers)
- * @param num_peers number of peers to start; FIXME: maybe put that ALSO into cfg?
+ * @param num_peers number of peers to start; FIXME: maybe put that ALSO into
+ * cfg?; should be greater than 0
* @param event_mask bit mask with set of events to call 'cc' for;
* or-ed values of "1LL" shifted by the
* respective 'enum GNUNET_TESTBED_EventType'
* (i.e. "(1LL << GNUNET_TESTBED_ET_CONNECT) || ...")
- * @param cc controller callback to invoke on events
+ * @param cc controller callback to invoke on events; This callback is called
+ * for all peer start events even if GNUNET_TESTBED_ET_PEER_START isn't
+ * set in the event_mask as this is the only way get access to the
+ * handle of each peer
* @param cc_cls closure for cc
* @param master task to run once the testbed is ready
* @param master_cls closure for 'task'.
* @param testname name of the testcase (to configure logging, etc.)
* @param cfg_filename configuration filename to use
* (for testbed, controller and peers)
- * @param num_peers number of peers to start
+ * @param num_peers number of peers to start; should be greter than 0
+ * @param event_mask bit mask with set of events to call 'cc' for;
+ * or-ed values of "1LL" shifted by the
+ * respective 'enum GNUNET_TESTBED_EventType'
+ * (i.e. "(1LL << GNUNET_TESTBED_ET_CONNECT) || ...")
+ * @param cc controller callback to invoke on events; This callback is called
+ * for all peer start events even if GNUNET_TESTBED_ET_PEER_START isn't
+ * set in the event_mask as this is the only way get access to the
+ * handle of each peer
+ * @param cc_cls closure for cc
* @param test_master task to run once the test is ready
* @param test_master_cls closure for 'task'.
*/
GNUNET_TESTBED_test_run (const char *testname,
const char *cfg_filename,
unsigned int num_peers,
+ uint64_t event_mask,
+ GNUNET_TESTBED_ControllerCallback cc,
+ void *cc_cls,
GNUNET_TESTBED_TestMaster test_master,
void *test_master_cls);