c_helpers.c revision 275988
1/* Copyright (c) 2007 The NetBSD Foundation, Inc.
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */
25
26#include <sys/types.h>
27#include <sys/wait.h>
28#include <fcntl.h>
29#include <unistd.h>
30
31#include <signal.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include <atf-c.h>
37
38#include "atf-c/detail/env.h"
39#include "atf-c/detail/fs.h"
40#include "atf-c/detail/test_helpers.h"
41#include "atf-c/detail/text.h"
42#include "atf-c/error.h"
43
44/* ---------------------------------------------------------------------
45 * Auxiliary functions.
46 * --------------------------------------------------------------------- */
47
48static
49void
50safe_remove(const char* path)
51{
52    if (unlink(path) == -1)
53        atf_tc_fail("unlink(2) of %s failed", path);
54}
55
56static
57void
58touch(const char *path)
59{
60    int fd;
61    fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0644);
62    if (fd == -1)
63        atf_tc_fail("Could not create file %s", path);
64    close(fd);
65}
66
67/* ---------------------------------------------------------------------
68 * Helper tests for "t_cleanup".
69 * --------------------------------------------------------------------- */
70
71ATF_TC_WITH_CLEANUP(cleanup_pass);
72ATF_TC_HEAD(cleanup_pass, tc)
73{
74    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
75               "program");
76}
77ATF_TC_BODY(cleanup_pass, tc)
78{
79    touch(atf_tc_get_config_var(tc, "tmpfile"));
80}
81ATF_TC_CLEANUP(cleanup_pass, tc)
82{
83    if (atf_tc_get_config_var_as_bool(tc, "cleanup"))
84        safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
85}
86
87ATF_TC_WITH_CLEANUP(cleanup_fail);
88ATF_TC_HEAD(cleanup_fail, tc)
89{
90    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
91                      "program");
92}
93ATF_TC_BODY(cleanup_fail, tc)
94{
95    touch(atf_tc_get_config_var(tc, "tmpfile"));
96    atf_tc_fail("On purpose");
97}
98ATF_TC_CLEANUP(cleanup_fail, tc)
99{
100    if (atf_tc_get_config_var_as_bool(tc, "cleanup"))
101        safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
102}
103
104ATF_TC_WITH_CLEANUP(cleanup_skip);
105ATF_TC_HEAD(cleanup_skip, tc)
106{
107    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
108                      "program");
109}
110ATF_TC_BODY(cleanup_skip, tc)
111{
112    touch(atf_tc_get_config_var(tc, "tmpfile"));
113    atf_tc_skip("On purpose");
114}
115ATF_TC_CLEANUP(cleanup_skip, tc)
116{
117    if (atf_tc_get_config_var_as_bool(tc, "cleanup"))
118        safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
119}
120
121ATF_TC_WITH_CLEANUP(cleanup_curdir);
122ATF_TC_HEAD(cleanup_curdir, tc)
123{
124    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
125                      "program");
126}
127ATF_TC_BODY(cleanup_curdir, tc)
128{
129    FILE *f;
130
131    f = fopen("oldvalue", "w");
132    if (f == NULL)
133        atf_tc_fail("Failed to create oldvalue file");
134    fprintf(f, "1234");
135    fclose(f);
136}
137ATF_TC_CLEANUP(cleanup_curdir, tc)
138{
139    FILE *f;
140
141    f = fopen("oldvalue", "r");
142    if (f != NULL) {
143        int i;
144        if (fscanf(f, "%d", &i) != 1)
145            fprintf(stderr, "Failed to read old value\n");
146        else
147            printf("Old value: %d", i);
148        fclose(f);
149    }
150}
151
152ATF_TC_WITH_CLEANUP(cleanup_sigterm);
153ATF_TC_HEAD(cleanup_sigterm, tc)
154{
155    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
156                      "program");
157}
158ATF_TC_BODY(cleanup_sigterm, tc)
159{
160    char *nofile;
161
162    touch(atf_tc_get_config_var(tc, "tmpfile"));
163    kill(getpid(), SIGTERM);
164
165    RE(atf_text_format(&nofile, "%s.no",
166                       atf_tc_get_config_var(tc, "tmpfile")));
167    touch(nofile);
168    free(nofile);
169}
170ATF_TC_CLEANUP(cleanup_sigterm, tc)
171{
172    safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
173}
174
175/* ---------------------------------------------------------------------
176 * Helper tests for "t_config".
177 * --------------------------------------------------------------------- */
178
179ATF_TC(config_unset);
180ATF_TC_HEAD(config_unset, tc)
181{
182    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
183                      "program");
184}
185ATF_TC_BODY(config_unset, tc)
186{
187    ATF_REQUIRE(!atf_tc_has_config_var(tc, "test"));
188}
189
190ATF_TC(config_empty);
191ATF_TC_HEAD(config_empty, tc)
192{
193    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
194                      "program");
195}
196ATF_TC_BODY(config_empty, tc)
197{
198    ATF_REQUIRE(atf_tc_has_config_var(tc, "test"));
199    ATF_REQUIRE(strlen(atf_tc_get_config_var(tc, "test")) == 0);
200}
201
202ATF_TC(config_value);
203ATF_TC_HEAD(config_value, tc)
204{
205    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
206                      "program");
207}
208ATF_TC_BODY(config_value, tc)
209{
210    ATF_REQUIRE(atf_tc_has_config_var(tc, "test"));
211    ATF_REQUIRE(strcmp(atf_tc_get_config_var(tc, "test"), "foo") == 0);
212}
213
214ATF_TC(config_multi_value);
215ATF_TC_HEAD(config_multi_value, tc)
216{
217    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
218                      "program");
219}
220ATF_TC_BODY(config_multi_value, tc)
221{
222    ATF_REQUIRE(atf_tc_has_config_var(tc, "test"));
223    ATF_REQUIRE(strcmp(atf_tc_get_config_var(tc, "test"), "foo bar") == 0);
224}
225
226/* ---------------------------------------------------------------------
227 * Helper tests for "t_expect".
228 * --------------------------------------------------------------------- */
229
230ATF_TC_WITHOUT_HEAD(expect_pass_and_pass);
231ATF_TC_BODY(expect_pass_and_pass, tc)
232{
233    atf_tc_expect_pass();
234
235}
236
237ATF_TC_WITHOUT_HEAD(expect_pass_but_fail_requirement);
238ATF_TC_BODY(expect_pass_but_fail_requirement, tc)
239{
240    atf_tc_expect_pass();
241    atf_tc_fail("Some reason");
242}
243
244ATF_TC_WITHOUT_HEAD(expect_pass_but_fail_check);
245ATF_TC_BODY(expect_pass_but_fail_check, tc)
246{
247    atf_tc_expect_pass();
248    atf_tc_fail_nonfatal("Some reason");
249}
250
251ATF_TC_WITHOUT_HEAD(expect_fail_and_fail_requirement);
252ATF_TC_BODY(expect_fail_and_fail_requirement, tc)
253{
254    atf_tc_expect_fail("Fail %s", "reason");
255    atf_tc_fail("The failure");
256    atf_tc_expect_pass();
257}
258
259ATF_TC_WITHOUT_HEAD(expect_fail_and_fail_check);
260ATF_TC_BODY(expect_fail_and_fail_check, tc)
261{
262    atf_tc_expect_fail("Fail first");
263    atf_tc_fail_nonfatal("abc");
264    atf_tc_expect_pass();
265
266    atf_tc_expect_fail("And fail again");
267    atf_tc_fail_nonfatal("def");
268    atf_tc_expect_pass();
269}
270
271ATF_TC_WITHOUT_HEAD(expect_fail_but_pass);
272ATF_TC_BODY(expect_fail_but_pass, tc)
273{
274    atf_tc_expect_fail("Fail first");
275    atf_tc_fail_nonfatal("abc");
276    atf_tc_expect_pass();
277
278    atf_tc_expect_fail("Will not fail");
279    atf_tc_expect_pass();
280
281    atf_tc_expect_fail("And fail again");
282    atf_tc_fail_nonfatal("def");
283    atf_tc_expect_pass();
284}
285
286ATF_TC_WITHOUT_HEAD(expect_exit_any_and_exit);
287ATF_TC_BODY(expect_exit_any_and_exit, tc)
288{
289    atf_tc_expect_exit(-1, "Call will exit");
290    exit(EXIT_SUCCESS);
291}
292
293ATF_TC_WITHOUT_HEAD(expect_exit_code_and_exit);
294ATF_TC_BODY(expect_exit_code_and_exit, tc)
295{
296    atf_tc_expect_exit(123, "Call will exit");
297    exit(123);
298}
299
300ATF_TC_WITHOUT_HEAD(expect_exit_but_pass);
301ATF_TC_BODY(expect_exit_but_pass, tc)
302{
303    atf_tc_expect_exit(-1, "Call won't exit");
304}
305
306ATF_TC_WITHOUT_HEAD(expect_signal_any_and_signal);
307ATF_TC_BODY(expect_signal_any_and_signal, tc)
308{
309    atf_tc_expect_signal(-1, "Call will signal");
310    kill(getpid(), SIGKILL);
311}
312
313ATF_TC_WITHOUT_HEAD(expect_signal_no_and_signal);
314ATF_TC_BODY(expect_signal_no_and_signal, tc)
315{
316    atf_tc_expect_signal(SIGHUP, "Call will signal");
317    kill(getpid(), SIGHUP);
318}
319
320ATF_TC_WITHOUT_HEAD(expect_signal_but_pass);
321ATF_TC_BODY(expect_signal_but_pass, tc)
322{
323    atf_tc_expect_signal(-1, "Call won't signal");
324}
325
326ATF_TC_WITHOUT_HEAD(expect_death_and_exit);
327ATF_TC_BODY(expect_death_and_exit, tc)
328{
329    atf_tc_expect_death("Exit case");
330    exit(123);
331}
332
333ATF_TC_WITHOUT_HEAD(expect_death_and_signal);
334ATF_TC_BODY(expect_death_and_signal, tc)
335{
336    atf_tc_expect_death("Signal case");
337    kill(getpid(), SIGKILL);
338}
339
340ATF_TC_WITHOUT_HEAD(expect_death_but_pass);
341ATF_TC_BODY(expect_death_but_pass, tc)
342{
343    atf_tc_expect_death("Call won't die");
344}
345
346ATF_TC(expect_timeout_and_hang);
347ATF_TC_HEAD(expect_timeout_and_hang, tc)
348{
349    atf_tc_set_md_var(tc, "timeout", "1");
350}
351ATF_TC_BODY(expect_timeout_and_hang, tc)
352{
353    atf_tc_expect_timeout("Will overrun");
354    sleep(5);
355}
356
357ATF_TC(expect_timeout_but_pass);
358ATF_TC_HEAD(expect_timeout_but_pass, tc)
359{
360    atf_tc_set_md_var(tc, "timeout", "1");
361}
362ATF_TC_BODY(expect_timeout_but_pass, tc)
363{
364    atf_tc_expect_timeout("Will just exit");
365}
366
367/* ---------------------------------------------------------------------
368 * Helper tests for "t_meta_data".
369 * --------------------------------------------------------------------- */
370
371ATF_TC_WITHOUT_HEAD(metadata_no_descr);
372ATF_TC_BODY(metadata_no_descr, tc)
373{
374}
375
376ATF_TC_WITHOUT_HEAD(metadata_no_head);
377ATF_TC_BODY(metadata_no_head, tc)
378{
379}
380
381/* ---------------------------------------------------------------------
382 * Helper tests for "t_srcdir".
383 * --------------------------------------------------------------------- */
384
385ATF_TC(srcdir_exists);
386ATF_TC_HEAD(srcdir_exists, tc)
387{
388    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_srcdir test "
389                      "program");
390}
391ATF_TC_BODY(srcdir_exists, tc)
392{
393    atf_fs_path_t p;
394    bool b;
395
396    RE(atf_fs_path_init_fmt(&p, "%s/datafile",
397                            atf_tc_get_config_var(tc, "srcdir")));
398    RE(atf_fs_exists(&p, &b));
399    atf_fs_path_fini(&p);
400    if (!b)
401        atf_tc_fail("Cannot find datafile");
402}
403
404/* ---------------------------------------------------------------------
405 * Helper tests for "t_result".
406 * --------------------------------------------------------------------- */
407
408ATF_TC_WITHOUT_HEAD(result_pass);
409ATF_TC_BODY(result_pass, tc)
410{
411    printf("msg\n");
412}
413
414ATF_TC_WITHOUT_HEAD(result_fail);
415ATF_TC_BODY(result_fail, tc)
416{
417    printf("msg\n");
418    atf_tc_fail("Failure reason");
419}
420
421ATF_TC_WITHOUT_HEAD(result_skip);
422ATF_TC_BODY(result_skip, tc)
423{
424    printf("msg\n");
425    atf_tc_skip("Skipped reason");
426}
427
428ATF_TC(result_newlines_fail);
429ATF_TC_HEAD(result_newlines_fail, tc)
430{
431    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_result test "
432                      "program");
433}
434ATF_TC_BODY(result_newlines_fail, tc)
435{
436    atf_tc_fail("First line\nSecond line");
437}
438
439ATF_TC(result_newlines_skip);
440ATF_TC_HEAD(result_newlines_skip, tc)
441{
442    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_result test "
443                      "program");
444}
445ATF_TC_BODY(result_newlines_skip, tc)
446{
447    atf_tc_skip("First line\nSecond line");
448}
449
450/* ---------------------------------------------------------------------
451 * Main.
452 * --------------------------------------------------------------------- */
453
454ATF_TP_ADD_TCS(tp)
455{
456    /* Add helper tests for t_cleanup. */
457    ATF_TP_ADD_TC(tp, cleanup_pass);
458    ATF_TP_ADD_TC(tp, cleanup_fail);
459    ATF_TP_ADD_TC(tp, cleanup_skip);
460    ATF_TP_ADD_TC(tp, cleanup_curdir);
461    ATF_TP_ADD_TC(tp, cleanup_sigterm);
462
463    /* Add helper tests for t_config. */
464    ATF_TP_ADD_TC(tp, config_unset);
465    ATF_TP_ADD_TC(tp, config_empty);
466    ATF_TP_ADD_TC(tp, config_value);
467    ATF_TP_ADD_TC(tp, config_multi_value);
468
469    /* Add helper tests for t_expect. */
470    ATF_TP_ADD_TC(tp, expect_pass_and_pass);
471    ATF_TP_ADD_TC(tp, expect_pass_but_fail_requirement);
472    ATF_TP_ADD_TC(tp, expect_pass_but_fail_check);
473    ATF_TP_ADD_TC(tp, expect_fail_and_fail_requirement);
474    ATF_TP_ADD_TC(tp, expect_fail_and_fail_check);
475    ATF_TP_ADD_TC(tp, expect_fail_but_pass);
476    ATF_TP_ADD_TC(tp, expect_exit_any_and_exit);
477    ATF_TP_ADD_TC(tp, expect_exit_code_and_exit);
478    ATF_TP_ADD_TC(tp, expect_exit_but_pass);
479    ATF_TP_ADD_TC(tp, expect_signal_any_and_signal);
480    ATF_TP_ADD_TC(tp, expect_signal_no_and_signal);
481    ATF_TP_ADD_TC(tp, expect_signal_but_pass);
482    ATF_TP_ADD_TC(tp, expect_death_and_exit);
483    ATF_TP_ADD_TC(tp, expect_death_and_signal);
484    ATF_TP_ADD_TC(tp, expect_death_but_pass);
485    ATF_TP_ADD_TC(tp, expect_timeout_and_hang);
486    ATF_TP_ADD_TC(tp, expect_timeout_but_pass);
487
488    /* Add helper tests for t_meta_data. */
489    ATF_TP_ADD_TC(tp, metadata_no_descr);
490    ATF_TP_ADD_TC(tp, metadata_no_head);
491
492    /* Add helper tests for t_srcdir. */
493    ATF_TP_ADD_TC(tp, srcdir_exists);
494
495    /* Add helper tests for t_result. */
496    ATF_TP_ADD_TC(tp, result_pass);
497    ATF_TP_ADD_TC(tp, result_fail);
498    ATF_TP_ADD_TC(tp, result_skip);
499    ATF_TP_ADD_TC(tp, result_newlines_fail);
500    ATF_TP_ADD_TC(tp, result_newlines_skip);
501
502    return atf_no_error();
503}
504