Returns now GNUNET_SYSERR
[oweals/gnunet.git] / src / util / test_configuration.c
index 4c7f69a146dc59675a9be59d0c8af71d94f124eb..429e03178b2ac45492f0314b5bb7d2656c7756a8 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 #include "platform.h"
 #include "gnunet_common.h"
 #include "gnunet_configuration_lib.h"
+#include "gnunet_disk_lib.h"
+
+#define DEBUG GNUNET_NO
+
+/* Test Configuration Diffs Options */
+enum
+{
+  EDIT_NOTHING,
+  EDIT_SECTION,
+  EDIT_ALL,
+  ADD_NEW_SECTION,
+  ADD_NEW_ENTRY,
+  REMOVE_SECTION,
+  REMOVE_ENTRY,
+  COMPARE
+#if DEBUG
+    , PRINT
+#endif
+};
 
 static struct GNUNET_CONFIGURATION_Handle *cfg;
+static struct GNUNET_CONFIGURATION_Handle *cfgDefault;
+
+struct DiffsCBData
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+  struct GNUNET_CONFIGURATION_Handle *cfgDiffs;
+  const char *section;
+  int callBackOption;
+  int status;
+};
+
+
+static void
+initDiffsCBData (struct DiffsCBData *cbData)
+{
+  cbData->section = NULL;
+  cbData->cfg = NULL;
+  cbData->cfgDiffs = NULL;
+  cbData->callBackOption = -1;
+  cbData->status = 0;
+}
+
+
+/**
+ * callback function for modifying
+ * and comparing configuration
+*/
+static void
+diffsCallBack (void *cls,
+              const char *section, const char *option, const char *value)
+{
+  struct DiffsCBData *cbData = cls;
+  int cbOption = cbData->callBackOption;
+
+  switch (cbOption)
+    {
+    case EDIT_SECTION:
+      if (NULL == cbData->section)
+       cbData->section = section;
+      if (strcmp (cbData->section, section) == 0)
+       {
+         GNUNET_CONFIGURATION_set_value_string (cbData->cfg, section, option,
+                                                "new-value");
+         GNUNET_CONFIGURATION_set_value_string (cbData->cfgDiffs, section,
+                                                option, "new-value");
+       }
+      break;
+    case EDIT_ALL:
+      GNUNET_CONFIGURATION_set_value_string (cbData->cfg, section, option,
+                                            "new-value");
+      GNUNET_CONFIGURATION_set_value_string (cbData->cfgDiffs, section,
+                                            option, "new-value");
+      break;
+    case ADD_NEW_ENTRY:
+      {
+       static int hit = 0;
+       if (hit == 0)
+         {
+           hit = 1;
+           GNUNET_CONFIGURATION_set_value_string (cbData->cfg, section,
+                                                  "new-key", "new-value");
+           GNUNET_CONFIGURATION_set_value_string (cbData->cfgDiffs, section,
+                                                  "new-key", "new-value");
+         }
+       break;
+      }
+    case COMPARE:
+      {
+       int ret;
+       char *diffValue;
+
+       diffValue = NULL;
+       ret =
+         GNUNET_CONFIGURATION_get_value_string (cbData->cfgDiffs, section,
+                                                option, &diffValue);
+       if (NULL != diffValue)
+         {
+           if (ret == GNUNET_SYSERR || strcmp (diffValue, value) != 0)
+             cbData->status = 1;
+         }
+       else
+         cbData->status = 1;
+       GNUNET_free_non_null (diffValue);
+       break;
+      }
+#if DEBUG
+    case PRINT:
+      if (NULL == cbData->section)
+       {
+         cbData->section = section;
+         printf ("\nSection: %s\n", section);
+       }
+      else if (strcmp (cbData->section, section) != 0)
+       {
+         cbData->section = section;
+         printf ("\nSection: %s\n", section);
+       }
+      printf ("%s = %s\n", option, abs_value);
+#endif
+    default:
+      break;
+    }
+}
+
+
+static struct GNUNET_CONFIGURATION_Handle *
+editConfiguration (struct GNUNET_CONFIGURATION_Handle *cfg, int option)
+{
+  struct DiffsCBData diffsCB;
+  initDiffsCBData (&diffsCB);
+  diffsCB.cfgDiffs = GNUNET_CONFIGURATION_create ();
+
+  switch (option)
+    {
+    case EDIT_SECTION:
+    case EDIT_ALL:
+    case ADD_NEW_ENTRY:
+      diffsCB.callBackOption = option;
+      diffsCB.cfg = cfg;
+      GNUNET_CONFIGURATION_iterate (cfg, diffsCallBack, &diffsCB);
+      break;
+    case EDIT_NOTHING:
+      /* Do nothing */
+      break;
+    case ADD_NEW_SECTION:
+      {
+       int i;
+       char *key;
+       for (i = 0; i < 5; i++)
+         {
+           GNUNET_asprintf (&key, "key%d", i);
+           GNUNET_CONFIGURATION_set_value_string (cfg, "new-section", key,
+                                                  "new-value");
+           GNUNET_CONFIGURATION_set_value_string (diffsCB.cfgDiffs,
+                                                  "new-section", key,
+                                                  "new-value");
+           GNUNET_free (key);
+         }
+       break;
+      }
+    case REMOVE_SECTION:
+      break;
+    case REMOVE_ENTRY:
+      break;
+    default:
+      break;
+    }
+
+  return diffsCB.cfgDiffs;
+}
+
+/**
+ * Checking configuration diffs
+ */
+static int
+checkDiffs (struct GNUNET_CONFIGURATION_Handle *cfgDefault, int option)
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+  struct GNUNET_CONFIGURATION_Handle *cfgDiffs;
+  struct DiffsCBData cbData;
+  int ret;
+  char *diffsFileName;
+
+  initDiffsCBData (&cbData);
+
+  cfg = GNUNET_CONFIGURATION_create ();
+  /* load defaults */
+  GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (cfg, NULL));
+
+  /* Modify configuration and save it */
+  cfgDiffs = editConfiguration (cfg, option);
+  diffsFileName =
+    GNUNET_DISK_mktemp ("gnunet-test-configurations-diffs.conf");
+  if (diffsFileName == NULL)
+    {
+      GNUNET_break (0);
+      GNUNET_CONFIGURATION_destroy (cfg);
+      GNUNET_CONFIGURATION_destroy (cfgDiffs);      
+      return 1;
+    }
+  GNUNET_CONFIGURATION_write_diffs (cfgDefault, cfg, diffsFileName);
+  GNUNET_CONFIGURATION_destroy (cfg);
+
+  /* Compare the dumped configuration with modifications done */
+  cfg = GNUNET_CONFIGURATION_create ();
+  GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, diffsFileName));
+  remove (diffsFileName);
+  cbData.callBackOption = COMPARE;
+  cbData.cfgDiffs = cfgDiffs;
+  GNUNET_CONFIGURATION_iterate (cfg, diffsCallBack, &cbData);
+  if (1 == (ret = cbData.status))
+    {
+      fprintf (stderr,
+              "Incorrect Configuration Diffs: Diffs may contain data not actually edited\n");
+      goto housekeeping;
+    }
+  cbData.cfgDiffs = cfg;
+  GNUNET_CONFIGURATION_iterate (cfgDiffs, diffsCallBack, &cbData);
+  if ((ret = cbData.status) == 1)
+    fprintf (stderr,
+            "Incorrect Configuration Diffs: Data may be missing in diffs\n");
+
+housekeeping:
+#if DEBUG
+  cbData.section = NULL;
+  cbData.callBackOption = PRINT;
+  printf ("\nExpected Diffs:\n");
+  GNUNET_CONFIGURATION_iterate (cfgDiffs, diffsCallBack, &cbData);
+  cbData.section = NULL;
+  printf ("\nActual Diffs:\n");
+  GNUNET_CONFIGURATION_iterate (cfg, diffsCallBack, &cbData);
+#endif
+  GNUNET_CONFIGURATION_destroy (cfg);
+  GNUNET_CONFIGURATION_destroy (cfgDiffs);
+  GNUNET_free (diffsFileName);
+  return ret;
+}
+
 
 static int
 testConfig ()
@@ -46,27 +283,43 @@ testConfig ()
     }
   GNUNET_free (c);
   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
-                                                          "test", "five", &l))
-    return 3;
+                                                         "test", "five", &l))
+    {
+      GNUNET_break (0);
+      return 3;
+    }
   if (5 != l)
-    return 4;
+    {
+      GNUNET_break (0);
+      return 4;
+    }
   GNUNET_CONFIGURATION_set_value_string (cfg, "more", "c", "YES");
   if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_yesno (cfg, "more", "c"))
-    return 5;
+    {
+      GNUNET_break (0);
+      return 5;
+    }
   GNUNET_CONFIGURATION_set_value_number (cfg, "NUMBERS", "TEN", 10);
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (cfg, "NUMBERS", "TEN", &c))
-    return 6;
+    {
+      GNUNET_break (0);
+      return 6;
+    }
   if (0 != strcmp (c, "10"))
     {
       GNUNET_free (c);
+      GNUNET_break (0);
       return 7;
     }
   GNUNET_free (c);
 
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_filename (cfg, "last", "test", &c))
-    return 8;
+    {
+      GNUNET_break (0);
+      return 8;
+    }
 #ifndef MINGW
   if (0 != strcmp (c, "/hello/world"))
 #else
@@ -74,6 +327,7 @@ testConfig ()
   if (strstr (c, HI) != c + strlen (c) - strlen (HI))
 #endif
     {
+      GNUNET_break (0);
       GNUNET_free (c);
       return 9;
     }
@@ -100,6 +354,7 @@ check (void *data, const char *fn)
       (*idx)++;
       return GNUNET_OK;
     }
+  GNUNET_break (0);
   return GNUNET_SYSERR;
 }
 
@@ -110,66 +365,97 @@ testConfigFilenames ()
 
   idx = 0;
   if (3 != GNUNET_CONFIGURATION_iterate_value_filenames (cfg,
-                                                         "FILENAMES",
-                                                         "test",
-                                                         &check, &idx))
-    return 8;
+                                                        "FILENAMES",
+                                                        "test",
+                                                        &check, &idx))
+    {
+      GNUNET_break (0);
+      return 8;
+    }
   if (idx != 3)
     return 16;
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_remove_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/File Name"))
-    return 24;
+                                                 "FILENAMES",
+                                                 "test", "/File Name"))
+    {
+      GNUNET_break (0);
+      return 24;
+    }
 
   if (GNUNET_NO !=
       GNUNET_CONFIGURATION_remove_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/File Name"))
-    return 32;
+                                                 "FILENAMES",
+                                                 "test", "/File Name"))
+    {
+      GNUNET_break (0);
+      return 32;
+    }
   if (GNUNET_NO !=
       GNUNET_CONFIGURATION_remove_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "Stuff"))
-    return 40;
+                                                 "FILENAMES",
+                                                 "test", "Stuff"))
+    {
+      GNUNET_break (0);
+      return 40;
+    }
 
   if (GNUNET_NO !=
       GNUNET_CONFIGURATION_append_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/Hello"))
-    return 48;
+                                                 "FILENAMES",
+                                                 "test", "/Hello"))
+    {
+      GNUNET_break (0);
+      return 48;
+    }
   if (GNUNET_NO !=
       GNUNET_CONFIGURATION_append_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/World"))
-    return 56;
+                                                 "FILENAMES",
+                                                 "test", "/World"))
+    {
+      GNUNET_break (0);
+      return 56;
+    }
 
   if (GNUNET_YES !=
       GNUNET_CONFIGURATION_append_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/File 1"))
-    return 64;
+                                                 "FILENAMES",
+                                                 "test", "/File 1"))
+    {
+      GNUNET_break (0);
+      return 64;
+    }
 
   if (GNUNET_YES !=
       GNUNET_CONFIGURATION_append_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/File 2"))
-    return 72;
+                                                 "FILENAMES",
+                                                 "test", "/File 2"))
+    {
+      GNUNET_break (0);
+      return 72;
+    }
 
   idx = 0;
   want[1] = "/World";
   want[2] = "/File 1";
   want[3] = "/File 2";
   if (4 != GNUNET_CONFIGURATION_iterate_value_filenames (cfg,
-                                                         "FILENAMES",
-                                                         "test",
-                                                         &check, &idx))
-    return 80;
+                                                        "FILENAMES",
+                                                        "test",
+                                                        &check, &idx))
+    {
+      GNUNET_break (0);
+      return 80;
+    }
   if (idx != 4)
-    return 88;
+    {
+      GNUNET_break (0);
+      return 88;
+    }
   return 0;
 }
 
+
 int
 main (int argc, char *argv[])
 {
@@ -206,25 +492,51 @@ main (int argc, char *argv[])
       GNUNET_CONFIGURATION_destroy (cfg);
       return 1;
     }
-  if ((GNUNET_OK !=
-       GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "WEAKRANDOM",
-                                              &c))
-      || (0 != strcmp (c, "YES")))
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "WEAKRANDOM",
+                                            &c))
     {
+      GNUNET_break (0);
       GNUNET_CONFIGURATION_destroy (cfg);
       return 1;
     }
-  GNUNET_free (c);
-  if ((GNUNET_OK !=
-       GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", "SERVICEHOME",
-                                              &c))
-      || (0 != strcmp (c, "/var/lib/gnunet/")))
+  if (0 != strcmp (c, "YES"))
     {
+      GNUNET_break (0);
+      GNUNET_free (c);
       GNUNET_CONFIGURATION_destroy (cfg);
       return 1;
     }
+
   GNUNET_free (c);
   GNUNET_CONFIGURATION_destroy (cfg);
+
+  /* Testing configuration diffs */
+  cfgDefault = GNUNET_CONFIGURATION_create ();
+  if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfgDefault, NULL))
+    {
+      GNUNET_break (0);
+      GNUNET_CONFIGURATION_destroy (cfgDefault);
+      return 1;
+    }
+
+  /* Nothing changed in the new configuration */
+  failureCount += checkDiffs (cfgDefault, EDIT_NOTHING);
+
+  /* Modify all entries of the last section */
+  failureCount += checkDiffs (cfgDefault, EDIT_SECTION);
+
+  /* Add a new section */
+  failureCount += checkDiffs (cfgDefault, ADD_NEW_SECTION);
+
+  /* Add a new entry to the last section */
+  failureCount += checkDiffs (cfgDefault, ADD_NEW_ENTRY);
+
+  /* Modify all entries in the configuration */
+  failureCount += checkDiffs (cfgDefault, EDIT_ALL);
+
+  GNUNET_CONFIGURATION_destroy (cfgDefault);
+
   if (failureCount != 0)
     {
       fprintf (stderr, "Test failed: %u\n", failureCount);