gnunet_testing_lib.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. /*
  2. This file is part of GNUnet
  3. Copyright (C) 2008, 2009, 2012 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @author Christian Grothoff
  18. *
  19. * @file
  20. * Convenience API for writing testcases for GNUnet
  21. *
  22. * @defgroup testing Testing library
  23. * Library for writing testcases for GNUnet.
  24. *
  25. * It can start/stop one or more peers on a system; testing is responsible for
  26. * managing private keys, ports and paths; it is a low-level library that does
  27. * not support higher-level functions such as P2P connection, topology
  28. * management or distributed testbed maintenance (those are provided by the
  29. * [Testbed service](@ref testbed))
  30. *
  31. * @see [Documentation](https://gnunet.org/writing_testcases)
  32. *
  33. * @{
  34. */
  35. #ifndef GNUNET_TESTING_LIB_H
  36. #define GNUNET_TESTING_LIB_H
  37. #include "gnunet_util_lib.h"
  38. #include "gnunet_statistics_service.h"
  39. #include "gnunet_arm_service.h"
  40. #ifdef __cplusplus
  41. extern "C"
  42. {
  43. #if 0 /* keep Emacsens' auto-indent happy */
  44. }
  45. #endif
  46. #endif
  47. /**
  48. * Size of each hostkey in the hostkey file (in BYTES).
  49. */
  50. #define GNUNET_TESTING_HOSTKEYFILESIZE sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)
  51. /**
  52. * The environmental variable, if set, that dictates where testing should place
  53. * generated peer configurations
  54. */
  55. #define GNUNET_TESTING_PREFIX "GNUNET_TESTING_PREFIX"
  56. /**
  57. * Handle for a system on which GNUnet peers are executed;
  58. * a system is used for reserving unique paths and ports.
  59. */
  60. struct GNUNET_TESTING_System;
  61. /**
  62. * Handle for a GNUnet peer controlled by testing.
  63. */
  64. struct GNUNET_TESTING_Peer;
  65. /**
  66. * Specification of a service that is to be shared among peers
  67. */
  68. struct GNUNET_TESTING_SharedService
  69. {
  70. /**
  71. * The name of the service.
  72. */
  73. const char *service;
  74. /**
  75. * The configuration template for the service. Cannot be NULL
  76. */
  77. const struct GNUNET_CONFIGURATION_Handle *cfg;
  78. /**
  79. * The number of peers which share an instance of the service. 0 for sharing
  80. * among all peers
  81. */
  82. unsigned int share;
  83. };
  84. /**
  85. * Create a system handle. There must only be one system handle per operating
  86. * system. Uses a default range for allowed ports. Ports are still tested for
  87. * availability.
  88. *
  89. * @param testdir only the directory name without any path. This is used for all
  90. * service homes; the directory will be created in a temporary location
  91. * depending on the underlying OS. This variable will be
  92. * overridden with the value of the environmental variable
  93. * GNUNET_TESTING_PREFIX, if it exists.
  94. * @param trusted_ip the ip address which will be set as TRUSTED HOST in all
  95. * service configurations generated to allow control connections from
  96. * this ip. This can either be a single ip address or a network address
  97. * in CIDR notation.
  98. * @param hostname the hostname of the system we are using for testing; NULL for
  99. * localhost
  100. * @param shared_services NULL terminated array describing services that are to
  101. * be shared among peers
  102. * @return handle to this system, NULL on error
  103. */
  104. struct GNUNET_TESTING_System *
  105. GNUNET_TESTING_system_create (const char *testdir,
  106. const char *trusted_ip,
  107. const char *hostname,
  108. const struct GNUNET_TESTING_SharedService *
  109. shared_services);
  110. /**
  111. * Create a system handle. There must only be one system
  112. * handle per operating system. Use this function directly
  113. * if multiple system objects are created for the same host
  114. * (only really useful when testing --- or to make the port
  115. * range configureable).
  116. *
  117. * @param testdir only the directory name without any path. This is used for
  118. * all service homes; the directory will be created in a temporary
  119. * location depending on the underlying OS. This variable will be
  120. * overridden with the value of the environmental variable
  121. * GNUNET_TESTING_PREFIX, if it exists.
  122. * @param trusted_ip the ip address which will be set as TRUSTED HOST in all
  123. * service configurations generated to allow control connections from
  124. * this ip. This can either be a single ip address or a network address
  125. * in CIDR notation.
  126. * @param hostname the hostname of the system we are using for testing; NULL for
  127. * localhost
  128. * @param shared_services NULL terminated array describing services that are to
  129. * be shared among peers
  130. * @param lowport lowest port number this system is allowed to allocate (inclusive)
  131. * @param highport highest port number this system is allowed to allocate (exclusive)
  132. * @return handle to this system, NULL on error
  133. */
  134. struct GNUNET_TESTING_System *
  135. GNUNET_TESTING_system_create_with_portrange (const char *testdir,
  136. const char *trusted_ip,
  137. const char *hostname,
  138. const struct GNUNET_TESTING_SharedService *shared_services,
  139. uint16_t lowport,
  140. uint16_t highport);
  141. /**
  142. * Free system resources.
  143. *
  144. * @param system system to be freed
  145. * @param remove_paths should the 'testdir' and all subdirectories
  146. * be removed (clean up on shutdown)?
  147. */
  148. void
  149. GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system,
  150. int remove_paths);
  151. /**
  152. * Testing includes a number of pre-created hostkeys for
  153. * faster peer startup. This function can be used to
  154. * access the n-th key of those pre-created hostkeys; note
  155. * that these keys are ONLY useful for testing and not
  156. * secure as the private keys are part of the public
  157. * GNUnet source code.
  158. *
  159. * This is primarily a helper function used internally
  160. * by #GNUNET_TESTING_peer_configure().
  161. *
  162. * @param system the testing system handle
  163. * @param key_number desired pre-created hostkey to obtain
  164. * @param id set to the peer's identity (hash of the public
  165. * key; if NULL, #GNUNET_SYSERR is returned immediately
  166. * @return NULL on error (not enough keys)
  167. */
  168. struct GNUNET_CRYPTO_EddsaPrivateKey *
  169. GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system,
  170. uint32_t key_number,
  171. struct GNUNET_PeerIdentity *id);
  172. /**
  173. * Reserve a port for a peer.
  174. *
  175. * @param system system to use for reservation tracking
  176. * @return 0 if no free port was available
  177. */
  178. uint16_t
  179. GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system);
  180. /**
  181. * Release reservation of a TCP or UDP port for a peer
  182. * (used during GNUNET_TESTING_peer_destroy).
  183. *
  184. * @param system system to use for reservation tracking
  185. * @param port reserved port to release
  186. */
  187. void
  188. GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system,
  189. uint16_t port);
  190. /**
  191. * Create a new configuration using the given configuration as a template;
  192. * ports and paths will be modified to select available ports on the local
  193. * system. The default configuration will be available in PATHS section under
  194. * the option DEFAULTCONFIG after the call. SERVICE_HOME is also set in PATHS
  195. * section to the temporary directory specific to this configuration. If we run
  196. * out of "*port" numbers, return #GNUNET_SYSERR.
  197. *
  198. * This is primarily a helper function used internally
  199. * by #GNUNET_TESTING_peer_configure().
  200. *
  201. * @param system system to use to coordinate resource usage
  202. * @param cfg template configuration to update
  203. * @return #GNUNET_OK on success,
  204. * #GNUNET_SYSERR on error - the configuration will
  205. * be incomplete and should not be used there upon
  206. */
  207. int
  208. GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system,
  209. struct GNUNET_CONFIGURATION_Handle *cfg);
  210. // FIXME: add dual to 'release' ports again...
  211. /**
  212. * Configure a GNUnet peer. GNUnet must be installed on the local
  213. * system and available in the PATH.
  214. *
  215. * @param system system to use to coordinate resource usage
  216. * @param cfg configuration to use; will be UPDATED (to reflect needed
  217. * changes in port numbers and paths)
  218. * @param key_number number of the hostkey to use for the peer
  219. * @param id identifier for the daemon, will be set, can be NULL
  220. * @param emsg set to freshly allocated error message (set to NULL on success),
  221. * can be NULL
  222. * @return handle to the peer, NULL on error
  223. */
  224. struct GNUNET_TESTING_Peer *
  225. GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system,
  226. struct GNUNET_CONFIGURATION_Handle *cfg,
  227. uint32_t key_number,
  228. struct GNUNET_PeerIdentity *id,
  229. char **emsg);
  230. /**
  231. * Obtain the peer identity from a peer handle.
  232. *
  233. * @param peer peer handle for which we want the peer's identity
  234. * @param id identifier for the daemon, will be set
  235. */
  236. void
  237. GNUNET_TESTING_peer_get_identity (struct GNUNET_TESTING_Peer *peer,
  238. struct GNUNET_PeerIdentity *id);
  239. /**
  240. * Start the peer.
  241. *
  242. * @param peer peer to start
  243. * @return #GNUNET_OK on success,
  244. * #GNUNET_SYSERR on error (i.e. peer already running)
  245. */
  246. int
  247. GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer);
  248. /**
  249. * Stop the peer. This call is blocking as it kills the peer's main ARM process
  250. * by sending a SIGTERM and waits on it. For asynchronous shutdown of peer, see
  251. * GNUNET_TESTING_peer_stop_async().
  252. *
  253. * @param peer peer to stop
  254. * @return #GNUNET_OK on success,
  255. * #GNUNET_SYSERR on error (i.e. peer not running)
  256. */
  257. int
  258. GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer);
  259. /**
  260. * Destroy the peer. Releases resources locked during peer configuration.
  261. * If the peer is still running, it will be stopped AND a warning will be
  262. * printed (users of the API should stop the peer explicitly first).
  263. *
  264. * @param peer peer to destroy
  265. */
  266. void
  267. GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer);
  268. /**
  269. * Sends SIGTERM to the peer's main process
  270. *
  271. * @param peer the handle to the peer
  272. * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL
  273. * or upon any error while sending SIGTERM
  274. */
  275. int
  276. GNUNET_TESTING_peer_kill (struct GNUNET_TESTING_Peer *peer);
  277. /**
  278. * Waits for a peer to terminate. The peer's main process will also be destroyed.
  279. *
  280. * @param peer the handle to the peer
  281. * @return #GNUNET_OK if successful; #GNUNET_SYSERR if the main process is NULL
  282. * or upon any error while waiting
  283. */
  284. int
  285. GNUNET_TESTING_peer_wait (struct GNUNET_TESTING_Peer *peer);
  286. /**
  287. * Callback to inform whether the peer is running or stopped.
  288. *
  289. * @param cls the closure given to GNUNET_TESTING_peer_stop_async()
  290. * @param peer the respective peer whose status is being reported
  291. * @param success #GNUNET_YES if the peer is stopped; #GNUNET_SYSERR upon any
  292. * error
  293. */
  294. typedef void
  295. (*GNUNET_TESTING_PeerStopCallback) (void *cls,
  296. struct GNUNET_TESTING_Peer *peer,
  297. int success);
  298. /**
  299. * Stop a peer asynchronously using ARM API. Peer's shutdown is signaled
  300. * through the GNUNET_TESTING_PeerStopCallback().
  301. *
  302. * @param peer the peer to stop
  303. * @param cb the callback to signal peer shutdown
  304. * @param cb_cls closure for the @a cb
  305. * @return #GNUNET_OK upon successfully giving the request to the ARM API (this
  306. * does not mean that the peer is successfully stopped); #GNUNET_SYSERR
  307. * upon any error.
  308. */
  309. int
  310. GNUNET_TESTING_peer_stop_async (struct GNUNET_TESTING_Peer *peer,
  311. GNUNET_TESTING_PeerStopCallback cb,
  312. void *cb_cls);
  313. /**
  314. * Cancel a previous asynchronous peer stop request.
  315. * GNUNET_TESTING_peer_stop_async() should have been called before on the given
  316. * peer. It is an error to call this function if the peer stop callback was
  317. * already called
  318. *
  319. * @param peer the peer on which GNUNET_TESTING_peer_stop_async() was called
  320. * before.
  321. */
  322. void
  323. GNUNET_TESTING_peer_stop_async_cancel (struct GNUNET_TESTING_Peer *peer);
  324. /**
  325. * Signature of the 'main' function for a (single-peer) testcase that
  326. * is run using #GNUNET_TESTING_peer_run().
  327. *
  328. * @param cls closure
  329. * @param cfg configuration of the peer that was started
  330. * @param peer identity of the peer that was created
  331. */
  332. typedef void
  333. (*GNUNET_TESTING_TestMain) (void *cls,
  334. const struct GNUNET_CONFIGURATION_Handle *cfg,
  335. struct GNUNET_TESTING_Peer *peer);
  336. /**
  337. * Start a single peer and run a test using the testing library.
  338. * Starts a peer using the given configuration and then invokes the
  339. * given callback. This function ALSO initializes the scheduler loop
  340. * and should thus be called directly from "main". The testcase
  341. * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'.
  342. *
  343. * @param testdir only the directory name without any path. This is used for
  344. * all service homes; the directory will be created in a temporary
  345. * location depending on the underlying OS
  346. * @param cfgfilename name of the configuration file to use;
  347. * use NULL to only run with defaults
  348. * @param tm main function of the testcase
  349. * @param tm_cls closure for 'tm'
  350. * @return 0 on success, 1 on error
  351. */
  352. int
  353. GNUNET_TESTING_peer_run (const char *testdir,
  354. const char *cfgfilename,
  355. GNUNET_TESTING_TestMain tm,
  356. void *tm_cls);
  357. /**
  358. * Start a single service (no ARM, except of course if the given
  359. * service name is 'arm') and run a test using the testing library.
  360. * Starts a service using the given configuration and then invokes the
  361. * given callback. This function ALSO initializes the scheduler loop
  362. * and should thus be called directly from "main". The testcase
  363. * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'.
  364. *
  365. * This function is useful if the testcase is for a single service
  366. * and if that service doesn't itself depend on other services.
  367. *
  368. * @param testdir only the directory name without any path. This is used for
  369. * all service homes; the directory will be created in a temporary
  370. * location depending on the underlying OS
  371. * @param service_name name of the service to run
  372. * @param cfgfilename name of the configuration file to use;
  373. * use NULL to only run with defaults
  374. * @param tm main function of the testcase
  375. * @param tm_cls closure for @a tm
  376. * @return 0 on success, 1 on error
  377. */
  378. int
  379. GNUNET_TESTING_service_run (const char *testdir,
  380. const char *service_name,
  381. const char *cfgfilename,
  382. GNUNET_TESTING_TestMain tm,
  383. void *tm_cls);
  384. /**
  385. * Sometimes we use the binary name to determine which specific
  386. * test to run. In those cases, the string after the last "_"
  387. * in 'argv[0]' specifies a string that determines the configuration
  388. * file or plugin to use.
  389. *
  390. * This function returns the respective substring, taking care
  391. * of issues such as binaries ending in '.exe' on W32.
  392. *
  393. * @param argv0 the name of the binary
  394. * @return string between the last '_' and the '.exe' (or the end of the string),
  395. * NULL if argv0 has no '_'
  396. */
  397. char *
  398. GNUNET_TESTING_get_testname_from_underscore (const char *argv0);
  399. #if 0 /* keep Emacsens' auto-indent happy */
  400. {
  401. #endif
  402. #ifdef __cplusplus
  403. }
  404. #endif
  405. #endif
  406. /** @} */ /* end of group */