fixes
[oweals/gnunet.git] / src / fs / fs_test_lib.c
index e7e23d676dec34d5d8c60d80110670075c298d53..dd646eafe6168325c87eab9704b94a97c822aa6a 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
 
      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
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
@@ -30,6 +30,7 @@
 #include "fs_test_lib.h"
 #include "gnunet_testing_lib.h"
 
 #include "fs_test_lib.h"
 #include "gnunet_testing_lib.h"
 
+#define CONNECT_ATTEMPTS 4
 
 /**
  * Handle for a daemon started for testing FS.
 
 /**
  * Handle for a daemon started for testing FS.
 struct GNUNET_FS_TestDaemon
 {
 
 struct GNUNET_FS_TestDaemon
 {
 
+  /**
+   * Global configuration, only stored in first test daemon,
+   * otherwise NULL.
+   */
+  struct GNUNET_CONFIGURATION_Handle *gcfg;
+
   /**
    * Handle to the file sharing context using this daemon.
    */
   /**
    * Handle to the file sharing context using this daemon.
    */
@@ -136,6 +143,32 @@ struct GNUNET_FS_TestDaemon
                
 };
 
                
 };
 
+/**
+ * Check whether peers successfully shut down.
+ */
+static void 
+shutdown_callback (void *cls,
+                  const char *emsg)
+{
+  struct GNUNET_CONFIGURATION_Handle *gcfg = cls;
+
+  if (emsg != NULL)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Shutdown of peers failed: %s\n",
+                 emsg);
+    }
+  else
+    {
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "All peers successfully shut down!\n");
+#endif
+    }
+  if (gcfg != NULL)
+    GNUNET_CONFIGURATION_destroy (gcfg);
+}
+
 
 static void
 report_uri (void *cls,
 
 static void
 report_uri (void *cls,
@@ -173,6 +206,7 @@ report_success (void *cls,
   daemon->download_sched = NULL;
 }
 
   daemon->download_sched = NULL;
 }
 
+
 static void*
 progress_cb (void *cls,
             const struct GNUNET_FS_ProgressInfo *info)
 static void*
 progress_cb (void *cls,
             const struct GNUNET_FS_ProgressInfo *info)
@@ -191,6 +225,13 @@ progress_cb (void *cls,
                                         daemon,
                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
       break;
                                         daemon,
                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
       break;
+    case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
+      if (daemon->verbose)
+       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                   "Publishing at %llu/%llu bytes\n",
+                   (unsigned long long) info->value.publish.completed,
+                   (unsigned long long) info->value.publish.size);
+      break;
     case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
       if (daemon->verbose)
        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
       if (daemon->verbose)
        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -207,6 +248,9 @@ progress_cb (void *cls,
                                         daemon,
                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
       break;
                                         daemon,
                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
       break;
+    case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
+    case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
+      break;
       /* FIXME: monitor data correctness during download progress */
       /* FIXME: do performance reports given sufficient verbosity */
       /* FIXME: advance timeout task to "immediate" on error */
       /* FIXME: monitor data correctness during download progress */
       /* FIXME: do performance reports given sufficient verbosity */
       /* FIXME: advance timeout task to "immediate" on error */
@@ -217,7 +261,6 @@ progress_cb (void *cls,
 }
 
 
 }
 
 
-
 struct StartContext
 {
   struct GNUNET_SCHEDULER_Handle *sched;
 struct StartContext
 {
   struct GNUNET_SCHEDULER_Handle *sched;
@@ -250,11 +293,21 @@ notify_running (void *cls,
                  emsg);
       return;
     }
                  emsg);
       return;
     }
+  i = 0;
+  while (i < sctx->total)
+    {
+      if (GNUNET_TESTING_daemon_get (sctx->group,
+                                    i) == d)
+       break;
+      i++;
+    }
+  GNUNET_assert (i < sctx->total);
   GNUNET_assert (sctx->have < sctx->total);
   GNUNET_assert (sctx->have < sctx->total);
-  sctx->daemons[sctx->have]->cfg = GNUNET_CONFIGURATION_dup (cfg);
-  sctx->daemons[sctx->have]->group = sctx->group;
-  sctx->daemons[sctx->have]->daemon = d;
-  sctx->daemons[sctx->have]->id = *id;
+  GNUNET_assert (sctx->daemons[i]->cfg == NULL);
+  sctx->daemons[i]->cfg = GNUNET_CONFIGURATION_dup (cfg);
+  sctx->daemons[i]->group = sctx->group;
+  sctx->daemons[i]->daemon = d;
+  sctx->daemons[i]->id = *id;
   sctx->have++;
   if (sctx->have == sctx->total)
     {
   sctx->have++;
   if (sctx->have == sctx->total)
     {
@@ -262,17 +315,19 @@ notify_running (void *cls,
                                         sctx->cont,
                                         sctx->cont_cls,
                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
                                         sctx->cont,
                                         sctx->cont_cls,
                                         GNUNET_SCHEDULER_REASON_PREREQ_DONE);
-      GNUNET_CONFIGURATION_destroy (sctx->cfg);
+      sctx->daemons[0]->gcfg = sctx->cfg;
       GNUNET_SCHEDULER_cancel (sctx->sched,
                               sctx->timeout_task);
       for (i=0;i<sctx->total;i++)
       GNUNET_SCHEDULER_cancel (sctx->sched,
                               sctx->timeout_task);
       for (i=0;i<sctx->total;i++)
-       sctx->daemons[i]->fs = GNUNET_FS_start (sctx->sched,
-                                               sctx->daemons[i]->cfg,
-                                               "<tester>",
-                                               &progress_cb,
-                                               sctx->daemons[i],
-                                               GNUNET_FS_FLAGS_NONE,
-                                               GNUNET_FS_OPTIONS_END);
+       {
+         sctx->daemons[i]->fs = GNUNET_FS_start (sctx->sched,
+                                                 sctx->daemons[i]->cfg,
+                                                 "<tester>",
+                                                 &progress_cb,
+                                                 sctx->daemons[i],
+                                                 GNUNET_FS_FLAGS_NONE,
+                                                 GNUNET_FS_OPTIONS_END);
+       }
       GNUNET_free (sctx);
     }
 }
       GNUNET_free (sctx);
     }
 }
@@ -285,12 +340,18 @@ start_timeout (void *cls,
   struct StartContext *sctx = cls;
   unsigned int i;
 
   struct StartContext *sctx = cls;
   unsigned int i;
 
-  GNUNET_TESTING_daemons_stop (sctx->group);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+             "Timeout while trying to start daemons\n");
+  GNUNET_TESTING_daemons_stop (sctx->group,
+                              GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30), 
+                              &shutdown_callback,
+                              NULL);
   for (i=0;i<sctx->total;i++)
     {
       if (i < sctx->have)
        GNUNET_CONFIGURATION_destroy (sctx->daemons[i]->cfg);
       GNUNET_free (sctx->daemons[i]);
   for (i=0;i<sctx->total;i++)
     {
       if (i < sctx->have)
        GNUNET_CONFIGURATION_destroy (sctx->daemons[i]->cfg);
       GNUNET_free (sctx->daemons[i]);
+      sctx->daemons[i] = NULL;
     }
   GNUNET_CONFIGURATION_destroy (sctx->cfg);
   GNUNET_SCHEDULER_add_continuation (sctx->sched,
     }
   GNUNET_CONFIGURATION_destroy (sctx->cfg);
   GNUNET_SCHEDULER_add_continuation (sctx->sched,
@@ -305,6 +366,7 @@ start_timeout (void *cls,
  * Start daemons for testing.
  *
  * @param sched scheduler to use
  * Start daemons for testing.
  *
  * @param sched scheduler to use
+ * @param template_cfg_file configuration template to use
  * @param timeout if this operation cannot be completed within the
  *                given period, call the continuation with an error code
  * @param total number of daemons to start
  * @param timeout if this operation cannot be completed within the
  *                given period, call the continuation with an error code
  * @param total number of daemons to start
@@ -315,6 +377,7 @@ start_timeout (void *cls,
  */
 void
 GNUNET_FS_TEST_daemons_start (struct GNUNET_SCHEDULER_Handle *sched,
  */
 void
 GNUNET_FS_TEST_daemons_start (struct GNUNET_SCHEDULER_Handle *sched,
+                             const char *template_cfg_file,
                              struct GNUNET_TIME_Relative timeout,
                              unsigned int total,
                              struct GNUNET_FS_TestDaemon **daemons,
                              struct GNUNET_TIME_Relative timeout,
                              unsigned int total,
                              struct GNUNET_FS_TestDaemon **daemons,
@@ -334,7 +397,7 @@ GNUNET_FS_TEST_daemons_start (struct GNUNET_SCHEDULER_Handle *sched,
   sctx->cfg = GNUNET_CONFIGURATION_create ();
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_load (sctx->cfg,
   sctx->cfg = GNUNET_CONFIGURATION_create ();
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_load (sctx->cfg,
-                                "fs_test_lib_data.conf"))
+                                template_cfg_file))
     {
       GNUNET_break (0);
       GNUNET_CONFIGURATION_destroy (sctx->cfg);
     {
       GNUNET_break (0);
       GNUNET_CONFIGURATION_destroy (sctx->cfg);
@@ -350,6 +413,9 @@ GNUNET_FS_TEST_daemons_start (struct GNUNET_SCHEDULER_Handle *sched,
   sctx->group = GNUNET_TESTING_daemons_start (sched,
                                              sctx->cfg,
                                              total,
   sctx->group = GNUNET_TESTING_daemons_start (sched,
                                              sctx->cfg,
                                              total,
+                                             timeout,
+                                             NULL,
+                                             NULL,
                                              &notify_running,
                                              sctx,
                                              NULL, NULL,
                                              &notify_running,
                                              sctx,
                                              NULL, NULL,
@@ -369,10 +435,25 @@ struct ConnectContext
 };
 
 
 };
 
 
+/**
+ * Prototype of a function that will be called whenever
+ * two daemons are connected by the testing library.
+ *
+ * @param cls closure
+ * @param first peer id for first daemon
+ * @param second peer id for the second daemon
+ * @param distance distance between the connected peers
+ * @param first_cfg config for the first daemon
+ * @param second_cfg config for the second daemon
+ * @param first_daemon handle for the first daemon
+ * @param second_daemon handle for the second daemon
+ * @param emsg error message (NULL on success)
+ */
 static void
 notify_connection (void *cls,
                   const struct GNUNET_PeerIdentity *first,
                   const struct GNUNET_PeerIdentity *second,
 static void
 notify_connection (void *cls,
                   const struct GNUNET_PeerIdentity *first,
                   const struct GNUNET_PeerIdentity *second,
+                  uint32_t distance,
                   const struct GNUNET_CONFIGURATION_Handle *first_cfg,
                   const struct GNUNET_CONFIGURATION_Handle *second_cfg,
                   struct GNUNET_TESTING_Daemon *first_daemon,
                   const struct GNUNET_CONFIGURATION_Handle *first_cfg,
                   const struct GNUNET_CONFIGURATION_Handle *second_cfg,
                   struct GNUNET_TESTING_Daemon *first_daemon,
@@ -383,7 +464,7 @@ notify_connection (void *cls,
   
   if (emsg != NULL)
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
   
   if (emsg != NULL)
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-               _("Failed to connect peers: %s\n"),
+               "Failed to connect peers: %s\n",
                emsg);
   GNUNET_SCHEDULER_add_continuation (cc->sched,
                                     cc->cont,
                emsg);
   GNUNET_SCHEDULER_add_continuation (cc->sched,
                                     cc->cont,
@@ -423,11 +504,39 @@ GNUNET_FS_TEST_daemons_connect (struct GNUNET_SCHEDULER_Handle *sched,
   GNUNET_TESTING_daemons_connect (daemon1->daemon,
                                  daemon2->daemon,
                                  timeout,
   GNUNET_TESTING_daemons_connect (daemon1->daemon,
                                  daemon2->daemon,
                                  timeout,
+                                 CONNECT_ATTEMPTS,
                                  &notify_connection,
                                  ncc);
 }
 
 
                                  &notify_connection,
                                  ncc);
 }
 
 
+/**
+ * Obtain peer configuration used for testing.
+ *
+ * @param daemons array with the daemons
+ * @param off which configuration to get
+ * @return peer configuration
+ */
+const struct GNUNET_CONFIGURATION_Handle *
+GNUNET_FS_TEST_get_configuration (struct GNUNET_FS_TestDaemon **daemons,
+                                 unsigned int off)
+{
+  return daemons[off]->cfg;  
+}
+
+/**
+ * Obtain peer group used for testing.
+ *
+ * @param daemons array with the daemons (must contain at least one)
+ * @return peer group
+ */
+struct GNUNET_TESTING_PeerGroup *
+GNUNET_FS_TEST_get_group (struct GNUNET_FS_TestDaemon **daemons)
+{
+  return daemons[0]->group;  
+}
+
+
 /**
  * Stop daemons used for testing.
  *
 /**
  * Stop daemons used for testing.
  *
@@ -441,16 +550,25 @@ GNUNET_FS_TEST_daemons_stop (struct GNUNET_SCHEDULER_Handle *sched,
                             struct GNUNET_FS_TestDaemon **daemons)
 {
   unsigned int i;
                             struct GNUNET_FS_TestDaemon **daemons)
 {
   unsigned int i;
+  struct GNUNET_TESTING_PeerGroup *pg;
+  struct GNUNET_CONFIGURATION_Handle *gcfg;
 
   GNUNET_assert (total > 0);
 
   GNUNET_assert (total > 0);
-  GNUNET_TESTING_daemons_stop (daemons[0]->group);
+  pg = daemons[0]->group;
+  gcfg = daemons[0]->gcfg;
   for (i=0;i<total;i++)
     {
   for (i=0;i<total;i++)
     {
-      GNUNET_FS_stop (daemons[i]->fs);
-      GNUNET_CONFIGURATION_destroy (daemons[i]->cfg);
+      if (daemons[i]->fs != NULL)
+       GNUNET_FS_stop (daemons[i]->fs);
+      if (daemons[i]->cfg != NULL)
+       GNUNET_CONFIGURATION_destroy (daemons[i]->cfg);
       GNUNET_free (daemons[i]);
       daemons[i] = NULL;
     }  
       GNUNET_free (daemons[i]);
       daemons[i] = NULL;
     }  
+  GNUNET_TESTING_daemons_stop (pg, 
+                              GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30), 
+                              &shutdown_callback, 
+                              gcfg);
 }
 
 
 }
 
 
@@ -460,7 +578,9 @@ publish_timeout (void *cls,
 {
   struct GNUNET_FS_TestDaemon *daemon = cls;
   GNUNET_FS_TEST_UriContinuation cont;
 {
   struct GNUNET_FS_TestDaemon *daemon = cls;
   GNUNET_FS_TEST_UriContinuation cont;
-  
+
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+             "Timeout while trying to publish data\n");
   cont = daemon->publish_cont;
   daemon->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK;
   daemon->publish_cont = NULL;
   cont = daemon->publish_cont;
   daemon->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK;
   daemon->publish_cont = NULL;
@@ -483,7 +603,11 @@ file_generator (void *cls,
   uint8_t *cbuf = buf;
   int mod;
 
   uint8_t *cbuf = buf;
   int mod;
 
-  for (pos=0;pos<max;pos++)
+  if (buf == NULL)
+    return 0;
+  for (pos=0;pos<8;pos++)
+    cbuf[pos] = (uint8_t) (offset >> pos*8);
+  for (pos=8;pos<max;pos++)
     {
       mod = (255 - (offset / 1024 / 32));
       if (mod == 0)
     {
       mod = (255 - (offset / 1024 / 32));
       if (mod == 0)
@@ -531,7 +655,8 @@ GNUNET_FS_TEST_publish (struct GNUNET_SCHEDULER_Handle *sched,
   daemon->publish_seed = seed;
   daemon->verbose = verbose;
   daemon->publish_sched = sched;
   daemon->publish_seed = seed;
   daemon->verbose = verbose;
   daemon->publish_sched = sched;
-  fi = GNUNET_FS_file_information_create_from_reader (daemon,
+  fi = GNUNET_FS_file_information_create_from_reader (daemon->fs,
+                                                     daemon,                                                 
                                                      size,
                                                      &file_generator,
                                                      daemon,
                                                      size,
                                                      &file_generator,
                                                      daemon,
@@ -558,6 +683,8 @@ download_timeout (void *cls,
 {
   struct GNUNET_FS_TestDaemon *daemon = cls;
 
 {
   struct GNUNET_FS_TestDaemon *daemon = cls;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+             "Timeout while trying to download file\n");
   daemon->download_timeout_task = GNUNET_SCHEDULER_NO_TASK;
   GNUNET_FS_download_stop (daemon->download_context, GNUNET_YES);
   daemon->download_context = NULL;
   daemon->download_timeout_task = GNUNET_SCHEDULER_NO_TASK;
   GNUNET_FS_download_stop (daemon->download_context, GNUNET_YES);
   daemon->download_context = NULL;
@@ -606,7 +733,7 @@ GNUNET_FS_TEST_download (struct GNUNET_SCHEDULER_Handle *sched,
   daemon->download_seed = seed;  
   daemon->download_context = GNUNET_FS_download_start (daemon->fs,
                                                       uri,
   daemon->download_seed = seed;  
   daemon->download_context = GNUNET_FS_download_start (daemon->fs,
                                                       uri,
-                                                      NULL,
+                                                      NULL, NULL,
                                                       NULL,
                                                       0,
                                                       size,
                                                       NULL,
                                                       0,
                                                       size,