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