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