Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/atf/atf-c++/check_test.cpp
39507 views
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 "atf-c++/check.hpp"
27
28
extern "C" {
29
#include <fcntl.h>
30
#include <signal.h>
31
#include <unistd.h>
32
}
33
34
#include <cstdlib>
35
#include <cstring>
36
#include <fstream>
37
#include <iostream>
38
#include <list>
39
#include <memory>
40
#include <vector>
41
42
#include <atf-c++.hpp>
43
44
#include "atf-c++/detail/fs.hpp"
45
#include "atf-c++/detail/process.hpp"
46
#include "atf-c++/detail/test_helpers.hpp"
47
#include "atf-c++/detail/text.hpp"
48
#include "atf-c++/utils.hpp"
49
50
// ------------------------------------------------------------------------
51
// Auxiliary functions.
52
// ------------------------------------------------------------------------
53
54
static
55
std::unique_ptr< atf::check::check_result >
56
do_exec(const atf::tests::tc* tc, const char* helper_name)
57
{
58
std::vector< std::string > argv;
59
argv.push_back(get_process_helpers_path(*tc, false).str());
60
argv.push_back(helper_name);
61
std::cout << "Executing " << argv[0] << " " << argv[1] << "\n";
62
63
atf::process::argv_array argva(argv);
64
return atf::check::exec(argva);
65
}
66
67
static
68
std::unique_ptr< atf::check::check_result >
69
do_exec(const atf::tests::tc* tc, const char* helper_name, const char *carg2)
70
{
71
std::vector< std::string > argv;
72
argv.push_back(get_process_helpers_path(*tc, false).str());
73
argv.push_back(helper_name);
74
argv.push_back(carg2);
75
std::cout << "Executing " << argv[0] << " " << argv[1] << " "
76
<< argv[2] << "\n";
77
78
atf::process::argv_array argva(argv);
79
return atf::check::exec(argva);
80
}
81
82
// ------------------------------------------------------------------------
83
// Helper test cases for the free functions.
84
// ------------------------------------------------------------------------
85
86
ATF_TEST_CASE(h_build_c_o_ok);
87
ATF_TEST_CASE_HEAD(h_build_c_o_ok)
88
{
89
set_md_var("descr", "Helper test case for build_c_o");
90
}
91
ATF_TEST_CASE_BODY(h_build_c_o_ok)
92
{
93
std::ofstream sfile("test.c");
94
sfile << "#include <stdio.h>\n";
95
sfile.close();
96
97
ATF_REQUIRE(atf::check::build_c_o("test.c", "test.o",
98
atf::process::argv_array()));
99
}
100
101
ATF_TEST_CASE(h_build_c_o_fail);
102
ATF_TEST_CASE_HEAD(h_build_c_o_fail)
103
{
104
set_md_var("descr", "Helper test case for build_c_o");
105
}
106
ATF_TEST_CASE_BODY(h_build_c_o_fail)
107
{
108
std::ofstream sfile("test.c");
109
sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
110
sfile.close();
111
112
ATF_REQUIRE(!atf::check::build_c_o("test.c", "test.o",
113
atf::process::argv_array()));
114
}
115
116
ATF_TEST_CASE(h_build_cpp_ok);
117
ATF_TEST_CASE_HEAD(h_build_cpp_ok)
118
{
119
set_md_var("descr", "Helper test case for build_cpp");
120
}
121
ATF_TEST_CASE_BODY(h_build_cpp_ok)
122
{
123
std::ofstream sfile("test.c");
124
sfile << "#define A foo\n";
125
sfile << "#define B bar\n";
126
sfile << "A B\n";
127
sfile.close();
128
129
ATF_REQUIRE(atf::check::build_cpp("test.c", "test.p",
130
atf::process::argv_array()));
131
}
132
133
ATF_TEST_CASE(h_build_cpp_fail);
134
ATF_TEST_CASE_HEAD(h_build_cpp_fail)
135
{
136
set_md_var("descr", "Helper test case for build_cpp");
137
}
138
ATF_TEST_CASE_BODY(h_build_cpp_fail)
139
{
140
std::ofstream sfile("test.c");
141
sfile << "#include \"./non-existent.h\"\n";
142
sfile.close();
143
144
ATF_REQUIRE(!atf::check::build_cpp("test.c", "test.p",
145
atf::process::argv_array()));
146
}
147
148
ATF_TEST_CASE(h_build_cxx_o_ok);
149
ATF_TEST_CASE_HEAD(h_build_cxx_o_ok)
150
{
151
set_md_var("descr", "Helper test case for build_cxx_o");
152
}
153
ATF_TEST_CASE_BODY(h_build_cxx_o_ok)
154
{
155
std::ofstream sfile("test.cpp");
156
sfile << "#include <iostream>\n";
157
sfile.close();
158
159
ATF_REQUIRE(atf::check::build_cxx_o("test.cpp", "test.o",
160
atf::process::argv_array()));
161
}
162
163
ATF_TEST_CASE(h_build_cxx_o_fail);
164
ATF_TEST_CASE_HEAD(h_build_cxx_o_fail)
165
{
166
set_md_var("descr", "Helper test case for build_cxx_o");
167
}
168
ATF_TEST_CASE_BODY(h_build_cxx_o_fail)
169
{
170
std::ofstream sfile("test.cpp");
171
sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
172
sfile.close();
173
174
ATF_REQUIRE(!atf::check::build_cxx_o("test.cpp", "test.o",
175
atf::process::argv_array()));
176
}
177
178
// ------------------------------------------------------------------------
179
// Test cases for the free functions.
180
// ------------------------------------------------------------------------
181
182
ATF_TEST_CASE(build_c_o);
183
ATF_TEST_CASE_HEAD(build_c_o)
184
{
185
set_md_var("descr", "Tests the build_c_o function");
186
}
187
ATF_TEST_CASE_BODY(build_c_o)
188
{
189
ATF_TEST_CASE_USE(h_build_c_o_ok);
190
run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_ok) >();
191
ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
192
ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
193
194
ATF_TEST_CASE_USE(h_build_c_o_fail);
195
run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_fail) >();
196
ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
197
ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
198
ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
199
ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
200
}
201
202
ATF_TEST_CASE(build_cpp);
203
ATF_TEST_CASE_HEAD(build_cpp)
204
{
205
set_md_var("descr", "Tests the build_cpp function");
206
}
207
ATF_TEST_CASE_BODY(build_cpp)
208
{
209
ATF_TEST_CASE_USE(h_build_cpp_ok);
210
run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_ok) >();
211
ATF_REQUIRE(atf::utils::grep_file("-o.*test.p", "stdout"));
212
ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
213
ATF_REQUIRE(atf::utils::grep_file("foo bar", "test.p"));
214
215
ATF_TEST_CASE_USE(h_build_cpp_fail);
216
run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_fail) >();
217
ATF_REQUIRE(atf::utils::grep_file("-o test.p", "stdout"));
218
ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
219
ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
220
ATF_REQUIRE(atf::utils::grep_file("non-existent.h", "stderr"));
221
}
222
223
ATF_TEST_CASE(build_cxx_o);
224
ATF_TEST_CASE_HEAD(build_cxx_o)
225
{
226
set_md_var("descr", "Tests the build_cxx_o function");
227
}
228
ATF_TEST_CASE_BODY(build_cxx_o)
229
{
230
ATF_TEST_CASE_USE(h_build_cxx_o_ok);
231
run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_ok) >();
232
ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
233
ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
234
235
ATF_TEST_CASE_USE(h_build_cxx_o_fail);
236
run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_fail) >();
237
ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
238
ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
239
ATF_REQUIRE(atf::utils::grep_file("test.cpp", "stderr"));
240
ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
241
}
242
243
ATF_TEST_CASE(exec_cleanup);
244
ATF_TEST_CASE_HEAD(exec_cleanup)
245
{
246
set_md_var("descr", "Tests that exec properly cleans up the temporary "
247
"files it creates");
248
}
249
ATF_TEST_CASE_BODY(exec_cleanup)
250
{
251
std::unique_ptr< atf::fs::path > out;
252
std::unique_ptr< atf::fs::path > err;
253
254
{
255
std::unique_ptr< atf::check::check_result > r =
256
do_exec(this, "exit-success");
257
out.reset(new atf::fs::path(r->stdout_path()));
258
err.reset(new atf::fs::path(r->stderr_path()));
259
ATF_REQUIRE(atf::fs::exists(*out.get()));
260
ATF_REQUIRE(atf::fs::exists(*err.get()));
261
}
262
ATF_REQUIRE(!atf::fs::exists(*out.get()));
263
ATF_REQUIRE(!atf::fs::exists(*err.get()));
264
}
265
266
ATF_TEST_CASE(exec_exitstatus);
267
ATF_TEST_CASE_HEAD(exec_exitstatus)
268
{
269
set_md_var("descr", "Tests that exec properly captures the exit "
270
"status of the executed command");
271
}
272
ATF_TEST_CASE_BODY(exec_exitstatus)
273
{
274
{
275
std::unique_ptr< atf::check::check_result > r =
276
do_exec(this, "exit-success");
277
ATF_REQUIRE(r->exited());
278
ATF_REQUIRE(!r->signaled());
279
ATF_REQUIRE_EQ(r->exitcode(), EXIT_SUCCESS);
280
}
281
282
{
283
std::unique_ptr< atf::check::check_result > r =
284
do_exec(this, "exit-failure");
285
ATF_REQUIRE(r->exited());
286
ATF_REQUIRE(!r->signaled());
287
ATF_REQUIRE_EQ(r->exitcode(), EXIT_FAILURE);
288
}
289
290
{
291
std::unique_ptr< atf::check::check_result > r =
292
do_exec(this, "exit-signal");
293
ATF_REQUIRE(!r->exited());
294
ATF_REQUIRE(r->signaled());
295
ATF_REQUIRE_EQ(r->termsig(), SIGKILL);
296
}
297
}
298
299
static
300
void
301
check_lines(const std::string& path, const char* outname,
302
const char* resname)
303
{
304
std::ifstream f(path.c_str());
305
ATF_REQUIRE(f);
306
307
std::string line;
308
std::getline(f, line);
309
ATF_REQUIRE_EQ(line, std::string("Line 1 to ") + outname + " for " +
310
resname);
311
std::getline(f, line);
312
ATF_REQUIRE_EQ(line, std::string("Line 2 to ") + outname + " for " +
313
resname);
314
}
315
316
ATF_TEST_CASE(exec_stdout_stderr);
317
ATF_TEST_CASE_HEAD(exec_stdout_stderr)
318
{
319
set_md_var("descr", "Tests that exec properly captures the stdout "
320
"and stderr streams of the child process");
321
}
322
ATF_TEST_CASE_BODY(exec_stdout_stderr)
323
{
324
std::unique_ptr< atf::check::check_result > r1 =
325
do_exec(this, "stdout-stderr", "result1");
326
ATF_REQUIRE(r1->exited());
327
ATF_REQUIRE_EQ(r1->exitcode(), EXIT_SUCCESS);
328
329
std::unique_ptr< atf::check::check_result > r2 =
330
do_exec(this, "stdout-stderr", "result2");
331
ATF_REQUIRE(r2->exited());
332
ATF_REQUIRE_EQ(r2->exitcode(), EXIT_SUCCESS);
333
334
const std::string out1 = r1->stdout_path();
335
const std::string out2 = r2->stdout_path();
336
const std::string err1 = r1->stderr_path();
337
const std::string err2 = r2->stderr_path();
338
339
ATF_REQUIRE(out1.find("check.XXXXXX") == std::string::npos);
340
ATF_REQUIRE(out2.find("check.XXXXXX") == std::string::npos);
341
ATF_REQUIRE(err1.find("check.XXXXXX") == std::string::npos);
342
ATF_REQUIRE(err2.find("check.XXXXXX") == std::string::npos);
343
344
ATF_REQUIRE(out1.find("/check") != std::string::npos);
345
ATF_REQUIRE(out2.find("/check") != std::string::npos);
346
ATF_REQUIRE(err1.find("/check") != std::string::npos);
347
ATF_REQUIRE(err2.find("/check") != std::string::npos);
348
349
ATF_REQUIRE(out1.find("/stdout") != std::string::npos);
350
ATF_REQUIRE(out2.find("/stdout") != std::string::npos);
351
ATF_REQUIRE(err1.find("/stderr") != std::string::npos);
352
ATF_REQUIRE(err2.find("/stderr") != std::string::npos);
353
354
ATF_REQUIRE(out1 != out2);
355
ATF_REQUIRE(err1 != err2);
356
357
check_lines(out1, "stdout", "result1");
358
check_lines(out2, "stdout", "result2");
359
check_lines(err1, "stderr", "result1");
360
check_lines(err2, "stderr", "result2");
361
}
362
363
ATF_TEST_CASE(exec_unknown);
364
ATF_TEST_CASE_HEAD(exec_unknown)
365
{
366
set_md_var("descr", "Tests that running a non-existing binary "
367
"is handled correctly");
368
}
369
ATF_TEST_CASE_BODY(exec_unknown)
370
{
371
std::vector< std::string > argv;
372
argv.push_back("/foo/bar/non-existent");
373
374
atf::process::argv_array argva(argv);
375
std::unique_ptr< atf::check::check_result > r = atf::check::exec(argva);
376
ATF_REQUIRE(r->exited());
377
ATF_REQUIRE_EQ(r->exitcode(), 127);
378
}
379
380
// ------------------------------------------------------------------------
381
// Main.
382
// ------------------------------------------------------------------------
383
384
ATF_INIT_TEST_CASES(tcs)
385
{
386
// Add the test cases for the free functions.
387
ATF_ADD_TEST_CASE(tcs, build_c_o);
388
ATF_ADD_TEST_CASE(tcs, build_cpp);
389
ATF_ADD_TEST_CASE(tcs, build_cxx_o);
390
ATF_ADD_TEST_CASE(tcs, exec_cleanup);
391
ATF_ADD_TEST_CASE(tcs, exec_exitstatus);
392
ATF_ADD_TEST_CASE(tcs, exec_stdout_stderr);
393
ATF_ADD_TEST_CASE(tcs, exec_unknown);
394
}
395
396