-Merge branch 'master' of ssh://gnunet.org/gnunet into gsoc2018/rest_api
[oweals/gnunet.git] / src / util / test_scheduler.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your 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      Affero General Public License for more details.
14     
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 /**
19  * @file util/test_scheduler.c
20  * @brief tests for the scheduler
21  */
22 #include "platform.h"
23 #include "gnunet_util_lib.h"
24
25
26 static struct GNUNET_DISK_PipeHandle *p;
27
28 static const struct GNUNET_DISK_FileHandle *fds[2];
29
30 static struct GNUNET_SCHEDULER_Task *never_run_task;
31
32
33 static void
34 task2 (void *cls)
35 {
36   int *ok = cls;
37
38   /* t3 should be ready (albeit with lower priority) */
39   GNUNET_assert (1 ==
40                  GNUNET_SCHEDULER_get_load (GNUNET_SCHEDULER_PRIORITY_COUNT));
41   GNUNET_assert (2 == *ok);
42   (*ok) = 3;
43 }
44
45
46 static void
47 task3 (void *cls)
48 {
49   int *ok = cls;
50
51   GNUNET_assert (3 == *ok);
52   (*ok) = 4;
53 }
54
55
56 static void
57 taskWrt (void *cls)
58 {
59   static char c;
60   int *ok = cls;
61   const struct GNUNET_SCHEDULER_TaskContext *tc;
62
63   tc = GNUNET_SCHEDULER_get_task_context ();
64   GNUNET_assert (6 == *ok);
65   GNUNET_assert (GNUNET_NETWORK_fdset_handle_isset (tc->write_ready, fds[1]));
66   (*ok) = 7;
67   GNUNET_assert (1 == GNUNET_DISK_file_write (fds[1], &c, 1));
68 }
69
70
71 static void
72 taskNeverRun (void *cls)
73 {
74   GNUNET_assert (0);
75 }
76
77
78 static void
79 taskLastRd (void *cls)
80 {
81   int *ok = cls;
82
83   GNUNET_assert (8 == *ok);
84   (*ok) = 0;
85 }
86
87
88 static void
89 taskLastSig (void *cls)
90 {
91   int *ok = cls;
92
93   GNUNET_SCHEDULER_cancel (never_run_task);
94   GNUNET_assert (9 == *ok);
95   (*ok) = 0;
96 }
97
98
99 static void
100 taskLastShutdown (void *cls)
101 {
102   int *ok = cls;
103
104   GNUNET_assert (10 == *ok);
105   (*ok) = 0;
106 }
107
108
109 static void
110 taskRd (void *cls)
111 {
112   static char c;
113   int *ok = cls;
114   const struct GNUNET_SCHEDULER_TaskContext *tc;
115
116   tc = GNUNET_SCHEDULER_get_task_context ();
117   GNUNET_assert (7 == *ok);
118   GNUNET_assert (GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, fds[0]));
119   GNUNET_assert (1 == GNUNET_DISK_file_read (fds[0], &c, 1));
120   (*ok) = 8;
121   GNUNET_SCHEDULER_add_shutdown (&taskLastRd,
122                                  cls);
123   GNUNET_SCHEDULER_shutdown ();
124 }
125
126
127 static void
128 task4 (void *cls)
129 {
130   int *ok = cls;
131
132   GNUNET_assert (4 == *ok);
133   (*ok) = 6;
134   p = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
135   GNUNET_assert (NULL != p);
136   fds[0] = GNUNET_DISK_pipe_handle (p, GNUNET_DISK_PIPE_END_READ);
137   fds[1] = GNUNET_DISK_pipe_handle (p, GNUNET_DISK_PIPE_END_WRITE);
138   GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
139                                   fds[0],
140                                   &taskRd,
141                                   cls);
142   GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
143                                    fds[1],
144                                    &taskWrt,
145                                    cls);
146 }
147
148
149 static void
150 task1 (void *cls)
151 {
152   int *ok = cls;
153
154   GNUNET_assert (1 == *ok);
155   (*ok) = 2;
156   GNUNET_SCHEDULER_add_now (&task3, cls);
157   GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI,
158                                       &task2,
159                                       cls);
160   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
161                                 &task4,
162                                 cls);
163 }
164
165
166 /**
167  * Main method, starts scheduler with task1,
168  * checks that "ok" is correct at the end.
169  */
170 static int
171 check ()
172 {
173   int ok;
174
175   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
176               "[Check scheduling]\n");
177   ok = 1;
178   GNUNET_SCHEDULER_run (&task1, &ok);
179   return ok;
180 }
181
182
183 static void
184 taskShutdown (void *cls)
185 {
186   int *ok = cls;
187
188   GNUNET_assert (1 == *ok);
189   *ok = 10;
190   GNUNET_SCHEDULER_add_shutdown (&taskLastShutdown, cls);
191   GNUNET_SCHEDULER_shutdown ();
192 }
193
194
195 /**
196  * Main method, starts scheduler with task1,
197  * checks that "ok" is correct at the end.
198  */
199 static int
200 checkShutdown ()
201 {
202   int ok;
203
204   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
205               "[Check shutdown]\n");
206   ok = 1;
207   GNUNET_SCHEDULER_run (&taskShutdown, &ok);
208   return ok;
209 }
210
211
212 #ifndef MINGW
213 static void
214 taskSig (void *cls)
215 {
216   int *ok = cls;
217
218   GNUNET_assert (1 == *ok);
219   *ok = 9;
220   GNUNET_SCHEDULER_add_shutdown (&taskLastSig, cls);
221   never_run_task = 
222     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
223                                   &taskNeverRun,
224                                   NULL);
225   GNUNET_break (0 == PLIBC_KILL (getpid (),
226                                  GNUNET_TERM_SIG));
227 }
228
229
230 /**
231  * Main method, starts scheduler with task1,
232  * checks that "ok" is correct at the end.
233  */
234 static int
235 checkSignal ()
236 {
237   int ok;
238
239   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
240               "[Check signal handling]\n");
241   ok = 1;
242   GNUNET_SCHEDULER_run (&taskSig, &ok);
243   return ok;
244 }
245 #endif
246
247
248 static void
249 taskCancel (void *cls)
250 {
251   int *ok = cls;
252
253   GNUNET_assert (1 == *ok);
254   *ok = 0;
255   GNUNET_SCHEDULER_cancel (GNUNET_SCHEDULER_add_now (&taskNeverRun, NULL));
256 }
257
258
259 /**
260  * Main method, starts scheduler with task1,
261  * checks that "ok" is correct at the end.
262  */
263 static int
264 checkCancel ()
265 {
266   int ok;
267
268   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
269               "[Check task cancellation]\n");
270   ok = 1;
271   GNUNET_SCHEDULER_run (&taskCancel, &ok);
272   return ok;
273 }
274
275
276 int
277 main (int argc, char *argv[])
278 {
279   int ret = 0;
280
281   GNUNET_log_setup ("test_scheduler", "WARNING", NULL);
282   ret += check ();
283   ret += checkCancel ();
284 #ifndef MINGW
285   ret += checkSignal ();
286 #endif
287   ret += checkShutdown ();
288   GNUNET_DISK_pipe_close (p);
289
290   return ret;
291 }
292
293 /* end of test_scheduler.c */