source: mainline/uspace/app/tester/proc/task_wait.c@ d4ec49e

Last change on this file since d4ec49e was d4ec49e, checked in by Matthieu Riolo <matthieu.riolo@…>, 6 years ago

taskman: Implement waiting both for retval and exit
Conflicts:

uspace/lib/c/generic/task.c
uspace/lib/c/include/task.h

  • Property mode set to 100644
File size: 7.8 KB
RevLine 
[70d28e8]1/*
2 * Copyright (c) 2015 Michal Koutny
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <async.h>
30#include <errno.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <task.h>
34
35#include "../tester.h"
36#include "common.h"
37
38#define DUMMY_TASK "/root/app/tester"
39#define DUMMY_TASK_ARG "proc_dummy_task"
40
41#define S(x) #x
42#define S_(x) S(x)
43#define S__LINE__ S_(__LINE__)
44
45#define TASSERT(expr) \
46 do { \
47 if (!(expr)) \
48 return "Failed " #expr " " __FILE__ ":" S__LINE__ ; \
49 } while (0)
50
51static int dummy_task_spawn(task_id_t *task_id, task_wait_t *wait,
52 const char *behavior)
53{
54 return task_spawnl(task_id, wait,
55 DUMMY_TASK, DUMMY_TASK, DUMMY_TASK_ARG, behavior,
56 NULL);
57}
58
59const char *test_proc_task_wait(void)
60{
61 const char *err = NULL;
62
63 int rc;
64 task_id_t tid;
65 task_wait_t wait;
66 int retval;
67 task_exit_t texit;
68
[62273d1]69 TPRINTF("11 match\n");
[70d28e8]70
71 task_wait_set(&wait, TASK_WAIT_EXIT);
72 rc = dummy_task_spawn(&tid, &wait, STR_FAIL);
73 TASSERT(rc == EOK);
74
[62273d1]75 TPRINTF("waiting...");
[d4ec49e]76 texit = TASK_EXIT_RUNNING; retval = 255;
[70d28e8]77 rc = task_wait(&wait, &texit, &retval);
[62273d1]78 TPRINTF("done.\n");
[70d28e8]79 TASSERT(rc == EOK);
[d4ec49e]80 TASSERT(task_wait_get(&wait) == 0);
[70d28e8]81 TASSERT(texit == TASK_EXIT_UNEXPECTED);
[62273d1]82 TPRINTF("OK\n");
[70d28e8]83 /* ---- */
84
[62273d1]85 TPRINTF("12 lost wait\n");
[70d28e8]86
87 task_wait_set(&wait, TASK_WAIT_RETVAL);
88 rc = dummy_task_spawn(&tid, &wait, STR_FAIL);
89 TASSERT(rc == EOK);
90
[62273d1]91 TPRINTF("waiting...");
[d4ec49e]92 texit = TASK_EXIT_RUNNING; retval = 255;
[70d28e8]93 rc = task_wait(&wait, &texit, &retval);
[62273d1]94 TPRINTF("done.\n");
[70d28e8]95 TASSERT(rc == EINVAL);
[d4ec49e]96 TASSERT(task_wait_get(&wait) == 0);
[62273d1]97 TPRINTF("OK\n");
[70d28e8]98 /* ---- */
99
[62273d1]100 TPRINTF("13 partial match\n");
[70d28e8]101
102 task_wait_set(&wait, TASK_WAIT_RETVAL | TASK_WAIT_EXIT);
103 rc = dummy_task_spawn(&tid, &wait, STR_BYPASS);
104 TASSERT(rc == EOK);
105
[62273d1]106 TPRINTF("waiting...");
[d4ec49e]107 texit = TASK_EXIT_RUNNING; retval = 255;
[70d28e8]108 rc = task_wait(&wait, &texit, &retval);
[62273d1]109 TPRINTF("done.\n");
[70d28e8]110 TASSERT(rc == EOK);
[d4ec49e]111 TASSERT(task_wait_get(&wait) == 0);
[70d28e8]112 TASSERT(texit == TASK_EXIT_UNEXPECTED);
113 /* retval is undefined */
[62273d1]114 TPRINTF("OK\n");
[70d28e8]115 /* ---- */
116
[d4ec49e]117 TPRINTF("21 ignore retval and still wait for exit\n");
[70d28e8]118
119 task_wait_set(&wait, TASK_WAIT_EXIT);
[d4ec49e]120 /* STR_JOB_OK to emulate daemon that eventually terminates */
[70d28e8]121 rc = dummy_task_spawn(&tid, &wait, STR_JOB_OK);
122 TASSERT(rc == EOK);
123
[62273d1]124 TPRINTF("waiting...");
[d4ec49e]125 texit = TASK_EXIT_RUNNING; retval = 255;
[70d28e8]126 rc = task_wait(&wait, &texit, &retval);
[62273d1]127 TPRINTF("done.\n");
[70d28e8]128 TASSERT(rc == EOK);
[d4ec49e]129 TASSERT(task_wait_get(&wait) == 0);
[70d28e8]130 TASSERT(texit == TASK_EXIT_NORMAL);
131 /* retval is unknown */
[62273d1]132 TPRINTF("OK\n");
[70d28e8]133 /* ---- */
134
[62273d1]135 TPRINTF("22 good match\n");
[70d28e8]136
137 task_wait_set(&wait, TASK_WAIT_RETVAL);
138 rc = dummy_task_spawn(&tid, &wait, STR_DAEMON);
139 TASSERT(rc == EOK);
140
[62273d1]141 TPRINTF("waiting...");
[d4ec49e]142 texit = TASK_EXIT_RUNNING; retval = 255;
[70d28e8]143 rc = task_wait(&wait, &texit, &retval);
[62273d1]144 TPRINTF("done.\n");
[70d28e8]145 TASSERT(rc == EOK);
[d4ec49e]146 TASSERT(task_wait_get(&wait) == 0);
[70d28e8]147 /* exit is not expected */
148 TASSERT(retval == EOK);
149 task_kill(tid); /* Terminate daemon */
[62273d1]150 TPRINTF("OK\n");
[70d28e8]151 /* ---- */
152
[62273d1]153 TPRINTF("23 partial match (non-exited task)\n");
[70d28e8]154
155 task_wait_set(&wait, TASK_WAIT_RETVAL | TASK_WAIT_EXIT);
156 rc = dummy_task_spawn(&tid, &wait, STR_DAEMON);
157 TASSERT(rc == EOK);
158
[62273d1]159 TPRINTF("waiting...");
[d4ec49e]160 texit = TASK_EXIT_RUNNING; retval = 255;
[70d28e8]161 rc = task_wait(&wait, &texit, &retval);
[62273d1]162 TPRINTF("done.\n");
[70d28e8]163 TASSERT(rc == EOK);
[d4ec49e]164 TASSERT(task_wait_get(&wait) == TASK_WAIT_EXIT);
[70d28e8]165 /* exit is not expected */
166 TASSERT(retval == EOK);
167 task_kill(tid); /* Terminate daemon */
[62273d1]168 TPRINTF("OK\n");
[70d28e8]169 /* ---- */
170
[62273d1]171 TPRINTF("31 on exit return\n");
[70d28e8]172
173 task_wait_set(&wait, TASK_WAIT_EXIT);
174 rc = dummy_task_spawn(&tid, &wait, STR_JOB_OK);
175 TASSERT(rc == EOK);
176
[62273d1]177 TPRINTF("waiting...");
[d4ec49e]178 texit = TASK_EXIT_RUNNING; retval = 255;
[70d28e8]179 rc = task_wait(&wait, &texit, &retval);
[62273d1]180 TPRINTF("done.\n");
[70d28e8]181 TASSERT(rc == EOK);
[d4ec49e]182 TASSERT(task_wait_get(&wait) == 0);
[70d28e8]183 TASSERT(texit == TASK_EXIT_NORMAL);
184 /* retval is unknown */
[62273d1]185 TPRINTF("OK\n");
[70d28e8]186 /* ---- */
187
188
[62273d1]189 TPRINTF("32 keep retval until exit\n");
[70d28e8]190
191 task_wait_set(&wait, TASK_WAIT_RETVAL);
192 rc = dummy_task_spawn(&tid, &wait, STR_JOB_OK);
193 TASSERT(rc == EOK);
194
[62273d1]195 TPRINTF("waiting...");
[d4ec49e]196 texit = TASK_EXIT_RUNNING; retval = 255;
[70d28e8]197 rc = task_wait(&wait, &texit, &retval);
[62273d1]198 TPRINTF("done.\n");
[70d28e8]199 TASSERT(rc == EOK);
[d4ec49e]200 /* Job atomically exited, so there's nothing more to wait for. */
201 TASSERT(task_wait_get(&wait) == 0);
[70d28e8]202 /* exit is unknown */
203 TASSERT(retval == EOK);
204 /* check task already exited */
205 rc = task_kill(tid);
206 TASSERT(rc == ENOENT);
[62273d1]207 TPRINTF("OK\n");
[70d28e8]208 /* ---- */
209
[62273d1]210 TPRINTF("33 double good match\n");
[70d28e8]211
212 task_wait_set(&wait, TASK_WAIT_RETVAL | TASK_WAIT_EXIT);
213 rc = dummy_task_spawn(&tid, &wait, STR_JOB_OK);
214 TASSERT(rc == EOK);
215
[62273d1]216 TPRINTF("waiting...");
[d4ec49e]217 texit = TASK_EXIT_RUNNING; retval = 255;
[70d28e8]218 rc = task_wait(&wait, &texit, &retval);
[62273d1]219 TPRINTF("done.\n");
[70d28e8]220 TASSERT(rc == EOK);
[d4ec49e]221 TASSERT(task_wait_get(&wait) == 0);
222 TASSERT(texit == TASK_EXIT_NORMAL);
223 TASSERT(retval == EOK);
224 TPRINTF("OK\n");
225 /* ---- */
226
227 TPRINTF("14 partially lost wait\n");
228
229 task_wait_set(&wait, TASK_WAIT_BOTH);
230 rc = dummy_task_spawn(&tid, &wait, STR_FAIL);
231 TASSERT(rc == EOK);
232
233 TPRINTF("waiting...");
234 texit = TASK_EXIT_RUNNING; retval = 255;
235 rc = task_wait(&wait, &texit, &retval);
236 TPRINTF("done.\n");
237 TASSERT(rc == EINVAL);
238 TASSERT(task_wait_get(&wait) == 0);
239 TASSERT(texit == TASK_EXIT_UNEXPECTED);
240 /* retval is undefined */
241 TPRINTF("OK\n");
242 /* ---- */
243
244 TPRINTF("24 repeated wait\n");
245
246 task_wait_set(&wait, TASK_WAIT_BOTH);
247 rc = dummy_task_spawn(&tid, &wait, STR_DAEMON);
248 TASSERT(rc == EOK);
249
250 TPRINTF("waiting...");
251 texit = TASK_EXIT_RUNNING; retval = 255;
252 rc = task_wait(&wait, &texit, &retval);
253 TPRINTF("done.\n");
254 TASSERT(rc == EOK);
255 TASSERT(task_wait_get(&wait) == TASK_WAIT_EXIT);
256 TASSERT(retval == EOK);
257 task_kill(tid); /* Terminate daemon */
258 TPRINTF("waiting 2...");
259 texit = TASK_EXIT_RUNNING; retval = 255;
260 rc = task_wait(&wait, &texit, &retval);
261 TPRINTF("done.\n");
262 TASSERT(rc == EOK);
263 TASSERT(task_wait_get(&wait) == 0);
264 //TASSERT(texit == TASK_EXIT_UNEXPECTED); // TODO resolve this in taskman/kernel
265 TPRINTF("OK\n");
266 /* ---- */
267
268 TPRINTF("34 double wait in one\n");
269
270 task_wait_set(&wait, TASK_WAIT_BOTH);
271 rc = dummy_task_spawn(&tid, &wait, STR_JOB_OK);
272 TASSERT(rc == EOK);
273
274 TPRINTF("waiting...");
275 texit = TASK_EXIT_RUNNING; retval = 255;
276 rc = task_wait(&wait, &texit, &retval);
277 TPRINTF("done.\n");
278 TASSERT(rc == EOK);
279 TASSERT(task_wait_get(&wait) == 0);
[70d28e8]280 TASSERT(texit == TASK_EXIT_NORMAL);
281 TASSERT(retval == EOK);
[62273d1]282 TPRINTF("OK\n");
[70d28e8]283 /* ---- */
284
285 TPRINTF("All task waiting tests finished");
286
287
288
289 return err;
290}
Note: See TracBrowser for help on using the repository browser.