357a5e71a16bb4203de4ad77b6dc3d090afaf0b6
[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     waitedFor = GNUNET_TIME_absolute_get_duration (startedWaitingAt);
152
153 #if LOG_BACKOFF
154     fprintf(killLogFilePtr, 
155             "Waited for: %llu ms\n", 
156             (unsigned long long) waitedFor.value);
157 #endif
158   }
159   else
160     waitedFor.value = 0;
161   /* Connect to the doNothing task */
162   doNothingConnection = GNUNET_CLIENT_connect (sched, "do-nothing", cfg);
163 #if LOG_BACKOFF
164   if (NULL == doNothingConnection)
165     fprintf(killLogFilePtr, 
166             "Unable to connect to do-nothing process!\n");
167 #endif  
168   if (trialCount == 12) {
169     GNUNET_ARM_stop_service (arm, 
170                              "do-nothing", 
171                              TIMEOUT,
172                              &arm_notify_stop, NULL);
173     ok = 0;
174     return;
175   }
176   
177   /* Use the created connection to kill the doNothingTask */
178   GNUNET_CLIENT_service_shutdown(sched, doNothingConnection, TIMEOUT, &shutdown_cont, NULL);
179
180 }
181
182        
183 static void
184 task (void *cls,
185       struct GNUNET_SCHEDULER_Handle *s,
186       char *const *args,
187       const char *cfgfile,
188       const struct GNUNET_CONFIGURATION_Handle *c)
189 {
190   cfg = c;
191   sched = s;
192   
193   arm = GNUNET_ARM_connect (cfg, sched, NULL);
194 #if START_ARM
195   GNUNET_ARM_start_service (arm, "arm", GNUNET_TIME_UNIT_ZERO, &arm_notify, NULL);
196 #else
197   arm_do_nothing (NULL, GNUNET_YES);
198 #endif
199 }
200
201 static int
202 check ()
203 {
204   char *const argv[] = {
205     "test-arm-api",
206     "-c", "test_arm_api_data.conf",
207 #if VERBOSE
208     "-L", "DEBUG",
209 #endif
210     NULL
211   };
212   struct GNUNET_GETOPT_CommandLineOption options[] = {
213     GNUNET_GETOPT_OPTION_END
214   };
215   
216   /* Running ARM  and running the do_nothing task */
217   GNUNET_assert (GNUNET_OK ==
218                  GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
219                                      argv,
220                                      "test-exponential-backoff",
221                                      "nohelp", options, &task, NULL));
222   
223   
224   return ok;
225 }
226
227 static int
228 init()
229 {
230 #if LOG_BACKOFF
231   killLogFileName = GNUNET_DISK_mktemp("exponential-backoff-waiting.log");
232   if (NULL == (killLogFilePtr = FOPEN(killLogFileName, "w"))) {
233     GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "fopen", killLogFileName);
234     GNUNET_free (killLogFileName);
235     return GNUNET_SYSERR;
236   }  
237 #endif
238   return GNUNET_OK;
239 }
240
241
242 static void
243 houseKeep()
244 {
245 #if LOG_BACKOFF
246   GNUNET_assert (0 == fclose (killLogFilePtr));
247   GNUNET_free(killLogFileName);
248 #endif
249 }
250
251
252 int
253 main (int argc, char *argv[])
254 {
255   int ret;
256
257   GNUNET_log_setup ("test-exponential-backoff",
258 #if VERBOSE
259                     "DEBUG",
260 #else
261                     "WARNING",
262 #endif
263                     NULL);
264   
265   init();
266   ret = check ();
267   houseKeep();
268   return ret;
269 }
270
271 /* end of test_exponential_backoff.c */