xref: /netbsd-src/external/bsd/atf/dist/atf-c++/macros_test.cpp (revision 88fcb00c0357f2d7c1774f86a352637bfda96184)
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 "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 atf::tests::tc& tc, 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(*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_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(*this, "before");
109     ATF_REQUIRE(condition);
110     create_ctl_file(*this, "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(*this, "before");
124     ATF_REQUIRE_EQ(v1, v2);
125     create_ctl_file(*this, "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(*this, "before");
143     ATF_REQUIRE_IN(element, collection);
144     create_ctl_file(*this, "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(*this, "before");
158     ATF_REQUIRE_MATCH(regexp, string);
159     create_ctl_file(*this, "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(*this, "before");
177     ATF_REQUIRE_NOT_IN(element, collection);
178     create_ctl_file(*this, "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(*this, "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(*this, "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(*this, "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(*this, "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(*this, "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(*this, "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(*this, "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(*this, "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     run_h_tc< ATF_TEST_CASE_NAME(h_pass) >();
293     ATF_REQUIRE(grep_file("result", "^passed"));
294     ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
295     ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
296 }
297 
298 ATF_TEST_CASE(fail);
299 ATF_TEST_CASE_HEAD(fail)
300 {
301     set_md_var("descr", "Tests the ATF_FAIL macro");
302 }
303 ATF_TEST_CASE_BODY(fail)
304 {
305     run_h_tc< ATF_TEST_CASE_NAME(h_fail) >();
306     ATF_REQUIRE(grep_file("result", "^failed: Failed on purpose"));
307     ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
308     ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
309 }
310 
311 ATF_TEST_CASE(skip);
312 ATF_TEST_CASE_HEAD(skip)
313 {
314     set_md_var("descr", "Tests the ATF_SKIP macro");
315 }
316 ATF_TEST_CASE_BODY(skip)
317 {
318     run_h_tc< ATF_TEST_CASE_NAME(h_skip) >();
319     ATF_REQUIRE(grep_file("result", "^skipped: Skipped on purpose"));
320     ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
321     ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
322 }
323 
324 ATF_TEST_CASE(require);
325 ATF_TEST_CASE_HEAD(require)
326 {
327     set_md_var("descr", "Tests the ATF_REQUIRE macro");
328 }
329 ATF_TEST_CASE_BODY(require)
330 {
331     struct test {
332         const char *cond;
333         bool ok;
334     } *t, tests[] = {
335         { "false", false },
336         { "true", true },
337         { NULL, false }
338     };
339 
340     const atf::fs::path before("before");
341     const atf::fs::path after("after");
342 
343     for (t = &tests[0]; t->cond != NULL; t++) {
344         atf::tests::vars_map config;
345         config["condition"] = t->cond;
346 
347         std::cout << "Checking with a " << t->cond << " value\n";
348 
349         run_h_tc< ATF_TEST_CASE_NAME(h_require) >(config);
350 
351         ATF_REQUIRE(atf::fs::exists(before));
352         if (t->ok) {
353             ATF_REQUIRE(grep_file("result", "^passed"));
354             ATF_REQUIRE(atf::fs::exists(after));
355         } else {
356             ATF_REQUIRE(grep_file("result", "^failed: .*condition not met"));
357             ATF_REQUIRE(!atf::fs::exists(after));
358         }
359 
360         atf::fs::remove(before);
361         if (t->ok)
362             atf::fs::remove(after);
363     }
364 }
365 
366 ATF_TEST_CASE(require_eq);
367 ATF_TEST_CASE_HEAD(require_eq)
368 {
369     set_md_var("descr", "Tests the ATF_REQUIRE_EQ macro");
370 }
371 ATF_TEST_CASE_BODY(require_eq)
372 {
373     struct test {
374         const char *v1;
375         const char *v2;
376         bool ok;
377     } *t, tests[] = {
378         { "1", "1", true },
379         { "1", "2", false },
380         { "2", "1", false },
381         { "2", "2", true },
382         { NULL, NULL, false }
383     };
384 
385     const atf::fs::path before("before");
386     const atf::fs::path after("after");
387 
388     for (t = &tests[0]; t->v1 != NULL; t++) {
389         atf::tests::vars_map config;
390         config["v1"] = t->v1;
391         config["v2"] = t->v2;
392 
393         std::cout << "Checking with " << t->v1 << ", " << t->v2
394                   << " and expecting " << (t->ok ? "true" : "false")
395                   << "\n";
396 
397         run_h_tc< ATF_TEST_CASE_NAME(h_require_eq) >(config);
398 
399         ATF_REQUIRE(atf::fs::exists(before));
400         if (t->ok) {
401             ATF_REQUIRE(grep_file("result", "^passed"));
402             ATF_REQUIRE(atf::fs::exists(after));
403         } else {
404             ATF_REQUIRE(grep_file("result", "^failed: .*v1 != v2"));
405             ATF_REQUIRE(!atf::fs::exists(after));
406         }
407 
408         atf::fs::remove(before);
409         if (t->ok)
410             atf::fs::remove(after);
411     }
412 }
413 
414 ATF_TEST_CASE(require_in);
415 ATF_TEST_CASE_HEAD(require_in)
416 {
417     set_md_var("descr", "Tests the ATF_REQUIRE_IN macro");
418 }
419 ATF_TEST_CASE_BODY(require_in)
420 {
421     struct test {
422         const char *value;
423         bool ok;
424     } *t, tests[] = {
425         { "foo", true },
426         { "bar", true },
427         { "baz", true },
428         { "xxx", false },
429         { "fooa", false },
430         { "foo ", false },
431         { NULL, false }
432     };
433 
434     const atf::fs::path before("before");
435     const atf::fs::path after("after");
436 
437     for (t = &tests[0]; t->value != NULL; t++) {
438         atf::tests::vars_map config;
439         config["value"] = t->value;
440 
441         run_h_tc< ATF_TEST_CASE_NAME(h_require_in) >(config);
442 
443         ATF_REQUIRE(atf::fs::exists(before));
444         if (t->ok) {
445             ATF_REQUIRE(grep_file("result", "^passed"));
446             ATF_REQUIRE(atf::fs::exists(after));
447         } else {
448             ATF_REQUIRE(grep_file("result", "^failed: "));
449             ATF_REQUIRE(!atf::fs::exists(after));
450         }
451 
452         atf::fs::remove(before);
453         if (t->ok)
454             atf::fs::remove(after);
455     }
456 }
457 
458 ATF_TEST_CASE(require_match);
459 ATF_TEST_CASE_HEAD(require_match)
460 {
461     set_md_var("descr", "Tests the ATF_REQUIRE_MATCH macro");
462 }
463 ATF_TEST_CASE_BODY(require_match)
464 {
465     struct test {
466         const char *regexp;
467         const char *string;
468         bool ok;
469     } *t, tests[] = {
470         { "foo.*bar", "this is a foo, bar, baz", true },
471         { "bar.*baz", "this is a baz, bar, foo", false },
472         { NULL, NULL, false }
473     };
474 
475     const atf::fs::path before("before");
476     const atf::fs::path after("after");
477 
478     for (t = &tests[0]; t->regexp != NULL; t++) {
479         atf::tests::vars_map config;
480         config["regexp"] = t->regexp;
481         config["string"] = t->string;
482 
483         std::cout << "Checking with " << t->regexp << ", " << t->string
484                   << " and expecting " << (t->ok ? "true" : "false")
485                   << "\n";
486 
487         run_h_tc< ATF_TEST_CASE_NAME(h_require_match) >(config);
488 
489         ATF_REQUIRE(atf::fs::exists(before));
490         if (t->ok) {
491             ATF_REQUIRE(grep_file("result", "^passed"));
492             ATF_REQUIRE(atf::fs::exists(after));
493         } else {
494             ATF_REQUIRE(grep_file("result", "^failed: "));
495             ATF_REQUIRE(!atf::fs::exists(after));
496         }
497 
498         atf::fs::remove(before);
499         if (t->ok)
500             atf::fs::remove(after);
501     }
502 }
503 
504 ATF_TEST_CASE(require_not_in);
505 ATF_TEST_CASE_HEAD(require_not_in)
506 {
507     set_md_var("descr", "Tests the ATF_REQUIRE_NOT_IN macro");
508 }
509 ATF_TEST_CASE_BODY(require_not_in)
510 {
511     struct test {
512         const char *value;
513         bool ok;
514     } *t, tests[] = {
515         { "foo", false },
516         { "bar", false },
517         { "baz", false },
518         { "xxx", true },
519         { "fooa", true },
520         { "foo ", true },
521         { NULL, false }
522     };
523 
524     const atf::fs::path before("before");
525     const atf::fs::path after("after");
526 
527     for (t = &tests[0]; t->value != NULL; t++) {
528         atf::tests::vars_map config;
529         config["value"] = t->value;
530 
531         run_h_tc< ATF_TEST_CASE_NAME(h_require_not_in) >(config);
532 
533         ATF_REQUIRE(atf::fs::exists(before));
534         if (t->ok) {
535             ATF_REQUIRE(grep_file("result", "^passed"));
536             ATF_REQUIRE(atf::fs::exists(after));
537         } else {
538             ATF_REQUIRE(grep_file("result", "^failed: "));
539             ATF_REQUIRE(!atf::fs::exists(after));
540         }
541 
542         atf::fs::remove(before);
543         if (t->ok)
544             atf::fs::remove(after);
545     }
546 }
547 
548 ATF_TEST_CASE(require_throw);
549 ATF_TEST_CASE_HEAD(require_throw)
550 {
551     set_md_var("descr", "Tests the ATF_REQUIRE_THROW macro");
552 }
553 ATF_TEST_CASE_BODY(require_throw)
554 {
555     struct test {
556         const char *what;
557         bool ok;
558         const char *msg;
559     } *t, tests[] = {
560         { "throw_int", false, "unexpected error" },
561         { "throw_rt", true, NULL },
562         { "no_throw_rt", false, "did not throw" },
563         { NULL, false, NULL }
564     };
565 
566     const atf::fs::path before("before");
567     const atf::fs::path after("after");
568 
569     for (t = &tests[0]; t->what != NULL; t++) {
570         atf::tests::vars_map config;
571         config["what"] = t->what;
572 
573         std::cout << "Checking with " << t->what << " and expecting "
574                   << (t->ok ? "true" : "false") << "\n";
575 
576         run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
577 
578         ATF_REQUIRE(atf::fs::exists(before));
579         if (t->ok) {
580             ATF_REQUIRE(grep_file("result", "^passed"));
581             ATF_REQUIRE(atf::fs::exists(after));
582         } else {
583             std::cout << "Checking that message contains '" << t->msg
584                       << "'\n";
585             std::string exp_result = std::string("^failed: .*") + t->msg;
586             ATF_REQUIRE(grep_file("result", exp_result.c_str()));
587             ATF_REQUIRE(!atf::fs::exists(after));
588         }
589 
590         atf::fs::remove(before);
591         if (t->ok)
592             atf::fs::remove(after);
593     }
594 }
595 
596 ATF_TEST_CASE(require_throw_re);
597 ATF_TEST_CASE_HEAD(require_throw_re)
598 {
599     set_md_var("descr", "Tests the ATF_REQUIRE_THROW_RE macro");
600 }
601 ATF_TEST_CASE_BODY(require_throw_re)
602 {
603     struct test {
604         const char *what;
605         bool ok;
606         const char *msg;
607     } *t, tests[] = {
608         { "throw_int", false, "unexpected error" },
609         { "throw_rt_match", true, NULL },
610         { "throw_rt_no_match", true, "threw.*runtime_error(baz foo bar a).*"
611           "does not match 'a foo bar baz'" },
612         { "no_throw_rt", false, "did not throw" },
613         { NULL, false, NULL }
614     };
615 
616     const atf::fs::path before("before");
617     const atf::fs::path after("after");
618 
619     for (t = &tests[0]; t->what != NULL; t++) {
620         atf::tests::vars_map config;
621         config["what"] = t->what;
622 
623         std::cout << "Checking with " << t->what << " and expecting "
624                   << (t->ok ? "true" : "false") << "\n";
625 
626         run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
627 
628         ATF_REQUIRE(atf::fs::exists(before));
629         if (t->ok) {
630             ATF_REQUIRE(grep_file("result", "^passed"));
631             ATF_REQUIRE(atf::fs::exists(after));
632         } else {
633             std::cout << "Checking that message contains '" << t->msg
634                       << "'\n";
635             std::string exp_result = std::string("^failed: .*") + t->msg;
636             ATF_REQUIRE(grep_file("result", exp_result.c_str()));
637             ATF_REQUIRE(!atf::fs::exists(after));
638         }
639 
640         atf::fs::remove(before);
641         if (t->ok)
642             atf::fs::remove(after);
643     }
644 }
645 
646 ATF_TEST_CASE(check_errno);
647 ATF_TEST_CASE_HEAD(check_errno)
648 {
649     set_md_var("descr", "Tests the ATF_CHECK_ERRNO macro");
650 }
651 ATF_TEST_CASE_BODY(check_errno)
652 {
653     struct test {
654         const char *what;
655         bool ok;
656         const char *msg;
657     } *t, tests[] = {
658         { "no_error", false,
659           "Expected true value in errno_ok_stub\\(\\) == -1" },
660         { "errno_ok", true, NULL },
661         { "errno_fail", false,
662           "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
663         { NULL, false, NULL }
664     };
665 
666     const atf::fs::path before("before");
667     const atf::fs::path after("after");
668 
669     for (t = &tests[0]; t->what != NULL; t++) {
670         atf::tests::vars_map config;
671         config["what"] = t->what;
672 
673         run_h_tc< ATF_TEST_CASE_NAME(h_check_errno) >(config);
674 
675         ATF_REQUIRE(atf::fs::exists(before));
676         ATF_REQUIRE(atf::fs::exists(after));
677 
678         if (t->ok) {
679             ATF_REQUIRE(grep_file("result", "^passed"));
680         } else {
681             ATF_REQUIRE(grep_file("result", "^failed"));
682 
683             std::string exp_result = "macros_test.cpp:[0-9]+: " +
684                 std::string(t->msg) + "$";
685             ATF_REQUIRE(grep_file("stderr", exp_result.c_str()));
686         }
687 
688         atf::fs::remove(before);
689         atf::fs::remove(after);
690     }
691 }
692 
693 ATF_TEST_CASE(require_errno);
694 ATF_TEST_CASE_HEAD(require_errno)
695 {
696     set_md_var("descr", "Tests the ATF_REQUIRE_ERRNO macro");
697 }
698 ATF_TEST_CASE_BODY(require_errno)
699 {
700     struct test {
701         const char *what;
702         bool ok;
703         const char *msg;
704     } *t, tests[] = {
705         { "no_error", false,
706           "Expected true value in errno_ok_stub\\(\\) == -1" },
707         { "errno_ok", true, NULL },
708         { "errno_fail", false,
709           "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
710         { NULL, false, NULL }
711     };
712 
713     const atf::fs::path before("before");
714     const atf::fs::path after("after");
715 
716     for (t = &tests[0]; t->what != NULL; t++) {
717         atf::tests::vars_map config;
718         config["what"] = t->what;
719 
720         run_h_tc< ATF_TEST_CASE_NAME(h_require_errno) >(config);
721 
722         ATF_REQUIRE(atf::fs::exists(before));
723         if (t->ok) {
724             ATF_REQUIRE(grep_file("result", "^passed"));
725             ATF_REQUIRE(atf::fs::exists(after));
726         } else {
727             std::string exp_result = "^failed: .*macros_test.cpp:[0-9]+: " +
728                 std::string(t->msg) + "$";
729             ATF_REQUIRE(grep_file("result", exp_result.c_str()));
730 
731             ATF_REQUIRE(!atf::fs::exists(after));
732         }
733 
734         atf::fs::remove(before);
735         if (t->ok)
736             atf::fs::remove(after);
737     }
738 }
739 
740 // ------------------------------------------------------------------------
741 // Tests cases for the header file.
742 // ------------------------------------------------------------------------
743 
744 HEADER_TC(include, "atf-c++/macros.hpp");
745 BUILD_TC(use, "macros_hpp_test.cpp",
746          "Tests that the macros provided by the atf-c++/macros.hpp file "
747          "do not cause syntax errors when used",
748          "Build of macros_hpp_test.cpp failed; some macros in "
749          "atf-c++/macros.hpp are broken");
750 
751 // ------------------------------------------------------------------------
752 // Main.
753 // ------------------------------------------------------------------------
754 
755 ATF_INIT_TEST_CASES(tcs)
756 {
757     // Add the test cases for the macros.
758     ATF_ADD_TEST_CASE(tcs, pass);
759     ATF_ADD_TEST_CASE(tcs, fail);
760     ATF_ADD_TEST_CASE(tcs, skip);
761     ATF_ADD_TEST_CASE(tcs, check_errno);
762     ATF_ADD_TEST_CASE(tcs, require);
763     ATF_ADD_TEST_CASE(tcs, require_eq);
764     ATF_ADD_TEST_CASE(tcs, require_in);
765     ATF_ADD_TEST_CASE(tcs, require_match);
766     ATF_ADD_TEST_CASE(tcs, require_not_in);
767     ATF_ADD_TEST_CASE(tcs, require_throw);
768     ATF_ADD_TEST_CASE(tcs, require_throw_re);
769     ATF_ADD_TEST_CASE(tcs, require_errno);
770 
771     // Add the test cases for the header file.
772     ATF_ADD_TEST_CASE(tcs, include);
773     ATF_ADD_TEST_CASE(tcs, use);
774 }
775