global reindent, now with uncrustify hook enabled
[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  * Checking configuration diffs
209  */
210 static int
211 checkDiffs (struct GNUNET_CONFIGURATION_Handle *cfg_default, int option)
212 {
213   struct GNUNET_CONFIGURATION_Handle *cfg;
214   struct GNUNET_CONFIGURATION_Handle *cfgDiffs;
215   struct DiffsCBData cbData;
216   int ret;
217   char *diffsFileName;
218
219   initDiffsCBData (&cbData);
220
221   cfg = GNUNET_CONFIGURATION_create ();
222   /* load defaults */
223   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (cfg, NULL));
224
225   /* Modify configuration and save it */
226   cfgDiffs = editConfiguration (cfg, option);
227   diffsFileName = GNUNET_DISK_mktemp ("gnunet-test-configurations-diffs.conf");
228   if (diffsFileName == NULL)
229   {
230     GNUNET_break (0);
231     GNUNET_CONFIGURATION_destroy (cfg);
232     GNUNET_CONFIGURATION_destroy (cfgDiffs);
233     return 1;
234   }
235   GNUNET_CONFIGURATION_write_diffs (cfg_default, cfg, diffsFileName);
236   GNUNET_CONFIGURATION_destroy (cfg);
237
238   /* Compare the dumped configuration with modifications done */
239   cfg = GNUNET_CONFIGURATION_create ();
240   GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, diffsFileName));
241   if (0 != remove (diffsFileName))
242     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "remove",
243                               diffsFileName);
244   cbData.callBackOption = COMPARE;
245   cbData.cfgDiffs = cfgDiffs;
246   GNUNET_CONFIGURATION_iterate (cfg, diffsCallBack, &cbData);
247   if (1 == (ret = cbData.status))
248   {
249     fprintf (stderr, "%s",
250              "Incorrect Configuration Diffs: Diffs may contain data not actually edited\n");
251     goto housekeeping;
252   }
253   cbData.cfgDiffs = cfg;
254   GNUNET_CONFIGURATION_iterate (cfgDiffs, diffsCallBack, &cbData);
255   if ((ret = cbData.status) == 1)
256     fprintf (stderr, "%s",
257              "Incorrect Configuration Diffs: Data may be missing in diffs\n");
258
259 housekeeping:
260 #if 0
261   cbData.section = NULL;
262   cbData.callBackOption = PRINT;
263   printf ("\nExpected Diffs:\n");
264   GNUNET_CONFIGURATION_iterate (cfgDiffs, diffsCallBack, &cbData);
265   cbData.section = NULL;
266   printf ("\nActual Diffs:\n");
267   GNUNET_CONFIGURATION_iterate (cfg, diffsCallBack, &cbData);
268 #endif
269   GNUNET_CONFIGURATION_destroy (cfg);
270   GNUNET_CONFIGURATION_destroy (cfgDiffs);
271   GNUNET_free (diffsFileName);
272   return ret;
273 }
274
275
276 static int
277 testConfig ()
278 {
279   char *c;
280   unsigned long long l;
281
282   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "test", "b", &c))
283     return 1;
284   if (0 != strcmp ("b", c))
285   {
286     fprintf (stderr, "Got `%s'\n", c);
287     GNUNET_free (c);
288     return 2;
289   }
290   GNUNET_free (c);
291   if (GNUNET_OK !=
292       GNUNET_CONFIGURATION_get_value_number (cfg, "test", "five", &l))
293   {
294     GNUNET_break (0);
295     return 3;
296   }
297   if (5 != l)
298   {
299     GNUNET_break (0);
300     return 4;
301   }
302   GNUNET_CONFIGURATION_set_value_string (cfg, "more", "c", "YES");
303   if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_yesno (cfg, "more", "c"))
304   {
305     GNUNET_break (0);
306     return 5;
307   }
308   GNUNET_CONFIGURATION_set_value_number (cfg, "NUMBERS", "TEN", 10);
309   if (GNUNET_OK !=
310       GNUNET_CONFIGURATION_get_value_string (cfg, "NUMBERS", "TEN", &c))
311   {
312     GNUNET_break (0);
313     return 6;
314   }
315   if (0 != strcmp (c, "10"))
316   {
317     GNUNET_free (c);
318     GNUNET_break (0);
319     return 7;
320   }
321   GNUNET_free (c);
322
323   if (GNUNET_OK !=
324       GNUNET_CONFIGURATION_get_value_filename (cfg, "last", "test", &c))
325   {
326     GNUNET_break (0);
327     return 8;
328   }
329
330   if (0 != strcmp (c, "/hello/world"))
331   {
332     GNUNET_break (0);
333     GNUNET_free (c);
334     return 9;
335   }
336   GNUNET_free (c);
337
338   if (GNUNET_OK !=
339       GNUNET_CONFIGURATION_get_value_size (cfg, "last", "size", &l))
340   {
341     GNUNET_break (0);
342     return 10;
343   }
344   if (l != 512 * 1024)
345   {
346     GNUNET_break (0);
347     return 11;
348   }
349   return 0;
350 }
351
352 static const char *want[] = {
353   "/Hello",
354   "/File Name",
355   "/World",
356   NULL,
357   NULL,
358 };
359
360 static int
361 check (void *data, const char *fn)
362 {
363   int *idx = data;
364
365   if (0 == strcmp (want[*idx], fn))
366   {
367     (*idx)++;
368     return GNUNET_OK;
369   }
370   GNUNET_break (0);
371   return GNUNET_SYSERR;
372 }
373
374 static int
375 testConfigFilenames ()
376 {
377   int idx;
378
379   idx = 0;
380   if (3 !=
381       GNUNET_CONFIGURATION_iterate_value_filenames (cfg, "FILENAMES", "test",
382                                                     &check, &idx))
383   {
384     GNUNET_break (0);
385     return 8;
386   }
387   if (idx != 3)
388     return 16;
389   if (GNUNET_OK !=
390       GNUNET_CONFIGURATION_remove_value_filename (cfg, "FILENAMES", "test",
391                                                   "/File Name"))
392   {
393     GNUNET_break (0);
394     return 24;
395   }
396
397   if (GNUNET_NO !=
398       GNUNET_CONFIGURATION_remove_value_filename (cfg, "FILENAMES", "test",
399                                                   "/File Name"))
400   {
401     GNUNET_break (0);
402     return 32;
403   }
404   if (GNUNET_NO !=
405       GNUNET_CONFIGURATION_remove_value_filename (cfg, "FILENAMES", "test",
406                                                   "Stuff"))
407   {
408     GNUNET_break (0);
409     return 40;
410   }
411
412   if (GNUNET_NO !=
413       GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
414                                                   "/Hello"))
415   {
416     GNUNET_break (0);
417     return 48;
418   }
419   if (GNUNET_NO !=
420       GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
421                                                   "/World"))
422   {
423     GNUNET_break (0);
424     return 56;
425   }
426
427   if (GNUNET_YES !=
428       GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
429                                                   "/File 1"))
430   {
431     GNUNET_break (0);
432     return 64;
433   }
434
435   if (GNUNET_YES !=
436       GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
437                                                   "/File 2"))
438   {
439     GNUNET_break (0);
440     return 72;
441   }
442
443   idx = 0;
444   want[1] = "/World";
445   want[2] = "/File 1";
446   want[3] = "/File 2";
447   if (4 !=
448       GNUNET_CONFIGURATION_iterate_value_filenames (cfg, "FILENAMES", "test",
449                                                     &check, &idx))
450   {
451     GNUNET_break (0);
452     return 80;
453   }
454   if (idx != 4)
455   {
456     GNUNET_break (0);
457     return 88;
458   }
459   return 0;
460 }
461
462
463 int
464 main (int argc, char *argv[])
465 {
466   int failureCount = 0;
467   char *c;
468
469   GNUNET_log_setup ("test_configuration", "WARNING", NULL);
470   cfg = GNUNET_CONFIGURATION_create ();
471   GNUNET_assert (cfg != NULL);
472   if (GNUNET_OK !=
473       GNUNET_CONFIGURATION_parse (cfg, "test_configuration_data.conf"))
474   {
475     fprintf (stderr, "%s", "Failed to parse configuration file\n");
476     GNUNET_CONFIGURATION_destroy (cfg);
477     return 1;
478   }
479   failureCount += testConfig ();
480   if (failureCount > 0)
481     goto error;
482
483   failureCount = testConfigFilenames ();
484   if (failureCount > 0)
485     goto error;
486
487   if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, "/tmp/gnunet-test.conf"))
488   {
489     fprintf (stderr, "%s", "Failed to write configuration file\n");
490     GNUNET_CONFIGURATION_destroy (cfg);
491     return 1;
492   }
493   GNUNET_CONFIGURATION_destroy (cfg);
494   GNUNET_assert (0 == unlink ("/tmp/gnunet-test.conf"));
495
496   cfg = GNUNET_CONFIGURATION_create ();
497   if (GNUNET_OK !=
498       GNUNET_CONFIGURATION_load (cfg, "test_configuration_data.conf"))
499   {
500     GNUNET_break (0);
501     GNUNET_CONFIGURATION_destroy (cfg);
502     return 1;
503   }
504   if (GNUNET_OK !=
505       GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "WEAKRANDOM", &c))
506   {
507     GNUNET_break (0);
508     GNUNET_CONFIGURATION_destroy (cfg);
509     return 1;
510   }
511   if (0 != strcmp (c, "YES"))
512   {
513     GNUNET_break (0);
514     GNUNET_free (c);
515     GNUNET_CONFIGURATION_destroy (cfg);
516     return 1;
517   }
518
519   GNUNET_free (c);
520   GNUNET_CONFIGURATION_destroy (cfg);
521
522   /* Testing configuration diffs */
523   cfg_default = GNUNET_CONFIGURATION_create ();
524   if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg_default, NULL))
525   {
526     GNUNET_break (0);
527     GNUNET_CONFIGURATION_destroy (cfg_default);
528     return 1;
529   }
530
531   /* Nothing changed in the new configuration */
532   failureCount += checkDiffs (cfg_default, EDIT_NOTHING);
533
534   /* Modify all entries of the last section */
535   failureCount += checkDiffs (cfg_default, EDIT_SECTION);
536
537   /* Add a new section */
538   failureCount += checkDiffs (cfg_default, ADD_NEW_SECTION);
539
540   /* Add a new entry to the last section */
541   failureCount += checkDiffs (cfg_default, ADD_NEW_ENTRY);
542
543   /* Modify all entries in the configuration */
544   failureCount += checkDiffs (cfg_default, EDIT_ALL);
545
546   GNUNET_CONFIGURATION_destroy (cfg_default);
547
548 error:
549   if (failureCount != 0)
550   {
551     fprintf (stderr, "Test failed: %u\n", failureCount);
552     return 1;
553   }
554   return 0;
555 }