Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/atf/atf-c/check_test.c
39536 views
1
/* Copyright (c) 2008 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 "atf-c/check.h"
27
28
#include <fcntl.h>
29
#include <signal.h>
30
#include <stdio.h>
31
#include <stdlib.h>
32
#include <string.h>
33
#include <unistd.h>
34
35
#include <atf-c.h>
36
37
#include "atf-c/detail/fs.h"
38
#include "atf-c/detail/map.h"
39
#include "atf-c/detail/process.h"
40
#include "atf-c/detail/test_helpers.h"
41
42
/* ---------------------------------------------------------------------
43
* Auxiliary functions.
44
* --------------------------------------------------------------------- */
45
46
static
47
void
48
do_exec(const atf_tc_t *tc, const char *helper_name, atf_check_result_t *r)
49
{
50
atf_fs_path_t process_helpers;
51
const char *argv[3];
52
53
get_process_helpers_path(tc, false, &process_helpers);
54
55
argv[0] = atf_fs_path_cstring(&process_helpers);
56
argv[1] = helper_name;
57
argv[2] = NULL;
58
printf("Executing %s %s\n", argv[0], argv[1]);
59
RE(atf_check_exec_array(argv, r));
60
61
atf_fs_path_fini(&process_helpers);
62
}
63
64
static
65
void
66
do_exec_with_arg(const atf_tc_t *tc, const char *helper_name, const char *arg,
67
atf_check_result_t *r)
68
{
69
atf_fs_path_t process_helpers;
70
const char *argv[4];
71
72
get_process_helpers_path(tc, false, &process_helpers);
73
74
argv[0] = atf_fs_path_cstring(&process_helpers);
75
argv[1] = helper_name;
76
argv[2] = arg;
77
argv[3] = NULL;
78
printf("Executing %s %s %s\n", argv[0], argv[1], argv[2]);
79
RE(atf_check_exec_array(argv, r));
80
81
atf_fs_path_fini(&process_helpers);
82
}
83
84
static
85
void
86
check_line(int fd, const char *exp)
87
{
88
char *line = atf_utils_readline(fd);
89
ATF_CHECK(line != NULL);
90
ATF_CHECK_STREQ_MSG(exp, line, "read: '%s', expected: '%s'", line, exp);
91
free(line);
92
}
93
94
/* ---------------------------------------------------------------------
95
* Helper test cases for the free functions.
96
* --------------------------------------------------------------------- */
97
98
ATF_TC(h_build_c_o_ok);
99
ATF_TC_HEAD(h_build_c_o_ok, tc)
100
{
101
atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
102
}
103
ATF_TC_BODY(h_build_c_o_ok, tc)
104
{
105
FILE *sfile;
106
bool success;
107
108
ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
109
fprintf(sfile, "#include <stdio.h>\n");
110
fclose(sfile);
111
112
RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
113
ATF_REQUIRE(success);
114
}
115
116
ATF_TC(h_build_c_o_fail);
117
ATF_TC_HEAD(h_build_c_o_fail, tc)
118
{
119
atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
120
}
121
ATF_TC_BODY(h_build_c_o_fail, tc)
122
{
123
FILE *sfile;
124
bool success;
125
126
ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
127
fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
128
fclose(sfile);
129
130
RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
131
ATF_REQUIRE(!success);
132
}
133
134
ATF_TC(h_build_cpp_ok);
135
ATF_TC_HEAD(h_build_cpp_ok, tc)
136
{
137
atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
138
}
139
ATF_TC_BODY(h_build_cpp_ok, tc)
140
{
141
FILE *sfile;
142
bool success;
143
atf_fs_path_t test_p;
144
145
RE(atf_fs_path_init_fmt(&test_p, "test.p"));
146
147
ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
148
fprintf(sfile, "#define A foo\n");
149
fprintf(sfile, "#define B bar\n");
150
fprintf(sfile, "A B\n");
151
fclose(sfile);
152
153
RE(atf_check_build_cpp("test.c", atf_fs_path_cstring(&test_p), NULL,
154
&success));
155
ATF_REQUIRE(success);
156
157
atf_fs_path_fini(&test_p);
158
}
159
160
ATF_TC(h_build_cpp_fail);
161
ATF_TC_HEAD(h_build_cpp_fail, tc)
162
{
163
atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
164
}
165
ATF_TC_BODY(h_build_cpp_fail, tc)
166
{
167
FILE *sfile;
168
bool success;
169
170
ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
171
fprintf(sfile, "#include \"./non-existent.h\"\n");
172
fclose(sfile);
173
174
RE(atf_check_build_cpp("test.c", "test.p", NULL, &success));
175
ATF_REQUIRE(!success);
176
}
177
178
ATF_TC(h_build_cxx_o_ok);
179
ATF_TC_HEAD(h_build_cxx_o_ok, tc)
180
{
181
atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
182
}
183
ATF_TC_BODY(h_build_cxx_o_ok, tc)
184
{
185
FILE *sfile;
186
bool success;
187
188
ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
189
fprintf(sfile, "#include <iostream>\n");
190
fclose(sfile);
191
192
RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
193
ATF_REQUIRE(success);
194
}
195
196
ATF_TC(h_build_cxx_o_fail);
197
ATF_TC_HEAD(h_build_cxx_o_fail, tc)
198
{
199
atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
200
}
201
ATF_TC_BODY(h_build_cxx_o_fail, tc)
202
{
203
FILE *sfile;
204
bool success;
205
206
ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
207
fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
208
fclose(sfile);
209
210
RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
211
ATF_REQUIRE(!success);
212
}
213
214
/* ---------------------------------------------------------------------
215
* Test cases for the free functions.
216
* --------------------------------------------------------------------- */
217
218
static
219
void
220
init_and_run_h_tc(atf_tc_t *tc, const atf_tc_pack_t *tcpack,
221
const char *outname, const char *errname)
222
{
223
const char *const config[] = { NULL };
224
225
RE(atf_tc_init_pack(tc, tcpack, config));
226
run_h_tc(tc, outname, errname, "result");
227
atf_tc_fini(tc);
228
}
229
230
ATF_TC(build_c_o);
231
ATF_TC_HEAD(build_c_o, tc)
232
{
233
atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_c_o "
234
"function");
235
}
236
ATF_TC_BODY(build_c_o, tc)
237
{
238
init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_ok),
239
&ATF_TC_PACK_NAME(h_build_c_o_ok), "stdout", "stderr");
240
ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
241
ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
242
243
init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_fail),
244
&ATF_TC_PACK_NAME(h_build_c_o_fail), "stdout", "stderr");
245
ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
246
ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
247
ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
248
ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
249
}
250
251
ATF_TC(build_cpp);
252
ATF_TC_HEAD(build_cpp, tc)
253
{
254
atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cpp "
255
"function");
256
}
257
ATF_TC_BODY(build_cpp, tc)
258
{
259
init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_ok),
260
&ATF_TC_PACK_NAME(h_build_cpp_ok), "stdout", "stderr");
261
ATF_CHECK(atf_utils_grep_file("-o.*test.p", "stdout"));
262
ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
263
ATF_CHECK(atf_utils_grep_file("foo bar", "test.p"));
264
265
init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_fail),
266
&ATF_TC_PACK_NAME(h_build_cpp_fail), "stdout", "stderr");
267
ATF_CHECK(atf_utils_grep_file("-o test.p", "stdout"));
268
ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
269
ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
270
ATF_CHECK(atf_utils_grep_file("non-existent.h", "stderr"));
271
}
272
273
ATF_TC(build_cxx_o);
274
ATF_TC_HEAD(build_cxx_o, tc)
275
{
276
atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cxx_o "
277
"function");
278
}
279
ATF_TC_BODY(build_cxx_o, tc)
280
{
281
init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_ok),
282
&ATF_TC_PACK_NAME(h_build_cxx_o_ok), "stdout", "stderr");
283
ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
284
ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
285
286
init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_fail),
287
&ATF_TC_PACK_NAME(h_build_cxx_o_fail), "stdout", "stderr");
288
ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
289
ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
290
ATF_CHECK(atf_utils_grep_file("test.cpp", "stderr"));
291
ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
292
}
293
294
ATF_TC(exec_array);
295
ATF_TC_HEAD(exec_array, tc)
296
{
297
atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
298
"works properly");
299
}
300
ATF_TC_BODY(exec_array, tc)
301
{
302
atf_fs_path_t process_helpers;
303
atf_check_result_t result;
304
305
get_process_helpers_path(tc, false, &process_helpers);
306
307
const char *argv[4];
308
argv[0] = atf_fs_path_cstring(&process_helpers);
309
argv[1] = "echo";
310
argv[2] = "test-message";
311
argv[3] = NULL;
312
313
RE(atf_check_exec_array(argv, &result));
314
315
ATF_CHECK(atf_check_result_exited(&result));
316
ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
317
318
{
319
const char *path = atf_check_result_stdout(&result);
320
int fd = open(path, O_RDONLY);
321
ATF_CHECK(fd != -1);
322
check_line(fd, "test-message");
323
close(fd);
324
}
325
326
atf_check_result_fini(&result);
327
atf_fs_path_fini(&process_helpers);
328
}
329
330
ATF_TC(exec_cleanup);
331
ATF_TC_HEAD(exec_cleanup, tc)
332
{
333
atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
334
"properly cleans up the temporary files it creates");
335
}
336
ATF_TC_BODY(exec_cleanup, tc)
337
{
338
atf_fs_path_t out, err;
339
atf_check_result_t result;
340
bool exists;
341
342
do_exec(tc, "exit-success", &result);
343
RE(atf_fs_path_init_fmt(&out, "%s", atf_check_result_stdout(&result)));
344
RE(atf_fs_path_init_fmt(&err, "%s", atf_check_result_stderr(&result)));
345
346
RE(atf_fs_exists(&out, &exists)); ATF_CHECK(exists);
347
RE(atf_fs_exists(&err, &exists)); ATF_CHECK(exists);
348
atf_check_result_fini(&result);
349
RE(atf_fs_exists(&out, &exists)); ATF_CHECK(!exists);
350
RE(atf_fs_exists(&err, &exists)); ATF_CHECK(!exists);
351
352
atf_fs_path_fini(&err);
353
atf_fs_path_fini(&out);
354
}
355
356
ATF_TC(exec_exitstatus);
357
ATF_TC_HEAD(exec_exitstatus, tc)
358
{
359
atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
360
"properly captures the exit status of the executed "
361
"command");
362
}
363
ATF_TC_BODY(exec_exitstatus, tc)
364
{
365
{
366
atf_check_result_t result;
367
do_exec(tc, "exit-success", &result);
368
ATF_CHECK(atf_check_result_exited(&result));
369
ATF_CHECK(!atf_check_result_signaled(&result));
370
ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
371
atf_check_result_fini(&result);
372
}
373
374
{
375
atf_check_result_t result;
376
do_exec(tc, "exit-failure", &result);
377
ATF_CHECK(atf_check_result_exited(&result));
378
ATF_CHECK(!atf_check_result_signaled(&result));
379
ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_FAILURE);
380
atf_check_result_fini(&result);
381
}
382
383
{
384
atf_check_result_t result;
385
do_exec(tc, "exit-signal", &result);
386
ATF_CHECK(!atf_check_result_exited(&result));
387
ATF_CHECK(atf_check_result_signaled(&result));
388
ATF_CHECK(atf_check_result_termsig(&result) == SIGKILL);
389
atf_check_result_fini(&result);
390
}
391
}
392
393
ATF_TC(exec_stdout_stderr);
394
ATF_TC_HEAD(exec_stdout_stderr, tc)
395
{
396
atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
397
"properly captures the stdout and stderr streams "
398
"of the child process");
399
}
400
ATF_TC_BODY(exec_stdout_stderr, tc)
401
{
402
atf_check_result_t result1, result2;
403
const char *out1, *out2;
404
const char *err1, *err2;
405
406
do_exec_with_arg(tc, "stdout-stderr", "result1", &result1);
407
ATF_CHECK(atf_check_result_exited(&result1));
408
ATF_CHECK(atf_check_result_exitcode(&result1) == EXIT_SUCCESS);
409
410
do_exec_with_arg(tc, "stdout-stderr", "result2", &result2);
411
ATF_CHECK(atf_check_result_exited(&result2));
412
ATF_CHECK(atf_check_result_exitcode(&result2) == EXIT_SUCCESS);
413
414
out1 = atf_check_result_stdout(&result1);
415
out2 = atf_check_result_stdout(&result2);
416
err1 = atf_check_result_stderr(&result1);
417
err2 = atf_check_result_stderr(&result2);
418
419
ATF_CHECK(strstr(out1, "check.XXXXXX") == NULL);
420
ATF_CHECK(strstr(out2, "check.XXXXXX") == NULL);
421
ATF_CHECK(strstr(err1, "check.XXXXXX") == NULL);
422
ATF_CHECK(strstr(err2, "check.XXXXXX") == NULL);
423
424
ATF_CHECK(strstr(out1, "/check") != NULL);
425
ATF_CHECK(strstr(out2, "/check") != NULL);
426
ATF_CHECK(strstr(err1, "/check") != NULL);
427
ATF_CHECK(strstr(err2, "/check") != NULL);
428
429
ATF_CHECK(strstr(out1, "/stdout") != NULL);
430
ATF_CHECK(strstr(out2, "/stdout") != NULL);
431
ATF_CHECK(strstr(err1, "/stderr") != NULL);
432
ATF_CHECK(strstr(err2, "/stderr") != NULL);
433
434
ATF_CHECK(strcmp(out1, out2) != 0);
435
ATF_CHECK(strcmp(err1, err2) != 0);
436
437
#define CHECK_LINES(path, outname, resname) \
438
do { \
439
int fd = open(path, O_RDONLY); \
440
ATF_CHECK(fd != -1); \
441
check_line(fd, "Line 1 to " outname " for " resname); \
442
check_line(fd, "Line 2 to " outname " for " resname); \
443
close(fd); \
444
} while (false)
445
446
CHECK_LINES(out1, "stdout", "result1");
447
CHECK_LINES(out2, "stdout", "result2");
448
CHECK_LINES(err1, "stderr", "result1");
449
CHECK_LINES(err2, "stderr", "result2");
450
451
#undef CHECK_LINES
452
453
atf_check_result_fini(&result2);
454
atf_check_result_fini(&result1);
455
}
456
457
ATF_TC(exec_umask);
458
ATF_TC_HEAD(exec_umask, tc)
459
{
460
atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
461
"works regardless of umask");
462
}
463
ATF_TC_BODY(exec_umask, tc)
464
{
465
atf_check_result_t result;
466
atf_fs_path_t process_helpers;
467
const char *argv[3];
468
469
get_process_helpers_path(tc, false, &process_helpers);
470
argv[0] = atf_fs_path_cstring(&process_helpers);
471
argv[1] = "exit-success";
472
argv[2] = NULL;
473
474
umask(0222);
475
RE(atf_check_exec_array(argv, &result));
476
477
atf_fs_path_fini(&process_helpers);
478
}
479
480
ATF_TC(exec_unknown);
481
ATF_TC_HEAD(exec_unknown, tc)
482
{
483
atf_tc_set_md_var(tc, "descr", "Checks that running a non-existing "
484
"binary is handled correctly");
485
}
486
ATF_TC_BODY(exec_unknown, tc)
487
{
488
const char *argv[2];
489
argv[0] = "/foo/bar/non-existent";
490
argv[1] = NULL;
491
492
atf_check_result_t result;
493
RE(atf_check_exec_array(argv, &result));
494
ATF_CHECK(atf_check_result_exited(&result));
495
ATF_CHECK(atf_check_result_exitcode(&result) == 127);
496
atf_check_result_fini(&result);
497
}
498
499
/* ---------------------------------------------------------------------
500
* Main.
501
* --------------------------------------------------------------------- */
502
503
ATF_TP_ADD_TCS(tp)
504
{
505
/* Add the test cases for the free functions. */
506
ATF_TP_ADD_TC(tp, build_c_o);
507
ATF_TP_ADD_TC(tp, build_cpp);
508
ATF_TP_ADD_TC(tp, build_cxx_o);
509
ATF_TP_ADD_TC(tp, exec_array);
510
ATF_TP_ADD_TC(tp, exec_cleanup);
511
ATF_TP_ADD_TC(tp, exec_exitstatus);
512
ATF_TP_ADD_TC(tp, exec_stdout_stderr);
513
ATF_TP_ADD_TC(tp, exec_umask);
514
ATF_TP_ADD_TC(tp, exec_unknown);
515
516
return atf_no_error();
517
}
518
519