xref: /netbsd-src/external/bsd/atf/dist/atf-c++/macros_test.cpp (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 //
2 // Automated Testing Framework (atf)
3 //
4 // Copyright (c) 2008, 2009, 2010 The NetBSD Foundation, Inc.
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 // 1. Redistributions of source code must retain the above copyright
11 //    notice, this list of conditions and the following disclaimer.
12 // 2. Redistributions in binary form must reproduce the above copyright
13 //    notice, this list of conditions and the following disclaimer in the
14 //    documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 
30 extern "C" {
31 #include <fcntl.h>
32 #include <unistd.h>
33 }
34 
35 #include <cerrno>
36 #include <cstdlib>
37 #include <iostream>
38 #include <stdexcept>
39 
40 #include "atf-c++/fs.hpp"
41 #include "atf-c++/macros.hpp"
42 #include "atf-c++/process.hpp"
43 #include "atf-c++/sanity.hpp"
44 #include "atf-c++/text.hpp"
45 
46 #include "test_helpers.hpp"
47 
48 // ------------------------------------------------------------------------
49 // Auxiliary functions.
50 // ------------------------------------------------------------------------
51 
52 static
53 void
54 create_ctl_file(const atf::tests::tc& tc, const char *name)
55 {
56     ATF_CHECK(open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
57 }
58 
59 // ------------------------------------------------------------------------
60 // Auxiliary test cases.
61 // ------------------------------------------------------------------------
62 
63 ATF_TEST_CASE(h_pass);
64 ATF_TEST_CASE_HEAD(h_pass)
65 {
66     set_md_var("descr", "Helper test case");
67 }
68 ATF_TEST_CASE_BODY(h_pass)
69 {
70     create_ctl_file(*this, "before");
71     ATF_PASS();
72     create_ctl_file(*this, "after");
73 }
74 
75 ATF_TEST_CASE(h_fail);
76 ATF_TEST_CASE_HEAD(h_fail)
77 {
78     set_md_var("descr", "Helper test case");
79 }
80 ATF_TEST_CASE_BODY(h_fail)
81 {
82     create_ctl_file(*this, "before");
83     ATF_FAIL("Failed on purpose");
84     create_ctl_file(*this, "after");
85 }
86 
87 ATF_TEST_CASE(h_skip);
88 ATF_TEST_CASE_HEAD(h_skip)
89 {
90     set_md_var("descr", "Helper test case");
91 }
92 ATF_TEST_CASE_BODY(h_skip)
93 {
94     create_ctl_file(*this, "before");
95     ATF_SKIP("Skipped on purpose");
96     create_ctl_file(*this, "after");
97 }
98 
99 ATF_TEST_CASE(h_check);
100 ATF_TEST_CASE_HEAD(h_check)
101 {
102     set_md_var("descr", "Helper test case");
103 }
104 ATF_TEST_CASE_BODY(h_check)
105 {
106     bool condition = atf::text::to_bool(get_config_var("condition"));
107 
108     create_ctl_file(*this, "before");
109     ATF_CHECK(condition);
110     create_ctl_file(*this, "after");
111 }
112 
113 ATF_TEST_CASE(h_check_equal);
114 ATF_TEST_CASE_HEAD(h_check_equal)
115 {
116     set_md_var("descr", "Helper test case");
117 }
118 ATF_TEST_CASE_BODY(h_check_equal)
119 {
120     long v1 = atf::text::to_type< long >(get_config_var("v1"));
121     long v2 = atf::text::to_type< long >(get_config_var("v2"));
122 
123     create_ctl_file(*this, "before");
124     ATF_CHECK_EQUAL(v1, v2);
125     create_ctl_file(*this, "after");
126 }
127 
128 ATF_TEST_CASE(h_check_throw);
129 ATF_TEST_CASE_HEAD(h_check_throw)
130 {
131     set_md_var("descr", "Helper test case");
132 }
133 ATF_TEST_CASE_BODY(h_check_throw)
134 {
135     create_ctl_file(*this, "before");
136 
137     if (get_config_var("what") == "throw_int")
138         ATF_CHECK_THROW(std::runtime_error, if (1) throw int(5));
139     else if (get_config_var("what") == "throw_rt")
140         ATF_CHECK_THROW(std::runtime_error,
141                         if (1) throw std::runtime_error("e"));
142     else if (get_config_var("what") == "no_throw_rt")
143         ATF_CHECK_THROW(std::runtime_error,
144                         if (0) throw std::runtime_error("e"));
145 
146     create_ctl_file(*this, "after");
147 }
148 
149 static int
150 errno_fail_stub(const int raised_errno)
151 {
152     errno = raised_errno;
153     return -1;
154 }
155 
156 static int
157 errno_ok_stub(void)
158 {
159     return 0;
160 }
161 
162 ATF_TEST_CASE(h_check_errno);
163 ATF_TEST_CASE_HEAD(h_check_errno)
164 {
165     set_md_var("descr", "Helper test case");
166 }
167 ATF_TEST_CASE_BODY(h_check_errno)
168 {
169     create_ctl_file(*this, "before");
170 
171     if (get_config_var("what") == "no_error")
172         ATF_CHECK_ERRNO(-1, errno_ok_stub() == -1);
173     else if (get_config_var("what") == "errno_ok")
174         ATF_CHECK_ERRNO(2, errno_fail_stub(2) == -1);
175     else if (get_config_var("what") == "errno_fail")
176         ATF_CHECK_ERRNO(3, errno_fail_stub(4) == -1);
177     else
178         UNREACHABLE;
179 
180     create_ctl_file(*this, "after");
181 }
182 
183 ATF_TEST_CASE(h_require_errno);
184 ATF_TEST_CASE_HEAD(h_require_errno)
185 {
186     set_md_var("descr", "Helper test case");
187 }
188 ATF_TEST_CASE_BODY(h_require_errno)
189 {
190     create_ctl_file(*this, "before");
191 
192     if (get_config_var("what") == "no_error")
193         ATF_REQUIRE_ERRNO(-1, errno_ok_stub() == -1);
194     else if (get_config_var("what") == "errno_ok")
195         ATF_REQUIRE_ERRNO(2, errno_fail_stub(2) == -1);
196     else if (get_config_var("what") == "errno_fail")
197         ATF_REQUIRE_ERRNO(3, errno_fail_stub(4) == -1);
198     else
199         UNREACHABLE;
200 
201     create_ctl_file(*this, "after");
202 }
203 
204 // ------------------------------------------------------------------------
205 // Test cases for the macros.
206 // ------------------------------------------------------------------------
207 
208 ATF_TEST_CASE(pass);
209 ATF_TEST_CASE_HEAD(pass)
210 {
211     set_md_var("descr", "Tests the ATF_PASS macro");
212     set_md_var("use.fs", "true");
213 }
214 ATF_TEST_CASE_BODY(pass)
215 {
216     run_h_tc< ATF_TEST_CASE_NAME(h_pass) >();
217     ATF_CHECK(grep_file("result", "^passed"));
218     ATF_CHECK(atf::fs::exists(atf::fs::path("before")));
219     ATF_CHECK(!atf::fs::exists(atf::fs::path("after")));
220 }
221 
222 ATF_TEST_CASE(fail);
223 ATF_TEST_CASE_HEAD(fail)
224 {
225     set_md_var("descr", "Tests the ATF_FAIL macro");
226     set_md_var("use.fs", "true");
227 }
228 ATF_TEST_CASE_BODY(fail)
229 {
230     run_h_tc< ATF_TEST_CASE_NAME(h_fail) >();
231     ATF_CHECK(grep_file("result", "^failed: Failed on purpose"));
232     ATF_CHECK(atf::fs::exists(atf::fs::path("before")));
233     ATF_CHECK(!atf::fs::exists(atf::fs::path("after")));
234 }
235 
236 ATF_TEST_CASE(skip);
237 ATF_TEST_CASE_HEAD(skip)
238 {
239     set_md_var("descr", "Tests the ATF_SKIP macro");
240     set_md_var("use.fs", "true");
241 }
242 ATF_TEST_CASE_BODY(skip)
243 {
244     run_h_tc< ATF_TEST_CASE_NAME(h_skip) >();
245     ATF_CHECK(grep_file("result", "^skipped: Skipped on purpose"));
246     ATF_CHECK(atf::fs::exists(atf::fs::path("before")));
247     ATF_CHECK(!atf::fs::exists(atf::fs::path("after")));
248 }
249 
250 ATF_TEST_CASE(check);
251 ATF_TEST_CASE_HEAD(check)
252 {
253     set_md_var("descr", "Tests the ATF_CHECK macro");
254     set_md_var("use.fs", "true");
255 }
256 ATF_TEST_CASE_BODY(check)
257 {
258     struct test {
259         const char *cond;
260         bool ok;
261     } *t, tests[] = {
262         { "false", false },
263         { "true", true },
264         { NULL, false }
265     };
266 
267     const atf::fs::path before("before");
268     const atf::fs::path after("after");
269 
270     for (t = &tests[0]; t->cond != NULL; t++) {
271         atf::tests::vars_map config;
272         config["condition"] = t->cond;
273 
274         std::cout << "Checking with a " << t->cond << " value" << std::endl;
275 
276         run_h_tc< ATF_TEST_CASE_NAME(h_check) >(config);
277 
278         ATF_CHECK(atf::fs::exists(before));
279         if (t->ok) {
280             ATF_CHECK(grep_file("result", "^passed"));
281             ATF_CHECK(atf::fs::exists(after));
282         } else {
283             ATF_CHECK(grep_file("result", "^failed: .*condition not met"));
284             ATF_CHECK(!atf::fs::exists(after));
285         }
286 
287         atf::fs::remove(before);
288         if (t->ok)
289             atf::fs::remove(after);
290     }
291 }
292 
293 ATF_TEST_CASE(check_equal);
294 ATF_TEST_CASE_HEAD(check_equal)
295 {
296     set_md_var("descr", "Tests the ATF_CHECK_EQUAL macro");
297     set_md_var("use.fs", "true");
298 }
299 ATF_TEST_CASE_BODY(check_equal)
300 {
301     struct test {
302         const char *v1;
303         const char *v2;
304         bool ok;
305     } *t, tests[] = {
306         { "1", "1", true },
307         { "1", "2", false },
308         { "2", "1", false },
309         { "2", "2", true },
310         { NULL, NULL, false }
311     };
312 
313     const atf::fs::path before("before");
314     const atf::fs::path after("after");
315 
316     for (t = &tests[0]; t->v1 != NULL; t++) {
317         atf::tests::vars_map config;
318         config["v1"] = t->v1;
319         config["v2"] = t->v2;
320 
321         std::cout << "Checking with " << t->v1 << ", " << t->v2
322                   << " and expecting " << (t->ok ? "true" : "false")
323                   << std::endl;
324 
325         run_h_tc< ATF_TEST_CASE_NAME(h_check_equal) >(config);
326 
327         ATF_CHECK(atf::fs::exists(before));
328         if (t->ok) {
329             ATF_CHECK(grep_file("result", "^passed"));
330             ATF_CHECK(atf::fs::exists(after));
331         } else {
332             ATF_CHECK(grep_file("result", "^failed: .*v1 != v2"));
333             ATF_CHECK(!atf::fs::exists(after));
334         }
335 
336         atf::fs::remove(before);
337         if (t->ok)
338             atf::fs::remove(after);
339     }
340 }
341 
342 ATF_TEST_CASE(check_throw);
343 ATF_TEST_CASE_HEAD(check_throw)
344 {
345     set_md_var("descr", "Tests the ATF_CHECK_THROW macro");
346     set_md_var("use.fs", "true");
347 }
348 ATF_TEST_CASE_BODY(check_throw)
349 {
350     struct test {
351         const char *what;
352         bool ok;
353         const char *msg;
354     } *t, tests[] = {
355         { "throw_int", false, "unexpected error" },
356         { "throw_rt", true, NULL },
357         { "no_throw_rt", false, "did not throw" },
358         { NULL, false, NULL }
359     };
360 
361     const atf::fs::path before("before");
362     const atf::fs::path after("after");
363 
364     for (t = &tests[0]; t->what != NULL; t++) {
365         atf::tests::vars_map config;
366         config["what"] = t->what;
367 
368         std::cout << "Checking with " << t->what << " and expecting "
369                   << (t->ok ? "true" : "false") << std::endl;
370 
371         run_h_tc< ATF_TEST_CASE_NAME(h_check_throw) >(config);
372 
373         ATF_CHECK(atf::fs::exists(before));
374         if (t->ok) {
375             ATF_CHECK(grep_file("result", "^passed"));
376             ATF_CHECK(atf::fs::exists(after));
377         } else {
378             std::cout << "Checking that message contains '" << t->msg
379                       << "'" << std::endl;
380             std::string exp_result = std::string("^failed: .*") + t->msg;
381             ATF_CHECK(grep_file("result", exp_result.c_str()));
382             ATF_CHECK(!atf::fs::exists(after));
383         }
384 
385         atf::fs::remove(before);
386         if (t->ok)
387             atf::fs::remove(after);
388     }
389 }
390 
391 ATF_TEST_CASE(check_errno);
392 ATF_TEST_CASE_HEAD(check_errno)
393 {
394     set_md_var("descr", "Tests the ATF_CHECK_ERRNO macro");
395     set_md_var("use.fs", "true");
396 }
397 ATF_TEST_CASE_BODY(check_errno)
398 {
399     struct test {
400         const char *what;
401         bool ok;
402         const char *msg;
403     } *t, tests[] = {
404         { "no_error", false,
405           "Expected true value in errno_ok_stub\\(\\) == -1" },
406         { "errno_ok", true, NULL },
407         { "errno_fail", false,
408           "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
409         { NULL, false, NULL }
410     };
411 
412     const atf::fs::path before("before");
413     const atf::fs::path after("after");
414 
415     for (t = &tests[0]; t->what != NULL; t++) {
416         atf::tests::vars_map config;
417         config["what"] = t->what;
418 
419         run_h_tc< ATF_TEST_CASE_NAME(h_check_errno) >(config);
420 
421         ATF_CHECK(atf::fs::exists(before));
422         ATF_CHECK(atf::fs::exists(after));
423 
424         if (t->ok) {
425             ATF_CHECK(grep_file("result", "^passed"));
426         } else {
427             ATF_CHECK(grep_file("result", "^failed"));
428 
429             std::string exp_result = "macros_test.cpp:[0-9]+: " +
430                 std::string(t->msg) + "$";
431             ATF_CHECK(grep_file("stderr", exp_result.c_str()));
432         }
433 
434         atf::fs::remove(before);
435         atf::fs::remove(after);
436     }
437 }
438 
439 ATF_TEST_CASE(require_errno);
440 ATF_TEST_CASE_HEAD(require_errno)
441 {
442     set_md_var("descr", "Tests the ATF_REQUIRE_ERRNO macro");
443     set_md_var("use.fs", "true");
444 }
445 ATF_TEST_CASE_BODY(require_errno)
446 {
447     struct test {
448         const char *what;
449         bool ok;
450         const char *msg;
451     } *t, tests[] = {
452         { "no_error", false,
453           "Expected true value in errno_ok_stub\\(\\) == -1" },
454         { "errno_ok", true, NULL },
455         { "errno_fail", false,
456           "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
457         { NULL, false, NULL }
458     };
459 
460     const atf::fs::path before("before");
461     const atf::fs::path after("after");
462 
463     for (t = &tests[0]; t->what != NULL; t++) {
464         atf::tests::vars_map config;
465         config["what"] = t->what;
466 
467         run_h_tc< ATF_TEST_CASE_NAME(h_require_errno) >(config);
468 
469         ATF_CHECK(atf::fs::exists(before));
470         if (t->ok) {
471             ATF_CHECK(grep_file("result", "^passed"));
472             ATF_CHECK(atf::fs::exists(after));
473         } else {
474             std::string exp_result = "^failed: .*macros_test.cpp:[0-9]+: " +
475                 std::string(t->msg) + "$";
476             ATF_CHECK(grep_file("result", exp_result.c_str()));
477 
478             ATF_CHECK(!atf::fs::exists(after));
479         }
480 
481         atf::fs::remove(before);
482         if (t->ok)
483             atf::fs::remove(after);
484     }
485 }
486 
487 // ------------------------------------------------------------------------
488 // Tests cases for the header file.
489 // ------------------------------------------------------------------------
490 
491 HEADER_TC(include, "atf-c++/macros.hpp");
492 BUILD_TC(use, "macros_hpp_test.cpp",
493          "Tests that the macros provided by the atf-c++/macros.hpp file "
494          "do not cause syntax errors when used",
495          "Build of macros_hpp_test.cpp failed; some macros in "
496          "atf-c++/macros.hpp are broken");
497 
498 // ------------------------------------------------------------------------
499 // Main.
500 // ------------------------------------------------------------------------
501 
502 ATF_INIT_TEST_CASES(tcs)
503 {
504     // Add the test cases for the macros.
505     ATF_ADD_TEST_CASE(tcs, pass);
506     ATF_ADD_TEST_CASE(tcs, fail);
507     ATF_ADD_TEST_CASE(tcs, skip);
508     ATF_ADD_TEST_CASE(tcs, check);
509     ATF_ADD_TEST_CASE(tcs, check_equal);
510     ATF_ADD_TEST_CASE(tcs, check_throw);
511     ATF_ADD_TEST_CASE(tcs, check_errno);
512     ATF_ADD_TEST_CASE(tcs, require_errno);
513 
514     // Add the test cases for the header file.
515     ATF_ADD_TEST_CASE(tcs, include);
516     ATF_ADD_TEST_CASE(tcs, use);
517 }
518