gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: - added handling of asynchronous task to


From: gnunet
Subject: [gnunet] branch master updated: - added handling of asynchronous task to testing ng. added testbed commands for setting up test invironment (atm wihtout the use of the ne async handling)
Date: Thu, 15 Apr 2021 15:37:36 +0200

This is an automated email from the git hooks/post-receive script.

t3sserakt pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 925c210d9 - added handling of asynchronous task to testing ng. added 
testbed commands for setting up test invironment (atm wihtout the use of the ne 
async handling)
925c210d9 is described below

commit 925c210d978cd0e3dfc718d9e4c65ad713a817b9
Author: t3sserakt <t3ss@posteo.de>
AuthorDate: Thu Apr 15 15:35:28 2021 +0200

    - added handling of asynchronous task to testing ng. added testbed commands 
for setting up test invironment (atm wihtout the use of the ne async handling)
---
 src/include/gnunet_testbed_ng_service.h         |  35 +--
 src/include/gnunet_testing_ng_lib.h             | 104 ++++-----
 src/testbed/testbed_api_cmd_controller.c        |   1 -
 src/testbed/testbed_api_cmd_peer.c              |  40 +++-
 src/testbed/testbed_api_cmd_peer_store.c        |  60 ++++++
 src/testbed/testbed_api_cmd_service.c           | 140 ------------
 src/testbed/testbed_api_cmd_tng_connect.c       |  55 +++++
 src/testbed/testbed_api_cmd_tng_service.c       | 276 ++++++++++++++++++++++++
 src/testing/testing.h                           |  74 +++++++
 src/testing/testing_api_cmd_batch.c             |   3 +-
 src/testing/testing_api_cmd_hello_world.c       |   1 -
 src/testing/testing_api_cmd_hello_world_birth.c |   1 -
 src/testing/testing_api_loop.c                  | 186 +++++++++++++++-
 src/transport/transport-testing-ng.h            |  71 ++++++
 14 files changed, 798 insertions(+), 249 deletions(-)

diff --git a/src/include/gnunet_testbed_ng_service.h 
b/src/include/gnunet_testbed_ng_service.h
index a6f30889f..370617e68 100644
--- a/src/include/gnunet_testbed_ng_service.h
+++ b/src/include/gnunet_testbed_ng_service.h
@@ -38,33 +38,7 @@
 #include "gnunet_util_lib.h"
 #include "gnunet_testing_ng_lib.h"
 
-struct ServiceState
-{
-  /**
-   * Handle to operation
-   */
-  struct GNUNET_TESTBED_Operation *operation;
-
-  /**
-   * Flag indicating if service is ready.
-   */
-  int service_ready;
-
-  /**
-   * Abort task identifier
-   */
-  struct GNUNET_SCHEDULER_Task *abort_task;
-
-  /**
-   * Label of peer command.
-   */
-  const char *peer_label;
-
-  /**
-   * Name of service to start.
-   */
-  const char *servicename;
-};
+struct TngState;
 
 struct PeerCmdState
 {
@@ -110,11 +84,6 @@ struct PeerCmdState
    */
   struct GNUNET_SCHEDULER_Task *abort_task;
 
-  /**
-   * Handle for host registration
-   */
-  struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle;
-
   /**
    * Flag indicating if peer is ready.
    */
@@ -242,6 +211,6 @@ void
 GNUNET_TESTBED_shutdown_peer (struct PeerCmdState *ps);
 
 void
-GNUNET_TESTBED_shutdown_service (struct ServiceState *ss);
+GNUNET_TESTBED_shutdown_service (struct TngState *ss);
 
 #endif
diff --git a/src/include/gnunet_testing_ng_lib.h 
b/src/include/gnunet_testing_ng_lib.h
index 0bc516614..001d92aad 100644
--- a/src/include/gnunet_testing_ng_lib.h
+++ b/src/include/gnunet_testing_ng_lib.h
@@ -51,46 +51,7 @@
  * Global state of the interpreter, used by a command
  * to access information about other commands.
  */
-// SUGGESTION: consider making this struct opaque (only known inside of 
libgnunettesting,
-// say main loop and a few select commands, like next/fail/batch); + helper
-// function to access 'cfg'?
-struct GNUNET_TESTING_Interpreter
-{
-
-  /**
-   * Commands the interpreter will run.
-   */
-  struct GNUNET_TESTING_Command *commands;
-
-  /**
-   * Interpreter task (if one is scheduled).
-   */
-  struct GNUNET_SCHEDULER_Task *task;
-
-  /**
-   * Our configuration.
-   */
-  const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  /**
-   * Task run on timeout.
-   */
-  struct GNUNET_SCHEDULER_Task *timeout_task;
-
-  /**
-   * Instruction pointer.  Tells #interpreter_run() which instruction to run
-   * next.  Need (signed) int because it gets -1 when rewinding the
-   * interpreter to the first CMD.
-   */
-  int ip;
-
-  /**
-   * Result of the testcases, #GNUNET_OK on success
-   */
-  int result;
-
-};
-
+struct GNUNET_TESTING_Interpreter;
 
 /**
  * A command to be run by the interpreter.
@@ -131,20 +92,25 @@ struct GNUNET_TESTING_Command
 
   /**
    * Wait for any asynchronous execution of @e run to conclude,
-   * then call @a cont.  Finish may only be called once per command.
+   * then call finish_cont. Finish may only be called once per command.
    *
    * This member may be NULL if this command is a synchronous command,
    * and also should be set to NULL once the command has finished.
    *
+   * @param cls closure
    * @param cont function to call upon completion, can be NULL
    * @param cont_cls closure for @a cont
    */
-  // SUGGESTION (NEW!)
-  void
+  bool
   (*finish)(void *cls,
-            struct GNUNET_SCHEDULER_Task cont,
+            GNUNET_SCHEDULER_TaskCallback cont,
             void *cont_cls);
 
+  /**
+   * Task for running the finish function.
+   */
+  struct GNUNET_SCHEDULER_Task *finish_task;
+
   /**
    * Clean up after the command.  Run during forced termination
    * (CTRL-C) or test failure or test success.
@@ -206,7 +172,6 @@ struct GNUNET_TESTING_Command
    * time, the interpreter will fail.  Should be set generously to ensure
    * tests do not fail on slow systems.
    */
-  // SUGGESTION (NEW):
   struct GNUNET_TIME_Relative default_timeout;
 
   /**
@@ -215,12 +180,38 @@ struct GNUNET_TESTING_Command
    * #TALER_TESTING_cmd_finish() must be used
    * to ensure that a command actually completed.
    */
-  // SUGGESTION (NEW):
   bool asynchronous_finish;
 
 };
 
 
+/**
+ * Struct to use for command-specific context information closure of a command 
waiting
+ * for another command.
+ */
+struct SyncState
+{
+  /**
+   * Closure for all commands with command-specific context information.
+   */
+  void *cls;
+
+  /**
+   * The asynchronous command the synchronous command of this closure waits 
for.
+   */
+  const struct GNUNET_TESTING_Command *async_cmd;
+
+  /**
+   * Task for running the finish method of the asynchronous task the command 
is waiting for.
+   */
+  struct GNUNET_SCHEDULER_Task *finish_task;
+
+  /**
+   * When did the execution of this commands finish function start?
+   */
+  struct GNUNET_TIME_Absolute start_finish_time;
+};
+
 /**
  * Lookup command by label.
  *
@@ -243,15 +234,6 @@ GNUNET_TESTING_interpreter_get_current_label (
   struct GNUNET_TESTING_Interpreter *is);
 
 
-/**
- * Current command is done, run the next one.
- *
- * @param is interpreter state.
- */
-void
-GNUNET_TESTING_interpreter_next (struct GNUNET_TESTING_Interpreter *is);
-
-
 /**
  * Current command failed, clean up and fail the test case.
  *
@@ -271,14 +253,13 @@ GNUNET_TESTING_cmd_end (void);
 
 
 /**
- * Turn synchronous command into asynchronous command.
+ * Turn asynchronous command into non blocking command by setting 
asynchronous_finish to true.
  *
  * @param cmd command to make synchronous.
  * @return a finish-command.
  */
-// SUGGESTION (NEW!)
 const struct GNUNET_TESTING_Command
-TALER_TESTING_cmd_make_asynchronous (const struct GNUNET_TESTING_Command cmd);
+GNUNET_TESTING_cmd_make_unblocking (const struct GNUNET_TESTING_Command cmd);
 
 
 /**
@@ -292,11 +273,10 @@ TALER_TESTING_cmd_make_asynchronous (const struct 
GNUNET_TESTING_Command cmd);
  * @param timeout how long to wait at most for @a cmd_ref to finish
  * @return a finish-command.
  */
-// SUGGESTION (NEW!)
 const struct GNUNET_TESTING_Command
-TALER_TESTING_cmd_finish (const char *finish_label,
-                          const char *cmd_ref,
-                          struct GNUNET_TIME_Relative timeout);
+GNUNET_TESTING_cmd_finish (const char *finish_label,
+                           const char *cmd_ref,
+                           struct GNUNET_TIME_Relative timeout);
 
 
 /**
diff --git a/src/testbed/testbed_api_cmd_controller.c 
b/src/testbed/testbed_api_cmd_controller.c
index d65f41760..da23df1ef 100644
--- a/src/testbed/testbed_api_cmd_controller.c
+++ b/src/testbed/testbed_api_cmd_controller.c
@@ -121,7 +121,6 @@ registration_comp (void *cls,
   {
     cs->reg_handle = NULL;
     cs->host_ready = GNUNET_YES;
-    GNUNET_TESTING_interpreter_next (cs->is);
   }
 }
 
diff --git a/src/testbed/testbed_api_cmd_peer.c 
b/src/testbed/testbed_api_cmd_peer.c
index 4a727bc94..2e253e408 100644
--- a/src/testbed/testbed_api_cmd_peer.c
+++ b/src/testbed/testbed_api_cmd_peer.c
@@ -20,8 +20,8 @@
 
 
 /**
- * @file testbed/testbed_api_cmd_controller.c
- * @brief Command to create a controller.
+ * @file testbed/testbed_api_cmd_peer.c
+ * @brief Command to create a peer.
  * @author t3sserakt
  */
 #include "platform.h"
@@ -54,10 +54,43 @@ peer_traits (void *cls,
              const char *trait,
              unsigned int index)
 {
-  (void) cls;
+  struct PeerCmdState *ps = cls;
+
+  struct GNUNET_TESTING_Trait traits[] = {
+    {
+      .index = 0,
+      .trait_name = "peer",
+      .ptr = (const void *) ps->peer,
+    },
+    GNUNET_TESTING_trait_end ()
+  };
+
+  return GNUNET_TESTING_get_trait (traits,
+                                   ret,
+                                   trait,
+                                   index);
+
   return GNUNET_OK;
 }
 
+/**
+ * Offer data from trait
+ *
+ * @param cmd command to extract the controller from.
+ * @param peer pointer GNUNET_TESTBED_PEER
+ * @return #GNUNET_OK on success.
+ */
+int
+GNUNET_TESTBED_get_trait_peer (const struct GNUNET_TESTING_Command *cmd,
+                               struct GNUNET_TESTBED_Peer **
+                               peer)
+{
+  return cmd->traits (cmd->cls,
+                      (const void **) peer,
+                      "peer",
+                      (unsigned int) 0);
+}
+
 
 /**
 *
@@ -110,7 +143,6 @@ peer_started_cb (void *cls,
   if (NULL == emsg)
   {
     ps->peer_ready = GNUNET_YES;
-    GNUNET_TESTING_interpreter_next (ps->is);
   }
   else
   {
diff --git a/src/testbed/testbed_api_cmd_peer_store.c 
b/src/testbed/testbed_api_cmd_peer_store.c
new file mode 100644
index 000000000..fc96f589c
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_peer_store.c
@@ -0,0 +1,60 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      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
+      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/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testbed/testbed_api_cmd_peer_store.c
+ * @brief Command to start the peer store service of a peer.
+ * @author t3sserakt
+ */
+
+
+static void
+service_run (void *cls,
+             const struct GNUNET_TESTING_Command *cmd,
+             struct GNUNET_TESTING_Interpreter *is)
+{
+  struct PeerStoreState *pss = cls;
+
+  pss->psh = GNUNET_PEERSTORE_connect (pss->cfg);
+  GNUNET_TESTING_interpreter_next (ps->is);
+}
+
+
+struct GNUNET_TESTING_Command
+GNUNET_TESTBED_cmd_peer_store (const char *label,
+                               struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+
+  struct PeerStoreState *pss;
+
+  pss = GNUNET_new (struct PeerStoreState);
+  pss->cfg = cfg;
+
+  struct GNUNET_TESTING_Command cmd = {
+    .cls = pss,
+    .label = label,
+    .run = &peer_store_run,
+    .cleanup = &peer_store_cleanup,
+    .traits = &peer_store_traits
+  };
+
+  return cmd;
+
+}
diff --git a/src/testbed/testbed_api_cmd_service.c 
b/src/testbed/testbed_api_cmd_service.c
deleted file mode 100644
index 58b3309de..000000000
--- a/src/testbed/testbed_api_cmd_service.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-      This file is part of GNUnet
-      Copyright (C) 2021 GNUnet e.V.
-
-      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
-      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/>.
-
-     SPDX-License-Identifier: AGPL3.0-or-later
- */
-
-/**
- * @file testbed/testbed_api_cmd_controller.c
- * @brief Command to create a controller.
- * @author t3sserakt
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_testing_ng_lib.h"
-#include "gnunet-service-testbed.h"
-#include "testbed_api_hosts.h"
-#include "gnunet_testbed_ng_service.h"
-
-/**
- * Generic logging shortcut
- */
-#define LOG(kind, ...)                           \
-  GNUNET_log (kind, __VA_ARGS__)
-
-
-/**
- * abort task to run on test timed out
- *
- * @param cls NULL
- * @param tc the task context
- */
-static void
-do_abort (void *cls)
-{
-  struct ServiceState *ss = cls;
-
-  if (GNUNET_NO == ss->service_ready)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
-    ss->abort_task = NULL;
-    GNUNET_TESTBED_shutdown_service (ss);
-  }
-}
-
-/**
-*
-*
-* @param cls closure
-* @param cmd current CMD being cleaned up.
-*/
-static void
-service_cleanup (void *cls,
-                 const struct GNUNET_TESTING_Command *cmd)
-{
-  (void) cls;
-}
-
-/**
-*
-*
-* @param cls closure.
-* @param[out] ret result
-* @param trait name of the trait.
-* @param index index number of the object to offer.
-* @return #GNUNET_OK on success.
-*/
-static int
-service_traits (void *cls,
-                const void **ret,
-                const char *trait,
-                unsigned int index)
-{
-  (void) cls;
-  return GNUNET_OK;
-}
-
-static void
-service_run (void *cls,
-             const struct GNUNET_TESTING_Command *cmd,
-             struct GNUNET_TESTING_Interpreter *is)
-{
-  struct ServiceState *ss = cls;
-
-  // TODO this is unfinished code!
-  ss->operation =
-    GNUNET_TESTBED_service_connect (NULL, NULL, NULL,
-                                    NULL, NULL,
-                                    NULL,
-                                    NULL, NULL);
-
-}
-
-/**
- * Shutdown nicely
- *
- * @param cs service state.
- */
-void
-GNUNET_TESTBED_shutdown_service (struct ServiceState *cs)
-{
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Shutting down...\n");
-}
-
-
-struct GNUNET_TESTING_Command
-GNUNET_TESTBED_cmd_service (const char *label,
-                            const char *peer_label,
-                            const char *servicename)
-{
-  struct ServiceState *ss;
-
-  ss = GNUNET_new (struct ServiceState);
-  ss->servicename = servicename;
-  ss->peer_label = peer_label;
-
-  struct GNUNET_TESTING_Command cmd = {
-    .cls = ss,
-    .label = label,
-    .run = &service_run,
-    .cleanup = &service_cleanup,
-    .traits = &service_traits
-  };
-
-  return cmd;
-}
diff --git a/src/testbed/testbed_api_cmd_tng_connect.c 
b/src/testbed/testbed_api_cmd_tng_connect.c
new file mode 100644
index 000000000..e52cd3c76
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_tng_connect.c
@@ -0,0 +1,55 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      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
+      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/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+
+/**
+ * @file testbed/testbed_api_cmd_peer.c
+ * @brief Command to create a peer.
+ * @author t3sserakt
+ */
+
+
+static void
+tng_connect_run (void *cls,
+                 const struct GNUNET_TESTING_Command *cmd,
+                 struct GNUNET_TESTING_Interpreter *is)
+{
+  struct TngConnectState *tcs = cls;
+
+  tcs->ah = GNUNET_TRANSPORT_application_init (tcs->cfg);
+}
+
+struct GNUNET_TESTING_Command
+GNUNET_TESTBED_cmd_tng_connect (const char *label)
+{
+  struct TngConnectState *tcs;
+
+  ts = GNUNET_new (struct TngConnectState);
+
+  struct GNUNET_TESTING_Command cmd = {
+    .cls = tcs,
+    .label = label,
+    .run = &tng_connect_run,
+    .cleanup = &tmg_connect_cleanup,
+    .traits = &tng_connect_traits
+  };
+
+  return cmd;
+}
diff --git a/src/testbed/testbed_api_cmd_tng_service.c 
b/src/testbed/testbed_api_cmd_tng_service.c
new file mode 100644
index 000000000..f9ef44bad
--- /dev/null
+++ b/src/testbed/testbed_api_cmd_tng_service.c
@@ -0,0 +1,276 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      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
+      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/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @file testbed/testbed_api_cmd_tng.c
+ * @brief Command to start the transport service of a peer.
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_testing_ng_lib.h"
+#include "gnunet-service-testbed.h"
+#include "testbed_api_hosts.h"
+#include "gnunet_testbed_ng_service.h"
+
+/**
+ * Generic logging shortcut
+ */
+#define LOG(kind, ...)                           \
+  GNUNET_log (kind, __VA_ARGS__)
+
+
+/**
+ * abort task to run on test timed out
+ *
+ * @param cls NULL
+ * @param tc the task context
+ */
+static void
+do_abort (void *cls)
+{
+  struct TngState *ts = cls;
+
+  if (GNUNET_NO == ts->service_ready)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING, "Test timedout -- Aborting\n");
+    ts->abort_task = NULL;
+    GNUNET_TESTBED_shutdown_service (ts);
+  }
+}
+
+/**
+*
+*
+* @param cls closure
+* @param cmd current CMD being cleaned up.
+*/
+static void
+tng_service_cleanup (void *cls,
+                     const struct GNUNET_TESTING_Command *cmd)
+{
+  (void) cls;
+}
+
+/**
+*
+*
+* @param cls closure.
+* @param[out] ret result
+* @param trait name of the trait.
+* @param index index number of the object to offer.
+* @return #GNUNET_OK on success.
+*/
+static int
+tng_service_traits (void *cls,
+                    const void **ret,
+                    const char *trait,
+                    unsigned int index)
+{
+  (void) cls;
+  return GNUNET_OK;
+}
+
+
+static void *
+notify_connect (void *cls,
+                const struct GNUNET_PeerIdentity *peer,
+                struct GNUNET_MQ_Handle *mq)
+{
+  struct TngState *ts = cls;
+
+  if (NULL != emsg)
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         "There was an error starting the transport subsystem: %s\n",
+         emsg);
+  }
+  GNUNET_TESTING_interpreter_next (ps->is);
+  return ts->nc (ts->cb_cls);
+
+}
+
+
+static void
+notify_disconnect (void *cls,
+                   const struct GNUNET_PeerIdentity *peer,
+                   void *handler_cls)
+{
+}
+
+
+
+
+/**
+ * Adapter function called to establish a connection to
+ * a service.
+ *
+ * @param cls closure
+ * @param cfg configuration of the peer to connect to; will be available until
+ *          GNUNET_TESTBED_operation_done() is called on the operation returned
+ *          from GNUNET_TESTBED_service_connect()
+ * @return service handle to return in 'op_result', NULL on error
+ */
+static void *
+connect_adapter (void *cls,
+                 const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  struct TngState *ts = cls;
+
+  service_handle = GNUNET_TRANSPORT_core_connect (cfg,
+                                                  ts->peer_identity,
+                                                  ts->handlers,
+                                                  ts,
+                                                  &notify_connect,
+                                                  &notify_disconnect);
+  return service_handle;
+}
+
+
+/**
+ * Adapter function called to destroy a connection to
+ * a service.
+ *
+ * @param cls closure
+ * @param op_result service handle returned from the connect adapter
+ */
+static void
+disconnect_adapter (void *cls,
+                    void *op_result)
+{
+}
+
+/**
+ * Callback to be called when a service connect operation is completed
+ *
+ * @param cls the callback closure from functions generating an operation
+ * @param op the operation that has been finished
+ * @param ca_result the service handle returned from 
GNUNET_TESTBED_ConnectAdapter()
+ * @param emsg error message in case the operation has failed; will be NULL if
+ *          operation has executed successfully.
+ */
+static void
+service_connect_comp_cb (void *cls,
+                         struct GNUNET_TESTBED_Operation *op,
+                         void *ca_result,
+                         const char *emsg)
+{
+  struct TngState *ts = cls;
+
+  if (NULL != emsg)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "An error occured connecting to service %s\n",
+         emsg);
+    GNUNET_TESTBED_operation_done (ts->operation);
+  }
+}
+
+
+/**
+ * Callback to be called when the requested peer information is available
+ *
+ * @param cls the closure from GNUNET_TESTBED_peer_getinformation()
+ * @param op the operation this callback corresponds to
+ * @param pinfo the result; will be NULL if the operation has failed
+ * @param emsg error message if the operation has failed;
+ *             NULL if the operation is successfull
+ */
+static void
+pi_cb (void *cls,
+       struct GNUNET_TESTBED_Operation *op,
+       const struct GNUNET_TESTBED_PeerInformation *pinfo,
+       const char *emsg)
+{
+  struct TngState *ts = cls;
+
+  ts->peer_identity = pinfo->id;
+  ts->operation =
+    GNUNET_TESTBED_service_connect (NULL, peer, NULL,
+                                    &service_connect_comp_cb, ts,
+                                    &connect_adapter,
+                                    &disconnect_adapter,
+                                    ts);
+}
+
+
+static void
+tng_service_run (void *cls,
+                 const struct GNUNET_TESTING_Command *cmd,
+                 struct GNUNET_TESTING_Interpreter *is)
+{
+  struct TngState *ts = cls;
+  struct GNUNET_TESTBED_Peer *peer;
+  const struct GNUNET_TESTING_Command *peer_cmd;
+
+  ts->is = is;
+  peer_cmd = GNUNET_TESTING_interpreter_lookup_command (
+    ts->peer_label);
+  GNUNET_TESTBED_get_trait_peer (peer_cmd,
+                                 &peer);
+
+  ts->operation = GNUNET_TESTBED_peer_get_information (peer,
+                                                       
GNUNET_TESTBED_PIT_IDENTITY,
+                                                       &pi_cb,
+                                                       ts);
+}
+
+/**
+ * Shutdown nicely
+ *
+ * @param cs service state.
+ */
+void
+GNUNET_TESTBED_shutdown_service (struct TngState *cs)
+{
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Shutting down...\n");
+}
+
+
+struct GNUNET_TESTING_Command
+GNUNET_TESTBED_cmd_tng_service (const char *label,
+                                const char *peer_label,
+                                const struct GNUNET_MQ_MessageHandler 
*handlers,
+                                GNUNET_TRANSPORT_NotifyConnect nc,
+                                void *cb_cls)
+
+{
+  struct TngState *ts;
+
+  ts = GNUNET_new (struct TngState);
+  ts->servicename = servicename;
+  ts->peer_label = peer_label;
+  ts->handlers = handlers;
+  ts->nc = nc;
+  ts->nd = nd;
+  ts->cb_cls;
+
+
+  struct GNUNET_TESTING_Command cmd = {
+    .cls = ts,
+    .label = label,
+    .run = &tng_service_run,
+    .cleanup = &tmg_service_cleanup,
+    .traits = &tng_service_traits
+  };
+
+  return cmd;
+}
diff --git a/src/testing/testing.h b/src/testing/testing.h
new file mode 100644
index 000000000..b12466530
--- /dev/null
+++ b/src/testing/testing.h
@@ -0,0 +1,74 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      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
+      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/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @author t3sserakt
+ */
+
+#include "gnunet_util_lib.h"
+
+/**
+ * Global state of the interpreter, used by a command
+ * to access information about other commands.
+ */
+// SUGGESTION: consider making this struct opaque (only known inside of 
libgnunettesting,
+// say main loop and a few select commands, like next/fail/batch); + helper
+// function to access 'cfg'?
+struct GNUNET_TESTING_Interpreter
+{
+
+  /**
+   * Commands the interpreter will run.
+   */
+  struct GNUNET_TESTING_Command *commands;
+
+  /**
+   * Interpreter task (if one is scheduled).
+   */
+  struct GNUNET_SCHEDULER_Task *task;
+
+  /**
+   * Finish task of a blocking call to a commands finish method.
+   */
+  struct GNUNET_SCHEDULER_Task *finish_task;
+
+  /**
+   * Our configuration.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Task run on timeout.
+   */
+  struct GNUNET_SCHEDULER_Task *timeout_task;
+
+  /**
+   * Instruction pointer.  Tells #interpreter_run() which instruction to run
+   * next.  Need (signed) int because it gets -1 when rewinding the
+   * interpreter to the first CMD.
+   */
+  int ip;
+
+  /**
+   * Result of the testcases, #GNUNET_OK on success
+   */
+  int result;
+
+};
diff --git a/src/testing/testing_api_cmd_batch.c 
b/src/testing/testing_api_cmd_batch.c
index 531778129..af260f80d 100644
--- a/src/testing/testing_api_cmd_batch.c
+++ b/src/testing/testing_api_cmd_batch.c
@@ -26,7 +26,7 @@
  */
 #include "platform.h"
 #include "gnunet_testing_ng_lib.h"
-
+#include "testing.h"
 
 /**
  * State for a "batch" CMD.
@@ -70,7 +70,6 @@ batch_run (void *cls,
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Exiting from batch: %s\n",
                 cmd->label);
-    GNUNET_TESTING_interpreter_next (is);
     return;
   }
   bs->batch[bs->batch_ip].start_time
diff --git a/src/testing/testing_api_cmd_hello_world.c 
b/src/testing/testing_api_cmd_hello_world.c
index 8c1d7353d..4347ac818 100644
--- a/src/testing/testing_api_cmd_hello_world.c
+++ b/src/testing/testing_api_cmd_hello_world.c
@@ -89,7 +89,6 @@ hello_world_run (void *cls,
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Now I am a %s\n",
               hs->message);
-  GNUNET_TESTING_interpreter_next (is);
 }
 
 /**
diff --git a/src/testing/testing_api_cmd_hello_world_birth.c 
b/src/testing/testing_api_cmd_hello_world_birth.c
index 0faf93cd8..2a5bded92 100644
--- a/src/testing/testing_api_cmd_hello_world_birth.c
+++ b/src/testing/testing_api_cmd_hello_world_birth.c
@@ -112,7 +112,6 @@ hello_world_birth_run (void *cls,
   {
     hbs->what_am_i = "boy!";
   }
-  GNUNET_TESTING_interpreter_next (is);
 }
 
 /**
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c
index f29329a60..dbd86ba90 100644
--- a/src/testing/testing_api_loop.c
+++ b/src/testing/testing_api_loop.c
@@ -28,9 +28,49 @@
 #include "platform.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_testing_ng_lib.h"
+#include "testing.h"
 
 struct GNUNET_TESTING_Interpreter *is;
 
+/**
+ * Closure used to sync an asynchronous with an synchronous command.
+ */
+struct SyncTaskClosure
+{
+
+  /**
+   * The asynchronous command the synchronous command waits for.
+   */
+  const struct GNUNET_TESTING_Command *async_cmd;
+
+  /**
+   * The synchronous command that waits for the asynchronous command.
+   */
+  const struct GNUNET_TESTING_Command *sync_cmd;
+
+  /**
+   * The interpreter of the test.
+   */
+  struct GNUNET_TESTING_Interpreter *is;
+};
+
+/**
+* Closure used to run the finish task.
+*/
+struct FinishTaskClosure
+{
+
+  /**
+   * The asynchronous command the synchronous command waits for.
+   */
+  const struct GNUNET_TESTING_Command *cmd;
+
+  /**
+   * The interpreter of the test.
+   */
+  struct GNUNET_TESTING_Interpreter *is;
+};
+
 /**
  * Lookup command by label.
  *
@@ -107,9 +147,10 @@ interpreter_run (void *cls);
 /**
  * Current command is done, run the next one.
  */
-void
-GNUNET_TESTING_interpreter_next (struct GNUNET_TESTING_Interpreter *is)
+static void
+interpreter_next (void *cls)
 {
+  struct GNUNET_TESTING_Interpreter *is = cls;
   static unsigned long long ipc;
   static struct GNUNET_TIME_Absolute last_report;
   struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
@@ -141,6 +182,123 @@ GNUNET_TESTING_interpreter_next (struct 
GNUNET_TESTING_Interpreter *is)
 }
 
 
+static void
+run_finish_task_next (void *cls)
+{
+  struct FinishTaskClosure *ftc = cls;
+  const struct GNUNET_TESTING_Command *cmd = ftc->cmd;
+  struct GNUNET_TESTING_Interpreter *is = ftc->is;
+
+  if (cmd->finish (cmd->cls, &interpreter_next, is))
+  {
+    is->finish_task = GNUNET_SCHEDULER_add_now (&run_finish_task_next, ftc);
+  }
+  else
+  {
+    is->finish_task = NULL;
+  }
+
+}
+
+
+static void
+run_finish_task_sync (void *cls)
+{
+  struct SyncTaskClosure *stc = cls;
+  const struct GNUNET_TESTING_Command *cmd = stc->async_cmd;
+  const struct GNUNET_TESTING_Command *sync_cmd = stc->sync_cmd;
+  struct FinishTaskClosure *ftc;
+  struct SyncState *sync_state = sync_cmd->cls;
+  struct GNUNET_SCHEDULER_Task *finish_task = sync_state->finish_task;
+
+  GNUNET_assert (NULL != finish_task);
+  ftc = GNUNET_new (struct FinishTaskClosure);
+  ftc->cmd = stc->sync_cmd;
+  ftc->is = stc->is;
+  struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
+  if (cmd->default_timeout.rel_value_us < now.abs_value_us
+      - sync_state->start_finish_time.abs_value_us)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "The command with label %s did not finish its asyncronous task 
in time.\n",
+                cmd->label);
+    is->result = GNUNET_SYSERR;
+    GNUNET_SCHEDULER_shutdown ();
+  }
+
+  if (cmd->finish (cmd->cls, run_finish_task_next, ftc))
+  {
+    finish_task = GNUNET_SCHEDULER_add_now (&run_finish_task_sync, stc);
+  }
+  else
+  {
+    finish_task = NULL;
+  }
+}
+
+
+static void
+start_finish_on_ref (void *cls,
+                     const struct GNUNET_TESTING_Command *cmd,
+                     struct GNUNET_TESTING_Interpreter *is)
+{
+  struct SyncState *sync_state = cls;
+  struct SyncTaskClosure *stc;
+  const struct GNUNET_TESTING_Command *async_cmd;
+
+  async_cmd = sync_state->async_cmd;
+  stc = GNUNET_new (struct SyncTaskClosure);
+  stc->async_cmd = async_cmd;
+  stc->sync_cmd = cmd;
+  stc->is = is;
+  sync_state->start_finish_time = GNUNET_TIME_absolute_get ();
+  sync_state->finish_task = GNUNET_SCHEDULER_add_now (&run_finish_task_sync,
+                                                      stc);
+}
+
+
+const struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_finish (const char *finish_label,
+                           const char *cmd_ref,
+                           struct GNUNET_TIME_Relative timeout)
+{
+  const struct GNUNET_TESTING_Command *async_cmd;
+  struct SyncState *sync_state;
+
+  async_cmd = GNUNET_TESTING_interpreter_lookup_command (cmd_ref);
+  sync_state = GNUNET_new (struct SyncState);
+  sync_state->async_cmd = async_cmd;
+
+  struct GNUNET_TESTING_Command cmd = {
+    .cls = sync_state,
+    .label = finish_label,
+    .run = &start_finish_on_ref,
+    .asynchronous_finish = GNUNET_NO
+  };
+
+  return cmd;
+}
+
+
+const struct GNUNET_TESTING_Command
+GNUNET_TESTING_cmd_make_asynchronous (const struct GNUNET_TESTING_Command cmd)
+{
+
+  GNUNET_assert (NULL != cmd.finish);
+  const struct GNUNET_TESTING_Command async_cmd = {
+    .cls = cmd.cls,
+    .label = cmd.label,
+    .run = cmd.run,
+    .cleanup = cmd.cleanup,
+    .traits = cmd.traits,
+    .finish = cmd.finish,
+    .asynchronous_finish = GNUNET_YES
+  };
+
+  return async_cmd;
+}
+
+
 /**
  * Current command failed, clean up and fail the test case.
  *
@@ -195,14 +353,15 @@ GNUNET_TESTING_interpreter_get_current_label (struct
 
 
 /**
- * Run the main interpreter loop that performs exchange operations.
+ * Run the main interpreter loop.
  *
  * @param cls contains the `struct GNUNET_TESTING_Interpreter`
  */
 static void
 interpreter_run (void *cls)
 {
-  (void) cls;
+  struct FinishTaskClosure *ftc;
+  struct GNUNET_TESTING_Interpreter *is = cls;
   struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip];
 
   is->task = NULL;
@@ -227,6 +386,17 @@ interpreter_run (void *cls)
   cmd->run (cmd->cls,
             cmd,
             is);
+  if ((NULL != cmd->finish) && (GNUNET_NO == cmd->asynchronous_finish))
+  {
+    ftc = GNUNET_new (struct FinishTaskClosure);
+    ftc->cmd = cmd;
+    ftc->is = is;
+    cmd->finish_task = GNUNET_SCHEDULER_add_now (run_finish_task_next, ftc);
+  }
+  else
+  {
+    interpreter_next (is);
+  }
 }
 
 
@@ -253,9 +423,15 @@ do_shutdown (void *cls)
 
   for (unsigned int j = 0;
        NULL != (cmd = &is->commands[j])->label;
-       j++)
+       j++) {
     cmd->cleanup (cmd->cls,
                   cmd);
+    if (NULL != cmd->finish_task)
+    {
+      GNUNET_SCHEDULER_cancel (cmd->finish_task);
+      cmd->finish_task = NULL;
+    }
+  }
 
   if (NULL != is->task)
   {
diff --git a/src/transport/transport-testing-ng.h 
b/src/transport/transport-testing-ng.h
new file mode 100644
index 000000000..cd5ba65a9
--- /dev/null
+++ b/src/transport/transport-testing-ng.h
@@ -0,0 +1,71 @@
+/*
+      This file is part of GNUnet
+      Copyright (C) 2021 GNUnet e.V.
+
+      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
+      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/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+ */
+
+/**
+ * @author t3sserakt
+ */
+
+struct TngState
+{
+  /**
+   * Handle to operation
+   */
+  struct GNUNET_TESTBED_Operation *operation;
+
+  /**
+   * Flag indicating if service is ready.
+   */
+  int service_ready;
+
+  /**
+   * Abort task identifier
+   */
+  struct GNUNET_SCHEDULER_Task *abort_task;
+
+  /**
+   * Label of peer command.
+   */
+  const char *peer_label;
+
+  /**
+   * Name of service to start.
+   */
+  const char *servicename;
+
+  /**
+   * Peer identity of the system.
+   */
+  struct GNUNET_PeerIdentity *peer_identity;
+
+  /**
+   * Message handler for transport service.
+   */
+  const struct GNUNET_MQ_MessageHandler *handlers;
+
+  /**
+   * Notify connect callback
+   */
+  GNUNET_TRANSPORT_NotifyConnect nc;
+
+  /**
+   * Closure for the @a nc callback
+   */
+  void *cb_cls;
+};

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]