stuff
[oweals/gnunet.git] / src / arm / test_exponential_backoff.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20 /**
21  * @file arm/test_exponential_backoff.c
22  * @brief testcase for gnunet-service-arm.c
23  */
24 #include "platform.h"
25 #include "gnunet_arm_service.h"
26 #include "gnunet_client_lib.h"
27 #include "gnunet_configuration_lib.h"
28 #include "gnunet_program_lib.h"
29
30 #define VERBOSE GNUNET_NO
31 #define START_ARM GNUNET_YES
32 #define LOG_BACKOFF GNUNET_NO
33 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
34 #define SERVICE_TEST_TIMEOUT GNUNET_TIME_UNIT_FOREVER_REL
35 #define FIVE_MILLISECONDS GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 5)
36
37 static struct GNUNET_SCHEDULER_Handle *sched;
38 static const struct GNUNET_CONFIGURATION_Handle *cfg;
39 static struct GNUNET_ARM_Handle *arm;
40 static int ok = 1;
41
42 static int trialCount;
43 static struct GNUNET_TIME_Absolute startedWaitingAt;
44 struct GNUNET_TIME_Relative waitedFor;
45
46 #if LOG_BACKOFF
47 static FILE *killLogFilePtr;
48 static char *killLogFileName;
49 #endif
50
51
52 static void
53 arm_notify_stop (void *cls, int success)
54 {
55   GNUNET_assert (success == GNUNET_NO);
56 #if START_ARM
57   GNUNET_ARM_stop_service (arm, "arm", TIMEOUT, NULL, NULL);
58 #endif
59 }
60
61
62 static void
63 kill_task (void *cbData,
64            const struct GNUNET_SCHEDULER_TaskContext *tc);
65
66
67 static void
68 do_nothing_notify (void *cls, int success)
69 {
70   GNUNET_assert (success == GNUNET_YES);
71   ok = 1;
72   GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_UNIT_SECONDS, 
73                                 &kill_task, NULL);
74 }
75
76
77 static void
78 arm_notify (void *cls, int success)
79
80   GNUNET_assert (success == GNUNET_YES);
81   GNUNET_ARM_start_service (arm, 
82                             "do-nothing", TIMEOUT, 
83                             &do_nothing_notify, NULL);
84 }
85
86
87 static void
88 kill_task (void *cbData,
89                    const struct GNUNET_SCHEDULER_TaskContext *tc);
90
91
92 static void
93 do_nothing_restarted_notify_task (void *cls,
94                                   const struct GNUNET_SCHEDULER_TaskContext *tc)
95 {       
96   static char a;
97   
98   trialCount++;
99
100 #if LOG_BACKOFF  
101   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 
102     {
103       fprintf(killLogFilePtr, 
104               "%d.Reason is shutdown!\n",
105               trialCount);
106     } 
107   else if ((tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT) != 0) 
108     {
109       fprintf(killLogFilePtr, 
110               "%d.Reason is timeout!\n", 
111               trialCount);
112     }
113   else if ((tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE) != 0) 
114     {
115       fprintf(killLogFilePtr, 
116               "%d.Service is running!\n", 
117               trialCount);
118     }  
119 #endif
120   GNUNET_SCHEDULER_add_now (sched, &kill_task, &a);
121 }
122
123
124 static void
125 do_test (void *cbData,
126          const struct GNUNET_SCHEDULER_TaskContext *tc)
127 {                                     
128   GNUNET_CLIENT_service_test(sched, "do-nothing", 
129                              cfg, TIMEOUT,
130                              &do_nothing_restarted_notify_task, NULL);
131 }
132
133
134 static void
135 shutdown_cont (void *cls, int reason)
136 {
137   trialCount++;
138   startedWaitingAt = GNUNET_TIME_absolute_get();
139   GNUNET_SCHEDULER_add_delayed (sched,
140                                 waitedFor,
141                                 &do_test,
142                                 NULL);
143 }
144 static void
145 kill_task (void *cbData,
146                    const struct GNUNET_SCHEDULER_TaskContext *tc)
147 {
148   static struct GNUNET_CLIENT_Connection * doNothingConnection = NULL;
149
150   if (NULL != cbData) 
151     {
152       waitedFor = GNUNET_TIME_absolute_get_duration (startedWaitingAt);
153       
154 #if LOG_BACKOFF
155       fprintf(killLogFilePtr, 
156               "Waited for: %llu ms\n", 
157               (unsigned long long) waitedFor.value);
158 #endif
159     }
160   else
161     {
162       waitedFor.value = 0;
163     }
164   /* Connect to the doNothing task */
165   doNothingConnection = GNUNET_CLIENT_connect (sched, "do-nothing", cfg);
166 #if LOG_BACKOFF
167   if (NULL == doNothingConnection)
168     fprintf(killLogFilePtr, 
169             "Unable to connect to do-nothing process!\n");
170 #endif  
171   if (trialCount == 12) {
172     GNUNET_ARM_stop_service (arm, 
173                              "do-nothing", 
174                              TIMEOUT,
175                              &arm_notify_stop, NULL);
176     ok = 0;
177     return;
178   }
179   
180   /* Use the created connection to kill the doNothingTask */
181   GNUNET_CLIENT_service_shutdown(sched,
182                                  doNothingConnection, 
183                                  TIMEOUT, 
184                                  &shutdown_cont, NULL);
185 }
186
187        
188 static void
189 task (void *cls,
190       struct GNUNET_SCHEDULER_Handle *s,
191       char *const *args,
192       const char *cfgfile,
193       const struct GNUNET_CONFIGURATION_Handle *c)
194 {
195   cfg = c;
196   sched = s;
197   
198   arm = GNUNET_ARM_connect (cfg, sched, NULL);
199 #if START_ARM
200   GNUNET_ARM_start_service (arm, "arm", GNUNET_TIME_UNIT_ZERO, &arm_notify, NULL);
201 #else
202   arm_do_nothing (NULL, GNUNET_YES);
203 #endif
204 }
205
206 static int
207 check ()
208 {
209   char *const argv[] = {
210     "test-arm-api",
211     "-c", "test_arm_api_data.conf",
212 #if VERBOSE
213     "-L", "DEBUG",
214 #endif
215     NULL
216   };
217   struct GNUNET_GETOPT_CommandLineOption options[] = {
218     GNUNET_GETOPT_OPTION_END
219   };
220   
221   /* Running ARM  and running the do_nothing task */
222   GNUNET_assert (GNUNET_OK ==
223                  GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
224                                      argv,
225                                      "test-exponential-backoff",
226                                      "nohelp", options, &task, NULL));
227   
228   
229   return ok;
230 }
231
232 static int
233 init()
234 {
235 #if LOG_BACKOFF
236   killLogFileName = GNUNET_DISK_mktemp("exponential-backoff-waiting.log");
237   if (NULL == (killLogFilePtr = FOPEN(killLogFileName, "w"))) {
238     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", killLogFileName);
239     GNUNET_free (killLogFileName);
240     return GNUNET_SYSERR;
241   }  
242 #endif
243   return GNUNET_OK;
244 }
245
246
247 static void
248 houseKeep()
249 {
250 #if LOG_BACKOFF
251   GNUNET_assert (0 == fclose (killLogFilePtr));
252   GNUNET_free(killLogFileName);
253 #endif
254 }
255
256
257 int
258 main (int argc, char *argv[])
259 {
260   int ret;
261
262   GNUNET_log_setup ("test-exponential-backoff",
263 #if VERBOSE
264                     "DEBUG",
265 #else
266                     "WARNING",
267 #endif
268                     NULL);
269   
270   init();
271   ret = check ();
272   houseKeep();
273   return ret;
274 }
275
276 /* end of test_exponential_backoff.c */