api for controlled churn
authorChristian Grothoff <christian@grothoff.org>
Thu, 27 May 2010 10:43:18 +0000 (10:43 +0000)
committerChristian Grothoff <christian@grothoff.org>
Thu, 27 May 2010 10:43:18 +0000 (10:43 +0000)
src/include/gnunet_testing_lib.h
src/testing/testing.c
src/testing/testing_group.c

index d3ede33e8777f1e9dae2576c3662538d28cb1454..9fd43c8ff4e8d0ce5d981a0913901e66f832b41d 100644 (file)
@@ -546,10 +546,11 @@ GNUNET_TESTING_daemons_restart (struct GNUNET_TESTING_PeerGroup *pg,
  *
  * @param pg handle to the peer group
  * @param timeout how long to wait for shutdown
- *
  */
 void
-GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg, struct GNUNET_TIME_Relative timeout);
+GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg, 
+                            struct GNUNET_TIME_Relative timeout);
+
 
 /**
  * Simulate churn by stopping some peers (and possibly
@@ -714,6 +715,25 @@ GNUNET_TESTING_connect_topology (struct GNUNET_TESTING_PeerGroup *pg,
                                  enum GNUNET_TESTING_TopologyOption options,
                                  double option_modifier);
 
+/**
+ * Start or stop an individual peer from the given group.
+ *
+ * @param pg handle to the peer group
+ * @param offset which peer to start or stop
+ * @param desired_status GNUNET_YES to have it running, GNUNET_NO to stop it
+ * @param timeout how long to wait for shutdown
+ * @param cb function to call at the end
+ * @param cb_cls closure for cb
+ */
+void
+GNUNET_TESTING_daemons_vary (struct GNUNET_TESTING_PeerGroup *pg, 
+                            unsigned int offset,
+                            int desired_status,
+                            struct GNUNET_TIME_Relative timeout,
+                            GNUNET_TESTING_NotifyCompletion cb,
+                            void *cb_cls);
+
+
 /**
  * Start "count" GNUnet daemons with a particular topology.
  *
index adcc06193284c9442093d0986bf433132abdd445..0c650d313902668c2953c8decf0d7f63849d6a54 100644 (file)
@@ -922,7 +922,8 @@ void
 GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d,
                             struct GNUNET_TIME_Relative timeout,
                             GNUNET_TESTING_NotifyCompletion cb, void *cb_cls,
-                            int delete_files, int allow_restart)
+                            int delete_files,
+                           int allow_restart)
 {
   char *arg;
   char *del_arg;
@@ -960,13 +961,10 @@ GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               _("Terminating peer `%4s'\n"), GNUNET_i2s (&d->id));
 #endif
-
   d->phase = SP_SHUTDOWN_START;
   d->running = GNUNET_NO;
-
   if (allow_restart == GNUNET_YES)
     d->churn = GNUNET_YES;
-
   if (d->th != NULL)
     {
       GNUNET_TRANSPORT_get_hello_cancel(d->th, &process_hello, d);
@@ -993,7 +991,6 @@ GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d,
 #endif
                                         "-c", d->cfgfile, "-e", "-q", del_arg, NULL);
       /* Use -e to end arm, and -d to remove temp files */
-
       GNUNET_free (arg);
     }
   else
index d878ec1041235dc6519959c5b3f0d677a3c393fc..bf90ea4b0b9e66dc8c9acc5990a8aeb7f2adc69b 100644 (file)
@@ -2698,17 +2698,20 @@ churn_stop_callback (void *cls, const char *emsg)
 
   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++;
-  }
+    {
+      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--;
-  }
+    {
+      churn_ctx->num_to_stop--;
+    }
 
 #if DEBUG_CHURN
-    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Stopped peer, %d left.\n", churn_ctx->num_to_stop);
+  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 
+            "Stopped peer, %d left.\n", 
+            churn_ctx->num_to_stop);
 #endif
   total_left = (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + (churn_ctx->num_to_start - churn_ctx->num_failed_start);
 
@@ -2716,7 +2719,10 @@ churn_stop_callback (void *cls, const char *emsg)
   {
     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);
+        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);
@@ -2748,17 +2754,21 @@ churn_start_callback (void *cls,
 
   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++;
-  }
+    {
+      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--;
-  }
-
+    {
+      churn_ctx->num_to_start--;
+    }
+  
 #if DEBUG_CHURN
-    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Started peer, %d left.\n", churn_ctx->num_to_start);
+  GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
+            "Started peer, %d left.\n", 
+            churn_ctx->num_to_start);
 #endif
 
   total_left = (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + (churn_ctx->num_to_start - churn_ctx->num_failed_start);
@@ -2766,14 +2776,17 @@ churn_start_callback (void *cls,
   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);
+      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
@@ -2885,15 +2898,19 @@ GNUNET_TESTING_daemons_churn (struct GNUNET_TESTING_PeerGroup *pg,
 #if DEBUG_CHURN
     GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Stopping peer %d!\n", running_permute[i]);
 #endif
-    GNUNET_TESTING_daemon_stop(pg->peers[running_arr[running_permute[i]]].daemon, timeout, &churn_stop_callback, churn_ctx, GNUNET_NO, GNUNET_YES);
+    GNUNET_TESTING_daemon_stop (pg->peers[running_arr[running_permute[i]]].daemon,
+                               timeout, 
+                               &churn_stop_callback, churn_ctx, 
+                               GNUNET_NO, GNUNET_YES);
   }
 
   for (i = 0; i < von; i++)
-  {
+    {
 #if DEBUG_CHURN
-    GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Starting up peer %d!\n", stopped_permute[i]);
+      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Starting up peer %d!\n", stopped_permute[i]);
 #endif
-    GNUNET_TESTING_daemon_start_stopped(pg->peers[stopped_arr[stopped_permute[i]]].daemon, timeout, &churn_start_callback, churn_ctx);
+      GNUNET_TESTING_daemon_start_stopped(pg->peers[stopped_arr[stopped_permute[i]]].daemon, 
+                                         timeout, &churn_start_callback, churn_ctx);
   }
 
   GNUNET_free(running_arr);
@@ -2932,36 +2949,85 @@ GNUNET_TESTING_daemons_restart (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TEST
 }
 
 /**
- * Shutdown all peers started in the given group.
+ * Start or stop an individual peer from the given group.
  *
  * @param pg handle to the peer group
+ * @param offset which peer to start or stop
+ * @param desired_status GNUNET_YES to have it running, GNUNET_NO to stop it
  * @param timeout how long to wait for shutdown
+ * @param cb function to call at the end
+ * @param cb_cls closure for cb
+ */
+void
+GNUNET_TESTING_daemons_vary (struct GNUNET_TESTING_PeerGroup *pg, 
+                            unsigned int offset,
+                            int desired_status,
+                            struct GNUNET_TIME_Relative timeout,
+                            GNUNET_TESTING_NotifyCompletion cb,
+                            void *cb_cls)
+{
+  struct ChurnContext *churn_ctx;
+
+  if (GNUNET_NO == desired_status)
+    {
+      if (NULL != pg->peers[offset].daemon)
+       {
+         churn_ctx = GNUNET_malloc(sizeof(struct ChurnContext));
+         churn_ctx->num_to_start = 0;
+         churn_ctx->num_to_stop = 1;
+         churn_ctx->cb = cb;
+         churn_ctx->cb_cls = cb_cls;  
+         GNUNET_TESTING_daemon_stop(pg->peers[offset].daemon, 
+                                    timeout, &churn_stop_callback, churn_ctx, 
+                                    GNUNET_NO, GNUNET_YES);     
+       }
+    }
+  else if (GNUNET_YES == desired_status)
+    {
+      if (NULL == pg->peers[offset].daemon)
+       {
+         churn_ctx = GNUNET_malloc(sizeof(struct ChurnContext));
+         churn_ctx->num_to_start = 1;
+         churn_ctx->num_to_stop = 0;
+         churn_ctx->cb = cb;
+         churn_ctx->cb_cls = cb_cls;  
+         GNUNET_TESTING_daemon_start_stopped(pg->peers[offset].daemon, 
+                                             timeout, &churn_start_callback, churn_ctx);
+       }
+    }
+  else
+    GNUNET_break (0);
+}
+
+
+/**
+ * Shutdown all peers started in the given group.
  *
+ * @param pg handle to the peer group
+ * @param timeout how long to wait for shutdown
  */
 void
-GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg, struct GNUNET_TIME_Relative timeout)
+GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg, 
+                            struct GNUNET_TIME_Relative timeout)
 {
   unsigned int off;
 
   for (off = 0; off < pg->total; off++)
     {
-      /* FIXME: should we wait for our
-         continuations to be called here? This
-         would require us to take a continuation
-         as well... */
+      /* FIXME: should we wait for our continuations to be called
+         here? This would require us to take a continuation as
+         well... */
 
       if (NULL != pg->peers[off].daemon)
         GNUNET_TESTING_daemon_stop (pg->peers[off].daemon, timeout, NULL, NULL, GNUNET_YES, GNUNET_NO);
       if (NULL != pg->peers[off].cfg)
         GNUNET_CONFIGURATION_destroy (pg->peers[off].cfg);
-
       if (pg->peers[off].allowed_peers != NULL)
         GNUNET_CONTAINER_multihashmap_destroy(pg->peers[off].allowed_peers);
       if (pg->peers[off].connect_peers != NULL)
         GNUNET_CONTAINER_multihashmap_destroy(pg->peers[off].connect_peers);
       if (pg->peers[off].blacklisted_peers != NULL)
         GNUNET_CONTAINER_multihashmap_destroy(pg->peers[off].blacklisted_peers);
-
     }
   GNUNET_free (pg->peers);
   if (NULL != pg->hosts)