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