xref: /freebsd/contrib/atf/atf-c++/macros_test.cpp (revision 145992504973bd16cf3518af9ba5ce185fefa82a)
1 //
2 // Automated Testing Framework (atf)
3 //
4 // Copyright (c) 2008 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 "macros.hpp"
41 
42 #include "detail/fs.hpp"
43 #include "detail/process.hpp"
44 #include "detail/sanity.hpp"
45 #include "detail/test_helpers.hpp"
46 #include "detail/text.hpp"
47 
48 // ------------------------------------------------------------------------
49 // Auxiliary functions.
50 // ------------------------------------------------------------------------
51 
52 static
53 void
54 create_ctl_file(const char *name)
55 {
56     ATF_REQUIRE(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("before");
71     ATF_PASS();
72     create_ctl_file("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("before");
83     ATF_FAIL("Failed on purpose");
84     create_ctl_file("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("before");
95     ATF_SKIP("Skipped on purpose");
96     create_ctl_file("after");
97 }
98 
99 ATF_TEST_CASE(h_require);
100 ATF_TEST_CASE_HEAD(h_require)
101 {
102     set_md_var("descr", "Helper test case");
103 }
104 ATF_TEST_CASE_BODY(h_require)
105 {
106     bool condition = atf::text::to_bool(get_config_var("condition"));
107 
108     create_ctl_file("before");
109     ATF_REQUIRE(condition);
110     create_ctl_file("after");
111 }
112 
113 ATF_TEST_CASE(h_require_eq);
114 ATF_TEST_CASE_HEAD(h_require_eq)
115 {
116     set_md_var("descr", "Helper test case");
117 }
118 ATF_TEST_CASE_BODY(h_require_eq)
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("before");
124     ATF_REQUIRE_EQ(v1, v2);
125     create_ctl_file("after");
126 }
127 
128 ATF_TEST_CASE(h_require_in);
129 ATF_TEST_CASE_HEAD(h_require_in)
130 {
131     set_md_var("descr", "Helper test case");
132 }
133 ATF_TEST_CASE_BODY(h_require_in)
134 {
135     const std::string element = get_config_var("value");
136 
137     std::set< std::string > collection;
138     collection.insert("foo");
139     collection.insert("bar");
140     collection.insert("baz");
141 
142     create_ctl_file("before");
143     ATF_REQUIRE_IN(element, collection);
144     create_ctl_file("after");
145 }
146 
147 ATF_TEST_CASE(h_require_match);
148 ATF_TEST_CASE_HEAD(h_require_match)
149 {
150     set_md_var("descr", "Helper test case");
151 }
152 ATF_TEST_CASE_BODY(h_require_match)
153 {
154     const std::string regexp = get_config_var("regexp");
155     const std::string string = get_config_var("string");
156 
157     create_ctl_file("before");
158     ATF_REQUIRE_MATCH(regexp, string);
159     create_ctl_file("after");
160 }
161 
162 ATF_TEST_CASE(h_require_not_in);
163 ATF_TEST_CASE_HEAD(h_require_not_in)
164 {
165     set_md_var("descr", "Helper test case");
166 }
167 ATF_TEST_CASE_BODY(h_require_not_in)
168 {
169     const std::string element = get_config_var("value");
170 
171     std::set< std::string > collection;
172     collection.insert("foo");
173     collection.insert("bar");
174     collection.insert("baz");
175 
176     create_ctl_file("before");
177     ATF_REQUIRE_NOT_IN(element, collection);
178     create_ctl_file("after");
179 }
180 
181 ATF_TEST_CASE(h_require_throw);
182 ATF_TEST_CASE_HEAD(h_require_throw)
183 {
184     set_md_var("descr", "Helper test case");
185 }
186 ATF_TEST_CASE_BODY(h_require_throw)
187 {
188     create_ctl_file("before");
189 
190     if (get_config_var("what") == "throw_int")
191         ATF_REQUIRE_THROW(std::runtime_error, if (1) throw int(5));
192     else if (get_config_var("what") == "throw_rt")
193         ATF_REQUIRE_THROW(std::runtime_error,
194                         if (1) throw std::runtime_error("e"));
195     else if (get_config_var("what") == "no_throw_rt")
196         ATF_REQUIRE_THROW(std::runtime_error,
197                         if (0) throw std::runtime_error("e"));
198 
199     create_ctl_file("after");
200 }
201 
202 ATF_TEST_CASE(h_require_throw_re);
203 ATF_TEST_CASE_HEAD(h_require_throw_re)
204 {
205     set_md_var("descr", "Helper test case");
206 }
207 ATF_TEST_CASE_BODY(h_require_throw_re)
208 {
209     create_ctl_file("before");
210 
211     if (get_config_var("what") == "throw_int")
212         ATF_REQUIRE_THROW_RE(std::runtime_error, "5", if (1) throw int(5));
213     else if (get_config_var("what") == "throw_rt_match")
214         ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
215                              if (1) throw std::runtime_error("a foo bar baz"));
216     else if (get_config_var("what") == "throw_rt_no_match")
217         ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
218                              if (1) throw std::runtime_error("baz foo bar a"));
219     else if (get_config_var("what") == "no_throw_rt")
220         ATF_REQUIRE_THROW_RE(std::runtime_error, "e",
221                              if (0) throw std::runtime_error("e"));
222 
223     create_ctl_file("after");
224 }
225 
226 static int
227 errno_fail_stub(const int raised_errno)
228 {
229     errno = raised_errno;
230     return -1;
231 }
232 
233 static int
234 errno_ok_stub(void)
235 {
236     return 0;
237 }
238 
239 ATF_TEST_CASE(h_check_errno);
240 ATF_TEST_CASE_HEAD(h_check_errno)
241 {
242     set_md_var("descr", "Helper test case");
243 }
244 ATF_TEST_CASE_BODY(h_check_errno)
245 {
246     create_ctl_file("before");
247 
248     if (get_config_var("what") == "no_error")
249         ATF_CHECK_ERRNO(-1, errno_ok_stub() == -1);
250     else if (get_config_var("what") == "errno_ok")
251         ATF_CHECK_ERRNO(2, errno_fail_stub(2) == -1);
252     else if (get_config_var("what") == "errno_fail")
253         ATF_CHECK_ERRNO(3, errno_fail_stub(4) == -1);
254     else
255         UNREACHABLE;
256 
257     create_ctl_file("after");
258 }
259 
260 ATF_TEST_CASE(h_require_errno);
261 ATF_TEST_CASE_HEAD(h_require_errno)
262 {
263     set_md_var("descr", "Helper test case");
264 }
265 ATF_TEST_CASE_BODY(h_require_errno)
266 {
267     create_ctl_file("before");
268 
269     if (get_config_var("what") == "no_error")
270         ATF_REQUIRE_ERRNO(-1, errno_ok_stub() == -1);
271     else if (get_config_var("what") == "errno_ok")
272         ATF_REQUIRE_ERRNO(2, errno_fail_stub(2) == -1);
273     else if (get_config_var("what") == "errno_fail")
274         ATF_REQUIRE_ERRNO(3, errno_fail_stub(4) == -1);
275     else
276         UNREACHABLE;
277 
278     create_ctl_file("after");
279 }
280 
281 // ------------------------------------------------------------------------
282 // Test cases for the macros.
283 // ------------------------------------------------------------------------
284 
285 ATF_TEST_CASE(pass);
286 ATF_TEST_CASE_HEAD(pass)
287 {
288     set_md_var("descr", "Tests the ATF_PASS macro");
289 }
290 ATF_TEST_CASE_BODY(pass)
291 {
292     ATF_TEST_CASE_USE(h_pass);
293     run_h_tc< ATF_TEST_CASE_NAME(h_pass) >();
294     ATF_REQUIRE(grep_file("result", "^passed"));
295     ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
296     ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
297 }
298 
299 ATF_TEST_CASE(fail);
300 ATF_TEST_CASE_HEAD(fail)
301 {
302     set_md_var("descr", "Tests the ATF_FAIL macro");
303 }
304 ATF_TEST_CASE_BODY(fail)
305 {
306     ATF_TEST_CASE_USE(h_fail);
307     run_h_tc< ATF_TEST_CASE_NAME(h_fail) >();
308     ATF_REQUIRE(grep_file("result", "^failed: Failed on purpose"));
309     ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
310     ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
311 }
312 
313 ATF_TEST_CASE(skip);
314 ATF_TEST_CASE_HEAD(skip)
315 {
316     set_md_var("descr", "Tests the ATF_SKIP macro");
317 }
318 ATF_TEST_CASE_BODY(skip)
319 {
320     ATF_TEST_CASE_USE(h_skip);
321     run_h_tc< ATF_TEST_CASE_NAME(h_skip) >();
322     ATF_REQUIRE(grep_file("result", "^skipped: Skipped on purpose"));
323     ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
324     ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
325 }
326 
327 ATF_TEST_CASE(require);
328 ATF_TEST_CASE_HEAD(require)
329 {
330     set_md_var("descr", "Tests the ATF_REQUIRE macro");
331 }
332 ATF_TEST_CASE_BODY(require)
333 {
334     struct test {
335         const char *cond;
336         bool ok;
337     } *t, tests[] = {
338         { "false", false },
339         { "true", true },
340         { NULL, false }
341     };
342 
343     const atf::fs::path before("before");
344     const atf::fs::path after("after");
345 
346     for (t = &tests[0]; t->cond != NULL; t++) {
347         atf::tests::vars_map config;
348         config["condition"] = t->cond;
349 
350         std::cout << "Checking with a " << t->cond << " value\n";
351 
352         ATF_TEST_CASE_USE(h_require);
353         run_h_tc< ATF_TEST_CASE_NAME(h_require) >(config);
354 
355         ATF_REQUIRE(atf::fs::exists(before));
356         if (t->ok) {
357             ATF_REQUIRE(grep_file("result", "^passed"));
358             ATF_REQUIRE(atf::fs::exists(after));
359         } else {
360             ATF_REQUIRE(grep_file("result", "^failed: .*condition not met"));
361             ATF_REQUIRE(!atf::fs::exists(after));
362         }
363 
364         atf::fs::remove(before);
365         if (t->ok)
366             atf::fs::remove(after);
367     }
368 }
369 
370 ATF_TEST_CASE(require_eq);
371 ATF_TEST_CASE_HEAD(require_eq)
372 {
373     set_md_var("descr", "Tests the ATF_REQUIRE_EQ macro");
374 }
375 ATF_TEST_CASE_BODY(require_eq)
376 {
377     struct test {
378         const char *v1;
379         const char *v2;
380         bool ok;
381     } *t, tests[] = {
382         { "1", "1", true },
383         { "1", "2", false },
384         { "2", "1", false },
385         { "2", "2", true },
386         { NULL, NULL, false }
387     };
388 
389     const atf::fs::path before("before");
390     const atf::fs::path after("after");
391 
392     for (t = &tests[0]; t->v1 != NULL; t++) {
393         atf::tests::vars_map config;
394         config["v1"] = t->v1;
395         config["v2"] = t->v2;
396 
397         std::cout << "Checking with " << t->v1 << ", " << t->v2
398                   << " and expecting " << (t->ok ? "true" : "false")
399                   << "\n";
400 
401         ATF_TEST_CASE_USE(h_require_eq);
402         run_h_tc< ATF_TEST_CASE_NAME(h_require_eq) >(config);
403 
404         ATF_REQUIRE(atf::fs::exists(before));
405         if (t->ok) {
406             ATF_REQUIRE(grep_file("result", "^passed"));
407             ATF_REQUIRE(atf::fs::exists(after));
408         } else {
409             ATF_REQUIRE(grep_file("result", "^failed: .*v1 != v2"));
410             ATF_REQUIRE(!atf::fs::exists(after));
411         }
412 
413         atf::fs::remove(before);
414         if (t->ok)
415             atf::fs::remove(after);
416     }
417 }
418 
419 ATF_TEST_CASE(require_in);
420 ATF_TEST_CASE_HEAD(require_in)
421 {
422     set_md_var("descr", "Tests the ATF_REQUIRE_IN macro");
423 }
424 ATF_TEST_CASE_BODY(require_in)
425 {
426     struct test {
427         const char *value;
428         bool ok;
429     } *t, tests[] = {
430         { "foo", true },
431         { "bar", true },
432         { "baz", true },
433         { "xxx", false },
434         { "fooa", false },
435         { "foo ", false },
436         { NULL, false }
437     };
438 
439     const atf::fs::path before("before");
440     const atf::fs::path after("after");
441 
442     for (t = &tests[0]; t->value != NULL; t++) {
443         atf::tests::vars_map config;
444         config["value"] = t->value;
445 
446         ATF_TEST_CASE_USE(h_require_in);
447         run_h_tc< ATF_TEST_CASE_NAME(h_require_in) >(config);
448 
449         ATF_REQUIRE(atf::fs::exists(before));
450         if (t->ok) {
451             ATF_REQUIRE(grep_file("result", "^passed"));
452             ATF_REQUIRE(atf::fs::exists(after));
453         } else {
454             ATF_REQUIRE(grep_file("result", "^failed: "));
455             ATF_REQUIRE(!atf::fs::exists(after));
456         }
457 
458         atf::fs::remove(before);
459         if (t->ok)
460             atf::fs::remove(after);
461     }
462 }
463 
464 ATF_TEST_CASE(require_match);
465 ATF_TEST_CASE_HEAD(require_match)
466 {
467     set_md_var("descr", "Tests the ATF_REQUIRE_MATCH macro");
468 }
469 ATF_TEST_CASE_BODY(require_match)
470 {
471     struct test {
472         const char *regexp;
473         const char *string;
474         bool ok;
475     } *t, tests[] = {
476         { "foo.*bar", "this is a foo, bar, baz", true },
477         { "bar.*baz", "this is a baz, bar, foo", false },
478         { NULL, NULL, false }
479     };
480 
481     const atf::fs::path before("before");
482     const atf::fs::path after("after");
483 
484     for (t = &tests[0]; t->regexp != NULL; t++) {
485         atf::tests::vars_map config;
486         config["regexp"] = t->regexp;
487         config["string"] = t->string;
488 
489         std::cout << "Checking with " << t->regexp << ", " << t->string
490                   << " and expecting " << (t->ok ? "true" : "false")
491                   << "\n";
492 
493         ATF_TEST_CASE_USE(h_require_match);
494         run_h_tc< ATF_TEST_CASE_NAME(h_require_match) >(config);
495 
496         ATF_REQUIRE(atf::fs::exists(before));
497         if (t->ok) {
498             ATF_REQUIRE(grep_file("result", "^passed"));
499             ATF_REQUIRE(atf::fs::exists(after));
500         } else {
501             ATF_REQUIRE(grep_file("result", "^failed: "));
502             ATF_REQUIRE(!atf::fs::exists(after));
503         }
504 
505         atf::fs::remove(before);
506         if (t->ok)
507             atf::fs::remove(after);
508     }
509 }
510 
511 ATF_TEST_CASE(require_not_in);
512 ATF_TEST_CASE_HEAD(require_not_in)
513 {
514     set_md_var("descr", "Tests the ATF_REQUIRE_NOT_IN macro");
515 }
516 ATF_TEST_CASE_BODY(require_not_in)
517 {
518     struct test {
519         const char *value;
520         bool ok;
521     } *t, tests[] = {
522         { "foo", false },
523         { "bar", false },
524         { "baz", false },
525         { "xxx", true },
526         { "fooa", true },
527         { "foo ", true },
528         { NULL, false }
529     };
530 
531     const atf::fs::path before("before");
532     const atf::fs::path after("after");
533 
534     for (t = &tests[0]; t->value != NULL; t++) {
535         atf::tests::vars_map config;
536         config["value"] = t->value;
537 
538         ATF_TEST_CASE_USE(h_require_not_in);
539         run_h_tc< ATF_TEST_CASE_NAME(h_require_not_in) >(config);
540 
541         ATF_REQUIRE(atf::fs::exists(before));
542         if (t->ok) {
543             ATF_REQUIRE(grep_file("result", "^passed"));
544             ATF_REQUIRE(atf::fs::exists(after));
545         } else {
546             ATF_REQUIRE(grep_file("result", "^failed: "));
547             ATF_REQUIRE(!atf::fs::exists(after));
548         }
549 
550         atf::fs::remove(before);
551         if (t->ok)
552             atf::fs::remove(after);
553     }
554 }
555 
556 ATF_TEST_CASE(require_throw);
557 ATF_TEST_CASE_HEAD(require_throw)
558 {
559     set_md_var("descr", "Tests the ATF_REQUIRE_THROW macro");
560 }
561 ATF_TEST_CASE_BODY(require_throw)
562 {
563     struct test {
564         const char *what;
565         bool ok;
566         const char *msg;
567     } *t, tests[] = {
568         { "throw_int", false, "unexpected error" },
569         { "throw_rt", true, NULL },
570         { "no_throw_rt", false, "did not throw" },
571         { NULL, false, NULL }
572     };
573 
574     const atf::fs::path before("before");
575     const atf::fs::path after("after");
576 
577     for (t = &tests[0]; t->what != NULL; t++) {
578         atf::tests::vars_map config;
579         config["what"] = t->what;
580 
581         std::cout << "Checking with " << t->what << " and expecting "
582                   << (t->ok ? "true" : "false") << "\n";
583 
584         ATF_TEST_CASE_USE(h_require_throw);
585         run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
586 
587         ATF_REQUIRE(atf::fs::exists(before));
588         if (t->ok) {
589             ATF_REQUIRE(grep_file("result", "^passed"));
590             ATF_REQUIRE(atf::fs::exists(after));
591         } else {
592             std::cout << "Checking that message contains '" << t->msg
593                       << "'\n";
594             std::string exp_result = std::string("^failed: .*") + t->msg;
595             ATF_REQUIRE(grep_file("result", exp_result.c_str()));
596             ATF_REQUIRE(!atf::fs::exists(after));
597         }
598 
599         atf::fs::remove(before);
600         if (t->ok)
601             atf::fs::remove(after);
602     }
603 }
604 
605 ATF_TEST_CASE(require_throw_re);
606 ATF_TEST_CASE_HEAD(require_throw_re)
607 {
608     set_md_var("descr", "Tests the ATF_REQUIRE_THROW_RE macro");
609 }
610 ATF_TEST_CASE_BODY(require_throw_re)
611 {
612     struct test {
613         const char *what;
614         bool ok;
615         const char *msg;
616     } *t, tests[] = {
617         { "throw_int", false, "unexpected error" },
618         { "throw_rt_match", true, NULL },
619         { "throw_rt_no_match", false,
620           "threw.*runtime_error\\(baz foo bar a\\).*"
621           "does not match 'foo\\.\\*baz'" },
622         { "no_throw_rt", false, "did not throw" },
623         { NULL, false, NULL }
624     };
625 
626     const atf::fs::path before("before");
627     const atf::fs::path after("after");
628 
629     for (t = &tests[0]; t->what != NULL; t++) {
630         atf::tests::vars_map config;
631         config["what"] = t->what;
632 
633         std::cout << "Checking with " << t->what << " and expecting "
634                   << (t->ok ? "true" : "false") << "\n";
635 
636         ATF_TEST_CASE_USE(h_require_throw_re);
637         run_h_tc< ATF_TEST_CASE_NAME(h_require_throw_re) >(config);
638 
639         ATF_REQUIRE(atf::fs::exists(before));
640         if (t->ok) {
641             ATF_REQUIRE(grep_file("result", "^passed"));
642             ATF_REQUIRE(atf::fs::exists(after));
643         } else {
644             std::cout << "Checking that message contains '" << t->msg
645                       << "'\n";
646             std::string exp_result = std::string("^failed: .*") + t->msg;
647             ATF_REQUIRE(grep_file("result", exp_result.c_str()));
648             ATF_REQUIRE(!atf::fs::exists(after));
649         }
650 
651         atf::fs::remove(before);
652         if (t->ok)
653             atf::fs::remove(after);
654     }
655 }
656 
657 ATF_TEST_CASE(check_errno);
658 ATF_TEST_CASE_HEAD(check_errno)
659 {
660     set_md_var("descr", "Tests the ATF_CHECK_ERRNO macro");
661 }
662 ATF_TEST_CASE_BODY(check_errno)
663 {
664     struct test {
665         const char *what;
666         bool ok;
667         const char *msg;
668     } *t, tests[] = {
669         { "no_error", false,
670           "Expected true value in errno_ok_stub\\(\\) == -1" },
671         { "errno_ok", true, NULL },
672         { "errno_fail", false,
673           "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
674         { NULL, false, NULL }
675     };
676 
677     const atf::fs::path before("before");
678     const atf::fs::path after("after");
679 
680     for (t = &tests[0]; t->what != NULL; t++) {
681         atf::tests::vars_map config;
682         config["what"] = t->what;
683 
684         ATF_TEST_CASE_USE(h_check_errno);
685         run_h_tc< ATF_TEST_CASE_NAME(h_check_errno) >(config);
686 
687         ATF_REQUIRE(atf::fs::exists(before));
688         ATF_REQUIRE(atf::fs::exists(after));
689 
690         if (t->ok) {
691             ATF_REQUIRE(grep_file("result", "^passed"));
692         } else {
693             ATF_REQUIRE(grep_file("result", "^failed"));
694 
695             std::string exp_result = "macros_test.cpp:[0-9]+: " +
696                 std::string(t->msg) + "$";
697             ATF_REQUIRE(grep_file("stderr", exp_result.c_str()));
698         }
699 
700         atf::fs::remove(before);
701         atf::fs::remove(after);
702     }
703 }
704 
705 ATF_TEST_CASE(require_errno);
706 ATF_TEST_CASE_HEAD(require_errno)
707 {
708     set_md_var("descr", "Tests the ATF_REQUIRE_ERRNO macro");
709 }
710 ATF_TEST_CASE_BODY(require_errno)
711 {
712     struct test {
713         const char *what;
714         bool ok;
715         const char *msg;
716     } *t, tests[] = {
717         { "no_error", false,
718           "Expected true value in errno_ok_stub\\(\\) == -1" },
719         { "errno_ok", true, NULL },
720         { "errno_fail", false,
721           "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
722         { NULL, false, NULL }
723     };
724 
725     const atf::fs::path before("before");
726     const atf::fs::path after("after");
727 
728     for (t = &tests[0]; t->what != NULL; t++) {
729         atf::tests::vars_map config;
730         config["what"] = t->what;
731 
732         ATF_TEST_CASE_USE(h_require_errno);
733         run_h_tc< ATF_TEST_CASE_NAME(h_require_errno) >(config);
734 
735         ATF_REQUIRE(atf::fs::exists(before));
736         if (t->ok) {
737             ATF_REQUIRE(grep_file("result", "^passed"));
738             ATF_REQUIRE(atf::fs::exists(after));
739         } else {
740             std::string exp_result = "^failed: .*macros_test.cpp:[0-9]+: " +
741                 std::string(t->msg) + "$";
742             ATF_REQUIRE(grep_file("result", exp_result.c_str()));
743 
744             ATF_REQUIRE(!atf::fs::exists(after));
745         }
746 
747         atf::fs::remove(before);
748         if (t->ok)
749             atf::fs::remove(after);
750     }
751 }
752 
753 // ------------------------------------------------------------------------
754 // Tests cases for the header file.
755 // ------------------------------------------------------------------------
756 
757 HEADER_TC(include, "atf-c++/macros.hpp");
758 BUILD_TC(use, "macros_hpp_test.cpp",
759          "Tests that the macros provided by the atf-c++/macros.hpp file "
760          "do not cause syntax errors when used",
761          "Build of macros_hpp_test.cpp failed; some macros in "
762          "atf-c++/macros.hpp are broken");
763 BUILD_TC_FAIL(detect_unused_tests, "unused_test.cpp",
764          "Tests that defining an unused test case raises a warning (and thus "
765          "an error)",
766          "Build of unused_test.cpp passed; unused test cases are not properly "
767          "detected");
768 
769 // ------------------------------------------------------------------------
770 // Main.
771 // ------------------------------------------------------------------------
772 
773 ATF_INIT_TEST_CASES(tcs)
774 {
775     // Add the test cases for the macros.
776     ATF_ADD_TEST_CASE(tcs, pass);
777     ATF_ADD_TEST_CASE(tcs, fail);
778     ATF_ADD_TEST_CASE(tcs, skip);
779     ATF_ADD_TEST_CASE(tcs, check_errno);
780     ATF_ADD_TEST_CASE(tcs, require);
781     ATF_ADD_TEST_CASE(tcs, require_eq);
782     ATF_ADD_TEST_CASE(tcs, require_in);
783     ATF_ADD_TEST_CASE(tcs, require_match);
784     ATF_ADD_TEST_CASE(tcs, require_not_in);
785     ATF_ADD_TEST_CASE(tcs, require_throw);
786     ATF_ADD_TEST_CASE(tcs, require_throw_re);
787     ATF_ADD_TEST_CASE(tcs, require_errno);
788 
789     // Add the test cases for the header file.
790     ATF_ADD_TEST_CASE(tcs, include);
791     ATF_ADD_TEST_CASE(tcs, use);
792     ATF_ADD_TEST_CASE(tcs, detect_unused_tests);
793 }
794