1a563ca70SAlex Hornung /*
2a563ca70SAlex Hornung * Copyright (c) 2011 Alex Hornung <alex@alexhornung.com>.
3a563ca70SAlex Hornung * All rights reserved.
4a563ca70SAlex Hornung *
5a563ca70SAlex Hornung * Redistribution and use in source and binary forms, with or without
6a563ca70SAlex Hornung * modification, are permitted provided that the following conditions
7a563ca70SAlex Hornung * are met:
8a563ca70SAlex Hornung *
9a563ca70SAlex Hornung * 1. Redistributions of source code must retain the above copyright
10a563ca70SAlex Hornung * notice, this list of conditions and the following disclaimer.
11a563ca70SAlex Hornung * 2. Redistributions in binary form must reproduce the above copyright
12a563ca70SAlex Hornung * notice, this list of conditions and the following disclaimer in
13a563ca70SAlex Hornung * the documentation and/or other materials provided with the
14a563ca70SAlex Hornung * distribution.
15a563ca70SAlex Hornung *
16a563ca70SAlex Hornung * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a563ca70SAlex Hornung * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a563ca70SAlex Hornung * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19a563ca70SAlex Hornung * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20a563ca70SAlex Hornung * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21a563ca70SAlex Hornung * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
22a563ca70SAlex Hornung * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23a563ca70SAlex Hornung * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24a563ca70SAlex Hornung * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25a563ca70SAlex Hornung * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26a563ca70SAlex Hornung * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27a563ca70SAlex Hornung * SUCH DAMAGE.
28a563ca70SAlex Hornung */
29a563ca70SAlex Hornung
30a563ca70SAlex Hornung #include <sys/resource.h>
31a563ca70SAlex Hornung #include <sys/time.h>
32a563ca70SAlex Hornung #include <sys/types.h>
33a563ca70SAlex Hornung #include <sys/wait.h>
34a563ca70SAlex Hornung
35a563ca70SAlex Hornung #include <errno.h>
36a563ca70SAlex Hornung #include <signal.h>
37a563ca70SAlex Hornung #include <stdio.h>
38a563ca70SAlex Hornung #include <stdlib.h>
39a563ca70SAlex Hornung #include <stdint.h>
40a563ca70SAlex Hornung #include <string.h>
41a563ca70SAlex Hornung #include <unistd.h>
42a563ca70SAlex Hornung #include <pwd.h>
43a563ca70SAlex Hornung
44a563ca70SAlex Hornung #include <err.h>
45a563ca70SAlex Hornung
46a563ca70SAlex Hornung #include <libprop/proplib.h>
47a563ca70SAlex Hornung
48a563ca70SAlex Hornung #include "parser.h"
49a563ca70SAlex Hornung #include "testcase.h"
50a563ca70SAlex Hornung #include "runlist.h"
51a563ca70SAlex Hornung #include "config.h"
52a563ca70SAlex Hornung #include <dfregress.h>
53a563ca70SAlex Hornung
54a563ca70SAlex Hornung prop_dictionary_t
testcase_from_struct(struct testcase * testcase)55a563ca70SAlex Hornung testcase_from_struct(struct testcase *testcase)
56a563ca70SAlex Hornung {
57a563ca70SAlex Hornung int i, r;
58a563ca70SAlex Hornung prop_dictionary_t dict, testcase_dict;
59a563ca70SAlex Hornung prop_array_t a;
60a563ca70SAlex Hornung char *s;
61a563ca70SAlex Hornung
62a563ca70SAlex Hornung testcase_dict = prop_dictionary_create();
63a563ca70SAlex Hornung if (testcase_dict == NULL)
64a563ca70SAlex Hornung err(1, "could not create testcase dict");
65a563ca70SAlex Hornung r = prop_dictionary_set_cstring(testcase_dict, "name", testcase->name);
66a563ca70SAlex Hornung if (r == 0)
67a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
68a563ca70SAlex Hornung r = prop_dictionary_set_cstring(testcase_dict, "type", testcase->type_str);
69a563ca70SAlex Hornung if (r == 0)
70a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
71a563ca70SAlex Hornung
720d575305SAntonio Huete Jimenez r = prop_dictionary_set_int32(testcase_dict, "argc",
730d575305SAntonio Huete Jimenez (int32_t)testcase->argc);
740d575305SAntonio Huete Jimenez if (r == 0)
750d575305SAntonio Huete Jimenez err(1, "prop_dictionary operation failed");
760d575305SAntonio Huete Jimenez
77a563ca70SAlex Hornung a = prop_array_create_with_capacity(testcase->argc+1);
78a563ca70SAlex Hornung if (a == NULL)
79a563ca70SAlex Hornung err(1, "prop_array_create for argv failed");
80a563ca70SAlex Hornung
81a563ca70SAlex Hornung s = strrchr(testcase->name, '/');
82a563ca70SAlex Hornung r = prop_array_set_cstring(a, 0, (s == NULL) ? testcase->name : s+1);
83a563ca70SAlex Hornung if (r == 0)
84a563ca70SAlex Hornung err(1, "prop_array_set_cstring operation failed");
85a563ca70SAlex Hornung
86a563ca70SAlex Hornung for (i = 1; i <= testcase->argc; i++) {
87a563ca70SAlex Hornung r = prop_array_set_cstring(a, i, testcase->argv[i-1]);
88a563ca70SAlex Hornung if (r == 0)
89a563ca70SAlex Hornung err(1, "prop_array_set_cstring operation failed");
90a563ca70SAlex Hornung }
91a563ca70SAlex Hornung
92a563ca70SAlex Hornung r = prop_dictionary_set(testcase_dict, "args", a);
93a563ca70SAlex Hornung if (r == 0)
94a563ca70SAlex Hornung err(1, "prop_dictionary_set \"args\" failed");
95a563ca70SAlex Hornung
96a563ca70SAlex Hornung dict = prop_dictionary_create();
97a563ca70SAlex Hornung if (dict == NULL)
98a563ca70SAlex Hornung err(1, "could not create dict");
99a563ca70SAlex Hornung
100a563ca70SAlex Hornung r = prop_dictionary_set_int32(dict, "timeout_in_secs",
101a563ca70SAlex Hornung (int32_t)testcase->opts.timeout_in_secs);
102a563ca70SAlex Hornung if (r == 0)
103a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
104a563ca70SAlex Hornung
105*039caa27SAntonio Huete Jimenez r = prop_dictionary_set_int32(dict, "rc",
106*039caa27SAntonio Huete Jimenez (int32_t)testcase->opts.rc);
107*039caa27SAntonio Huete Jimenez if (r == 0)
108*039caa27SAntonio Huete Jimenez err(1, "prop_dictionary operation failed");
109*039caa27SAntonio Huete Jimenez
110a563ca70SAlex Hornung r = prop_dictionary_set_uint32(dict, "flags", testcase->opts.flags);
111a563ca70SAlex Hornung if (r == 0)
112a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
113a563ca70SAlex Hornung
114a563ca70SAlex Hornung if (testcase->opts.pre_cmd != NULL) {
115a563ca70SAlex Hornung r = prop_dictionary_set_cstring(dict, "pre_cmd",
116a563ca70SAlex Hornung testcase->opts.pre_cmd);
117a563ca70SAlex Hornung if (r == 0)
118a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
119a563ca70SAlex Hornung }
120a563ca70SAlex Hornung
121a563ca70SAlex Hornung if (testcase->opts.post_cmd != NULL) {
122a563ca70SAlex Hornung r = prop_dictionary_set_cstring(dict, "post_cmd",
123a563ca70SAlex Hornung testcase->opts.post_cmd);
124a563ca70SAlex Hornung if (r == 0)
125a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
126a563ca70SAlex Hornung }
127a563ca70SAlex Hornung
1280d575305SAntonio Huete Jimenez if (testcase->opts.interpreter != NULL) {
1290d575305SAntonio Huete Jimenez r = prop_dictionary_set_cstring(dict, "interpreter",
1300d575305SAntonio Huete Jimenez testcase->opts.interpreter);
1310d575305SAntonio Huete Jimenez if (r == 0)
1320d575305SAntonio Huete Jimenez err(1, "prop_dictionary operation failed");
1330d575305SAntonio Huete Jimenez }
1340d575305SAntonio Huete Jimenez
135a563ca70SAlex Hornung r = prop_dictionary_set_uint32(dict, "runas_uid",
136a563ca70SAlex Hornung (uint32_t)testcase->opts.runas_uid);
137a563ca70SAlex Hornung if (r == 0)
138a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
139a563ca70SAlex Hornung
140a563ca70SAlex Hornung r = prop_dictionary_set_cstring(dict, "make_cmd",
141a563ca70SAlex Hornung (testcase->opts.make_cmd != NULL) ? testcase->opts.make_cmd : "make");
142a563ca70SAlex Hornung if (r == 0)
143a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
144a563ca70SAlex Hornung
145a563ca70SAlex Hornung r = prop_dictionary_set(testcase_dict, "opts", dict);
146a563ca70SAlex Hornung if (r == 0)
147a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
148a563ca70SAlex Hornung
149a563ca70SAlex Hornung return testcase_dict;
150a563ca70SAlex Hornung }
151a563ca70SAlex Hornung
152a563ca70SAlex Hornung struct timeval *
testcase_get_timeout(prop_dictionary_t testcase)153a563ca70SAlex Hornung testcase_get_timeout(prop_dictionary_t testcase)
154a563ca70SAlex Hornung {
155a563ca70SAlex Hornung static struct timeval tv;
156a563ca70SAlex Hornung int32_t val;
157a563ca70SAlex Hornung int r;
158a563ca70SAlex Hornung
159a563ca70SAlex Hornung r = prop_dictionary_get_int32(prop_dictionary_get(testcase, "opts"),
160a563ca70SAlex Hornung "timeout_in_secs", &val);
161a563ca70SAlex Hornung if (r == 0)
162a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
163a563ca70SAlex Hornung
164a563ca70SAlex Hornung tv.tv_usec = 0;
165a563ca70SAlex Hornung tv.tv_sec = (long)val;
166a563ca70SAlex Hornung
167a563ca70SAlex Hornung return &tv;
168a563ca70SAlex Hornung }
169a563ca70SAlex Hornung
170a563ca70SAlex Hornung int
testcase_get_type(prop_dictionary_t testcase)171a563ca70SAlex Hornung testcase_get_type(prop_dictionary_t testcase)
172a563ca70SAlex Hornung {
173a563ca70SAlex Hornung const char *type;
174a563ca70SAlex Hornung int r;
175a563ca70SAlex Hornung
176a563ca70SAlex Hornung r = prop_dictionary_get_cstring_nocopy(testcase, "type", &type);
177a563ca70SAlex Hornung if (r == 0)
178a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
179a563ca70SAlex Hornung
180a563ca70SAlex Hornung if (strcmp(type, "userland") == 0)
181a563ca70SAlex Hornung return TESTCASE_TYPE_USERLAND;
182a563ca70SAlex Hornung else if (strcmp(type, "kernel") == 0)
183a563ca70SAlex Hornung return TESTCASE_TYPE_KERNEL;
184a563ca70SAlex Hornung else if (strcmp(type, "buildonly") == 0)
185a563ca70SAlex Hornung return TESTCASE_TYPE_BUILDONLY;
186a563ca70SAlex Hornung
187a563ca70SAlex Hornung return 0;
188a563ca70SAlex Hornung }
189a563ca70SAlex Hornung
190a563ca70SAlex Hornung const char *
testcase_get_type_desc(prop_dictionary_t testcase)191a563ca70SAlex Hornung testcase_get_type_desc(prop_dictionary_t testcase)
192a563ca70SAlex Hornung {
193a563ca70SAlex Hornung const char *str;
194a563ca70SAlex Hornung int r;
195a563ca70SAlex Hornung
196a563ca70SAlex Hornung r = prop_dictionary_get_cstring_nocopy(testcase, "type", &str);
197a563ca70SAlex Hornung if (r == 0)
198a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
199a563ca70SAlex Hornung
200a563ca70SAlex Hornung return str;
201a563ca70SAlex Hornung }
202a563ca70SAlex Hornung
203a563ca70SAlex Hornung const char *
testcase_get_name(prop_dictionary_t testcase)204a563ca70SAlex Hornung testcase_get_name(prop_dictionary_t testcase)
205a563ca70SAlex Hornung {
206a563ca70SAlex Hornung const char *str;
207a563ca70SAlex Hornung int r;
208a563ca70SAlex Hornung
209a563ca70SAlex Hornung r = prop_dictionary_get_cstring_nocopy(testcase, "name", &str);
210a563ca70SAlex Hornung if (r == 0)
211a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
212a563ca70SAlex Hornung
213a563ca70SAlex Hornung return str;
214a563ca70SAlex Hornung }
215a563ca70SAlex Hornung
2160d575305SAntonio Huete Jimenez int
testcase_get_argc(prop_dictionary_t testcase)2170d575305SAntonio Huete Jimenez testcase_get_argc(prop_dictionary_t testcase)
2180d575305SAntonio Huete Jimenez {
2190d575305SAntonio Huete Jimenez int32_t argc;
2200d575305SAntonio Huete Jimenez int r;
2210d575305SAntonio Huete Jimenez
2220d575305SAntonio Huete Jimenez r = prop_dictionary_get_int32(testcase, "argc", &argc);
2230d575305SAntonio Huete Jimenez if (r == 0)
2240d575305SAntonio Huete Jimenez err(1, "prop_dictionary operation failed for argc");
2250d575305SAntonio Huete Jimenez
2260d575305SAntonio Huete Jimenez return argc;
2270d575305SAntonio Huete Jimenez }
2280d575305SAntonio Huete Jimenez
229a563ca70SAlex Hornung const char **
testcase_get_args(prop_dictionary_t testcase)230a563ca70SAlex Hornung testcase_get_args(prop_dictionary_t testcase)
231a563ca70SAlex Hornung {
232a563ca70SAlex Hornung /* Sane limit of 63 arguments... who wants more than that? */
233a563ca70SAlex Hornung static const char *argv[64];
234a563ca70SAlex Hornung unsigned int i, count;
235a563ca70SAlex Hornung prop_array_t a;
236a563ca70SAlex Hornung int r;
237a563ca70SAlex Hornung
238a563ca70SAlex Hornung a = prop_dictionary_get(testcase, "args");
239a563ca70SAlex Hornung if (a == NULL)
240a563ca70SAlex Hornung err(1, "testcase_get_args NULL array");
241a563ca70SAlex Hornung
242a563ca70SAlex Hornung count = prop_array_count(a);
243a563ca70SAlex Hornung
244a563ca70SAlex Hornung for (i = 0; i < count; i++) {
245a563ca70SAlex Hornung r = prop_array_get_cstring_nocopy(a, i, &argv[i]);
246a563ca70SAlex Hornung if (r == 0)
247a563ca70SAlex Hornung err(1, "error building argv");
248a563ca70SAlex Hornung }
249a563ca70SAlex Hornung
250a563ca70SAlex Hornung argv[i] = NULL;
251a563ca70SAlex Hornung
252a563ca70SAlex Hornung return argv;
253a563ca70SAlex Hornung }
254a563ca70SAlex Hornung
255a563ca70SAlex Hornung uint32_t
testcase_get_flags(prop_dictionary_t testcase)256a563ca70SAlex Hornung testcase_get_flags(prop_dictionary_t testcase)
257a563ca70SAlex Hornung {
258a563ca70SAlex Hornung uint32_t flags;
259a563ca70SAlex Hornung int r;
260a563ca70SAlex Hornung
261a563ca70SAlex Hornung r = prop_dictionary_get_uint32(prop_dictionary_get(testcase, "opts"),
262a563ca70SAlex Hornung "flags", &flags);
263a563ca70SAlex Hornung if (r == 0)
264a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
265a563ca70SAlex Hornung
266a563ca70SAlex Hornung return flags;
267a563ca70SAlex Hornung }
268a563ca70SAlex Hornung
269a563ca70SAlex Hornung int
testcase_get_precmd_type(prop_dictionary_t testcase)270a563ca70SAlex Hornung testcase_get_precmd_type(prop_dictionary_t testcase)
271a563ca70SAlex Hornung {
272a563ca70SAlex Hornung uint32_t flags = testcase_get_flags(testcase);
273a563ca70SAlex Hornung
274a563ca70SAlex Hornung return (flags & (TESTCASE_INT_PRE | TESTCASE_CUSTOM_PRE));
275a563ca70SAlex Hornung }
276a563ca70SAlex Hornung
277a563ca70SAlex Hornung int
testcase_get_rc(prop_dictionary_t testcase)278*039caa27SAntonio Huete Jimenez testcase_get_rc(prop_dictionary_t testcase)
279*039caa27SAntonio Huete Jimenez {
280*039caa27SAntonio Huete Jimenez int32_t rc;
281*039caa27SAntonio Huete Jimenez int r;
282*039caa27SAntonio Huete Jimenez
283*039caa27SAntonio Huete Jimenez r = prop_dictionary_get_int32(prop_dictionary_get(testcase, "opts"),
284*039caa27SAntonio Huete Jimenez "rc", &rc);
285*039caa27SAntonio Huete Jimenez if (r == 0)
286*039caa27SAntonio Huete Jimenez err(1, "prop_dictionary operation failed for rc");
287*039caa27SAntonio Huete Jimenez
288*039caa27SAntonio Huete Jimenez return rc;
289*039caa27SAntonio Huete Jimenez }
290*039caa27SAntonio Huete Jimenez
291*039caa27SAntonio Huete Jimenez int
testcase_get_postcmd_type(prop_dictionary_t testcase)292a563ca70SAlex Hornung testcase_get_postcmd_type(prop_dictionary_t testcase)
293a563ca70SAlex Hornung {
294a563ca70SAlex Hornung uint32_t flags = testcase_get_flags(testcase);
295a563ca70SAlex Hornung
296a563ca70SAlex Hornung return (flags & (TESTCASE_INT_POST | TESTCASE_CUSTOM_POST));
297a563ca70SAlex Hornung }
298a563ca70SAlex Hornung
299a563ca70SAlex Hornung int
testcase_needs_setuid(prop_dictionary_t testcase)300a563ca70SAlex Hornung testcase_needs_setuid(prop_dictionary_t testcase)
301a563ca70SAlex Hornung {
302a563ca70SAlex Hornung uint32_t flags = testcase_get_flags(testcase);
303a563ca70SAlex Hornung
304a563ca70SAlex Hornung return (flags & TESTCASE_RUN_AS);
305a563ca70SAlex Hornung }
306a563ca70SAlex Hornung
307a563ca70SAlex Hornung uid_t
testcase_get_runas_uid(prop_dictionary_t testcase)308a563ca70SAlex Hornung testcase_get_runas_uid(prop_dictionary_t testcase)
309a563ca70SAlex Hornung {
310a563ca70SAlex Hornung uint32_t uid = 0;
31117b89cd0SSascha Wildner int r;
312a563ca70SAlex Hornung
313a563ca70SAlex Hornung r = prop_dictionary_get_uint32(
314a563ca70SAlex Hornung prop_dictionary_get(testcase, "opts"), "runas_uid", &uid);
31517b89cd0SSascha Wildner if (r == 0)
31617b89cd0SSascha Wildner err(1, "prop_dictionary operation failed");
317a563ca70SAlex Hornung
318a563ca70SAlex Hornung return (uid_t)uid;
319a563ca70SAlex Hornung }
320a563ca70SAlex Hornung
321a563ca70SAlex Hornung const char *
testcase_get_custom_precmd(prop_dictionary_t testcase)322a563ca70SAlex Hornung testcase_get_custom_precmd(prop_dictionary_t testcase)
323a563ca70SAlex Hornung {
324a563ca70SAlex Hornung const char *str;
325a563ca70SAlex Hornung int r;
326a563ca70SAlex Hornung
327a563ca70SAlex Hornung r = prop_dictionary_get_cstring_nocopy(
328a563ca70SAlex Hornung prop_dictionary_get(testcase, "opts"), "pre_cmd", &str);
329a563ca70SAlex Hornung if (r == 0)
330a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
331a563ca70SAlex Hornung
332a563ca70SAlex Hornung return str;
333a563ca70SAlex Hornung }
334a563ca70SAlex Hornung
335a563ca70SAlex Hornung const char *
testcase_get_custom_postcmd(prop_dictionary_t testcase)336a563ca70SAlex Hornung testcase_get_custom_postcmd(prop_dictionary_t testcase)
337a563ca70SAlex Hornung {
338a563ca70SAlex Hornung const char *str;
339a563ca70SAlex Hornung int r;
340a563ca70SAlex Hornung
341a563ca70SAlex Hornung r = prop_dictionary_get_cstring_nocopy(
342a563ca70SAlex Hornung prop_dictionary_get(testcase, "opts"), "pre_cmd", &str);
343a563ca70SAlex Hornung if (r == 0)
344a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
345a563ca70SAlex Hornung
346a563ca70SAlex Hornung return str;
347a563ca70SAlex Hornung }
348a563ca70SAlex Hornung
3490d575305SAntonio Huete Jimenez static const char *
_testcase_get_interpreter(prop_dictionary_t testcase,bool fatal)3500d575305SAntonio Huete Jimenez _testcase_get_interpreter(prop_dictionary_t testcase, bool fatal)
3510d575305SAntonio Huete Jimenez {
3520d575305SAntonio Huete Jimenez const char *str;
3530d575305SAntonio Huete Jimenez int r;
3540d575305SAntonio Huete Jimenez
3550d575305SAntonio Huete Jimenez r = prop_dictionary_get_cstring_nocopy(
3560d575305SAntonio Huete Jimenez prop_dictionary_get(testcase, "opts"), "interpreter", &str);
35729e6131eSAntonio Huete Jimenez if (r == 0) {
35829e6131eSAntonio Huete Jimenez if (fatal)
3590d575305SAntonio Huete Jimenez err(1, "prop_dictionary operation failed for interpreter");
3600d575305SAntonio Huete Jimenez else
3610d575305SAntonio Huete Jimenez return NULL;
36229e6131eSAntonio Huete Jimenez }
3630d575305SAntonio Huete Jimenez
3640d575305SAntonio Huete Jimenez return str;
3650d575305SAntonio Huete Jimenez }
3660d575305SAntonio Huete Jimenez
3670d575305SAntonio Huete Jimenez const char *
testcase_get_interpreter(prop_dictionary_t testcase)3680d575305SAntonio Huete Jimenez testcase_get_interpreter(prop_dictionary_t testcase)
3690d575305SAntonio Huete Jimenez {
3700d575305SAntonio Huete Jimenez return _testcase_get_interpreter(testcase, true);
3710d575305SAntonio Huete Jimenez }
3720d575305SAntonio Huete Jimenez
3730d575305SAntonio Huete Jimenez const char *
testcase_get_interpreter_noexit(prop_dictionary_t testcase)3740d575305SAntonio Huete Jimenez testcase_get_interpreter_noexit(prop_dictionary_t testcase)
3750d575305SAntonio Huete Jimenez {
3760d575305SAntonio Huete Jimenez return _testcase_get_interpreter(testcase, false);
3770d575305SAntonio Huete Jimenez }
3780d575305SAntonio Huete Jimenez
379a563ca70SAlex Hornung const char *
testcase_get_make_cmd(prop_dictionary_t testcase)380a563ca70SAlex Hornung testcase_get_make_cmd(prop_dictionary_t testcase)
381a563ca70SAlex Hornung {
382a563ca70SAlex Hornung const char *str;
383a563ca70SAlex Hornung int r;
384a563ca70SAlex Hornung
385a563ca70SAlex Hornung r = prop_dictionary_get_cstring_nocopy(
386a563ca70SAlex Hornung prop_dictionary_get(testcase, "opts"), "make_cmd", &str);
387a563ca70SAlex Hornung if (r == 0)
388a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
389a563ca70SAlex Hornung
390a563ca70SAlex Hornung return str;
391a563ca70SAlex Hornung }
392a563ca70SAlex Hornung
393a563ca70SAlex Hornung prop_dictionary_t
testcase_get_result_dict(prop_dictionary_t testcase)394a563ca70SAlex Hornung testcase_get_result_dict(prop_dictionary_t testcase)
395a563ca70SAlex Hornung {
396a563ca70SAlex Hornung prop_dictionary_t result_dict;
397a563ca70SAlex Hornung int r;
398a563ca70SAlex Hornung
399a563ca70SAlex Hornung result_dict = prop_dictionary_get(testcase, "result");
400a563ca70SAlex Hornung if (result_dict == NULL) {
401a563ca70SAlex Hornung result_dict = prop_dictionary_create();
402a563ca70SAlex Hornung if (result_dict == NULL)
403a563ca70SAlex Hornung err(1, "could not allocate new result dict");
404a563ca70SAlex Hornung
405a563ca70SAlex Hornung r = prop_dictionary_set(testcase, "result", result_dict);
406a563ca70SAlex Hornung if (r == 0)
407a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
408a563ca70SAlex Hornung }
409a563ca70SAlex Hornung
410a563ca70SAlex Hornung return result_dict;
411a563ca70SAlex Hornung }
412a563ca70SAlex Hornung
413a563ca70SAlex Hornung int
testcase_set_build_buf(prop_dictionary_t testcase,const char * buf)414a563ca70SAlex Hornung testcase_set_build_buf(prop_dictionary_t testcase, const char *buf)
415a563ca70SAlex Hornung {
416a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
417a563ca70SAlex Hornung
418a563ca70SAlex Hornung return !prop_dictionary_set_cstring(dict, "build_buf", buf);
419a563ca70SAlex Hornung }
420a563ca70SAlex Hornung
421a563ca70SAlex Hornung int
testcase_set_cleanup_buf(prop_dictionary_t testcase,const char * buf)422a563ca70SAlex Hornung testcase_set_cleanup_buf(prop_dictionary_t testcase, const char *buf)
423a563ca70SAlex Hornung {
424a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
425a563ca70SAlex Hornung
426a563ca70SAlex Hornung return !prop_dictionary_set_cstring(dict, "cleanup_buf", buf);
427a563ca70SAlex Hornung }
428a563ca70SAlex Hornung
429a563ca70SAlex Hornung int
testcase_set_sys_buf(prop_dictionary_t testcase,const char * buf)430a563ca70SAlex Hornung testcase_set_sys_buf(prop_dictionary_t testcase, const char *buf)
431a563ca70SAlex Hornung {
432a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
433a563ca70SAlex Hornung
434a563ca70SAlex Hornung return !prop_dictionary_set_cstring(dict, "sys_buf", buf);
435a563ca70SAlex Hornung }
436a563ca70SAlex Hornung
437a563ca70SAlex Hornung int
testcase_set_precmd_buf(prop_dictionary_t testcase,const char * buf)438a563ca70SAlex Hornung testcase_set_precmd_buf(prop_dictionary_t testcase, const char *buf)
439a563ca70SAlex Hornung {
440a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
441a563ca70SAlex Hornung
442a563ca70SAlex Hornung return !prop_dictionary_set_cstring(dict, "precmd_buf", buf);
443a563ca70SAlex Hornung }
444a563ca70SAlex Hornung
445a563ca70SAlex Hornung int
testcase_set_postcmd_buf(prop_dictionary_t testcase,const char * buf)446a563ca70SAlex Hornung testcase_set_postcmd_buf(prop_dictionary_t testcase, const char *buf)
447a563ca70SAlex Hornung {
448a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
449a563ca70SAlex Hornung
450a563ca70SAlex Hornung return !prop_dictionary_set_cstring(dict, "postcmd_buf", buf);
451a563ca70SAlex Hornung }
452a563ca70SAlex Hornung
453a563ca70SAlex Hornung int
testcase_set_stdout_buf(prop_dictionary_t testcase,const char * buf)454a563ca70SAlex Hornung testcase_set_stdout_buf(prop_dictionary_t testcase, const char *buf)
455a563ca70SAlex Hornung {
456a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
457a563ca70SAlex Hornung
458a563ca70SAlex Hornung return !prop_dictionary_set_cstring(dict, "stdout_buf", buf);
459a563ca70SAlex Hornung }
460a563ca70SAlex Hornung
461a563ca70SAlex Hornung int
testcase_set_stderr_buf(prop_dictionary_t testcase,const char * buf)462a563ca70SAlex Hornung testcase_set_stderr_buf(prop_dictionary_t testcase, const char *buf)
463a563ca70SAlex Hornung {
464a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
465a563ca70SAlex Hornung
466a563ca70SAlex Hornung return !prop_dictionary_set_cstring(dict, "stderr_buf", buf);
467a563ca70SAlex Hornung }
468a563ca70SAlex Hornung
469a563ca70SAlex Hornung int
testcase_set_result(prop_dictionary_t testcase,int result)470a563ca70SAlex Hornung testcase_set_result(prop_dictionary_t testcase, int result)
471a563ca70SAlex Hornung {
472a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
473a563ca70SAlex Hornung
474a563ca70SAlex Hornung return !prop_dictionary_set_int32(dict, "result", result);
475a563ca70SAlex Hornung }
476a563ca70SAlex Hornung
477a563ca70SAlex Hornung int
testcase_set_exit_value(prop_dictionary_t testcase,int exitval)478a563ca70SAlex Hornung testcase_set_exit_value(prop_dictionary_t testcase, int exitval)
479a563ca70SAlex Hornung {
480a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
481a563ca70SAlex Hornung
482a563ca70SAlex Hornung return !prop_dictionary_set_int32(dict, "exit_value", exitval);
483a563ca70SAlex Hornung }
484a563ca70SAlex Hornung
485a563ca70SAlex Hornung int
testcase_set_signal(prop_dictionary_t testcase,int sig)486a563ca70SAlex Hornung testcase_set_signal(prop_dictionary_t testcase, int sig)
487a563ca70SAlex Hornung {
488a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
489a563ca70SAlex Hornung
490a563ca70SAlex Hornung return !prop_dictionary_set_int32(dict, "signal", sig);
491a563ca70SAlex Hornung }
492a563ca70SAlex Hornung
493a563ca70SAlex Hornung const char *
testcase_get_build_buf(prop_dictionary_t testcase)494a563ca70SAlex Hornung testcase_get_build_buf(prop_dictionary_t testcase)
495a563ca70SAlex Hornung {
496a563ca70SAlex Hornung const char *str = "";
497a563ca70SAlex Hornung
498a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
499a563ca70SAlex Hornung prop_dictionary_get_cstring_nocopy(dict, "build_buf", &str);
500a563ca70SAlex Hornung
501a563ca70SAlex Hornung return str;
502a563ca70SAlex Hornung }
503a563ca70SAlex Hornung
504a563ca70SAlex Hornung const char *
testcase_get_cleanup_buf(prop_dictionary_t testcase)505a563ca70SAlex Hornung testcase_get_cleanup_buf(prop_dictionary_t testcase)
506a563ca70SAlex Hornung {
507a563ca70SAlex Hornung const char *str = "";
508a563ca70SAlex Hornung
509a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
510a563ca70SAlex Hornung prop_dictionary_get_cstring_nocopy(dict, "cleanup_buf", &str);
511a563ca70SAlex Hornung
512a563ca70SAlex Hornung return str;
513a563ca70SAlex Hornung }
514a563ca70SAlex Hornung
515a563ca70SAlex Hornung const char *
testcase_get_sys_buf(prop_dictionary_t testcase)516a563ca70SAlex Hornung testcase_get_sys_buf(prop_dictionary_t testcase)
517a563ca70SAlex Hornung {
518a563ca70SAlex Hornung const char *str = "";
519a563ca70SAlex Hornung
520a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
521a563ca70SAlex Hornung prop_dictionary_get_cstring_nocopy(dict, "sys_buf", &str);
522a563ca70SAlex Hornung
523a563ca70SAlex Hornung return str;
524a563ca70SAlex Hornung }
525a563ca70SAlex Hornung
526a563ca70SAlex Hornung const char *
testcase_get_precmd_buf(prop_dictionary_t testcase)527a563ca70SAlex Hornung testcase_get_precmd_buf(prop_dictionary_t testcase)
528a563ca70SAlex Hornung {
529a563ca70SAlex Hornung const char *str = "";
530a563ca70SAlex Hornung
531a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
532a563ca70SAlex Hornung prop_dictionary_get_cstring_nocopy(dict, "precmd_buf", &str);
533a563ca70SAlex Hornung
534a563ca70SAlex Hornung return str;
535a563ca70SAlex Hornung }
536a563ca70SAlex Hornung
537a563ca70SAlex Hornung const char *
testcase_get_postcmd_buf(prop_dictionary_t testcase)538a563ca70SAlex Hornung testcase_get_postcmd_buf(prop_dictionary_t testcase)
539a563ca70SAlex Hornung {
540a563ca70SAlex Hornung const char *str = "";
541a563ca70SAlex Hornung
542a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
543a563ca70SAlex Hornung prop_dictionary_get_cstring_nocopy(dict, "postcmd_buf", &str);
544a563ca70SAlex Hornung
545a563ca70SAlex Hornung return str;
546a563ca70SAlex Hornung }
547a563ca70SAlex Hornung
548a563ca70SAlex Hornung const char *
testcase_get_stdout_buf(prop_dictionary_t testcase)549a563ca70SAlex Hornung testcase_get_stdout_buf(prop_dictionary_t testcase)
550a563ca70SAlex Hornung {
551a563ca70SAlex Hornung const char *str = "";
552a563ca70SAlex Hornung
553a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
554a563ca70SAlex Hornung prop_dictionary_get_cstring_nocopy(dict, "stdout_buf", &str);
555a563ca70SAlex Hornung
556a563ca70SAlex Hornung return str;
557a563ca70SAlex Hornung }
558a563ca70SAlex Hornung
559a563ca70SAlex Hornung const char *
testcase_get_stderr_buf(prop_dictionary_t testcase)560a563ca70SAlex Hornung testcase_get_stderr_buf(prop_dictionary_t testcase)
561a563ca70SAlex Hornung {
562a563ca70SAlex Hornung const char *str = "";
563a563ca70SAlex Hornung
564a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
565a563ca70SAlex Hornung prop_dictionary_get_cstring_nocopy(dict, "stderr_buf", &str);
566a563ca70SAlex Hornung
567a563ca70SAlex Hornung return str;
568a563ca70SAlex Hornung }
569a563ca70SAlex Hornung
570a563ca70SAlex Hornung int
testcase_get_result(prop_dictionary_t testcase)571a563ca70SAlex Hornung testcase_get_result(prop_dictionary_t testcase)
572a563ca70SAlex Hornung {
573a563ca70SAlex Hornung int32_t result = RESULT_NOTRUN;
574a563ca70SAlex Hornung
575a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
576a563ca70SAlex Hornung prop_dictionary_get_int32(dict, "result", &result);
577a563ca70SAlex Hornung
578a563ca70SAlex Hornung return (int)result;
579a563ca70SAlex Hornung }
580a563ca70SAlex Hornung
581a563ca70SAlex Hornung const char *
testcase_get_result_desc(prop_dictionary_t testcase)582a563ca70SAlex Hornung testcase_get_result_desc(prop_dictionary_t testcase)
583a563ca70SAlex Hornung {
584a563ca70SAlex Hornung int result = testcase_get_result(testcase);
585a563ca70SAlex Hornung
586a563ca70SAlex Hornung switch(result) {
587a563ca70SAlex Hornung case RESULT_TIMEOUT: return "TIMEOUT";
588a563ca70SAlex Hornung case RESULT_SIGNALLED: return "SIGNALLED";
589a563ca70SAlex Hornung case RESULT_NOTRUN: return "NOT RUN";
590a563ca70SAlex Hornung case RESULT_FAIL: return "FAIL";
591a563ca70SAlex Hornung case RESULT_PASS: return "PASS";
592a563ca70SAlex Hornung case RESULT_PREFAIL: return "PREFAIL";
593a563ca70SAlex Hornung case RESULT_POSTFAIL: return "POSTFAIL";
594a563ca70SAlex Hornung case RESULT_BUILDFAIL: return "BUILDFAIL";
595a563ca70SAlex Hornung default: return "UNKNOWN";
596a563ca70SAlex Hornung }
597a563ca70SAlex Hornung }
598a563ca70SAlex Hornung
599a563ca70SAlex Hornung int
testcase_get_exit_value(prop_dictionary_t testcase)600a563ca70SAlex Hornung testcase_get_exit_value(prop_dictionary_t testcase)
601a563ca70SAlex Hornung {
602a563ca70SAlex Hornung int32_t exitval;
603a563ca70SAlex Hornung int r;
604a563ca70SAlex Hornung
605a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
606a563ca70SAlex Hornung r = prop_dictionary_get_int32(dict, "exit_value", &exitval);
607a563ca70SAlex Hornung if (r == 0)
608a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
609a563ca70SAlex Hornung
610a563ca70SAlex Hornung return (int)exitval;
611a563ca70SAlex Hornung }
612a563ca70SAlex Hornung
613a563ca70SAlex Hornung int
testcase_get_signal(prop_dictionary_t testcase)614a563ca70SAlex Hornung testcase_get_signal(prop_dictionary_t testcase)
615a563ca70SAlex Hornung {
616a563ca70SAlex Hornung int32_t sig;
617a563ca70SAlex Hornung int r;
618a563ca70SAlex Hornung
619a563ca70SAlex Hornung prop_dictionary_t dict = testcase_get_result_dict(testcase);
620a563ca70SAlex Hornung r = prop_dictionary_get_int32(dict, "signal", &sig);
621a563ca70SAlex Hornung if (r == 0)
622a563ca70SAlex Hornung err(1, "prop_dictionary operation failed");
623a563ca70SAlex Hornung
624a563ca70SAlex Hornung return (int)sig;
625a563ca70SAlex Hornung }
626a563ca70SAlex Hornung
627a563ca70SAlex Hornung int
parse_testcase_option(struct testcase_options * opts,char * option)628a563ca70SAlex Hornung parse_testcase_option(struct testcase_options *opts, char *option)
629a563ca70SAlex Hornung {
630a563ca70SAlex Hornung struct passwd *pwd;
631a563ca70SAlex Hornung char *parameter, *endptr;
632a563ca70SAlex Hornung long lval;
633a563ca70SAlex Hornung int noparam = 0;
634a563ca70SAlex Hornung
635a563ca70SAlex Hornung parameter = strchr(option, '=');
636a563ca70SAlex Hornung noparam = (parameter == NULL);
637a563ca70SAlex Hornung if (!noparam)
638a563ca70SAlex Hornung {
639a563ca70SAlex Hornung *parameter = '\0';
640a563ca70SAlex Hornung ++parameter;
641a563ca70SAlex Hornung }
642a563ca70SAlex Hornung
643a563ca70SAlex Hornung if (strcmp(option, "timeout") == 0) {
644a563ca70SAlex Hornung if (noparam)
645a563ca70SAlex Hornung syntax_error("The option 'timeout' needs a parameter");
646a563ca70SAlex Hornung /* NOTREACHED */
647a563ca70SAlex Hornung
648a563ca70SAlex Hornung lval = strtol(parameter, &endptr, 10);
649a563ca70SAlex Hornung if (*endptr != '\0')
650a563ca70SAlex Hornung syntax_error("The option 'timeout' expects an integer "
651a563ca70SAlex Hornung "parameter, not '%s'", parameter);
652a563ca70SAlex Hornung /* NOTREACHED */
653a563ca70SAlex Hornung
654a563ca70SAlex Hornung opts->timeout_in_secs = (long int)lval;
655*039caa27SAntonio Huete Jimenez } else if (strcmp(option, "rc") == 0) {
656*039caa27SAntonio Huete Jimenez if (noparam)
657*039caa27SAntonio Huete Jimenez syntax_error("The option 'timeout' needs a parameter");
658*039caa27SAntonio Huete Jimenez /* NOTREACHED */
659*039caa27SAntonio Huete Jimenez
660*039caa27SAntonio Huete Jimenez lval = strtol(parameter, &endptr, 10);
661*039caa27SAntonio Huete Jimenez if (*endptr != '\0')
662*039caa27SAntonio Huete Jimenez syntax_error("The option 'timeout' expects an integer "
663*039caa27SAntonio Huete Jimenez "parameter, not '%s'", parameter);
664*039caa27SAntonio Huete Jimenez /* NOTREACHED */
665*039caa27SAntonio Huete Jimenez
666*039caa27SAntonio Huete Jimenez opts->rc = (int)lval;
667a563ca70SAlex Hornung } else if (strcmp(option, "intpre") == 0) {
668a563ca70SAlex Hornung opts->flags |= TESTCASE_INT_PRE;
669a563ca70SAlex Hornung } else if (strcmp(option, "intpost") == 0) {
670a563ca70SAlex Hornung opts->flags |= TESTCASE_INT_POST;
671a563ca70SAlex Hornung } else if (strcmp(option, "pre") == 0) {
672a563ca70SAlex Hornung if (noparam)
673a563ca70SAlex Hornung syntax_error("The option 'pre' needs a parameter");
674a563ca70SAlex Hornung /* NOTREACHED */
675a563ca70SAlex Hornung
676a563ca70SAlex Hornung opts->flags |= TESTCASE_CUSTOM_PRE;
677a563ca70SAlex Hornung opts->pre_cmd = strdup(parameter);
678a563ca70SAlex Hornung } else if (strcmp(option, "post") == 0) {
679a563ca70SAlex Hornung if (noparam)
680a563ca70SAlex Hornung syntax_error("The option 'post' needs a parameter");
681a563ca70SAlex Hornung /* NOTREACHED */
682a563ca70SAlex Hornung
683a563ca70SAlex Hornung opts->flags |= TESTCASE_CUSTOM_POST;
684a563ca70SAlex Hornung opts->post_cmd = strdup(parameter);
685a563ca70SAlex Hornung } else if (strcmp(option, "runas") == 0) {
686a563ca70SAlex Hornung if (noparam)
687a563ca70SAlex Hornung syntax_error("The option 'runas' needs a parameter");
688a563ca70SAlex Hornung /* NOTREACHED */
689a563ca70SAlex Hornung
690a563ca70SAlex Hornung if ((pwd = getpwnam(parameter))) {
691a563ca70SAlex Hornung opts->runas_uid = pwd->pw_uid;
692a563ca70SAlex Hornung opts->flags |= TESTCASE_RUN_AS;
693a563ca70SAlex Hornung } else {
694a563ca70SAlex Hornung syntax_error("invalid user name for 'runas': %s",
695a563ca70SAlex Hornung parameter);
696a563ca70SAlex Hornung }
697a563ca70SAlex Hornung } else if (strcmp(option, "nobuild") == 0) {
698a563ca70SAlex Hornung opts->flags |= TESTCASE_NOBUILD;
6990d575305SAntonio Huete Jimenez } else if (strcmp(option, "interpreter") == 0) {
7000d575305SAntonio Huete Jimenez if (noparam)
7010d575305SAntonio Huete Jimenez syntax_error("The option 'interpreter' needs a parameter");
7020d575305SAntonio Huete Jimenez /* NOTREACHED */
7030d575305SAntonio Huete Jimenez opts->interpreter = strdup(parameter);
704a563ca70SAlex Hornung } else if (strcmp(option, "make") == 0) {
705a563ca70SAlex Hornung if (noparam)
706a563ca70SAlex Hornung syntax_error("The option 'make' needs a parameter");
707a563ca70SAlex Hornung /* NOTREACHED */
708a563ca70SAlex Hornung
709a563ca70SAlex Hornung opts->make_cmd = strdup(parameter);
710a563ca70SAlex Hornung } else if (strcmp(option, "defaults") == 0) {
711a563ca70SAlex Hornung /* Valid option, does nothing */
712a563ca70SAlex Hornung } else {
713a563ca70SAlex Hornung syntax_error("Unknown option: %s", option);
714a563ca70SAlex Hornung /* NOTREACHED */
715a563ca70SAlex Hornung }
716a563ca70SAlex Hornung
717a563ca70SAlex Hornung return 0;
718a563ca70SAlex Hornung }
719a563ca70SAlex Hornung
720a563ca70SAlex Hornung void
testcase_entry_parser(void * arg,char ** tokens)721a563ca70SAlex Hornung testcase_entry_parser(void *arg, char **tokens)
722a563ca70SAlex Hornung {
723a563ca70SAlex Hornung prop_array_t runlist;
724a563ca70SAlex Hornung prop_dictionary_t testcase_dict;
725a563ca70SAlex Hornung struct testcase *testcase;
726a563ca70SAlex Hornung char *options[256];
727a563ca70SAlex Hornung int i, r, nopts;
728a563ca70SAlex Hornung
729a563ca70SAlex Hornung runlist = (prop_array_t)arg;
730a563ca70SAlex Hornung
731a563ca70SAlex Hornung testcase = malloc(sizeof(struct testcase));
732a563ca70SAlex Hornung if (testcase == NULL)
733a563ca70SAlex Hornung err(1, "could not malloc testcase memory");
734a563ca70SAlex Hornung
735a563ca70SAlex Hornung bzero(testcase, sizeof(struct testcase));
736a563ca70SAlex Hornung
737a563ca70SAlex Hornung entry_check_num_args(tokens, 3);
738a563ca70SAlex Hornung
739a563ca70SAlex Hornung testcase->argv = &tokens[3];
740a563ca70SAlex Hornung for (testcase->argc = 0; testcase->argv[testcase->argc] != NULL;
741a563ca70SAlex Hornung testcase->argc++)
742a563ca70SAlex Hornung ;
743a563ca70SAlex Hornung
744a563ca70SAlex Hornung nopts = parse_options(tokens[2], options);
745a563ca70SAlex Hornung
746a563ca70SAlex Hornung testcase->name = tokens[0];
747a563ca70SAlex Hornung
748a563ca70SAlex Hornung if (strcmp(tokens[1], "userland") == 0) {
749a563ca70SAlex Hornung testcase->type = TESTCASE_TYPE_USERLAND;
750a563ca70SAlex Hornung } else if (strcmp(tokens[1], "kernel") == 0) {
751a563ca70SAlex Hornung testcase->type = TESTCASE_TYPE_KERNEL;
752a563ca70SAlex Hornung } else if (strcmp(tokens[1], "buildonly") == 0) {
753a563ca70SAlex Hornung testcase->type = TESTCASE_TYPE_BUILDONLY;
754a563ca70SAlex Hornung } else {
755a563ca70SAlex Hornung syntax_error("Unknown type: %s", tokens[1]);
756a563ca70SAlex Hornung /* NOTREACHED */
757a563ca70SAlex Hornung }
758a563ca70SAlex Hornung
759a563ca70SAlex Hornung testcase->type_str = tokens[1];
760a563ca70SAlex Hornung
761a563ca70SAlex Hornung config_get_defaults(&testcase->opts);
762a563ca70SAlex Hornung
763a563ca70SAlex Hornung for (i = 0; i < nopts; i++)
764a563ca70SAlex Hornung parse_testcase_option(&testcase->opts, options[i]);
765a563ca70SAlex Hornung
766a563ca70SAlex Hornung if ((testcase->type != TESTCASE_TYPE_USERLAND) &&
767a563ca70SAlex Hornung (testcase->opts.flags & (TESTCASE_INT_PRE | TESTCASE_INT_POST)))
768a563ca70SAlex Hornung syntax_error("'intpre' and 'intpost' options are only valid "
769a563ca70SAlex Hornung "with testcase type 'userland'");
770a563ca70SAlex Hornung
771a563ca70SAlex Hornung if ((testcase->type == TESTCASE_TYPE_BUILDONLY) &&
772a563ca70SAlex Hornung (testcase->opts.flags & TESTCASE_NOBUILD))
773a563ca70SAlex Hornung syntax_error("'nobuild' option is incompatible with type "
774a563ca70SAlex Hornung "'buildonly'");
775a563ca70SAlex Hornung
776a563ca70SAlex Hornung testcase_dict = testcase_from_struct(testcase);
777a563ca70SAlex Hornung if (testcase->opts.pre_cmd != NULL)
778a563ca70SAlex Hornung free(testcase->opts.pre_cmd);
779a563ca70SAlex Hornung if (testcase->opts.post_cmd != NULL)
780a563ca70SAlex Hornung free(testcase->opts.post_cmd);
7810d575305SAntonio Huete Jimenez if (testcase->opts.interpreter != NULL)
7820d575305SAntonio Huete Jimenez free(testcase->opts.interpreter);
783a563ca70SAlex Hornung if (testcase->opts.make_cmd != NULL)
784a563ca70SAlex Hornung free(testcase->opts.make_cmd);
785a563ca70SAlex Hornung free(testcase);
786a563ca70SAlex Hornung
787a563ca70SAlex Hornung r = prop_array_add(runlist, testcase_dict);
788a563ca70SAlex Hornung if (r == 0)
789a563ca70SAlex Hornung err(1, "prop_array_add failed");
790a563ca70SAlex Hornung }
791