gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r11319 - gnunet/src/testing


From: gnunet
Subject: [GNUnet-SVN] r11319 - gnunet/src/testing
Date: Tue, 11 May 2010 18:11:56 +0200

Author: nevans
Date: 2010-05-11 18:11:56 +0200 (Tue, 11 May 2010)
New Revision: 11319

Added:
   gnunet/src/testing/test_testing_topology_blacklist.c
Modified:
   gnunet/src/testing/testing_group.c
Log:
blacklist testcase, testing_group support for blacklisting

Added: gnunet/src/testing/test_testing_topology_blacklist.c
===================================================================
--- gnunet/src/testing/test_testing_topology_blacklist.c                        
        (rev 0)
+++ gnunet/src/testing/test_testing_topology_blacklist.c        2010-05-11 
16:11:56 UTC (rev 11319)
@@ -0,0 +1,505 @@
+/*
+     This file is part of GNUnet.
+     (C) 2009 Christian Grothoff (and other contributing authors)
+
+     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
+     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.
+
+     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.
+*/
+/**
+ * @file testing/test_testing_topology_blacklist.c
+ * @brief base testcase for testing transport level blacklisting
+ */
+#include "platform.h"
+#include "gnunet_testing_lib.h"
+#include "gnunet_core_service.h"
+
+#define VERBOSE GNUNET_YES
+
+/**
+ * How long until we fail the whole testcase?
+ */
+#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 
600)
+
+/**
+ * How long until we give up on starting the peers? (Must be longer than the 
connect timeout!)
+ */
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
+
+#define DEFAULT_NUM_PEERS 4
+
+#define MAX_OUTSTANDING_CONNECTIONS 300
+
+static int ok;
+
+static unsigned long long num_peers;
+
+static unsigned int total_connections;
+
+static unsigned int failed_connections;
+
+static unsigned int expected_connections;
+
+static unsigned int expected_failed_connections;
+
+static unsigned long long peers_left;
+
+static struct GNUNET_TESTING_PeerGroup *pg;
+
+static struct GNUNET_SCHEDULER_Handle *sched;
+
+const struct GNUNET_CONFIGURATION_Handle *main_cfg;
+
+GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+static char *dotOutFileName;
+
+static FILE *dotOutFile;
+
+static char *blacklist_transports;
+
+static enum GNUNET_TESTING_Topology topology = GNUNET_TESTING_TOPOLOGY_CLIQUE; 
/* Overlay should allow all connections */
+
+static enum GNUNET_TESTING_Topology blacklist_topology = 
GNUNET_TESTING_TOPOLOGY_RING; /* Blacklist underlay into a ring */
+
+static enum GNUNET_TESTING_Topology connection_topology = 
GNUNET_TESTING_TOPOLOGY_NONE; /* NONE actually means connect all allowed peers 
*/
+
+static enum GNUNET_TESTING_TopologyOption connect_topology_option = 
GNUNET_TESTING_TOPOLOGY_OPTION_ALL; /* Try to connect all possible OVERLAY 
connections */
+
+static double connect_topology_option_modifier = 0.0;
+
+static char *test_directory;
+
+#define MTYPE 12345
+
+struct GNUNET_TestMessage
+{
+  /**
+   * Header of the message
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Unique identifier for this message.
+   */
+  uint32_t uid;
+};
+
+static void
+finish_testing ()
+{
+  GNUNET_assert (pg != NULL);
+
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Called finish testing, stopping daemons.\n");
+#endif
+  sleep(1);
+#if VERBOSE
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      "Calling daemons_stop\n");
+#endif
+  GNUNET_TESTING_daemons_stop (pg, TIMEOUT);
+#if VERBOSE
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      "daemons_stop finished\n");
+#endif
+  if (dotOutFile != NULL)
+    {
+      fprintf(dotOutFile, "}");
+      fclose(dotOutFile);
+    }
+
+  ok = 0;
+}
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  char *msg = cls;
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "End badly was called (%s)... stopping daemons.\n", msg);
+
+  if (pg != NULL)
+    {
+      GNUNET_TESTING_daemons_stop (pg, TIMEOUT);
+      ok = 7331;                /* Opposite of leet */
+    }
+  else
+    ok = 401;                   /* Never got peers started */
+
+  if (dotOutFile != NULL)
+    {
+      fprintf(dotOutFile, "}");
+      fclose(dotOutFile);
+    }
+}
+
+
+
+void
+topology_callback (void *cls,
+                   const struct GNUNET_PeerIdentity *first,
+                   const struct GNUNET_PeerIdentity *second,
+                   const struct GNUNET_CONFIGURATION_Handle *first_cfg,
+                   const struct GNUNET_CONFIGURATION_Handle *second_cfg,
+                   struct GNUNET_TESTING_Daemon *first_daemon,
+                   struct GNUNET_TESTING_Daemon *second_daemon,
+                   const char *emsg)
+{
+  if (emsg == NULL)
+    {
+      total_connections++;
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connected peer %s to peer %s\n",
+               first_daemon->shortname,
+               second_daemon->shortname);
+#endif
+      if (dotOutFile != NULL)
+        fprintf(dotOutFile, "\tn%s -- n%s;\n", first_daemon->shortname, 
second_daemon->shortname);
+    }
+#if VERBOSE
+  else
+    {
+      failed_connections++;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect peer %s to peer 
%s with error :\n%s\n",
+               first_daemon->shortname,
+               second_daemon->shortname, emsg);
+    }
+#endif
+
+  if (total_connections == expected_connections)
+    {
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Created %d total connections, which is our target number 
(that's bad)!\n",
+                  total_connections);
+#endif
+
+      GNUNET_SCHEDULER_cancel (sched, die_task);
+      die_task = GNUNET_SCHEDULER_NO_TASK;
+      die_task = GNUNET_SCHEDULER_add_now (sched,
+                                           &end_badly, "from topology_callback 
(too many successful connections)");
+    }
+  else if (total_connections + failed_connections == expected_connections)
+    {
+      if ((failed_connections == expected_failed_connections) && 
(total_connections == expected_connections - expected_failed_connections))
+        {
+          GNUNET_SCHEDULER_cancel (sched, die_task);
+          die_task = GNUNET_SCHEDULER_NO_TASK;
+          die_task = GNUNET_SCHEDULER_add_now (sched,
+                                               &finish_testing, NULL);
+        }
+      else
+        {
+          GNUNET_SCHEDULER_cancel (sched, die_task);
+          die_task = GNUNET_SCHEDULER_add_now (sched,
+                                               &end_badly, "from 
topology_callback (wrong number of failed connections)");
+        }
+    }
+  else
+    {
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Have %d total connections, %d failed connections, Want %d 
(failed) and %d (successful)\n",
+                  total_connections, failed_connections, 
expected_failed_connections, expected_connections - 
expected_failed_connections);
+#endif
+    }
+}
+
+static void
+connect_topology ()
+{
+  expected_connections = -1;
+  if ((pg != NULL) && (peers_left == 0))
+    {
+      expected_connections = GNUNET_TESTING_connect_topology (pg, 
connection_topology, connect_topology_option, connect_topology_option_modifier);
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Have %d expected connections\n", expected_connections);
+#endif
+    }
+
+  GNUNET_SCHEDULER_cancel (sched, die_task);
+  if (expected_connections == GNUNET_SYSERR)
+    {
+      die_task = GNUNET_SCHEDULER_add_now (sched,
+                                           &end_badly, "from connect topology 
(bad return)");
+    }
+
+  die_task = GNUNET_SCHEDULER_add_delayed (sched,
+                                           TEST_TIMEOUT,
+                                           &end_badly, "from connect topology 
(timeout)");
+}
+
+static void
+create_topology ()
+{
+  peers_left = num_peers; /* Reset counter */
+  if (GNUNET_TESTING_create_topology (pg, topology, blacklist_topology, 
blacklist_transports) != GNUNET_SYSERR)
+    {
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Topology set up, now starting peers!\n");
+#endif
+      GNUNET_TESTING_daemons_continue_startup(pg);
+    }
+  else
+    {
+      GNUNET_SCHEDULER_cancel (sched, die_task);
+      die_task = GNUNET_SCHEDULER_add_now (sched,
+                                           &end_badly, "from create topology 
(bad return)");
+    }
+  GNUNET_SCHEDULER_cancel (sched, die_task);
+  die_task = GNUNET_SCHEDULER_add_delayed (sched,
+                                           TEST_TIMEOUT,
+                                           &end_badly, "from continue startup 
(timeout)");
+}
+
+
+static void
+peers_started_callback (void *cls,
+       const struct GNUNET_PeerIdentity *id,
+       const struct GNUNET_CONFIGURATION_Handle *cfg,
+       struct GNUNET_TESTING_Daemon *d, const char *emsg)
+{
+  if (emsg != NULL)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to start daemon with error: 
`%s'\n",
+                  emsg);
+      return;
+    }
+  GNUNET_assert (id != NULL);
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n",
+              (num_peers - peers_left) + 1, num_peers);
+#endif
+  peers_left--;
+  if (peers_left == 0)
+    {
+#if VERBOSE
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "All %d daemons started, now creating topology!\n",
+                  num_peers);
+#endif
+      GNUNET_SCHEDULER_cancel (sched, die_task);
+      /* Set up task in case topology creation doesn't finish
+       * within a reasonable amount of time */
+      die_task = GNUNET_SCHEDULER_add_delayed (sched,
+                                               GNUNET_TIME_relative_multiply
+                                               (GNUNET_TIME_UNIT_MINUTES, 5),
+                                               &end_badly, "from 
peers_started_callback");
+      connect_topology ();
+      ok = 0;
+    }
+}
+
+/**
+ * Callback indicating that the hostkey was created for a peer.
+ *
+ * @param cls NULL
+ * @param id the peer identity
+ * @param d the daemon handle (pretty useless at this point, remove?)
+ * @param emsg non-null on failure
+ */
+void hostkey_callback (void *cls,
+                       const struct GNUNET_PeerIdentity *id,
+                       struct GNUNET_TESTING_Daemon *d,
+                       const char *emsg)
+{
+  if (emsg != NULL)
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Hostkey callback received error: 
%s\n", emsg);
+    }
+
+#if VERBOSE
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Hostkey created for peer `%s'\n",
+                GNUNET_i2s(id));
+#endif
+    peers_left--;
+    if (peers_left == 0)
+      {
+#if VERBOSE
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "All %d hostkeys created, now creating topology!\n",
+                    num_peers);
+#endif
+        GNUNET_SCHEDULER_cancel (sched, die_task);
+        /* Set up task in case topology creation doesn't finish
+         * within a reasonable amount of time */
+        die_task = GNUNET_SCHEDULER_add_delayed (sched,
+                                                 GNUNET_TIME_relative_multiply
+                                                 (GNUNET_TIME_UNIT_MINUTES, 5),
+                                                 &end_badly, "from 
hostkey_callback");
+        GNUNET_SCHEDULER_add_now(sched, &create_topology, NULL);
+        ok = 0;
+      }
+}
+
+static void
+run (void *cls,
+     struct GNUNET_SCHEDULER_Handle *s,
+     char *const *args,
+     const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  unsigned long long topology_num;
+  unsigned long long connect_topology_num;
+  unsigned long long blacklist_topology_num;
+  unsigned long long connect_topology_option_num;
+  char *connect_topology_option_modifier_string;
+  sched = s;
+  ok = 1;
+
+  dotOutFile = fopen (dotOutFileName, "w");
+  if (dotOutFile != NULL)
+    {
+      fprintf (dotOutFile, "strict graph G {\n");
+    }
+
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Starting daemons based on config file %s\n", cfgfile);
+#endif
+
+  if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string(cfg, "paths", 
"servicehome", &test_directory))
+    {
+      ok = 404;
+      return;
+    }
+
+  if (GNUNET_YES ==
+      GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "topology",
+                                             &topology_num))
+    topology = topology_num;
+
+  if (GNUNET_YES ==
+      GNUNET_CONFIGURATION_get_value_number (cfg, "testing", 
"connect_topology",
+                                             &connect_topology_num))
+    connection_topology = connect_topology_num;
+
+  if (GNUNET_YES ==
+        GNUNET_CONFIGURATION_get_value_number (cfg, "testing", 
"connect_topology_option",
+                                               &connect_topology_option_num))
+    connect_topology_option = connect_topology_option_num;
+
+  if (GNUNET_YES ==
+        GNUNET_CONFIGURATION_get_value_string (cfg, "testing", 
"connect_topology_option_modifier",
+                                               
&connect_topology_option_modifier_string))
+    {
+      if (sscanf(connect_topology_option_modifier_string, "%lf", 
&connect_topology_option_modifier) != 1)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+        _("Invalid value `%s' for option `%s' in section `%s': expected 
float\n"),
+        connect_topology_option_modifier_string,
+        "connect_topology_option_modifier",
+        "TESTING");
+        GNUNET_free (connect_topology_option_modifier_string);
+      }
+    }
+
+  GNUNET_CONFIGURATION_get_value_string (cfg, "testing", 
"blacklist_transports",
+                                         &blacklist_transports);
+
+  if (GNUNET_YES ==
+      GNUNET_CONFIGURATION_get_value_number (cfg, "testing", 
"blacklist_topology",
+                                             &blacklist_topology_num))
+    blacklist_topology = blacklist_topology_num;
+
+  if (GNUNET_SYSERR ==
+      GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers",
+                                             &num_peers))
+    num_peers = DEFAULT_NUM_PEERS;
+
+  main_cfg = cfg;
+
+  peers_left = num_peers;
+
+  /* For this specific test we only really want a CLIQUE topology as the
+   * overlay allowed topology, and a RING topology as the underlying connection
+   * allowed topology.  So we will expect only num_peers * 2 connections to
+   * work, and (num_peers * (num_peers - 1)) - (num_peers * 2) to fail.
+   */
+  expected_connections = num_peers * (num_peers - 1);
+  expected_failed_connections = expected_connections - (num_peers * 2);
+
+
+  /* Set up a task to end testing if peer start fails */
+  die_task = GNUNET_SCHEDULER_add_delayed (sched,
+                                           GNUNET_TIME_relative_multiply
+                                           (GNUNET_TIME_UNIT_MINUTES, 5),
+                                           &end_badly, "didn't start all 
daemons in reasonable amount of time!!!");
+
+  pg = GNUNET_TESTING_daemons_start (sched, cfg,
+                                     peers_left, TIMEOUT, &hostkey_callback, 
NULL, &peers_started_callback, NULL,
+                                     &topology_callback, NULL, NULL);
+
+}
+
+static int
+check ()
+{
+  int ret;
+  char *const argv[] = {"test-testing-topology-blacklist",
+    "-c",
+    "test_testing_data_topology_blacklist.conf",
+#if VERBOSE
+    "-L", "DEBUG",
+#endif
+    NULL
+  };
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_OPTION_END
+  };
+  ret = GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
+                      argv, "test-testing-topology-blacklist", "nohelp",
+                      options, &run, &ok);
+  if (ret != GNUNET_OK)
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 
"`test-testing-topology-blacklist': Failed with error code %d\n", ret);
+    }
+
+  return ok;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int ret;
+
+  GNUNET_log_setup ("test_testing_topology_blacklist",
+#if VERBOSE
+                    "DEBUG",
+#else
+                    "WARNING",
+#endif
+                    NULL);
+  ret = check ();
+
+  /**
+   * Need to remove base directory, subdirectories taken care
+   * of by the testing framework.
+   */
+  if (test_directory != NULL)
+    {
+      if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK)
+        {
+          GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to remove testing 
directory %s\n", test_directory);
+        }
+    }
+
+  return ret;
+}
+
+/* end of test_testing_topology_blacklist.c */

Modified: gnunet/src/testing/testing_group.c
===================================================================
--- gnunet/src/testing/testing_group.c  2010-05-11 16:00:00 UTC (rev 11318)
+++ gnunet/src/testing/testing_group.c  2010-05-11 16:11:56 UTC (rev 11319)
@@ -57,6 +57,42 @@
 typedef int (*GNUNET_TESTING_ConnectionProcessor)
 (struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, unsigned int second);
 
+/**
+ * Context for handling churning a peer group
+ */
+struct ChurnContext
+{
+  /**
+   * Callback used to notify of churning finished
+   */
+  GNUNET_TESTING_NotifyCompletion cb;
+
+  /**
+   * Closure for callback
+   */
+  void *cb_cls;
+
+  /**
+   * Number of peers that still need to be started
+   */
+  unsigned int num_to_start;
+
+  /**
+   * Number of peers that still need to be stopped
+   */
+  unsigned int num_to_stop;
+ 
+  /**
+   * Number of peers that failed to start
+   */
+  unsigned int num_failed_start;
+
+  /**
+   * Number of peers that failed to stop
+   */
+  unsigned int num_failed_stop;
+};
+
 struct RestartContext
 {
   /**
@@ -1208,7 +1244,19 @@
   return GNUNET_YES;
 }
 
+struct BlacklistContext
+{
+  /*
+   * The (open) file handle to write to
+   */
+  FILE *temp_file_handle;
 
+  /*
+   * The transport that this peer will be blacklisted on.
+   */
+  char *transport;
+};
+
 /**
  * Iterator for writing blacklist data to appropriate files.
  *
@@ -1223,14 +1271,15 @@
                          const GNUNET_HashCode * key,
                          void *value)
 {
-  FILE *temp_blacklist_handle = cls;
+  struct BlacklistContext *blacklist_ctx = cls;
+  //FILE *temp_blacklist_handle = cls;
   struct GNUNET_TESTING_Daemon *peer = value;
   struct GNUNET_PeerIdentity *temppeer;
   struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc;
 
   temppeer = &peer->id;
   GNUNET_CRYPTO_hash_to_enc(&temppeer->hashPubKey, &peer_enc);
-  fprintf(temp_blacklist_handle, "tcp:%s\n", (char *)&peer_enc);
+  fprintf(blacklist_ctx->temp_file_handle, "%s:%s\n", 
blacklist_ctx->transport, (char *)&peer_enc);
 
   return GNUNET_YES;
 }
@@ -1364,11 +1413,13 @@
  * to the appropriate place.
  *
  * @param pg the peer group we are dealing with
+ * @param transports space delimited list of transports to blacklist
  */
 static int
-create_and_copy_blacklist_files (struct GNUNET_TESTING_PeerGroup *pg)
+create_and_copy_blacklist_files (struct GNUNET_TESTING_PeerGroup *pg, char 
*transports)
 {
-  FILE *temp_friend_handle;
+  FILE *temp_file_handle;
+  static struct BlacklistContext blacklist_ctx;
   unsigned int pg_iter;
   char *temp_service_path;
   pid_t *pidarr;
@@ -1379,17 +1430,43 @@
   int count;
   int ret;
   int max_wait = 10;
+  int transport_len;
+  unsigned int i;
+  char *pos;
+  char *temp_transports;
 
   pidarr = GNUNET_malloc(sizeof(pid_t) * pg->total);
   for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
     {
       mytemp = GNUNET_DISK_mktemp("blacklist");
       GNUNET_assert(mytemp != NULL);
-      temp_friend_handle = fopen (mytemp, "wt");
-      GNUNET_assert(temp_friend_handle != NULL);
-      
GNUNET_CONTAINER_multihashmap_iterate(pg->peers[pg_iter].blacklisted_peers, 
&blacklist_file_iterator, temp_friend_handle);
-      fclose(temp_friend_handle);
+      temp_file_handle = fopen (mytemp, "wt");
+      GNUNET_assert(temp_file_handle != NULL);
+      temp_transports = GNUNET_strdup(transports);
+      blacklist_ctx.temp_file_handle = temp_file_handle;
+      transport_len = strlen(temp_transports) + 1;
+      pos = NULL;
 
+      for (i = 0; i < transport_len; i++)
+      {
+        if ((temp_transports[i] == ' ') && (pos == NULL))
+          continue; /* At start of string (whitespace) */
+        else if ((temp_transports[i] == ' ') || (temp_transports[i] == '\0')) 
/* At end of string */
+        {
+          temp_transports[i] = '\0';
+          blacklist_ctx.transport = pos;
+          
GNUNET_CONTAINER_multihashmap_iterate(pg->peers[pg_iter].blacklisted_peers, 
&blacklist_file_iterator, &blacklist_ctx);
+          pos = NULL;
+        } /* At beginning of actual string */
+        else if (pos == NULL)
+        {
+          pos = &temp_transports[i];
+        }
+      }
+
+      GNUNET_free_non_null(temp_transports);
+      fclose(temp_file_handle);
+
       if (GNUNET_OK !=
           
GNUNET_CONFIGURATION_get_value_string(pg->peers[pg_iter].daemon->cfg, "PATHS", 
"SERVICEHOME", &temp_service_path))
         {
@@ -1669,6 +1746,8 @@
  * @param topology which topology to connect the peers in
  * @param restrict_topology allow only direct TCP connections in this topology
  *                          use GNUNET_TESTING_TOPOLOGY_NONE for no 
restrictions
+ * @param restrict_transports space delimited list of transports to blacklist
+ *                            to create restricted topology
  *
  * @return the maximum number of connections were all allowed peers
  *         connected to each other
@@ -1676,7 +1755,8 @@
 int
 GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg,
                                 enum GNUNET_TESTING_Topology topology,
-                                enum GNUNET_TESTING_Topology restrict_topology)
+                                enum GNUNET_TESTING_Topology restrict_topology,
+                                char *restrict_transports)
 {
   int ret;
   int num_connections;
@@ -1847,9 +1927,9 @@
       break;
     }
 
-  if (unblacklisted_connections > 0)
+  if ((unblacklisted_connections > 0) && (restrict_transports != NULL))
   {
-    ret = create_and_copy_blacklist_files(pg);
+    ret = create_and_copy_blacklist_files(pg, restrict_transports);
     if (ret != GNUNET_OK)
       {
 #if VERBOSE_TESTING
@@ -2606,12 +2686,55 @@
 
 }
 
+/**
+ * Callback for informing us about a successful
+ * or unsuccessful churn stop call.
+ *
+ * @param cls a ChurnContext
+ * @param emsg NULL on success, non-NULL on failure
+ *
+ */
 void
 churn_stop_callback (void *cls, const char *emsg)
 {
+  struct ChurnContext *churn_ctx = cls;
+  unsigned int total_left;
+  char *error_message;
 
+  error_message = NULL;
+  if (emsg != NULL)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Churn stop callback failed with 
error `%s'\n", emsg);
+    churn_ctx->num_failed_stop++;
+  }
+  else
+  {
+    churn_ctx->num_to_stop--;
+  }
+
+  total_left = (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + 
(churn_ctx->num_to_start - churn_ctx->num_failed_start);
+
+  if (total_left == 0)
+  {
+    if ((churn_ctx->num_failed_stop > 0) || (churn_ctx->num_failed_start > 0))
+      GNUNET_asprintf(&error_message, "Churn didn't complete successfully, %u 
peers failed to start %u peers failed to be stopped!", 
churn_ctx->num_failed_start, churn_ctx->num_failed_stop);
+    churn_ctx->cb(churn_ctx->cb_cls, error_message);
+    GNUNET_free_non_null(error_message);
+    GNUNET_free(churn_ctx);
+  }
 }
 
+/**
+ * Callback for informing us about a successful
+ * or unsuccessful churn start call.
+ *
+ * @param cls a ChurnContext
+ * @param id the peer identity of the started peer
+ * @param cfg the handle to the configuration of the peer
+ * @param d handle to the daemon for the peer
+ * @param emsg NULL on success, non-NULL on failure
+ *
+ */
 void
 churn_start_callback (void *cls,
                       const struct GNUNET_PeerIdentity *id,
@@ -2619,17 +2742,34 @@
                       struct GNUNET_TESTING_Daemon *d,
                       const char *emsg)
 {
+  struct ChurnContext *churn_ctx = cls;
+  unsigned int total_left;
+  char *error_message;
 
-}
+  error_message = NULL;
+  if (emsg != NULL)
+  {
+    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Churn stop callback failed with 
error `%s'\n", emsg);
+    churn_ctx->num_failed_start++;
+  }
+  else
+  {
+    churn_ctx->num_to_start--;
+  }
 
-/**
- * Context for handling churning a peer group
- */
-struct ChurnContext
-{
+  total_left = (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + 
(churn_ctx->num_to_start - churn_ctx->num_failed_start);
 
-};
+  if (total_left == 0)
+  {
+    if ((churn_ctx->num_failed_stop > 0) || (churn_ctx->num_failed_start > 0))
+      GNUNET_asprintf(&error_message, "Churn didn't complete successfully, %u 
peers failed to start %u peers failed to be stopped!", 
churn_ctx->num_failed_start, churn_ctx->num_failed_stop);
+    churn_ctx->cb(churn_ctx->cb_cls, error_message);
+    GNUNET_free_non_null(error_message);
+    GNUNET_free(churn_ctx);
+  }
 
+}
+
 /**
  * Simulate churn by stopping some peers (and possibly
  * re-starting others if churn is called multiple times).  This
@@ -2638,9 +2778,7 @@
  * online will be taken offline; then "von" random peers that are then
  * offline will be put back online.  No notifications will be
  * generated for any of these operations except for the callback upon
- * completion.  Note that the implementation is at liberty to keep
- * the ARM service itself (but none of the other services or daemons)
- * running even though the "peer" is being varied offline.
+ * completion.
  *
  * @param pg handle for the peer group
  * @param voff number of peers that should go offline
@@ -2707,6 +2845,11 @@
   running = 0;
   stopped = 0;
 
+  churn_ctx->num_to_start = von;
+  churn_ctx->num_to_stop = voff;
+  churn_ctx->cb = cb;
+  churn_ctx->cb_cls = cb_cls;  
+
   for (i = 0; i < pg->total; i++)
   {
     if (pg->peers[i].daemon->running == GNUNET_YES)
@@ -2730,7 +2873,6 @@
   {
     
GNUNET_TESTING_daemon_start_stopped(pg->peers[stopped_arr[stopped_permute[i]]].daemon,
 timeout, &churn_start_callback, churn_ctx);
   }
-
 }
 
 




reply via email to

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