gnunet_testing_lib.h 16 KB

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