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

Last change on this file since 3ea98e8 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
Line 
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
69 TPRINTF("11 match\n");
70
71 task_wait_set(&wait, TASK_WAIT_EXIT);
72 rc = dummy_task_spawn(&tid, &wait, STR_FAIL);
73 TASSERT(rc == EOK);
74
75 TPRINTF("waiting...");
76 texit = TASK_EXIT_RUNNING; retval = 255;
77 rc = task_wait(&wait, &texit, &retval);
78 TPRINTF("done.\n");
79 TASSERT(rc == EOK);
80 TASSERT(task_wait_get(&wait) == 0);
81 TASSERT(texit == TASK_EXIT_UNEXPECTED);
82 TPRINTF("OK\n");
83 /* ---- */
84
85 TPRINTF("12 lost wait\n");
86
87 task_wait_set(&wait, TASK_WAIT_RETVAL);
88 rc = dummy_task_spawn(&tid, &wait, STR_FAIL);
89 TASSERT(rc == EOK);
90
91 TPRINTF("waiting...");
92 texit = TASK_EXIT_RUNNING; retval = 255;
93 rc = task_wait(&wait, &texit, &retval);
94 TPRINTF("done.\n");
95 TASSERT(rc == EINVAL);
96 TASSERT(task_wait_get(&wait) == 0);
97 TPRINTF("OK\n");
98 /* ---- */
99
100 TPRINTF("13 partial match\n");
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
106 TPRINTF("waiting...");
107 texit = TASK_EXIT_RUNNING; retval = 255;
108 rc = task_wait(&wait, &texit, &retval);
109 TPRINTF("done.\n");
110 TASSERT(rc == EOK);
111 TASSERT(task_wait_get(&wait) == 0);
112 TASSERT(texit == TASK_EXIT_UNEXPECTED);
113 /* retval is undefined */
114 TPRINTF("OK\n");
115 /* ---- */
116
117 TPRINTF("21 ignore retval and still wait for exit\n");
118
119 task_wait_set(&wait, TASK_WAIT_EXIT);
120 /* STR_JOB_OK to emulate daemon that eventually terminates */
121 rc = dummy_task_spawn(&tid, &wait, STR_JOB_OK);
122 TASSERT(rc == EOK);
123
124 TPRINTF("waiting...");
125 texit = TASK_EXIT_RUNNING; retval = 255;
126 rc = task_wait(&wait, &texit, &retval);
127 TPRINTF("done.\n");
128 TASSERT(rc == EOK);
129 TASSERT(task_wait_get(&wait) == 0);
130 TASSERT(texit == TASK_EXIT_NORMAL);
131 /* retval is unknown */
132 TPRINTF("OK\n");
133 /* ---- */
134
135 TPRINTF("22 good match\n");
136
137 task_wait_set(&wait, TASK_WAIT_RETVAL);
138 rc = dummy_task_spawn(&tid, &wait, STR_DAEMON);
139 TASSERT(rc == EOK);
140
141 TPRINTF("waiting...");
142 texit = TASK_EXIT_RUNNING; retval = 255;
143 rc = task_wait(&wait, &texit, &retval);
144 TPRINTF("done.\n");
145 TASSERT(rc == EOK);
146 TASSERT(task_wait_get(&wait) == 0);
147 /* exit is not expected */
148 TASSERT(retval == EOK);
149 task_kill(tid); /* Terminate daemon */
150 TPRINTF("OK\n");
151 /* ---- */
152
153 TPRINTF("23 partial match (non-exited task)\n");
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
159 TPRINTF("waiting...");
160 texit = TASK_EXIT_RUNNING; retval = 255;
161 rc = task_wait(&wait, &texit, &retval);
162 TPRINTF("done.\n");
163 TASSERT(rc == EOK);
164 TASSERT(task_wait_get(&wait) == TASK_WAIT_EXIT);
165 /* exit is not expected */
166 TASSERT(retval == EOK);
167 task_kill(tid); /* Terminate daemon */
168 TPRINTF("OK\n");
169 /* ---- */
170
171 TPRINTF("31 on exit return\n");
172
173 task_wait_set(&wait, TASK_WAIT_EXIT);
174 rc = dummy_task_spawn(&tid, &wait, STR_JOB_OK);
175 TASSERT(rc == EOK);
176
177 TPRINTF("waiting...");
178 texit = TASK_EXIT_RUNNING; retval = 255;
179 rc = task_wait(&wait, &texit, &retval);
180 TPRINTF("done.\n");
181 TASSERT(rc == EOK);
182 TASSERT(task_wait_get(&wait) == 0);
183 TASSERT(texit == TASK_EXIT_NORMAL);
184 /* retval is unknown */
185 TPRINTF("OK\n");
186 /* ---- */
187
188
189 TPRINTF("32 keep retval until exit\n");
190
191 task_wait_set(&wait, TASK_WAIT_RETVAL);
192 rc = dummy_task_spawn(&tid, &wait, STR_JOB_OK);
193 TASSERT(rc == EOK);
194
195 TPRINTF("waiting...");
196 texit = TASK_EXIT_RUNNING; retval = 255;
197 rc = task_wait(&wait, &texit, &retval);
198 TPRINTF("done.\n");
199 TASSERT(rc == EOK);
200 /* Job atomically exited, so there's nothing more to wait for. */
201 TASSERT(task_wait_get(&wait) == 0);
202 /* exit is unknown */
203 TASSERT(retval == EOK);
204 /* check task already exited */
205 rc = task_kill(tid);
206 TASSERT(rc == ENOENT);
207 TPRINTF("OK\n");
208 /* ---- */
209
210 TPRINTF("33 double good match\n");
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
216 TPRINTF("waiting...");
217 texit = TASK_EXIT_RUNNING; retval = 255;
218 rc = task_wait(&wait, &texit, &retval);
219 TPRINTF("done.\n");
220 TASSERT(rc == EOK);
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);
280 TASSERT(texit == TASK_EXIT_NORMAL);
281 TASSERT(retval == EOK);
282 TPRINTF("OK\n");
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.