aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2011-07-25 14:27:33 +0000
committerNathan S. Evans <evans@in.tum.de>2011-07-25 14:27:33 +0000
commit08f1114108442793fb00dc443ed6b94b81c3b443 (patch)
treeec282bc9ef6963f2a9d6ff21e5b9f3db395bbd8a /src
parent91d1bc4750c36d7f3e996f483fe4bee7c242eb45 (diff)
downloadgnunet-08f1114108442793fb00dc443ed6b94b81c3b443.tar.gz
gnunet-08f1114108442793fb00dc443ed6b94b81c3b443.zip
churn a service
Diffstat (limited to 'src')
-rw-r--r--src/dht/gnunet-dht-driver.c2
-rw-r--r--src/include/gnunet_testing_lib.h55
-rw-r--r--src/nse/nse-profiler.c2
-rw-r--r--src/testing/test_testing_topology_churn.c8
-rw-r--r--src/testing/testing.c262
-rw-r--r--src/testing/testing_group.c116
6 files changed, 412 insertions, 33 deletions
diff --git a/src/dht/gnunet-dht-driver.c b/src/dht/gnunet-dht-driver.c
index 882a77b65..7c602cfca 100644
--- a/src/dht/gnunet-dht-driver.c
+++ b/src/dht/gnunet-dht-driver.c
@@ -1901,7 +1901,7 @@ churn_peers(void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
1901 "churn_peers: want %u total, %u running, starting %u, stopping %u\n", 1901 "churn_peers: want %u total, %u running, starting %u, stopping %u\n",
1902 churn_array[current_churn_round], count_running, churn_up, 1902 churn_array[current_churn_round], count_running, churn_up,
1903 churn_down); 1903 churn_down);
1904 GNUNET_TESTING_daemons_churn (pg, churn_down, churn_up, timeout, 1904 GNUNET_TESTING_daemons_churn (pg, NULL, churn_down, churn_up, timeout,
1905 &churn_complete, find_peer_context); 1905 &churn_complete, find_peer_context);
1906 current_churn_round++; 1906 current_churn_round++;
1907} 1907}
diff --git a/src/include/gnunet_testing_lib.h b/src/include/gnunet_testing_lib.h
index 60b0256a0..34920bbab 100644
--- a/src/include/gnunet_testing_lib.h
+++ b/src/include/gnunet_testing_lib.h
@@ -176,6 +176,18 @@ enum GNUNET_TESTING_StartPhase
176 SP_SHUTDOWN_START, 176 SP_SHUTDOWN_START,
177 177
178 /** 178 /**
179 * We should shutdown a *single* service via gnunet-arm. Call the dead_cb
180 * upon notification from gnunet-arm that the service has been stopped.
181 */
182 SP_SERVICE_SHUTDOWN_START,
183
184 /**
185 * We should start a *single* service via gnunet-arm. Call the daemon cb
186 * upon notification from gnunet-arm that the service has been started.
187 */
188 SP_SERVICE_START,
189
190 /**
179 * We've received a configuration update and are currently waiting for 191 * We've received a configuration update and are currently waiting for
180 * the copy process for the update to complete. Once it is, we will 192 * the copy process for the update to complete. Once it is, we will
181 * return to "SP_START_DONE" (and rely on ARM to restart all affected 193 * return to "SP_START_DONE" (and rely on ARM to restart all affected
@@ -362,6 +374,14 @@ struct GNUNET_TESTING_Daemon
362 * (if it's going to be restarted later) 374 * (if it's going to be restarted later)
363 */ 375 */
364 int churn; 376 int churn;
377
378 /**
379 * Currently, a single char * pointing to a service
380 * that has been churned off.
381 *
382 * FIXME: make this a linked list of services that have been churned off!!!
383 */
384 char *churned_services;
365}; 385};
366 386
367 387
@@ -494,6 +514,21 @@ GNUNET_TESTING_daemon_start_stopped (struct GNUNET_TESTING_Daemon *daemon,
494 void *cb_cls); 514 void *cb_cls);
495 515
496/** 516/**
517 * Stops a GNUnet daemon.
518 *
519 * @param d the daemon for which the service should be started
520 * @param service the name of the service to start
521 * @param timeout how long to wait for process for shutdown to complete
522 * @param cb function called once the daemon was stopped
523 * @param cb_cls closure for cb
524 */
525void
526GNUNET_TESTING_daemon_start_stopped_service (struct GNUNET_TESTING_Daemon *d,
527 char *service,
528 struct GNUNET_TIME_Relative timeout,
529 GNUNET_TESTING_NotifyDaemonRunning cb, void *cb_cls);
530
531/**
497 * Get a certain testing daemon handle. 532 * Get a certain testing daemon handle.
498 * 533 *
499 * @param pg handle to the set of running peers 534 * @param pg handle to the set of running peers
@@ -549,6 +584,24 @@ void GNUNET_TESTING_daemon_reconfigure (struct GNUNET_TESTING_Daemon *d,
549 GNUNET_TESTING_NotifyCompletion cb, 584 GNUNET_TESTING_NotifyCompletion cb,
550 void * cb_cls); 585 void * cb_cls);
551 586
587/**
588 * Stops a single service of a GNUnet daemon. Used like daemon_stop,
589 * only doesn't stop the entire peer in any case. If the service
590 * is not currently running, this call is likely to fail after
591 * timeout!
592 *
593 * @param d the daemon that should be stopped
594 * @param service the name of the service to stop
595 * @param timeout how long to wait for process for shutdown to complete
596 * @param cb function called once the service was stopped
597 * @param cb_cls closure for cb
598 */
599void
600GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d,
601 char *service,
602 struct GNUNET_TIME_Relative timeout,
603 GNUNET_TESTING_NotifyCompletion cb, void *cb_cls);
604
552 605
553/** 606/**
554 * Establish a connection between two GNUnet daemons. 607 * Establish a connection between two GNUnet daemons.
@@ -677,6 +730,7 @@ GNUNET_TESTING_daemons_running (struct GNUNET_TESTING_PeerGroup *pg);
677 * running even though the "peer" is being varied offline. 730 * running even though the "peer" is being varied offline.
678 * 731 *
679 * @param pg handle for the peer group 732 * @param pg handle for the peer group
733 * @param service the service to churn on/off, NULL for all
680 * @param voff number of peers that should go offline 734 * @param voff number of peers that should go offline
681 * @param von number of peers that should come back online; 735 * @param von number of peers that should come back online;
682 * must be zero on first call (since "testbed_start" 736 * must be zero on first call (since "testbed_start"
@@ -688,6 +742,7 @@ GNUNET_TESTING_daemons_running (struct GNUNET_TESTING_PeerGroup *pg);
688 */ 742 */
689void 743void
690GNUNET_TESTING_daemons_churn (struct GNUNET_TESTING_PeerGroup *pg, 744GNUNET_TESTING_daemons_churn (struct GNUNET_TESTING_PeerGroup *pg,
745 char *service,
691 unsigned int voff, 746 unsigned int voff,
692 unsigned int von, 747 unsigned int von,
693 struct GNUNET_TIME_Relative timeout, 748 struct GNUNET_TIME_Relative timeout,
diff --git a/src/nse/nse-profiler.c b/src/nse/nse-profiler.c
index 498f058d2..538cd1f50 100644
--- a/src/nse/nse-profiler.c
+++ b/src/nse/nse-profiler.c
@@ -496,7 +496,7 @@ churn_peers (void *cls,
496 - peers_next_round : 0, 496 - peers_next_round : 0,
497 (peers_next_round > peers_running) ? peers_next_round 497 (peers_next_round > peers_running) ? peers_next_round
498 - peers_running : 0); 498 - peers_running : 0);
499 GNUNET_TESTING_daemons_churn (pg, 499 GNUNET_TESTING_daemons_churn (pg, "nse",
500 (peers_running > peers_next_round) ? peers_running 500 (peers_running > peers_next_round) ? peers_running
501 - peers_next_round 501 - peers_next_round
502 : 0, 502 : 0,
diff --git a/src/testing/test_testing_topology_churn.c b/src/testing/test_testing_topology_churn.c
index f1d93fa46..b92288199 100644
--- a/src/testing/test_testing_topology_churn.c
+++ b/src/testing/test_testing_topology_churn.c
@@ -173,28 +173,28 @@ static void
173churn_peers_both () 173churn_peers_both ()
174{ 174{
175 churn_ctx.next_task = &finish_testing; 175 churn_ctx.next_task = &finish_testing;
176 GNUNET_TESTING_daemons_churn (pg, 1, 1, TIMEOUT, &churn_callback, NULL); 176 GNUNET_TESTING_daemons_churn (pg, NULL, 1, 1, TIMEOUT, &churn_callback, NULL);
177} 177}
178 178
179static void 179static void
180churn_peers_off_again () 180churn_peers_off_again ()
181{ 181{
182 churn_ctx.next_task = &churn_peers_both; 182 churn_ctx.next_task = &churn_peers_both;
183 GNUNET_TESTING_daemons_churn (pg, 2, 0, TIMEOUT, &churn_callback, NULL); 183 GNUNET_TESTING_daemons_churn (pg, NULL, 2, 0, TIMEOUT, &churn_callback, NULL);
184} 184}
185 185
186static void 186static void
187churn_peers_on () 187churn_peers_on ()
188{ 188{
189 churn_ctx.next_task = &churn_peers_off_again; 189 churn_ctx.next_task = &churn_peers_off_again;
190 GNUNET_TESTING_daemons_churn (pg, 0, 2, TIMEOUT, &churn_callback, NULL); 190 GNUNET_TESTING_daemons_churn (pg, NULL, 0, 2, TIMEOUT, &churn_callback, NULL);
191} 191}
192 192
193static void 193static void
194churn_peers_off () 194churn_peers_off ()
195{ 195{
196 churn_ctx.next_task = &churn_peers_on; 196 churn_ctx.next_task = &churn_peers_on;
197 GNUNET_TESTING_daemons_churn (pg, 2, 0, TIMEOUT, &churn_callback, NULL); 197 GNUNET_TESTING_daemons_churn (pg, NULL, 2, 0, TIMEOUT, &churn_callback, NULL);
198} 198}
199 199
200static void 200static void
diff --git a/src/testing/testing.c b/src/testing/testing.c
index b9f0fb538..c35500c35 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -784,6 +784,87 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
784 case SP_START_DONE: 784 case SP_START_DONE:
785 GNUNET_break (0); 785 GNUNET_break (0);
786 break; 786 break;
787 case SP_SERVICE_START:
788 /* confirm gnunet-arm exited */
789 if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
790 {
791 if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value ==
792 0)
793 {
794 cb = d->cb;
795 d->cb = NULL;
796 if (NULL != cb)
797 cb (d->cb_cls,
798 NULL,
799 d->cfg,
800 d,
801 (NULL == d->hostname)
802 ? _("`gnunet-arm' does not seem to terminate.\n")
803 : _("`ssh' does not seem to terminate.\n"));
804 return;
805 }
806 /* wait some more */
807 d->task
808 = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT,
809 &start_fsm, d);
810 return;
811 }
812 if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0))
813 {
814 cb = d->cb;
815 d->cb = NULL;
816 if (NULL != cb)
817 cb (d->cb_cls,
818 NULL,
819 d->cfg,
820 d,
821 (NULL == d->hostname)
822 ? _("`gnunet-arm' does not seem to terminate.\n")
823 : _("`ssh' does not seem to terminate.\n"));
824 return;
825 }
826#if DEBUG_TESTING
827 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service startup complete!\n");
828#endif
829 cb = d->cb;
830 d->cb = NULL;
831 d->phase = SP_START_DONE;
832 if (NULL != cb)
833 cb (d->cb_cls, &d->id, d->cfg, d, NULL);
834 break;
835 case SP_SERVICE_SHUTDOWN_START:
836 /* confirm copying complete */
837 if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
838 {
839 if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value ==
840 0)
841 {
842 if (NULL != d->dead_cb)
843 d->dead_cb (d->dead_cb_cls,
844 _
845 ("either `gnunet-arm' or `ssh' does not seem to terminate.\n"));
846 return;
847 }
848 /* wait some more */
849 d->task
850 = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT,
851 &start_fsm, d);
852 return;
853 }
854 if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0))
855 {
856 if (NULL != d->dead_cb)
857 d->dead_cb (d->dead_cb_cls,
858 _
859 ("shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n"));
860 return;
861 }
862#if DEBUG_TESTING
863 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n");
864#endif
865 if (NULL != d->dead_cb)
866 d->dead_cb (d->dead_cb_cls, NULL);
867 break;
787 case SP_SHUTDOWN_START: 868 case SP_SHUTDOWN_START:
788 /* confirm copying complete */ 869 /* confirm copying complete */
789 if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code)) 870 if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
@@ -958,6 +1039,94 @@ GNUNET_TESTING_daemon_running (struct GNUNET_TESTING_Daemon *daemon)
958 1039
959 1040
960/** 1041/**
1042 * Stops a GNUnet daemon.
1043 *
1044 * @param d the daemon for which the service should be started
1045 * @param service the name of the service to start
1046 * @param timeout how long to wait for process for shutdown to complete
1047 * @param cb function called once the daemon was stopped
1048 * @param cb_cls closure for cb
1049 */
1050void
1051GNUNET_TESTING_daemon_start_stopped_service (struct GNUNET_TESTING_Daemon *d,
1052 char *service,
1053 struct GNUNET_TIME_Relative timeout,
1054 GNUNET_TESTING_NotifyDaemonRunning cb, void *cb_cls)
1055{
1056 char *arg;
1057 d->cb = cb;
1058 d->cb_cls = cb_cls;
1059
1060 GNUNET_assert(d->running == GNUNET_YES);
1061
1062 if (d->phase == SP_CONFIG_UPDATE)
1063 {
1064 GNUNET_SCHEDULER_cancel (d->task);
1065 d->phase = SP_START_DONE;
1066 }
1067
1068#if DEBUG_TESTING
1069 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1070 _("Terminating peer `%4s'\n"), GNUNET_i2s (&d->id));
1071#endif
1072 if (d->churned_services == NULL)
1073 {
1074 d->dead_cb(d->dead_cb_cls, "No service has been churned off yet!!");
1075 return;
1076 }
1077 d->phase = SP_SERVICE_START;
1078 GNUNET_free(d->churned_services);
1079
1080 /* Check if this is a local or remote process */
1081 if (NULL != d->hostname)
1082 {
1083#if DEBUG_TESTING
1084 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1085 "Starting gnunet-arm with config `%s' on host `%s'.\n",
1086 d->cfgfile, d->hostname);
1087#endif
1088
1089 if (d->username != NULL)
1090 GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname);
1091 else
1092 arg = GNUNET_strdup (d->hostname);
1093
1094 d->proc = GNUNET_OS_start_process (NULL, NULL, "ssh", "ssh",
1095#if !DEBUG_TESTING
1096 "-q",
1097#endif
1098 arg, "gnunet-arm",
1099#if DEBUG_TESTING
1100 "-L", "DEBUG",
1101#endif
1102 "-c", d->cfgfile, "-i", service, "-q",
1103 NULL);
1104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1105 "Starting gnunet-arm with command ssh %s gnunet-arm -c %s -i %s -q\n",
1106 arg, "gnunet-arm", d->cfgfile, service);
1107 GNUNET_free (arg);
1108 }
1109 else
1110 {
1111#if DEBUG_TESTING
1112 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1113 "Starting gnunet-arm with config `%s' locally.\n",
1114 d->cfgfile);
1115#endif
1116 d->proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
1117 "gnunet-arm",
1118#if DEBUG_TESTING
1119 "-L", "DEBUG",
1120#endif
1121 "-c", d->cfgfile, "-i", service, "-q",
1122 NULL);
1123 }
1124
1125 d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1126 d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d);
1127}
1128
1129/**
961 * Start a peer that has previously been stopped using the daemon_stop 1130 * Start a peer that has previously been stopped using the daemon_stop
962 * call (and files weren't deleted and the allow restart flag) 1131 * call (and files weren't deleted and the allow restart flag)
963 * 1132 *
@@ -1333,6 +1502,99 @@ GNUNET_TESTING_daemon_restart (struct GNUNET_TESTING_Daemon *d,
1333 * Stops a GNUnet daemon. 1502 * Stops a GNUnet daemon.
1334 * 1503 *
1335 * @param d the daemon that should be stopped 1504 * @param d the daemon that should be stopped
1505 * @param service the name of the service to stop
1506 * @param timeout how long to wait for process for shutdown to complete
1507 * @param cb function called once the daemon was stopped
1508 * @param cb_cls closure for cb
1509 * @param delete_files GNUNET_YES to remove files, GNUNET_NO
1510 * to leave them
1511 * @param allow_restart GNUNET_YES to restart peer later (using this API)
1512 * GNUNET_NO to kill off and clean up for good
1513 */
1514void
1515GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d,
1516 char *service,
1517 struct GNUNET_TIME_Relative timeout,
1518 GNUNET_TESTING_NotifyCompletion cb, void *cb_cls)
1519{
1520 char *arg;
1521 d->dead_cb = cb;
1522 d->dead_cb_cls = cb_cls;
1523
1524 GNUNET_assert(d->running == GNUNET_YES);
1525
1526 if (d->phase == SP_CONFIG_UPDATE)
1527 {
1528 GNUNET_SCHEDULER_cancel (d->task);
1529 d->phase = SP_START_DONE;
1530 }
1531
1532#if DEBUG_TESTING
1533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1534 _("Terminating peer `%4s'\n"), GNUNET_i2s (&d->id));
1535#endif
1536 if (d->churned_services != NULL)
1537 {
1538 d->dead_cb(d->dead_cb_cls, "A service has already been turned off!!");
1539 return;
1540 }
1541 d->phase = SP_SERVICE_SHUTDOWN_START;
1542 d->churned_services = GNUNET_strdup(service);
1543
1544 /* Check if this is a local or remote process */
1545 if (NULL != d->hostname)
1546 {
1547#if DEBUG_TESTING
1548 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1549 "Stopping gnunet-arm with config `%s' on host `%s'.\n",
1550 d->cfgfile, d->hostname);
1551#endif
1552
1553 if (d->username != NULL)
1554 GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname);
1555 else
1556 arg = GNUNET_strdup (d->hostname);
1557
1558 d->proc = GNUNET_OS_start_process (NULL, NULL, "ssh", "ssh",
1559#if !DEBUG_TESTING
1560 "-q",
1561#endif
1562 arg, "gnunet-arm",
1563#if DEBUG_TESTING
1564 "-L", "DEBUG",
1565#endif
1566 "-c", d->cfgfile, "-k", service, "-q",
1567 NULL);
1568 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1569 "Stopping gnunet-arm with command ssh %s gnunet-arm -c %s -k %s -q\n",
1570 arg, "gnunet-arm", d->cfgfile, service);
1571 GNUNET_free (arg);
1572 }
1573 else
1574 {
1575#if DEBUG_TESTING
1576 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1577 "Stopping gnunet-arm with config `%s' locally.\n",
1578 d->cfgfile);
1579#endif
1580 d->proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
1581 "gnunet-arm",
1582#if DEBUG_TESTING
1583 "-L", "DEBUG",
1584#endif
1585 "-c", d->cfgfile, "-k", service, "-q",
1586 NULL);
1587 }
1588
1589 d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1590 d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d);
1591}
1592
1593
1594/**
1595 * Stops a GNUnet daemon.
1596 *
1597 * @param d the daemon that should be stopped
1336 * @param timeout how long to wait for process for shutdown to complete 1598 * @param timeout how long to wait for process for shutdown to complete
1337 * @param cb function called once the daemon was stopped 1599 * @param cb function called once the daemon was stopped
1338 * @param cb_cls closure for cb 1600 * @param cb_cls closure for cb
diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c
index e7be22a8a..b9ccf69f2 100644
--- a/src/testing/testing_group.c
+++ b/src/testing/testing_group.c
@@ -103,6 +103,12 @@ struct ChurnContext
103 struct GNUNET_TESTING_PeerGroup *pg; 103 struct GNUNET_TESTING_PeerGroup *pg;
104 104
105 /** 105 /**
106 * Name of the service to churn on/off, NULL
107 * to churn entire peer.
108 */
109 char *service;
110
111 /**
106 * Callback used to notify of churning finished 112 * Callback used to notify of churning finished
107 */ 113 */
108 GNUNET_TESTING_NotifyCompletion cb; 114 GNUNET_TESTING_NotifyCompletion cb;
@@ -5576,9 +5582,15 @@ schedule_churn_restart(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
5576 &schedule_churn_restart, peer_restart_ctx); 5582 &schedule_churn_restart, peer_restart_ctx);
5577 else 5583 else
5578 { 5584 {
5579 GNUNET_TESTING_daemon_start_stopped (peer_restart_ctx->daemon, 5585 if (startup_ctx->churn_ctx->service != NULL)
5580 startup_ctx->timeout, 5586 GNUNET_TESTING_daemon_start_stopped_service (peer_restart_ctx->daemon,
5581 &churn_start_callback, startup_ctx); 5587 startup_ctx->churn_ctx->service,
5588 startup_ctx->timeout,
5589 &churn_start_callback, startup_ctx);
5590 else
5591 GNUNET_TESTING_daemon_start_stopped (peer_restart_ctx->daemon,
5592 startup_ctx->timeout,
5593 &churn_start_callback, startup_ctx);
5582 GNUNET_free (peer_restart_ctx); 5594 GNUNET_free (peer_restart_ctx);
5583 } 5595 }
5584} 5596}
@@ -6336,9 +6348,15 @@ schedule_churn_shutdown_task(void *cls,
6336 else 6348 else
6337 { 6349 {
6338 shutdown_ctx->outstanding++; 6350 shutdown_ctx->outstanding++;
6339 GNUNET_TESTING_daemon_stop (peer_shutdown_ctx->daemon, 6351 if (churn_ctx->service != NULL)
6340 shutdown_ctx->timeout, shutdown_ctx->cb, 6352 GNUNET_TESTING_daemon_stop_service (peer_shutdown_ctx->daemon,
6341 shutdown_ctx, GNUNET_NO, GNUNET_YES); 6353 churn_ctx->service,
6354 shutdown_ctx->timeout, shutdown_ctx->cb,
6355 shutdown_ctx);
6356 else
6357 GNUNET_TESTING_daemon_stop (peer_shutdown_ctx->daemon,
6358 shutdown_ctx->timeout, shutdown_ctx->cb,
6359 shutdown_ctx, GNUNET_NO, GNUNET_YES);
6342 GNUNET_free (peer_shutdown_ctx); 6360 GNUNET_free (peer_shutdown_ctx);
6343 } 6361 }
6344} 6362}
@@ -6355,6 +6373,7 @@ schedule_churn_shutdown_task(void *cls,
6355 * completion. 6373 * completion.
6356 * 6374 *
6357 * @param pg handle for the peer group 6375 * @param pg handle for the peer group
6376 * @param service the service to churn off/on, NULL to churn peer
6358 * @param voff number of peers that should go offline 6377 * @param voff number of peers that should go offline
6359 * @param von number of peers that should come back online; 6378 * @param von number of peers that should come back online;
6360 * must be zero on first call (since "testbed_start" 6379 * must be zero on first call (since "testbed_start"
@@ -6366,6 +6385,7 @@ schedule_churn_shutdown_task(void *cls,
6366 */ 6385 */
6367void 6386void
6368GNUNET_TESTING_daemons_churn(struct GNUNET_TESTING_PeerGroup *pg, 6387GNUNET_TESTING_daemons_churn(struct GNUNET_TESTING_PeerGroup *pg,
6388 char *service,
6369 unsigned int voff, unsigned int von, 6389 unsigned int voff, unsigned int von,
6370 struct GNUNET_TIME_Relative timeout, 6390 struct GNUNET_TIME_Relative timeout,
6371 GNUNET_TESTING_NotifyCompletion cb, void *cb_cls) 6391 GNUNET_TESTING_NotifyCompletion cb, void *cb_cls)
@@ -6385,6 +6405,7 @@ GNUNET_TESTING_daemons_churn(struct GNUNET_TESTING_PeerGroup *pg,
6385 unsigned int *stopped_arr; 6405 unsigned int *stopped_arr;
6386 unsigned int *running_permute; 6406 unsigned int *running_permute;
6387 unsigned int *stopped_permute; 6407 unsigned int *stopped_permute;
6408 char *pos;
6388 6409
6389 shutdown_ctx = NULL; 6410 shutdown_ctx = NULL;
6390 peer_shutdown_ctx = NULL; 6411 peer_shutdown_ctx = NULL;
@@ -6402,15 +6423,39 @@ GNUNET_TESTING_daemons_churn(struct GNUNET_TESTING_PeerGroup *pg,
6402 6423
6403 for (i = 0; i < pg->total; i++) 6424 for (i = 0; i < pg->total; i++)
6404 { 6425 {
6405 if (pg->peers[i].daemon->running == GNUNET_YES) 6426 if (service == NULL)
6406 { 6427 {
6407 GNUNET_assert (running != -1); 6428 if (pg->peers[i].daemon->running == GNUNET_YES)
6408 running++; 6429 {
6430 GNUNET_assert (running != -1);
6431 running++;
6432 }
6433 else
6434 {
6435 GNUNET_assert (stopped != -1);
6436 stopped++;
6437 }
6409 } 6438 }
6410 else 6439 else
6411 { 6440 {
6412 GNUNET_assert (stopped != -1); 6441 /* FIXME: make churned services a list! */
6413 stopped++; 6442 pos = pg->peers[i].daemon->churned_services;
6443 /* FIXME: while (pos != NULL) */
6444 if (pos != NULL)
6445 {
6446 if (0 == strcasecmp(pos, service))
6447 {
6448 GNUNET_assert (stopped != -1);
6449 stopped++;
6450 break;
6451 }
6452 /* FIXME: pos = pos->next; */
6453 }
6454 if (pos == NULL)
6455 {
6456 GNUNET_assert (running != -1);
6457 running++;
6458 }
6414 } 6459 }
6415 } 6460 }
6416 6461
@@ -6463,17 +6508,43 @@ GNUNET_TESTING_daemons_churn(struct GNUNET_TESTING_PeerGroup *pg,
6463 6508
6464 for (i = 0; i < pg->total; i++) 6509 for (i = 0; i < pg->total; i++)
6465 { 6510 {
6466 if (pg->peers[i].daemon->running == GNUNET_YES) 6511 if (service == NULL)
6467 { 6512 {
6468 GNUNET_assert ((running_arr != NULL) && (total_running > running)); 6513 if (pg->peers[i].daemon->running == GNUNET_YES)
6469 running_arr[running] = i; 6514 {
6470 running++; 6515 GNUNET_assert ((running_arr != NULL) && (total_running > running));
6516 running_arr[running] = i;
6517 running++;
6518 }
6519 else
6520 {
6521 GNUNET_assert ((stopped_arr != NULL) && (total_stopped > stopped));
6522 stopped_arr[stopped] = i;
6523 stopped++;
6524 }
6471 } 6525 }
6472 else 6526 else
6473 { 6527 {
6474 GNUNET_assert ((stopped_arr != NULL) && (total_stopped > stopped)); 6528 /* FIXME: make churned services a list! */
6475 stopped_arr[stopped] = i; 6529 pos = pg->peers[i].daemon->churned_services;
6476 stopped++; 6530 /* FIXME: while (pos != NULL) */
6531 if (pos != NULL)
6532 {
6533 if (0 == strcasecmp(pos, service))
6534 {
6535 GNUNET_assert ((stopped_arr != NULL) && (total_stopped > stopped));
6536 stopped_arr[stopped] = i;
6537 stopped++;
6538 break;
6539 }
6540 /* FIXME: pos = pos->next; */
6541 }
6542 if (pos == NULL)
6543 {
6544 GNUNET_assert ((running_arr != NULL) && (total_running > running));
6545 running_arr[running] = i;
6546 running++;
6547 }
6477 } 6548 }
6478 } 6549 }
6479 6550
@@ -6500,12 +6571,6 @@ GNUNET_TESTING_daemons_churn(struct GNUNET_TESTING_PeerGroup *pg,
6500 peer_shutdown_ctx->shutdown_ctx = shutdown_ctx; 6571 peer_shutdown_ctx->shutdown_ctx = shutdown_ctx;
6501 GNUNET_SCHEDULER_add_now (&schedule_churn_shutdown_task, 6572 GNUNET_SCHEDULER_add_now (&schedule_churn_shutdown_task,
6502 peer_shutdown_ctx); 6573 peer_shutdown_ctx);
6503
6504 /*
6505 GNUNET_TESTING_daemon_stop (pg->peers[running_arr[running_permute[i]]].daemon,
6506 timeout,
6507 &churn_stop_callback, churn_ctx,
6508 GNUNET_NO, GNUNET_YES); */
6509 } 6574 }
6510 6575
6511 GNUNET_assert (stopped >= von); 6576 GNUNET_assert (stopped >= von);
@@ -6528,9 +6593,6 @@ GNUNET_TESTING_daemons_churn(struct GNUNET_TESTING_PeerGroup *pg,
6528 peer_restart_ctx->daemon 6593 peer_restart_ctx->daemon
6529 = pg->peers[stopped_arr[stopped_permute[i]]].daemon; 6594 = pg->peers[stopped_arr[stopped_permute[i]]].daemon;
6530 GNUNET_SCHEDULER_add_now (&schedule_churn_restart, peer_restart_ctx); 6595 GNUNET_SCHEDULER_add_now (&schedule_churn_restart, peer_restart_ctx);
6531 /*
6532 GNUNET_TESTING_daemon_start_stopped(pg->peers[stopped_arr[stopped_permute[i]]].daemon,
6533 timeout, &churn_start_callback, churn_ctx); */
6534 } 6596 }
6535 6597
6536 GNUNET_free_non_null (running_arr); 6598 GNUNET_free_non_null (running_arr);