1240116Smarcel// Copyright (c) 2008 The NetBSD Foundation, Inc.
2240116Smarcel// All rights reserved.
3240116Smarcel//
4240116Smarcel// Redistribution and use in source and binary forms, with or without
5240116Smarcel// modification, are permitted provided that the following conditions
6240116Smarcel// are met:
7240116Smarcel// 1. Redistributions of source code must retain the above copyright
8240116Smarcel//    notice, this list of conditions and the following disclaimer.
9240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright
10240116Smarcel//    notice, this list of conditions and the following disclaimer in the
11240116Smarcel//    documentation and/or other materials provided with the distribution.
12240116Smarcel//
13240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25240116Smarcel
26275988Sngie#include "atf-c++/macros.hpp"
27275988Sngie
28240116Smarcelextern "C" {
29240116Smarcel#include <fcntl.h>
30240116Smarcel#include <unistd.h>
31240116Smarcel}
32240116Smarcel
33240116Smarcel#include <cerrno>
34240116Smarcel#include <cstdlib>
35240116Smarcel#include <iostream>
36240116Smarcel#include <stdexcept>
37240116Smarcel
38275988Sngie#include <atf-c++.hpp>
39240116Smarcel
40275988Sngie#include "atf-c++/detail/fs.hpp"
41275988Sngie#include "atf-c++/detail/process.hpp"
42275988Sngie#include "atf-c++/detail/sanity.hpp"
43275988Sngie#include "atf-c++/detail/test_helpers.hpp"
44275988Sngie#include "atf-c++/detail/text.hpp"
45275988Sngie#include "atf-c++/utils.hpp"
46240116Smarcel
47240116Smarcel// ------------------------------------------------------------------------
48240116Smarcel// Auxiliary functions.
49240116Smarcel// ------------------------------------------------------------------------
50240116Smarcel
51240116Smarcelstatic
52240116Smarcelvoid
53240116Smarcelcreate_ctl_file(const char *name)
54240116Smarcel{
55240116Smarcel    ATF_REQUIRE(open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
56240116Smarcel}
57240116Smarcel
58240116Smarcel// ------------------------------------------------------------------------
59240116Smarcel// Auxiliary test cases.
60240116Smarcel// ------------------------------------------------------------------------
61240116Smarcel
62240116SmarcelATF_TEST_CASE(h_pass);
63240116SmarcelATF_TEST_CASE_HEAD(h_pass)
64240116Smarcel{
65240116Smarcel    set_md_var("descr", "Helper test case");
66240116Smarcel}
67240116SmarcelATF_TEST_CASE_BODY(h_pass)
68240116Smarcel{
69240116Smarcel    create_ctl_file("before");
70240116Smarcel    ATF_PASS();
71240116Smarcel    create_ctl_file("after");
72240116Smarcel}
73240116Smarcel
74240116SmarcelATF_TEST_CASE(h_fail);
75240116SmarcelATF_TEST_CASE_HEAD(h_fail)
76240116Smarcel{
77240116Smarcel    set_md_var("descr", "Helper test case");
78240116Smarcel}
79240116SmarcelATF_TEST_CASE_BODY(h_fail)
80240116Smarcel{
81240116Smarcel    create_ctl_file("before");
82240116Smarcel    ATF_FAIL("Failed on purpose");
83240116Smarcel    create_ctl_file("after");
84240116Smarcel}
85240116Smarcel
86240116SmarcelATF_TEST_CASE(h_skip);
87240116SmarcelATF_TEST_CASE_HEAD(h_skip)
88240116Smarcel{
89240116Smarcel    set_md_var("descr", "Helper test case");
90240116Smarcel}
91240116SmarcelATF_TEST_CASE_BODY(h_skip)
92240116Smarcel{
93240116Smarcel    create_ctl_file("before");
94240116Smarcel    ATF_SKIP("Skipped on purpose");
95240116Smarcel    create_ctl_file("after");
96240116Smarcel}
97240116Smarcel
98240116SmarcelATF_TEST_CASE(h_require);
99240116SmarcelATF_TEST_CASE_HEAD(h_require)
100240116Smarcel{
101240116Smarcel    set_md_var("descr", "Helper test case");
102240116Smarcel}
103240116SmarcelATF_TEST_CASE_BODY(h_require)
104240116Smarcel{
105240116Smarcel    bool condition = atf::text::to_bool(get_config_var("condition"));
106240116Smarcel
107240116Smarcel    create_ctl_file("before");
108240116Smarcel    ATF_REQUIRE(condition);
109240116Smarcel    create_ctl_file("after");
110240116Smarcel}
111240116Smarcel
112240116SmarcelATF_TEST_CASE(h_require_eq);
113240116SmarcelATF_TEST_CASE_HEAD(h_require_eq)
114240116Smarcel{
115240116Smarcel    set_md_var("descr", "Helper test case");
116240116Smarcel}
117240116SmarcelATF_TEST_CASE_BODY(h_require_eq)
118240116Smarcel{
119240116Smarcel    long v1 = atf::text::to_type< long >(get_config_var("v1"));
120240116Smarcel    long v2 = atf::text::to_type< long >(get_config_var("v2"));
121240116Smarcel
122240116Smarcel    create_ctl_file("before");
123240116Smarcel    ATF_REQUIRE_EQ(v1, v2);
124240116Smarcel    create_ctl_file("after");
125240116Smarcel}
126240116Smarcel
127240116SmarcelATF_TEST_CASE(h_require_in);
128240116SmarcelATF_TEST_CASE_HEAD(h_require_in)
129240116Smarcel{
130240116Smarcel    set_md_var("descr", "Helper test case");
131240116Smarcel}
132240116SmarcelATF_TEST_CASE_BODY(h_require_in)
133240116Smarcel{
134240116Smarcel    const std::string element = get_config_var("value");
135240116Smarcel
136240116Smarcel    std::set< std::string > collection;
137240116Smarcel    collection.insert("foo");
138240116Smarcel    collection.insert("bar");
139240116Smarcel    collection.insert("baz");
140240116Smarcel
141240116Smarcel    create_ctl_file("before");
142240116Smarcel    ATF_REQUIRE_IN(element, collection);
143240116Smarcel    create_ctl_file("after");
144240116Smarcel}
145240116Smarcel
146240116SmarcelATF_TEST_CASE(h_require_match);
147240116SmarcelATF_TEST_CASE_HEAD(h_require_match)
148240116Smarcel{
149240116Smarcel    set_md_var("descr", "Helper test case");
150240116Smarcel}
151240116SmarcelATF_TEST_CASE_BODY(h_require_match)
152240116Smarcel{
153240116Smarcel    const std::string regexp = get_config_var("regexp");
154240116Smarcel    const std::string string = get_config_var("string");
155240116Smarcel
156240116Smarcel    create_ctl_file("before");
157240116Smarcel    ATF_REQUIRE_MATCH(regexp, string);
158240116Smarcel    create_ctl_file("after");
159240116Smarcel}
160240116Smarcel
161240116SmarcelATF_TEST_CASE(h_require_not_in);
162240116SmarcelATF_TEST_CASE_HEAD(h_require_not_in)
163240116Smarcel{
164240116Smarcel    set_md_var("descr", "Helper test case");
165240116Smarcel}
166240116SmarcelATF_TEST_CASE_BODY(h_require_not_in)
167240116Smarcel{
168240116Smarcel    const std::string element = get_config_var("value");
169240116Smarcel
170240116Smarcel    std::set< std::string > collection;
171240116Smarcel    collection.insert("foo");
172240116Smarcel    collection.insert("bar");
173240116Smarcel    collection.insert("baz");
174240116Smarcel
175240116Smarcel    create_ctl_file("before");
176240116Smarcel    ATF_REQUIRE_NOT_IN(element, collection);
177240116Smarcel    create_ctl_file("after");
178240116Smarcel}
179240116Smarcel
180240116SmarcelATF_TEST_CASE(h_require_throw);
181240116SmarcelATF_TEST_CASE_HEAD(h_require_throw)
182240116Smarcel{
183240116Smarcel    set_md_var("descr", "Helper test case");
184240116Smarcel}
185240116SmarcelATF_TEST_CASE_BODY(h_require_throw)
186240116Smarcel{
187240116Smarcel    create_ctl_file("before");
188240116Smarcel
189240116Smarcel    if (get_config_var("what") == "throw_int")
190240116Smarcel        ATF_REQUIRE_THROW(std::runtime_error, if (1) throw int(5));
191240116Smarcel    else if (get_config_var("what") == "throw_rt")
192240116Smarcel        ATF_REQUIRE_THROW(std::runtime_error,
193240116Smarcel                        if (1) throw std::runtime_error("e"));
194240116Smarcel    else if (get_config_var("what") == "no_throw_rt")
195240116Smarcel        ATF_REQUIRE_THROW(std::runtime_error,
196240116Smarcel                        if (0) throw std::runtime_error("e"));
197240116Smarcel
198240116Smarcel    create_ctl_file("after");
199240116Smarcel}
200240116Smarcel
201240116SmarcelATF_TEST_CASE(h_require_throw_re);
202240116SmarcelATF_TEST_CASE_HEAD(h_require_throw_re)
203240116Smarcel{
204240116Smarcel    set_md_var("descr", "Helper test case");
205240116Smarcel}
206240116SmarcelATF_TEST_CASE_BODY(h_require_throw_re)
207240116Smarcel{
208240116Smarcel    create_ctl_file("before");
209240116Smarcel
210240116Smarcel    if (get_config_var("what") == "throw_int")
211240116Smarcel        ATF_REQUIRE_THROW_RE(std::runtime_error, "5", if (1) throw int(5));
212240116Smarcel    else if (get_config_var("what") == "throw_rt_match")
213240116Smarcel        ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
214240116Smarcel                             if (1) throw std::runtime_error("a foo bar baz"));
215240116Smarcel    else if (get_config_var("what") == "throw_rt_no_match")
216240116Smarcel        ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
217240116Smarcel                             if (1) throw std::runtime_error("baz foo bar a"));
218240116Smarcel    else if (get_config_var("what") == "no_throw_rt")
219240116Smarcel        ATF_REQUIRE_THROW_RE(std::runtime_error, "e",
220240116Smarcel                             if (0) throw std::runtime_error("e"));
221240116Smarcel
222240116Smarcel    create_ctl_file("after");
223240116Smarcel}
224240116Smarcel
225240116Smarcelstatic int
226240116Smarcelerrno_fail_stub(const int raised_errno)
227240116Smarcel{
228240116Smarcel    errno = raised_errno;
229240116Smarcel    return -1;
230240116Smarcel}
231240116Smarcel
232240116Smarcelstatic int
233240116Smarcelerrno_ok_stub(void)
234240116Smarcel{
235240116Smarcel    return 0;
236240116Smarcel}
237240116Smarcel
238240116SmarcelATF_TEST_CASE(h_check_errno);
239240116SmarcelATF_TEST_CASE_HEAD(h_check_errno)
240240116Smarcel{
241240116Smarcel    set_md_var("descr", "Helper test case");
242240116Smarcel}
243240116SmarcelATF_TEST_CASE_BODY(h_check_errno)
244240116Smarcel{
245240116Smarcel    create_ctl_file("before");
246240116Smarcel
247240116Smarcel    if (get_config_var("what") == "no_error")
248240116Smarcel        ATF_CHECK_ERRNO(-1, errno_ok_stub() == -1);
249240116Smarcel    else if (get_config_var("what") == "errno_ok")
250240116Smarcel        ATF_CHECK_ERRNO(2, errno_fail_stub(2) == -1);
251240116Smarcel    else if (get_config_var("what") == "errno_fail")
252240116Smarcel        ATF_CHECK_ERRNO(3, errno_fail_stub(4) == -1);
253240116Smarcel    else
254240116Smarcel        UNREACHABLE;
255240116Smarcel
256240116Smarcel    create_ctl_file("after");
257240116Smarcel}
258240116Smarcel
259240116SmarcelATF_TEST_CASE(h_require_errno);
260240116SmarcelATF_TEST_CASE_HEAD(h_require_errno)
261240116Smarcel{
262240116Smarcel    set_md_var("descr", "Helper test case");
263240116Smarcel}
264240116SmarcelATF_TEST_CASE_BODY(h_require_errno)
265240116Smarcel{
266240116Smarcel    create_ctl_file("before");
267240116Smarcel
268240116Smarcel    if (get_config_var("what") == "no_error")
269240116Smarcel        ATF_REQUIRE_ERRNO(-1, errno_ok_stub() == -1);
270240116Smarcel    else if (get_config_var("what") == "errno_ok")
271240116Smarcel        ATF_REQUIRE_ERRNO(2, errno_fail_stub(2) == -1);
272240116Smarcel    else if (get_config_var("what") == "errno_fail")
273240116Smarcel        ATF_REQUIRE_ERRNO(3, errno_fail_stub(4) == -1);
274240116Smarcel    else
275240116Smarcel        UNREACHABLE;
276240116Smarcel
277240116Smarcel    create_ctl_file("after");
278240116Smarcel}
279240116Smarcel
280240116Smarcel// ------------------------------------------------------------------------
281240116Smarcel// Test cases for the macros.
282240116Smarcel// ------------------------------------------------------------------------
283240116Smarcel
284240116SmarcelATF_TEST_CASE(pass);
285240116SmarcelATF_TEST_CASE_HEAD(pass)
286240116Smarcel{
287240116Smarcel    set_md_var("descr", "Tests the ATF_PASS macro");
288240116Smarcel}
289240116SmarcelATF_TEST_CASE_BODY(pass)
290240116Smarcel{
291240116Smarcel    ATF_TEST_CASE_USE(h_pass);
292240116Smarcel    run_h_tc< ATF_TEST_CASE_NAME(h_pass) >();
293260029Sjmmv    ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
294240116Smarcel    ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
295240116Smarcel    ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
296240116Smarcel}
297240116Smarcel
298240116SmarcelATF_TEST_CASE(fail);
299240116SmarcelATF_TEST_CASE_HEAD(fail)
300240116Smarcel{
301240116Smarcel    set_md_var("descr", "Tests the ATF_FAIL macro");
302240116Smarcel}
303240116SmarcelATF_TEST_CASE_BODY(fail)
304240116Smarcel{
305240116Smarcel    ATF_TEST_CASE_USE(h_fail);
306240116Smarcel    run_h_tc< ATF_TEST_CASE_NAME(h_fail) >();
307260029Sjmmv    ATF_REQUIRE(atf::utils::grep_file("^failed: Failed on purpose", "result"));
308240116Smarcel    ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
309240116Smarcel    ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
310240116Smarcel}
311240116Smarcel
312240116SmarcelATF_TEST_CASE(skip);
313240116SmarcelATF_TEST_CASE_HEAD(skip)
314240116Smarcel{
315240116Smarcel    set_md_var("descr", "Tests the ATF_SKIP macro");
316240116Smarcel}
317240116SmarcelATF_TEST_CASE_BODY(skip)
318240116Smarcel{
319240116Smarcel    ATF_TEST_CASE_USE(h_skip);
320240116Smarcel    run_h_tc< ATF_TEST_CASE_NAME(h_skip) >();
321260029Sjmmv    ATF_REQUIRE(atf::utils::grep_file("^skipped: Skipped on purpose",
322260029Sjmmv        "result"));
323240116Smarcel    ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
324240116Smarcel    ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
325240116Smarcel}
326240116Smarcel
327240116SmarcelATF_TEST_CASE(require);
328240116SmarcelATF_TEST_CASE_HEAD(require)
329240116Smarcel{
330240116Smarcel    set_md_var("descr", "Tests the ATF_REQUIRE macro");
331240116Smarcel}
332240116SmarcelATF_TEST_CASE_BODY(require)
333240116Smarcel{
334240116Smarcel    struct test {
335240116Smarcel        const char *cond;
336240116Smarcel        bool ok;
337240116Smarcel    } *t, tests[] = {
338240116Smarcel        { "false", false },
339240116Smarcel        { "true", true },
340240116Smarcel        { NULL, false }
341240116Smarcel    };
342240116Smarcel
343240116Smarcel    const atf::fs::path before("before");
344240116Smarcel    const atf::fs::path after("after");
345240116Smarcel
346240116Smarcel    for (t = &tests[0]; t->cond != NULL; t++) {
347240116Smarcel        atf::tests::vars_map config;
348240116Smarcel        config["condition"] = t->cond;
349240116Smarcel
350240116Smarcel        std::cout << "Checking with a " << t->cond << " value\n";
351240116Smarcel
352240116Smarcel        ATF_TEST_CASE_USE(h_require);
353240116Smarcel        run_h_tc< ATF_TEST_CASE_NAME(h_require) >(config);
354240116Smarcel
355240116Smarcel        ATF_REQUIRE(atf::fs::exists(before));
356240116Smarcel        if (t->ok) {
357260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
358240116Smarcel            ATF_REQUIRE(atf::fs::exists(after));
359240116Smarcel        } else {
360260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file(
361260029Sjmmv                "^failed: .*condition not met", "result"));
362240116Smarcel            ATF_REQUIRE(!atf::fs::exists(after));
363240116Smarcel        }
364240116Smarcel
365240116Smarcel        atf::fs::remove(before);
366240116Smarcel        if (t->ok)
367240116Smarcel            atf::fs::remove(after);
368240116Smarcel    }
369240116Smarcel}
370240116Smarcel
371240116SmarcelATF_TEST_CASE(require_eq);
372240116SmarcelATF_TEST_CASE_HEAD(require_eq)
373240116Smarcel{
374240116Smarcel    set_md_var("descr", "Tests the ATF_REQUIRE_EQ macro");
375240116Smarcel}
376240116SmarcelATF_TEST_CASE_BODY(require_eq)
377240116Smarcel{
378240116Smarcel    struct test {
379240116Smarcel        const char *v1;
380240116Smarcel        const char *v2;
381240116Smarcel        bool ok;
382240116Smarcel    } *t, tests[] = {
383240116Smarcel        { "1", "1", true },
384240116Smarcel        { "1", "2", false },
385240116Smarcel        { "2", "1", false },
386240116Smarcel        { "2", "2", true },
387240116Smarcel        { NULL, NULL, false }
388240116Smarcel    };
389240116Smarcel
390240116Smarcel    const atf::fs::path before("before");
391240116Smarcel    const atf::fs::path after("after");
392240116Smarcel
393240116Smarcel    for (t = &tests[0]; t->v1 != NULL; t++) {
394240116Smarcel        atf::tests::vars_map config;
395240116Smarcel        config["v1"] = t->v1;
396240116Smarcel        config["v2"] = t->v2;
397240116Smarcel
398240116Smarcel        std::cout << "Checking with " << t->v1 << ", " << t->v2
399240116Smarcel                  << " and expecting " << (t->ok ? "true" : "false")
400240116Smarcel                  << "\n";
401240116Smarcel
402240116Smarcel        ATF_TEST_CASE_USE(h_require_eq);
403240116Smarcel        run_h_tc< ATF_TEST_CASE_NAME(h_require_eq) >(config);
404240116Smarcel
405240116Smarcel        ATF_REQUIRE(atf::fs::exists(before));
406240116Smarcel        if (t->ok) {
407260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
408240116Smarcel            ATF_REQUIRE(atf::fs::exists(after));
409240116Smarcel        } else {
410260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^failed: .*v1 != v2", "result"));
411240116Smarcel            ATF_REQUIRE(!atf::fs::exists(after));
412240116Smarcel        }
413240116Smarcel
414240116Smarcel        atf::fs::remove(before);
415240116Smarcel        if (t->ok)
416240116Smarcel            atf::fs::remove(after);
417240116Smarcel    }
418240116Smarcel}
419240116Smarcel
420240116SmarcelATF_TEST_CASE(require_in);
421240116SmarcelATF_TEST_CASE_HEAD(require_in)
422240116Smarcel{
423240116Smarcel    set_md_var("descr", "Tests the ATF_REQUIRE_IN macro");
424240116Smarcel}
425240116SmarcelATF_TEST_CASE_BODY(require_in)
426240116Smarcel{
427240116Smarcel    struct test {
428240116Smarcel        const char *value;
429240116Smarcel        bool ok;
430240116Smarcel    } *t, tests[] = {
431240116Smarcel        { "foo", true },
432240116Smarcel        { "bar", true },
433240116Smarcel        { "baz", true },
434240116Smarcel        { "xxx", false },
435240116Smarcel        { "fooa", false },
436240116Smarcel        { "foo ", false },
437240116Smarcel        { NULL, false }
438240116Smarcel    };
439240116Smarcel
440240116Smarcel    const atf::fs::path before("before");
441240116Smarcel    const atf::fs::path after("after");
442240116Smarcel
443240116Smarcel    for (t = &tests[0]; t->value != NULL; t++) {
444240116Smarcel        atf::tests::vars_map config;
445240116Smarcel        config["value"] = t->value;
446240116Smarcel
447240116Smarcel        ATF_TEST_CASE_USE(h_require_in);
448240116Smarcel        run_h_tc< ATF_TEST_CASE_NAME(h_require_in) >(config);
449240116Smarcel
450240116Smarcel        ATF_REQUIRE(atf::fs::exists(before));
451240116Smarcel        if (t->ok) {
452260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
453240116Smarcel            ATF_REQUIRE(atf::fs::exists(after));
454240116Smarcel        } else {
455260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
456240116Smarcel            ATF_REQUIRE(!atf::fs::exists(after));
457240116Smarcel        }
458240116Smarcel
459240116Smarcel        atf::fs::remove(before);
460240116Smarcel        if (t->ok)
461240116Smarcel            atf::fs::remove(after);
462240116Smarcel    }
463240116Smarcel}
464240116Smarcel
465240116SmarcelATF_TEST_CASE(require_match);
466240116SmarcelATF_TEST_CASE_HEAD(require_match)
467240116Smarcel{
468240116Smarcel    set_md_var("descr", "Tests the ATF_REQUIRE_MATCH macro");
469240116Smarcel}
470240116SmarcelATF_TEST_CASE_BODY(require_match)
471240116Smarcel{
472240116Smarcel    struct test {
473240116Smarcel        const char *regexp;
474240116Smarcel        const char *string;
475240116Smarcel        bool ok;
476240116Smarcel    } *t, tests[] = {
477240116Smarcel        { "foo.*bar", "this is a foo, bar, baz", true },
478240116Smarcel        { "bar.*baz", "this is a baz, bar, foo", false },
479240116Smarcel        { NULL, NULL, false }
480240116Smarcel    };
481240116Smarcel
482240116Smarcel    const atf::fs::path before("before");
483240116Smarcel    const atf::fs::path after("after");
484240116Smarcel
485240116Smarcel    for (t = &tests[0]; t->regexp != NULL; t++) {
486240116Smarcel        atf::tests::vars_map config;
487240116Smarcel        config["regexp"] = t->regexp;
488240116Smarcel        config["string"] = t->string;
489240116Smarcel
490240116Smarcel        std::cout << "Checking with " << t->regexp << ", " << t->string
491240116Smarcel                  << " and expecting " << (t->ok ? "true" : "false")
492240116Smarcel                  << "\n";
493240116Smarcel
494240116Smarcel        ATF_TEST_CASE_USE(h_require_match);
495240116Smarcel        run_h_tc< ATF_TEST_CASE_NAME(h_require_match) >(config);
496240116Smarcel
497240116Smarcel        ATF_REQUIRE(atf::fs::exists(before));
498240116Smarcel        if (t->ok) {
499260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
500240116Smarcel            ATF_REQUIRE(atf::fs::exists(after));
501240116Smarcel        } else {
502260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
503240116Smarcel            ATF_REQUIRE(!atf::fs::exists(after));
504240116Smarcel        }
505240116Smarcel
506240116Smarcel        atf::fs::remove(before);
507240116Smarcel        if (t->ok)
508240116Smarcel            atf::fs::remove(after);
509240116Smarcel    }
510240116Smarcel}
511240116Smarcel
512240116SmarcelATF_TEST_CASE(require_not_in);
513240116SmarcelATF_TEST_CASE_HEAD(require_not_in)
514240116Smarcel{
515240116Smarcel    set_md_var("descr", "Tests the ATF_REQUIRE_NOT_IN macro");
516240116Smarcel}
517240116SmarcelATF_TEST_CASE_BODY(require_not_in)
518240116Smarcel{
519240116Smarcel    struct test {
520240116Smarcel        const char *value;
521240116Smarcel        bool ok;
522240116Smarcel    } *t, tests[] = {
523240116Smarcel        { "foo", false },
524240116Smarcel        { "bar", false },
525240116Smarcel        { "baz", false },
526240116Smarcel        { "xxx", true },
527240116Smarcel        { "fooa", true },
528240116Smarcel        { "foo ", true },
529240116Smarcel        { NULL, false }
530240116Smarcel    };
531240116Smarcel
532240116Smarcel    const atf::fs::path before("before");
533240116Smarcel    const atf::fs::path after("after");
534240116Smarcel
535240116Smarcel    for (t = &tests[0]; t->value != NULL; t++) {
536240116Smarcel        atf::tests::vars_map config;
537240116Smarcel        config["value"] = t->value;
538240116Smarcel
539240116Smarcel        ATF_TEST_CASE_USE(h_require_not_in);
540240116Smarcel        run_h_tc< ATF_TEST_CASE_NAME(h_require_not_in) >(config);
541240116Smarcel
542240116Smarcel        ATF_REQUIRE(atf::fs::exists(before));
543240116Smarcel        if (t->ok) {
544260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
545240116Smarcel            ATF_REQUIRE(atf::fs::exists(after));
546240116Smarcel        } else {
547260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
548240116Smarcel            ATF_REQUIRE(!atf::fs::exists(after));
549240116Smarcel        }
550240116Smarcel
551240116Smarcel        atf::fs::remove(before);
552240116Smarcel        if (t->ok)
553240116Smarcel            atf::fs::remove(after);
554240116Smarcel    }
555240116Smarcel}
556240116Smarcel
557240116SmarcelATF_TEST_CASE(require_throw);
558240116SmarcelATF_TEST_CASE_HEAD(require_throw)
559240116Smarcel{
560240116Smarcel    set_md_var("descr", "Tests the ATF_REQUIRE_THROW macro");
561240116Smarcel}
562240116SmarcelATF_TEST_CASE_BODY(require_throw)
563240116Smarcel{
564240116Smarcel    struct test {
565240116Smarcel        const char *what;
566240116Smarcel        bool ok;
567240116Smarcel        const char *msg;
568240116Smarcel    } *t, tests[] = {
569240116Smarcel        { "throw_int", false, "unexpected error" },
570240116Smarcel        { "throw_rt", true, NULL },
571240116Smarcel        { "no_throw_rt", false, "did not throw" },
572240116Smarcel        { NULL, false, NULL }
573240116Smarcel    };
574240116Smarcel
575240116Smarcel    const atf::fs::path before("before");
576240116Smarcel    const atf::fs::path after("after");
577240116Smarcel
578240116Smarcel    for (t = &tests[0]; t->what != NULL; t++) {
579240116Smarcel        atf::tests::vars_map config;
580240116Smarcel        config["what"] = t->what;
581240116Smarcel
582240116Smarcel        std::cout << "Checking with " << t->what << " and expecting "
583240116Smarcel                  << (t->ok ? "true" : "false") << "\n";
584240116Smarcel
585240116Smarcel        ATF_TEST_CASE_USE(h_require_throw);
586240116Smarcel        run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
587240116Smarcel
588240116Smarcel        ATF_REQUIRE(atf::fs::exists(before));
589240116Smarcel        if (t->ok) {
590260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
591240116Smarcel            ATF_REQUIRE(atf::fs::exists(after));
592240116Smarcel        } else {
593240116Smarcel            std::cout << "Checking that message contains '" << t->msg
594240116Smarcel                      << "'\n";
595240116Smarcel            std::string exp_result = std::string("^failed: .*") + t->msg;
596260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
597240116Smarcel            ATF_REQUIRE(!atf::fs::exists(after));
598240116Smarcel        }
599240116Smarcel
600240116Smarcel        atf::fs::remove(before);
601240116Smarcel        if (t->ok)
602240116Smarcel            atf::fs::remove(after);
603240116Smarcel    }
604240116Smarcel}
605240116Smarcel
606240116SmarcelATF_TEST_CASE(require_throw_re);
607240116SmarcelATF_TEST_CASE_HEAD(require_throw_re)
608240116Smarcel{
609240116Smarcel    set_md_var("descr", "Tests the ATF_REQUIRE_THROW_RE macro");
610240116Smarcel}
611240116SmarcelATF_TEST_CASE_BODY(require_throw_re)
612240116Smarcel{
613240116Smarcel    struct test {
614240116Smarcel        const char *what;
615240116Smarcel        bool ok;
616240116Smarcel        const char *msg;
617240116Smarcel    } *t, tests[] = {
618240116Smarcel        { "throw_int", false, "unexpected error" },
619240116Smarcel        { "throw_rt_match", true, NULL },
620240116Smarcel        { "throw_rt_no_match", false,
621240116Smarcel          "threw.*runtime_error\\(baz foo bar a\\).*"
622240116Smarcel          "does not match 'foo\\.\\*baz'" },
623240116Smarcel        { "no_throw_rt", false, "did not throw" },
624240116Smarcel        { NULL, false, NULL }
625240116Smarcel    };
626240116Smarcel
627240116Smarcel    const atf::fs::path before("before");
628240116Smarcel    const atf::fs::path after("after");
629240116Smarcel
630240116Smarcel    for (t = &tests[0]; t->what != NULL; t++) {
631240116Smarcel        atf::tests::vars_map config;
632240116Smarcel        config["what"] = t->what;
633240116Smarcel
634240116Smarcel        std::cout << "Checking with " << t->what << " and expecting "
635240116Smarcel                  << (t->ok ? "true" : "false") << "\n";
636240116Smarcel
637240116Smarcel        ATF_TEST_CASE_USE(h_require_throw_re);
638240116Smarcel        run_h_tc< ATF_TEST_CASE_NAME(h_require_throw_re) >(config);
639240116Smarcel
640240116Smarcel        ATF_REQUIRE(atf::fs::exists(before));
641240116Smarcel        if (t->ok) {
642260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
643240116Smarcel            ATF_REQUIRE(atf::fs::exists(after));
644240116Smarcel        } else {
645240116Smarcel            std::cout << "Checking that message contains '" << t->msg
646240116Smarcel                      << "'\n";
647240116Smarcel            std::string exp_result = std::string("^failed: .*") + t->msg;
648260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
649240116Smarcel            ATF_REQUIRE(!atf::fs::exists(after));
650240116Smarcel        }
651240116Smarcel
652240116Smarcel        atf::fs::remove(before);
653240116Smarcel        if (t->ok)
654240116Smarcel            atf::fs::remove(after);
655240116Smarcel    }
656240116Smarcel}
657240116Smarcel
658240116SmarcelATF_TEST_CASE(check_errno);
659240116SmarcelATF_TEST_CASE_HEAD(check_errno)
660240116Smarcel{
661240116Smarcel    set_md_var("descr", "Tests the ATF_CHECK_ERRNO macro");
662240116Smarcel}
663240116SmarcelATF_TEST_CASE_BODY(check_errno)
664240116Smarcel{
665240116Smarcel    struct test {
666240116Smarcel        const char *what;
667240116Smarcel        bool ok;
668240116Smarcel        const char *msg;
669240116Smarcel    } *t, tests[] = {
670240116Smarcel        { "no_error", false,
671240116Smarcel          "Expected true value in errno_ok_stub\\(\\) == -1" },
672240116Smarcel        { "errno_ok", true, NULL },
673240116Smarcel        { "errno_fail", false,
674240116Smarcel          "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
675240116Smarcel        { NULL, false, NULL }
676240116Smarcel    };
677240116Smarcel
678240116Smarcel    const atf::fs::path before("before");
679240116Smarcel    const atf::fs::path after("after");
680240116Smarcel
681240116Smarcel    for (t = &tests[0]; t->what != NULL; t++) {
682240116Smarcel        atf::tests::vars_map config;
683240116Smarcel        config["what"] = t->what;
684240116Smarcel
685240116Smarcel        ATF_TEST_CASE_USE(h_check_errno);
686240116Smarcel        run_h_tc< ATF_TEST_CASE_NAME(h_check_errno) >(config);
687240116Smarcel
688240116Smarcel        ATF_REQUIRE(atf::fs::exists(before));
689240116Smarcel        ATF_REQUIRE(atf::fs::exists(after));
690240116Smarcel
691240116Smarcel        if (t->ok) {
692260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
693240116Smarcel        } else {
694260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^failed", "result"));
695240116Smarcel
696240116Smarcel            std::string exp_result = "macros_test.cpp:[0-9]+: " +
697240116Smarcel                std::string(t->msg) + "$";
698260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "stderr"));
699240116Smarcel        }
700240116Smarcel
701240116Smarcel        atf::fs::remove(before);
702240116Smarcel        atf::fs::remove(after);
703240116Smarcel    }
704240116Smarcel}
705240116Smarcel
706240116SmarcelATF_TEST_CASE(require_errno);
707240116SmarcelATF_TEST_CASE_HEAD(require_errno)
708240116Smarcel{
709240116Smarcel    set_md_var("descr", "Tests the ATF_REQUIRE_ERRNO macro");
710240116Smarcel}
711240116SmarcelATF_TEST_CASE_BODY(require_errno)
712240116Smarcel{
713240116Smarcel    struct test {
714240116Smarcel        const char *what;
715240116Smarcel        bool ok;
716240116Smarcel        const char *msg;
717240116Smarcel    } *t, tests[] = {
718240116Smarcel        { "no_error", false,
719240116Smarcel          "Expected true value in errno_ok_stub\\(\\) == -1" },
720240116Smarcel        { "errno_ok", true, NULL },
721240116Smarcel        { "errno_fail", false,
722240116Smarcel          "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
723240116Smarcel        { NULL, false, NULL }
724240116Smarcel    };
725240116Smarcel
726240116Smarcel    const atf::fs::path before("before");
727240116Smarcel    const atf::fs::path after("after");
728240116Smarcel
729240116Smarcel    for (t = &tests[0]; t->what != NULL; t++) {
730240116Smarcel        atf::tests::vars_map config;
731240116Smarcel        config["what"] = t->what;
732240116Smarcel
733240116Smarcel        ATF_TEST_CASE_USE(h_require_errno);
734240116Smarcel        run_h_tc< ATF_TEST_CASE_NAME(h_require_errno) >(config);
735240116Smarcel
736240116Smarcel        ATF_REQUIRE(atf::fs::exists(before));
737240116Smarcel        if (t->ok) {
738260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
739240116Smarcel            ATF_REQUIRE(atf::fs::exists(after));
740240116Smarcel        } else {
741240116Smarcel            std::string exp_result = "^failed: .*macros_test.cpp:[0-9]+: " +
742240116Smarcel                std::string(t->msg) + "$";
743260029Sjmmv            ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
744240116Smarcel
745240116Smarcel            ATF_REQUIRE(!atf::fs::exists(after));
746240116Smarcel        }
747240116Smarcel
748240116Smarcel        atf::fs::remove(before);
749240116Smarcel        if (t->ok)
750240116Smarcel            atf::fs::remove(after);
751240116Smarcel    }
752240116Smarcel}
753240116Smarcel
754240116Smarcel// ------------------------------------------------------------------------
755240116Smarcel// Tests cases for the header file.
756240116Smarcel// ------------------------------------------------------------------------
757240116Smarcel
758240116SmarcelBUILD_TC(use, "macros_hpp_test.cpp",
759240116Smarcel         "Tests that the macros provided by the atf-c++/macros.hpp file "
760240116Smarcel         "do not cause syntax errors when used",
761240116Smarcel         "Build of macros_hpp_test.cpp failed; some macros in "
762240116Smarcel         "atf-c++/macros.hpp are broken");
763240116Smarcel
764262855SjmmvATF_TEST_CASE(detect_unused_tests);
765262855SjmmvATF_TEST_CASE_HEAD(detect_unused_tests)
766262855Sjmmv{
767262855Sjmmv    set_md_var("descr",
768262855Sjmmv               "Tests that defining an unused test case raises a warning (and "
769262855Sjmmv               "thus an error)");
770262855Sjmmv}
771262855SjmmvATF_TEST_CASE_BODY(detect_unused_tests)
772262855Sjmmv{
773262855Sjmmv    const char* validate_compiler =
774262855Sjmmv        "class test_class { public: int dummy; };\n"
775262855Sjmmv        "#define define_unused static test_class unused\n"
776262855Sjmmv        "define_unused;\n";
777262855Sjmmv
778262855Sjmmv    atf::utils::create_file("compiler_test.cpp", validate_compiler);
779262855Sjmmv    if (build_check_cxx_o("compiler_test.cpp"))
780262855Sjmmv        expect_fail("Compiler does not raise a warning on an unused "
781262855Sjmmv                    "static global variable declared by a macro");
782262855Sjmmv
783262855Sjmmv    if (build_check_cxx_o_srcdir(*this, "unused_test.cpp"))
784262855Sjmmv        ATF_FAIL("Build of unused_test.cpp passed; unused test cases are "
785262855Sjmmv                 "not properly detected");
786262855Sjmmv}
787262855Sjmmv
788240116Smarcel// ------------------------------------------------------------------------
789240116Smarcel// Main.
790240116Smarcel// ------------------------------------------------------------------------
791240116Smarcel
792240116SmarcelATF_INIT_TEST_CASES(tcs)
793240116Smarcel{
794240116Smarcel    // Add the test cases for the macros.
795240116Smarcel    ATF_ADD_TEST_CASE(tcs, pass);
796240116Smarcel    ATF_ADD_TEST_CASE(tcs, fail);
797240116Smarcel    ATF_ADD_TEST_CASE(tcs, skip);
798240116Smarcel    ATF_ADD_TEST_CASE(tcs, check_errno);
799240116Smarcel    ATF_ADD_TEST_CASE(tcs, require);
800240116Smarcel    ATF_ADD_TEST_CASE(tcs, require_eq);
801240116Smarcel    ATF_ADD_TEST_CASE(tcs, require_in);
802240116Smarcel    ATF_ADD_TEST_CASE(tcs, require_match);
803240116Smarcel    ATF_ADD_TEST_CASE(tcs, require_not_in);
804240116Smarcel    ATF_ADD_TEST_CASE(tcs, require_throw);
805240116Smarcel    ATF_ADD_TEST_CASE(tcs, require_throw_re);
806240116Smarcel    ATF_ADD_TEST_CASE(tcs, require_errno);
807240116Smarcel
808240116Smarcel    // Add the test cases for the header file.
809240116Smarcel    ATF_ADD_TEST_CASE(tcs, use);
810240116Smarcel    ATF_ADD_TEST_CASE(tcs, detect_unused_tests);
811240116Smarcel}
812