logging fixes, nicer comments
[oweals/gnunet.git] / src / util / test_configuration.c
index 4c7f69a146dc59675a9be59d0c8af71d94f124eb..80ae01c683227dccd760149e1a679292d8ba167d 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet.
-     (C) 2003, 2004, 2005, 2006, 2007 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2003, 2004, 2005, 2006, 2007 GNUnet e.V.
 
      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
@@ -14,8 +14,8 @@
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 /**
  * @file util/test_configuration.c
  */
 
 #include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_configuration_lib.h"
+#include "gnunet_util_lib.h"
+
+
+/* Test Configuration Diffs Options */
+enum
+{
+  EDIT_NOTHING,
+  EDIT_SECTION,
+  EDIT_ALL,
+  ADD_NEW_SECTION,
+  ADD_NEW_ENTRY,
+  REMOVE_SECTION,
+  REMOVE_ENTRY,
+  COMPARE,
+  PRINT
+};
 
 static struct GNUNET_CONFIGURATION_Handle *cfg;
+static struct GNUNET_CONFIGURATION_Handle *cfg_default;
+
+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 0
+  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, 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 *cfg_default, 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 (cfg_default, 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));
+  if (0 != remove (diffsFileName))
+    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "remove", diffsFileName);
+  cbData.callBackOption = COMPARE;
+  cbData.cfgDiffs = cfgDiffs;
+  GNUNET_CONFIGURATION_iterate (cfg, diffsCallBack, &cbData);
+  if (1 == (ret = cbData.status))
+  {
+    FPRINTF (stderr, "%s",
+             "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, "%s",
+             "Incorrect Configuration Diffs: Data may be missing in diffs\n");
+
+housekeeping:
+#if 0
+  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 ()
@@ -35,50 +269,77 @@ testConfig ()
   char *c;
   unsigned long long l;
 
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_string (cfg, "test", "b", &c))
+  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "test", "b", &c))
     return 1;
   if (0 != strcmp ("b", c))
-    {
-      fprintf (stderr, "Got `%s'\n", c);
-      GNUNET_free (c);
-      return 2;
-    }
+  {
+    FPRINTF (stderr, "Got `%s'\n", c);
+    GNUNET_free (c);
+    return 2;
+  }
   GNUNET_free (c);
-  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg,
-                                                          "test", "five", &l))
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_number (cfg, "test", "five", &l))
+  {
+    GNUNET_break (0);
     return 3;
+  }
   if (5 != l)
+  {
+    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"))
+  {
+    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))
+  {
+    GNUNET_break (0);
     return 6;
+  }
   if (0 != strcmp (c, "10"))
-    {
-      GNUNET_free (c);
-      return 7;
-    }
+  {
+    GNUNET_free (c);
+    GNUNET_break (0);
+    return 7;
+  }
   GNUNET_free (c);
 
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_filename (cfg, "last", "test", &c))
+  {
+    GNUNET_break (0);
     return 8;
+  }
 #ifndef MINGW
   if (0 != strcmp (c, "/hello/world"))
 #else
 #define HI "\\hello\\world"
   if (strstr (c, HI) != c + strlen (c) - strlen (HI))
 #endif
-    {
-      GNUNET_free (c);
-      return 9;
-    }
+  {
+    GNUNET_break (0);
+    GNUNET_free (c);
+    return 9;
+  }
   GNUNET_free (c);
 
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_size (cfg, "last", "size", &l))
+  {
+    GNUNET_break (0);
+    return 10;
+  }
+  if (l != 512 * 1024)
+  {
+    GNUNET_break (0);
+    return 11;
+  }
   return 0;
 }
 
@@ -96,10 +357,11 @@ check (void *data, const char *fn)
   int *idx = data;
 
   if (0 == strcmp (want[*idx], fn))
-    {
-      (*idx)++;
-      return GNUNET_OK;
-    }
+  {
+    (*idx)++;
+    return GNUNET_OK;
+  }
+  GNUNET_break (0);
   return GNUNET_SYSERR;
 }
 
@@ -109,67 +371,89 @@ testConfigFilenames ()
   int idx;
 
   idx = 0;
-  if (3 != GNUNET_CONFIGURATION_iterate_value_filenames (cfg,
-                                                         "FILENAMES",
-                                                         "test",
-                                                         &check, &idx))
+  if (3 !=
+      GNUNET_CONFIGURATION_iterate_value_filenames (cfg, "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"))
+      GNUNET_CONFIGURATION_remove_value_filename (cfg, "FILENAMES", "test",
+                                                  "/File Name"))
+  {
+    GNUNET_break (0);
     return 24;
+  }
 
   if (GNUNET_NO !=
-      GNUNET_CONFIGURATION_remove_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/File Name"))
+      GNUNET_CONFIGURATION_remove_value_filename (cfg, "FILENAMES", "test",
+                                                  "/File Name"))
+  {
+    GNUNET_break (0);
     return 32;
+  }
   if (GNUNET_NO !=
-      GNUNET_CONFIGURATION_remove_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "Stuff"))
+      GNUNET_CONFIGURATION_remove_value_filename (cfg, "FILENAMES", "test",
+                                                  "Stuff"))
+  {
+    GNUNET_break (0);
     return 40;
+  }
 
   if (GNUNET_NO !=
-      GNUNET_CONFIGURATION_append_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/Hello"))
+      GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
+                                                  "/Hello"))
+  {
+    GNUNET_break (0);
     return 48;
+  }
   if (GNUNET_NO !=
-      GNUNET_CONFIGURATION_append_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/World"))
+      GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
+                                                  "/World"))
+  {
+    GNUNET_break (0);
     return 56;
+  }
 
   if (GNUNET_YES !=
-      GNUNET_CONFIGURATION_append_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/File 1"))
+      GNUNET_CONFIGURATION_append_value_filename (cfg, "FILENAMES", "test",
+                                                  "/File 1"))
+  {
+    GNUNET_break (0);
     return 64;
+  }
 
   if (GNUNET_YES !=
-      GNUNET_CONFIGURATION_append_value_filename (cfg,
-                                                  "FILENAMES",
-                                                  "test", "/File 2"))
+      GNUNET_CONFIGURATION_append_value_filename (cfg, "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))
+  if (4 !=
+      GNUNET_CONFIGURATION_iterate_value_filenames (cfg, "FILENAMES", "test",
+                                                    &check, &idx))
+  {
+    GNUNET_break (0);
     return 80;
+  }
   if (idx != 4)
+  {
+    GNUNET_break (0);
     return 88;
+  }
   return 0;
 }
 
+
 int
 main (int argc, char *argv[])
 {
@@ -181,54 +465,85 @@ main (int argc, char *argv[])
   GNUNET_assert (cfg != NULL);
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_parse (cfg, "test_configuration_data.conf"))
-    {
-      fprintf (stderr, "Failed to parse configuration file\n");
-      GNUNET_CONFIGURATION_destroy (cfg);
-      return 1;
-    }
+  {
+    FPRINTF (stderr, "%s",  "Failed to parse configuration file\n");
+    GNUNET_CONFIGURATION_destroy (cfg);
+    return 1;
+  }
   failureCount += testConfig ();
-  failureCount += 2 * testConfigFilenames ();
+  if (failureCount > 0)
+    goto error;
+
+  failureCount = testConfigFilenames ();
+  if (failureCount > 0)
+    goto error;
 
   if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, "/tmp/gnunet-test.conf"))
-    {
-      fprintf (stderr, "Failed to write configuration file\n");
-      GNUNET_CONFIGURATION_destroy (cfg);
-      return 1;
-    }
+  {
+    FPRINTF (stderr, "%s",  "Failed to write configuration file\n");
+    GNUNET_CONFIGURATION_destroy (cfg);
+    return 1;
+  }
   GNUNET_CONFIGURATION_destroy (cfg);
   GNUNET_assert (0 == UNLINK ("/tmp/gnunet-test.conf"));
 
   cfg = GNUNET_CONFIGURATION_create ();
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_load (cfg, "test_configuration_data.conf"))
-    {
-      GNUNET_break (0);
-      GNUNET_CONFIGURATION_destroy (cfg);
-      return 1;
-    }
-  if ((GNUNET_OK !=
-       GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "WEAKRANDOM",
-                                              &c))
-      || (0 != strcmp (c, "YES")))
-    {
-      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/")))
-    {
-      GNUNET_CONFIGURATION_destroy (cfg);
-      return 1;
-    }
+  {
+    GNUNET_break (0);
+    GNUNET_CONFIGURATION_destroy (cfg);
+    return 1;
+  }
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "WEAKRANDOM", &c))
+  {
+    GNUNET_break (0);
+    GNUNET_CONFIGURATION_destroy (cfg);
+    return 1;
+  }
+  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 */
+  cfg_default = GNUNET_CONFIGURATION_create ();
+  if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg_default, NULL))
+  {
+    GNUNET_break (0);
+    GNUNET_CONFIGURATION_destroy (cfg_default);
+    return 1;
+  }
+
+  /* Nothing changed in the new configuration */
+  failureCount += checkDiffs (cfg_default, EDIT_NOTHING);
+
+  /* Modify all entries of the last section */
+  failureCount += checkDiffs (cfg_default, EDIT_SECTION);
+
+  /* Add a new section */
+  failureCount += checkDiffs (cfg_default, ADD_NEW_SECTION);
+
+  /* Add a new entry to the last section */
+  failureCount += checkDiffs (cfg_default, ADD_NEW_ENTRY);
+
+  /* Modify all entries in the configuration */
+  failureCount += checkDiffs (cfg_default, EDIT_ALL);
+
+  GNUNET_CONFIGURATION_destroy (cfg_default);
+
+error:
   if (failureCount != 0)
-    {
-      fprintf (stderr, "Test failed: %u\n", failureCount);
-      return 1;
-    }
+  {
+    FPRINTF (stderr, "Test failed: %u\n", failureCount);
+    return 1;
+  }
   return 0;
 }