REST/NAMESTORE: rework API
[oweals/gnunet.git] / src / cadet / cadet_test_lib.c
index ce348018fd7ed2e8c1deb2e88e55be543e9f50f8..db16e4015a1eeeb39102cce56a0a0411e6601536 100644 (file)
@@ -1,21 +1,21 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2012 GNUnet e.V.
+     Copyright (C) 2012, 2017 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 General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
+     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/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 /**
  * @file cadet/cadet_test_lib.c
@@ -27,6 +27,7 @@
 #include "cadet_test_lib.h"
 #include "gnunet_cadet_service.h"
 
+
 /**
  * Test context for a CADET Test.
  */
@@ -40,13 +41,18 @@ struct GNUNET_CADET_TEST_Context
   /**
    * Array of handles to the CADET for each peer.
    */
-  struct GNUNET_CADET_Handle **cadetes;
+  struct GNUNET_CADET_Handle **cadets;
 
   /**
    * Operation associated with the connection to the CADET.
    */
   struct GNUNET_TESTBED_Operation **ops;
 
+  /**
+   * Number of peers running, size of the arrays above.
+   */
+  unsigned int num_peers;
+
   /**
    * Main function of the test to run once all CADETs are available.
    */
@@ -58,29 +64,34 @@ struct GNUNET_CADET_TEST_Context
   void *app_main_cls;
 
   /**
-   * Number of peers running, size of the arrays above.
+   * Handler for incoming tunnels.
    */
-  unsigned int num_peers;
+  GNUNET_CADET_ConnectEventHandler connects;
 
   /**
-   * Handler for incoming tunnels.
+   * Function called when the transmit window size changes.
    */
-  GNUNET_CADET_InboundChannelNotificationHandler *new_channel;
+  GNUNET_CADET_WindowSizeEventHandler window_changes;
 
   /**
    * Cleaner for destroyed incoming tunnels.
    */
-  GNUNET_CADET_ChannelEndHandler *cleaner;
+  GNUNET_CADET_DisconnectEventHandler disconnects;
 
   /**
    * Message handlers.
    */
-  struct GNUNET_CADET_MessageHandler* handlers;
+  struct GNUNET_MQ_MessageHandler *handlers;
 
   /**
    * Application ports.
    */
-  const uint32_t *ports;
+  const struct GNUNET_HashCode **ports;
+
+  /**
+   * Number of ports in #ports.
+   */
+  unsigned int port_count;
 
 };
 
@@ -95,6 +106,11 @@ struct GNUNET_CADET_TEST_AdapterContext
    */
   unsigned int peer;
 
+  /**
+   * Port handlers for open ports.
+   */
+  struct GNUNET_CADET_Port **ports;
+
   /**
    * General context.
    */
@@ -114,18 +130,32 @@ struct GNUNET_CADET_TEST_AdapterContext
  */
 static void *
 cadet_connect_adapter (void *cls,
-                      const struct GNUNET_CONFIGURATION_Handle *cfg)
+                       const struct GNUNET_CONFIGURATION_Handle *cfg)
 {
   struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
   struct GNUNET_CADET_TEST_Context *ctx = actx->ctx;
   struct GNUNET_CADET_Handle *h;
 
-  h = GNUNET_CADET_connect (cfg,
-                           (void *) (long) actx->peer,
-                           ctx->new_channel,
-                           ctx->cleaner,
-                           ctx->handlers,
-                           ctx->ports);
+  h = GNUNET_CADET_connect (cfg);
+  if (NULL == h)
+  {
+    GNUNET_break(0);
+    return NULL;
+  }
+  if (NULL == ctx->ports)
+    return h;
+  actx->ports = GNUNET_new_array (ctx->port_count,
+                                  struct GNUNET_CADET_Port *);
+  for (unsigned int i = 0; i < ctx->port_count; i++)
+  {
+    actx->ports[i] = GNUNET_CADET_open_port (h,
+                                             ctx->ports[i],
+                                             ctx->connects,
+                                             (void *) (long) actx->peer,
+                                             ctx->window_changes,
+                                             ctx->disconnects,
+                                             ctx->handlers);
+  }
   return h;
 }
 
@@ -139,11 +169,20 @@ cadet_connect_adapter (void *cls,
  */
 static void
 cadet_disconnect_adapter (void *cls,
-                         void *op_result)
+                          void *op_result)
 {
   struct GNUNET_CADET_Handle *cadet = op_result;
   struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
 
+  if (NULL != actx->ports)
+  {
+    for (unsigned int i = 0; i < actx->ctx->port_count; i++)
+    {
+      GNUNET_CADET_close_port (actx->ports[i]);
+      actx->ports[i] = NULL;
+    }
+    GNUNET_free (actx->ports);
+  }
   GNUNET_free (actx);
   GNUNET_CADET_disconnect (cadet);
 }
@@ -166,46 +205,47 @@ cadet_connect_cb (void *cls,
                  const char *emsg)
 {
   struct GNUNET_CADET_TEST_Context *ctx = cls;
-  unsigned int i;
 
   if (NULL != emsg)
   {
-    fprintf (stderr, "Failed to connect to CADET service: %s\n",
+    fprintf (stderr,
+             "Failed to connect to CADET service: %s\n",
              emsg);
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  for (i = 0; i < ctx->num_peers; i++)
+  for (unsigned int i = 0; i < ctx->num_peers; i++)
     if (op == ctx->ops[i])
     {
-      ctx->cadetes[i] = ca_result;
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO, "...cadet %u connected\n", i);
+      ctx->cadets[i] = ca_result;
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "...cadet %u connected\n",
+                  i);
     }
-  for (i = 0; i < ctx->num_peers; i++)
-    if (NULL == ctx->cadetes[i])
+  for (unsigned int i = 0; i < ctx->num_peers; i++)
+    if (NULL == ctx->cadets[i])
       return; /* still some CADET connections missing */
   /* all CADET connections ready! */
   ctx->app_main (ctx->app_main_cls,
                  ctx,
                  ctx->num_peers,
                  ctx->peers,
-                 ctx->cadetes);
+                 ctx->cadets);
 }
 
 
 void
 GNUNET_CADET_TEST_cleanup (struct GNUNET_CADET_TEST_Context *ctx)
 {
-  unsigned int i;
-
-  for (i = 0; i < ctx->num_peers; i++)
+  for (unsigned int i = 0; i < ctx->num_peers; i++)
   {
     GNUNET_assert (NULL != ctx->ops[i]);
     GNUNET_TESTBED_operation_done (ctx->ops[i]);
     ctx->ops[i] = NULL;
   }
   GNUNET_free (ctx->ops);
-  GNUNET_free (ctx->cadetes);
+  GNUNET_free (ctx->cadets);
+  GNUNET_free (ctx->handlers);
   GNUNET_free (ctx);
   GNUNET_SCHEDULER_shutdown ();
 }
@@ -233,22 +273,37 @@ cadet_test_run (void *cls,
                unsigned int links_failed)
 {
   struct GNUNET_CADET_TEST_Context *ctx = cls;
-  unsigned int i;
 
+  if (0 != links_failed)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Some links failed (%u), ending\n",
+                links_failed);
+    exit (77);
+  }
   if  (num_peers != ctx->num_peers)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers started %u/%u, ending\n",
-                num_peers, ctx->num_peers);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Peers started %u/%u, ending\n",
+                num_peers,
+                ctx->num_peers);
     exit (1);
   }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Testbed up, %u peers and %u links\n",
+              num_peers,
+              links_succeeded);
   ctx->peers = peers;
-  for (i = 0; i < num_peers; i++)
+  for (unsigned int i = 0; i < num_peers; i++)
   {
     struct GNUNET_CADET_TEST_AdapterContext *newctx;
+
     newctx = GNUNET_new (struct GNUNET_CADET_TEST_AdapterContext);
     newctx->peer = i;
     newctx->ctx = ctx;
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to cadet %u\n", i);
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Connecting to cadet %u\n",
+                i);
     ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx,
                                                   peers[i],
                                                   "cadet",
@@ -257,39 +312,64 @@ cadet_test_run (void *cls,
                                                   &cadet_connect_adapter,
                                                   &cadet_disconnect_adapter,
                                                   newctx);
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "op handle %p\n", ctx->ops[i]);
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "op handle %p\n",
+                ctx->ops[i]);
   }
 }
 
 
+/**
+ * Run a test using the given name, configuration file and number of peers.
+ * All cadet callbacks will receive the peer number (long) as the closure.
+ *
+ * @param testname Name of the test (for logging).
+ * @param cfgfile Name of the configuration file.
+ * @param num_peers Number of peers to start.
+ * @param tmain Main function to run once the testbed is ready.
+ * @param tmain_cls Closure for @a tmain.
+ * @param connects Handler for incoming channels.
+ * @param window_changes Handler for the window size change notification.
+ * @param disconnects Cleaner for destroyed incoming channels.
+ * @param handlers Message handlers.
+ * @param ports Ports the peers offer, NULL-terminated.
+ */
 void
-GNUNET_CADET_TEST_run (const char *testname,
-                      const char *cfgname,
-                      unsigned int num_peers,
-                      GNUNET_CADET_TEST_AppMain tmain,
-                      void *tmain_cls,
-                      GNUNET_CADET_InboundChannelNotificationHandler new_channel,
-                      GNUNET_CADET_ChannelEndHandler cleaner,
-                      struct GNUNET_CADET_MessageHandler* handlers,
-                      const uint32_t *ports)
+GNUNET_CADET_TEST_ruN (const char *testname,
+                       const char *cfgfile,
+                       unsigned int num_peers,
+                       GNUNET_CADET_TEST_AppMain tmain,
+                       void *tmain_cls,
+                       GNUNET_CADET_ConnectEventHandler connects,
+                       GNUNET_CADET_WindowSizeEventHandler window_changes,
+                       GNUNET_CADET_DisconnectEventHandler disconnects,
+                       struct GNUNET_MQ_MessageHandler *handlers,
+                       const struct GNUNET_HashCode **ports)
 {
   struct GNUNET_CADET_TEST_Context *ctx;
 
   ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context);
   ctx->num_peers = num_peers;
-  ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *));
-  ctx->cadetes = GNUNET_malloc (num_peers * sizeof (struct GNUNET_CADET_Handle *));
+  ctx->ops = GNUNET_new_array (num_peers,
+                               struct GNUNET_TESTBED_Operation *);
+  ctx->cadets = GNUNET_new_array (num_peers,
+                                  struct GNUNET_CADET_Handle *);
   ctx->app_main = tmain;
   ctx->app_main_cls = tmain_cls;
-  ctx->new_channel = new_channel;
-  ctx->cleaner = cleaner;
-  ctx->handlers = handlers;
+  ctx->connects = connects;
+  ctx->window_changes = window_changes;
+  ctx->disconnects = disconnects;
+  ctx->handlers = GNUNET_MQ_copy_handlers (handlers);
   ctx->ports = ports;
+  ctx->port_count = 0;
+  while (NULL != ctx->ports[ctx->port_count])
+    ctx->port_count++;
   GNUNET_TESTBED_test_run (testname,
-                           cfgname,
+                           cfgfile,
                            num_peers,
                            0LL, NULL, NULL,
-                           &cadet_test_run, ctx);
+                           &cadet_test_run,
+                           ctx);
 }
 
 /* end of cadet_test_lib.c */