test_configuration.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2003, 2004, 2005, 2006, 2007 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. * @file util/test_configuration.c
  18. * @brief Test that the configuration module works.
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. /* Test Configuration Diffs Options */
  24. enum
  25. {
  26. EDIT_NOTHING,
  27. EDIT_SECTION,
  28. EDIT_ALL,
  29. ADD_NEW_SECTION,
  30. ADD_NEW_ENTRY,
  31. REMOVE_SECTION,
  32. REMOVE_ENTRY,
  33. COMPARE,
  34. PRINT
  35. };
  36. static struct GNUNET_CONFIGURATION_Handle *cfg;
  37. static struct GNUNET_CONFIGURATION_Handle *cfg_default;
  38. struct DiffsCBData
  39. {
  40. struct GNUNET_CONFIGURATION_Handle *cfg;
  41. struct GNUNET_CONFIGURATION_Handle *cfgDiffs;
  42. const char *section;
  43. int callBackOption;
  44. int status;
  45. };
  46. static void
  47. initDiffsCBData (struct DiffsCBData *cbData)
  48. {
  49. cbData->section = NULL;
  50. cbData->cfg = NULL;
  51. cbData->cfgDiffs = NULL;
  52. cbData->callBackOption = -1;
  53. cbData->status = 0;
  54. }
  55. /**
  56. * callback function for modifying
  57. * and comparing configuration
  58. */
  59. static void
  60. diffsCallBack (void *cls,
  61. const char *section,
  62. const char *option,
  63. const char *value)
  64. {
  65. struct DiffsCBData *cbData = cls;
  66. int cbOption = cbData->callBackOption;
  67. if (0 == strcasecmp ("PATHS",
  68. section))
  69. return;
  70. switch (cbOption)
  71. {
  72. case EDIT_SECTION:
  73. if (NULL == cbData->section)
  74. cbData->section = section;
  75. if (strcmp (cbData->section, section) == 0)
  76. {
  77. GNUNET_CONFIGURATION_set_value_string (cbData->cfg, section, option,
  78. "new-value");
  79. GNUNET_CONFIGURATION_set_value_string (cbData->cfgDiffs, section, option,
  80. "new-value");
  81. }
  82. break;
  83. case EDIT_ALL:
  84. GNUNET_CONFIGURATION_set_value_string (cbData->cfg, section, option,
  85. "new-value");
  86. GNUNET_CONFIGURATION_set_value_string (cbData->cfgDiffs, section, option,
  87. "new-value");
  88. break;
  89. case ADD_NEW_ENTRY:
  90. {
  91. static int hit = 0;
  92. if (hit == 0)
  93. {
  94. hit = 1;
  95. GNUNET_CONFIGURATION_set_value_string (cbData->cfg, section, "new-key",
  96. "new-value");
  97. GNUNET_CONFIGURATION_set_value_string (cbData->cfgDiffs, section,
  98. "new-key", "new-value");
  99. }
  100. break;
  101. }
  102. case COMPARE:
  103. {
  104. int ret;
  105. char *diffValue;
  106. diffValue = NULL;
  107. ret =
  108. GNUNET_CONFIGURATION_get_value_string (cbData->cfgDiffs,
  109. section,
  110. option,
  111. &diffValue);
  112. if (NULL != diffValue)
  113. {
  114. if ( (ret == GNUNET_SYSERR) ||
  115. (strcmp (diffValue, value) != 0) )
  116. {
  117. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  118. "Unexpected value %s in %s/%s\n",
  119. diffValue,
  120. section,
  121. option);
  122. cbData->status = 1;
  123. }
  124. }
  125. else
  126. {
  127. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  128. "Unexpected value %s in %s/%s\n",
  129. diffValue,
  130. section,
  131. option);
  132. cbData->status = 1;
  133. }
  134. GNUNET_free (diffValue);
  135. break;
  136. }
  137. #if 0
  138. case PRINT:
  139. if (NULL == cbData->section)
  140. {
  141. cbData->section = section;
  142. printf ("\nSection: %s\n", section);
  143. }
  144. else if (strcmp (cbData->section, section) != 0)
  145. {
  146. cbData->section = section;
  147. printf ("\nSection: %s\n", section);
  148. }
  149. printf ("%s = %s\n", option, value);
  150. #endif
  151. default:
  152. break;
  153. }
  154. }
  155. static struct GNUNET_CONFIGURATION_Handle *
  156. editConfiguration (struct GNUNET_CONFIGURATION_Handle *cfg,
  157. int option)
  158. {
  159. struct DiffsCBData diffsCB;
  160. initDiffsCBData (&diffsCB);
  161. diffsCB.cfgDiffs = GNUNET_CONFIGURATION_create ();
  162. switch (option)
  163. {
  164. case EDIT_SECTION:
  165. case EDIT_ALL:
  166. case ADD_NEW_ENTRY:
  167. diffsCB.callBackOption = option;
  168. diffsCB.cfg = cfg;
  169. GNUNET_CONFIGURATION_iterate (cfg, diffsCallBack, &diffsCB);
  170. break;
  171. case EDIT_NOTHING:
  172. /* Do nothing */
  173. break;
  174. case ADD_NEW_SECTION:
  175. {
  176. int i;
  177. char *key;
  178. for (i = 0; i < 5; i++)
  179. {
  180. GNUNET_asprintf (&key, "key%d", i);
  181. GNUNET_CONFIGURATION_set_value_string (cfg, "new-section", key,
  182. "new-value");
  183. GNUNET_CONFIGURATION_set_value_string (diffsCB.cfgDiffs, "new-section",
  184. key, "new-value");
  185. GNUNET_free (key);
  186. }
  187. break;
  188. }
  189. case REMOVE_SECTION:
  190. break;
  191. case REMOVE_ENTRY:
  192. break;
  193. default:
  194. break;
  195. }
  196. return diffsCB.cfgDiffs;
  197. }
  198. /**
  199. * Checking configuration diffs
  200. */
  201. static int
  202. checkDiffs (struct GNUNET_CONFIGURATION_Handle *cfg_default, int option)
  203. {
  204. struct GNUNET_CONFIGURATION_Handle *cfg;
  205. struct GNUNET_CONFIGURATION_Handle *cfgDiffs;
  206. struct DiffsCBData cbData;
  207. int ret;
  208. char *diffsFileName;
  209. initDiffsCBData (&cbData);
  210. cfg = GNUNET_CONFIGURATION_create ();
  211. /* load defaults */
  212. GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (cfg, NULL));
  213. /* Modify configuration and save it */
  214. cfgDiffs = editConfiguration (cfg, option);
  215. diffsFileName = GNUNET_DISK_mktemp ("gnunet-test-configurations-diffs.conf");
  216. if (diffsFileName == NULL)
  217. {
  218. GNUNET_break (0);
  219. GNUNET_CONFIGURATION_destroy (cfg);
  220. GNUNET_CONFIGURATION_destroy (cfgDiffs);
  221. return 1;
  222. }
  223. GNUNET_CONFIGURATION_write_diffs (cfg_default, cfg, diffsFileName);
  224. GNUNET_CONFIGURATION_destroy (cfg);
  225. /* Compare the dumped configuration with modifications done */
  226. cfg = GNUNET_CONFIGURATION_create ();
  227. GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, diffsFileName));
  228. if (0 != remove (diffsFileName))
  229. GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "remove",
  230. diffsFileName);
  231. cbData.callBackOption = COMPARE;
  232. cbData.cfgDiffs = cfgDiffs;
  233. GNUNET_CONFIGURATION_iterate (cfg,
  234. &diffsCallBack,
  235. &cbData);
  236. if (1 == (ret = cbData.status))
  237. {
  238. fprintf (stderr, "%s",
  239. "Incorrect Configuration Diffs: Diffs may contain data not actually edited\n");
  240. goto housekeeping;
  241. }
  242. cbData.cfgDiffs = cfg;
  243. GNUNET_CONFIGURATION_iterate (cfgDiffs, diffsCallBack, &cbData);
  244. if ((ret = cbData.status) == 1)
  245. fprintf (stderr, "%s",
  246. "Incorrect Configuration Diffs: Data may be missing in diffs\n");
  247. housekeeping:
  248. #if 0
  249. cbData.section = NULL;
  250. cbData.callBackOption = PRINT;
  251. printf ("\nExpected Diffs:\n");
  252. GNUNET_CONFIGURATION_iterate (cfgDiffs, diffsCallBack, &cbData);
  253. cbData.section = NULL;
  254. printf ("\nActual Diffs:\n");
  255. GNUNET_CONFIGURATION_iterate (cfg, diffsCallBack, &cbData);
  256. #endif
  257. GNUNET_CONFIGURATION_destroy (cfg);
  258. GNUNET_CONFIGURATION_destroy (cfgDiffs);
  259. GNUNET_free (diffsFileName);
  260. return ret;
  261. }
  262. static int
  263. testConfig ()
  264. {
  265. char *c;
  266. unsigned long long l;
  267. if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "test", "b", &c))
  268. return 1;
  269. if (0 != strcmp ("b", c))
  270. {
  271. fprintf (stderr, "Got `%s'\n", c);
  272. GNUNET_free (c);
  273. return 2;
  274. }
  275. GNUNET_free (c);
  276. if (GNUNET_OK !=
  277. GNUNET_CONFIGURATION_get_value_number (cfg, "test", "five", &l))
  278. {
  279. GNUNET_break (0);
  280. return 3;
  281. }
  282. if (5 != l)
  283. {
  284. GNUNET_break (0);
  285. return 4;
  286. }
  287. GNUNET_CONFIGURATION_set_value_string (cfg, "more", "c", "YES");
  288. if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_yesno (cfg, "more", "c"))
  289. {
  290. GNUNET_break (0);
  291. return 5;
  292. }
  293. GNUNET_CONFIGURATION_set_value_number (cfg, "NUMBERS", "TEN", 10);
  294. if (GNUNET_OK !=
  295. GNUNET_CONFIGURATION_get_value_string (cfg, "NUMBERS", "TEN", &c))
  296. {
  297. GNUNET_break (0);
  298. return 6;
  299. }
  300. if (0 != strcmp (c, "10"))
  301. {
  302. GNUNET_free (c);
  303. GNUNET_break (0);
  304. return 7;
  305. }
  306. GNUNET_free (c);
  307. if (GNUNET_OK !=
  308. GNUNET_CONFIGURATION_get_value_filename (cfg, "last", "test", &c))
  309. {
  310. GNUNET_break (0);
  311. return 8;
  312. }
  313. if (0 != strcmp (c, "/hello/world"))
  314. {
  315. GNUNET_break (0);
  316. GNUNET_free (c);
  317. return 9;
  318. }
  319. GNUNET_free (c);
  320. if (GNUNET_OK !=
  321. GNUNET_CONFIGURATION_get_value_size (cfg, "last", "size", &l))
  322. {
  323. GNUNET_break (0);
  324. return 10;
  325. }
  326. if (l != 512 * 1024)
  327. {
  328. GNUNET_break (0);
  329. return 11;
  330. }
  331. return 0;
  332. }
  333. static const char *want[] = {
  334. "/Hello",
  335. "/File Name",
  336. "/World",
  337. NULL,
  338. NULL,
  339. };
  340. static int
  341. check (void *data, const char *fn)
  342. {
  343. int *idx = data;
  344. if (0 == strcmp (want[*idx], fn))
  345. {
  346. (*idx)++;
  347. return GNUNET_OK;
  348. }
  349. GNUNET_break (0);
  350. return GNUNET_SYSERR;
  351. }
  352. static int
  353. testConfigFilenames ()
  354. {
  355. int idx;
  356. idx = 0;
  357. if (3 !=
  358. GNUNET_CONFIGURATION_iterate_value_filenames (cfg, "FILENAMES", "test",
  359. &check, &idx))
  360. {
  361. GNUNET_break (0);
  362. return 8;
  363. }
  364. if (idx != 3)
  365. return 16;
  366. if (GNUNET_OK !=
  367. GNUNET_CONFIGURATION_remove_value_filename (cfg, "FILENAMES", "test",
  368. "/File Name"))
  369. {
  370. GNUNET_break (0);
  371. return 24;
  372. }
  373. if (GNUNET_NO !=
  374. GNUNET_CONFIGURATION_remove_value_filename (cfg, "FILENAMES", "test",
  375. "/File Name"))
  376. {
  377. GNUNET_break (0);
  378. return 32;
  379. }
  380. if (GNUNET_NO !=
  381. GNUNET_CONFIGURATION_remove_value_filename (cfg, "FILENAMES", "test",
  382. "Stuff"))
  383. {
  384. GNUNET_break (0);
  385. return 40;
  386. }
  387. if (GNUNET_NO !=
  388. GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
  389. "/Hello"))
  390. {
  391. GNUNET_break (0);
  392. return 48;
  393. }
  394. if (GNUNET_NO !=
  395. GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
  396. "/World"))
  397. {
  398. GNUNET_break (0);
  399. return 56;
  400. }
  401. if (GNUNET_YES !=
  402. GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
  403. "/File 1"))
  404. {
  405. GNUNET_break (0);
  406. return 64;
  407. }
  408. if (GNUNET_YES !=
  409. GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
  410. "/File 2"))
  411. {
  412. GNUNET_break (0);
  413. return 72;
  414. }
  415. idx = 0;
  416. want[1] = "/World";
  417. want[2] = "/File 1";
  418. want[3] = "/File 2";
  419. if (4 !=
  420. GNUNET_CONFIGURATION_iterate_value_filenames (cfg, "FILENAMES", "test",
  421. &check, &idx))
  422. {
  423. GNUNET_break (0);
  424. return 80;
  425. }
  426. if (idx != 4)
  427. {
  428. GNUNET_break (0);
  429. return 88;
  430. }
  431. return 0;
  432. }
  433. int
  434. main (int argc, char *argv[])
  435. {
  436. int failureCount = 0;
  437. char *c;
  438. GNUNET_log_setup ("test_configuration", "WARNING", NULL);
  439. cfg = GNUNET_CONFIGURATION_create ();
  440. GNUNET_assert (cfg != NULL);
  441. if (GNUNET_OK !=
  442. GNUNET_CONFIGURATION_parse (cfg, "test_configuration_data.conf"))
  443. {
  444. fprintf (stderr, "%s", "Failed to parse configuration file\n");
  445. GNUNET_CONFIGURATION_destroy (cfg);
  446. return 1;
  447. }
  448. failureCount += testConfig ();
  449. if (failureCount > 0)
  450. goto error;
  451. failureCount = testConfigFilenames ();
  452. if (failureCount > 0)
  453. goto error;
  454. if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, "/tmp/gnunet-test.conf"))
  455. {
  456. fprintf (stderr, "%s", "Failed to write configuration file\n");
  457. GNUNET_CONFIGURATION_destroy (cfg);
  458. return 1;
  459. }
  460. GNUNET_CONFIGURATION_destroy (cfg);
  461. GNUNET_assert (0 == unlink ("/tmp/gnunet-test.conf"));
  462. cfg = GNUNET_CONFIGURATION_create ();
  463. if (GNUNET_OK !=
  464. GNUNET_CONFIGURATION_load (cfg, "test_configuration_data.conf"))
  465. {
  466. GNUNET_break (0);
  467. GNUNET_CONFIGURATION_destroy (cfg);
  468. return 1;
  469. }
  470. if (GNUNET_OK !=
  471. GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "WEAKRANDOM", &c))
  472. {
  473. GNUNET_break (0);
  474. GNUNET_CONFIGURATION_destroy (cfg);
  475. return 1;
  476. }
  477. if (0 != strcmp (c, "YES"))
  478. {
  479. GNUNET_break (0);
  480. GNUNET_free (c);
  481. GNUNET_CONFIGURATION_destroy (cfg);
  482. return 1;
  483. }
  484. GNUNET_free (c);
  485. GNUNET_CONFIGURATION_destroy (cfg);
  486. /* Testing configuration diffs */
  487. cfg_default = GNUNET_CONFIGURATION_create ();
  488. if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg_default, NULL))
  489. {
  490. GNUNET_break (0);
  491. GNUNET_CONFIGURATION_destroy (cfg_default);
  492. return 1;
  493. }
  494. /* Nothing changed in the new configuration */
  495. failureCount += checkDiffs (cfg_default, EDIT_NOTHING);
  496. /* Modify all entries of the last section */
  497. failureCount += checkDiffs (cfg_default, EDIT_SECTION);
  498. /* Add a new section */
  499. failureCount += checkDiffs (cfg_default, ADD_NEW_SECTION);
  500. /* Add a new entry to the last section */
  501. failureCount += checkDiffs (cfg_default, ADD_NEW_ENTRY);
  502. /* Modify all entries in the configuration */
  503. failureCount += checkDiffs (cfg_default, EDIT_ALL);
  504. GNUNET_CONFIGURATION_destroy (cfg_default);
  505. error:
  506. if (failureCount != 0)
  507. {
  508. fprintf (stderr, "Test failed: %u\n", failureCount);
  509. return 1;
  510. }
  511. return 0;
  512. }