REST/NAMESTORE: rework API
[oweals/gnunet.git] / src / arm / test_gnunet_service_arm.c
index 98d8c6354fd3c077b99b6f20f682c0983cb33fc2..55903c4990661d8797e942cf798076e59b190bda 100644 (file)
@@ -1,24 +1,24 @@
 /*
      This file is part of GNUnet.
-     (C) 2009 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2009, 2014 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 3, or (at your
-     option) any later version.
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
+     Affero General Public License for more details.
+    
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-     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.
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 /**
- * @file arm/test_gnunet_service_arm.c 
+ * @file arm/test_gnunet_service_arm.c
  * @brief testcase for gnunet-service-arm.c; tests ARM by making it start the resolver
  * @author Safey
  * @author Christian Grothoff
 
 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
 
+
 static int ret = 1;
 
+static int resolved_ok;
+
+static int asked_for_a_list;
+
 static struct GNUNET_ARM_Handle *arm;
 
+static const char hostname[] = "www.gnu.org"; /* any domain should do */
+
 
 static void
-arm_stopped (void *cls, enum GNUNET_ARM_ProcessStatus success)
+trigger_disconnect (void *cls)
 {
-  if (success != GNUNET_ARM_PROCESS_DOWN)
-    {
-      GNUNET_break (0);
-      ret = 4;
-    }
-  else
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM stopped\n");
-    }
   GNUNET_ARM_disconnect (arm);
   arm = NULL;
 }
 
 
 static void
-hostNameResolveCB (void *cls, const struct sockaddr *addr, socklen_t addrlen)
+arm_stop_cb (void *cls,
+            enum GNUNET_ARM_RequestStatus status,
+            enum GNUNET_ARM_Result result)
 {
-  if ((ret == 0) || (ret == 4))
-    return;
-  if (NULL == addr)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Name not resolved!\n");
-      GNUNET_ARM_stop_service (arm, "arm", TIMEOUT, &arm_stopped, NULL);
-      ret = 3;
-      return;
-    }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Resolved hostname, now stopping ARM\n");
-  ret = 0;
-  GNUNET_ARM_stop_service (arm, "arm", TIMEOUT, &arm_stopped, NULL);
+  GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
+  GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
+  if (result != GNUNET_ARM_RESULT_STOPPED)
+  {
+    GNUNET_break (0);
+    ret = 4;
+  }
+  GNUNET_SCHEDULER_add_now (&trigger_disconnect, NULL);
 }
 
 
 static void
-arm_notify (void *cls, enum GNUNET_ARM_ProcessStatus success)
+service_list (void *cls,
+             enum GNUNET_ARM_RequestStatus rs,
+             unsigned int count,
+              const char *const*list)
 {
-  if (success != GNUNET_ARM_PROCESS_STARTING)
+  unsigned int i;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "%u services are are currently running\n",
+             count);
+  if (GNUNET_ARM_REQUEST_SENT_OK != rs)
+    goto stop_arm;
+  for (i=0;i<count;i++)
+  {
+    if (0 == strcasecmp (list[i],
+                         "resolver (gnunet-service-resolver)"))
     {
-      GNUNET_break (0);
-      ret = 1;
-      return;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Got service list, now stopping arm\n");
+      ret = 0;
     }
+  }
+
+ stop_arm:
+  GNUNET_ARM_request_service_stop (arm,
+                                   "arm",
+                                   &arm_stop_cb,
+                                   NULL);
+}
+
+
+static void
+hostname_resolve_cb (void *cls,
+                     const struct sockaddr *addr,
+                     socklen_t addrlen)
+{
+  if ((0 == ret) || (4 == ret) || (1 == resolved_ok))
+    return;
+  if (NULL == addr)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to resolve hostname!\n");
+    GNUNET_break (0);
+    ret = 3;
+    GNUNET_ARM_request_service_stop (arm,
+                                     "arm",
+                                     &arm_stop_cb,
+                                     NULL);
+    return;
+  }
+  if (0 == asked_for_a_list)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Resolved hostname, now checking the service list\n");
+    GNUNET_ARM_request_service_list (arm,
+                                     &service_list,
+                                     NULL);
+    asked_for_a_list = 1;
+    resolved_ok = 1;
+  }
+}
+
+
+static void
+arm_start_cb (void *cls,
+             enum GNUNET_ARM_RequestStatus status,
+             enum GNUNET_ARM_Result result)
+{
+  GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
+  GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Trying to resolve our own hostname!\n");
+              "Trying to resolve a hostname via the resolver service!\n");
   /* connect to the resolver service */
   if (NULL ==
-      GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, TIMEOUT,
-                                       &hostNameResolveCB, NULL))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 "Unable initiate connection to resolver service\n");
-      ret = 2;
-      GNUNET_ARM_stop_service (arm, "arm", TIMEOUT, &arm_stopped, NULL);
-    }
+      GNUNET_RESOLVER_ip_get (hostname,
+                             AF_UNSPEC,
+                             TIMEOUT,
+                             &hostname_resolve_cb,
+                             NULL))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable initiate connection to resolver service\n");
+    GNUNET_break (0);
+    ret = 2;
+    GNUNET_ARM_request_service_stop (arm,
+                                     "arm",
+                                     &arm_stop_cb,
+                                     NULL);
+  }
 }
 
 
 static void
-run (void *cls, char *const *args, const char *cfgfile,
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
-  arm = GNUNET_ARM_connect (c, NULL);
-  GNUNET_ARM_start_service (arm, "arm",
-                           GNUNET_OS_INHERIT_STD_OUT_AND_ERR, START_TIMEOUT, 
-                           &arm_notify, NULL);
+  arm = GNUNET_ARM_connect (c,
+                            NULL,
+                            NULL);
+  GNUNET_ARM_request_service_start (arm,
+                                    "arm",
+                                    GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
+                                    &arm_start_cb,
+                                    NULL);
 }
 
 
@@ -119,36 +189,76 @@ main (int argc, char *av[])
 {
   static char *const argv[] = {
     "test-gnunet-service-arm",
-    "-c", "test_arm_api_data.conf",
+    "-c",
+    "test_arm_api_data.conf",
     NULL
   };
   static struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
-  char hostname[GNUNET_OS_get_hostname_max_length () + 1];
 
-  if (0 != gethostname (hostname, sizeof (hostname) - 1))
-    {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                          "gethostname");
-      FPRINTF (stderr,
-              "%s", "Failed to determine my own hostname, testcase not run.\n");
-      return 0;
-    }
-  if (NULL == gethostbyname (hostname))
+  /* trigger DNS lookup */
+#if HAVE_GETADDRINFO
+  {
+    struct addrinfo *ai;
+    int ret;
+
+    if (0 != (ret = getaddrinfo (hostname, NULL, NULL, &ai)))
     {
       FPRINTF (stderr,
-              "Failed to resolve my hostname `%s', testcase not run.\n",
-              hostname);
-      return 0;
+               "Failed to resolve `%s', testcase not run.\n",
+               hostname);
+      return 77;
     }
+    freeaddrinfo (ai);
+  }
+#elif HAVE_GETHOSTBYNAME2
+  {
+    struct hostent *host;
+
+    host = gethostbyname2 (hostname, AF_INET);
+    if (NULL == host)
+      host = gethostbyname2 (hostname, AF_INET6);
+    if (NULL == host)
+      {
+        FPRINTF (stderr,
+                 "Failed to resolve `%s', testcase not run.\n",
+                 hostname);
+        return 77;
+      }
+  }
+#elif HAVE_GETHOSTBYNAME
+  {
+    struct hostent *host;
+
+    host = gethostbyname (hostname);
+    if (NULL == host)
+      {
+        FPRINTF (stderr,
+                 "Failed to resolve `%s', testcase not run.\n",
+                 hostname);
+        return 77;
+      }
+  }
+#else
+  FPRINTF (stderr,
+           "libc fails to have resolver function, testcase not run.\n");
+  return 77;
+#endif
   GNUNET_log_setup ("test-gnunet-service-arm",
                    "WARNING",
                    NULL);
-  GNUNET_assert (GNUNET_OK ==
-                GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
-                                    argv, "test-gnunet-service-arm",
-                                    "nohelp", options, &run, NULL));
+  GNUNET_break (GNUNET_OK ==
+               GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
+                                   argv, "test-gnunet-service-arm",
+                                   "nohelp", options,
+                                    &run, NULL));
+  if (0 != ret)
+  {
+    fprintf (stderr,
+             "Test failed with error code %d\n",
+             ret);
+  }
   return ret;
 }