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