fix memleak
[oweals/gnunet.git] / src / dht / test_dht_api.c
index f09a008799a45080cfcacf458a550164133c6dde..04a0cf26dd69009bd6a85cb82449209818df8f3f 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
  *
  */
 #include "platform.h"
  *
  */
 #include "platform.h"
-#include "gnunet_common.h"
+#include "gnunet_util_lib.h"
 #include "gnunet_hello_lib.h"
 #include "gnunet_hello_lib.h"
-#include "gnunet_getopt_lib.h"
-#include "gnunet_os_lib.h"
-#include "gnunet_program_lib.h"
-#include "gnunet_scheduler_lib.h"
+#include "gnunet_testing_lib-new.h"
 #include "gnunet_dht_service.h"
 
 #include "gnunet_dht_service.h"
 
-#define VERBOSE GNUNET_NO
 
 
-#define VERBOSE_ARM GNUNET_NO
-
-#define START_ARM GNUNET_YES
+/**
+ * How long until we really give up on a particular testcase portion?
+ */
+#define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600)
 
 /**
 
 /**
- * How long until we give up on transmitting the message?
+ * How long until we give up on any particular operation (and retry)?
  */
  */
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 50)
+#define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
 
 #define MTYPE 12345
 
 
 #define MTYPE 12345
 
-struct PeerContext
+
+struct RetryContext
 {
 {
-  struct GNUNET_CONFIGURATION_Handle *cfg;
-  struct GNUNET_DHT_Handle *dht_handle;
-  struct GNUNET_PeerIdentity id;
-  struct GNUNET_DHT_GetHandle *get_handle;
-  struct GNUNET_DHT_FindPeerHandle *find_peer_handle;
-
-#if START_ARM
-  pid_t arm_pid;
-#endif
+  /**
+   * When to really abort the operation.
+   */
+  struct GNUNET_TIME_Absolute real_timeout;
+
+  /**
+   * What timeout to set for the current attempt (increases)
+   */
+  struct GNUNET_TIME_Relative next_timeout;
+
+  /**
+   * The task identifier of the retry task, so it can be cancelled.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier retry_task;
+
 };
 
 };
 
-static struct PeerContext p1;
 
 
-static struct GNUNET_SCHEDULER_Handle *sched;
+static struct GNUNET_DHT_Handle *dht_handle;
 
 
-static int ok;
+static struct GNUNET_DHT_GetHandle *get_handle;
+
+struct RetryContext retry_context;
+
+static int ok = 1;
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
 
 
-GNUNET_SCHEDULER_TaskIdentifier die_task;
 
 #if VERBOSE
 
 #if VERBOSE
-#define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
+#define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
 #else
 #define OKPP do { ok++; } while (0)
 #endif
 #else
 #define OKPP do { ok++; } while (0)
 #endif
@@ -77,36 +85,13 @@ GNUNET_SCHEDULER_TaskIdentifier die_task;
 static void
 end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
 static void
 end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  /* do work here */
-  GNUNET_SCHEDULER_cancel (sched, die_task);
-
-  GNUNET_DHT_disconnect (p1.dht_handle);
-
+  GNUNET_SCHEDULER_cancel (die_task);
   die_task = GNUNET_SCHEDULER_NO_TASK;
   die_task = GNUNET_SCHEDULER_NO_TASK;
-
-  if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "DHT disconnected, returning FAIL!\n");
-      ok = 365;
-    }
-  else
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                  "DHT disconnected, returning success!\n");
-      ok = 0;
-    }
-}
-
-static void
-stop_arm (struct PeerContext *p)
-{
-#if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  GNUNET_OS_process_wait (p->arm_pid);
-#endif
-  GNUNET_CONFIGURATION_destroy (p->cfg);
+  GNUNET_DHT_disconnect (dht_handle);
+  dht_handle = NULL;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "DHT disconnected, returning success!\n");
+  ok = 0;
 }
 
 
 }
 
 
@@ -114,58 +99,17 @@ static void
 end_badly ()
 {
   /* do work here */
 end_badly ()
 {
   /* do work here */
-#if VERBOSE
-  fprintf (stderr, "Ending on an unhappy note.\n");
-#endif
-
-  GNUNET_DHT_disconnect (p1.dht_handle);
-
+  FPRINTF (stderr, "%s",  "Ending on an unhappy note.\n");
+  if (get_handle != NULL)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping get request!\n");
+    GNUNET_DHT_get_stop (get_handle);
+  }
+  if (retry_context.retry_task != GNUNET_SCHEDULER_NO_TASK)
+    GNUNET_SCHEDULER_cancel (retry_context.retry_task);
+  GNUNET_DHT_disconnect (dht_handle);
+  dht_handle = NULL;
   ok = 1;
   ok = 1;
-  return;
-}
-
-/**
- * Signature of the main function of a task.
- *
- * @param cls closure
- * @param tc context information (why was this task triggered now)
- */
-void
-test_find_peer_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct PeerContext *peer = cls;
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer_stop!\n");
-  if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT)
-    GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL);
-
-  GNUNET_assert (peer->dht_handle != NULL);
-
-  GNUNET_DHT_find_peer_stop (peer->find_peer_handle, &end, &p1);
-
-  //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &end, &p1);
-
-}
-
-
-/**
- * Iterator called on each result obtained from a find peer
- * operation
- *
- * @param cls closure (NULL)
- * @param peer the peer we learned about
- * @param reply response
- */
-void test_find_peer_processor (void *cls,
-                          const struct GNUNET_PeerIdentity *peer,
-                          const struct GNUNET_MessageHeader *reply)
-{
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "test_find_peer_processor called (peer `%s'), stopping find peer request!\n", GNUNET_i2s(peer));
-
-  GNUNET_SCHEDULER_add_continuation (sched, &test_find_peer_stop, &p1,
-                                     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
 }
 
 
 }
 
 
@@ -175,196 +119,112 @@ void test_find_peer_processor (void *cls,
  * @param cls closure
  * @param tc context information (why was this task triggered now)
  */
  * @param cls closure
  * @param tc context information (why was this task triggered now)
  */
-void
-test_find_peer (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct PeerContext *peer = cls;
-  GNUNET_HashCode hash;
-  memset (&hash, 42, sizeof (GNUNET_HashCode));
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_find_peer!\n");
-  GNUNET_assert (peer->dht_handle != NULL);
-
-  peer->find_peer_handle =
-    GNUNET_DHT_find_peer_start (peer->dht_handle, TIMEOUT, 0, NULL, &hash,
-                                &test_find_peer_processor, NULL, NULL, NULL);
-
-  if (peer->find_peer_handle == NULL)
-    GNUNET_SCHEDULER_add_now (sched, &end_badly, &p1);
-}
-
-/**
- * Signature of the main function of a task.
- *
- * @param cls closure
- * @param tc context information (why was this task triggered now)
- */
-void
+static void
 test_get_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
 test_get_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  struct PeerContext *peer = cls;
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get_stop!\n");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get_stop!\n");
-  if (tc->reason == GNUNET_SCHEDULER_REASON_TIMEOUT)
-    GNUNET_SCHEDULER_add_now (sched, &end_badly, NULL);
-
-  GNUNET_assert (peer->dht_handle != NULL);
-
-  GNUNET_DHT_get_stop (peer->get_handle, &test_find_peer, &p1);
-
-  //GNUNET_SCHEDULER_add_delayed(sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1);
-
+  if ((tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT) != 0)
+  {
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_cancel (die_task);
+    die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
+    return;
+  }
+  GNUNET_assert (dht_handle != NULL);
+  GNUNET_DHT_get_stop (get_handle);
+  get_handle = NULL;
+  GNUNET_SCHEDULER_add_now (&end, NULL);
 }
 
 }
 
-void
-test_get_iterator (void *cls,
-                   struct GNUNET_TIME_Absolute exp,
-                   const GNUNET_HashCode * key,
-                   uint32_t type, uint32_t size, const void *data)
+
+static void
+test_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp,
+                   const struct GNUNET_HashCode * key,
+                   const struct GNUNET_PeerIdentity *get_path,
+                   unsigned int get_path_length,
+                   const struct GNUNET_PeerIdentity *put_path,
+                   unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
+                   size_t size, const void *data)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "test_get_iterator called (we got a result), stopping get request!\n");
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "test_get_iterator called (we got a result), stopping get request!\n");
-
-  GNUNET_SCHEDULER_add_continuation (sched, &test_get_stop, &p1,
+  GNUNET_SCHEDULER_add_continuation (&test_get_stop, NULL,
                                      GNUNET_SCHEDULER_REASON_PREREQ_DONE);
 }
 
                                      GNUNET_SCHEDULER_REASON_PREREQ_DONE);
 }
 
-/**
- * Signature of the main function of a task.
- *
- * @param cls closure
- * @param tc context information (why was this task triggered now)
- */
-void
-test_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct PeerContext *peer = cls;
-  GNUNET_HashCode hash;
-  memset (&hash, 42, sizeof (GNUNET_HashCode));
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get!\n");
-
-  GNUNET_assert (peer->dht_handle != NULL);
-
-  peer->get_handle =
-    GNUNET_DHT_get_start (peer->dht_handle, TIMEOUT, 42, &hash,
-                          &test_get_iterator, NULL, NULL, NULL);
-
-  if (peer->get_handle == NULL)
-    GNUNET_SCHEDULER_add_now (sched, &end_badly, &p1);
-}
 
 /**
  * Signature of the main function of a task.
  *
  * @param cls closure
 
 /**
  * Signature of the main function of a task.
  *
  * @param cls closure
- * @param tc context information (why was this task triggered now)
+ * @param success result of PUT
  */
  */
-void
-test_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+static void
+test_get (void *cls, int success)
 {
 {
-  struct PeerContext *peer = cls;
-  GNUNET_HashCode hash;
-  char *data;
-  size_t data_size = 42;
-  memset (&hash, 42, sizeof (GNUNET_HashCode));
-  data = GNUNET_malloc (data_size);
-  memset (data, 43, data_size);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_put!\n");
-  peer->dht_handle = GNUNET_DHT_connect (sched, peer->cfg, 100);
+  struct GNUNET_HashCode hash;
 
 
-  GNUNET_assert (peer->dht_handle != NULL);
-
-  GNUNET_DHT_put (peer->dht_handle, &hash, 0, data_size, data,
-                  GNUNET_TIME_relative_to_absolute (TIMEOUT), TIMEOUT,
-                  &test_get, &p1);
+  memset (&hash, 42, sizeof (struct GNUNET_HashCode));
 
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get!\n");
+  GNUNET_assert (dht_handle != NULL);
+  retry_context.real_timeout = GNUNET_TIME_relative_to_absolute (TOTAL_TIMEOUT);
+  retry_context.next_timeout = BASE_TIMEOUT;
+
+  get_handle =
+      GNUNET_DHT_get_start (dht_handle, 
+                            GNUNET_BLOCK_TYPE_TEST, &hash, 1,
+                            GNUNET_DHT_RO_NONE, NULL, 0, &test_get_iterator,
+                            NULL);
+
+  if (get_handle == NULL)
+  {
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_cancel (die_task);
+    die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
+    return;
+  }
 }
 
 }
 
-static void
-setup_peer (struct PeerContext *p, const char *cfgname)
-{
-  p->cfg = GNUNET_CONFIGURATION_create ();
-#if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
-                                        "gnunet-service-arm",
-#if VERBOSE_ARM
-                                        "-L", "DEBUG",
-#endif
-                                        "-c", cfgname, NULL);
-#endif
-  GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
-
-}
 
 static void
 run (void *cls,
 
 static void
 run (void *cls,
-     struct GNUNET_SCHEDULER_Handle *s,
-     char *const *args,
-     const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
+     const struct GNUNET_CONFIGURATION_Handle *cfg,
+     struct GNUNET_TESTING_Peer *peer)
 {
 {
+  struct GNUNET_HashCode hash;
+  char *data;
+  size_t data_size = 42;
+
   GNUNET_assert (ok == 1);
   OKPP;
   GNUNET_assert (ok == 1);
   OKPP;
-  sched = s;
+  die_task =
+      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
+                                    (GNUNET_TIME_UNIT_MINUTES, 1), &end_badly,
+                                    NULL);
 
 
-  die_task = GNUNET_SCHEDULER_add_delayed (sched,
-                                           GNUNET_TIME_relative_multiply
-                                           (GNUNET_TIME_UNIT_MINUTES, 1),
-                                           &end_badly, NULL);
-
-  setup_peer (&p1, "test_dht_api_peer1.conf");
-
-  GNUNET_SCHEDULER_add_delayed (sched,
-                                GNUNET_TIME_relative_multiply
-                                (GNUNET_TIME_UNIT_SECONDS, 1), &test_put,
-                                &p1);
-}
-
-static int
-check ()
-{
-
-  char *const argv[] = { "test-dht-api",
-    "-c",
-    "test_dht_api_data.conf",
-#if VERBOSE
-    "-L", "DEBUG",
-#endif
-    NULL
-  };
-
-  struct GNUNET_GETOPT_CommandLineOption options[] = {
-    GNUNET_GETOPT_OPTION_END
-  };
-
-  ok = 1;
-  GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
-                      argv, "test-dht-api", "nohelp", options, &run, &ok);
-  stop_arm (&p1);
-  return ok;
+  memset (&hash, 42, sizeof (struct GNUNET_HashCode));
+  data = GNUNET_malloc (data_size);
+  memset (data, 43, data_size);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_put!\n");
+  dht_handle = GNUNET_DHT_connect (cfg, 100);
+  GNUNET_assert (dht_handle != NULL);
+  GNUNET_DHT_put (dht_handle, &hash, 1, GNUNET_DHT_RO_NONE,
+                  GNUNET_BLOCK_TYPE_TEST, data_size, data,
+                  GNUNET_TIME_relative_to_absolute (TOTAL_TIMEOUT),
+                  TOTAL_TIMEOUT, &test_get, NULL);
+  GNUNET_free (data);
 }
 
 
 int
 main (int argc, char *argv[])
 {
 }
 
 
 int
 main (int argc, char *argv[])
 {
-  int ret;
-#ifdef MINGW
-  return GNUNET_SYSERR;
-#endif
-
-  GNUNET_log_setup ("test-dht-api",
-#if VERBOSE
-                    "DEBUG",
-#else
-                    "WARNING",
-#endif
-                    NULL);
-  ret = check ();
-
-  GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-dht-peer-1");
-
-  return ret;
+  if (0 != GNUNET_TESTING_peer_run ("test-dht-api",
+                                   "test_dht_api_data.conf",
+                                   &run, NULL))
+    return 1;
+  return ok;
 }
 
 /* end of test_dht_api.c */
 }
 
 /* end of test_dht_api.c */