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