implement exponential back-off cool down for ARM process restarts
[oweals/gnunet.git] / src / arm / test_arm_api.c
index 89f63d3ec590f0a8dd6f90b55529231db62d2d91..0449c41d4a2479bb2a93390818af8f757772c5f0 100644 (file)
@@ -1,10 +1,10 @@
 /*
      This file is part of GNUnet.
 /*
      This file is part of GNUnet.
-     (C) 2009 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2009, 2011, 2016 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
 
      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
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
 
      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 arm/test_arm_api.c
  * @brief testcase for arm_api.c
  */
 #include "platform.h"
 */
 /**
  * @file arm/test_arm_api.c
  * @brief testcase for arm_api.c
  */
 #include "platform.h"
-#include "gnunet_common.h"
+#include "gnunet_util_lib.h"
 #include "gnunet_arm_service.h"
 #include "gnunet_arm_service.h"
-#include "gnunet_client_lib.h"
-#include "gnunet_configuration_lib.h"
-#include "gnunet_getopt_lib.h"
-#include "gnunet_program_lib.h"
 #include "gnunet_resolver_service.h"
 
 #include "gnunet_resolver_service.h"
 
-#define VERBOSE GNUNET_NO
+#define LOG(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
 
 
-#define START_ARM GNUNET_YES
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
 
 
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
 
-static struct GNUNET_SCHEDULER_Handle *sched;
+static struct GNUNET_ARM_Handle *arm;
 
 
-static struct GNUNET_CONFIGURATION_Handle *cfg;
+static struct GNUNET_ARM_Operation *op;
 
 static int ok = 1;
 
 
 static int ok = 1;
 
+static int phase = 0;
+
+
 static void
 static void
-dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen)
+arm_stop_cb (void *cls,
+            enum GNUNET_ARM_RequestStatus status,
+            enum GNUNET_ARM_Result result)
+{
+  op = NULL;
+  /* (6), a stop request should be sent to ARM successfully */
+  /* ARM should report that it is stopping */
+  GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
+  GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
+  GNUNET_break (phase == 6);
+  phase++;
+  LOG ("Sent 'STOP' request for arm to ARM %s\n",
+       (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
+static void
+resolver_stop_cb (void *cls,
+                 enum GNUNET_ARM_RequestStatus status,
+                  enum GNUNET_ARM_Result result)
+{
+  op = NULL;
+  /* (5), a stop request should be sent to ARM successfully.
+   * ARM should report that resolver is stopped.
+   */
+  GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
+  GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
+  GNUNET_break (phase == 5);
+  LOG ("Sent 'STOP' request for resolver to ARM %s\n",
+       (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
+  phase++;
+  GNUNET_assert (NULL == op);
+  op = GNUNET_ARM_request_service_stop (arm,
+                                        "arm",
+                                        &arm_stop_cb,
+                                        NULL);
+}
+
+
+static void
+dns_notify (void *cls,
+            const struct sockaddr *addr,
+            socklen_t addrlen)
 {
   if (addr == NULL)
     {
 {
   if (addr == NULL)
     {
-      GNUNET_assert (ok == 0);
-#if START_ARM
-      GNUNET_ARM_stop_service ("arm", cfg, sched, TIMEOUT, NULL, NULL);
-#endif
+      /* (4), resolver should finish resolving localhost */
+      GNUNET_break (phase == 4);
+      phase++;
+      LOG ("Finished resolving localhost\n");
+      if (ok != 0)
+        ok = 2;
+      GNUNET_assert (NULL == op);
+      op = GNUNET_ARM_request_service_stop (arm,
+                                            "resolver",
+                                            &resolver_stop_cb,
+                                            NULL);
       return;
     }
       return;
     }
-  GNUNET_assert (addr != NULL);
+  /* (3), resolver should resolve localhost */
+  GNUNET_break (phase == 3);
+  LOG ("Resolved localhost\n");
+  phase++;
+  GNUNET_break (addr != NULL);
   ok = 0;
 }
 
 
 static void
   ok = 0;
 }
 
 
 static void
-resolver_notify (void *cls, int success)
+resolver_start_cb (void *cls,
+                  enum GNUNET_ARM_RequestStatus status,
+                  enum GNUNET_ARM_Result result)
 {
 {
-  GNUNET_assert (success == GNUNET_YES);
-  sleep (1);                    /* FIXME: that we need to do this is a problem... */
-  GNUNET_RESOLVER_ip_get (sched,
-                          cfg,
-                          "localhost", AF_INET, TIMEOUT, &dns_notify, NULL);
+  op = NULL;
+  /* (2), the start request for resolver should be sent successfully
+   * ARM should report that resolver service is starting.
+   */
+  GNUNET_assert (status == GNUNET_ARM_REQUEST_SENT_OK);
+  GNUNET_break (phase == 2);
+  GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
+  LOG ("Sent 'START' request for resolver to ARM %s\n",
+       (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
+  phase++;
+  GNUNET_RESOLVER_ip_get ("localhost",
+                          AF_INET,
+                          TIMEOUT,
+                          &dns_notify, NULL);
 }
 
 }
 
+
 static void
 static void
-arm_notify (void *cls, int success)
+arm_conn (void *cls,
+         int connected)
 {
 {
-  GNUNET_assert (success == GNUNET_YES);
-#if START_ARM
-  sleep (1);                    /* FIXME: that we need to do this is a problem... */
-#endif
-  GNUNET_ARM_start_service ("resolver",
-                            cfg, sched, TIMEOUT, &resolver_notify, NULL);
+  if (GNUNET_SYSERR == connected)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               _("Fatal error initializing ARM API.\n"));
+    GNUNET_SCHEDULER_shutdown ();
+    GNUNET_assert (0);
+    return;
+  }
+  if (GNUNET_YES == connected)
+  {
+    /* (1), arm connection should be established */
+    LOG ("Connected to ARM\n");
+    GNUNET_break (phase == 1);
+    phase++;
+    GNUNET_assert (NULL == op);
+    op = GNUNET_ARM_request_service_start (arm,
+                                           "resolver",
+                                           GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+                                           &resolver_start_cb,
+                                           NULL);
+  }
+  else
+  {
+    /* (7), ARM should stop (we disconnect from it) */
+    LOG ("Disconnected from ARM\n");
+    GNUNET_break (phase == 7);
+    if (phase != 7)
+      ok = 3;
+    else if (ok == 1)
+      ok = 0;
+  }
+}
+
+
+static void
+arm_start_cb (void *cls,
+             enum GNUNET_ARM_RequestStatus status,
+             enum GNUNET_ARM_Result result)
+{
+  op = NULL;
+  /* (0) The request should be "sent" successfully
+   * ("sent", because it isn't going anywhere, ARM API starts ARM service
+   * by itself).
+   * ARM API should report that ARM service is starting.
+   */
+  GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
+  GNUNET_break (phase == 0);
+  LOG ("Sent 'START' request for arm to ARM %s\n",
+       (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
+  GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
+  phase++;
+}
+
+
+static void
+do_shutdown (void *cls)
+{
+  if (NULL != op)
+  {
+    GNUNET_ARM_operation_cancel (op);
+    op = NULL;
+  }
+  if (NULL != arm)
+  {
+    GNUNET_ARM_disconnect (arm);
+    arm = NULL;
+  }
 }
 
 
 static void
 task (void *cls,
 }
 
 
 static void
 task (void *cls,
-      struct GNUNET_SCHEDULER_Handle *s,
       char *const *args,
       char *const *args,
-      const char *cfgfile, struct GNUNET_CONFIGURATION_Handle *c)
+      const char *cfgfile,
+      const struct GNUNET_CONFIGURATION_Handle *c)
 {
   cfg = c;
 {
   cfg = c;
-  sched = s;
-#if START_ARM
-  GNUNET_ARM_start_service ("arm", cfg, sched, TIMEOUT, &arm_notify, NULL);
-#else
-  arm_notify (NULL, GNUNET_YES);
-#endif
+  arm = GNUNET_ARM_connect (cfg,
+                            &arm_conn,
+                            NULL);
+  if (NULL == arm)
+    return;
+  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+                                 NULL);
+  op = GNUNET_ARM_request_service_start (arm,
+                                         "arm",
+                                         GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+                                         &arm_start_cb,
+                                         NULL);
 }
 
 
 }
 
 
-
-static int
-check ()
+int
+main (int argc, char *argvx[])
 {
   char *const argv[] = {
     "test-arm-api",
     "-c", "test_arm_api_data.conf",
 {
   char *const argv[] = {
     "test-arm-api",
     "-c", "test_arm_api_data.conf",
-#if VERBOSE
-    "-L", "DEBUG",
-#endif
     NULL
   };
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
     NULL
   };
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
+  GNUNET_log_setup ("test-arm-api",
+                   "WARNING",
+                   NULL);
   GNUNET_assert (GNUNET_OK ==
   GNUNET_assert (GNUNET_OK ==
-                 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
-                                     argv,
-                                     "test-arm-api",
-                                     "nohelp", options, &task, NULL));
+                GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
+                                    argv, "test-arm-api", "nohelp", options,
+                                    &task, NULL));
   return ok;
 }
 
   return ok;
 }
 
-int
-main (int argc, char *argv[])
-{
-  int ret;
-
-
-  GNUNET_log_setup ("test-arm-api",
-#if VERBOSE
-                    "DEBUG",
-#else
-                    "WARNING",
-#endif
-                    NULL);
-  ret = check ();
-
-  return ret;
-}
-
 /* end of test_arm_api.c */
 /* end of test_arm_api.c */